8 "./manipulation/var/rcheckableType",
9 "./manipulation/support",
16 ], function( jQuery
, strundefined
, concat
, push
, deletedIds
, access
, rcheckableType
, support
) {
18 function createSafeFragment( document
) {
19 var list
= nodeNames
.split( "|" ),
20 safeFrag
= document
.createDocumentFragment();
22 if ( safeFrag
.createElement
) {
23 while ( list
.length
) {
24 safeFrag
.createElement(
32 var nodeNames
= "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" +
33 "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",
34 rinlinejQuery
= / jQuery
\d
+="(?:null|\d+)"/g
,
35 rnoshimcache
= new RegExp("<(?:" + nodeNames
+ ")[\\s/>]", "i"),
36 rleadingWhitespace
= /^\s+/,
37 rxhtmlTag
= /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
38 rtagName
= /<([\w:]+)/,
41 rnoInnerhtml
= /<(?:script|style|link)/i,
42 // checked="checked" or checked
43 rchecked
= /checked\s*(?:[^=]|=\s*.checked.)/i,
44 rscriptType
= /^$|\/(?:java|ecma)script/i,
45 rscriptTypeMasked
= /^true\/(.*)/,
46 rcleanScript
= /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,
48 // We have to close these tags to support XHTML (#13200)
50 option
: [ 1, "<select multiple='multiple'>", "</select>" ],
51 legend
: [ 1, "<fieldset>", "</fieldset>" ],
52 area
: [ 1, "<map>", "</map>" ],
53 param
: [ 1, "<object>", "</object>" ],
54 thead
: [ 1, "<table>", "</table>" ],
55 tr
: [ 2, "<table><tbody>", "</tbody></table>" ],
56 col
: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
57 td
: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
59 // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,
60 // unless wrapped in a div with non-breaking characters in front of it.
61 _default
: support
.htmlSerialize
? [ 0, "", "" ] : [ 1, "X<div>", "</div>" ]
63 safeFragment
= createSafeFragment( document
),
64 fragmentDiv
= safeFragment
.appendChild( document
.createElement("div") );
66 wrapMap
.optgroup
= wrapMap
.option
;
67 wrapMap
.tbody
= wrapMap
.tfoot
= wrapMap
.colgroup
= wrapMap
.caption
= wrapMap
.thead
;
68 wrapMap
.th
= wrapMap
.td
;
70 function getAll( context
, tag
) {
73 found
= typeof context
.getElementsByTagName
!== strundefined
? context
.getElementsByTagName( tag
|| "*" ) :
74 typeof context
.querySelectorAll
!== strundefined
? context
.querySelectorAll( tag
|| "*" ) :
78 for ( found
= [], elems
= context
.childNodes
|| context
; (elem
= elems
[i
]) != null; i
++ ) {
79 if ( !tag
|| jQuery
.nodeName( elem
, tag
) ) {
82 jQuery
.merge( found
, getAll( elem
, tag
) );
87 return tag
=== undefined || tag
&& jQuery
.nodeName( context
, tag
) ?
88 jQuery
.merge( [ context
], found
) :
92 // Used in buildFragment, fixes the defaultChecked property
93 function fixDefaultChecked( elem
) {
94 if ( rcheckableType
.test( elem
.type
) ) {
95 elem
.defaultChecked
= elem
.checked
;
100 // Manipulating tables requires a tbody
101 function manipulationTarget( elem
, content
) {
102 return jQuery
.nodeName( elem
, "table" ) &&
103 jQuery
.nodeName( content
.nodeType
!== 11 ? content
: content
.firstChild
, "tr" ) ?
105 elem
.getElementsByTagName("tbody")[0] ||
106 elem
.appendChild( elem
.ownerDocument
.createElement("tbody") ) :
110 // Replace/restore the type attribute of script elements for safe DOM manipulation
111 function disableScript( elem
) {
112 elem
.type
= (jQuery
.find
.attr( elem
, "type" ) !== null) + "/" + elem
.type
;
115 function restoreScript( elem
) {
116 var match
= rscriptTypeMasked
.exec( elem
.type
);
118 elem
.type
= match
[1];
120 elem
.removeAttribute("type");
125 // Mark scripts as having already been evaluated
126 function setGlobalEval( elems
, refElements
) {
129 for ( ; (elem
= elems
[i
]) != null; i
++ ) {
130 jQuery
._data( elem
, "globalEval", !refElements
|| jQuery
._data( refElements
[i
], "globalEval" ) );
134 function cloneCopyEvent( src
, dest
) {
136 if ( dest
.nodeType
!== 1 || !jQuery
.hasData( src
) ) {
141 oldData
= jQuery
._data( src
),
142 curData
= jQuery
._data( dest
, oldData
),
143 events
= oldData
.events
;
146 delete curData
.handle
;
149 for ( type
in events
) {
150 for ( i
= 0, l
= events
[ type
].length
; i
< l
; i
++ ) {
151 jQuery
.event
.add( dest
, type
, events
[ type
][ i
] );
156 // make the cloned public data object a copy from the original
157 if ( curData
.data
) {
158 curData
.data
= jQuery
.extend( {}, curData
.data
);
162 function fixCloneNodeIssues( src
, dest
) {
163 var nodeName
, e
, data
;
165 // We do not need to do anything for non-Elements
166 if ( dest
.nodeType
!== 1 ) {
170 nodeName
= dest
.nodeName
.toLowerCase();
172 // IE6-8 copies events bound via attachEvent when using cloneNode.
173 if ( !support
.noCloneEvent
&& dest
[ jQuery
.expando
] ) {
174 data
= jQuery
._data( dest
);
176 for ( e
in data
.events
) {
177 jQuery
.removeEvent( dest
, e
, data
.handle
);
180 // Event data gets referenced instead of copied if the expando gets copied too
181 dest
.removeAttribute( jQuery
.expando
);
184 // IE blanks contents when cloning scripts, and tries to evaluate newly-set text
185 if ( nodeName
=== "script" && dest
.text
!== src
.text
) {
186 disableScript( dest
).text
= src
.text
;
187 restoreScript( dest
);
189 // IE6-10 improperly clones children of object elements using classid.
190 // IE10 throws NoModificationAllowedError if parent is null, #12132.
191 } else if ( nodeName
=== "object" ) {
192 if ( dest
.parentNode
) {
193 dest
.outerHTML
= src
.outerHTML
;
196 // This path appears unavoidable for IE9. When cloning an object
197 // element in IE9, the outerHTML strategy above is not sufficient.
198 // If the src has innerHTML and the destination does not,
199 // copy the src.innerHTML into the dest.innerHTML. #10324
200 if ( support
.html5Clone
&& ( src
.innerHTML
&& !jQuery
.trim(dest
.innerHTML
) ) ) {
201 dest
.innerHTML
= src
.innerHTML
;
204 } else if ( nodeName
=== "input" && rcheckableType
.test( src
.type
) ) {
205 // IE6-8 fails to persist the checked state of a cloned checkbox
206 // or radio button. Worse, IE6-7 fail to give the cloned element
207 // a checked appearance if the defaultChecked value isn't also set
209 dest
.defaultChecked
= dest
.checked
= src
.checked
;
211 // IE6-7 get confused and end up setting the value of a cloned
212 // checkbox/radio button to an empty string instead of "on"
213 if ( dest
.value
!== src
.value
) {
214 dest
.value
= src
.value
;
217 // IE6-8 fails to return the selected option to the default selected
218 // state when cloning options
219 } else if ( nodeName
=== "option" ) {
220 dest
.defaultSelected
= dest
.selected
= src
.defaultSelected
;
222 // IE6-8 fails to set the defaultValue to the correct value when
223 // cloning other types of input fields
224 } else if ( nodeName
=== "input" || nodeName
=== "textarea" ) {
225 dest
.defaultValue
= src
.defaultValue
;
230 clone: function( elem
, dataAndEvents
, deepDataAndEvents
) {
231 var destElements
, node
, clone
, i
, srcElements
,
232 inPage
= jQuery
.contains( elem
.ownerDocument
, elem
);
234 if ( support
.html5Clone
|| jQuery
.isXMLDoc(elem
) || !rnoshimcache
.test( "<" + elem
.nodeName
+ ">" ) ) {
235 clone
= elem
.cloneNode( true );
237 // IE<=8 does not properly clone detached, unknown element nodes
239 fragmentDiv
.innerHTML
= elem
.outerHTML
;
240 fragmentDiv
.removeChild( clone
= fragmentDiv
.firstChild
);
243 if ( (!support
.noCloneEvent
|| !support
.noCloneChecked
) &&
244 (elem
.nodeType
=== 1 || elem
.nodeType
=== 11) && !jQuery
.isXMLDoc(elem
) ) {
246 // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
247 destElements
= getAll( clone
);
248 srcElements
= getAll( elem
);
250 // Fix all IE cloning issues
251 for ( i
= 0; (node
= srcElements
[i
]) != null; ++i
) {
252 // Ensure that the destination node is not null; Fixes #9587
253 if ( destElements
[i
] ) {
254 fixCloneNodeIssues( node
, destElements
[i
] );
259 // Copy the events from the original to the clone
260 if ( dataAndEvents
) {
261 if ( deepDataAndEvents
) {
262 srcElements
= srcElements
|| getAll( elem
);
263 destElements
= destElements
|| getAll( clone
);
265 for ( i
= 0; (node
= srcElements
[i
]) != null; i
++ ) {
266 cloneCopyEvent( node
, destElements
[i
] );
269 cloneCopyEvent( elem
, clone
);
273 // Preserve script evaluation history
274 destElements
= getAll( clone
, "script" );
275 if ( destElements
.length
> 0 ) {
276 setGlobalEval( destElements
, !inPage
&& getAll( elem
, "script" ) );
279 destElements
= srcElements
= node
= null;
281 // Return the cloned set
285 buildFragment: function( elems
, context
, scripts
, selection
) {
286 var j
, elem
, contains
,
287 tmp
, tag
, tbody
, wrap
,
290 // Ensure a safe fragment
291 safe
= createSafeFragment( context
),
296 for ( ; i
< l
; i
++ ) {
299 if ( elem
|| elem
=== 0 ) {
301 // Add nodes directly
302 if ( jQuery
.type( elem
) === "object" ) {
303 jQuery
.merge( nodes
, elem
.nodeType
? [ elem
] : elem
);
305 // Convert non-html into a text node
306 } else if ( !rhtml
.test( elem
) ) {
307 nodes
.push( context
.createTextNode( elem
) );
309 // Convert html into DOM nodes
311 tmp
= tmp
|| safe
.appendChild( context
.createElement("div") );
313 // Deserialize a standard representation
314 tag
= (rtagName
.exec( elem
) || [ "", "" ])[ 1 ].toLowerCase();
315 wrap
= wrapMap
[ tag
] || wrapMap
._default
;
317 tmp
.innerHTML
= wrap
[1] + elem
.replace( rxhtmlTag
, "<$1></$2>" ) + wrap
[2];
319 // Descend through wrappers to the right content
325 // Manually add leading whitespace removed by IE
326 if ( !support
.leadingWhitespace
&& rleadingWhitespace
.test( elem
) ) {
327 nodes
.push( context
.createTextNode( rleadingWhitespace
.exec( elem
)[0] ) );
330 // Remove IE's autoinserted <tbody> from table fragments
331 if ( !support
.tbody
) {
333 // String was a <table>, *may* have spurious <tbody>
334 elem
= tag
=== "table" && !rtbody
.test( elem
) ?
337 // String was a bare <thead> or <tfoot>
338 wrap
[1] === "<table>" && !rtbody
.test( elem
) ?
342 j
= elem
&& elem
.childNodes
.length
;
344 if ( jQuery
.nodeName( (tbody
= elem
.childNodes
[j
]), "tbody" ) && !tbody
.childNodes
.length
) {
345 elem
.removeChild( tbody
);
350 jQuery
.merge( nodes
, tmp
.childNodes
);
352 // Fix #12392 for WebKit and IE > 9
353 tmp
.textContent
= "";
355 // Fix #12392 for oldIE
356 while ( tmp
.firstChild
) {
357 tmp
.removeChild( tmp
.firstChild
);
360 // Remember the top-level container for proper cleanup
361 tmp
= safe
.lastChild
;
366 // Fix #11356: Clear elements from fragment
368 safe
.removeChild( tmp
);
371 // Reset defaultChecked for any radios and checkboxes
372 // about to be appended to the DOM in IE 6/7 (#8060)
373 if ( !support
.appendChecked
) {
374 jQuery
.grep( getAll( nodes
, "input" ), fixDefaultChecked
);
378 while ( (elem
= nodes
[ i
++ ]) ) {
380 // #4087 - If origin and destination elements are the same, and this is
381 // that element, do not do anything
382 if ( selection
&& jQuery
.inArray( elem
, selection
) !== -1 ) {
386 contains
= jQuery
.contains( elem
.ownerDocument
, elem
);
388 // Append to fragment
389 tmp
= getAll( safe
.appendChild( elem
), "script" );
391 // Preserve script evaluation history
393 setGlobalEval( tmp
);
396 // Capture executables
399 while ( (elem
= tmp
[ j
++ ]) ) {
400 if ( rscriptType
.test( elem
.type
|| "" ) ) {
401 scripts
.push( elem
);
412 cleanData: function( elems
, /* internal */ acceptData
) {
413 var elem
, type
, id
, data
,
415 internalKey
= jQuery
.expando
,
416 cache
= jQuery
.cache
,
417 deleteExpando
= support
.deleteExpando
,
418 special
= jQuery
.event
.special
;
420 for ( ; (elem
= elems
[i
]) != null; i
++ ) {
421 if ( acceptData
|| jQuery
.acceptData( elem
) ) {
423 id
= elem
[ internalKey
];
424 data
= id
&& cache
[ id
];
428 for ( type
in data
.events
) {
429 if ( special
[ type
] ) {
430 jQuery
.event
.remove( elem
, type
);
432 // This is a shortcut to avoid jQuery.event.remove's overhead
434 jQuery
.removeEvent( elem
, type
, data
.handle
);
439 // Remove cache only if it was not already removed by jQuery.event.remove
444 // IE does not allow us to delete expando properties from nodes,
445 // nor does it have a removeAttribute function on Document nodes;
446 // we must handle all of these cases
447 if ( deleteExpando
) {
448 delete elem
[ internalKey
];
450 } else if ( typeof elem
.removeAttribute
!== strundefined
) {
451 elem
.removeAttribute( internalKey
);
454 elem
[ internalKey
] = null;
457 deletedIds
.push( id
);
466 text: function( value
) {
467 return access( this, function( value
) {
468 return value
=== undefined ?
469 jQuery
.text( this ) :
470 this.empty().append( ( this[0] && this[0].ownerDocument
|| document
).createTextNode( value
) );
471 }, null, value
, arguments
.length
);
475 return this.domManip( arguments
, function( elem
) {
476 if ( this.nodeType
=== 1 || this.nodeType
=== 11 || this.nodeType
=== 9 ) {
477 var target
= manipulationTarget( this, elem
);
478 target
.appendChild( elem
);
483 prepend: function() {
484 return this.domManip( arguments
, function( elem
) {
485 if ( this.nodeType
=== 1 || this.nodeType
=== 11 || this.nodeType
=== 9 ) {
486 var target
= manipulationTarget( this, elem
);
487 target
.insertBefore( elem
, target
.firstChild
);
493 return this.domManip( arguments
, function( elem
) {
494 if ( this.parentNode
) {
495 this.parentNode
.insertBefore( elem
, this );
501 return this.domManip( arguments
, function( elem
) {
502 if ( this.parentNode
) {
503 this.parentNode
.insertBefore( elem
, this.nextSibling
);
508 remove: function( selector
, keepData
/* Internal Use Only */ ) {
510 elems
= selector
? jQuery
.filter( selector
, this ) : this,
513 for ( ; (elem
= elems
[i
]) != null; i
++ ) {
515 if ( !keepData
&& elem
.nodeType
=== 1 ) {
516 jQuery
.cleanData( getAll( elem
) );
519 if ( elem
.parentNode
) {
520 if ( keepData
&& jQuery
.contains( elem
.ownerDocument
, elem
) ) {
521 setGlobalEval( getAll( elem
, "script" ) );
523 elem
.parentNode
.removeChild( elem
);
534 for ( ; (elem
= this[i
]) != null; i
++ ) {
535 // Remove element nodes and prevent memory leaks
536 if ( elem
.nodeType
=== 1 ) {
537 jQuery
.cleanData( getAll( elem
, false ) );
540 // Remove any remaining nodes
541 while ( elem
.firstChild
) {
542 elem
.removeChild( elem
.firstChild
);
545 // If this is a select, ensure that it displays empty (#12336)
547 if ( elem
.options
&& jQuery
.nodeName( elem
, "select" ) ) {
548 elem
.options
.length
= 0;
555 clone: function( dataAndEvents
, deepDataAndEvents
) {
556 dataAndEvents
= dataAndEvents
== null ? false : dataAndEvents
;
557 deepDataAndEvents
= deepDataAndEvents
== null ? dataAndEvents
: deepDataAndEvents
;
559 return this.map(function() {
560 return jQuery
.clone( this, dataAndEvents
, deepDataAndEvents
);
564 html: function( value
) {
565 return access( this, function( value
) {
566 var elem
= this[ 0 ] || {},
570 if ( value
=== undefined ) {
571 return elem
.nodeType
=== 1 ?
572 elem
.innerHTML
.replace( rinlinejQuery
, "" ) :
576 // See if we can take a shortcut and just use innerHTML
577 if ( typeof value
=== "string" && !rnoInnerhtml
.test( value
) &&
578 ( support
.htmlSerialize
|| !rnoshimcache
.test( value
) ) &&
579 ( support
.leadingWhitespace
|| !rleadingWhitespace
.test( value
) ) &&
580 !wrapMap
[ (rtagName
.exec( value
) || [ "", "" ])[ 1 ].toLowerCase() ] ) {
582 value
= value
.replace( rxhtmlTag
, "<$1></$2>" );
585 for (; i
< l
; i
++ ) {
586 // Remove element nodes and prevent memory leaks
587 elem
= this[i
] || {};
588 if ( elem
.nodeType
=== 1 ) {
589 jQuery
.cleanData( getAll( elem
, false ) );
590 elem
.innerHTML
= value
;
596 // If using innerHTML throws an exception, use the fallback method
601 this.empty().append( value
);
603 }, null, value
, arguments
.length
);
606 replaceWith: function() {
607 var arg
= arguments
[ 0 ];
609 // Make the changes, replacing each context element with the new content
610 this.domManip( arguments
, function( elem
) {
611 arg
= this.parentNode
;
613 jQuery
.cleanData( getAll( this ) );
616 arg
.replaceChild( elem
, this );
620 // Force removal if there was no new content (e.g., from empty arguments)
621 return arg
&& (arg
.length
|| arg
.nodeType
) ? this : this.remove();
624 detach: function( selector
) {
625 return this.remove( selector
, true );
628 domManip: function( args
, callback
) {
630 // Flatten any nested arrays
631 args
= concat
.apply( [], args
);
633 var first
, node
, hasScripts
,
634 scripts
, doc
, fragment
,
640 isFunction
= jQuery
.isFunction( value
);
642 // We can't cloneNode fragments that contain checked, in WebKit
644 ( l
> 1 && typeof value
=== "string" &&
645 !support
.checkClone
&& rchecked
.test( value
) ) ) {
646 return this.each(function( index
) {
647 var self
= set.eq( index
);
649 args
[0] = value
.call( this, index
, self
.html() );
651 self
.domManip( args
, callback
);
656 fragment
= jQuery
.buildFragment( args
, this[ 0 ].ownerDocument
, false, this );
657 first
= fragment
.firstChild
;
659 if ( fragment
.childNodes
.length
=== 1 ) {
664 scripts
= jQuery
.map( getAll( fragment
, "script" ), disableScript
);
665 hasScripts
= scripts
.length
;
667 // Use the original fragment for the last item instead of the first because it can end up
668 // being emptied incorrectly in certain situations (#8070).
669 for ( ; i
< l
; i
++ ) {
672 if ( i
!== iNoClone
) {
673 node
= jQuery
.clone( node
, true, true );
675 // Keep references to cloned scripts for later restoration
677 jQuery
.merge( scripts
, getAll( node
, "script" ) );
681 callback
.call( this[i
], node
, i
);
685 doc
= scripts
[ scripts
.length
- 1 ].ownerDocument
;
688 jQuery
.map( scripts
, restoreScript
);
690 // Evaluate executable scripts on first document insertion
691 for ( i
= 0; i
< hasScripts
; i
++ ) {
693 if ( rscriptType
.test( node
.type
|| "" ) &&
694 !jQuery
._data( node
, "globalEval" ) && jQuery
.contains( doc
, node
) ) {
697 // Optional AJAX dependency, but won't run scripts if not present
698 if ( jQuery
._evalUrl
) {
699 jQuery
._evalUrl( node
.src
);
702 jQuery
.globalEval( ( node
.text
|| node
.textContent
|| node
.innerHTML
|| "" ).replace( rcleanScript
, "" ) );
708 // Fix #11809: Avoid leaking memory
709 fragment
= first
= null;
719 prependTo
: "prepend",
720 insertBefore
: "before",
721 insertAfter
: "after",
722 replaceAll
: "replaceWith"
723 }, function( name
, original
) {
724 jQuery
.fn
[ name
] = function( selector
) {
728 insert
= jQuery( selector
),
729 last
= insert
.length
- 1;
731 for ( ; i
<= last
; i
++ ) {
732 elems
= i
=== last
? this : this.clone(true);
733 jQuery( insert
[i
] )[ original
]( elems
);
735 // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get()
736 push
.apply( ret
, elems
.get() );
739 return this.pushStack( ret
);