Hello.
I create a custom script for FireFox (GreaseMonkey plugin). The functions that I declared in UserJS are not available in the page context. For example.

// ==UserScript== // @include * // ==/UserScript== function go(){ alert("Okey"); }; body=document.getElementsByTagName("body")[0]; span=document.createElement("span"); span.innerHTML="<INPUT type=button onclick=\"javascript:go();\" value=click />"; body.appendChild(span); 

When clicking on the button in the console, the error falls

 go is not defined 

That is, there is no such function in the context of the page; it exists only in the context of the GreaseMonkey extension.
How can I solve this problem while maintaining UserJS cross-browser compatibility? I don't want to write something like

 if (browser=="firefox"){ span.innerHTML="Вариант для FireFox"; } else { span.innerHTML="Вариант для Chrome, Opera, Safari"; }; 

    2 answers 2

    Firstly, unsafeWindow is not available in all browsers, and secondly, it also has a bunch of restrictions. To get full cross-browser access to the current page, I usually did this:

     var extension = function() { // We're free! // Теперь, к примеру, мы можем полноценно юзать jQuery, если он был подключен $('.some-selector').click(/* ... */); } // Выбираемся из песочницы var script = document.createElement("script"); script.textContent = '(' + extension.toString() + ')();'; document.getElementsByTagName("head")[0].appendChild(script); 
    • Not bad, perhaps I will. - ReinRaus
    • The option is excellent, but for 100% compatibility it is better to do so. script.textContent = extension.toString (). replace (/^.?? \ {| \}. *? $ / g, ''); - ReinRaus
    • Not interesting, boring trifle - instead of document.getElementsByTagName ("head") [0] You can document.head - Zowie
    • I caught a strange console.log bug ((function () {re1 = / Vanya /; txt1 = 'Vanya'}). ToString ()); Result function () {re1 = / 20 = O /; txt1 = "\ u0432 \ u0430 \ u043D \ u044F"; } That is, the regulars are decoded incorrectly if they contain Cyrillic. - ReinRaus
    • In the first case, you can probably get around this: rel = new RegExp ('vanya'); And the second option is quite valid: console.log ("\ u0432 \ u0430 \ u043D \ u044F"); // "Vanya" PS And this is in which browser? - Ilya Pirogov

    GM executes the user script in its own global context, and the page context is available as an unsafeWindow object. Respectively,

     unsafeWindow.foo = function () { alert( 'Userscripts are good, mmkay?' ); } 

    There is also the key metadata @unwrap , which prohibits wrapping userscript into an anonymous function.

    • one
      Be sure to read the links! - karmadro4
    • You're right. I did just that, but I have a lot of functions that need to be added through innerHTML, in the end it turns out the need to make a lot of unsafeWindow assignments. You can of course wrap all these functions in a class, but then you have to do all the calls through the class name. This is a solution, of course, but I don’t really like it. - ReinRaus