Embed JS functions on a page from Greasemonkey script in Chrome

I have a Greasemonkey script that works fine in Firefox and Opera. However, I struggle to get it working in Chrome. The problem is entering a function on the page that may be called by code from the page. Here is what I am doing so far:

First, I get a reference link to unsafeWindow for Firefox. This allows me to have the same code for FF and Opera (and Chrome, I thought).

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

Then I add a function to the page. This is really a very thin shell that does nothing but call the corresponding function in the context of my GM script:

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

Then in my script:

 setConfigOption = function(newValue) { // do something with it, eg store in localStorage } 

Finally, I add HTML to the page with a link to call the function.

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

To summarize: In Firefox, when a user clicks on this nested link, he makes a function call on unsafeWindow, which then runs a timeout, which calls the corresponding function in the context of my GM script, which then performs the actual processing. (Correct me if I am wrong here.)

In Chrome, I just get the error "Uncaught ReferenceError: setConfigOption not defined". Indeed, entering "window.setConfigOption" into the console gives "undefined". Firebug and the Opera Developer Console have a feature.

Maybe there is another way to do this, but some of my functions call the Flash object on the page, which I believe requires me to have functions in the context of the page.

I quickly looked at the unsafeWindow alternatives on the Greasemonkey wiki, but they all look pretty ugly. Am I completely on the wrong track here, or do I need to study them more closely?

SOLUTION: I followed Max S. 'tips , and now it works in both Firefox and Chrome. Since the functions that I needed to access the page had to go into normal, I moved the entire script page to the page, i.e. It is completely wrapped in a function that he called "main ()".

To make the extra ugliness of this hack a little more bearable, I could at least refuse to use unsafeWindow and wrappedJSObject now.

I have not yet been able to get the content area runner from the wiki Greasemonkey. It should do the same and it seems to execute just fine, but my functions are never available for the <a> elements on the page, for example. I still do not understand why this is so.

+36
javascript google-chrome google-chrome-extension greasemonkey userscripts
Feb 20 '10 at 18:20
source share
4 answers

The only way to contact the code running on the page in Chrome is through the DOM, so you have to use a hack to insert the <script> with your code. Note that this may turn out to be an error if your script should run before everything else on the page.

EDIT: Here the Nice Alert extension does the following:

 function main () { // ... window.alert = function() {/* ... */}; // ... } var script = document.createElement('script'); script.appendChild(document.createTextNode('('+ main +')();')); (document.body || document.head || document.documentElement).appendChild(script); 
+59
Feb 20 '10 at 18:45
source share

I have it:

contentscript.js:

 function injectJs(link) { var scr = document.createElement('script'); scr.type="text/javascript"; scr.src=link; document.getElementsByTagName('head')[0].appendChild(scr) //document.body.appendChild(scr); } injectJs(chrome.extension.getURL('injected.js')); 

injected.js:

 function main() { alert('Hello World!'); } main(); 
+15
Feb 26 '10 at 17:34
source share

I quickly looked at the unsafeWindow alternatives in the Greasemonkey wiki, but they all look pretty ugly. Am I completely on the wrong track here, or do I need to study them more closely?

You should look, because this is only an available option. I would rather use a hack location .

myscript.user.js:

 function myFunc(){ alert('Hello World!'); } location.href="javascript:(function(){" + myFunc + "})()" 

example.com/mypage.html

 <script> myFunc() // Hello World! </script> 

Of course this is ugly. But it works well.




The content reach method mentioned by Max S. is better than location hacking because it is easier to debug.

+4
Feb 20 '10 at 18:54
source share

Other answers force you to use function expressions , import an external file, or use a long, fixed hack .

This answer will add javascript to the page directly from your source code. It will use ECMAScript 6 (ES6) template literals to easily get a multi-line javascript string on a page.

 var script = document.createElement('script'); script.type = "text/javascript"; script.innerHTML = ` function test() { alert(1); } `; document.getElementsByTagName('head')[0].appendChild(script); 

Note the backward marks `` which define the beginning and end of a multi-line string.

+1
Feb 23 '18 at 2:20
source share



All Articles