From 6c2a501de40a5f6b3ad382e2d309e5a10fce04d0 Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Tue, 6 Dec 2011 15:25:38 -0500 Subject: [PATCH] Fix #5571. Setters should treat `undefined` as a no-op and be chainable. --- src/attributes.js | 4 +- src/core.js | 56 ++++++++++++++------ src/css.js | 9 +--- src/data.js | 63 ++++++++++++---------- src/dimensions.js | 73 ++++++++++++-------------- src/manipulation.js | 84 ++++++++++++++---------------- src/offset.js | 107 +++++++++++++++----------------------- src/queue.js | 20 ++++--- test/unit/attributes.js | 8 ++- test/unit/data.js | 3 +- test/unit/dimensions.js | 18 +++++-- test/unit/manipulation.js | 10 ++++ test/unit/offset.js | 12 +++-- test/unit/queue.js | 6 ++- 14 files changed, 246 insertions(+), 227 deletions(-) diff --git a/src/attributes.js b/src/attributes.js index 5aa5273cd..475f4031e 100644 --- a/src/attributes.js +++ b/src/attributes.js @@ -12,7 +12,7 @@ var rclass = /[\n\t\r]/g, jQuery.fn.extend({ attr: function( name, value ) { - return jQuery.access( this, name, value, true, jQuery.attr ); + return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 ); }, removeAttr: function( name ) { @@ -22,7 +22,7 @@ jQuery.fn.extend({ }, prop: function( name, value ) { - return jQuery.access( this, name, value, true, jQuery.prop ); + return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 ); }, removeProp: function( name ) { diff --git a/src/core.js b/src/core.js index 2fa9d8b88..1a029814f 100644 --- a/src/core.js +++ b/src/core.js @@ -801,31 +801,55 @@ jQuery.extend({ // Mutifunctional method to get and set values to a collection // The value/s can optionally be executed if it's a function - access: function( elems, key, value, exec, fn, pass ) { - var length = elems.length; + access: function( elems, fn, key, value, chainable, emptyGet, pass ) { + var exec, + bulk = key == null, + i = 0, + length = elems.length; - // Setting many attributes - if ( typeof key === "object" ) { - for ( var k in key ) { - jQuery.access( elems, k, key[k], exec, fn, value ); + // Sets many values + if ( key && typeof key === "object" ) { + for ( i in key ) { + jQuery.access( elems, fn, i, key[i], 1, emptyGet, value ); } - return elems; - } + chainable = 1; - // Setting one attribute - if ( value !== undefined ) { + // Sets one value + } else if ( value !== undefined ) { // Optionally, function values get executed if exec is true - exec = !pass && exec && jQuery.isFunction(value); + exec = pass === undefined && jQuery.isFunction( value ); - for ( var i = 0; i < length; i++ ) { - fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); + if ( bulk ) { + // Bulk operations only iterate when executing function values + if ( exec ) { + exec = fn; + fn = function( elem, key, value ) { + return exec.call( jQuery( elem ), value ); + }; + + // Otherwise they run against the entire set + } else { + fn.call( elems, value ); + fn = null; + } } - return elems; + if ( fn ) { + for (; i < length; i++ ) { + fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); + } + } + + chainable = 1; } - // Getting an attribute - return length ? fn( elems[0], key ) : undefined; + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + length ? fn( elems[0], key ) : emptyGet; }, now: function() { diff --git a/src/css.js b/src/css.js index d31543ea1..b6c5607e4 100644 --- a/src/css.js +++ b/src/css.js @@ -17,16 +17,11 @@ var ralpha = /alpha\([^)]*\)/i, currentStyle; jQuery.fn.css = function( name, value ) { - // Setting 'undefined' is a no-op - if ( arguments.length === 2 && value === undefined ) { - return this; - } - - return jQuery.access( this, name, value, true, function( elem, name, value ) { + return jQuery.access( this, function( elem, name, value ) { return value !== undefined ? jQuery.style( elem, name, value ) : jQuery.css( elem, name ); - }); + }, name, value, arguments.length > 1 ); }; jQuery.extend({ diff --git a/src/data.js b/src/data.js index 11f26565b..43b8b7b5d 100644 --- a/src/data.js +++ b/src/data.js @@ -246,62 +246,69 @@ jQuery.extend({ jQuery.fn.extend({ data: function( key, value ) { - var parts, attr, name, + var parts, part, attr, name, l, + elem = this[0], + i = 0, data = null; - if ( typeof key === "undefined" ) { + // Gets all values + if ( key === undefined ) { if ( this.length ) { - data = jQuery.data( this[0] ); + data = jQuery.data( elem ); - if ( this[0].nodeType === 1 && !jQuery._data( this[0], "parsedAttrs" ) ) { - attr = this[0].attributes; - for ( var i = 0, l = attr.length; i < l; i++ ) { + if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { + attr = elem.attributes; + for ( l = attr.length; i < l; i++ ) { name = attr[i].name; if ( name.indexOf( "data-" ) === 0 ) { name = jQuery.camelCase( name.substring(5) ); - dataAttr( this[0], name, data[ name ] ); + dataAttr( elem, name, data[ name ] ); } } - jQuery._data( this[0], "parsedAttrs", true ); + jQuery._data( elem, "parsedAttrs", true ); } } return data; + } - } else if ( typeof key === "object" ) { + // Sets multiple values + if ( typeof key === "object" ) { return this.each(function() { jQuery.data( this, key ); }); } - parts = key.split("."); - parts[1] = parts[1] ? "." + parts[1] : ""; + return jQuery.access( this, function( value ) { + parts = key.split( ".", 2 ), + parts[1] = parts[1] ? "." + parts[1] : ""; + part = parts[1] + "!"; - if ( value === undefined ) { - data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]); + if ( value === undefined ) { + data = this.triggerHandler( "getData" + part, [ parts[0] ] ); - // Try to fetch any internally stored data first - if ( data === undefined && this.length ) { - data = jQuery.data( this[0], key ); - data = dataAttr( this[0], key, data ); + // Try to fetch any internally stored data first + if ( data === undefined && elem ) { + data = jQuery.data( elem, key ); + data = dataAttr( elem, key, data ); + } + + return data === undefined && parts[1] ? + this.data( parts[0] ) : + data; } - return data === undefined && parts[1] ? - this.data( parts[0] ) : - data; + parts[1] = value; + this.each(function() { + var self = jQuery( this ); - } else { - return this.each(function() { - var self = jQuery( this ), - args = [ parts[0], value ]; - - self.triggerHandler( "setData" + parts[1] + "!", args ); + self.triggerHandler( "setData" + part, parts ); jQuery.data( this, key, value ); - self.triggerHandler( "changeData" + parts[1] + "!", args ); + self.triggerHandler( "changeData" + part, parts ); }); - } + }, null, value, arguments.length > 1, null, false ); }, removeData: function( key ) { diff --git a/src/dimensions.js b/src/dimensions.js index d339817c9..769b99693 100644 --- a/src/dimensions.js +++ b/src/dimensions.js @@ -1,9 +1,10 @@ (function( jQuery ) { // Create width, height, innerHeight, innerWidth, outerHeight and outerWidth methods -jQuery.each([ "Height", "Width" ], function( i, name ) { - - var type = name.toLowerCase(); +jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { + var clientProp = "client" + name, + scrollProp = "scroll" + name, + offsetProp = "offset" + name; // innerHeight and innerWidth jQuery.fn[ "inner" + name ] = function() { @@ -25,50 +26,40 @@ jQuery.each([ "Height", "Width" ], function( i, name ) { null; }; - jQuery.fn[ type ] = function( size ) { - // Get window width or height - var elem = this[0]; - if ( !elem ) { - return size == null ? null : this; - } + jQuery.fn[ type ] = function( value ) { + return jQuery.access( this, function( elem, type, value ) { + var doc, docElemProp, orig, ret; - if ( jQuery.isFunction( size ) ) { - return this.each(function( i ) { - var self = jQuery( this ); - self[ type ]( size.call( this, i, self[ type ]() ) ); - }); - } + if ( jQuery.isWindow( elem ) ) { + // 3rd condition allows Nokia support, as it supports the docElem prop but not CSS1Compat + doc = elem.document; + docElemProp = doc.documentElement[ clientProp ]; + return doc.compatMode === "CSS1Compat" && docElemProp || + doc.body && doc.body[ clientProp ] || docElemProp; + } - if ( jQuery.isWindow( elem ) ) { - // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode - // 3rd condition allows Nokia support, as it supports the docElem prop but not CSS1Compat - var docElemProp = elem.document.documentElement[ "client" + name ], - body = elem.document.body; - return elem.document.compatMode === "CSS1Compat" && docElemProp || - body && body[ "client" + name ] || docElemProp; + // Get document width or height + if ( elem.nodeType === 9 ) { + // Either scroll[Width/Height] or offset[Width/Height], whichever is greater + doc = elem.documentElement; + return Math.max( + doc[ clientProp ], + elem.body[ scrollProp ], doc[ scrollProp ], + elem.body[ offsetProp ], doc[ offsetProp ] + ); + } - // Get document width or height - } else if ( elem.nodeType === 9 ) { - // Either scroll[Width/Height] or offset[Width/Height], whichever is greater - return Math.max( - elem.documentElement["client" + name], - elem.body["scroll" + name], elem.documentElement["scroll" + name], - elem.body["offset" + name], elem.documentElement["offset" + name] - ); - - // Get or set width or height on the element - } else if ( size === undefined ) { - var orig = jQuery.css( elem, type ), + // Get width or height on the element + if ( value === undefined ) { + orig = jQuery.css( elem, type ); ret = parseFloat( orig ); + return jQuery.isNumeric( ret ) ? ret : orig; + } - return jQuery.isNumeric( ret ) ? ret : orig; - - // Set the width or height on the element (default to pixels if value is unitless) - } else { - return this.css( type, typeof size === "string" ? size : size + "px" ); - } + // Set the width or height on the element + jQuery( elem ).css( type, value ); + }, type, value, arguments.length, null ); }; - }); })( jQuery ); diff --git a/src/manipulation.js b/src/manipulation.js index 28d63b8a2..5715a905d 100644 --- a/src/manipulation.js +++ b/src/manipulation.js @@ -51,20 +51,12 @@ if ( !jQuery.support.htmlSerialize ) { } jQuery.fn.extend({ - text: function( text ) { - if ( jQuery.isFunction(text) ) { - return this.each(function(i) { - var self = jQuery( this ); - - self.text( text.call(this, i, self.text()) ); - }); - } - - if ( typeof text !== "object" && text !== undefined ) { - return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) ); - } - - return jQuery.text( this ); + text: function( value ) { + return jQuery.access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) ); + }, null, value, arguments.length ); }, wrapAll: function( html ) { @@ -216,44 +208,44 @@ jQuery.fn.extend({ }, html: function( value ) { - if ( value === undefined ) { - return this[0] && this[0].nodeType === 1 ? - this[0].innerHTML.replace(rinlinejQuery, "") : - null; + return jQuery.access( this, function( value ) { + var elem = this[0] || {}, + i = 0, + l = this.length; - // See if we can take a shortcut and just use innerHTML - } else if ( typeof value === "string" && !rnoInnerhtml.test( value ) && - (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) && - !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) { - - value = value.replace(rxhtmlTag, "<$1>"); - - try { - for ( var i = 0, l = this.length; i < l; i++ ) { - // Remove element nodes and prevent memory leaks - if ( this[i].nodeType === 1 ) { - jQuery.cleanData( this[i].getElementsByTagName("*") ); - this[i].innerHTML = value; - } - } - - // If using innerHTML throws an exception, use the fallback method - } catch(e) { - this.empty().append( value ); + if ( value === undefined ) { + return elem.nodeType === 1 ? + elem.innerHTML.replace( rinlinejQuery, "" ) : + null; } - } else if ( jQuery.isFunction( value ) ) { - this.each(function(i){ - var self = jQuery( this ); - self.html( value.call(this, i, self.html()) ); - }); + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && + !wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) { - } else { - this.empty().append( value ); - } + value = value.replace( rxhtmlTag, "<$1>" ); - return this; + try { + for (; i < l; i++ ) { + // Remove element nodes and prevent memory leaks + elem = this[i] || {}; + if ( elem.nodeType === 1 ) { + jQuery.cleanData( elem.getElementsByTagName( "*" ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch(e) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); }, replaceWith: function( value ) { diff --git a/src/offset.js b/src/offset.js index ad10236f6..6433a5b7a 100644 --- a/src/offset.js +++ b/src/offset.js @@ -1,40 +1,22 @@ (function( jQuery ) { -var rtable = /^t(?:able|d|h)$/i, +var getOffset, + rtable = /^t(?:able|d|h)$/i, rroot = /^(?:body|html)$/i; if ( "getBoundingClientRect" in document.documentElement ) { - jQuery.fn.offset = function( options ) { - var elem = this[0], box; - - if ( options ) { - return this.each(function( i ) { - jQuery.offset.setOffset( this, options, i ); - }); - } - - if ( !elem || !elem.ownerDocument ) { - return null; - } - - if ( elem === elem.ownerDocument.body ) { - return jQuery.offset.bodyOffset( elem ); - } - + getOffset = function( elem, doc, docElem, box ) { try { box = elem.getBoundingClientRect(); } catch(e) {} - var doc = elem.ownerDocument, - docElem = doc.documentElement; - // Make sure we're not dealing with a disconnected DOM node if ( !box || !jQuery.contains( docElem, elem ) ) { return box ? { top: box.top, left: box.left } : { top: 0, left: 0 }; } var body = doc.body, - win = getWindow(doc), + win = getWindow( doc ), clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0, scrollTop = win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop, @@ -46,28 +28,10 @@ if ( "getBoundingClientRect" in document.documentElement ) { }; } else { - jQuery.fn.offset = function( options ) { - var elem = this[0]; - - if ( options ) { - return this.each(function( i ) { - jQuery.offset.setOffset( this, options, i ); - }); - } - - if ( !elem || !elem.ownerDocument ) { - return null; - } - - if ( elem === elem.ownerDocument.body ) { - return jQuery.offset.bodyOffset( elem ); - } - + getOffset = function( elem, doc, docElem ) { var computedStyle, offsetParent = elem.offsetParent, prevOffsetParent = elem, - doc = elem.ownerDocument, - docElem = doc.documentElement, body = doc.body, defaultView = doc.defaultView, prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle, @@ -118,6 +82,29 @@ if ( "getBoundingClientRect" in document.documentElement ) { }; } +jQuery.fn.offset = function( options ) { + if ( arguments.length ) { + return options === undefined ? + this : + this.each(function( i ) { + jQuery.offset.setOffset( this, options, i ); + }); + } + + var elem = this[0], + doc = elem && elem.ownerDocument; + + if ( !doc ) { + return null; + } + + if ( elem === doc.body ) { + return jQuery.offset.bodyOffset( elem ); + } + + return getOffset( elem, doc, doc.documentElement ); +}; + jQuery.offset = { bodyOffset: function( body ) { @@ -223,42 +210,30 @@ jQuery.fn.extend({ // Create scrollLeft and scrollTop methods -jQuery.each( ["Left", "Top"], function( i, name ) { - var method = "scroll" + name; +jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( method, prop ) { + var top = /Y/.test( prop ); jQuery.fn[ method ] = function( val ) { - var elem, win; + return jQuery.access( this, function( elem, method, val ) { + var win = getWindow( elem ); - if ( val === undefined ) { - elem = this[ 0 ]; - - if ( !elem ) { - return null; + if ( val === undefined ) { + return win ? (prop in win) ? win[ prop ] : + jQuery.support.boxModel && win.document.documentElement[ method ] || + win.document.body[ method ] : + elem[ method ]; } - win = getWindow( elem ); - - // Return the scroll offset - return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] : - jQuery.support.boxModel && win.document.documentElement[ method ] || - win.document.body[ method ] : - elem[ method ]; - } - - // Set the scroll offset - return this.each(function() { - win = getWindow( this ); - if ( win ) { win.scrollTo( - !i ? val : jQuery( win ).scrollLeft(), - i ? val : jQuery( win ).scrollTop() + !top ? val : jQuery( win ).scrollLeft(), + top ? val : jQuery( win ).scrollTop() ); } else { - this[ method ] = val; + elem[ method ] = val; } - }); + }, method, val, arguments.length, null ); }; }); diff --git a/src/queue.js b/src/queue.js index ef97485f9..da3e59721 100644 --- a/src/queue.js +++ b/src/queue.js @@ -100,21 +100,27 @@ jQuery.extend({ jQuery.fn.extend({ queue: function( type, data ) { + var setter = 2; + if ( typeof type !== "string" ) { data = type; type = "fx"; + setter--; } - if ( data === undefined ) { + if ( arguments.length < setter ) { return jQuery.queue( this[0], type ); } - return this.each(function() { - var queue = jQuery.queue( this, type, data ); - if ( type === "fx" && queue[0] !== "inprogress" ) { - jQuery.dequeue( this, type ); - } - }); + return data === undefined ? + this : + this.each(function() { + var queue = jQuery.queue( this, type, data ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + }); }, dequeue: function( type ) { return this.each(function() { diff --git a/test/unit/attributes.js b/test/unit/attributes.js index 0bdea7f96..dbfa8c0c1 100644 --- a/test/unit/attributes.js +++ b/test/unit/attributes.js @@ -158,7 +158,7 @@ test("attr(Hash)", function() { }); test("attr(String, Object)", function() { - expect(78); + expect(81); var div = jQuery("div").attr("foo", "bar"), fail = false; @@ -353,6 +353,12 @@ test("attr(String, Object)", function() { + "").appendTo("body"); equal( $svg.attr("cx", 100).attr("cx"), "100", "Set attribute on svg element" ); $svg.remove(); + + // undefined values are chainable + jQuery("#name").attr("maxlength", "5").removeAttr("nonexisting"); + equal( typeof jQuery("#name").attr("maxlength", undefined), "object", ".attr('attribute', undefined) is chainable (#5571)" ); + equal( jQuery("#name").attr("maxlength", undefined).attr("maxlength"), "5", ".attr('attribute', undefined) does not change value (#5571)" ); + equal( jQuery("#name").attr("nonexisting", undefined).attr("nonexisting"), undefined, ".attr('attribute', undefined) does not create attribute (#5571)" ); }); test("attr(jquery_method)", function(){ diff --git a/test/unit/data.js b/test/unit/data.js index 133793817..006e29e6a 100644 --- a/test/unit/data.js +++ b/test/unit/data.js @@ -222,8 +222,7 @@ test(".data(String) and .data(String, Object)", function() { div.data("test", "overwritten"); equal( div.data("test"), "overwritten", "Check for overwritten data" ); - div.data("test", undefined); - equal( div.data("test"), "overwritten", "Check that data wasn't removed"); + equal( div.data("test", undefined).data("test"), "overwritten", "Check that .data('key',undefined) does nothing but is chainable (#5571)"); div.data("test", null); ok( div.data("test") === null, "Check for null data"); diff --git a/test/unit/dimensions.js b/test/unit/dimensions.js index 117247822..222459f51 100644 --- a/test/unit/dimensions.js +++ b/test/unit/dimensions.js @@ -41,11 +41,16 @@ test("width()", function() { testWidth( pass ); }); -test("width() with function", function() { +test("width(undefined)", function() { + expect(1); + equal(jQuery("#nothiddendiv").width(30).width(undefined).width(), 30, ".width(undefined) is chainable (#5571)"); +}); + +test("width(Function)", function() { testWidth( fn ); }); -test("width() with function args", function() { +test("width(Function(args))", function() { expect( 2 ); var $div = jQuery("#nothiddendiv"); @@ -90,11 +95,16 @@ test("height()", function() { testHeight( pass ); }); -test("height() with function", function() { +test("height(undefined)", function() { + expect(1); + equal(jQuery("#nothiddendiv").height(30).height(undefined).height(), 30, ".height(undefined) is chainable (#5571)"); +}); + +test("height(Function)", function() { testHeight( fn ); }); -test("height() with function args", function() { +test("height(Function(args))", function() { expect( 2 ); var $div = jQuery("#nothiddendiv"); diff --git a/test/unit/manipulation.js b/test/unit/manipulation.js index f690b721d..44bb9110c 100644 --- a/test/unit/manipulation.js +++ b/test/unit/manipulation.js @@ -16,6 +16,11 @@ test("text()", function() { notEqual( jQuery(document).text(), "", "Retrieving text for the document retrieves all text (#10724)."); }); +test("text(undefined)", function() { + expect(1); + equal( jQuery("#foo").text("Hello cruel world!"); @@ -1207,6 +1212,11 @@ test("clone() on XML nodes", function() { }); } +test("html(undefined)", function() { + expect(1); + equal( jQuery("#foo").html("test").html(undefined).html().toLowerCase(), "test", ".html(undefined) is chainable (#5571)" ); +}); + var testHtml = function(valueObj) { expect(34); diff --git a/test/unit/offset.js b/test/unit/offset.js index a37130653..466e65006 100644 --- a/test/unit/offset.js +++ b/test/unit/offset.js @@ -342,7 +342,7 @@ testoffset("table", function( jQuery ) { }); testoffset("scroll", function( jQuery, win ) { - expect(22); + expect(24); var ie = jQuery.browser.msie && parseInt( jQuery.browser.version, 10 ) < 8; @@ -362,8 +362,9 @@ testoffset("scroll", function( jQuery, win ) { equal( jQuery("#scroll-1-1").scrollTop(), 0, "jQuery('#scroll-1-1').scrollTop()" ); equal( jQuery("#scroll-1-1").scrollLeft(), 0, "jQuery('#scroll-1-1').scrollLeft()" ); - // equal( jQuery("body").scrollTop(), 0, "jQuery("body").scrollTop()" ); - // equal( jQuery("body").scrollLeft(), 0, "jQuery("body").scrollTop()" ); + // scroll method chaining + equal( jQuery("#scroll-1").scrollTop(undefined).scrollTop(), 5, ".scrollTop(undefined) is chainable (#5571)" ); + equal( jQuery("#scroll-1").scrollLeft(undefined).scrollLeft(), 5, ".scrollLeft(undefined) is chainable (#5571)" ); win.name = "test"; @@ -405,11 +406,12 @@ testoffset("body", function( jQuery ) { equal( jQuery("body").offset().left, 1, "jQuery('#body').offset().left" ); }); -test("Chaining offset(coords) returns jQuery object", function() { - expect(2); +test("chaining", function() { + expect(3); var coords = { top: 1, left: 1 }; equal( jQuery("#absolute-1").offset(coords).selector, "#absolute-1", "offset(coords) returns jQuery object" ); equal( jQuery("#non-existent").offset(coords).selector, "#non-existent", "offset(coords) with empty jQuery set returns jQuery object" ); + equal( jQuery("#absolute-1").offset(undefined).selector, "#absolute-1", "offset(undefined) returns jQuery object (#5571)" ); }); test("offsetParent", function(){ diff --git a/test/unit/queue.js b/test/unit/queue.js index 40523e7f9..701956050 100644 --- a/test/unit/queue.js +++ b/test/unit/queue.js @@ -1,7 +1,7 @@ module("queue", { teardown: moduleTeardown }); test("queue() with other types",function() { - expect(11); + expect(12); var counter = 0; stop(); @@ -36,6 +36,8 @@ test("queue() with other types",function() { equal( $div.queue("foo").length, 4, "Testing queue length" ); + equal( $div.queue("foo", undefined).queue("foo").length, 4, ".queue('name',undefined) does nothing but is chainable (#5571)"); + $div.dequeue("foo"); equal( counter, 3, "Testing previous call to dequeue" ); @@ -289,4 +291,4 @@ test("promise()", function() { jQuery.each( objects, function() { this.dequeue(); }); -}); \ No newline at end of file +});