looking for a way (with grease/tampermonkey) to replace part of url(s) on page - greasemonkey

So I frequent a webpage which uses ouo.io to try and make some advertisement money on links. Lucky me that that particular redirector-service doesnt alter or hide the original url in any way, so I was thinking that perhaps it would be possible (with a tamper/greasemonkey script I guess) to remove the ouo part from the urls automatically
The urls are like this
https:// ouo.io/qs/pRqHNWPK?s=https://destination.url/
(The space between the protocol and the ouo part was intentional because without it this link trips the URL-shortener warning thus not letting me post)
Anybody who has a tampermonkey script that would be adaptable for this situation? I tried messing around and writing something myself but that didn't work (or do anything at all lmao).

Here is a sample code to show you how it can be done ...
(remove extra space added before ouo)
Redirecting based on location.href of the new page
// ==UserScript==
// #name Remove Redirect
// #match https:// ouo.io/qs/*
// #grant none
// #version 1.0
// run-at document-start
// ==/UserScript==
const redirect = location.search.match(/http.+/); // find redirect URL
if (redirect) {
window.stop(); // stop loading the page
location.href = decodeURIComponent(redirect[0]);
}
You can also change the links on the pages. It is much more resource intensive since it has to run on every page thus not recommended. Here is an example ...
// ==UserScript==
// #name Remove Redirect Link
// #match *://*/*
// #grant none
// #version 1.0
// ==/UserScript==
document.querySelectorAll('a[href^="https:// ouo.io/qs/"]').forEach(item => {
const redirect = item.search.match(/http.+/); // find redirect URL
if (redirect) {
item.href = decodeURIComponent(redirect[0]);
}
}):

Related

Gitlab, how to change tabulation size on code review

While reviewing the code with gitlab merge request web page, tabulation is 8 spaces.
It makes the code difficult to read. How could I move it to 1 or 2 spaces ?
It seems to be impossible to achieve that by available GitLab settings, but this can be hacked using Greasemonkey/Tampermonkey browser extension:
// ==UserScript==
// #name Custom tab-width
// #version 1
// #grant none
// #include https://your.gitlab.server.com/*/diffs*
// ==/UserScript==
var style = document.createElement("style");
style.type = "text/css";
style.innerHTML = "span.line {tab-size:2; -moz-tab-size:2;}";
document.head.appendChild(style);
or by any other stylish-like extensions which allow you to attach any custom css rules to web pages:
span.line {tab-size:2; -moz-tab-size:2;}

Accessing the window properties on another website by GM_xmlhttpRequest

I am currently writing a userscript for website A to access another the contents on website B. So I tried to use the GM_xmlhttpRequest to do it. However, a variable on B is written to the window property eg: window.var or responseContent.var.
However, when I tried to get the window.var, the output is undefined, which means the properties under the window variable cannot be read successfully. I guess the window object is refering to the website A but not website B, so the result is undefined (There is no window.var on A).
I am sure that the GM_xmlhttpRequest has successfully read the content of the website B because I have added console.log to see the response.responseText. I have also used the window.var to successfully visit that variable on website B by browser directly.
GM_xmlhttpRequest({
method: "GET",
url: url,
headers: {
referrer: "https://A.com"
},
onload: function (response) {
// console.log(response.responseText);
let responseContent = new Document();
responseContent = new DOMParser().parseFromString(response.responseText, "text/html");
let titleDiv = responseContent.querySelector("title");
if (titleDiv != null) {
if (titleDiv.innerText.includes("404")) {
console.log("404");
return;
} else {
console.log(responseContent.var);
console.log(window.var);
}
}
},
onerror: function (e) {
console.log(e);
}
});
I would like to retrieve content window.var on website B and show it on the console.log of A
Please help me solve the problem. Thank you in advance.
#wOxxOm's comments are on point. You cannot really get the executed javascript of another website like that. One way to go around it is to use <iframe> and post message, just like #wOxxOm said. But that may fail if the other website has policy against iframes.
If this userscript is just for your use, another way is to have two scripts, one for each website and have them both open in browser tabs. Then again you can use postMessage to have those two scripts communicate the information. Dirty solution for your second userscript would be to just post the variable info on regular interval:
// Userscript for website-b.com
// needs #grant for unsafe-window to get the window.var
setInterval(()=>{postMessage(unsafeWindow.var, "website-a.com");}, 1000);
That would send an update of var's value every second. It's not very elegant, but it's simple and works. For a more elegant solution, you may want to first postMessage from website a that will trigger postMessage(unsafeWindow.var, "website-a.com"). Working with that further, you will soon find yourself inventing an asynchronous communication protocol.
Alternatively, if the second website is simple, you can try to parse the value of var directly from HTML, or wherever the value is coming from. That's a preferred solution, but requires reverse-engineering on your part.

Greasemonkey: leaving user configuration intact while updating

I've written a user script for Greasemonkey that requires some user configuration. To specify how they want the script to behave, a user needs to set a couple variables.
Right now, the script is set up like this:
// ==UserScript==
// #name My script
// #description A simplified example
// #include http://www.example.com/
// #version 0.0.1
// #updateURL https://www.example.com/myscript.meta.js
// ==/UserScript==
// Configuration
var config1 = "on";
var config2 = "off";
// Programs
[various functions that refer to the configuration variables]
I'd like to be able to update the script using Greasemonkey's automatic updates, while leaving the user's configuration lines intact. Basically, I don't want to force every user to redo their configuration after each update.
Is there a good method for updating a Greasemonkey userscript while leaving some configuration intact?
You may wish to utilise the greasemonkey functions GM_getValue() and GM_setValue(), which will store values that stay that way until they're changed again. The script can set values based on user needs, and get the value where required.
Specific GM functions require a special grant, in the metadata for the userscript:
// #grant GM_getValue
// #grant GM_setValue
Your code with the GM value functions may look like this:
var value = 18;
GM_setValue('dataName', value);
if (GM_getValue('dataName') == 18) ...
When you make updates to the script, instead of having the values set by GM_setValue overwritten, you could first check to see if they have been written:
var value = 18;
if (typeof GM_getValue('dataName') === 'undefined')
GM_setValue('dataName', value);
To enable users to control these settings, you could inject an HTML interface that shows the values of the database entries, and allows them to be set. This approach would then make such settings immune to script updates (as long as the script doesn't overwrite the database values).
Also, this question may also be a beneficial read.

In a Greasemonkey script, how can I target a page by its elements?

I would like to change a page using a Greasemonkey script, but the page is the result of a CGI POST call and thus the URL looks like this:
http://www.example.com/cgi-bin/foo.pl
So obviously I cannot use the #include in the Greasemonkey script, because that URL fits a lot of pages the app can generate.
I could just look for some elements on the page within the script before doing stuff:
if (document.getElementById('someIdentifier')) {
// do changes in here
}
But I was wondering if there is a better, maybe built-in way to do this.
Greasemonkey (and most userscript engines) has no built-in way to target a page by its elements. Your script needs to poll or use mechanisms like Mutation Observers to check for the desired elements.
A handy way to do this is to use the waitForKeyElements() utility, and you still want to use the #include, #exclude, and/or #match directives to narrow down the page firings as much as possible.
Here is a complete Greasemonkey/Tampermonkey script illustrating the process:
// ==UserScript==
// #name _Do something after select posts
// #include http://www.example.com/cgi-bin/foo.pl*
// #require http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js
// #require https://gist.github.com/raw/2625891/waitForKeyElements.js
// #grant GM_addStyle
// ==/UserScript==
/*- The #grant directive is needed to work around a design change
introduced in GM 1.0. It restores the sandbox.
*/
function processTargetElement (jNode) {
//***** YOUR CODE HERE *****
jNode.css ("background", "pink");
}
waitForKeyElements ("#someIdentifier", processTargetElement);

delay or stop loading of google ads

How to tell google syndication not to wait forever to load the ads in case of slow internet connection or otherwise too? Can we fix a time that says okay go and search for 5ms to get ads otherwise don’t delay the load of rest of page.
The YSlow extension for Firebug is great for this sort of thing, it benchmarks your page loading and tells you what's slow, and advises what techniques you can use to improve things.
For example, it gives you advice on where to put your javascript to aid the speed of your site as perceived by the user.
Assuming you mean this is on your site, be sure that your javascript is loaded at the end of the page so your other content can load first
see this blog item "Google Ads Async (asynchronous)" might give you a good starting point for this:
<script type="text/javascript"><!--
// dynamically Load Ads out-of-band
setTimeout((function ()
{
// placeholder for ads
var eleAds = document.createElement("ads");
// dynamic script element
var eleScript = document.createElement("script");
// remember the implementation of document.write function
w = document.write;
// override and replace with our version
document.write = (function(params)
{
// replace our placeholder with real ads
eleAds.innerHTML = params;
// put the old implementation back in place
document.write=w;
});
// setup the ads script element
eleScript.setAttribute("type", "text/javascript");
eleScript.setAttribute("src", "http://pagead2.googlesyndication.com/pagead/show_ads.js");
// add the two elements, causing the ads script to run
document.body.appendChild(eleAds);
document.body.appendChild(eleScript);
}), 1);
//-->
</script>

Resources