aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichał Gołębiowski-Owczarek <m.goleb@gmail.com>2022-10-10 18:15:34 +0200
committerGitHub <noreply@github.com>2022-10-10 18:15:34 +0200
commitee6e874075ba1fcd8f9e62cd1ee5c04f6518b6d6 (patch)
treeda232f737c7d41c2c200088fddc3284427bc6ed7
parentaa231cd21421503d319ad6068e7df0fb3baa7fea (diff)
downloadjquery-ee6e874075ba1fcd8f9e62cd1ee5c04f6518b6d6.tar.gz
jquery-ee6e874075ba1fcd8f9e62cd1ee5c04f6518b6d6.zip
Manipulation: Extract domManip to a separate file
We've already had `buildFragment` extracted to a separate file long ago. `domManip` is quite a complex & crucial API and so far it has existed within the `manipulation.js` module. Extracting it makes the module shorter and easier to understand. A few comments / messages in tests have also been updated to not suggest there's a public `jQuery.domManip` API - it's been private since 3.0.0. Closes gh-5138
-rw-r--r--src/manipulation.js105
-rw-r--r--src/manipulation/domManip.js109
-rw-r--r--test/unit/ajax.js6
3 files changed, 113 insertions, 107 deletions
diff --git a/src/manipulation.js b/src/manipulation.js
index cad13bd92..d3ee1130f 100644
--- a/src/manipulation.js
+++ b/src/manipulation.js
@@ -1,19 +1,16 @@
import jQuery from "./core.js";
import isAttached from "./core/isAttached.js";
-import flat from "./var/flat.js";
import isIE from "./var/isIE.js";
import push from "./var/push.js";
import access from "./core/access.js";
import rtagName from "./manipulation/var/rtagName.js";
-import rscriptType from "./manipulation/var/rscriptType.js";
import wrapMap from "./manipulation/wrapMap.js";
import getAll from "./manipulation/getAll.js";
+import domManip from "./manipulation/domManip.js";
import setGlobalEval from "./manipulation/setGlobalEval.js";
-import buildFragment from "./manipulation/buildFragment.js";
import dataPriv from "./data/var/dataPriv.js";
import dataUser from "./data/var/dataUser.js";
import acceptData from "./data/var/acceptData.js";
-import DOMEval from "./core/DOMEval.js";
import nodeName from "./core/nodeName.js";
import "./core/init.js";
@@ -38,21 +35,6 @@ function manipulationTarget( elem, content ) {
return elem;
}
-// Replace/restore the type attribute of script elements for safe DOM manipulation
-function disableScript( elem ) {
- elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type;
- return elem;
-}
-function restoreScript( elem ) {
- if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) {
- elem.type = elem.type.slice( 5 );
- } else {
- elem.removeAttribute( "type" );
- }
-
- return elem;
-}
-
function cloneCopyEvent( src, dest ) {
var i, l, type, pdataOld, udataOld, udataCur, events;
@@ -85,91 +67,6 @@ function cloneCopyEvent( src, dest ) {
}
}
-function domManip( collection, args, callback, ignored ) {
-
- // Flatten any nested arrays
- args = flat( args );
-
- var fragment, first, scripts, hasScripts, node, doc,
- i = 0,
- l = collection.length,
- iNoClone = l - 1,
- value = args[ 0 ],
- valueIsFunction = typeof value === "function";
-
- if ( valueIsFunction ) {
- return collection.each( function( index ) {
- var self = collection.eq( index );
- args[ 0 ] = value.call( this, index, self.html() );
- domManip( self, args, callback, ignored );
- } );
- }
-
- if ( l ) {
- fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
- first = fragment.firstChild;
-
- if ( fragment.childNodes.length === 1 ) {
- fragment = first;
- }
-
- // Require either new content or an interest in ignored elements to invoke the callback
- if ( first || ignored ) {
- scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
- hasScripts = scripts.length;
-
- // Use the original fragment for the last item
- // instead of the first because it can end up
- // being emptied incorrectly in certain situations (trac-8070).
- for ( ; i < l; i++ ) {
- node = fragment;
-
- if ( i !== iNoClone ) {
- node = jQuery.clone( node, true, true );
-
- // Keep references to cloned scripts for later restoration
- if ( hasScripts ) {
- jQuery.merge( scripts, getAll( node, "script" ) );
- }
- }
-
- callback.call( collection[ i ], node, i );
- }
-
- if ( hasScripts ) {
- doc = scripts[ scripts.length - 1 ].ownerDocument;
-
- // Reenable scripts
- jQuery.map( scripts, restoreScript );
-
- // Evaluate executable scripts on first document insertion
- for ( i = 0; i < hasScripts; i++ ) {
- node = scripts[ i ];
- if ( rscriptType.test( node.type || "" ) &&
- !dataPriv.access( node, "globalEval" ) &&
- jQuery.contains( doc, node ) ) {
-
- if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) {
-
- // Optional AJAX dependency, but won't run scripts if not present
- if ( jQuery._evalUrl && !node.noModule ) {
- jQuery._evalUrl( node.src, {
- nonce: node.nonce,
- crossOrigin: node.crossOrigin
- }, doc );
- }
- } else {
- DOMEval( node.textContent, node, doc );
- }
- }
- }
- }
- }
- }
-
- return collection;
-}
-
function remove( elem, selector, keepData ) {
var node,
nodes = selector ? jQuery.filter( selector, elem ) : elem,
diff --git a/src/manipulation/domManip.js b/src/manipulation/domManip.js
new file mode 100644
index 000000000..f8dded566
--- /dev/null
+++ b/src/manipulation/domManip.js
@@ -0,0 +1,109 @@
+import jQuery from "../core.js";
+import flat from "../var/flat.js";
+import rscriptType from "./var/rscriptType.js";
+import getAll from "./getAll.js";
+import buildFragment from "./buildFragment.js";
+import dataPriv from "../data/var/dataPriv.js";
+import DOMEval from "../core/DOMEval.js";
+
+// Replace/restore the type attribute of script elements for safe DOM manipulation
+function disableScript( elem ) {
+ elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type;
+ return elem;
+}
+function restoreScript( elem ) {
+ if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) {
+ elem.type = elem.type.slice( 5 );
+ } else {
+ elem.removeAttribute( "type" );
+ }
+
+ return elem;
+}
+
+function domManip( collection, args, callback, ignored ) {
+
+ // Flatten any nested arrays
+ args = flat( args );
+
+ var fragment, first, scripts, hasScripts, node, doc,
+ i = 0,
+ l = collection.length,
+ iNoClone = l - 1,
+ value = args[ 0 ],
+ valueIsFunction = typeof value === "function";
+
+ if ( valueIsFunction ) {
+ return collection.each( function( index ) {
+ var self = collection.eq( index );
+ args[ 0 ] = value.call( this, index, self.html() );
+ domManip( self, args, callback, ignored );
+ } );
+ }
+
+ if ( l ) {
+ fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
+ first = fragment.firstChild;
+
+ if ( fragment.childNodes.length === 1 ) {
+ fragment = first;
+ }
+
+ // Require either new content or an interest in ignored elements to invoke the callback
+ if ( first || ignored ) {
+ scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
+ hasScripts = scripts.length;
+
+ // Use the original fragment for the last item
+ // instead of the first because it can end up
+ // being emptied incorrectly in certain situations (trac-8070).
+ for ( ; i < l; i++ ) {
+ node = fragment;
+
+ if ( i !== iNoClone ) {
+ node = jQuery.clone( node, true, true );
+
+ // Keep references to cloned scripts for later restoration
+ if ( hasScripts ) {
+ jQuery.merge( scripts, getAll( node, "script" ) );
+ }
+ }
+
+ callback.call( collection[ i ], node, i );
+ }
+
+ if ( hasScripts ) {
+ doc = scripts[ scripts.length - 1 ].ownerDocument;
+
+ // Reenable scripts
+ jQuery.map( scripts, restoreScript );
+
+ // Evaluate executable scripts on first document insertion
+ for ( i = 0; i < hasScripts; i++ ) {
+ node = scripts[ i ];
+ if ( rscriptType.test( node.type || "" ) &&
+ !dataPriv.access( node, "globalEval" ) &&
+ jQuery.contains( doc, node ) ) {
+
+ if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) {
+
+ // Optional AJAX dependency, but won't run scripts if not present
+ if ( jQuery._evalUrl && !node.noModule ) {
+ jQuery._evalUrl( node.src, {
+ nonce: node.nonce,
+ crossOrigin: node.crossOrigin
+ }, doc );
+ }
+ } else {
+ DOMEval( node.textContent, node, doc );
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return collection;
+}
+
+export default domManip;
diff --git a/test/unit/ajax.js b/test/unit/ajax.js
index e4d0efca5..05dd7d36c 100644
--- a/test/unit/ajax.js
+++ b/test/unit/ajax.js
@@ -2502,9 +2502,9 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
} );
} );
-//----------- jQuery.domManip()
+//----------- domManip()
- QUnit.test( "trac-11264 - jQuery.domManip() - no side effect because of ajaxSetup or global events", function( assert ) {
+ QUnit.test( "trac-11264 - domManip() - no side effect because of ajaxSetup or global events", function( assert ) {
assert.expect( 1 );
jQuery.ajaxSetup( {
@@ -2558,7 +2558,7 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
);
QUnit.test(
- "trac-11402 - jQuery.domManip() - script in comments are properly evaluated",
+ "trac-11402 - domManip() - script in comments are properly evaluated",
function( assert ) {
assert.expect( 2 );
jQuery( "#qunit-fixture" ).load( baseURL + "cleanScript.html", assert.async() );