Permalink
Cannot retrieve contributors at this time
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
486 lines (393 sloc)
12.1 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| define( [ | |
| "./core", | |
| "./var/concat", | |
| "./var/push", | |
| "./core/access", | |
| "./manipulation/var/rcheckableType", | |
| "./manipulation/var/rtagName", | |
| "./manipulation/var/rscriptType", | |
| "./manipulation/wrapMap", | |
| "./manipulation/getAll", | |
| "./manipulation/setGlobalEval", | |
| "./manipulation/buildFragment", | |
| "./manipulation/support", | |
| "./data/var/dataPriv", | |
| "./data/var/dataUser", | |
| "./data/var/acceptData", | |
| "./core/DOMEval", | |
| "./core/init", | |
| "./traversing", | |
| "./selector", | |
| "./event" | |
| ], function( jQuery, concat, push, access, | |
| rcheckableType, rtagName, rscriptType, | |
| wrapMap, getAll, setGlobalEval, buildFragment, support, | |
| dataPriv, dataUser, acceptData, DOMEval ) { | |
| "use strict"; | |
| var | |
| /* eslint-disable max-len */ | |
| // See https://github.com/eslint/eslint/issues/3229 | |
| rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi, | |
| /* eslint-enable */ | |
| // Support: IE <=10 - 11, Edge 12 - 13 | |
| // In IE/Edge using regex groups here causes severe slowdowns. | |
| // See https://connect.microsoft.com/IE/feedback/details/1736512/ | |
| rnoInnerhtml = /<script|<style|<link/i, | |
| // checked="checked" or checked | |
| rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, | |
| rscriptTypeMasked = /^true\/(.*)/, | |
| rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g; | |
| function manipulationTarget( elem, content ) { | |
| if ( jQuery.nodeName( elem, "table" ) && | |
| jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { | |
| return elem.getElementsByTagName( "tbody" )[ 0 ] || 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 ) { | |
| var match = rscriptTypeMasked.exec( elem.type ); | |
| if ( match ) { | |
| elem.type = match[ 1 ]; | |
| } else { | |
| elem.removeAttribute( "type" ); | |
| } | |
| return elem; | |
| } | |
| function cloneCopyEvent( src, dest ) { | |
| var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; | |
| if ( dest.nodeType !== 1 ) { | |
| return; | |
| } | |
| // 1. Copy private data: events, handlers, etc. | |
| if ( dataPriv.hasData( src ) ) { | |
| pdataOld = dataPriv.access( src ); | |
| pdataCur = dataPriv.set( dest, pdataOld ); | |
| events = pdataOld.events; | |
| if ( events ) { | |
| delete pdataCur.handle; | |
| pdataCur.events = {}; | |
| for ( type in events ) { | |
| for ( i = 0, l = events[ type ].length; i < l; i++ ) { | |
| jQuery.event.add( dest, type, events[ type ][ i ] ); | |
| } | |
| } | |
| } | |
| } | |
| // 2. Copy user data | |
| if ( dataUser.hasData( src ) ) { | |
| udataOld = dataUser.access( src ); | |
| udataCur = jQuery.extend( {}, udataOld ); | |
| dataUser.set( dest, udataCur ); | |
| } | |
| } | |
| // Fix IE bugs, see support tests | |
| function fixInput( src, dest ) { | |
| var nodeName = dest.nodeName.toLowerCase(); | |
| // Fails to persist the checked state of a cloned checkbox or radio button. | |
| if ( nodeName === "input" && rcheckableType.test( src.type ) ) { | |
| dest.checked = src.checked; | |
| // Fails to return the selected option to the default selected state when cloning options | |
| } else if ( nodeName === "input" || nodeName === "textarea" ) { | |
| dest.defaultValue = src.defaultValue; | |
| } | |
| } | |
| function domManip( collection, args, callback, ignored ) { | |
| // Flatten any nested arrays | |
| args = concat.apply( [], args ); | |
| var fragment, first, scripts, hasScripts, node, doc, | |
| i = 0, | |
| l = collection.length, | |
| iNoClone = l - 1, | |
| value = args[ 0 ], | |
| isFunction = jQuery.isFunction( value ); | |
| // We can't cloneNode fragments that contain checked, in WebKit | |
| if ( isFunction || | |
| ( l > 1 && typeof value === "string" && | |
| !support.checkClone && rchecked.test( value ) ) ) { | |
| return collection.each( function( index ) { | |
| var self = collection.eq( index ); | |
| if ( isFunction ) { | |
| 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 (#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 ) { | |
| // Support: Android <=4.0 only, PhantomJS 1 only | |
| // push.apply(_, arraylike) throws on ancient WebKit | |
| 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 ) { | |
| // Optional AJAX dependency, but won't run scripts if not present | |
| if ( jQuery._evalUrl ) { | |
| jQuery._evalUrl( node.src ); | |
| } | |
| } else { | |
| DOMEval( node.textContent.replace( rcleanScript, "" ), doc ); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| return collection; | |
| } | |
| function remove( elem, selector, keepData ) { | |
| var node, | |
| nodes = selector ? jQuery.filter( selector, elem ) : elem, | |
| i = 0; | |
| for ( ; ( node = nodes[ i ] ) != null; i++ ) { | |
| if ( !keepData && node.nodeType === 1 ) { | |
| jQuery.cleanData( getAll( node ) ); | |
| } | |
| if ( node.parentNode ) { | |
| if ( keepData && jQuery.contains( node.ownerDocument, node ) ) { | |
| setGlobalEval( getAll( node, "script" ) ); | |
| } | |
| node.parentNode.removeChild( node ); | |
| } | |
| } | |
| return elem; | |
| } | |
| jQuery.extend( { | |
| htmlPrefilter: function( html ) { | |
| return html.replace( rxhtmlTag, "<$1></$2>" ); | |
| }, | |
| clone: function( elem, dataAndEvents, deepDataAndEvents ) { | |
| var i, l, srcElements, destElements, | |
| clone = elem.cloneNode( true ), | |
| inPage = jQuery.contains( elem.ownerDocument, elem ); | |
| // Fix IE cloning issues | |
| if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && | |
| !jQuery.isXMLDoc( elem ) ) { | |
| // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 | |
| destElements = getAll( clone ); | |
| srcElements = getAll( elem ); | |
| for ( i = 0, l = srcElements.length; i < l; i++ ) { | |
| fixInput( srcElements[ i ], destElements[ i ] ); | |
| } | |
| } | |
| // Copy the events from the original to the clone | |
| if ( dataAndEvents ) { | |
| if ( deepDataAndEvents ) { | |
| srcElements = srcElements || getAll( elem ); | |
| destElements = destElements || getAll( clone ); | |
| for ( i = 0, l = srcElements.length; i < l; i++ ) { | |
| cloneCopyEvent( srcElements[ i ], destElements[ i ] ); | |
| } | |
| } else { | |
| cloneCopyEvent( elem, clone ); | |
| } | |
| } | |
| // Preserve script evaluation history | |
| destElements = getAll( clone, "script" ); | |
| if ( destElements.length > 0 ) { | |
| setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); | |
| } | |
| // Return the cloned set | |
| return clone; | |
| }, | |
| cleanData: function( elems ) { | |
| var data, elem, type, | |
| special = jQuery.event.special, | |
| i = 0; | |
| for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { | |
| if ( acceptData( elem ) ) { | |
| if ( ( data = elem[ dataPriv.expando ] ) ) { | |
| if ( data.events ) { | |
| for ( type in data.events ) { | |
| if ( special[ type ] ) { | |
| jQuery.event.remove( elem, type ); | |
| // This is a shortcut to avoid jQuery.event.remove's overhead | |
| } else { | |
| jQuery.removeEvent( elem, type, data.handle ); | |
| } | |
| } | |
| } | |
| // Support: Chrome <=35 - 45+ | |
| // Assign undefined instead of using delete, see Data#remove | |
| elem[ dataPriv.expando ] = undefined; | |
| } | |
| if ( elem[ dataUser.expando ] ) { | |
| // Support: Chrome <=35 - 45+ | |
| // Assign undefined instead of using delete, see Data#remove | |
| elem[ dataUser.expando ] = undefined; | |
| } | |
| } | |
| } | |
| } | |
| } ); | |
| jQuery.fn.extend( { | |
| detach: function( selector ) { | |
| return remove( this, selector, true ); | |
| }, | |
| remove: function( selector ) { | |
| return remove( this, selector ); | |
| }, | |
| text: function( value ) { | |
| return access( this, function( value ) { | |
| return value === undefined ? | |
| jQuery.text( this ) : | |
| this.empty().each( function() { | |
| if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { | |
| this.textContent = value; | |
| } | |
| } ); | |
| }, null, value, arguments.length ); | |
| }, | |
| append: function() { | |
| return domManip( this, arguments, function( elem ) { | |
| if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { | |
| var target = manipulationTarget( this, elem ); | |
| target.appendChild( elem ); | |
| } | |
| } ); | |
| }, | |
| prepend: function() { | |
| return domManip( this, arguments, function( elem ) { | |
| if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { | |
| var target = manipulationTarget( this, elem ); | |
| target.insertBefore( elem, target.firstChild ); | |
| } | |
| } ); | |
| }, | |
| before: function() { | |
| return domManip( this, arguments, function( elem ) { | |
| if ( this.parentNode ) { | |
| this.parentNode.insertBefore( elem, this ); | |
| } | |
| } ); | |
| }, | |
| after: function() { | |
| return domManip( this, arguments, function( elem ) { | |
| if ( this.parentNode ) { | |
| this.parentNode.insertBefore( elem, this.nextSibling ); | |
| } | |
| } ); | |
| }, | |
| empty: function() { | |
| var elem, | |
| i = 0; | |
| for ( ; ( elem = this[ i ] ) != null; i++ ) { | |
| if ( elem.nodeType === 1 ) { | |
| // Prevent memory leaks | |
| jQuery.cleanData( getAll( elem, false ) ); | |
| // Remove any remaining nodes | |
| elem.textContent = ""; | |
| } | |
| } | |
| return this; | |
| }, | |
| clone: function( dataAndEvents, deepDataAndEvents ) { | |
| dataAndEvents = dataAndEvents == null ? false : dataAndEvents; | |
| deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; | |
| return this.map( function() { | |
| return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); | |
| } ); | |
| }, | |
| html: function( value ) { | |
| return access( this, function( value ) { | |
| var elem = this[ 0 ] || {}, | |
| i = 0, | |
| l = this.length; | |
| if ( value === undefined && elem.nodeType === 1 ) { | |
| return elem.innerHTML; | |
| } | |
| // See if we can take a shortcut and just use innerHTML | |
| if ( typeof value === "string" && !rnoInnerhtml.test( value ) && | |
| !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { | |
| value = jQuery.htmlPrefilter( value ); | |
| try { | |
| for ( ; i < l; i++ ) { | |
| elem = this[ i ] || {}; | |
| // Remove element nodes and prevent memory leaks | |
| if ( elem.nodeType === 1 ) { | |
| jQuery.cleanData( getAll( elem, false ) ); | |
| elem.innerHTML = value; | |
| } | |
| } | |
| elem = 0; | |
| // If using innerHTML throws an exception, use the fallback method | |
| } catch ( e ) {} | |
| } | |
| if ( elem ) { | |
| this.empty().append( value ); | |
| } | |
| }, null, value, arguments.length ); | |
| }, | |
| replaceWith: function() { | |
| var ignored = []; | |
| // Make the changes, replacing each non-ignored context element with the new content | |
| return domManip( this, arguments, function( elem ) { | |
| var parent = this.parentNode; | |
| if ( jQuery.inArray( this, ignored ) < 0 ) { | |
| jQuery.cleanData( getAll( this ) ); | |
| if ( parent ) { | |
| parent.replaceChild( elem, this ); | |
| } | |
| } | |
| // Force callback invocation | |
| }, ignored ); | |
| } | |
| } ); | |
| jQuery.each( { | |
| appendTo: "append", | |
| prependTo: "prepend", | |
| insertBefore: "before", | |
| insertAfter: "after", | |
| replaceAll: "replaceWith" | |
| }, function( name, original ) { | |
| jQuery.fn[ name ] = function( selector ) { | |
| var elems, | |
| ret = [], | |
| insert = jQuery( selector ), | |
| last = insert.length - 1, | |
| i = 0; | |
| for ( ; i <= last; i++ ) { | |
| elems = i === last ? this : this.clone( true ); | |
| jQuery( insert[ i ] )[ original ]( elems ); | |
| // Support: Android <=4.0 only, PhantomJS 1 only | |
| // .get() because push.apply(_, arraylike) throws on ancient WebKit | |
| push.apply( ret, elems.get() ); | |
| } | |
| return this.pushStack( ret ); | |
| }; | |
| } ); | |
| return jQuery; | |
| } ); |