Skip to content

Commit 590eff6

Browse files
committed
Manipulation: privatize internal domManip() function
Fixes gh-2225
1 parent 63c1414 commit 590eff6

File tree

1 file changed

+100
-101
lines changed

1 file changed

+100
-101
lines changed

src/manipulation.js

Lines changed: 100 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,101 @@ function fixCloneNodeIssues( src, dest ) {
138138
}
139139
}
140140

141+
function domManip( collection, args, callback, ignored ) {
142+
143+
// Flatten any nested arrays
144+
args = concat.apply( [], args );
145+
146+
var first, node, hasScripts,
147+
scripts, doc, fragment,
148+
i = 0,
149+
l = collection.length,
150+
iNoClone = l - 1,
151+
value = args[0],
152+
isFunction = jQuery.isFunction( value );
153+
154+
// We can't cloneNode fragments that contain checked, in WebKit
155+
if ( isFunction ||
156+
( l > 1 && typeof value === "string" &&
157+
!support.checkClone && rchecked.test( value ) ) ) {
158+
return collection.each(function( index ) {
159+
var self = collection.eq( index );
160+
if ( isFunction ) {
161+
args[0] = value.call( this, index, self.html() );
162+
}
163+
domManip( self, args, callback, ignored );
164+
});
165+
}
166+
167+
if ( l ) {
168+
fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
169+
first = fragment.firstChild;
170+
171+
if ( fragment.childNodes.length === 1 ) {
172+
fragment = first;
173+
}
174+
175+
// Require either new content or an interest in ignored elements to invoke the callback
176+
if ( first || ignored ) {
177+
scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
178+
hasScripts = scripts.length;
179+
180+
// Use the original fragment for the last item
181+
// instead of the first because it can end up
182+
// being emptied incorrectly in certain situations (#8070).
183+
for ( ; i < l; i++ ) {
184+
node = fragment;
185+
186+
if ( i !== iNoClone ) {
187+
node = jQuery.clone( node, true, true );
188+
189+
// Keep references to cloned scripts for later restoration
190+
if ( hasScripts ) {
191+
// Support: Android<4.1, PhantomJS<2
192+
// push.apply(_, arraylike) throws on ancient WebKit
193+
jQuery.merge( scripts, getAll( node, "script" ) );
194+
}
195+
}
196+
197+
callback.call( collection[i], node, i );
198+
}
199+
200+
if ( hasScripts ) {
201+
doc = scripts[ scripts.length - 1 ].ownerDocument;
202+
203+
// Reenable scripts
204+
jQuery.map( scripts, restoreScript );
205+
206+
// Evaluate executable scripts on first document insertion
207+
for ( i = 0; i < hasScripts; i++ ) {
208+
node = scripts[ i ];
209+
if ( rscriptType.test( node.type || "" ) &&
210+
!jQuery._data( node, "globalEval" ) &&
211+
jQuery.contains( doc, node ) ) {
212+
213+
if ( node.src ) {
214+
// Optional AJAX dependency, but won't run scripts if not present
215+
if ( jQuery._evalUrl ) {
216+
jQuery._evalUrl( node.src );
217+
}
218+
} else {
219+
jQuery.globalEval(
220+
( node.text || node.textContent || node.innerHTML || "" )
221+
.replace( rcleanScript, "" )
222+
);
223+
}
224+
}
225+
}
226+
}
227+
228+
// Fix #11809: Avoid leaking memory
229+
fragment = first = null;
230+
}
231+
}
232+
233+
return collection;
234+
}
235+
141236
jQuery.extend({
142237
htmlPrefilter: function( html ) {
143238
return html.replace( rxhtmlTag, "<$1></$2>" );
@@ -266,7 +361,7 @@ jQuery.fn.extend({
266361
},
267362

268363
append: function() {
269-
return this.domManip( arguments, function( elem ) {
364+
return domManip( this, arguments, function( elem ) {
270365
if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
271366
var target = manipulationTarget( this, elem );
272367
target.appendChild( elem );
@@ -275,7 +370,7 @@ jQuery.fn.extend({
275370
},
276371

277372
prepend: function() {
278-
return this.domManip( arguments, function( elem ) {
373+
return domManip( this, arguments, function( elem ) {
279374
if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
280375
var target = manipulationTarget( this, elem );
281376
target.insertBefore( elem, target.firstChild );
@@ -284,15 +379,15 @@ jQuery.fn.extend({
284379
},
285380

286381
before: function() {
287-
return this.domManip( arguments, function( elem ) {
382+
return domManip( this, arguments, function( elem ) {
288383
if ( this.parentNode ) {
289384
this.parentNode.insertBefore( elem, this );
290385
}
291386
});
292387
},
293388

294389
after: function() {
295-
return this.domManip( arguments, function( elem ) {
390+
return domManip( this, arguments, function( elem ) {
296391
if ( this.parentNode ) {
297392
this.parentNode.insertBefore( elem, this.nextSibling );
298393
}
@@ -401,7 +496,7 @@ jQuery.fn.extend({
401496
var ignored = [];
402497

403498
// Make the changes, replacing each non-ignored context element with the new content
404-
return this.domManip( arguments, function( elem ) {
499+
return domManip( this, arguments, function( elem ) {
405500
var parent = this.parentNode;
406501

407502
if ( jQuery.inArray( this, ignored ) < 0 ) {
@@ -417,102 +512,6 @@ jQuery.fn.extend({
417512

418513
detach: function( selector ) {
419514
return this.remove( selector, true );
420-
},
421-
422-
domManip: function( args, callback, ignored ) {
423-
424-
// Flatten any nested arrays
425-
args = concat.apply( [], args );
426-
427-
var first, node, hasScripts,
428-
scripts, doc, fragment,
429-
i = 0,
430-
l = this.length,
431-
set = this,
432-
iNoClone = l - 1,
433-
value = args[0],
434-
isFunction = jQuery.isFunction( value );
435-
436-
// We can't cloneNode fragments that contain checked, in WebKit
437-
if ( isFunction ||
438-
( l > 1 && typeof value === "string" &&
439-
!support.checkClone && rchecked.test( value ) ) ) {
440-
return this.each(function( index ) {
441-
var self = set.eq( index );
442-
if ( isFunction ) {
443-
args[0] = value.call( this, index, self.html() );
444-
}
445-
self.domManip( args, callback, ignored );
446-
});
447-
}
448-
449-
if ( l ) {
450-
fragment = buildFragment( args, this[ 0 ].ownerDocument, false, this, ignored );
451-
first = fragment.firstChild;
452-
453-
if ( fragment.childNodes.length === 1 ) {
454-
fragment = first;
455-
}
456-
457-
// Require either new content or an interest in ignored elements to invoke the callback
458-
if ( first || ignored ) {
459-
scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
460-
hasScripts = scripts.length;
461-
462-
// Use the original fragment for the last item
463-
// instead of the first because it can end up
464-
// being emptied incorrectly in certain situations (#8070).
465-
for ( ; i < l; i++ ) {
466-
node = fragment;
467-
468-
if ( i !== iNoClone ) {
469-
node = jQuery.clone( node, true, true );
470-
471-
// Keep references to cloned scripts for later restoration
472-
if ( hasScripts ) {
473-
// Support: Android<4.1, PhantomJS<2
474-
// push.apply(_, arraylike) throws on ancient WebKit
475-
jQuery.merge( scripts, getAll( node, "script" ) );
476-
}
477-
}
478-
479-
callback.call( this[i], node, i );
480-
}
481-
482-
if ( hasScripts ) {
483-
doc = scripts[ scripts.length - 1 ].ownerDocument;
484-
485-
// Reenable scripts
486-
jQuery.map( scripts, restoreScript );
487-
488-
// Evaluate executable scripts on first document insertion
489-
for ( i = 0; i < hasScripts; i++ ) {
490-
node = scripts[ i ];
491-
if ( rscriptType.test( node.type || "" ) &&
492-
!jQuery._data( node, "globalEval" ) &&
493-
jQuery.contains( doc, node ) ) {
494-
495-
if ( node.src ) {
496-
// Optional AJAX dependency, but won't run scripts if not present
497-
if ( jQuery._evalUrl ) {
498-
jQuery._evalUrl( node.src );
499-
}
500-
} else {
501-
jQuery.globalEval(
502-
( node.text || node.textContent || node.innerHTML || "" )
503-
.replace( rcleanScript, "" )
504-
);
505-
}
506-
}
507-
}
508-
}
509-
510-
// Fix #11809: Avoid leaking memory
511-
fragment = first = null;
512-
}
513-
}
514-
515-
return this;
516515
}
517516
});
518517

0 commit comments

Comments
 (0)