Content Scope Runner: Difference between revisions

From GreaseSpot Wiki
Jump to navigationJump to search
(This version actually works.)
(Much cleaner. Now with explanation!)
Line 3: Line 3:
<pre class='sample'>if(typeof __PAGE_SCOPE_RUN__ == 'undefined') {
<pre class='sample'>if(typeof __PAGE_SCOPE_RUN__ == 'undefined') {
   (function page_scope_runner() {
   (function page_scope_runner() {
      // Grab the anonymous function the entire script is wrapped in
      var my_src = page_scope_runner.caller.toString();
     
      // Alter the script's environment to prevent unbounded recursion...
      var safe_source = "var __PAGE_SCOPE_RUN__ = 'yes';\n";
      // ...and then allow it to call our anonymous function.
      safeSource += "(" + my_src + ")();\n";
      // Create a script node holding this script, plus a marker that lets us
      // know we are running in the page scope (not the Greasemonkey sandbox).
       var script = document.createElement('script');
       var script = document.createElement('script');
       script.setAttribute("type", "application/javascript");
       script.setAttribute("type", "application/javascript");
       script.appendChild(document.createTextNode(safe_src));
       script.textContent = "(function() { var __PAGE_SCOPE_RUN__ = 'yes'; (" + page_scope_runner.caller.toString() + ")(); })();";
 
      // Insert the script node into the page, so it will run, and immediately
      // remove it to clean up.
       document.documentElement.appendChild(script);
       document.documentElement.appendChild(script);
       document.documentElement.removeChild(script);
       document.documentElement.removeChild(script);
Line 25: Line 12:
}</pre>
}</pre>


As long as this is the ''first'' piece of code in your script, it will stop execution of the remainder of the script, and re-start execution completely within the content scope.
As soon as execution reaches this code, the entire script will be injected into the page and re-run. Thus you need not worry about any of the [[security]] restrictions from [[XPCNativeWrappers]] in the Greasemonkey [[sandbox]]. You also will, of course, not have access to any of the [[API]]s.
Thus you need not worry about any of the [[security]] restrictions from [[XPCNativeWrappers]] in the Greasemonkey [[sandbox]].
 
You also will, of course, not have access to any of the [[API]]s.
== Explanation ==
 
The code block first checks to see if it is being run inside the page by looking for a marker it knows about. If the marker is not present, the block creates and injects a script element that starts by setting the aforementioned marker variable and finishes by executing the text of the userscript. Finally, the block calls `return`, ending execution.


<!-- This still needs work.
<!-- This still needs work.

Revision as of 06:39, 25 July 2010

An extension of the Content Script Injection technique, this snippet automatically runs the entire user script in the content scope.

if(typeof __PAGE_SCOPE_RUN__ == 'undefined') {
   (function page_scope_runner() {
      var script = document.createElement('script');
      script.setAttribute("type", "application/javascript");
      script.textContent = "(function() { var __PAGE_SCOPE_RUN__ = 'yes'; (" + page_scope_runner.caller.toString() + ")(); })();";
      document.documentElement.appendChild(script);
      document.documentElement.removeChild(script);
   })();
   return;
}

As soon as execution reaches this code, the entire script will be injected into the page and re-run. Thus you need not worry about any of the security restrictions from XPCNativeWrappers in the Greasemonkey sandbox. You also will, of course, not have access to any of the APIs.

Explanation

The code block first checks to see if it is being run inside the page by looking for a marker it knows about. If the marker is not present, the block creates and injects a script element that starts by setting the aforementioned marker variable and finishes by executing the text of the userscript. Finally, the block calls `return`, ending execution.