mirror of
https://github.com/jquery/jquery.git
synced 2024-11-23 02:54:22 +00:00
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
This commit is contained in:
parent
aa231cd214
commit
ee6e874075
@ -1,19 +1,16 @@
|
|||||||
import jQuery from "./core.js";
|
import jQuery from "./core.js";
|
||||||
import isAttached from "./core/isAttached.js";
|
import isAttached from "./core/isAttached.js";
|
||||||
import flat from "./var/flat.js";
|
|
||||||
import isIE from "./var/isIE.js";
|
import isIE from "./var/isIE.js";
|
||||||
import push from "./var/push.js";
|
import push from "./var/push.js";
|
||||||
import access from "./core/access.js";
|
import access from "./core/access.js";
|
||||||
import rtagName from "./manipulation/var/rtagName.js";
|
import rtagName from "./manipulation/var/rtagName.js";
|
||||||
import rscriptType from "./manipulation/var/rscriptType.js";
|
|
||||||
import wrapMap from "./manipulation/wrapMap.js";
|
import wrapMap from "./manipulation/wrapMap.js";
|
||||||
import getAll from "./manipulation/getAll.js";
|
import getAll from "./manipulation/getAll.js";
|
||||||
|
import domManip from "./manipulation/domManip.js";
|
||||||
import setGlobalEval from "./manipulation/setGlobalEval.js";
|
import setGlobalEval from "./manipulation/setGlobalEval.js";
|
||||||
import buildFragment from "./manipulation/buildFragment.js";
|
|
||||||
import dataPriv from "./data/var/dataPriv.js";
|
import dataPriv from "./data/var/dataPriv.js";
|
||||||
import dataUser from "./data/var/dataUser.js";
|
import dataUser from "./data/var/dataUser.js";
|
||||||
import acceptData from "./data/var/acceptData.js";
|
import acceptData from "./data/var/acceptData.js";
|
||||||
import DOMEval from "./core/DOMEval.js";
|
|
||||||
import nodeName from "./core/nodeName.js";
|
import nodeName from "./core/nodeName.js";
|
||||||
|
|
||||||
import "./core/init.js";
|
import "./core/init.js";
|
||||||
@ -38,21 +35,6 @@ function manipulationTarget( elem, content ) {
|
|||||||
return elem;
|
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 ) {
|
function cloneCopyEvent( src, dest ) {
|
||||||
var i, l, type, pdataOld, udataOld, udataCur, events;
|
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 ) {
|
function remove( elem, selector, keepData ) {
|
||||||
var node,
|
var node,
|
||||||
nodes = selector ? jQuery.filter( selector, elem ) : elem,
|
nodes = selector ? jQuery.filter( selector, elem ) : elem,
|
||||||
|
109
src/manipulation/domManip.js
Normal file
109
src/manipulation/domManip.js
Normal file
@ -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;
|
@ -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 );
|
assert.expect( 1 );
|
||||||
|
|
||||||
jQuery.ajaxSetup( {
|
jQuery.ajaxSetup( {
|
||||||
@ -2558,7 +2558,7 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
|
|||||||
);
|
);
|
||||||
|
|
||||||
QUnit.test(
|
QUnit.test(
|
||||||
"trac-11402 - jQuery.domManip() - script in comments are properly evaluated",
|
"trac-11402 - domManip() - script in comments are properly evaluated",
|
||||||
function( assert ) {
|
function( assert ) {
|
||||||
assert.expect( 2 );
|
assert.expect( 2 );
|
||||||
jQuery( "#qunit-fixture" ).load( baseURL + "cleanScript.html", assert.async() );
|
jQuery( "#qunit-fixture" ).load( baseURL + "cleanScript.html", assert.async() );
|
||||||
|
Loading…
Reference in New Issue
Block a user