From 247d824d35e81ec96e1a8913674c97fb45dd40ae Mon Sep 17 00:00:00 2001 From: "Rick Waldron waldron.rick@gmail.com" Date: Wed, 18 Apr 2012 13:49:37 -0400 Subject: [PATCH] Revert "Closes #741: Remove $("body") case in favor of $(document.body)." This reverts commit 532ba250a9f6c5b0f51ec53d68aef9fb148e8dd6. --- MIT-LICENSE.txt | 2 +- build/jshint-check.js | 3 +- src/ajax.js | 18 +-- src/attributes.js | 7 +- src/callbacks.js | 4 +- src/core.js | 13 +- src/css.js | 141 ++++++----------- src/data.js | 6 +- src/deferred.js | 24 ++- src/dimensions.js | 4 +- src/effects.js | 5 +- src/event.js | 26 ++-- src/manipulation.js | 311 +++++++++++++++++++++----------------- src/offset.js | 59 +++++++- src/support.js | 54 +++++-- src/traversing.js | 2 +- test/data/testinit.js | 51 +------ test/unit/ajax.js | 34 ++--- test/unit/attributes.js | 55 ++++--- test/unit/callbacks.js | 292 +++++++++++++++++------------------ test/unit/core.js | 33 ++-- test/unit/css.js | 12 -- test/unit/data.js | 6 + test/unit/deferred.js | 70 ++++----- test/unit/dimensions.js | 57 +------ test/unit/effects.js | 9 -- test/unit/event.js | 11 -- test/unit/manipulation.js | 60 ++------ test/unit/support.js | 24 +++ test/unit/traversing.js | 15 +- 30 files changed, 639 insertions(+), 769 deletions(-) diff --git a/MIT-LICENSE.txt b/MIT-LICENSE.txt index 7bf75e8a3..532704636 100644 --- a/MIT-LICENSE.txt +++ b/MIT-LICENSE.txt @@ -1,4 +1,4 @@ -Copyright (c) 2012 John Resig, http://jquery.com/ +Copyright (c) 2011 John Resig, http://jquery.com/ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/build/jshint-check.js b/build/jshint-check.js index b33beaad5..259453931 100644 --- a/build/jshint-check.js +++ b/build/jshint-check.js @@ -12,8 +12,7 @@ smarttabs: true, predef: [ "define", - "DOMParser", - "WebKitPoint" + "DOMParser" ], maxerr: 100 }; diff --git a/src/ajax.js b/src/ajax.js index 3de192766..2bcc1d0a2 100644 --- a/src/ajax.js +++ b/src/ajax.js @@ -426,8 +426,6 @@ jQuery.extend({ fireGlobals, // Loop variable i, - // Default abort message - strAbort = "canceled", // Fake xhr jqXHR = { @@ -473,7 +471,7 @@ jQuery.extend({ // Cancel the request abort: function( statusText ) { - statusText = statusText || strAbort; + statusText = statusText || "abort"; if ( transport ) { transport.abort( statusText ); } @@ -611,7 +609,7 @@ jQuery.extend({ } } else { tmp = map[ jqXHR.status ]; - jqXHR.always( tmp ); + jqXHR.then( tmp, tmp ); } } return this; @@ -645,7 +643,7 @@ jQuery.extend({ // If request was aborted inside a prefilter, stop there if ( state === 2 ) { - return jqXHR; + return false; } // We can fire global events as of now if asked to @@ -718,14 +716,12 @@ jQuery.extend({ // Allow custom headers/mimetypes and early abort if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) { - // Abort if not done already and return - return jqXHR.abort(); + // Abort if not done already + jqXHR.abort(); + return false; } - // aborting is no longer a cancelation - strAbort = "abort"; - // Install callbacks on deferreds for ( i in { success: 1, error: 1, complete: 1 } ) { jqXHR[ i ]( s[ i ] ); @@ -773,7 +769,7 @@ jQuery.extend({ var s = [], add = function( key, value ) { // If value is a function, invoke it and return its value - value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value ); + value = jQuery.isFunction( value ) ? value() : value; s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value ); }; diff --git a/src/attributes.js b/src/attributes.js index 4ec364cb7..df7ed028e 100644 --- a/src/attributes.js +++ b/src/attributes.js @@ -356,12 +356,7 @@ jQuery.extend({ i = 0; if ( value && elem.nodeType === 1 ) { - - if ( !jQuery.isXMLDoc( elem ) ) { - value = value.toLowerCase(); - } - - attrNames = value.split( rspace ); + attrNames = value.toLowerCase().split( rspace ); l = attrNames.length; for ( ; i < l; i++ ) { diff --git a/src/callbacks.js b/src/callbacks.js index 20422c35a..387868604 100644 --- a/src/callbacks.js +++ b/src/callbacks.js @@ -38,9 +38,9 @@ function createFlags( flags ) { */ jQuery.Callbacks = function( flags ) { - // Convert flags from String-formatted to Object-formatted if needed + // Convert flags from String-formatted to Object-formatted // (we check in cache first) - flags = typeof flags === "string" ? ( flagsCache[ flags ] || createFlags( flags ) ) : ( flags || {} ); + flags = flags ? ( flagsCache[ flags ] || createFlags( flags ) ) : {}; var // Actual callback list list = [], diff --git a/src/core.js b/src/core.js index f317666ce..4242903ff 100644 --- a/src/core.js +++ b/src/core.js @@ -90,6 +90,15 @@ jQuery.fn = jQuery.prototype = { return this; } + // The body element only exists once, optimize finding it + if ( selector === "body" && !context && document.body ) { + this.context = document; + this[0] = document.body; + this.selector = selector; + this.length = 1; + return this; + } + // Handle HTML strings if ( typeof selector === "string" ) { // Are we dealing with HTML string or an ID? @@ -123,7 +132,7 @@ jQuery.fn = jQuery.prototype = { } } else { - ret = jQuery.buildFragment( [ match[1] ], doc ); + ret = jQuery.buildFragment( [ match[1] ], [ doc ] ); selector = ( ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment ).childNodes; } @@ -191,7 +200,7 @@ jQuery.fn = jQuery.prototype = { }, toArray: function() { - return slice.call( this ); + return slice.call( this, 0 ); }, // Get the Nth element in the matched element set OR diff --git a/src/css.js b/src/css.js index a4d31a62c..960ac5ae6 100644 --- a/src/css.js +++ b/src/css.js @@ -13,35 +13,12 @@ var ralpha = /alpha\([^)]*\)/i, // order is important! cssExpand = [ "Top", "Right", "Bottom", "Left" ], - cssPrefixes = [ "O", "Webkit", "Moz", "ms" ], curCSS, + getComputedStyle, currentStyle; -// return a css property mapped to a potentially vendor prefixed property -function vendorPropName( style, name ) { - - // shortcut for names that are not vendor prefixed - if ( name in style ) { - return name; - } - - // check for vendor prefixed names - var capName = name.charAt(0).toUpperCase() + name.slice(1), - origName = name, - i = cssPrefixes.length; - - while ( i-- ) { - name = cssPrefixes[ i ] + capName; - if ( name in style ) { - return name; - } - } - - return origName; -} - jQuery.fn.css = function( name, value ) { return jQuery.access( this, function( elem, name, value ) { return value !== undefined ? @@ -95,15 +72,10 @@ jQuery.extend({ } // Make sure that we're working with the right name - var ret, type, hooks, - origName = jQuery.camelCase( name ), - style = elem.style; + var ret, type, origName = jQuery.camelCase( name ), + style = elem.style, hooks = jQuery.cssHooks[ origName ]; - name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) ); - - // gets hook for the prefixed version - // followed by the unprefixed version - hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + name = jQuery.cssProps[ origName ] || origName; // Check if we're setting a value if ( value !== undefined ) { @@ -147,15 +119,12 @@ jQuery.extend({ }, css: function( elem, name, extra ) { - var ret, hooks, - origName = jQuery.camelCase( name ); + var ret, hooks; // Make sure that we're working with the right name - name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) ); - - // gets hook for the prefixed version - // followed by the unprefixed version - hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + name = jQuery.camelCase( name ); + hooks = jQuery.cssHooks[ name ]; + name = jQuery.cssProps[ name ] || name; // cssFloat needs a special treatment if ( name === "cssFloat" ) { @@ -272,67 +241,51 @@ curCSS = getComputedStyle || currentStyle; function getWidthOrHeight( elem, name, extra ) { - // Start with offset property, which is equivalent to the border-box value + // Start with offset property var val = name === "width" ? elem.offsetWidth : elem.offsetHeight, i = name === "width" ? 1 : 0, - len = 4, - valueIsBorderBox = true, - isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box"; + len = 4; - if ( val <= 0 ) { - // Fall back to computed then uncomputed css if necessary - val = curCSS( elem, name ); - if ( val < 0 || val == null ) { - val = elem.style[ name ]; - } - - // Computed unit is not pixels. Stop here and return. - if ( rnumnonpx.test(val) ) { - return val; - } - - // we need the check for style in case a browser which returns unreliable values - // for getComputedStyle silently falls back to the reliable elem.style - valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] ); - - // Normalize "", auto, and prepare for extra - val = parseFloat( val ) || 0; - } - - // determine which box-sizing width we're supposed to be getting - if ( !extra ) { - extra = isBorderBox ? "border" : "content"; - } - - // if the measurement we need is already represented by the retrieved width - // there's no need to augment further - if ( extra !== (valueIsBorderBox ? "border" : "content") ) { - for ( ; i < len; i += 2 ) { - // both box models exclude margin, so add it if we want it - if ( extra === "margin" ) { - // we use jQuery.css instead of curCSS here - // because of the reliableMarginRight CSS hook! - val += parseFloat( jQuery.css( elem, extra + cssExpand[ i ] ) ) || 0; + if ( val > 0 ) { + if ( extra !== "border" ) { + for ( ; i < len; i += 2 ) { + if ( !extra ) { + val -= parseFloat( jQuery.css( elem, "padding" + cssExpand[ i ] ) ) || 0; + } + if ( extra === "margin" ) { + val += parseFloat( jQuery.css( elem, extra + cssExpand[ i ] ) ) || 0; + } else { + val -= parseFloat( jQuery.css( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0; + } } + } - if ( valueIsBorderBox ) { - // border-box includes padding, so remove it if we want content - if ( extra === "content" ) { - val -= parseFloat( curCSS( elem, "padding" + cssExpand[ i ] ) ) || 0; - } + return val + "px"; + } - // at this point, extra isnt border nor margin, so remove border - if ( extra !== "margin" ) { - val -= parseFloat( curCSS( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0; - } - } else { - // at this point, extra isnt content, so add padding - val += parseFloat( curCSS( elem, "padding" + cssExpand[ i ] ) ) || 0; + // Fall back to computed then uncomputed css if necessary + val = curCSS( elem, name ); + if ( val < 0 || val == null ) { + val = elem.style[ name ]; + } - // at this point, extra isnt content nor padding, so add border - if ( extra !== "padding" ) { - val += parseFloat( curCSS( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0; - } + // Computed unit is not pixels. Stop here and return. + if ( rnumnonpx.test(val) ) { + return val; + } + + // Normalize "", auto, and prepare for extra + val = parseFloat( val ) || 0; + + // Add padding, border, margin + if ( extra ) { + for ( ; i < len; i += 2 ) { + val += parseFloat( jQuery.css( elem, "padding" + cssExpand[ i ] ) ) || 0; + if ( extra !== "padding" ) { + val += parseFloat( jQuery.css( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0; + } + if ( extra === "margin" ) { + val += parseFloat( jQuery.css( elem, extra + cssExpand[ i ]) ) || 0; } } } @@ -367,7 +320,7 @@ if ( !jQuery.support.opacity ) { get: function( elem, computed ) { // IE uses filters for opacity return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ? - ( 0.01 * parseFloat( RegExp.$1 ) ) + "" : + ( parseFloat( RegExp.$1 ) / 100 ) + "" : computed ? "1" : ""; }, diff --git a/src/data.js b/src/data.js index ff4309f1e..017bd2efd 100644 --- a/src/data.js +++ b/src/data.js @@ -6,8 +6,6 @@ var rbrace = /^(?:\{.*\}|\[.*\])$/, jQuery.extend({ cache: {}, - deletedIds: [], - // Please use with caution uuid: 0, @@ -61,7 +59,7 @@ jQuery.extend({ // Only DOM nodes need a new unique ID for each element since their data // ends up in the global cache if ( isNode ) { - elem[ internalKey ] = id = jQuery.deletedIds.pop() || ++jQuery.uuid; + elem[ internalKey ] = id = ++jQuery.uuid; } else { id = internalKey; } @@ -214,8 +212,6 @@ jQuery.extend({ // We destroyed the cache and need to eliminate the expando on the node to avoid // false lookups in the cache for entries that no longer exist if ( isNode ) { - jQuery.deletedIds.push( id ); - // IE does not allow us to delete expando properties from nodes, // nor does it have a removeAttribute function on Document nodes; // we must handle all of these cases diff --git a/src/deferred.js b/src/deferred.js index 0cb9e06a5..c97084b70 100644 --- a/src/deferred.js +++ b/src/deferred.js @@ -28,11 +28,15 @@ jQuery.extend({ isResolved: doneList.fired, isRejected: failList.fired, + then: function( doneCallbacks, failCallbacks, progressCallbacks ) { + deferred.done( doneCallbacks ).fail( failCallbacks ).progress( progressCallbacks ); + return this; + }, always: function() { deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments ); return this; }, - then: function( fnDone, fnFail, fnProgress ) { + pipe: function( fnDone, fnFail, fnProgress ) { return jQuery.Deferred(function( newDefer ) { jQuery.each( { done: [ fnDone, "resolve" ], @@ -46,7 +50,7 @@ jQuery.extend({ deferred[ handler ](function() { returned = fn.apply( this, arguments ); if ( returned && jQuery.isFunction( returned.promise ) ) { - returned.promise().done( newDefer.resolve ).fail( newDefer.reject ).progress( newDefer.notify ); + returned.promise().then( newDefer.resolve, newDefer.reject, newDefer.notify ); } else { newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] ); } @@ -70,15 +74,9 @@ jQuery.extend({ return obj; } }, - deferred, + deferred = promise.promise({}), key; - // Keep pipe for back-compat - promise.pipe = promise.then; - - // Construct deferred - deferred = promise.promise({}); - for ( key in lists ) { deferred[ key ] = lists[ key ].fire; deferred[ key + "With" ] = lists[ key ].fireWith; @@ -102,7 +100,7 @@ jQuery.extend({ // Deferred helper when: function( firstParam ) { - var args = sliceDeferred.call( arguments ), + var args = sliceDeferred.call( arguments, 0 ), i = 0, length = args.length, pValues = new Array( length ), @@ -114,7 +112,7 @@ jQuery.extend({ promise = deferred.promise(); function resolveFunc( i ) { return function( value ) { - args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments ) : value; + args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; if ( !( --count ) ) { deferred.resolveWith( deferred, args ); } @@ -122,14 +120,14 @@ jQuery.extend({ } function progressFunc( i ) { return function( value ) { - pValues[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments ) : value; + pValues[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; deferred.notifyWith( promise, pValues ); }; } if ( length > 1 ) { for ( ; i < length; i++ ) { if ( args[ i ] && args[ i ].promise && jQuery.isFunction( args[ i ].promise ) ) { - args[ i ].promise().done( resolveFunc(i) ).fail( deferred.reject ).progress( progressFunc(i) ); + args[ i ].promise().then( resolveFunc(i), deferred.reject, progressFunc(i) ); } else { --count; } diff --git a/src/dimensions.js b/src/dimensions.js index 9ea688d76..64da9f4f2 100644 --- a/src/dimensions.js +++ b/src/dimensions.js @@ -59,13 +59,13 @@ jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { // Get width or height on the element if ( value === undefined ) { - orig = jQuery.css( elem, type, "content" ); + orig = jQuery.css( elem, type ); ret = parseFloat( orig ); return jQuery.isNumeric( ret ) ? ret : orig; } // Set the width or height on the element - jQuery.style( elem, type, value ); + jQuery( elem ).css( type, value ); }, type, value, arguments.length, null ); }; }); diff --git a/src/effects.js b/src/effects.js index 24d3d34a8..e154d2bd4 100644 --- a/src/effects.js +++ b/src/effects.js @@ -4,7 +4,6 @@ var elemdisplay = {}, iframe, iframeDoc, rfxtypes = /^(?:toggle|show|hide)$/, rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i, - rMarginProp = /^margin/, timerId, fxAttrs = [ // height animations @@ -637,8 +636,8 @@ jQuery.extend( jQuery.fx, { // Ensure props that can't be negative don't go there on undershoot easing jQuery.each( fxAttrs.concat.apply( [], fxAttrs ), function( i, prop ) { - // Exclude marginTop, marginLeft, marginBottom and marginRight from this list - if ( !rMarginProp.test( prop ) ) { + // exclude marginTop, marginLeft, marginBottom and marginRight from this list + if ( prop.indexOf( "margin" ) ) { jQuery.fx.step[ prop ] = function( fx ) { jQuery.style( fx.elem, prop, Math.max(0, fx.now) + fx.unit ); }; diff --git a/src/event.js b/src/event.js index 46036c5cf..621464fdd 100644 --- a/src/event.js +++ b/src/event.js @@ -154,7 +154,7 @@ jQuery.event = { var elemData = jQuery.hasData( elem ) && jQuery._data( elem ), t, tns, type, origType, namespaces, origCount, - j, events, special, eventType, handleObj; + j, events, special, handle, eventType, handleObj; if ( !elemData || !(events = elemData.events) ) { return; @@ -213,11 +213,14 @@ jQuery.event = { // Remove the expando if it's no longer used if ( jQuery.isEmptyObject( events ) ) { - delete elemData.handle; + handle = elemData.handle; + if ( handle ) { + handle.elem = null; + } // removeData also checks for emptiness and clears the expando if empty // so use it instead of delete - jQuery.removeData( elem, "events", true ); + jQuery.removeData( elem, [ "events", "handle" ], true ); } }, @@ -386,7 +389,7 @@ jQuery.event = { var handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []), delegateCount = handlers.delegateCount, - args = [].slice.call( arguments ), + args = [].slice.call( arguments, 0 ), run_all = !event.exclusive && !event.namespace, special = jQuery.event.special[ event.type ] || {}, handlerQueue = [], @@ -633,17 +636,8 @@ jQuery.removeEvent = document.removeEventListener ? } } : function( elem, type, handle ) { - var name = "on" + type; - if ( elem.detachEvent ) { - - // #8545, #7054, preventing memory leaks for custom events in IE6-8 – - // detachEvent needed property on element, by name of that event, to properly expose it to GC - if ( typeof elem[ name ] === "undefined" ) { - elem[ name ] = null; - } - - elem.detachEvent( name, handle ); + elem.detachEvent( "on" + type, handle ); } }; @@ -825,9 +819,8 @@ if ( !jQuery.support.changeBubbles ) { jQuery.event.add( this, "click._change", function( event ) { if ( this._just_changed && !event.isTrigger ) { this._just_changed = false; + jQuery.event.simulate( "change", this, event, true ); } - // Allow triggered, simulated change events (#11500) - jQuery.event.simulate( "change", this, event, true ); }); } return false; @@ -1074,3 +1067,4 @@ jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblcl }); })( jQuery ); + diff --git a/src/manipulation.js b/src/manipulation.js index cc6acee82..2a3757904 100644 --- a/src/manipulation.js +++ b/src/manipulation.js @@ -22,10 +22,9 @@ var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figca rtagName = /<([\w:]+)/, rtbody = /]", "i"), - rcheckableType = /^(?:checkbox|radio)$/, // checked="checked" or checked rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, rscriptType = /\/(java|ecma)script/i, @@ -40,17 +39,15 @@ var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figca area: [ 1, "", "" ], _default: [ 0, "", "" ] }, - safeFragment = createSafeFragment( document ), - fragmentDiv = safeFragment.appendChild( document.createElement("div") ); + safeFragment = createSafeFragment( document ); wrapMap.optgroup = wrapMap.option; wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; wrapMap.th = wrapMap.td; -// 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. +// IE can't serialize and