I am writing a Greasemonkey user script that should use jQuery and work on Google Chrome and Firefox.
I have seen several examples of how to do this, including very good answers here on SO. And all of them boil down to calling an "injection script" function passing another callback function as parameter.
The code inside that callback function is where the "magic" happens, including access to the jQuery
($
) object.
This solution works fine. But, one of the consequences of using it is that functions defined outside the callback function cannot be invoked from within it:
function doSomethingImportantThatIWantToUnitTest(){ ... }
function with_jquery(callback) {
var script = document.createElement("script");
script.type = "text/javascript";
script.textContent = "(" + callback.toString() + ")(jQuery)";
document.body.appendChild(script);
};
with_jquery(function ($) {
doSomethingImportantThatIWantToUnitTest(); // <---- meh. Not defined!
});
So, I can only use functions defined inside the callback function. But these functions, in turn, cannot be called from outside. In particular, they cannot be called from a unit test, for example, which is very annoying to me.
Is there a way to write Greasemonkey scripts for Chrome and yet unit-test it?
You should be able to pass anything you want into the callback function, including function variables.
var f = function doSomethingImportantThatIWantToUnitTest(){ ... }
function with_jquery(callback) {
var script = document.createElement("script");
script.type = "text/javascript";
script.textContent = "(" + callback.toString() + ")(jQuery,f)";
document.body.appendChild(script);
};
with_jquery(function ($, f) {
f(); // <---- DEFINED!
});
If you have more than a few functions you want to do, and don't want to update the code in several different places, you can just pass in an object or array that has all the functions as object properties or elements in an array.
Although if it were me, I would just define the functions within the scope you are using them.
doSomethingImport...
aka f
is not defined in the scope of the page (that's assumed at )(jQuery,f)
). Mind you: In a Content Script (Chrome), methods defined within a Content Script are not available to injected scripts - Rob W 2012-04-09 20:25