]> source.dussan.org Git - jquery.git/commitdiff
Core: Fire iframe script in its context, add doc param in globalEval
authorMichał Gołębiowski-Owczarek <m.goleb@gmail.com>
Mon, 10 Feb 2020 18:17:22 +0000 (19:17 +0100)
committerMichał Gołębiowski-Owczarek <m.goleb@gmail.com>
Mon, 10 Feb 2020 18:20:50 +0000 (19:20 +0100)
1. Support passing custom document to jQuery.globalEval; the script will be
   invoked in the context of this document.
2. Fire external scripts appended to iframe contents in that iframe context;
   this was already supported & tested for inline scripts but not for external
   ones.

Fixes gh-4518
Closes gh-4601

(cherry picked from commit 4592595b478be979141ce35c693dbc6b65647173)

src/core.js
src/manipulation.js
src/manipulation/_evalUrl.js
test/data/core/globaleval-context.html [new file with mode: 0644]
test/data/manipulation/set-global-scripttest.js [new file with mode: 0644]
test/data/testinit.js
test/unit/core.js
test/unit/manipulation.js

index f57075ce782394c4356f8c4ed6261a91c209afde..3c8c661bd726ceb39e3acb854be8aeafe1fe9369 100644 (file)
@@ -245,9 +245,10 @@ jQuery.extend( {
                return true;
        },
 
-       // Evaluates a script in a global context
-       globalEval: function( code, options ) {
-               DOMEval( code, { nonce: options && options.nonce } );
+       // Evaluates a script in a provided context; falls back to the global one
+       // if not specified.
+       globalEval: function( code, options, doc ) {
+               DOMEval( code, { nonce: options && options.nonce }, doc );
        },
 
        each: function( obj, callback ) {
index 1026eaf54fed0a409683b5857d99c30260fbe0da..892ab621c86d665b1443570a1ac222c8588466d4 100644 (file)
@@ -201,7 +201,7 @@ function domManip( collection, args, callback, ignored ) {
                                                        if ( jQuery._evalUrl && !node.noModule ) {
                                                                jQuery._evalUrl( node.src, {
                                                                        nonce: node.nonce || node.getAttribute( "nonce" )
-                                                               } );
+                                                               }, doc );
                                                        }
                                                } else {
                                                        DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc );
index 9a4d2ac6fda3abadae7c97fc3dd7a39d7e7e3422..6163b68c4e586a4e567b7862c023e264b8b9240b 100644 (file)
@@ -4,7 +4,7 @@ define( [
 
 "use strict";
 
-jQuery._evalUrl = function( url, options ) {
+jQuery._evalUrl = function( url, options, doc ) {
        return jQuery.ajax( {
                url: url,
 
@@ -22,7 +22,7 @@ jQuery._evalUrl = function( url, options ) {
                        "text script": function() {}
                },
                dataFilter: function( response ) {
-                       jQuery.globalEval( response, options );
+                       jQuery.globalEval( response, options, doc );
                }
        } );
 };
diff --git a/test/data/core/globaleval-context.html b/test/data/core/globaleval-context.html
new file mode 100644 (file)
index 0000000..1b75e3a
--- /dev/null
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+       <head>
+               <meta charset=utf-8 />
+               <title>body</title>
+       </head>
+       <body>
+               <div id="qunit-fixture"></div>
+               <script src="../../jquery.js"></script>
+               <script src="../iframeTest.js"></script>
+               <script>
+                       startIframeTest();
+               </script>
+       </body>
+</html>
diff --git a/test/data/manipulation/set-global-scripttest.js b/test/data/manipulation/set-global-scripttest.js
new file mode 100644 (file)
index 0000000..7fdbf9d
--- /dev/null
@@ -0,0 +1,2 @@
+window.scriptTest = true;
+parent.finishTest();
index 6938fed244af86cc14c3c04d666b66ac64ffd8ac..cfbee6d734bdd37121881f5f7929932ef52092a1 100644 (file)
@@ -262,12 +262,24 @@ this.testIframe = function( title, fileName, func, wrapper ) {
                        args.unshift( assert );
 
                        setTimeout( function() {
+                               var result;
+
                                this.iframeCallback = undefined;
 
-                               func.apply( this, args );
-                               func = function() {};
-                               $iframe.remove();
-                               done();
+                               result = func.apply( this, args );
+
+                               function finish() {
+                                       func = function() {};
+                                       $iframe.remove();
+                                       done();
+                               }
+
+                               // Wait for promises returned by `func`.
+                               if ( result && result.then ) {
+                                       result.then( finish );
+                               } else {
+                                       finish();
+                               }
                        } );
                };
 
index 05ea4337ef2592a5105dd7f2bde9695ba5c948f2..1c3dc73657a790aa5e919195a9418ae241f9a272 100644 (file)
@@ -197,6 +197,19 @@ QUnit.test( "globalEval execution after script injection (#7862)", function( ass
        assert.ok( window.strictEvalTest - now < 500, "Code executed synchronously" );
 } );
 
+testIframe(
+       "globalEval with custom document context",
+       "core/globaleval-context.html",
+       function( assert, framejQuery, frameWindow, frameDocument ) {
+               assert.expect( 2 );
+
+               jQuery.globalEval( "window.scriptTest = true;", {}, frameDocument );
+               assert.ok( !window.scriptTest, "script executed in iframe context" );
+               assert.ok( frameWindow.scriptTest, "script executed in iframe context" );
+       }
+);
+
+
 QUnit.test( "noConflict", function( assert ) {
        assert.expect( 7 );
 
index b7fc95a0a55010ad1a56249cdeede36bc2da15f4..3cf5cf77ef0f467fb217886cd3b1ef6b69438ce0 100644 (file)
@@ -2315,6 +2315,27 @@ testIframe(
        }
 );
 
+testIframe(
+       "domManip executes external scripts in iframes in the iframes' context",
+       "manipulation/scripts-context.html",
+       function( assert, framejQuery, frameWindow, frameDocument ) {
+               assert.expect( 2 );
+
+               Globals.register( "finishTest" );
+
+               return new Promise( function( resolve ) {
+                       window.finishTest = resolve;
+                       jQuery( frameDocument.body ).append(
+                               "<script src='" + url( "manipulation/set-global-scripttest.js" ) + "'></script>" );
+                       assert.ok( !window.scriptTest, "script executed in iframe context" );
+                       assert.ok( frameWindow.scriptTest, "script executed in iframe context" );
+               } );
+       },
+
+       // The AJAX module is needed for jQuery._evalUrl.
+       QUnit[ jQuery.ajax ? "test" : "skip" ]
+);
+
 QUnit.test( "jQuery.clone - no exceptions for object elements #9587", function( assert ) {
 
        assert.expect( 1 );