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 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,
|
||||
|
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 );
|
||||
|
||||
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() );
|
||||
|
Loading…
Reference in New Issue
Block a user