Take the 2-minute tour ×



var uw = (this.unsafeWindow) ? this.unsafeWindow : window;

Next, I inject a function into the page. It's really just a very thin wrapper that does nothing but invoking the corresponding function in the context of my GM script:

uw.setConfigOption = function(newValue) {
    setTimeout(setConfigOption, 0, newValue);

Then, there's the corresponding function right in my script:

setConfigOption = function(newValue) {
    // do something with it, e.g. store in localStorage

Last, I inject some HTML into the page with a link to invoke the function.

var p = document.createElement('p');
p.innerHTML = '<a href="javascript:setConfigOption(1)">set config option to 1</a>';

To summarize: In Firefox, when the user clicks that injected link, it will execute the function call on the unsafeWindow, which then triggers a timeout that invokes the corresponding function in the context of my GM script, which then does the actual processing. (Correct me if I'm wrong here.)

In Chrome, I just get a "Uncaught ReferenceError: setConfigOption is not defined" error. And indeed, entering "window.setConfigOption" into the console yields an "undefined". In Firebug and the Opera developer console, the function is there.

Maybe there's another way to do this, but a few of my functions are invoked by a Flash object on the page, which I believe makes it necessary that I have functions in the page context.

I took a quick look at the alternatives to unsafeWindow on the Greasemonkey wiki, but they all look pretty ugly. Am I completely on the wrong track here or should I look more closely into these?

RESOLUTION: I followed Max S.' advice and it works in both Firefox and Chrome now. Because the functions I needed to be available to the page had to call back into the regular ones, I moved my whole script to the page, i.e. it is completely wrapped into the function he called 'main()'.

To make the extra uglyness of that hack a little bit more bearable, I could at least drop the usage of unsafeWindow and wrappedJSObject now.

I still haven't managed to get the content scope runner from the Greasemonkey wiki working. It should do the same and it seems to execute just fine, but my functions are never accessible to <a> elements from the page, for example. I haven't yet figured out why that is.

share|improve this question

3 Answers 3

up vote 30 down vote accepted

The only way to communicate with the code running on the page in Chrome is through the DOM, so you'll have to use a hack like inserting a <script> tag with your code. Note that this may prove buggy if your script needs to run before everything else on the page.

EDIT: Here's how the Nice Alert extension does this:

function main () {
  // ...
  // ...

var script = document.createElement('script');
share|improve this answer
I tried the 'content scope runner' (which does exactly that, if I'm not mistaken), and while the functions were available to my script, they didn't seem to be available to the page (e.g. an anchor tag). Do you have any example code or anything you can link to? I'm not very concerned about the order of execution. I can work around that when I manage to call an injected function from the page. :) –  hheimbuerger Feb 20 '10 at 19:37
Order of content script execution can be defined via run_at statement code.google.com/chrome/extensions/content_scripts.html –  NVI Feb 20 '10 at 20:27
re run_at: I'm not writing a Chrome extension, though (and I don't intend to, too much work to maintain two scripts). This is just a Greasemonkey script that I'm trying to make compatible enough so that Chrome can do its 'auto-conversion' of GM scripts to extensions. –  hheimbuerger Feb 20 '10 at 20:32
While your isolated example works for me, I haven't gotten that working in my full script yet. I guess, unlike when using unsafeWindow, I can't call back into functions that are directly in my script now. I guess I'll have to move everything into the page context then. I'll try that tomorrow. –  hheimbuerger Feb 20 '10 at 20:32
@NV: run_at=document_start will probably have problems with inserting the <script> into a DOM that is not yet loaded. @hheimbuerger: yes, wrap all your code into a function that insert it with a script. –  Max Shawabkeh Feb 20 '10 at 20:36

I have this :

contentscript.js :

function injectJs(link) {
var scr = document.createElement('script');


injected.js :

function main() {
     alert('Hello World!');

share|improve this answer
This one's great! Also shortcut for people using jQuery: function injectjs(link) { $('<script type="text/javascript" src="'+link+'"/>').appendTo($('head')); } –  Piotrek Okoński Mar 29 '12 at 0:09


You should look, because it's only available option. I'd prefer to use location hack.


function myFunc(){
  alert('Hello World!');

location.href="javascript:(function(){" + myFunc + "})()"


myFunc() // Hello World!

Sure, it's ugly. But it's working well.

Content Scope Runner method, mentioned by Max S. is better than location hack, because its easier to debug.

share|improve this answer
Could you please post an example of how that can be used to define a function that can be invoked by an anchor or a Flash object? –  hheimbuerger Feb 20 '10 at 19:34
What do you mean "by an anchor"? –  NVI Feb 20 '10 at 20:16
With an <a> tag, as in my example code, e.g. <a href="javascript:setConfigOption(1)">. (I think if this works, it should from the Flash object, too.) –  hheimbuerger Feb 20 '10 at 20:29
myscript.user.js: location.href="javascript:(function(){window.setConfigOption=function(){ /* ... */ }})()" –  NVI Feb 20 '10 at 20:32
I guess that would work too, but I went for Max S.' content scope runner-like approach for now. Thanks for your help! –  hheimbuerger Feb 21 '10 at 14:08

Your Answer


