Is there any way I can get this piece of code to work inside Greasemonkey/Scriptish, or would I have to inject it into the webpage itself?
body = document.getElementsByTagName("body")[0];
fakeConsole = 'window.top._console';
injected = document.getElementById("sandbox") ? true : false;
sandboxframe = injected ? document.getElementsById("sandbox") : document.createElement('iframe');
sandbox = null;
if (!injected) {
body.appendChild(sandboxframe);
sandboxframe.setAttribute('id', 'sandbox');
sandboxframe.setAttribute('style', "display:none")
}
var p = sandboxframe.contentWindow.eval('1 + 1');
console.log(p);
This code does work when using source:
<script type="text/javascript" src="test.js"></script>
But not when using in a Greasemonkey script, I have observed there's some kind of security barrier I'm not quite familiar with and attempted to use unsafeWindow to bypass XPCNativeWrapper.
Please shed some light on this.
Several things:
getElementsById
is not a function.@grant none
directive applies. More on this below.@grant none
is not possible; you will have to "inject" the code. More on this below.eval()
should be avoided as much as possible. eval()
makes performance, maintenance, debugging, and security much harder.In some scenarios, Greasemonkey no longer uses the XPCNativeWrapper
. See the doc for the @grant
directive.
So this means that (1) If your script uses no GM_
functions and (2) the script specifies @grant none
, then your code will run as-is (excepting the getElementsById
typo).
Note that no other scripting engine does this. (For darn good reasons. Greasemonkey's new behavior concerning @grant
, and the sandbox, is controversial at best.)
If you wish to use GM_
functions, then you must inject the iframe code. See the next section.
Scriptish, Sandboxed Greasemonkey, Chrome, etc. all do not handle iframes well from within their respective sandboxes. (See these Q's, for example.)
The only reliable way to run this kind of code from a GM/userscript is to inject it. Like so:
function gmMain () {
body = document.getElementsByTagName("body")[0];
fakeConsole = 'window.top._console';
injected = document.getElementById("sandbox") ? true : false;
sandboxframe = injected ? document.getElementById("sandbox") : document.createElement('iframe');
sandbox = null;
if (!injected) {
body.appendChild(sandboxframe);
sandboxframe.setAttribute('id', 'sandbox');
sandboxframe.setAttribute('style', "display:none")
}
var p = sandboxframe.contentWindow.eval('1 + 1');
console.log(p);
}
addJS_Node (null, null, gmMain);
function addJS_Node (text, s_URL, funcToRun, runOnLoad) {
var D = document;
var scriptNode = D.createElement ('script');
if (runOnLoad) {
scriptNode.addEventListener ("load", runOnLoad, false);
}
scriptNode.type = "text/javascript";
if (text) scriptNode.textContent = text;
if (s_URL) scriptNode.src = s_URL;
if (funcToRun) scriptNode.textContent = '(' + funcToRun.toString() + ')()';
var targ = D.getElementsByTagName ('head')[0] || D.body || D.documentElement;
targ.appendChild (scriptNode);
}