Content Scope Runner: Difference between revisions

From GreaseSpot Wiki
Jump to navigationJump to search
m (Reverted edits by 159.18.221.197 (Talk) to last revision by Arantius)
(This version actually works.)
Line 1: Line 1:
An extension of the [[Content Script Injection]] technique, this snippet automatically runs the ''entire'' user script in the content scope.
An extension of the [[Content Script Injection]] technique, this snippet automatically runs the ''entire'' user script in the content scope.


<pre class='sample'>
<pre class='sample'>if(typeof __PAGE_SCOPE_RUN__ == 'undefined') {
(function page_scope_runner() {
  (function page_scope_runner() {
  if ('undefined' == typeof __PAGE_SCOPE_RUN__) {
      // Grab the anonymous function the entire script is wrapped in
    // If we're _not_ already running in the page, grab the full source
      var my_src = page_scope_runner.caller.toString();
    // of this script.
     
    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
      // 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).
      // 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.textContent = "const __PAGE_SCOPE_RUN__ = true;\n" + my_src;
      script.appendChild(document.createTextNode(safe_src));


    // Insert the script node into the page, so it will run, and immediately
      // Insert the script node into the page, so it will run, and immediately
    // remove it to clean up.
      // remove it to clean up.
    document.documentElement.appendChild(script);
      document.documentElement.appendChild(script);
    document.documentElement.removeChild(script);
      document.documentElement.removeChild(script);
 
  })();
    // Stop running, because we know Greasemonkey actually runs us in
  return;
    // an anonymous wrapper.
}</pre>
    return;
  }
})();
</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 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.
Line 30: Line 29:
You also will, of course, not have access to any of the [[API]]s.
You also will, of course, not have access to any of the [[API]]s.


<!-- This still needs work.
== @require ==
== @require ==


Line 36: Line 36:


  <nowiki>// @require http://userscripts.org/scripts/source/68059.user.js</nowiki>
  <nowiki>// @require http://userscripts.org/scripts/source/68059.user.js</nowiki>
-->


[[Category:Coding Tips:Interacting With The Page]]
[[Category:Coding Tips:Interacting With The Page]]
[[Category:@require Library]]
[[Category:@require Library]]

Revision as of 06:22, 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() {
      // 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');
      script.setAttribute("type", "application/javascript");
      script.appendChild(document.createTextNode(safe_src));

      // Insert the script node into the page, so it will run, and immediately
      // remove it to clean up.
      document.documentElement.appendChild(script);
      document.documentElement.removeChild(script);
   })();
   return;
}

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. 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.