I am creating a userscript and in Opera it works like a charm, but in Fire Fox and Chrome it gives the following error:
Error: PunishCalc is not defined
I have the variables (so users can config multiple items in the script) at the top of the script like this:
var LoginFormat = true;
var PunishCalc = true;
var WorldList = true;
var aWerelden = Array();
var TitleTickets = true;
var OverviewLink = true;
var CookieMarker = true;
As you can see, PunishCalc
is actually defined there.
This is the most vital part of the script: it implements jQuery on the page.
function addJQuery(callback)
{
var script = document.createElement("script");
script.setAttribute("src", "http://code.jquery.com/jquery-1.7.2.min.js");
script.addEventListener("load", function()
{
var script = document.createElement("script");
script.textContent = "(" + callback.toString() + ")();";
document.body.appendChild(script);
}, false);
document.body.appendChild(script);
}
function main()
{
// All the code will be in here
}
addJQuery(main);
That leads me to the piece of code that uses the variable:
else if(document.location.href.indexOf("village.php?mode=list") > -1 && PunishCalc === true)
{
// Code here
}
As you can see it just checks if the variable is true or not. That's all it has to do. Does anyone have an idea why it works in Opera but not in Chrome or Firefox?
The whole problem comes from how jQuery is loaded.
We insert a <script>
tag in the page and add a listener to run something when the script is loaded. The code to run is main.toString()
, which is actually every statements of main
, but not the actual function.
Userscripts in Firefox and Chrome are sandboxed, the page context and the script context are completely different. So when the main.toString()
statements are executed, you are not in your userscript scope anymore, but in the current page scope. That is because of the inserted <script>
which executes a code in its context: the current page. There is no PunishCalc
defined here as it is defined in the userscript scope.
To bypass this restriction, put every statements in your main
function.