diff options
author | Rick Waldron waldron.rick@gmail.com <waldron.rick@gmail.com> | 2012-04-18 13:49:37 -0400 |
---|---|---|
committer | Rick Waldron waldron.rick@gmail.com <waldron.rick@gmail.com> | 2012-04-18 13:49:37 -0400 |
commit | 247d824d35e81ec96e1a8913674c97fb45dd40ae (patch) | |
tree | e35343a252d755f9c5b8295a77f9e8ad5ff27e12 | |
parent | 532ba250a9f6c5b0f51ec53d68aef9fb148e8dd6 (diff) | |
download | jquery-247d824d35e81ec96e1a8913674c97fb45dd40ae.tar.gz jquery-247d824d35e81ec96e1a8913674c97fb45dd40ae.zip |
Revert "Closes #741: Remove $("body") case in favor of $(document.body)."
This reverts commit 532ba250a9f6c5b0f51ec53d68aef9fb148e8dd6.
-rw-r--r-- | MIT-LICENSE.txt | 2 | ||||
-rw-r--r-- | build/jshint-check.js | 3 | ||||
-rw-r--r-- | src/ajax.js | 18 | ||||
-rw-r--r-- | src/attributes.js | 7 | ||||
-rw-r--r-- | src/callbacks.js | 4 | ||||
-rw-r--r-- | src/core.js | 13 | ||||
-rw-r--r-- | src/css.js | 131 | ||||
-rw-r--r-- | src/data.js | 6 | ||||
-rw-r--r-- | src/deferred.js | 24 | ||||
-rw-r--r-- | src/dimensions.js | 4 | ||||
-rw-r--r-- | src/effects.js | 5 | ||||
-rw-r--r-- | src/event.js | 26 | ||||
-rw-r--r-- | src/manipulation.js | 309 | ||||
-rw-r--r-- | src/offset.js | 57 | ||||
-rw-r--r-- | src/support.js | 54 | ||||
-rw-r--r-- | src/traversing.js | 2 | ||||
-rw-r--r-- | test/data/testinit.js | 51 | ||||
-rw-r--r-- | test/unit/ajax.js | 34 | ||||
-rw-r--r-- | test/unit/attributes.js | 55 | ||||
-rw-r--r-- | test/unit/callbacks.js | 292 | ||||
-rw-r--r-- | test/unit/core.js | 33 | ||||
-rw-r--r-- | test/unit/css.js | 12 | ||||
-rw-r--r-- | test/unit/data.js | 6 | ||||
-rw-r--r-- | test/unit/deferred.js | 70 | ||||
-rw-r--r-- | test/unit/dimensions.js | 57 | ||||
-rw-r--r-- | test/unit/effects.js | 9 | ||||
-rw-r--r-- | test/unit/event.js | 11 | ||||
-rw-r--r-- | test/unit/manipulation.js | 60 | ||||
-rw-r--r-- | test/unit/support.js | 24 | ||||
-rw-r--r-- | test/unit/traversing.js | 15 |
30 files changed, 632 insertions, 762 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"; - - 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 ]; - } + len = 4; - // Computed unit is not pixels. Stop here and return. - if ( rnumnonpx.test(val) ) { - return val; + 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; + } + } } - // 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 ] ); + return val + "px"; + } - // Normalize "", auto, and prepare for extra - val = parseFloat( val ) || 0; + // Fall back to computed then uncomputed css if necessary + val = curCSS( elem, name ); + if ( val < 0 || val == null ) { + val = elem.style[ name ]; } - // determine which box-sizing width we're supposed to be getting - if ( !extra ) { - extra = isBorderBox ? "border" : "content"; + // Computed unit is not pixels. Stop here and return. + if ( rnumnonpx.test(val) ) { + return val; } - // if the measurement we need is already represented by the retrieved width - // there's no need to augment further - if ( extra !== (valueIsBorderBox ? "border" : "content") ) { + // Normalize "", auto, and prepare for extra + val = parseFloat( val ) || 0; + + // Add padding, border, margin + if ( extra ) { 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; + val += parseFloat( jQuery.css( elem, "padding" + cssExpand[ i ] ) ) || 0; + if ( extra !== "padding" ) { + 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; - } - - // 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; - - // at this point, extra isnt content nor padding, so add border - if ( extra !== "padding" ) { - val += parseFloat( curCSS( 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 = /<tbody/i, rhtml = /<|&#?\w+;/, - rnoInnerhtml = /<(?:script|style|link)/i, + rnoInnerhtml = /<(?:script|style)/i, rnocache = /<(?:script|object|embed|option|style)/i, rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "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, "<map>", "</map>" ], _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 <link> and <script> tags normally if ( !jQuery.support.htmlSerialize ) { - wrapMap._default = [ 1, "X<div>", "</div>" ]; + wrapMap._default = [ 1, "div<div>", "</div>" ]; } jQuery.fn.extend({ @@ -222,9 +219,8 @@ jQuery.fn.extend({ null; } - // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && - ( jQuery.support.htmlSerialize || !rnoshimcache.test( value ) ) && ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && !wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) { @@ -253,7 +249,7 @@ jQuery.fn.extend({ }, replaceWith: function( value ) { - if ( this[0] && this[0].parentNode && this[0].parentNode.nodeType != 11 ) { + if ( this[0] && this[0].parentNode ) { // Make sure that the elements are removed from the DOM before they are inserted // this can help fix replacing a parent with child elements if ( jQuery.isFunction( value ) ) { @@ -279,11 +275,11 @@ jQuery.fn.extend({ jQuery(parent).append( value ); } }); + } else { + return this.length ? + this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) : + this; } - - return this.length ? - this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) : - this; }, detach: function( selector ) { @@ -291,50 +287,62 @@ jQuery.fn.extend({ }, domManip: function( args, table, callback ) { - var results, first, fragment, iNoClone, - i = 0, + var results, first, fragment, parent, value = args[0], - scripts = [], - l = this.length; + scripts = []; // We can't cloneNode fragments that contain checked, in WebKit - if ( !jQuery.support.checkClone && l > 1 && typeof value === "string" && rchecked.test( value ) ) { + if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) { return this.each(function() { - jQuery(this).domManip( args, table, callback ); + jQuery(this).domManip( args, table, callback, true ); }); } if ( jQuery.isFunction(value) ) { return this.each(function(i) { var self = jQuery(this); - args[0] = value.call( this, i, table ? self.html() : undefined ); + args[0] = value.call(this, i, table ? self.html() : undefined); self.domManip( args, table, callback ); }); } if ( this[0] ) { - results = jQuery.buildFragment( args, this, scripts ); + parent = value && value.parentNode; + + // If we're in a fragment, just use that instead of building a new one + if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) { + results = { fragment: parent }; + + } else { + results = jQuery.buildFragment( args, this, scripts ); + } + fragment = results.fragment; - first = fragment.firstChild; if ( fragment.childNodes.length === 1 ) { - fragment = first; + first = fragment = fragment.firstChild; + } else { + first = fragment.firstChild; } if ( first ) { table = table && jQuery.nodeName( first, "tr" ); - // Use the original fragment for the last item instead of the first because it can end up - // being emptied incorrectly in certain situations (#8070). - // Fragments from the fragment cache must always be cloned and never used in place. - for ( iNoClone = results.cacheable || l - 1; i < l; i++ ) { + for ( var i = 0, l = this.length, lastIndex = l - 1; i < l; i++ ) { callback.call( - table && jQuery.nodeName( this[i], "table" ) ? - findOrAppend( this[i], "tbody" ) : + table ? + root(this[i], first) : this[i], - i === iNoClone ? - fragment : - jQuery.clone( fragment, true, true ) + // Make sure that we do not leak memory by inadvertently discarding + // the original fragment (which might have attached data) instead of + // using it; in addition, use the original fragment object for the last + // item instead of first because it can end up being emptied incorrectly + // in certain situations (Bug #8070). + // Fragments from the fragment cache must always be cloned and never used + // in place. + results.cacheable || ( l > 1 && i < lastIndex ) ? + jQuery.clone( fragment, true, true ) : + fragment ); } } @@ -364,8 +372,11 @@ jQuery.fn.extend({ } }); -function findOrAppend( elem, tag ) { - return elem.getElementsByTagName( tag )[0] || elem.appendChild( elem.ownerDocument.createElement( tag ) ); +function root( elem, cur ) { + return jQuery.nodeName(elem, "table") ? + (elem.getElementsByTagName("tbody")[0] || + elem.appendChild(elem.ownerDocument.createElement("tbody"))) : + elem; } function cloneCopyEvent( src, dest ) { @@ -424,15 +435,7 @@ function cloneFixAttributes( src, dest ) { if ( nodeName === "object" ) { dest.outerHTML = src.outerHTML; - // This path appears unavoidable for IE9. When cloning an object - // element in IE9, the outerHTML strategy above is not sufficient. - // If the src has innerHTML and the destination does not, - // copy the src.innerHTML into the dest.innerHTML. #10324 - if ( jQuery.support.html5Clone && (src.innerHTML && !jQuery.trim(dest.innerHTML)) ) { - dest.innerHTML = src.innerHTML; - } - - } else if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + } else if ( nodeName === "input" && (src.type === "checkbox" || src.type === "radio") ) { // IE6-8 fails to persist the checked state of a cloned checkbox // or radio button. Worse, IE6-7 fail to give the cloned element // a checked appearance if the defaultChecked value isn't also set @@ -471,19 +474,22 @@ function cloneFixAttributes( src, dest ) { dest.removeAttribute( "_change_attached" ); } -jQuery.buildFragment = function( args, context, scripts ) { - var fragment, cacheable, cachehit, +jQuery.buildFragment = function( args, nodes, scripts ) { + var fragment, cacheable, cacheresults, doc, first = args[ 0 ]; - // Set context from what may come in as undefined or a jQuery collection or a node - context = context || document; - context = (context[0] || context).ownerDocument || context[0] || context; + // nodes may contain either an explicit document object, + // a jQuery collection or context object. + // If nodes[0] contains a valid object to assign to doc + if ( nodes && nodes[0] ) { + doc = nodes[0].ownerDocument || nodes[0]; + } // Ensure that an attr object doesn't incorrectly stand in as a document object // Chrome and Firefox seem to allow this to occur and will throw exception // Fixes #8950 - if ( typeof context.createDocumentFragment === "undefined" ) { - context = document; + if ( !doc.createDocumentFragment ) { + doc = document; } // Only cache "small" (1/2 KB) HTML strings that are associated with the main document @@ -491,26 +497,26 @@ jQuery.buildFragment = function( args, context, scripts ) { // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache // Lastly, IE6,7,8 will not correctly reuse cached fragments that were created from unknown elems #10501 - if ( args.length === 1 && typeof first === "string" && first.length < 512 && context === document && + if ( args.length === 1 && typeof first === "string" && first.length < 512 && doc === document && first.charAt(0) === "<" && !rnocache.test( first ) && (jQuery.support.checkClone || !rchecked.test( first )) && (jQuery.support.html5Clone || !rnoshimcache.test( first )) ) { - // Mark cacheable and look for a hit cacheable = true; - fragment = jQuery.fragments[ first ]; - cachehit = fragment !== undefined; + + cacheresults = jQuery.fragments[ first ]; + if ( cacheresults && cacheresults !== 1 ) { + fragment = cacheresults; + } } if ( !fragment ) { - fragment = context.createDocumentFragment(); - jQuery.clean( args, context, fragment, scripts ); + fragment = doc.createDocumentFragment(); + jQuery.clean( args, doc, fragment, scripts ); + } - // Update the cache, but only store false - // unless this is a second parsing of the same content - if ( cacheable ) { - jQuery.fragments[ first ] = cachehit && fragment; - } + if ( cacheable ) { + jQuery.fragments[ first ] = cacheresults ? fragment : 1; } return { fragment: fragment, cacheable: cacheable }; @@ -530,9 +536,10 @@ jQuery.each({ insert = jQuery( selector ), parent = this.length === 1 && this[0].parentNode; - if ( (parent == null || parent && parent.nodeType === 11 && parent.childNodes.length === 1) && insert.length === 1 ) { + if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) { insert[ original ]( this[0] ); return this; + } else { for ( var i = 0, l = insert.length; i < l; i++ ) { var elems = ( i > 0 ? this.clone(true) : this ).get(); @@ -559,26 +566,39 @@ function getAll( elem ) { // Used in clean, fixes the defaultChecked property function fixDefaultChecked( elem ) { - if ( rcheckableType.test( elem.type ) ) { + if ( elem.type === "checkbox" || elem.type === "radio" ) { elem.defaultChecked = elem.checked; } } +// Finds all inputs and passes them to fixDefaultChecked +function findInputs( elem ) { + var nodeName = ( elem.nodeName || "" ).toLowerCase(); + if ( nodeName === "input" ) { + fixDefaultChecked( elem ); + // Skip scripts, get other children + } else if ( nodeName !== "script" && typeof elem.getElementsByTagName !== "undefined" ) { + jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked ); + } +} + +// Derived From: http://www.iecss.com/shimprove/javascript/shimprove.1-0-1.js +function shimCloneNode( elem ) { + var div = document.createElement( "div" ); + safeFragment.appendChild( div ); + + div.innerHTML = elem.outerHTML; + return div.firstChild; +} jQuery.extend({ clone: function( elem, dataAndEvents, deepDataAndEvents ) { var srcElements, destElements, i, - clone; - - if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { - clone = elem.cloneNode( true ); - - // IE<=8 does not properly clone detached, unknown element nodes - } else { - fragmentDiv.innerHTML = elem.outerHTML; - fragmentDiv.removeChild( clone = fragmentDiv.firstChild ); - } + // IE<=8 does not properly clone detached, unknown element nodes + clone = jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ? + elem.cloneNode( true ) : + shimCloneNode( elem ); if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) && (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { @@ -626,17 +646,17 @@ jQuery.extend({ }, clean: function( elems, context, fragment, scripts ) { - var j, safe, elem, tag, wrap, depth, div, hasBody, tbody, len, handleScript, jsTags, - i = 0, - ret = []; + var checkScriptType, script, j, + ret = []; + + context = context || document; - // Ensure that context is a document - if ( !context || typeof context.createDocumentFragment === "undefined" ) { - context = document; + // !context.createElement fails in IE with an error but returns typeof 'object' + if ( typeof context.createElement === "undefined" ) { + context = context.ownerDocument || context[0] && context[0].ownerDocument || document; } - // Use the already-created safe fragment if context permits - for ( safe = context === document && safeFragment; (elem = elems[i]) != null; i++ ) { + for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { if ( typeof elem === "number" ) { elem += ""; } @@ -650,17 +670,27 @@ jQuery.extend({ if ( !rhtml.test( elem ) ) { elem = context.createTextNode( elem ); } else { - // Ensure a safe container in which to render the html - safe = safe || createSafeFragment( context ); - div = div || safe.appendChild( context.createElement("div") ); - // Fix "XHTML"-style tags in all browsers elem = elem.replace(rxhtmlTag, "<$1></$2>"); + // Trim whitespace, otherwise indexOf won't work as expected + var tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase(), + wrap = wrapMap[ tag ] || wrapMap._default, + depth = wrap[0], + div = context.createElement("div"), + safeChildNodes = safeFragment.childNodes, + remove; + + // Append wrapper element to unknown element safe doc fragment + if ( context === document ) { + // Use the fragment we've already created for this document + safeFragment.appendChild( div ); + } else { + // Use a fragment created with the owner document + createSafeFragment( context ).appendChild( div ); + } + // Go to html and back, then peel off extra wrappers - tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase(); - wrap = wrapMap[ tag ] || wrapMap._default; - depth = wrap[0]; div.innerHTML = wrap[1] + elem + wrap[2]; // Move to the right depth @@ -672,7 +702,7 @@ jQuery.extend({ if ( !jQuery.support.tbody ) { // String was a <table>, *may* have spurious <tbody> - hasBody = rtbody.test(elem); + var hasBody = rtbody.test(elem), tbody = tag === "table" && !hasBody ? div.firstChild && div.firstChild.childNodes : @@ -695,8 +725,33 @@ jQuery.extend({ elem = div.childNodes; - // Remember the top-level container for proper cleanup - div = safe.lastChild; + // Clear elements from DocumentFragment (safeFragment or otherwise) + // to avoid hoarding elements. Fixes #11356 + if ( div ) { + div.parentNode.removeChild( div ); + + // Guard against -1 index exceptions in FF3.6 + if ( safeChildNodes.length > 0 ) { + remove = safeChildNodes[ safeChildNodes.length - 1 ]; + + if ( remove && remove.parentNode ) { + remove.parentNode.removeChild( remove ); + } + } + } + } + } + + // Resets defaultChecked for any radios and checkboxes + // about to be appended to the DOM in IE 6/7 (#8060) + var len; + if ( !jQuery.support.appendChecked ) { + if ( elem[0] && typeof (len = elem.length) === "number" ) { + for ( j = 0; j < len; j++ ) { + findInputs( elem[j] ); + } + } else { + findInputs( elem ); } } @@ -707,51 +762,22 @@ jQuery.extend({ } } - // Fix #11356: Clear elements from safeFragment - if ( div ) { - safe.removeChild( div ); - div = safe = null; - } - - // Reset defaultChecked for any radios and checkboxes - // about to be appended to the DOM in IE 6/7 (#8060) - if ( !jQuery.support.appendChecked ) { - for ( i = 0; (elem = ret[i]) != null; i++ ) { - if ( jQuery.nodeName( elem, "input" ) ) { - fixDefaultChecked( elem ); - } else if ( typeof elem.getElementsByTagName !== "undefined" ) { - jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked ); - } - } - } - - // Append elements to a provided document fragment 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 ); - } + checkScriptType = function( elem ) { + return !elem.type || rscriptType.test( elem.type ); }; + for ( i = 0; ret[i]; i++ ) { + script = ret[i]; + if ( scripts && jQuery.nodeName( script, "script" ) && (!script.type || rscriptType.test( script.type )) ) { + scripts.push( script.parentNode ? script.parentNode.removeChild( script ) : script ); - 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 ); + } else { + if ( script.nodeType === 1 ) { + var jsTags = jQuery.grep( script.getElementsByTagName( "script" ), checkScriptType ); - // 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; } + fragment.appendChild( script ); } } } @@ -785,20 +811,21 @@ jQuery.extend({ jQuery.removeEvent( elem, type, data.handle ); } } - } - - // Remove cache only if jQuery.event.remove was not removed it before - if ( cache[ id ] ) { - if ( deleteExpando ) { - delete elem[ jQuery.expando ]; - } else if ( elem.removeAttribute ) { - elem.removeAttribute( jQuery.expando ); + // Null the DOM reference to avoid IE6/7/8 leak (#7054) + if ( data.handle ) { + data.handle.elem = null; } + } + + if ( deleteExpando ) { + delete elem[ jQuery.expando ]; - jQuery.deletedIds.push( id ); - delete cache[ id ]; + } else if ( elem.removeAttribute ) { + elem.removeAttribute( jQuery.expando ); } + + delete cache[ id ]; } } } diff --git a/src/offset.js b/src/offset.js index 69c4d72ad..6433a5b7a 100644 --- a/src/offset.js +++ b/src/offset.js @@ -1,12 +1,11 @@ (function( jQuery ) { var getOffset, + rtable = /^t(?:able|d|h)$/i, rroot = /^(?:body|html)$/i; if ( "getBoundingClientRect" in document.documentElement ) { - getOffset = function( elem, doc, docElem ) { - var box; - + getOffset = function( elem, doc, docElem, box ) { try { box = elem.getBoundingClientRect(); } catch(e) {} @@ -30,12 +29,56 @@ if ( "getBoundingClientRect" in document.documentElement ) { } else { getOffset = function( elem, doc, docElem ) { - if ( !jQuery.contains( docElem, elem ) ) { - return { top: 0, left: 0 }; + var computedStyle, + offsetParent = elem.offsetParent, + prevOffsetParent = elem, + body = doc.body, + defaultView = doc.defaultView, + prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle, + top = elem.offsetTop, + left = elem.offsetLeft; + + while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) { + if ( jQuery.support.fixedPosition && prevComputedStyle.position === "fixed" ) { + break; + } + + computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle; + top -= elem.scrollTop; + left -= elem.scrollLeft; + + if ( elem === offsetParent ) { + top += elem.offsetTop; + left += elem.offsetLeft; + + if ( jQuery.support.doesNotAddBorder && !(jQuery.support.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) { + top += parseFloat( computedStyle.borderTopWidth ) || 0; + left += parseFloat( computedStyle.borderLeftWidth ) || 0; + } + + prevOffsetParent = offsetParent; + offsetParent = elem.offsetParent; + } + + if ( jQuery.support.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) { + top += parseFloat( computedStyle.borderTopWidth ) || 0; + left += parseFloat( computedStyle.borderLeftWidth ) || 0; + } + + prevComputedStyle = computedStyle; + } + + if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) { + top += body.offsetTop; + left += body.offsetLeft; + } + + if ( jQuery.support.fixedPosition && prevComputedStyle.position === "fixed" ) { + top += Math.max( docElem.scrollTop, body.scrollTop ); + left += Math.max( docElem.scrollLeft, body.scrollLeft ); } - var point = getWindow( doc ).webkitConvertPointFromNodeToPage( elem, new WebKitPoint( 0, 0 ) ); - return { top: point.y, left: point.x }; + return { top: top, left: left }; }; } diff --git a/src/support.js b/src/support.js index 8e50a15b7..baebaa2a0 100644 --- a/src/support.js +++ b/src/support.js @@ -91,8 +91,7 @@ jQuery.support = (function() { inlineBlockNeedsLayout: false, shrinkWrapBlocks: false, reliableMarginRight: true, - pixelMargin: true, - boxSizingReliable: true + pixelMargin: true }; // jQuery.boxModel DEPRECATED in 1.3, use jQuery.support.boxModel instead @@ -179,9 +178,9 @@ jQuery.support = (function() { // Run tests that need a body at doc ready jQuery(function() { - var container, offsetSupport, marginDiv, - conMarginTop = 1, - boxSizingPrefixes = [ "", "-moz-", "-webkit-", "" ], + var container, outer, inner, table, td, offsetSupport, + marginDiv, conMarginTop, style, html, positionTopLeftWidthHeight, + paddingMarginBorderVisibility, paddingMarginBorder, body = document.getElementsByTagName("body")[0]; if ( !body ) { @@ -189,8 +188,17 @@ jQuery.support = (function() { return; } + conMarginTop = 1; + paddingMarginBorder = "padding:0;margin:0;border:"; + positionTopLeftWidthHeight = "position:absolute;top:0;left:0;width:1px;height:1px;"; + paddingMarginBorderVisibility = paddingMarginBorder + "0;visibility:hidden;"; + style = "style='" + positionTopLeftWidthHeight + paddingMarginBorder + "5px solid #000;"; + html = "<div " + style + "display:block;'><div style='" + paddingMarginBorder + "0;display:block;overflow:hidden;'></div></div>" + + "<table " + style + "' cellpadding='0' cellspacing='0'>" + + "<tr><td></td></tr></table>"; + container = document.createElement("div"); - container.style.cssText = "visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:" + conMarginTop + "px"; + container.style.cssText = paddingMarginBorderVisibility + "width:0;height:0;position:static;top:0;margin-top:" + conMarginTop + "px"; body.insertBefore( container, body.firstChild ); // Construct the test element @@ -204,7 +212,7 @@ jQuery.support = (function() { // 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 = "<table><tr><td style='padding:0;margin:0;border:0;display:none'></td><td>t</td></tr></table>"; + div.innerHTML = "<table><tr><td style='" + paddingMarginBorder + "0;display:none'></td><td>t</td></tr></table>"; tds = div.getElementsByTagName( "td" ); isSupported = ( tds[ 0 ].offsetHeight === 0 ); @@ -252,17 +260,35 @@ jQuery.support = (function() { support.shrinkWrapBlocks = ( div.offsetWidth !== 3 ); } - div.style.cssText = boxSizingPrefixes.join("box-sizing:border-box;") + "border:1px;width:4px;padding:1px;display:block;margin-top:1%;"; - support.boxSizing = ( div.offsetWidth === 4 ); - if ( window.getComputedStyle ) { - support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px"; - support.pixelMargin = ( window.getComputedStyle( div, null ) || { marginTop: 0 } ).marginTop !== "1%"; - } + div.style.cssText = positionTopLeftWidthHeight + paddingMarginBorderVisibility; + div.innerHTML = html; + + outer = div.firstChild; + inner = outer.firstChild; + td = outer.nextSibling.firstChild.firstChild; offsetSupport = { - doesNotIncludeMarginInBodyOffset: ( body.offsetTop !== conMarginTop ) + doesNotAddBorder: ( inner.offsetTop !== 5 ), + doesAddBorderForTableAndCells: ( td.offsetTop === 5 ) }; + inner.style.position = "fixed"; + inner.style.top = "20px"; + + // safari subtracts parent border width here which is 5px + offsetSupport.fixedPosition = ( inner.offsetTop === 20 || inner.offsetTop === 15 ); + inner.style.position = inner.style.top = ""; + + outer.style.overflow = "hidden"; + outer.style.position = "relative"; + + offsetSupport.subtractsBorderForOverflowNotVisible = ( inner.offsetTop === -5 ); + offsetSupport.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== conMarginTop ); + + if ( window.getComputedStyle ) { + div.style.marginTop = "1%"; + support.pixelMargin = ( window.getComputedStyle( div, null ) || { marginTop: 0 } ).marginTop !== "1%"; + } if ( typeof container.style.zoom !== "undefined" ) { container.style.zoom = 1; diff --git a/src/traversing.js b/src/traversing.js index 2e45aade7..08c95ec4a 100644 --- a/src/traversing.js +++ b/src/traversing.js @@ -54,7 +54,7 @@ jQuery.fn.extend({ }, has: function( target ) { - var targets = jQuery( target, this ); + var targets = jQuery( target ); return this.filter(function() { for ( var i = 0, l = targets.length; i < l; i++ ) { if ( jQuery.contains( this, targets[i] ) ) { diff --git a/test/data/testinit.js b/test/data/testinit.js index 1f775c1d7..43244e7eb 100644 --- a/test/data/testinit.js +++ b/test/data/testinit.js @@ -1,5 +1,3 @@ -/*jshint multistr:true*/ - var jQuery = this.jQuery || "jQuery", // For testing .noConflict() $ = this.$ || "$", originaljQuery = jQuery, @@ -47,53 +45,6 @@ function t(a,b,c) { deepEqual(f, q.apply(q,c), a + " (" + b + ")"); } - -var createDashboardXML = function() { - var string = '<?xml version="1.0" encoding="UTF-8"?> \ - <dashboard> \ - <locations class="foo"> \ - <location for="bar" checked="different"> \ - <infowindowtab> \ - <tab title="Location"><![CDATA[blabla]]></tab> \ - <tab title="Users"><![CDATA[blublu]]></tab> \ - </infowindowtab> \ - </location> \ - </locations> \ - </dashboard>'; - - return jQuery.parseXML(string); -}; - -var createWithFriesXML = function() { - var string = '<?xml version="1.0" encoding="UTF-8"?> \ - <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" \ - xmlns:xsd="http://www.w3.org/2001/XMLSchema" \ - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> \ - <soap:Body> \ - <jsconf xmlns="http://www.example.com/ns1"> \ - <response xmlns:ab="http://www.example.com/ns2"> \ - <meta> \ - <component id="seite1" class="component"> \ - <properties xmlns:cd="http://www.example.com/ns3"> \ - <property name="prop1"> \ - <thing /> \ - <value>1</value> \ - </property> \ - <property name="prop2"> \ - <thing att="something" /> \ - </property> \ - <foo_bar>foo</foo_bar> \ - </properties> \ - </component> \ - </meta> \ - </response> \ - </jsconf> \ - </soap:Body> \ - </soap:Envelope>'; - - return jQuery.parseXML(string); -}; - var fireNative; if ( document.createEvent ) { fireNative = function( node, type ) { @@ -208,4 +159,4 @@ function url(value) { window.start = function() { oldStart(); }; -})(); +})();
\ No newline at end of file diff --git a/test/unit/ajax.js b/test/unit/ajax.js index d13eaaeca..de680cb7d 100644 --- a/test/unit/ajax.js +++ b/test/unit/ajax.js @@ -857,7 +857,7 @@ test("jQuery.ajax - beforeSend", function() { test("jQuery.ajax - beforeSend, cancel request (#2688)", function() { expect(2); - jQuery.ajax({ + var request = jQuery.ajax({ url: url("data/name.html"), beforeSend: function() { ok( true, "beforeSend got called, canceling" ); @@ -872,14 +872,13 @@ test("jQuery.ajax - beforeSend, cancel request (#2688)", function() { error: function() { ok( false, "request didn't get canceled" ); } - }).fail(function( _, reason ) { - strictEqual( reason, "canceled", "canceled request must fail with 'canceled' status text" ); }); + ok( request === false, "canceled request must return false instead of XMLHttpRequest instance" ); }); test("jQuery.ajax - beforeSend, cancel request manually", function() { expect(2); - jQuery.ajax({ + var request = jQuery.ajax({ url: url("data/name.html"), beforeSend: function(xhr) { ok( true, "beforeSend got called, canceling" ); @@ -894,9 +893,8 @@ test("jQuery.ajax - beforeSend, cancel request manually", function() { error: function() { ok( false, "request didn't get canceled" ); } - }).fail(function( _, reason ) { - strictEqual( reason, "canceled", "manually canceled request must fail with 'canceled' status text" ); }); + ok( request === false, "canceled request must return false instead of XMLHttpRequest instance" ); }); window.foobar = null; @@ -962,16 +960,13 @@ test("serialize()", function() { }); test("jQuery.param()", function() { - expect(22); + expect(21); equal( !jQuery.ajaxSettings.traditional, true, "traditional flag, falsy by default" ); var params = {foo:"bar", baz:42, quux:"All your base are belong to us"}; equal( jQuery.param(params), "foo=bar&baz=42&quux=All+your+base+are+belong+to+us", "simple" ); - params = {"string":"foo","null":null,"undefined":undefined}; - equal( jQuery.param(params), "string=foo&null=&undefined=", "handle nulls and undefineds properly" ); - params = {someName: [1, 2, 3], regularThing: "blah" }; equal( jQuery.param(params), "someName%5B%5D=1&someName%5B%5D=2&someName%5B%5D=3®ularThing=blah", "with array" ); @@ -985,13 +980,13 @@ test("jQuery.param()", function() { equal( jQuery.param(params), "foo%5Bbar%5D=baz&foo%5Bbeep%5D=42&foo%5Bquux%5D=All+your+base+are+belong+to+us", "even more arrays" ); params = { a:[1,2], b:{ c:3, d:[4,5], e:{ x:[6], y:7, z:[8,9] }, f:true, g:false, h:undefined }, i:[10,11], j:true, k:false, l:[undefined,0], m:"cowboy hat?" }; - equal( decodeURIComponent( jQuery.param(params) ), "a[]=1&a[]=2&b[c]=3&b[d][]=4&b[d][]=5&b[e][x][]=6&b[e][y]=7&b[e][z][]=8&b[e][z][]=9&b[f]=true&b[g]=false&b[h]=&i[]=10&i[]=11&j=true&k=false&l[]=&l[]=0&m=cowboy+hat?", "huge structure" ); + equal( decodeURIComponent( jQuery.param(params) ), "a[]=1&a[]=2&b[c]=3&b[d][]=4&b[d][]=5&b[e][x][]=6&b[e][y]=7&b[e][z][]=8&b[e][z][]=9&b[f]=true&b[g]=false&b[h]=undefined&i[]=10&i[]=11&j=true&k=false&l[]=undefined&l[]=0&m=cowboy+hat?", "huge structure" ); params = { a: [ 0, [ 1, 2 ], [ 3, [ 4, 5 ], [ 6 ] ], { b: [ 7, [ 8, 9 ], [ { c: 10, d: 11 } ], [ [ 12 ] ], [ [ [ 13 ] ] ], { e: { f: { g: [ 14, [ 15 ] ] } } }, 16 ] }, 17 ] }; equal( decodeURIComponent( jQuery.param(params) ), "a[]=0&a[1][]=1&a[1][]=2&a[2][]=3&a[2][1][]=4&a[2][1][]=5&a[2][2][]=6&a[3][b][]=7&a[3][b][1][]=8&a[3][b][1][]=9&a[3][b][2][0][c]=10&a[3][b][2][0][d]=11&a[3][b][3][0][]=12&a[3][b][4][0][0][]=13&a[3][b][5][e][f][g][]=14&a[3][b][5][e][f][g][1][]=15&a[3][b][]=16&a[]=17", "nested arrays" ); params = { a:[1,2], b:{ c:3, d:[4,5], e:{ x:[6], y:7, z:[8,9] }, f:true, g:false, h:undefined }, i:[10,11], j:true, k:false, l:[undefined,0], m:"cowboy hat?" }; - equal( jQuery.param(params,true), "a=1&a=2&b=%5Bobject+Object%5D&i=10&i=11&j=true&k=false&l=&l=0&m=cowboy+hat%3F", "huge structure, forced traditional" ); + equal( jQuery.param(params,true), "a=1&a=2&b=%5Bobject+Object%5D&i=10&i=11&j=true&k=false&l=undefined&l=0&m=cowboy+hat%3F", "huge structure, forced traditional" ); equal( decodeURIComponent( jQuery.param({ a: [1,2,3], "b[]": [4,5,6], "c[d]": [7,8,9], e: { f: [10], g: [11,12], h: 13 } }) ), "a[]=1&a[]=2&a[]=3&b[]=4&b[]=5&b[]=6&c[d][]=7&c[d][]=8&c[d][]=9&e[f][]=10&e[g][]=11&e[g][]=12&e[h]=13", "Make sure params are not double-encoded." ); @@ -1016,16 +1011,16 @@ test("jQuery.param()", function() { equal( jQuery.param(params), "foo%5Bbar%5D=baz&foo%5Bbeep%5D=42&foo%5Bquux%5D=All+your+base+are+belong+to+us", "even more arrays" ); params = { a:[1,2], b:{ c:3, d:[4,5], e:{ x:[6], y:7, z:[8,9] }, f:true, g:false, h:undefined }, i:[10,11], j:true, k:false, l:[undefined,0], m:"cowboy hat?" }; - equal( jQuery.param(params), "a=1&a=2&b=%5Bobject+Object%5D&i=10&i=11&j=true&k=false&l=&l=0&m=cowboy+hat%3F", "huge structure" ); + equal( jQuery.param(params), "a=1&a=2&b=%5Bobject+Object%5D&i=10&i=11&j=true&k=false&l=undefined&l=0&m=cowboy+hat%3F", "huge structure" ); params = { a: [ 0, [ 1, 2 ], [ 3, [ 4, 5 ], [ 6 ] ], { b: [ 7, [ 8, 9 ], [ { c: 10, d: 11 } ], [ [ 12 ] ], [ [ [ 13 ] ] ], { e: { f: { g: [ 14, [ 15 ] ] } } }, 16 ] }, 17 ] }; equal( jQuery.param(params), "a=0&a=1%2C2&a=3%2C4%2C5%2C6&a=%5Bobject+Object%5D&a=17", "nested arrays (not possible when jQuery.param.traditional == true)" ); params = { a:[1,2], b:{ c:3, d:[4,5], e:{ x:[6], y:7, z:[8,9] }, f:true, g:false, h:undefined }, i:[10,11], j:true, k:false, l:[undefined,0], m:"cowboy hat?" }; - equal( decodeURIComponent( jQuery.param(params,false) ), "a[]=1&a[]=2&b[c]=3&b[d][]=4&b[d][]=5&b[e][x][]=6&b[e][y]=7&b[e][z][]=8&b[e][z][]=9&b[f]=true&b[g]=false&b[h]=&i[]=10&i[]=11&j=true&k=false&l[]=&l[]=0&m=cowboy+hat?", "huge structure, forced not traditional" ); + equal( decodeURIComponent( jQuery.param(params,false) ), "a[]=1&a[]=2&b[c]=3&b[d][]=4&b[d][]=5&b[e][x][]=6&b[e][y]=7&b[e][z][]=8&b[e][z][]=9&b[f]=true&b[g]=false&b[h]=undefined&i[]=10&i[]=11&j=true&k=false&l[]=undefined&l[]=0&m=cowboy+hat?", "huge structure, forced not traditional" ); params = { param1: null }; - equal( jQuery.param(params,false), "param1=", "Make sure that null params aren't traversed." ); + equal( jQuery.param(params,false), "param1=null", "Make sure that null params aren't traversed." ); params = {"test": {"length": 3, "foo": "bar"} }; equal( jQuery.param( params, false ), "test%5Blength%5D=3&test%5Bfoo%5D=bar", "Sub-object with a length property" ); @@ -2114,14 +2109,13 @@ test( "jQuery.ajax - Context with circular references (#9887)", 2, function () { context = {}; context.field = context; try { - jQuery.ajax( "non-existing", { + success = !jQuery.ajax( "non-existing", { context: context, beforeSend: function() { ok( this === context, "context was not deep extended" ); return false; } }); - success = true; } catch (e) { console.log( e ); } ok( success, "context with circular reference did not generate an exception" ); }); @@ -2321,14 +2315,12 @@ test("jQuery.ajax - abort in prefilter", function() { } }); - jQuery.ajax({ + strictEqual( jQuery.ajax({ abortInPrefilter: true, error: function() { ok( false, "error callback called" ); } - }).fail(function( _, reason ) { - strictEqual( reason, 'canceled', "Request aborted by the prefilter must fail with 'canceled' status text" ); - }); + }), false, "Request was properly aborted early by the prefilter" ); }); diff --git a/test/unit/attributes.js b/test/unit/attributes.js index a39712f34..dd21b6539 100644 --- a/test/unit/attributes.js +++ b/test/unit/attributes.js @@ -127,13 +127,18 @@ test("attr(String)", function() { equal( $form.prop("enctype"), "multipart/form-data", "Set the enctype of a form (encoding in IE6/7 #6743)" ); }); -test("attr(String) in XML Files", function() { - expect(3); - var xml = createDashboardXML(); - equal( jQuery( "locations", xml ).attr("class"), "foo", "Check class attribute in XML document" ); - equal( jQuery( "location", xml ).attr("for"), "bar", "Check for attribute in XML document" ); - equal( jQuery( "location", xml ).attr("checked"), "different", "Check that hooks are not attached in XML document" ); -}); +if ( !isLocal ) { + test("attr(String) in XML Files", function() { + expect(3); + stop(); + jQuery.get("data/dashboard.xml", function( xml ) { + equal( jQuery( "locations", xml ).attr("class"), "foo", "Check class attribute in XML document" ); + equal( jQuery( "location", xml ).attr("for"), "bar", "Check for attribute in XML document" ); + equal( jQuery( "location", xml ).attr("checked"), "different", "Check that hooks are not attached in XML document" ); + start(); + }); + }); +} test("attr(String, Function)", function() { expect(2); @@ -387,16 +392,21 @@ test("attr(jquery_method)", function(){ equal( elem.style.paddingRight, "1px", "attr({...})"); }); -test("attr(String, Object) - Loaded via XML document", function() { - expect(2); - var xml = createDashboardXML(); - var titles = []; - jQuery( "tab", xml ).each(function() { - titles.push( jQuery(this).attr("title") ); +if ( !isLocal ) { + test("attr(String, Object) - Loaded via XML document", function() { + expect(2); + stop(); + jQuery.get("data/dashboard.xml", function( xml ) { + var titles = []; + jQuery( "tab", xml ).each(function() { + titles.push( jQuery(this).attr("title") ); + }); + equal( titles[0], "Location", "attr() in XML context: Check first title" ); + equal( titles[1], "Users", "attr() in XML context: Check second title" ); + start(); + }); }); - equal( titles[0], "Location", "attr() in XML context: Check first title" ); - equal( titles[1], "Users", "attr() in XML context: Check second title" ); -}); +} test("attr('tabindex')", function() { expect(8); @@ -1182,16 +1192,3 @@ test("coords returns correct values in IE6/IE7, see #10828", function() { area = map.html("<area shape='rect' href='#' alt='a' /></map>").find("area"); equal( area.attr("coords"), undefined, "did not retrieve coords correctly"); }); - -test("Handle cased attributes on XML DOM correctly in removeAttr()", function() { - expect(1); - - var xmlStr = "<root><item fooBar='123' /></root>", - $xmlDoc = jQuery( jQuery.parseXML( xmlStr ) ), - $item = $xmlDoc.find( "item" ), - el = $item[0]; - - $item.removeAttr( "fooBar" ); - - equal( el.attributes.length, 0, "attribute with upper case did not get removed" ); -}); diff --git a/test/unit/callbacks.js b/test/unit/callbacks.js index acc61f32c..acc88f2c2 100644 --- a/test/unit/callbacks.js +++ b/test/unit/callbacks.js @@ -33,171 +33,149 @@ var output, } }; - function showFlags( flags ) { - if ( typeof flags === "string" ) { - return '"' + flags + '"'; - } - var output = [], key; - for ( key in flags ) { - output.push( '"' + key + '": ' + flags[ key ] ); - } - return "{ " + output.join( ", " ) + " }"; - } +jQuery.each( tests, function( flags, resultString ) { -jQuery.each( tests, function( strFlags, resultString ) { + jQuery.each( filters, function( filterLabel, filter ) { - var objectFlags = {}; + test( "jQuery.Callbacks( \"" + flags + "\" ) - " + filterLabel, function() { - jQuery.each( strFlags.split( " " ), function() { - if ( this.length ) { - objectFlags[ this ] = true; - } - }); + expect( 20 ); - jQuery.each( filters, function( filterLabel, filter ) { + // Give qunit a little breathing room + stop(); + setTimeout( start, 0 ); + + var cblist; + results = resultString.split( /\s+/ ); - jQuery.each( { "string": strFlags, "object": objectFlags }, function( flagsTypes, flags ) { - - test( "jQuery.Callbacks( " + showFlags( flags ) + " ) - " + filterLabel, function() { - - expect( 20 ); - - // Give qunit a little breathing room - stop(); - setTimeout( start, 0 ); - - var cblist; - results = resultString.split( /\s+/ ); - - // Basic binding and firing - output = "X"; - cblist = jQuery.Callbacks( flags ); - cblist.add(function( str ) { - output += str; - }); - cblist.fire( "A" ); - strictEqual( output, "XA", "Basic binding and firing" ); - strictEqual( cblist.fired(), true, ".fired() detects firing" ); - output = "X"; - cblist.disable(); - cblist.add(function( str ) { - output += str; - }); - strictEqual( output, "X", "Adding a callback after disabling" ); - cblist.fire( "A" ); - strictEqual( output, "X", "Firing after disabling" ); - - // Basic binding and firing (context, arguments) - output = "X"; - cblist = jQuery.Callbacks( flags ); - cblist.add(function() { - equal( this, window, "Basic binding and firing (context)" ); - output += Array.prototype.join.call( arguments, "" ); - }); - cblist.fireWith( window, [ "A", "B" ] ); - strictEqual( output, "XAB", "Basic binding and firing (arguments)" ); - - // fireWith with no arguments - output = ""; - cblist = jQuery.Callbacks( flags ); - cblist.add(function() { - equal( this, window, "fireWith with no arguments (context is window)" ); - strictEqual( arguments.length, 0, "fireWith with no arguments (no arguments)" ); - }); - cblist.fireWith(); - - // Basic binding, removing and firing - output = "X"; - cblist = jQuery.Callbacks( flags ); - cblist.add( outputA, outputB, outputC ); - cblist.remove( outputB, outputC ); - cblist.fire(); - strictEqual( output, "XA", "Basic binding, removing and firing" ); - - // Empty - output = "X"; - cblist = jQuery.Callbacks( flags ); - cblist.add( outputA ); - cblist.add( outputB ); + // Basic binding and firing + output = "X"; + cblist = jQuery.Callbacks( flags ); + cblist.add(function( str ) { + output += str; + }); + cblist.fire( "A" ); + strictEqual( output, "XA", "Basic binding and firing" ); + strictEqual( cblist.fired(), true, ".fired() detects firing" ); + output = "X"; + cblist.disable(); + cblist.add(function( str ) { + output += str; + }); + strictEqual( output, "X", "Adding a callback after disabling" ); + cblist.fire( "A" ); + strictEqual( output, "X", "Firing after disabling" ); + + // Basic binding and firing (context, arguments) + output = "X"; + cblist = jQuery.Callbacks( flags ); + cblist.add(function() { + equal( this, window, "Basic binding and firing (context)" ); + output += Array.prototype.join.call( arguments, "" ); + }); + cblist.fireWith( window, [ "A", "B" ] ); + strictEqual( output, "XAB", "Basic binding and firing (arguments)" ); + + // fireWith with no arguments + output = ""; + cblist = jQuery.Callbacks( flags ); + cblist.add(function() { + equal( this, window, "fireWith with no arguments (context is window)" ); + strictEqual( arguments.length, 0, "fireWith with no arguments (no arguments)" ); + }); + cblist.fireWith(); + + // Basic binding, removing and firing + output = "X"; + cblist = jQuery.Callbacks( flags ); + cblist.add( outputA, outputB, outputC ); + cblist.remove( outputB, outputC ); + cblist.fire(); + strictEqual( output, "XA", "Basic binding, removing and firing" ); + + // Empty + output = "X"; + cblist = jQuery.Callbacks( flags ); + cblist.add( outputA ); + cblist.add( outputB ); + cblist.add( outputC ); + cblist.empty(); + cblist.fire(); + strictEqual( output, "X", "Empty" ); + + // Locking + output = "X"; + cblist = jQuery.Callbacks( flags ); + cblist.add( function( str ) { + output += str; + }); + cblist.lock(); + cblist.add( function( str ) { + output += str; + }); + cblist.fire( "A" ); + cblist.add( function( str ) { + output += str; + }); + strictEqual( output, "X", "Lock early" ); + + // Ordering + output = "X"; + cblist = jQuery.Callbacks( flags ); + cblist.add( function() { cblist.add( outputC ); - cblist.empty(); - cblist.fire(); - strictEqual( output, "X", "Empty" ); - - // Locking - output = "X"; - cblist = jQuery.Callbacks( flags ); - cblist.add( function( str ) { - output += str; - }); - cblist.lock(); - cblist.add( function( str ) { - output += str; - }); - cblist.fire( "A" ); - cblist.add( function( str ) { - output += str; - }); - strictEqual( output, "X", "Lock early" ); - - // Ordering - output = "X"; - cblist = jQuery.Callbacks( flags ); - cblist.add( function() { - cblist.add( outputC ); - outputA(); - }, outputB ); - cblist.fire(); - strictEqual( output, results.shift(), "Proper ordering" ); - - // Add and fire again - output = "X"; - cblist.add( function() { - cblist.add( outputC ); - outputA(); - }, outputB ); - strictEqual( output, results.shift(), "Add after fire" ); - - output = "X"; - cblist.fire(); - strictEqual( output, results.shift(), "Fire again" ); - - // Multiple fire - output = "X"; - cblist = jQuery.Callbacks( flags ); - cblist.add( function( str ) { - output += str; - } ); - cblist.fire( "A" ); - strictEqual( output, "XA", "Multiple fire (first fire)" ); - output = "X"; - cblist.add( function( str ) { - output += str; - } ); - strictEqual( output, results.shift(), "Multiple fire (first new callback)" ); - output = "X"; - cblist.fire( "B" ); - strictEqual( output, results.shift(), "Multiple fire (second fire)" ); - output = "X"; - cblist.add( function( str ) { - output += str; - } ); - strictEqual( output, results.shift(), "Multiple fire (second new callback)" ); - - // Return false - output = "X"; - cblist = jQuery.Callbacks( flags ); - cblist.add( outputA, function() { return false; }, outputB ); - cblist.add( outputA ); - cblist.fire(); - strictEqual( output, results.shift(), "Callback returning false" ); - - // Add another callback (to control lists with memory do not fire anymore) - output = "X"; + outputA(); + }, outputB ); + cblist.fire(); + strictEqual( output, results.shift(), "Proper ordering" ); + + // Add and fire again + output = "X"; + cblist.add( function() { cblist.add( outputC ); - strictEqual( output, results.shift(), "Adding a callback after one returned false" ); + outputA(); + }, outputB ); + strictEqual( output, results.shift(), "Add after fire" ); + + output = "X"; + cblist.fire(); + strictEqual( output, results.shift(), "Fire again" ); + + // Multiple fire + output = "X"; + cblist = jQuery.Callbacks( flags ); + cblist.add( function( str ) { + output += str; + } ); + cblist.fire( "A" ); + strictEqual( output, "XA", "Multiple fire (first fire)" ); + output = "X"; + cblist.add( function( str ) { + output += str; + } ); + strictEqual( output, results.shift(), "Multiple fire (first new callback)" ); + output = "X"; + cblist.fire( "B" ); + strictEqual( output, results.shift(), "Multiple fire (second fire)" ); + output = "X"; + cblist.add( function( str ) { + output += str; + } ); + strictEqual( output, results.shift(), "Multiple fire (second new callback)" ); + + // Return false + output = "X"; + cblist = jQuery.Callbacks( flags ); + cblist.add( outputA, function() { return false; }, outputB ); + cblist.add( outputA ); + cblist.fire(); + strictEqual( output, results.shift(), "Callback returning false" ); + + // Add another callback (to control lists with memory do not fire anymore) + output = "X"; + cblist.add( outputC ); + strictEqual( output, results.shift(), "Adding a callback after one returned false" ); - }); }); }); }); diff --git a/test/unit/core.js b/test/unit/core.js index 94f985db6..e87c10664 100644 --- a/test/unit/core.js +++ b/test/unit/core.js @@ -547,16 +547,21 @@ test("XSS via location.hash", function() { jQuery( '#<img id="check9521" src="no-such-.gif" onerror="jQuery._check9521(false)">' ).appendTo("#qunit-fixture"); } catch (err) { jQuery._check9521(true); - } + }; }); +if ( !isLocal ) { test("isXMLDoc - XML", function() { expect(3); - var xml = createDashboardXML(); - ok( jQuery.isXMLDoc( xml ), "XML document" ); - ok( jQuery.isXMLDoc( xml.documentElement ), "XML documentElement" ); - ok( jQuery.isXMLDoc( jQuery("tab", xml)[0] ), "XML Tab Element" ); + stop(); + jQuery.get("data/dashboard.xml", function(xml) { + ok( jQuery.isXMLDoc( xml ), "XML document" ); + ok( jQuery.isXMLDoc( xml.documentElement ), "XML documentElement" ); + ok( jQuery.isXMLDoc( jQuery("tab", xml)[0] ), "XML Tab Element" ); + start(); + }); }); +} test("isWindow", function() { expect( 14 ); @@ -633,16 +638,20 @@ test("jQuery('html', context)", function() { equal($span.length, 1, "Verify a span created with a div context works, #1763"); }); +if ( !isLocal ) { test("jQuery(selector, xml).text(str) - Loaded via XML document", function() { expect(2); - - var xml = createDashboardXML(); - // tests for #1419 where IE was a problem - var tab = jQuery("tab", xml).eq(0); - equal( tab.text(), "blabla", "Verify initial text correct" ); - tab.text("newtext"); - equal( tab.text(), "newtext", "Verify new text correct" ); + stop(); + jQuery.get("data/dashboard.xml", function(xml) { + // tests for #1419 where IE was a problem + var tab = jQuery("tab", xml).eq(0); + equal( tab.text(), "blabla", "Verify initial text correct" ); + tab.text("newtext"); + equal( tab.text(), "newtext", "Verify new text correct" ); + start(); + }); }); +} test("end()", function() { expect(3); diff --git a/test/unit/css.js b/test/unit/css.js index 6d0b39f81..8e7f8ec10 100644 --- a/test/unit/css.js +++ b/test/unit/css.js @@ -555,18 +555,6 @@ test("outerWidth(true) and css('margin') returning % instead of px in Webkit, se equal( el.outerWidth(true), 400, "outerWidth(true) and css('margin') returning % instead of px in Webkit, see #10639" ); }); -test("css('width') should respect box-sizing, see #11004", function() { - var el_disconnected = jQuery("<div style='width:300px;margin:2px;padding:2px;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;'>test</div>"), - el = el_disconnected.clone().appendTo("#qunit-fixture"), - width_initial = el.css("width"), - width_roundtrip = el.css("width", el.css("width")).css("width"), - width_initial_disconnected = el_disconnected.css("width"), - width_roundtrip_disconnected = el_disconnected.css("width", el_disconnected.css("width")).css("width"); - - equal( width_roundtrip, width_initial, "css('width') is not respecting box-sizing, see #11004"); - equal( width_roundtrip_disconnected, width_initial_disconnected, "css('width') is not respecting box-sizing for disconnected element, see #11004"); -}); - test( "cssHooks - expand", function() { expect( 15 ); var result, diff --git a/test/unit/data.js b/test/unit/data.js index 89869f795..7598ba8be 100644 --- a/test/unit/data.js +++ b/test/unit/data.js @@ -184,6 +184,9 @@ test(".data()", function() { var dataObj = div.data(); + // TODO: Remove this hack which was introduced in 1.5.1 + delete dataObj.toJSON; + deepEqual( dataObj, {test: "success"}, "data() get the entire data object" ); strictEqual( div.data("foo"), undefined, "Make sure that missing result is still undefined" ); @@ -195,6 +198,9 @@ test(".data()", function() { dataObj = jQuery.extend(true, {}, jQuery(obj).data()); + // TODO: Remove this hack which was introduced for 1.5.1 + delete dataObj.toJSON; + deepEqual( dataObj, { foo: "baz" }, "Retrieve data object from a wrapped JS object (#7524)" ); }); diff --git a/test/unit/deferred.js b/test/unit/deferred.js index 7ff274d56..4a50da2c1 100644 --- a/test/unit/deferred.js +++ b/test/unit/deferred.js @@ -8,36 +8,32 @@ jQuery.each( [ "", " - new operator" ], function( _, withNew ) { test("jQuery.Deferred" + withNew, function() { - expect( 23 ); + expect( 22 ); - var defer = createDeferred(); - - strictEqual( defer.pipe, defer.then, "pipe is an alias of then" ); - - createDeferred().resolve().done(function() { + createDeferred().resolve().then( function() { ok( true , "Success on resolve" ); ok( this.isResolved(), "Deferred is resolved" ); strictEqual( this.state(), "resolved", "Deferred is resolved (state)" ); - }).fail(function() { + }, function() { ok( false , "Error on resolve" ); - }).always(function() { + }).always( function() { ok( true , "Always callback on resolve" ); }); - createDeferred().reject().done(function() { + createDeferred().reject().then( function() { ok( false , "Success on reject" ); - }).fail(function() { + }, function() { ok( true , "Error on reject" ); ok( this.isRejected(), "Deferred is rejected" ); strictEqual( this.state(), "rejected", "Deferred is rejected (state)" ); - }).always(function() { + }).always( function() { ok( true , "Always callback on reject" ); }); - createDeferred(function( defer ) { + createDeferred( function( defer ) { ok( this === defer , "Defer passed as this & first argument" ); this.resolve( "done" ); - }).done( function( value ) { + }).then( function( value ) { strictEqual( value , "done" , "Passed function executed" ); }); @@ -62,7 +58,7 @@ jQuery.each( [ "", " - new operator" ], function( _, withNew ) { test( "jQuery.Deferred - chainability", function() { - var methods = "resolve reject notify resolveWith rejectWith notifyWith done fail progress always".split( " " ), + var methods = "resolve reject notify resolveWith rejectWith notifyWith done fail progress then always".split( " " ), defer = jQuery.Deferred(); expect( methods.length ); @@ -73,12 +69,12 @@ test( "jQuery.Deferred - chainability", function() { }); }); -test( "jQuery.Deferred.then - filtering (done)", function() { +test( "jQuery.Deferred.pipe - filtering (done)", function() { expect(4); var defer = jQuery.Deferred(), - piped = defer.then(function( a, b ) { + piped = defer.pipe(function( a, b ) { return a * b; }), value1, @@ -100,21 +96,21 @@ test( "jQuery.Deferred.then - filtering (done)", function() { strictEqual( value2, 3, "second resolve value ok" ); strictEqual( value3, 6, "result of filter ok" ); - jQuery.Deferred().reject().then(function() { - ok( false, "then should not be called on reject" ); + jQuery.Deferred().reject().pipe(function() { + ok( false, "pipe should not be called on reject" ); }); - jQuery.Deferred().resolve().then( jQuery.noop ).done(function( value ) { - strictEqual( value, undefined, "then done callback can return undefined/null" ); + jQuery.Deferred().resolve().pipe( jQuery.noop ).done(function( value ) { + strictEqual( value, undefined, "pipe done callback can return undefined/null" ); }); }); -test( "jQuery.Deferred.then - filtering (fail)", function() { +test( "jQuery.Deferred.pipe - filtering (fail)", function() { expect(4); var defer = jQuery.Deferred(), - piped = defer.then( null, function( a, b ) { + piped = defer.pipe( null, function( a, b ) { return a * b; } ), value1, @@ -136,21 +132,21 @@ test( "jQuery.Deferred.then - filtering (fail)", function() { strictEqual( value2, 3, "second reject value ok" ); strictEqual( value3, 6, "result of filter ok" ); - jQuery.Deferred().resolve().then( null, function() { - ok( false, "then should not be called on resolve" ); + jQuery.Deferred().resolve().pipe( null, function() { + ok( false, "pipe should not be called on resolve" ); } ); - jQuery.Deferred().reject().then( null, jQuery.noop ).fail(function( value ) { - strictEqual( value, undefined, "then fail callback can return undefined/null" ); + jQuery.Deferred().reject().pipe( null, jQuery.noop ).fail(function( value ) { + strictEqual( value, undefined, "pipe fail callback can return undefined/null" ); }); }); -test( "jQuery.Deferred.then - filtering (progress)", function() { +test( "jQuery.Deferred.pipe - filtering (progress)", function() { expect(3); var defer = jQuery.Deferred(), - piped = defer.then( null, null, function( a, b ) { + piped = defer.pipe( null, null, function( a, b ) { return a * b; } ), value1, @@ -173,12 +169,12 @@ test( "jQuery.Deferred.then - filtering (progress)", function() { strictEqual( value3, 6, "result of filter ok" ); }); -test( "jQuery.Deferred.then - deferred (done)", function() { +test( "jQuery.Deferred.pipe - deferred (done)", function() { expect(3); var defer = jQuery.Deferred(), - piped = defer.then(function( a, b ) { + piped = defer.pipe(function( a, b ) { return jQuery.Deferred(function( defer ) { defer.reject( a * b ); }); @@ -203,12 +199,12 @@ test( "jQuery.Deferred.then - deferred (done)", function() { strictEqual( value3, 6, "result of filter ok" ); }); -test( "jQuery.Deferred.then - deferred (fail)", function() { +test( "jQuery.Deferred.pipe - deferred (fail)", function() { expect(3); var defer = jQuery.Deferred(), - piped = defer.then( null, function( a, b ) { + piped = defer.pipe( null, function( a, b ) { return jQuery.Deferred(function( defer ) { defer.resolve( a * b ); }); @@ -233,12 +229,12 @@ test( "jQuery.Deferred.then - deferred (fail)", function() { strictEqual( value3, 6, "result of filter ok" ); }); -test( "jQuery.Deferred.then - deferred (progress)", function() { +test( "jQuery.Deferred.pipe - deferred (progress)", function() { expect(3); var defer = jQuery.Deferred(), - piped = defer.then( null, null, function( a, b ) { + piped = defer.pipe( null, null, function( a, b ) { return jQuery.Deferred(function( defer ) { defer.resolve( a * b ); }); @@ -263,13 +259,13 @@ test( "jQuery.Deferred.then - deferred (progress)", function() { strictEqual( value3, 6, "result of filter ok" ); }); -test( "jQuery.Deferred.then - context", function() { +test( "jQuery.Deferred.pipe - context", function() { expect(4); var context = {}; - jQuery.Deferred().resolveWith( context, [ 2 ] ).then(function( value ) { + jQuery.Deferred().resolveWith( context, [ 2 ] ).pipe(function( value ) { return value * 3; }).done(function( value ) { strictEqual( this, context, "custom context correctly propagated" ); @@ -277,7 +273,7 @@ test( "jQuery.Deferred.then - context", function() { }); var defer = jQuery.Deferred(), - piped = defer.then(function( value ) { + piped = defer.pipe(function( value ) { return value * 3; }); diff --git a/test/unit/dimensions.js b/test/unit/dimensions.js index ef3d8ca68..c6b8e835c 100644 --- a/test/unit/dimensions.js +++ b/test/unit/dimensions.js @@ -230,13 +230,12 @@ test("outerWidth()", function() { jQuery.removeData($div[0], "olddisplay", true); }); -test("child of a hidden elem (or unconnected node) has accurate inner/outer/Width()/Height() see #9441 #9300", function() { - expect(16); +test("child of a hidden elem has accurate inner/outer/Width()/Height() see #9441 #9300", function() { + expect(8); // setup html - var $divNormal = jQuery("<div>").css({ width: "100px", height: "100px", border: "10px solid white", padding: "2px", margin: "3px" }), - $divChild = $divNormal.clone(), - $divUnconnected = $divNormal.clone(), + var $divNormal = jQuery("<div>").css({ width: "100px", height: "100px", border: "10px solid white", padding: "2px", margin: "3px" }), + $divChild = $divNormal.clone(), $divHiddenParent = jQuery("<div>").css( "display", "none" ).append( $divChild ).appendTo("body"); $divNormal.appendTo("body"); @@ -251,17 +250,6 @@ test("child of a hidden elem (or unconnected node) has accurate inner/outer/Widt equal( $divChild.outerHeight(), $divNormal.outerHeight(), "child of a hidden element outerHeight() is wrong see #9441" ); equal( $divChild.outerHeight(true), $divNormal.outerHeight( true ), "child of a hidden element outerHeight( true ) is wrong see #9300" ); - // tests that child div of an unconnected div works the same as a normal div - equal( $divUnconnected.width(), $divNormal.width(), "unconnected element width() is wrong see #9441" ); - equal( $divUnconnected.innerWidth(), $divNormal.innerWidth(), "unconnected element innerWidth() is wrong see #9441" ); - equal( $divUnconnected.outerWidth(), $divNormal.outerWidth(), "unconnected element outerWidth() is wrong see #9441" ); - equal( $divUnconnected.outerWidth(true), $divNormal.outerWidth( true ), "unconnected element outerWidth( true ) is wrong see #9300" ); - - equal( $divUnconnected.height(), $divNormal.height(), "unconnected element height() is wrong see #9441" ); - equal( $divUnconnected.innerHeight(), $divNormal.innerHeight(), "unconnected element innerHeight() is wrong see #9441" ); - equal( $divUnconnected.outerHeight(), $divNormal.outerHeight(), "unconnected element outerHeight() is wrong see #9441" ); - equal( $divUnconnected.outerHeight(true), $divNormal.outerHeight( true ), "unconnected element outerHeight( true ) is wrong see #9300" ); - // teardown html $divHiddenParent.remove(); $divNormal.remove(); @@ -290,43 +278,6 @@ test("getting dimensions shouldnt modify runtimeStyle see #9233", function() { $div.remove(); }); -test("box-sizing:border-box child of a hidden elem (or unconnected node) has accurate inner/outer/Width()/Height() see #10413", function() { - expect(16); - - // setup html - var $divNormal = jQuery("<div>").css({ boxSizing: "border-box", width: "100px", height: "100px", border: "10px solid white", padding: "2px", margin: "3px" }), - $divChild = $divNormal.clone(), - $divUnconnected = $divNormal.clone(), - $divHiddenParent = jQuery("<div>").css( "display", "none" ).append( $divChild ).appendTo("body"); - $divNormal.appendTo("body"); - - // tests that child div of a hidden div works the same as a normal div - equal( $divChild.width(), $divNormal.width(), "child of a hidden element width() is wrong see #10413" ); - equal( $divChild.innerWidth(), $divNormal.innerWidth(), "child of a hidden element innerWidth() is wrong see #10413" ); - equal( $divChild.outerWidth(), $divNormal.outerWidth(), "child of a hidden element outerWidth() is wrong see #10413" ); - equal( $divChild.outerWidth(true), $divNormal.outerWidth( true ), "child of a hidden element outerWidth( true ) is wrong see #10413" ); - - equal( $divChild.height(), $divNormal.height(), "child of a hidden element height() is wrong see #10413" ); - equal( $divChild.innerHeight(), $divNormal.innerHeight(), "child of a hidden element innerHeight() is wrong see #10413" ); - equal( $divChild.outerHeight(), $divNormal.outerHeight(), "child of a hidden element outerHeight() is wrong see #10413" ); - equal( $divChild.outerHeight(true), $divNormal.outerHeight( true ), "child of a hidden element outerHeight( true ) is wrong see #10413" ); - - // tests that child div of an unconnected div works the same as a normal div - equal( $divUnconnected.width(), $divNormal.width(), "unconnected element width() is wrong see #10413" ); - equal( $divUnconnected.innerWidth(), $divNormal.innerWidth(), "unconnected element innerWidth() is wrong see #10413" ); - equal( $divUnconnected.outerWidth(), $divNormal.outerWidth(), "unconnected element outerWidth() is wrong see #10413" ); - equal( $divUnconnected.outerWidth(true), $divNormal.outerWidth( true ), "unconnected element outerWidth( true ) is wrong see #10413" ); - - equal( $divUnconnected.height(), $divNormal.height(), "unconnected element height() is wrong see #10413" ); - equal( $divUnconnected.innerHeight(), $divNormal.innerHeight(), "unconnected element innerHeight() is wrong see #10413" ); - equal( $divUnconnected.outerHeight(), $divNormal.outerHeight(), "unconnected element outerHeight() is wrong see #10413" ); - equal( $divUnconnected.outerHeight(true), $divNormal.outerHeight( true ), "unconnected element outerHeight( true ) is wrong see #10413" ); - - // teardown html - $divHiddenParent.remove(); - $divNormal.remove(); -}); - test("outerHeight()", function() { expect(11); diff --git a/test/unit/effects.js b/test/unit/effects.js index 25c9834e4..e478cdf63 100644 --- a/test/unit/effects.js +++ b/test/unit/effects.js @@ -263,15 +263,6 @@ test("animate negative height", function() { }); }); -test("animate negative margin", function() { - expect(1); - stop(); - jQuery("#foo").animate({ marginTop: -100 }, 100, function() { - equal( jQuery(this).css("marginTop"), "-100px", "Verify margin." ); - start(); - }); -}); - test("animate negative padding", function() { expect(1); stop(); diff --git a/test/unit/event.js b/test/unit/event.js index 172f3a82a..3c9a08109 100644 --- a/test/unit/event.js +++ b/test/unit/event.js @@ -2867,15 +2867,4 @@ test("fixHooks extensions", function() { })(); -asyncTest("trigger click on checkbox, fires change event", function() { - expect(1); - - var check = jQuery("#check2"); - check.on( "change", function() { - // get it? - check.off("change"); - ok( true, "Change event fired as a result of triggered click" ); - start(); - }).trigger("click"); -}); diff --git a/test/unit/manipulation.js b/test/unit/manipulation.js index 672b204e1..ff31c4db4 100644 --- a/test/unit/manipulation.js +++ b/test/unit/manipulation.js @@ -555,28 +555,6 @@ test("html(String) with HTML5 (Bug #6485)", function() { equal( jQuery("#qunit-fixture").children().children().children().length, 1, "Make sure nested HTML5 elements can hold children." ); }); - - -test("IE8 serialization bug", function () { - expect(2); - var wrapper = jQuery("<div></div>"); - - wrapper.html("<div></div><article></article>"); - equal( wrapper.children("article").length, 1, "HTML5 elements are insertable with .html()"); - - wrapper.html("<div></div><link></link>"); - equal( wrapper.children("link").length, 1, "Link elements are insertable with .html()"); -}); - -test("html() object element #10324", function() { - expect( 1 ); - - var object = jQuery("<object id='object2'><param name='object2test' value='test'></param></object>?").appendTo("#qunit-fixture"), - clone = object.clone(); - - equal( clone.html(), object.html(), "html() returns correct innerhtml of cloned object elements" ); -}); - test("append(xml)", function() { expect( 1 ); @@ -924,7 +902,7 @@ test("insertAfter(String|Element|Array<Element>|jQuery)", function() { }); var testReplaceWith = function(val) { - expect(22); + expect(21); jQuery("#yahoo").replaceWith(val( "<b id='replace'>buga</b>" )); ok( jQuery("#replace")[0], "Replace element with string" ); ok( !jQuery("#yahoo")[0], "Verify that original element is gone, after string" ); @@ -985,9 +963,6 @@ var testReplaceWith = function(val) { equal( set[0].nodeName.toLowerCase(), "span", "Replace the disconnected node." ); equal( set.length, 1, "Replace the disconnected node." ); - // #11338 - ok( jQuery("<div>1</div>").replaceWith( val("<span/>") ).is("span"), "#11338, Make sure disconnected node with content is replaced"); - var non_existant = jQuery("#does-not-exist").replaceWith( val("<b>should not throw an error</b>") ); equal( non_existant.length, 0, "Length of non existant element." ); @@ -1018,7 +993,7 @@ test("replaceWith(String|Element|Array<Element>|jQuery)", function() { test("replaceWith(Function)", function() { testReplaceWith(functionReturningObj); - expect(23); + expect(22); var y = jQuery("#yahoo")[0]; @@ -1245,17 +1220,22 @@ test("clone(multiple selected options) (Bug #8129)", function() { }); +if (!isLocal) { test("clone() on XML nodes", function() { expect(2); - var xml = createDashboardXML(); - var root = jQuery(xml.documentElement).clone(); - var origTab = jQuery("tab", xml).eq(0); - var cloneTab = jQuery("tab", root).eq(0); - origTab.text("origval"); - cloneTab.text("cloneval"); - equal(origTab.text(), "origval", "Check original XML node was correctly set"); - equal(cloneTab.text(), "cloneval", "Check cloned XML node was correctly set"); + stop(); + jQuery.get("data/dashboard.xml", function (xml) { + var root = jQuery(xml.documentElement).clone(); + var origTab = jQuery("tab", xml).eq(0); + var cloneTab = jQuery("tab", root).eq(0); + origTab.text("origval"); + cloneTab.text("cloneval"); + equal(origTab.text(), "origval", "Check original XML node was correctly set"); + equal(cloneTab.text(), "cloneval", "Check cloned XML node was correctly set"); + start(); + }); }); +} test("clone() on local XML nodes with html5 nodename", function() { expect(2); @@ -1775,12 +1755,4 @@ test("Guard against exceptions when clearing safeChildNodes", function() { } catch(e) {} ok( div && div.jquery, "Created nodes safely, guarded against exceptions on safeChildNodes[ -1 ]" ); -}); - -test("Ensure oldIE creates a new set on appendTo (#8894)", function() { - strictEqual( jQuery("<div/>").clone().addClass("test").appendTo("<div/>").end().hasClass("test"), false, "Check jQuery.fn.appendTo after jQuery.clone" ); - strictEqual( jQuery("<div/>").find("p").end().addClass("test").appendTo("<div/>").end().hasClass("test"), false, "Check jQuery.fn.appendTo after jQuery.fn.find" ); - strictEqual( jQuery("<div/>").text("test").addClass("test").appendTo("<div/>").end().hasClass("test"), false, "Check jQuery.fn.appendTo after jQuery.fn.text" ); - strictEqual( jQuery("<bdi/>").clone().addClass("test").appendTo("<div/>").end().hasClass("test"), false, "Check jQuery.fn.appendTo after clone html5 element" ); - strictEqual( jQuery("<p/>").appendTo("<div/>").end().length, jQuery("<p>test</p>").appendTo("<div/>").end().length, "Elements created with createElement and with createDocumentFragment should be treated alike" ); -}); +});
\ No newline at end of file diff --git a/test/unit/support.js b/test/unit/support.js index a9243be51..b714a1cec 100644 --- a/test/unit/support.js +++ b/test/unit/support.js @@ -98,6 +98,10 @@ if ( /chrome\/16\.0/i.test(userAgent) ) { "reliableHiddenOffsets":true, "ajax":true, "cors":true, + "doesNotAddBorder":true, + "doesAddBorderForTableAndCells":false, + "fixedPosition":true, + "subtractsBorderForOverflowNotVisible":false, "doesNotIncludeMarginInBodyOffset":true }; for ( i in expected ) { @@ -137,6 +141,10 @@ if ( /chrome\/16\.0/i.test(userAgent) ) { "reliableHiddenOffsets":false, "ajax":true, "cors":false, + "doesNotAddBorder":false, + "doesAddBorderForTableAndCells":true, + "fixedPosition":true, + "subtractsBorderForOverflowNotVisible":false, "doesNotIncludeMarginInBodyOffset":true }; for ( i in expected ) { @@ -156,8 +164,11 @@ if ( /chrome\/16\.0/i.test(userAgent) ) { "cors": false, "cssFloat": false, "deleteExpando": false, + "doesAddBorderForTableAndCells": true, + "doesNotAddBorder": true, "doesNotIncludeMarginInBodyOffset": true, "enctype": true, + "fixedPosition": true, "focusinBubbles": true, "getSetAttribute": false, "hrefNormalized": false, @@ -175,6 +186,7 @@ if ( /chrome\/16\.0/i.test(userAgent) ) { "reliableMarginRight": true, "shrinkWrapBlocks": false, "submitBubbles": false, + "subtractsBorderForOverflowNotVisible": false, "tbody": false, "style": false }; @@ -215,6 +227,10 @@ if ( /chrome\/16\.0/i.test(userAgent) ) { "reliableHiddenOffsets":false, "ajax":true, "cors":false, + "doesNotAddBorder":true, + "doesAddBorderForTableAndCells":true, + "fixedPosition":false, + "subtractsBorderForOverflowNotVisible":false, "doesNotIncludeMarginInBodyOffset":true }; for ( i in expected ) { @@ -254,6 +270,10 @@ if ( /chrome\/16\.0/i.test(userAgent) ) { "reliableHiddenOffsets":true, "ajax":true, "cors":true, + "doesNotAddBorder":true, + "doesAddBorderForTableAndCells":false, + "fixedPosition":true, + "subtractsBorderForOverflowNotVisible":false, "doesNotIncludeMarginInBodyOffset":true }; for ( i in expected ) { @@ -293,6 +313,10 @@ if ( /chrome\/16\.0/i.test(userAgent) ) { "reliableHiddenOffsets":true, "ajax":true, "cors":true, + "doesNotAddBorder":true, + "doesAddBorderForTableAndCells":true, + "fixedPosition":true, + "subtractsBorderForOverflowNotVisible":false, "doesNotIncludeMarginInBodyOffset":true }; for ( i in expected ) { diff --git a/test/unit/traversing.js b/test/unit/traversing.js index 80d30aa19..8e8b5360a 100644 --- a/test/unit/traversing.js +++ b/test/unit/traversing.js @@ -370,27 +370,21 @@ test("not(jQuery)", function() { }); test("has(Element)", function() { - expect(3); + expect(2); var obj = jQuery("#qunit-fixture").has(jQuery("#sndp")[0]); deepEqual( obj.get(), q("qunit-fixture"), "Keeps elements that have the element as a descendant" ); - var detached = jQuery("<a><b><i/></b></a>"); - deepEqual( detached.has( detached.find("i")[0] ).get(), detached.get(), "...Even when detached" ); - var multipleParent = jQuery("#qunit-fixture, #header").has(jQuery("#sndp")[0]); deepEqual( obj.get(), q("qunit-fixture"), "Does not include elements that do not have the element as a descendant" ); }); test("has(Selector)", function() { - expect(4); + expect(3); var obj = jQuery("#qunit-fixture").has("#sndp"); deepEqual( obj.get(), q("qunit-fixture"), "Keeps elements that have any element matching the selector as a descendant" ); - var detached = jQuery("<a><b><i/></b></a>"); - deepEqual( detached.has("i").get(), detached.get(), "...Even when detached" ); - var multipleParent = jQuery("#qunit-fixture, #header").has("#sndp"); deepEqual( obj.get(), q("qunit-fixture"), "Does not include elements that do not have the element as a descendant" ); @@ -399,14 +393,11 @@ test("has(Selector)", function() { }); test("has(Arrayish)", function() { - expect(4); + expect(3); var simple = jQuery("#qunit-fixture").has(jQuery("#sndp")); deepEqual( simple.get(), q("qunit-fixture"), "Keeps elements that have any element in the jQuery list as a descendant" ); - var detached = jQuery("<a><b><i/></b></a>"); - deepEqual( detached.has( detached.find("i") ).get(), detached.get(), "...Even when detached" ); - var multipleParent = jQuery("#qunit-fixture, #header").has(jQuery("#sndp")); deepEqual( multipleParent.get(), q("qunit-fixture"), "Does not include elements that do not have an element in the jQuery list as a descendant" ); |