From 77cdc0ce65731246b1b20fbaf50f744322c0a4d7 Mon Sep 17 00:00:00 2001 From: Andrew Nacin Date: Tue, 15 Jan 2013 17:52:42 +0000 Subject: [PATCH] jQuery 1.9 final. jQuery Migrate 1.0. Uncompressed for now, while we iron out kinks. props jorbin. see #22975. git-svn-id: https://develop.svn.wordpress.org/trunk@23301 602fd350-edb4-49c9-b593-d223f7449a82 --- wp-includes/js/jquery/jquery-migrate.js | 219 +++-- wp-includes/js/jquery/jquery.js | 1059 +++++++++++++---------- wp-includes/script-loader.php | 4 +- 3 files changed, 737 insertions(+), 545 deletions(-) diff --git a/wp-includes/js/jquery/jquery-migrate.js b/wp-includes/js/jquery/jquery-migrate.js index f8460fe737..27111d80f9 100644 --- a/wp-includes/js/jquery/jquery-migrate.js +++ b/wp-includes/js/jquery/jquery-migrate.js @@ -1,24 +1,20 @@ /*! - * jQuery Migrate - v1.0.0pre - 2012-12-17 + * jQuery Migrate - v1.0.0 - 2013-01-14 * https://github.com/jquery/jquery-migrate - * Copyright 2012 jQuery Foundation and other contributors; Licensed MIT + * Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors; Licensed MIT */ - (function( jQuery, window, undefined ) { "use strict"; -// Use Uglify to do conditional compilation of warning messages; -// the minified version will set this to false and remove dead code. -if ( typeof window.JQMIGRATE_WARN === "undefined" ) { - window.JQMIGRATE_WARN = true; -} - var warnedAbout = {}; // List of warnings already given; public read only jQuery.migrateWarnings = []; +// Set to true to prevent console output; migrateWarnings still maintained +// jQuery.migrateMute = false; + // Forget any warnings we've already given; public jQuery.migrateReset = function() { warnedAbout = {}; @@ -26,19 +22,17 @@ jQuery.migrateReset = function() { }; function migrateWarn( msg) { - if ( window.JQMIGRATE_WARN ) { - if ( !warnedAbout[ msg ] ) { - warnedAbout[ msg ] = true; - jQuery.migrateWarnings.push( msg ); - if ( window.console && console.warn ) { - console.warn( "JQMIGRATE: " + msg ); - } + if ( !warnedAbout[ msg ] ) { + warnedAbout[ msg ] = true; + jQuery.migrateWarnings.push( msg ); + if ( window.console && console.warn && !jQuery.migrateMute ) { + console.warn( "JQMIGRATE: " + msg ); } } } function migrateWarnProp( obj, prop, value, msg ) { - if ( window.JQMIGRATE_WARN && Object.defineProperty ) { + if ( Object.defineProperty ) { // On ES5 browsers (non-oldIE), warn if the code tries to get prop; // allow property to be overwritten in case some other plugin wants it try { @@ -65,7 +59,7 @@ function migrateWarnProp( obj, prop, value, msg ) { obj[ prop ] = value; } -if ( window.JQMIGRATE_WARN && document.compatMode === "BackCompat" ) { +if ( document.compatMode === "BackCompat" ) { // jQuery has never supported or tested Quirks Mode migrateWarn( "jQuery is not compatible with Quirks Mode" ); } @@ -78,15 +72,20 @@ var attrFn = {}, valueAttrSet = jQuery.attrHooks.value && jQuery.attrHooks.value.set || function() { return undefined; }, rnoType = /^(?:input|button)$/i, - rnoAttrNodeType = /^[238]$/; + rnoAttrNodeType = /^[238]$/, + rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, + ruseDefault = /^(?:checked|selected)$/i; // jQuery.attrFn migrateWarnProp( jQuery, "attrFn", attrFn, "jQuery.attrFn is deprecated" ); jQuery.attr = function( elem, name, value, pass ) { + var lowerName = name.toLowerCase(), + nType = elem && elem.nodeType; + if ( pass ) { migrateWarn("jQuery.fn.attr( props, pass ) is deprecated"); - if ( elem && !rnoAttrNodeType.test( elem.nodeType ) && jQuery.isFunction( jQuery.fn[ name ] ) ) { + if ( elem && !rnoAttrNodeType.test( nType ) && jQuery.isFunction( jQuery.fn[ name ] ) ) { return jQuery( elem )[ name ]( value ); } } @@ -96,25 +95,71 @@ jQuery.attr = function( elem, name, value, pass ) { migrateWarn("Can't change the 'type' of an input or button in IE 6/7/8"); } + // Restore boolHook for boolean property/attribute synchronization + if ( !jQuery.attrHooks[ lowerName ] && rboolean.test( lowerName ) ) { + jQuery.attrHooks[ lowerName ] = { + get: function( elem, name ) { + // Align boolean attributes with corresponding properties + // Fall back to attribute presence where some booleans are not supported + var attrNode, + property = jQuery.prop( elem, name ); + return property === true || typeof property !== "boolean" && + ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ? + + name.toLowerCase() : + undefined; + }, + set: function( elem, value, name ) { + var propName; + if ( value === false ) { + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + // value is true since we know at this point it's type boolean and not false + // Set boolean attributes to the same name and set the DOM property + propName = jQuery.propFix[ name ] || name; + if ( propName in elem ) { + // Only set the IDL specifically if it already exists on the element + elem[ propName ] = true; + } + + elem.setAttribute( name, name.toLowerCase() ); + } + return name; + } + }; + + // Warn only for attributes that can remain distinct from their properties post-1.9 + if ( ruseDefault.test( lowerName ) ) { + migrateWarn( "jQuery.fn.attr(" + lowerName + ") may use property instead of attribute" ); + } + } + return attr.call( jQuery, elem, name, value ); }; // attrHooks: value jQuery.attrHooks.value = { get: function( elem, name ) { - if ( jQuery.nodeName( elem, "button" ) ) { + var nodeName = ( elem.nodeName || "" ).toLowerCase(); + if ( nodeName === "button" ) { return valueAttrGet.apply( this, arguments ); } - migrateWarn("property-based jQuery.fn.attr('value') is deprecated"); + if ( nodeName !== "input" && nodeName !== "option" ) { + migrateWarn("property-based jQuery.fn.attr('value') is deprecated"); + } return name in elem ? elem.value : null; }, - set: function( elem, value, name ) { - if ( jQuery.nodeName( elem, "button" ) ) { + set: function( elem, value ) { + var nodeName = ( elem.nodeName || "" ).toLowerCase(); + if ( nodeName === "button" ) { return valueAttrSet.apply( this, arguments ); } - migrateWarn("property-based jQuery.fn.attr('value', val) is deprecated"); + if ( nodeName !== "input" && nodeName !== "option" ) { + migrateWarn("property-based jQuery.fn.attr('value', val) is deprecated"); + } // Does not return so that setAttribute is also used elem.value = value; } @@ -122,10 +167,9 @@ jQuery.attrHooks.value = { var matched, browser, - oldAccess = jQuery.access, oldInit = jQuery.fn.init, // Note this does NOT include the # XSS fix from 1.7! - rquickExpr = /^(?:.*(<[\w\W]+>)[^>]*|#([\w-]*))$/; + rquickExpr = /^(?:.*(<[\w\W]+>)[^>]*|#([\w\-]*))$/; // $(html) "looks like html" rule change jQuery.fn.init = function( selector, context, rootjQuery ) { @@ -151,27 +195,6 @@ jQuery.fn.init = function( selector, context, rootjQuery ) { }; jQuery.fn.init.prototype = jQuery.fn; -if ( jQuery.fn.jquery >= "1.9" ) { - // jQuery.access( ..., pass ) - jQuery.access = function( elems, fn, key, value, chainable, emptyGet, pass ) { - var i = 0, - length = elems.length; - - if ( key && typeof key === "object" && value ) { - for ( i in key ) { - jQuery.access( elems, fn, i, key[i], true, emptyGet, value ); - } - return elems; - } else if ( pass && key != null && value !== undefined ) { - for ( ; i < length; i++ ) { - fn( elems[i], key, value, true ); - } - return elems; - } - return oldAccess.call( jQuery, elems, fn, key, value, chainable, emptyGet ); - }; -} - jQuery.uaMatch = function( ua ) { ua = ua.toLowerCase(); @@ -250,7 +273,8 @@ jQuery.fn.data = function( name ) { }; -var oldSelf = jQuery.fn.andSelf || jQuery.fn.addBack, +var rscriptType = /\/(java|ecma)script/i, + oldSelf = jQuery.fn.andSelf || jQuery.fn.addBack, oldFragment = jQuery.buildFragment; jQuery.fn.andSelf = function() { @@ -258,25 +282,83 @@ jQuery.fn.andSelf = function() { return oldSelf.apply( this, arguments ); }; -jQuery.buildFragment = function( args, context, scripts ) { - var fragment; - - if ( !oldFragment ) { - // Set context from what may come in as undefined or a jQuery collection or a node - // Updated to fix #12266 where accessing context[0] could throw an exception in IE9/10 & - // also doubles as fix for #8950 where plain objects caused createDocumentFragment exception +// Since jQuery.clean is used internally on older versions, we only shim if it's missing +if ( !jQuery.clean ) { + jQuery.clean = function( elems, context, fragment, scripts ) { + // Set context per 1.8 logic context = context || document; context = !context.nodeType && context[0] || context; context = context.ownerDocument || context; - fragment = context.createDocumentFragment(); - jQuery.clean( args, context, fragment, scripts ); + migrateWarn("jQuery.clean() is deprecated"); - migrateWarn("jQuery.buildFragment() is deprecated"); - return { fragment: fragment, cacheable: false }; + var i, elem, handleScript, jsTags, + ret = []; + + jQuery.merge( ret, jQuery.buildFragment( elems, context ).childNodes ); + + // Complex logic lifted directly from jQuery 1.8 + if ( fragment ) { + // Special handling of each script element + handleScript = function( elem ) { + // Check if we consider it executable + if ( !elem.type || rscriptType.test( elem.type ) ) { + // Detach the script and store it in the scripts array (if provided) or the fragment + // Return truthy to indicate that it has been handled + return scripts ? + scripts.push( elem.parentNode ? elem.parentNode.removeChild( elem ) : elem ) : + fragment.appendChild( elem ); + } + }; + + for ( i = 0; (elem = ret[i]) != null; i++ ) { + // Check if we're done after handling an executable script + if ( !( jQuery.nodeName( elem, "script" ) && handleScript( elem ) ) ) { + // Append to fragment and handle embedded scripts + fragment.appendChild( elem ); + if ( typeof elem.getElementsByTagName !== "undefined" ) { + // handleScript alters the DOM, so use jQuery.merge to ensure snapshot iteration + jsTags = jQuery.grep( jQuery.merge( [], elem.getElementsByTagName("script") ), handleScript ); + + // Splice the scripts into ret after their former ancestor and advance our index beyond them + ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) ); + i += jsTags.length; + } + } + } + } + + return ret; + }; +} + +jQuery.buildFragment = function( elems, context, scripts, selection ) { + var ret, + warning = "jQuery.buildFragment() is deprecated"; + + // Set context per 1.8 logic + context = context || document; + context = !context.nodeType && context[0] || context; + context = context.ownerDocument || context; + + try { + ret = oldFragment.call( jQuery, elems, context, scripts, selection ); + + // jQuery < 1.8 required arrayish context; jQuery 1.9 fails on it + } catch( x ) { + ret = oldFragment.call( jQuery, elems, context.nodeType ? [ context ] : context[ 0 ], scripts, selection ); + + // Success from tweaking context means buildFragment was called by the user + migrateWarn( warning ); } - // Don't warn if we are in a version where buildFragment is used internally - return oldFragment.apply( this, arguments ); + + // jQuery < 1.9 returned an object instead of the fragment itself + if ( !ret.fragment ) { + migrateWarnProp( ret, "fragment", ret, warning ); + migrateWarnProp( ret, "cacheable", false, warning ); + } + + return ret; }; var eventAdd = jQuery.event.add, @@ -303,6 +385,9 @@ if ( jQuery.event.props && jQuery.event.props[ 0 ] !== "attrChange" ) { jQuery.event.props.unshift( "attrChange", "attrName", "relatedNode", "srcElement" ); } +// Undocumented jQuery.event.handle was "deprecated" in jQuery 1.7 +migrateWarnProp( jQuery.event, "handle", jQuery.event.dispatch, "jQuery.event.handle is undocumented and deprecated" ); + // Support for 'hover' pseudo-event and ajax event warnings jQuery.event.add = function( elem, types, handler, data, selector ){ if ( elem !== document && rajaxEvent.test( types ) ) { @@ -314,7 +399,7 @@ jQuery.event.remove = function( elem, types, handler, selector, mappedTypes ){ eventRemove.call( this, elem, hoverHack( types ) || "", handler, selector, mappedTypes ); }; -jQuery.fn.error = function( data, fn ) { +jQuery.fn.error = function() { var args = Array.prototype.slice.call( arguments, 0); migrateWarn("jQuery.fn.error() is deprecated"); args.splice( 0, 0, "error" ); @@ -387,25 +472,25 @@ jQuery.event.trigger = function( event, data, elem, onlyHandlers ){ jQuery.each( ajaxEvents.split("|"), function( _, name ) { jQuery.event.special[ name ] = { - setup: function( data ) { + setup: function() { var elem = this; // The document needs no shimming; must be !== for oldIE if ( elem !== document ) { - jQuery.event.add( document, name + "." + jQuery.guid, function( event ) { + jQuery.event.add( document, name + "." + jQuery.guid, function() { jQuery.event.trigger( name, null, elem, true ); }); jQuery._data( this, name, jQuery.guid++ ); } return false; }, - teardown: function( data, handleObj ) { + teardown: function() { if ( this !== document ) { jQuery.event.remove( document, name + "." + jQuery._data( this, name ) ); } return false; } - } + }; } ); diff --git a/wp-includes/js/jquery/jquery.js b/wp-includes/js/jquery/jquery.js index 32400aaf68..840e17940f 100644 --- a/wp-includes/js/jquery/jquery.js +++ b/wp-includes/js/jquery/jquery.js @@ -1,15 +1,15 @@ /*! - * jQuery JavaScript Library v1.9.0b1 + * jQuery JavaScript Library v1.9.0 * http://jquery.com/ * * Includes Sizzle.js * http://sizzlejs.com/ * - * Copyright 2012 jQuery Foundation and other contributors + * Copyright 2005, 2012 jQuery Foundation, Inc. and other contributors * Released under the MIT license * http://jquery.org/license * - * Date: 2012-12-16 + * Date: 2013-1-14 */ (function( window, undefined ) { "use strict"; @@ -36,7 +36,7 @@ var // List of deleted data cache ids, so we can reuse them core_deletedIds = [], - core_version = "1.9.0b1", + core_version = "1.9.0", // Save a reference to some core methods core_concat = core_deletedIds.concat, @@ -111,13 +111,6 @@ jQuery.fn = jQuery.prototype = { return this; } - // HANDLE: $(DOMElement) - if ( selector.nodeType ) { - this.context = this[0] = selector; - this.length = 1; - return this; - } - // Handle HTML strings if ( typeof selector === "string" ) { if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { @@ -191,6 +184,12 @@ jQuery.fn = jQuery.prototype = { return this.constructor( context ).find( selector ); } + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + // HANDLE: $(function) // Shortcut for document ready } else if ( jQuery.isFunction( selector ) ) { @@ -442,9 +441,12 @@ jQuery.extend({ }, type: function( obj ) { - return obj == null ? - String( obj ) : - class2type[ core_toString.call(obj) ] || "object"; + if ( obj == null ) { + return String( obj ); + } + return typeof obj === "object" || typeof obj === "function" ? + class2type[ core_toString.call(obj) ] || "object" : + typeof obj; }, isPlainObject: function( obj ) { @@ -509,8 +511,7 @@ jQuery.extend({ return [ context.createElement( parsed[1] ) ]; } - parsed = context.createDocumentFragment(); - jQuery.clean( [ data ], context, parsed, scripts ); + parsed = jQuery.buildFragment( [ data ], context, scripts ); if ( scripts ) { jQuery( scripts ).remove(); } @@ -1164,22 +1165,19 @@ jQuery.extend({ return jQuery.Deferred(function( newDefer ) { jQuery.each( tuples, function( i, tuple ) { var action = tuple[ 0 ], - fn = fns[ i ]; + fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; // deferred[ done | fail | progress ] for forwarding actions to newDefer - deferred[ tuple[1] ]( jQuery.isFunction( fn ) ? - function() { - var returned = fn.apply( this, arguments ); - if ( returned && jQuery.isFunction( returned.promise ) ) { - returned.promise() - .done( newDefer.resolve ) - .fail( newDefer.reject ) - .progress( newDefer.notify ); - } else { - newDefer[ action + "With" ]( this === promise ? newDefer.promise() : this, [ returned ] ); - } - } : - newDefer[ action ] - ); + deferred[ tuple[1] ](function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .done( newDefer.resolve ) + .fail( newDefer.reject ) + .progress( newDefer.notify ); + } else { + newDefer[ action + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); + } + }); }); fns = null; }).promise(); @@ -1215,7 +1213,7 @@ jQuery.extend({ // deferred[ resolve | reject | notify ] deferred[ tuple[0] ] = function() { - deferred[ tuple[0] + "With" ]( promise, arguments ); + deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); return this; }; deferred[ tuple[0] + "With" ] = list.fireWith; @@ -1287,17 +1285,7 @@ jQuery.extend({ }); jQuery.support = (function() { - var support, - all, - a, - select, - opt, - input, - fragment, - eventName, - i, - isSupported, - clickFn, + var support, all, a, select, opt, input, fragment, eventName, isSupported, i, div = document.createElement("div"); // Setup @@ -1367,9 +1355,6 @@ jQuery.support = (function() { boxModel: document.compatMode === "CSS1Compat", // Will be defined later - submitBubbles: true, - changeBubbles: true, - focusinBubbles: false, deleteExpando: true, noCloneEvent: true, inlineBlockNeedsLayout: false, @@ -1388,24 +1373,13 @@ jQuery.support = (function() { select.disabled = true; support.optDisabled = !opt.disabled; - // Test to see if it's possible to delete an expando from an element - // Fails in Internet Explorer + // Support: IE<9 try { delete div.test; } catch( e ) { support.deleteExpando = false; } - if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { - div.attachEvent( "onclick", clickFn = function() { - // Cloning a node shouldn't copy over any - // bound event handlers (IE does this) - support.noCloneEvent = false; - }); - div.cloneNode( true ).fireEvent("onclick"); - div.detachEvent( "onclick", clickFn ); - } - // Check if we can trust getAttribute("value") input = document.createElement("input"); input.setAttribute( "value", "" ); @@ -1417,49 +1391,46 @@ jQuery.support = (function() { support.radioValue = input.value === "t"; // #11217 - WebKit loses check when the name is after the checked attribute - input.setAttribute( "checked", "checked" ); + input.setAttribute( "checked", "t" ); input.setAttribute( "name", "t" ); - div.appendChild( input ); fragment = document.createDocumentFragment(); - fragment.appendChild( div.lastChild ); - - // WebKit doesn't clone checked state correctly in fragments - support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; + fragment.appendChild( input ); // Check if a disconnected checkbox will retain its checked // value of true after appended to the DOM (IE6/7) support.appendChecked = input.checked; - fragment.removeChild( input ); - fragment.appendChild( div ); + // WebKit doesn't clone checked state correctly in fragments + support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; - // Technique from Juriy Zaytsev - // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/ - // We only care about the case where non-standard event systems - // are used, namely in IE. Short-circuiting here helps us to - // avoid an eval call (in setAttribute) which can cause CSP - // to go haywire. See: https://developer.mozilla.org/en/Security/CSP + // Support: IE<9 + // Opera does not clone events (and typeof div.attachEvent === undefined). + // IE9-10 clones events bound via attachEvent, but they don't trigger with .click() if ( div.attachEvent ) { - for ( i in { - submit: true, - change: true, - focusin: true - }) { - eventName = "on" + i; - isSupported = ( eventName in div ); - if ( !isSupported ) { - div.setAttribute( eventName, "return;" ); - isSupported = ( typeof div[ eventName ] === "function" ); - } - support[ i + "Bubbles" ] = isSupported; - } + div.attachEvent( "onclick", function() { + support.noCloneEvent = false; + }); + + div.cloneNode( true ).click(); } + // Support: IE<9 (lack submit/change bubble), Firefox 17+ (lack focusin event) + // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP), test/csp.php + for ( i in { submit: true, change: true, focusin: true }) { + div.setAttribute( eventName = "on" + i, "t" ); + + support[ i + "Bubbles" ] = eventName in window || div.attributes[ eventName ].expando === false; + } + + div.style.backgroundClip = "content-box"; + div.cloneNode( true ).style.backgroundClip = ""; + support.clearCloneStyle = div.style.backgroundClip === "content-box"; + // Run tests that need a body at doc ready jQuery(function() { - var container, div, tds, marginDiv, - divReset = "padding:0;margin:0;border:0;display:block;overflow:hidden;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;", + var container, marginDiv, tds, + divReset = "padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;", body = document.getElementsByTagName("body")[0]; if ( !body ) { @@ -1468,20 +1439,17 @@ jQuery.support = (function() { } container = document.createElement("div"); - container.style.cssText = "visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px"; - body.insertBefore( container, body.firstChild ); + container.style.cssText = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px"; - // Construct the test element - div = document.createElement("div"); - container.appendChild( div ); + body.appendChild( container ).appendChild( div ); + // Support: IE8 // Check if table cells still have offsetWidth/Height when they are set // to display:none and there are still other visible table cells in a // table row; if so, offsetWidth/Height are not reliable for use when // determining if an element has been hidden directly using // display:none (it is still safe to use offsets if a parent element is // hidden; don safety goggles and see bug #4512 for more information). - // (only IE 8 fails this test) div.innerHTML = "
t
"; tds = div.getElementsByTagName("td"); tds[ 0 ].style.cssText = "padding:0;margin:0;border:0;display:none"; @@ -1490,8 +1458,8 @@ jQuery.support = (function() { tds[ 0 ].style.display = ""; tds[ 1 ].style.display = "none"; + // Support: IE8 // Check if empty table cells still have offsetWidth/Height - // (IE <= 8 fail this test) support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); // Check box-sizing and margin behavior @@ -1500,39 +1468,36 @@ jQuery.support = (function() { support.boxSizing = ( div.offsetWidth === 4 ); support.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== 1 ); - // NOTE: To any future maintainer, we've window.getComputedStyle - // because jsdom on node.js will break without it. + // Use window.getComputedStyle because jsdom on node.js will break without it. if ( window.getComputedStyle ) { support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%"; support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px"; // Check if div with explicit width and no margin-right incorrectly - // gets computed margin-right based on width of container. For more - // info see bug #3333 + // gets computed margin-right based on width of container. (#3333) // Fails in WebKit before Feb 2011 nightlies // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right - marginDiv = document.createElement("div"); + marginDiv = div.appendChild( document.createElement("div") ); marginDiv.style.cssText = div.style.cssText = divReset; marginDiv.style.marginRight = marginDiv.style.width = "0"; div.style.width = "1px"; - div.appendChild( marginDiv ); + support.reliableMarginRight = !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight ); } if ( typeof div.style.zoom !== "undefined" ) { + // Support: IE<8 // Check if natively block-level elements act like inline-block // elements when setting their display to 'inline' and giving // them layout - // (IE < 8 does this) div.innerHTML = ""; div.style.cssText = divReset + "width:1px;padding:1px;display:inline;zoom:1"; support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 ); + // Support: IE6 // Check if elements with layout shrink-wrap their children - // (IE 6 does this) div.style.display = "block"; - div.style.overflow = "visible"; div.innerHTML = "
"; div.firstChild.style.width = "5px"; support.shrinkWrapBlocks = ( div.offsetWidth !== 3 ); @@ -1542,20 +1507,21 @@ jQuery.support = (function() { body.style.zoom = 1; } - // Null elements to avoid leaks in IE body.removeChild( container ); + + // Null elements to avoid leaks in IE container = div = tds = marginDiv = null; }); // Null elements to avoid leaks in IE - fragment.removeChild( div ); - all = a = select = opt = input = fragment = div = null; + all = select = fragment = opt = a = input = null; return support; })(); + var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/, rmultiDash = /([A-Z])/g; - + function internalData( elem, name, data, pvt /* Internal Use Only */ ){ if ( !jQuery.acceptData( elem ) ) { return; @@ -1771,7 +1737,7 @@ jQuery.extend({ _data: function( elem, name, data ) { return internalData( elem, name, data, true ); }, - + _removeData: function( elem, name ) { return internalRemoveData( elem, name, true ); }, @@ -1926,6 +1892,7 @@ jQuery.extend({ startLength--; } + hooks.cur = fn; if ( fn ) { // Add a progress sentinel to prevent the fx queue from being @@ -2367,7 +2334,11 @@ jQuery.extend({ } else { - ret = elem.getAttribute( name ); + // In IE9+, Flash objects don't have .getAttribute (#12945) + // Support: IE9+ + if ( typeof elem.getAttribute !== "undefined" ) { + ret = elem.getAttribute( name ); + } // Non-existent attributes return null, we normalize to undefined return ret == null ? @@ -2637,8 +2608,9 @@ if ( !jQuery.support.style ) { jQuery.attrHooks.style = { get: function( elem ) { // Return undefined in the case of empty string - // Normalize to lowercase since IE uppercases css property names - return elem.style.cssText.toLowerCase() || undefined; + // Note: IE uppercases css property names, but if we were to .toLowerCase() + // .cssText, that would destroy case senstitivity in URL's, like in "background" + return elem.style.cssText || undefined; }, set: function( elem, value ) { return ( elem.style.cssText = value + "" ); @@ -2697,20 +2669,31 @@ var rformElems = /^(?:input|select|textarea)$/i, rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, rtypenamespace = /^([^.]*)(?:\.(.+)|)$/; +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + /* * Helper functions for managing events -- not part of the public interface. * Props to Dean Edwards' addEvent library for many of the ideas. */ jQuery.event = { - add: function( elem, types, handler, data, selector ) { - var elemData, eventHandle, events, - tns, type, namespaces, handleObj, - handleObjIn, handlers, special, - t = 0; + global: {}, - // Don't attach events to noData or text/comment nodes (allow plain objects tho) - if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) { + add: function( elem, types, handler, data, selector ) { + + var handleObjIn, eventHandle, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + // Don't attach events to noData or text/comment nodes (but allow plain objects) + elemData = elem.nodeType !== 3 && elem.nodeType !== 8 && jQuery._data( elem ); + + if ( !elemData ) { return; } @@ -2727,13 +2710,11 @@ jQuery.event = { } // Init the element's event structure and main handler, if this is the first - events = elemData.events; - if ( !events ) { - elemData.events = events = {}; + if ( !(events = elemData.events) ) { + events = elemData.events = {}; } - eventHandle = elemData.handle; - if ( !eventHandle ) { - elemData.handle = eventHandle = function( e ) { + if ( !(eventHandle = elemData.handle) ) { + eventHandle = elemData.handle = function( e ) { // Discard the second event of a jQuery.event.trigger() and // when an event is called after a page has unloaded return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ? @@ -2747,11 +2728,11 @@ jQuery.event = { // Handle multiple events separated by a space // jQuery(...).bind("mouseover mouseout", fn); types = ( types || "" ).match( core_rnotwhite ) || [""]; - for ( ; t < types.length; t++ ) { - - tns = rtypenamespace.exec( types[t] ) || []; - type = tns[1]; - namespaces = ( tns[2] || "" ).split( "." ).sort(); + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); // If event changes its type, use the special event handlers for the changed type special = jQuery.event.special[ type ] || {}; @@ -2765,7 +2746,7 @@ jQuery.event = { // handleObj is passed to all event handlers handleObj = jQuery.extend({ type: type, - origType: tns[1], + origType: origType, data: data, handler: handler, guid: handler.guid, @@ -2775,8 +2756,7 @@ jQuery.event = { }, handleObjIn ); // Init the event handler queue if we're the first - handlers = events[ type ]; - if ( !handlers ) { + if ( !(handlers = events[ type ]) ) { handlers = events[ type ] = []; handlers.delegateCount = 0; @@ -2815,14 +2795,12 @@ jQuery.event = { elem = null; }, - global: {}, - // Detach an event or set of events from an element remove: function( elem, types, handler, selector, mappedTypes ) { - var tns, type, origType, namespaces, origCount, - j, events, special, eventType, handleObj, - t = 0, + var j, origCount, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, elemData = jQuery.hasData( elem ) && jQuery._data( elem ); if ( !elemData || !(events = elemData.events) ) { @@ -2831,10 +2809,11 @@ jQuery.event = { // Once for each type.namespace in types; type may be omitted types = ( types || "" ).match( core_rnotwhite ) || [""]; - for ( ; t < types.length; t++ ) { - tns = rtypenamespace.exec( types[t] ) || []; - type = origType = tns[1]; - namespaces = tns[2]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); // Unbind all events (on this namespace, if provided) for the element if ( !type ) { @@ -2845,23 +2824,23 @@ jQuery.event = { } special = jQuery.event.special[ type ] || {}; - type = ( selector? special.delegateType : special.bindType ) || type; - eventType = events[ type ] || []; - origCount = eventType.length; - namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.|)") + "(\\.|$)") : null; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ); // Remove matching events - for ( j = 0; j < eventType.length; j++ ) { - handleObj = eventType[ j ]; + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; if ( ( mappedTypes || origType === handleObj.origType ) && ( !handler || handler.guid === handleObj.guid ) && - ( !namespaces || namespaces.test( handleObj.namespace ) ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { - eventType.splice( j--, 1 ); + handlers.splice( j, 1 ); if ( handleObj.selector ) { - eventType.delegateCount--; + handlers.delegateCount--; } if ( special.remove ) { special.remove.call( elem, handleObj ); @@ -2871,7 +2850,7 @@ jQuery.event = { // Remove generic event handler if we removed something and no more handlers exist // (avoids potential for endless recursion during removal of special event handlers) - if ( eventType.length === 0 && origCount !== eventType.length ) { + if ( origCount && !handlers.length ) { if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { jQuery.removeEvent( elem, type, elemData.handle ); } @@ -2892,11 +2871,12 @@ jQuery.event = { trigger: function( event, data, elem, onlyHandlers ) { - var i, cur, old, ontype, special, handle, eventPath, bubbleType, + var i, cur, tmp, bubbleType, ontype, handle, special, + eventPath = [ elem || document ], type = event.type || event, namespaces = event.namespace ? event.namespace.split(".") : []; - elem = elem || document; + cur = tmp = elem = elem || document; // Don't do events on text and comment nodes if ( elem.nodeType === 3 || elem.nodeType === 8 ) { @@ -2914,21 +2894,18 @@ jQuery.event = { type = namespaces.shift(); namespaces.sort(); } + ontype = type.indexOf(":") < 0 && "on" + type; - // Caller can pass in an Event, Object, or just an event type string - event = typeof event === "object" ? - // jQuery.Event object - event[ jQuery.expando ] ? event : - // Object literal - new jQuery.Event( type, event ) : - // Just the event type (string) - new jQuery.Event( type ); + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); - event.type = type; event.isTrigger = true; event.namespace = namespaces.join("."); - event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)") : null; - ontype = type.indexOf(":") < 0 ? "on" + type : ""; + event.namespace_re = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) : + null; // Clean up the event in case it is being reused event.result = undefined; @@ -2937,8 +2914,9 @@ jQuery.event = { } // Clone any incoming data and prepend the event, creating the handler arg list - data = data != null ? jQuery.makeArray( data ) : []; - data.unshift( event ); + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); // Allow special events to draw outside the lines special = jQuery.event.special[ type ] || {}; @@ -2948,33 +2926,38 @@ jQuery.event = { // Determine event propagation path in advance, per W3C events spec (#9951) // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) - eventPath = [[ elem, special.bindType || type ]]; if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { bubbleType = special.delegateType || type; - cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode; - for ( old = elem; cur; cur = cur.parentNode ) { - eventPath.push([ cur, bubbleType ]); - old = cur; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; } // Only add window if we got to document (e.g., not plain obj or detached DOM) - if ( old === (elem.ownerDocument || document) ) { - eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]); + if ( tmp === (elem.ownerDocument || document) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); } } // Fire handlers on the event path - for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) { + i = 0; + while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) { - cur = eventPath[i][0]; - event.type = eventPath[i][1]; + event.type = i > 1 ? + bubbleType : + special.bindType || type; + // jQuery handler handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); if ( handle ) { handle.apply( cur, data ); } - // Note that this is a bare JS function and not a jQuery handler + + // Native handler handle = ontype && cur[ ontype ]; if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) { event.preventDefault(); @@ -2994,9 +2977,9 @@ jQuery.event = { if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) { // Don't re-trigger an onFOO event when we call its FOO() method - old = elem[ ontype ]; + tmp = elem[ ontype ]; - if ( old ) { + if ( tmp ) { elem[ ontype ] = null; } @@ -3010,8 +2993,8 @@ jQuery.event = { } jQuery.event.triggered = undefined; - if ( old ) { - elem[ ontype ] = old; + if ( tmp ) { + elem[ ontype ] = tmp; } } } @@ -3025,12 +3008,11 @@ jQuery.event = { // Make a writable jQuery.Event from the native event object event = jQuery.event.fix( event ); - var i, j, cur, ret, selMatch, matched, matches, handleObj, sel, - handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []), - delegateCount = handlers.delegateCount, + var i, j, ret, matched, handleObj, + handlerQueue = [], args = core_slice.call( arguments ), - special = jQuery.event.special[ event.type ] || {}, - handlerQueue = []; + handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; // Use the fix-ed jQuery.Event rather than the (read-only) native event args[0] = event; @@ -3041,62 +3023,29 @@ jQuery.event = { return; } - // Determine handlers that should run if there are delegated events - // Avoid non-left-click bubbling in Firefox (#3861) - if ( delegateCount && !(event.button && event.type === "click") ) { - - for ( cur = event.target; cur != this; cur = cur.parentNode || this ) { - - // Don't process clicks (ONLY) on disabled elements (#6911, #8165, #11382, #11764) - if ( cur.disabled !== true || event.type !== "click" ) { - selMatch = {}; - matches = []; - for ( i = 0; i < delegateCount; i++ ) { - handleObj = handlers[ i ]; - sel = handleObj.selector; - - if ( selMatch[ sel ] === undefined ) { - selMatch[ sel ] = handleObj.needsContext ? - jQuery( sel, this ).index( cur ) >= 0 : - jQuery.find( sel, this, null, [ cur ] ).length; - } - if ( selMatch[ sel ] ) { - matches.push( handleObj ); - } - } - if ( matches.length ) { - handlerQueue.push({ elem: cur, matches: matches }); - } - } - } - } - - // Add the remaining (directly-bound) handlers - if ( handlers.length > delegateCount ) { - handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) }); - } + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); // Run delegates first; they may want to stop propagation beneath us - for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) { - matched = handlerQueue[ i ]; + i = 0; + while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) { event.currentTarget = matched.elem; - for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) { - handleObj = matched.matches[ j ]; + j = 0; + while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) { // Triggered event must either 1) have no namespace, or // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). - if ( !event.namespace || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) { + if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) { - event.data = handleObj.data; event.handleObj = handleObj; + event.data = handleObj.data; ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) .apply( matched.elem, args ); if ( ret !== undefined ) { - event.result = ret; - if ( ret === false ) { + if ( (event.result = ret) === false ) { event.preventDefault(); event.stopPropagation(); } @@ -3113,6 +3062,90 @@ jQuery.event = { return event.result; }, + handlers: function( event, handlers ) { + var i, matches, sel, handleObj, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + // Black-hole SVG instance trees (#13180) + // Avoid non-left-click bubbling in Firefox (#3861) + if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) { + + for ( ; cur != this; cur = cur.parentNode || this ) { + + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.disabled !== true || event.type !== "click" ) { + matches = []; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matches[ sel ] === undefined ) { + matches[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) >= 0 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matches[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, handlers: matches }); + } + } + } + } + + // Add the remaining (directly-bound) handlers + if ( delegateCount < handlers.length ) { + handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) }); + } + + return handlerQueue; + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, + originalEvent = event, + fixHook = jQuery.event.fixHooks[ event.type ] || {}, + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = new jQuery.Event( originalEvent ); + + i = copy.length; + while ( i-- ) { + prop = copy[ i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Support: IE<9 + // Fix target property (#1925) + if ( !event.target ) { + event.target = originalEvent.srcElement || document; + } + + // Support: Chrome 23+, Safari? + // Target should not be a text node (#504, #13143) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // Support: IE<9 + // For mouse/key events, metaKey==false if it's undefined (#3368, #11328) + event.metaKey = !!event.metaKey; + + return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; + }, + // Includes some event props shared by KeyEvent and MouseEvent props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), @@ -3163,40 +3196,6 @@ jQuery.event = { } }, - fix: function( event ) { - if ( event[ jQuery.expando ] ) { - return event; - } - - // Create a writable copy of the event object and normalize some properties - var i, prop, - originalEvent = event, - fixHook = jQuery.event.fixHooks[ event.type ] || {}, - copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; - - event = jQuery.Event( originalEvent ); - - for ( i = copy.length; i; ) { - prop = copy[ --i ]; - event[ prop ] = originalEvent[ prop ]; - } - - // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2) - if ( !event.target ) { - event.target = originalEvent.srcElement || document; - } - - // Target should not be a text node (#504, Safari) - if ( event.target.nodeType === 3 ) { - event.target = event.target.parentNode; - } - - // For mouse/key events, metaKey==false if it's undefined (#3368, #11328; IE6/7/8) - event.metaKey = !!event.metaKey; - - return fixHook.filter? fixHook.filter( event, originalEvent ) : event; - }, - special: { load: { // Prevent triggered image.load events from bubbling to window.load @@ -3219,8 +3218,9 @@ jQuery.event = { this.focus(); return false; } catch ( e ) { - // IE<9 dies on focus to hidden element (#1486,#12518) - // If this happens, let .trigger() run the handlers + // Support: IE<9 + // If we error on focus to hidden element (#1486, #12518), + // let .trigger() run the handlers } } }, @@ -3270,10 +3270,6 @@ jQuery.event = { } }; -// Some plugins are using, but it's undocumented/deprecated and will be removed. -// The 1.7 special event interface should provide all the hooks needed now. -jQuery.event.handle = jQuery.event.dispatch; - jQuery.removeEvent = document.removeEventListener ? function( elem, type, handle ) { if ( elem.removeEventListener ) { @@ -3328,54 +3324,51 @@ jQuery.Event = function( src, props ) { this[ jQuery.expando ] = true; }; -function returnFalse() { - return false; -} -function returnTrue() { - return true; -} - // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html jQuery.Event.prototype = { - preventDefault: function() { - this.isDefaultPrevented = returnTrue; + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + preventDefault: function() { var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; if ( !e ) { return; } - // if preventDefault exists run it on the original event + // If preventDefault exists, run it on the original event if ( e.preventDefault ) { e.preventDefault(); - // otherwise set the returnValue property of the original event to false (IE) + // Support: IE + // Otherwise set the returnValue property of the original event to false } else { e.returnValue = false; } }, stopPropagation: function() { - this.isPropagationStopped = returnTrue; - var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; if ( !e ) { return; } - // if stopPropagation exists run it on the original event + // If stopPropagation exists, run it on the original event if ( e.stopPropagation ) { e.stopPropagation(); } - // otherwise set the cancelBubble property of the original event to true (IE) + + // Support: IE + // Set the cancelBubble property of the original event to true e.cancelBubble = true; }, stopImmediatePropagation: function() { this.isImmediatePropagationStopped = returnTrue; this.stopPropagation(); - }, - isDefaultPrevented: returnFalse, - isPropagationStopped: returnFalse, - isImmediatePropagationStopped: returnFalse + } }; // Create mouseenter/leave events using mouseover/out and event-time checks @@ -3420,11 +3413,11 @@ if ( !jQuery.support.submitBubbles ) { // Node name check avoids a VML-related crash in IE (#9807) var elem = e.target, form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; - if ( form && !jQuery._data( form, "_submit_attached" ) ) { + if ( form && !jQuery._data( form, "submitBubbles" ) ) { jQuery.event.add( form, "submit._submit", function( event ) { event._submit_bubble = true; }); - jQuery._data( form, "_submit_attached", true ); + jQuery._data( form, "submitBubbles", true ); } }); // return undefined since we don't need an event listener @@ -3483,13 +3476,13 @@ if ( !jQuery.support.changeBubbles ) { jQuery.event.add( this, "beforeactivate._change", function( e ) { var elem = e.target; - if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "_change_attached" ) ) { + if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "changeBubbles" ) ) { jQuery.event.add( elem, "change._change", function( event ) { if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { jQuery.event.simulate( "change", this.parentNode, event, true ); } }); - jQuery._data( elem, "_change_attached", true ); + jQuery._data( elem, "changeBubbles", true ); } }); }, @@ -3544,7 +3537,7 @@ jQuery.fn.extend({ // Types can be a map of types/handlers if ( typeof types === "object" ) { // ( types-Object, selector, data ) - if ( typeof selector !== "string" ) { // && selector != null + if ( typeof selector !== "string" ) { // ( types-Object, data ) data = data || selector; selector = undefined; @@ -3633,15 +3626,6 @@ jQuery.fn.extend({ return this.off( types, null, fn ); }, - live: function( types, data, fn ) { - jQuery( this.context ).on( types, this.selector, data, fn ); - return this; - }, - die: function( types, fn ) { - jQuery( this.context ).off( types, this.selector || "**", fn ); - return this; - }, - delegate: function( selector, types, data, fn ) { return this.on( types, selector, data, fn ); }, @@ -3656,8 +3640,9 @@ jQuery.fn.extend({ }); }, triggerHandler: function( type, data ) { - if ( this[0] ) { - return jQuery.event.trigger( type, data, this[0], true ); + var elem = this[0]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); } }, @@ -3713,18 +3698,19 @@ var i, contains, sortOrder, + // Instance-specific data expando = "sizzle" + -(new Date()), - - strundefined = typeof undefined, - - // Used in sorting - MAX_NEGATIVE = 1 << 31, preferredDoc = window.document, - - Token = String, + support = {}, dirruns = 0, done = 0, - support = {}, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + + // General-purpose constants + strundefined = typeof undefined, + MAX_NEGATIVE = 1 << 31, // Array methods arr = [], @@ -3743,32 +3729,8 @@ var i, return -1; }, - // Augment a function for special use by Sizzle - markFunction = function( fn, value ) { - fn[ expando ] = value == null || value; - return fn; - }, - createCache = function() { - var cache = {}, - keys = []; - - return markFunction(function( key, value ) { - // Only keep the most recent entries - if ( keys.push( key ) > Expr.cacheLength ) { - delete cache[ keys.shift() ]; - } - - // Retrieve with (key + " ") to avoid collision with native Object.prototype properties (see Issue #157) - return (cache[ key + " " ] = value); - }, cache ); - }, - - classCache = createCache(), - tokenCache = createCache(), - compilerCache = createCache(), - - // Regex + // Regular expressions // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace whitespace = "[\\x20\\t\\r\\n\\f]", @@ -3776,7 +3738,7 @@ var i, characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", // Loosely modeled on CSS identifier characters - // An unquoted value should be a CSS identifier (http://www.w3.org/TR/css3-selectors/#attribute-selectors) + // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier identifier = characterEncoding.replace( "w", "w#" ), @@ -3799,21 +3761,7 @@ var i, rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), rcombinators = new RegExp( "^" + whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*" ), rpseudo = new RegExp( pseudos ), - - // Easily-parseable/retrievable ID or TAG or CLASS selectors - rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, - - rsibling = /[\x20\t\r\n\f]*[+~]/, - - rheader = /h\d/i, - rinputs = /input|select|textarea|button/i, - - rnative = /\{\s*\[native code\]\s*\}/, - - rbackslash = /\\(?!\\)/g, - - rescape = /'|\\/g, - rattributeQuotes = /\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g, + ridentifier = new RegExp( "^" + identifier + "$" ), matchExpr = { "ID": new RegExp( "^#(" + characterEncoding + ")" ), @@ -3831,29 +3779,31 @@ var i, whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) }, - /** - * For feature detection - * @param {Function} fn The function to test for native support - */ - isNative = function( fn ) { - return rnative.test( fn + "" ); - }, + rsibling = /[\x20\t\r\n\f]*[+~]/, - /** - * Support testing using an element - * @param {Function} fn Passed the created div and expects a boolean result - */ - assert = function( fn ) { - var div = document.createElement("div"); + rnative = /\{\s*\[native code\]\s*\}/, - try { - return fn( div ); - } catch (e) { - return false; - } finally { - // release memory in IE - div = null; - } + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rescape = /'|\\/g, + rattributeQuotes = /\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g, + + // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = /\\([\da-fA-F]{1,6}[\x20\t\r\n\f]?|.)/g, + funescape = function( _, escaped ) { + var high = "0x" + escaped - 0x10000; + // NaN means non-codepoint + return high !== high ? + escaped : + // BMP codepoint + high < 0 ? + String.fromCharCode( high + 0x10000 ) : + // Supplemental Plane codepoint (surrogate pair) + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); }; // Use a stripped-down slice if we can't use a native one @@ -3870,12 +3820,66 @@ try { }; } +/** + * For feature detection + * @param {Function} fn The function to test for native support + */ +function isNative( fn ) { + return rnative.test( fn + "" ); +} + +/** + * Create key-value caches of limited size + * @returns {Function(string, Object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var cache, + keys = []; + + return (cache = function( key, value ) { + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key += " " ) > Expr.cacheLength ) { + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return (cache[ key ] = value); + }); +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created div and expects a boolean result + */ +function assert( fn ) { + var div = document.createElement("div"); + + try { + return fn( div ); + } catch (e) { + return false; + } finally { + // release memory in IE + div = null; + } +} + function Sizzle( selector, context, results, seed ) { var match, elem, m, nodeType, // QSA vars i, groups, old, nid, newContext, newSelector; - if ( context && (( context.ownerDocument || context ) !== document) ) { + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { setDocument( context ); } @@ -3954,7 +3958,7 @@ function Sizzle( selector, context, results, seed ) { i = groups.length; while ( i-- ) { - groups[i] = nid + groups[i].join(""); + groups[i] = nid + toSelector( groups[i] ); } newContext = rsibling.test( selector ) && context.parentNode || context; newSelector = groups.join(","); @@ -3996,11 +4000,11 @@ isXML = Sizzle.isXML = function( elem ) { * @param {Element|Object} [doc] An element or document object to use to set the document * @returns {Object} Returns the current document */ -setDocument = Sizzle.setDocument = function( doc ) { - doc = doc && doc.ownerDocument || doc || window.document; +setDocument = Sizzle.setDocument = function( node ) { + var doc = node ? node.ownerDocument || node : preferredDoc; // If no document and documentElement is available, return - if ( !doc || doc.nodeType !== 9 || !doc.documentElement || document === doc ) { + if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { return document; } @@ -4087,7 +4091,7 @@ setDocument = Sizzle.setDocument = function( doc ) { } }; Expr.filter["ID"] = function( id ) { - var attrId = id.replace( rbackslash, "" ); + var attrId = id.replace( runescape, funescape ); return function( elem ) { return elem.getAttribute("id") === attrId; }; @@ -4105,7 +4109,7 @@ setDocument = Sizzle.setDocument = function( doc ) { } }; Expr.filter["ID"] = function( id ) { - var attrId = id.replace( rbackslash, "" ); + var attrId = id.replace( runescape, funescape ); return function( elem ) { var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id"); return node && node.value === attrId; @@ -4189,16 +4193,15 @@ setDocument = Sizzle.setDocument = function( doc ) { assert(function( div ) { - // Opera 10-12/IE9 - ^= $= *= and empty values + // Opera 10-12/IE8 - ^= $= *= and empty values // Should not select anything - div.innerHTML = "

"; - if ( div.querySelectorAll("[test^='']").length ) { + div.innerHTML = ""; + if ( div.querySelectorAll("[i^='']").length ) { rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:\"\"|'')" ); } // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) // IE8 throws error here and will not see later tests - div.innerHTML = ""; if ( !div.querySelectorAll(":enabled").length ) { rbuggyQSA.push( ":enabled", ":disabled" ); } @@ -4222,7 +4225,7 @@ setDocument = Sizzle.setDocument = function( doc ) { // This should fail with an exception // Gecko does not error, returns false instead - matches.call( div, "[test!='']:x" ); + matches.call( div, "[s!='']:x" ); rbuggyMatches.push( "!=", pseudos ); }); } @@ -4344,12 +4347,12 @@ setDocument = Sizzle.setDocument = function( doc ) { }; Sizzle.matches = function( expr, elements ) { - return Sizzle( expr, window.document, null, elements ); + return Sizzle( expr, null, null, elements ); }; Sizzle.matchesSelector = function( elem, expr ) { // Set document vars if needed - if ( elem && (( elem.ownerDocument || elem ) !== document) ) { + if ( ( elem.ownerDocument || elem ) !== document ) { setDocument( elem ); } @@ -4376,7 +4379,7 @@ Sizzle.matchesSelector = function( elem, expr ) { Sizzle.contains = function( context, elem ) { // Set document vars if needed - if ( context && (( context.ownerDocument || context ) !== document) ) { + if ( ( context.ownerDocument || context ) !== document ) { setDocument( context ); } return contains( context, elem ); @@ -4386,7 +4389,7 @@ Sizzle.attr = function( elem, name ) { var val; // Set document vars if needed - if ( elem && (( elem.ownerDocument || elem ) !== document) ) { + if ( ( elem.ownerDocument || elem ) !== document ) { setDocument( elem ); } @@ -4535,10 +4538,10 @@ Expr = Sizzle.selectors = { preFilter: { "ATTR": function( match ) { - match[1] = match[1].replace( rbackslash, "" ); + match[1] = match[1].replace( runescape, funescape ); // Move the given value to match[3] whether quoted or unquoted - match[3] = ( match[4] || match[5] || "" ).replace( rbackslash, "" ); + match[3] = ( match[4] || match[5] || "" ).replace( runescape, funescape ); if ( match[2] === "~=" ) { match[3] = " " + match[3] + " "; @@ -4615,14 +4618,14 @@ Expr = Sizzle.selectors = { return function() { return true; }; } - nodeName = nodeName.replace( rbackslash, "" ).toLowerCase(); + nodeName = nodeName.replace( runescape, funescape ).toLowerCase(); return function( elem ) { return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; }; }, "CLASS": function( className ) { - var pattern = classCache[ expando ][ className + " " ]; + var pattern = classCache[ className + " " ]; return pattern || (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && @@ -4824,6 +4827,34 @@ Expr = Sizzle.selectors = { }; }), + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + // lang value must be a valid identifider + if ( !ridentifier.test(lang || "") ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( (elemLang = documentIsXML ? + elem.getAttribute("xml:lang") || elem.getAttribute("lang") : + elem.lang) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); + return false; + }; + }), + // Miscellaneous "target": function( elem ) { var hash = window.location && window.location.hash; @@ -4964,7 +4995,7 @@ for ( i in { submit: true, reset: true } ) { function tokenize( selector, parseOnly ) { var matched, match, tokens, type, soFar, groups, preFilters, - cached = tokenCache[ expando ][ selector + " " ]; + cached = tokenCache[ selector + " " ]; if ( cached ) { return parseOnly ? 0 : cached.slice( 0 ); @@ -4989,22 +5020,26 @@ function tokenize( selector, parseOnly ) { // Combinators if ( (match = rcombinators.exec( soFar )) ) { - tokens.push( matched = new Token( match.shift() ) ); + matched = match.shift(); + tokens.push( { + value: matched, + // Cast descendant combinators to space + type: match[0].replace( rtrim, " " ) + } ); soFar = soFar.slice( matched.length ); - - // Cast descendant combinators to space - matched.type = match[0].replace( rtrim, " " ); } // Filters for ( type in Expr.filter ) { if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || (match = preFilters[ type ]( match ))) ) { - - tokens.push( matched = new Token( match.shift() ) ); + matched = match.shift(); + tokens.push( { + value: matched, + type: type, + matches: match + } ); soFar = soFar.slice( matched.length ); - matched.type = type; - matched.matches = match; } } @@ -5024,6 +5059,16 @@ function tokenize( selector, parseOnly ) { tokenCache( selector, groups ).slice( 0 ); } +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[i].value; + } + return selector; +} + function addCombinator( matcher, combinator, base ) { var dir = combinator.dir, checkNonElements = base && combinator.dir === "parentNode", @@ -5240,11 +5285,11 @@ function matcherFromTokens( tokens ) { } return setMatcher( i > 1 && elementMatcher( matchers ), - i > 1 && tokens.slice( 0, i - 1 ).join("").replace( rtrim, "$1" ), + i > 1 && toSelector( tokens.slice( 0, i - 1 ) ).replace( rtrim, "$1" ), matcher, i < j && matcherFromTokens( tokens.slice( i, j ) ), j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), - j < len && tokens.join("") + j < len && toSelector( tokens ) ); } matchers.push( matcher ); @@ -5357,7 +5402,7 @@ compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) { var i, setMatchers = [], elementMatchers = [], - cached = compilerCache[ expando ][ selector + " " ]; + cached = compilerCache[ selector + " " ]; if ( !cached ) { // Generate a function of recursive functions that can be used to check each element @@ -5403,12 +5448,12 @@ function select( selector, context, results, seed ) { context.nodeType === 9 && !documentIsXML && Expr.relative[ tokens[1].type ] ) { - context = Expr.find["ID"]( token.matches[0].replace( rbackslash, "" ), context )[0]; + context = Expr.find["ID"]( token.matches[0].replace( runescape, funescape ), context )[0]; if ( !context ) { return results; } - selector = selector.slice( tokens.shift().length ); + selector = selector.slice( tokens.shift().value.length ); } // Fetch a seed set for right-to-left matching @@ -5422,13 +5467,13 @@ function select( selector, context, results, seed ) { if ( (find = Expr.find[ type ]) ) { // Search, expanding context for leading sibling combinators if ( (seed = find( - token.matches[0].replace( rbackslash, "" ), + token.matches[0].replace( runescape, funescape ), rsibling.test( tokens[0].type ) && context.parentNode || context )) ) { // If seed is empty or no tokens remain, we can return early tokens.splice( i, 1 ); - selector = seed.length && tokens.join(""); + selector = seed.length && toSelector( tokens ); if ( !selector ) { push.apply( results, slice.call( seed, 0 ) ); return results; @@ -5780,19 +5825,21 @@ var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figca rscriptType = /^$|\/(?:java|ecma)script/i, rscriptTypeMasked = /^true\/(.*)/, rcleanScript = /^\s*\s*$/g, + + // We have to close these tags to support XHTML (#13200) wrapMap = { - option: [ 1, "", "" ], + legend: [ 1, "
", "
" ], + area: [ 1, "", "" ], + param: [ 1, "", "" ], + thead: [ 1, "", "
" ], + tr: [ 2, "", "
" ], + col: [ 2, "", "
" ], + td: [ 3, "", "
" ], // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, // unless wrapped in a div with non-breaking characters in front of it. - _default: jQuery.support.htmlSerialize ? [ 0, "" ] : [ 1, "X
" ] + _default: jQuery.support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X
", "
" ] }, safeFragment = createSafeFragment( document ), fragmentDiv = safeFragment.appendChild( document.createElement("div") ); @@ -5944,6 +5991,12 @@ jQuery.fn.extend({ while ( elem.firstChild ) { elem.removeChild( elem.firstChild ); } + + // If this is a select, ensure that it displays empty (#12336) + // Support: IE<9 + if ( elem.options && jQuery.nodeName( elem, "select" ) ) { + elem.options.length = 0; + } } return this; @@ -6038,25 +6091,24 @@ jQuery.fn.extend({ var fragment, first, scripts, hasScripts, node, doc, i = 0, l = this.length, + set = this, 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" || jQuery.support.checkClone || !rchecked.test( value ) ) ) { - return this.each(function() { - var self = jQuery( this ); + return this.each(function( index ) { + var self = set.eq( index ); if ( isFunction ) { - args[0] = value.call( this, i, table ? self.html() : undefined ); + args[0] = value.call( this, index, table ? self.html() : undefined ); } self.domManip( args, table, callback ); }); } - if ( this[0] ) { - doc = this[0].ownerDocument; - fragment = doc.createDocumentFragment(); - jQuery.clean( args, doc, fragment, undefined, this ); + if ( l ) { + fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this ); first = fragment.firstChild; if ( fragment.childNodes.length === 1 ) { @@ -6301,7 +6353,7 @@ function getAll( context, tag ) { found; } -// Used in clean, fixes the defaultChecked property +// Used in buildFragment, fixes the defaultChecked property function fixDefaultChecked( elem ) { if ( manipulation_rcheckableType.test( elem.type ) ) { elem.defaultChecked = elem.checked; @@ -6364,36 +6416,38 @@ jQuery.extend({ return clone; }, - clean: function( elems, context, fragment, scripts, selection ) { - var elem, i, j, tmp, tag, wrap, tbody, - ret = [], - safe = context === document && safeFragment; + buildFragment: function( elems, context, scripts, selection ) { + var contains, elem, tag, tmp, wrap, tbody, j, + l = elems.length, - // Ensure that context is a document - if ( !context || typeof context.createDocumentFragment === "undefined" ) { - context = document; - } + // Ensure a safe fragment + safe = createSafeFragment( context ), + + nodes = [], + i = 0; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; - for ( i = 0; (elem = elems[i]) != null; i++ ) { if ( elem || elem === 0 ) { + // Add nodes directly if ( jQuery.type( elem ) === "object" ) { - jQuery.merge( ret, elem.nodeType ? [ elem ] : elem ); + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); // Convert non-html into a text node } else if ( !rhtml.test( elem ) ) { - ret.push( context.createTextNode( elem ) ); + nodes.push( context.createTextNode( elem ) ); // Convert html into DOM nodes } else { - // Ensure a safe container - safe = safe || createSafeFragment( context ); tmp = tmp || safe.appendChild( context.createElement("div") ); // Deserialize a standard representation tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase(); wrap = wrapMap[ tag ] || wrapMap._default; - tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1>" ) + ( wrap[2] || "" ); + + tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1>" ) + wrap[2]; // Descend through wrappers to the right content j = wrap[0]; @@ -6403,7 +6457,7 @@ jQuery.extend({ // Manually add leading whitespace removed by IE if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { - ret.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) ); + nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) ); } // Remove IE's autoinserted from table fragments @@ -6426,7 +6480,7 @@ jQuery.extend({ } } - jQuery.merge( ret, tmp.childNodes ); + jQuery.merge( nodes, tmp.childNodes ); // Fix #12392 for WebKit and IE > 9 tmp.textContent = ""; @@ -6442,7 +6496,7 @@ jQuery.extend({ } } - // Fix #11356: Clear elements from safeFragment + // Fix #11356: Clear elements from fragment if ( tmp ) { safe.removeChild( tmp ); } @@ -6450,40 +6504,42 @@ jQuery.extend({ // Reset defaultChecked for any radios and checkboxes // about to be appended to the DOM in IE 6/7 (#8060) if ( !jQuery.support.appendChecked ) { - jQuery.grep( getAll( ret, "input" ), fixDefaultChecked ); + jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked ); } - if ( fragment ) { - for ( i = 0; (elem = ret[i]) != null; i++ ) { - safe = jQuery.contains( elem.ownerDocument, elem ); + i = 0; + while ( (elem = nodes[ i++ ]) ) { - // Append to fragment - // #4087 - If origin and destination elements are the same, and this is - // that element, do not append to fragment - if ( !selection || jQuery.inArray( elem, selection ) === -1 ) { - fragment.appendChild( elem ); - } - tmp = getAll( elem, "script" ); + // #4087 - If origin and destination elements are the same, and this is + // that element, do not do anything + if ( selection && jQuery.inArray( elem, selection ) !== -1 ) { + continue; + } - // Preserve script evaluation history - if ( safe ) { - setGlobalEval( tmp ); - } + contains = jQuery.contains( elem.ownerDocument, elem ); - // Capture executables - if ( scripts ) { - for ( j = 0; (elem = tmp[j]) != null; j++ ) { - if ( rscriptType.test( elem.type || "" ) ) { - scripts.push( elem ); - } + // Append to fragment + tmp = getAll( safe.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( contains ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( (elem = tmp[ j++ ]) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); } } } } - elem = tmp = safe = null; + tmp = null; - return ret; + return safe; }, cleanData: function( elems, /* internal */ acceptData ) { @@ -6525,7 +6581,7 @@ jQuery.extend({ if ( deleteExpando ) { delete elem[ internalKey ]; - } else if ( elem.removeAttribute ) { + } else if ( typeof elem.removeAttribute !== "undefined" ) { elem.removeAttribute( internalKey ); } else { @@ -6754,8 +6810,8 @@ jQuery.extend({ // Fixes #8908, it can be done more correctly by specifing setters in cssHooks, // but it would mean to define eight (for every problematic property) identical functions - if ( value === "" && name.indexOf("background") === 0 ) { - value = " "; + if ( !jQuery.support.clearCloneStyle && value === "" && name.indexOf("background") === 0 ) { + style[ name ] = "inherit"; } // If a hook was provided, use that value, otherwise just set the specified value @@ -7309,7 +7365,7 @@ var // Document location ajaxLocParts, ajaxLocation, - + ajax_nonce = jQuery.now(), ajax_rquery = /\?/, @@ -8609,6 +8665,7 @@ function createTweens( animation, props ) { function Animation( elem, properties, options ) { var result, + stopped, index = 0, length = animationPrefilters.length, deferred = jQuery.Deferred().always( function() { @@ -8616,6 +8673,9 @@ function Animation( elem, properties, options ) { delete tick.elem; }), tick = function() { + if ( stopped ) { + return false; + } var currentTime = fxNow || createFxNow(), remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497) @@ -8657,7 +8717,10 @@ function Animation( elem, properties, options ) { // if we are going to the end, we want to run all the tweens // otherwise we skip this part length = gotoEnd ? animation.tweens.length : 0; - + if ( stopped ) { + return this; + } + stopped = true; for ( ; index < length ; index++ ) { animation.tweens[ index ].run( 1 ); } @@ -8691,9 +8754,9 @@ function Animation( elem, properties, options ) { jQuery.fx.timer( jQuery.extend( tick, { + elem: elem, anim: animation, - queue: animation.opts.queue, - elem: elem + queue: animation.opts.queue }) ); @@ -9014,12 +9077,15 @@ jQuery.fn.extend({ doAnimation = function() { // Operate on a copy of prop so per-property easing won't be lost var anim = Animation( this, jQuery.extend( {}, prop ), optall ); - - // Empty animations resolve immediately - if ( empty ) { + doAnimation.finish = function() { + anim.stop( true ); + }; + // Empty animations, or finishing resolves immediately + if ( empty || jQuery._data( this, "finish" ) ) { anim.stop( true ); } }; + doAnimation.finish = doAnimation; return empty || optall.queue === false ? this.each( doAnimation ) : @@ -9074,6 +9140,47 @@ jQuery.fn.extend({ jQuery.dequeue( this, type ); } }); + }, + finish: function( type ) { + if ( type !== false ) { + type = type || "fx"; + } + return this.each(function() { + var index, + data = jQuery._data( this ), + queue = data[ type + "queue" ], + hooks = data[ type + "queueHooks" ], + timers = jQuery.timers, + length = queue ? queue.length : 0; + + // enable finishing flag on private data + data.finish = true; + + // empty the queue first + jQuery.queue( this, type, [] ); + + if ( hooks && hooks.cur && hooks.cur.finish ) { + hooks.cur.finish.call( this ); + } + + // look for any active animations, and finish them + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && timers[ index ].queue === type ) { + timers[ index ].anim.stop( true ); + timers.splice( index, 1 ); + } + } + + // look for any animations in the old queue and finish them + for ( index = 0; index < length; index++ ) { + if ( queue[ index ] && queue[ index ].finish ) { + queue[ index ].finish.call( this ); + } + } + + // turn off finishing flag + delete data.finish; + }); } }); diff --git a/wp-includes/script-loader.php b/wp-includes/script-loader.php index 1e11ccda19..099ced0f3e 100644 --- a/wp-includes/script-loader.php +++ b/wp-includes/script-loader.php @@ -126,8 +126,8 @@ function wp_default_scripts( &$scripts ) { // jQuery $scripts->add( 'jquery', false, array( 'jquery-core', 'jquery-migrate' ) ); - $scripts->add( 'jquery-core', '/wp-includes/js/jquery/jquery.js', array(), '1.9.0b1' ); - $scripts->add( 'jquery-migrate', '/wp-includes/js/jquery/jquery-migrate.js', array(), '1.0.0b1' ); + $scripts->add( 'jquery-core', '/wp-includes/js/jquery/jquery.js', array(), '1.9.0' ); + $scripts->add( 'jquery-migrate', '/wp-includes/js/jquery/jquery-migrate.js', array(), '1.0.0' ); // full jQuery UI $scripts->add( 'jquery-ui-core', '/wp-includes/js/jquery/ui/jquery.ui.core.min.js', array('jquery'), '1.9.2', 1 );