Controlling userscripts in sub windows
Sometimes a (top-level) userscript will open various URLs in sub-windows. As windows, the same or a different userscript may apply to them. This section describes ways in which a top-level userscript can control whether or how userscripts are to be run on the sub-windows.
There are four ways to open sub-windows.
Opening a separate window:
window.open(url name, features, replaces);
Opening a new tab:
GM_openInTab(url);
Setting the .src of a <frame> or <iframe> in the document. In a simple case this may consist of adding a .src bound <iframe> to the document.
var ifr = document.createElement("iframe");
ifr.src = "http://example.com/";
document.body.appendChild(ifr);
[edit] Passing parameters in the URL hash (#) field.
URLs (really URIs) may contain a terminal text field that is marked with a hash character (#).
The # and following characters can often be accessed via the property .hash, e.g. document.location.hash or a.href.hash.
The default browser behavior for opening a URL that contains a .hash field is to use it to determine initial scrolling into the page – to some DOM node with an .id or .name equal to the .hash.
For example the URL http://wiki.greasespot.net/Main_Page#Getting_Started should cause the retrieved page to be displayed starting with the 'Getting_Started' header.
However no browsers complain if .hash cannot be found as a .id or .name.
This means that .hash can be used to pass parameters to control user scripts on sub-windows.
Communication at the level of URL text strings has no security constraints (such as common domain) on its usage.
In the simplest case, a user script can pass a .hash to interact with the @include or @exclude metadata headers of a co-developed user script that might apply to a sub-window.
For example, to prevent a sub-user script from running its header could contain
// @exclude *#noGrease
which would exclude it from applying to any sub-window that was opened via a URL appended with ‘#noGrease’.
In the more general case, the .hash can encode information to tell sub-user scripts specific things to do.
Often the user scripts processing a domain for some particular task are consolidated – i.e. there is just one user script that applies to both the top-level window and any opened sub-windows.
Such a script can decide what to do by examining document.location.hash.
For example a consolidated user script might contain code like:
var hash = document.location.hash;
if (!hash) return doTopLevel();
var hashFunc = ({
"#noGrease" : function(){},
"#case1" : doCase1,
"#case2" : doCase2
})[hash];
if (hashFunc) return hashFunc();
When passing arbitrary parameters (including such as URLs), they may need to be encoded so the URL is valid. For example a consolidated user script named 'script8' might contain code like:
// top window passing parameters to a sub-window var hash = "#script8" + encodeURIComponent(params);
and
// sub-window accessing parameters
if(document.location.hash.match(/^\#script8(.*)/)) {
params = decodeURIComponent(RegExp.$1);
}
NOTE: The .search field (?) of a URL can often be used in ways similar to the .hash field.
In general this is a bad idea because the .search field is sent to the remote server, which may negatively alter the behavior of said page.