From 600d3145386a9dca8143918cc3e339168f886a63 Mon Sep 17 00:00:00 2001 From: jeresig Date: Wed, 6 Jan 2010 15:08:07 -0500 Subject: [PATCH 01/14] A first pass at making sure that all the setter function arguments receive the index of the element and a relevant value to work with. Fixes #5763. --- src/attributes.js | 114 ++++++++++++++++++++++++-------------------- src/core.js | 2 +- src/manipulation.js | 16 ++++--- 3 files changed, 72 insertions(+), 60 deletions(-) diff --git a/src/attributes.js b/src/attributes.js index a2108feb..664a0244 100644 --- a/src/attributes.js +++ b/src/attributes.js @@ -12,10 +12,27 @@ jQuery.fn.extend({ return access( this, name, value, true, jQuery.attr ); }, + removeAttr: function( name ) { + if ( jQuery.isFunction( name ) ) { + return this.each(function(i) { + var self = jQuery(this); + self.removeAttr( name.call(this, i, self.attr(name)) ); + }); + } + + return this.each(function(){ + jQuery.attr( this, name, "" ); + if ( this.nodeType === 1 ) { + this.removeAttribute( name ); + } + }); + }, + addClass: function( value ) { if ( jQuery.isFunction(value) ) { - return this.each(function() { - jQuery(this).addClass( value.call(this) ); + return this.each(function(i) { + var self = jQuery(this); + self.addClass( value.call(this, i, self.attr("class")) ); }); } @@ -46,8 +63,9 @@ jQuery.fn.extend({ removeClass: function( value ) { if ( jQuery.isFunction(value) ) { - return this.each(function() { - jQuery(this).removeClass( value.call(this) ); + return this.each(function(i) { + var self = jQuery(this); + self.removeClass( value.call(this, i, self.attr("class")) ); }); } @@ -75,6 +93,40 @@ jQuery.fn.extend({ return this; }, + toggleClass: function( classNames, state ) { + var type = typeof classNames; + + if ( jQuery.isFunction( classNames ) ) { + return this.each(function(i) { + var self = jQuery(this); + self.toggleClass( classNames.call(this, i, self.attr("class")), state ); + }); + } + + return this.each(function(){ + if ( type === "string" ) { + // toggle individual class names + var isBool = typeof state === "boolean", className, i = 0, + classNames = classNames.split( rspace ); + + while ( (className = classNames[ i++ ]) ) { + // check each className given, space seperated list + state = isBool ? state : !jQuery(this).hasClass( className ); + jQuery(this)[ state ? "addClass" : "removeClass" ]( className ); + } + + } else if ( type === "undefined" || type === "boolean" ) { + if ( this.className ) { + // store className if set + jQuery.data( this, "__className__", this.className ); + } + + // toggle whole className + this.className = this.className || classNames === false ? "" : jQuery.data( this, "__className__" ) || ""; + } + }); + }, + hasClass: function( selector ) { var className = " " + selector + " "; for ( var i = 0, l = this.length; i < l; i++ ) { @@ -149,9 +201,11 @@ jQuery.fn.extend({ var val = value; - return this.each(function() { + return this.each(function(i) { + var self = jQuery(this); + if ( jQuery.isFunction(value) ) { - val = value.call(this); + val = value.call(this, i, self.val()); // Typecast each time if the value is a Function and the appended // value is therefore different each time. @@ -165,13 +219,13 @@ jQuery.fn.extend({ } if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) { - this.checked = jQuery.inArray( jQuery(this).val(), val ) >= 0; + this.checked = jQuery.inArray( self.val(), val ) >= 0; } else if ( jQuery.nodeName( this, "select" ) ) { var values = jQuery.makeArray(val); jQuery( "option", this ).each(function() { - this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; + this.selected = jQuery.inArray( self.val(), values ) >= 0; }); if ( !values.length ) { @@ -185,50 +239,6 @@ jQuery.fn.extend({ } }); -jQuery.each({ - removeAttr: function( name ) { - jQuery.attr( this, name, "" ); - if ( this.nodeType === 1 ) { - this.removeAttribute( name ); - } - }, - - toggleClass: function( classNames, state ) { - var type = typeof classNames; - - if ( type === "string" ) { - // toggle individual class names - var isBool = typeof state === "boolean", className, i = 0, - classNames = classNames.split( rspace ); - - while ( (className = classNames[ i++ ]) ) { - // check each className given, space seperated list - state = isBool ? state : !jQuery(this).hasClass( className ); - jQuery(this)[ state ? "addClass" : "removeClass" ]( className ); - } - - } else if ( type === "undefined" || type === "boolean" ) { - if ( this.className ) { - // store className if set - jQuery.data( this, "__className__", this.className ); - } - - // toggle whole className - this.className = this.className || classNames === false ? "" : jQuery.data( this, "__className__" ) || ""; - } - } -}, function( name, fn ) { - jQuery.fn[ name ] = function( val, state ) { - if ( jQuery.isFunction( val ) ) { - return this.each(function() { - jQuery(this)[ name ]( val.call(this), state ); - }); - } - - return this.each( fn, arguments ); - }; -}); - jQuery.extend({ attrFn: { val: true, diff --git a/src/core.js b/src/core.js index 58cbbc7e..831570ed 100644 --- a/src/core.js +++ b/src/core.js @@ -775,7 +775,7 @@ function access( elems, key, value, exec, fn, pass ) { exec = exec && jQuery.isFunction(value); for ( var i = 0; i < length; i++ ) { - fn( elems[i], key, exec ? value.call( elems[i], i ) : value, pass ); + fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); } return elems; diff --git a/src/manipulation.js b/src/manipulation.js index 2af2d7e7..730dfca5 100644 --- a/src/manipulation.js +++ b/src/manipulation.js @@ -33,8 +33,9 @@ if ( !jQuery.support.htmlSerialize ) { jQuery.fn.extend({ text: function( text ) { if ( jQuery.isFunction(text) ) { - return this.each(function() { - return jQuery(this).text( text.call(this) ); + return this.each(function(i) { + var self = jQuery(this); + return self.text( text.call(this, i, self.text()) ); }); } @@ -47,8 +48,8 @@ jQuery.fn.extend({ wrapAll: function( html ) { if ( jQuery.isFunction( html ) ) { - return this.each(function() { - jQuery(this).wrapAll( html.apply(this, arguments) ); + return this.each(function(i) { + jQuery(this).wrapAll( html.call(this, i) ); }); } @@ -228,9 +229,10 @@ jQuery.fn.extend({ var results, first, value = args[0], scripts = []; if ( jQuery.isFunction(value) ) { - return this.each(function() { - args[0] = value.call(this); - return jQuery(this).domManip( args, table, callback ); + return this.each(function(i) { + var self = jQuery(this); + args[0] = value.call(this, i, table ? self.html() : undefined); + return self.domManip( args, table, callback ); }); } From 2526e293538c0959597fee60976b4360390d69e0 Mon Sep 17 00:00:00 2001 From: jeresig Date: Wed, 6 Jan 2010 15:23:30 -0500 Subject: [PATCH 02/14] Fixing some bugs in the re-tooling of toggleClass, adding in some performance optimizations. --- src/attributes.js | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/attributes.js b/src/attributes.js index 664a0244..a5a6662c 100644 --- a/src/attributes.js +++ b/src/attributes.js @@ -93,26 +93,27 @@ jQuery.fn.extend({ return this; }, - toggleClass: function( classNames, state ) { - var type = typeof classNames; + toggleClass: function( value, stateVal ) { + var type = typeof value, isBool = typeof stateVal === "boolean"; - if ( jQuery.isFunction( classNames ) ) { + if ( jQuery.isFunction( value ) ) { return this.each(function(i) { var self = jQuery(this); - self.toggleClass( classNames.call(this, i, self.attr("class")), state ); + self.toggleClass( value.call(this, i, self.attr("class")), stateVal ); }); } - return this.each(function(){ + return this.each(function() { if ( type === "string" ) { // toggle individual class names - var isBool = typeof state === "boolean", className, i = 0, - classNames = classNames.split( rspace ); + var className, i = 0, self = jQuery(this), + state = stateVal, + classNames = value.split( rspace ); while ( (className = classNames[ i++ ]) ) { // check each className given, space seperated list - state = isBool ? state : !jQuery(this).hasClass( className ); - jQuery(this)[ state ? "addClass" : "removeClass" ]( className ); + state = isBool ? state : !self.hasClass( className ); + self[ state ? "addClass" : "removeClass" ]( className ); } } else if ( type === "undefined" || type === "boolean" ) { @@ -122,7 +123,7 @@ jQuery.fn.extend({ } // toggle whole className - this.className = this.className || classNames === false ? "" : jQuery.data( this, "__className__" ) || ""; + this.className = this.className || value === false ? "" : jQuery.data( this, "__className__" ) || ""; } }); }, From 4681216c4bdf25b6b146b3f952917f46079c6ef7 Mon Sep 17 00:00:00 2001 From: jeresig Date: Thu, 7 Jan 2010 09:53:16 -0500 Subject: [PATCH 03/14] Fixed some bugs relating to the setter arg change in val and html. Also optimized the code in val a bit. --- src/attributes.js | 31 +++++++++++++------------------ src/manipulation.js | 2 +- 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/src/attributes.js b/src/attributes.js index a5a6662c..1dd70842 100644 --- a/src/attributes.js +++ b/src/attributes.js @@ -195,30 +195,25 @@ jQuery.fn.extend({ return undefined; } - // Typecast once if the value is a number - if ( typeof value === "number" ) { - value += ""; - } - - var val = value; + var isFunction = jQuery.isFunction(value); return this.each(function(i) { - var self = jQuery(this); - - if ( jQuery.isFunction(value) ) { - val = value.call(this, i, self.val()); - - // Typecast each time if the value is a Function and the appended - // value is therefore different each time. - if ( typeof val === "number" ) { - val += ""; - } - } + var self = jQuery(this), val = value; if ( this.nodeType !== 1 ) { return; } + if ( isFunction ) { + val = value.call(this, i, self.val()); + } + + // Typecast each time if the value is a Function and the appended + // value is therefore different each time. + if ( typeof val === "number" ) { + val += ""; + } + if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) { this.checked = jQuery.inArray( self.val(), val ) >= 0; @@ -226,7 +221,7 @@ jQuery.fn.extend({ var values = jQuery.makeArray(val); jQuery( "option", this ).each(function() { - this.selected = jQuery.inArray( self.val(), values ) >= 0; + this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; }); if ( !values.length ) { diff --git a/src/manipulation.js b/src/manipulation.js index 730dfca5..081bb548 100644 --- a/src/manipulation.js +++ b/src/manipulation.js @@ -173,7 +173,7 @@ jQuery.fn.extend({ html: function( value ) { if ( value === undefined ) { - return this[0] ? + return this[0] && this[0].nodeType === 1 ? this[0].innerHTML.replace(rinlinejQuery, "") : null; From 12e8f07e343b49042bd9a2035411c74b51ed7550 Mon Sep 17 00:00:00 2001 From: jeresig Date: Thu, 7 Jan 2010 09:55:15 -0500 Subject: [PATCH 04/14] Moved the val() tests from manipulation into attributes. --- test/unit/attributes.js | 86 +++++++++++++++++++++++++++++++++++++++ test/unit/manipulation.js | 86 --------------------------------------- 2 files changed, 86 insertions(+), 86 deletions(-) diff --git a/test/unit/attributes.js b/test/unit/attributes.js index 06920762..e1b4c0dc 100644 --- a/test/unit/attributes.js +++ b/test/unit/attributes.js @@ -292,6 +292,92 @@ test("attr('tabindex', value)", function() { equals(element.attr('tabindex'), -1, 'set negative tabindex'); }); +test("val()", function() { + expect(17); + + document.getElementById('text1').value = "bla"; + equals( jQuery("#text1").val(), "bla", "Check for modified value of input element" ); + + reset(); + + equals( jQuery("#text1").val(), "Test", "Check for value of input element" ); + // ticket #1714 this caused a JS error in IE + equals( jQuery("#first").val(), "", "Check a paragraph element to see if it has a value" ); + ok( jQuery([]).val() === undefined, "Check an empty jQuery object will return undefined from val" ); + + equals( jQuery('#select2').val(), '3', 'Call val() on a single="single" select' ); + + same( jQuery('#select3').val(), ['1', '2'], 'Call val() on a multiple="multiple" select' ); + + equals( jQuery('#option3c').val(), '2', 'Call val() on a option element with value' ); + + equals( jQuery('#option3a').val(), '', 'Call val() on a option element with empty value' ); + + equals( jQuery('#option3e').val(), 'no value', 'Call val() on a option element with no value attribute' ); + + equals( jQuery('#option3a').val(), '', 'Call val() on a option element with no value attribute' ); + + jQuery('#select3').val(""); + same( jQuery('#select3').val(), [''], 'Call val() on a multiple="multiple" select' ); + + var checks = jQuery("").appendTo("#form") + .add( jQuery("").appendTo("#form") ) + .add( jQuery("").appendTo("#form") ) + .add( jQuery("").appendTo("#form") ); + + same( checks.serialize(), "", "Get unchecked values." ); + + equals( checks.eq(3).val(), "on", "Make sure a value of 'on' is provided if none is specified." ); + + checks.val([ "2" ]); + same( checks.serialize(), "test=2", "Get a single checked value." ); + + checks.val([ "1", "" ]); + same( checks.serialize(), "test=1&test=", "Get multiple checked values." ); + + checks.val([ "", "2" ]); + same( checks.serialize(), "test=2&test=", "Get multiple checked values." ); + + checks.val([ "1", "on" ]); + same( checks.serialize(), "test=1&test=on", "Get multiple checked values." ); + + checks.remove(); +}); + +var testVal = function(valueObj) { + expect(6); + + jQuery("#text1").val(valueObj( 'test' )); + equals( document.getElementById('text1').value, "test", "Check for modified (via val(String)) value of input element" ); + + jQuery("#text1").val(valueObj( 67 )); + equals( document.getElementById('text1').value, "67", "Check for modified (via val(Number)) value of input element" ); + + jQuery("#select1").val(valueObj( "3" )); + equals( jQuery("#select1").val(), "3", "Check for modified (via val(String)) value of select element" ); + + jQuery("#select1").val(valueObj( 2 )); + equals( jQuery("#select1").val(), "2", "Check for modified (via val(Number)) value of select element" ); + + jQuery("#select1").append(""); + jQuery("#select1").val(valueObj( 4 )); + equals( jQuery("#select1").val(), "4", "Should be possible to set the val() to a newly created option" ); + + // using contents will get comments regular, text, and comment nodes + var j = jQuery("#nonnodes").contents(); + j.val(valueObj( "asdf" )); + equals( j.val(), "asdf", "Check node,textnode,comment with val()" ); + j.removeAttr("value"); +} + +test("val(String/Number)", function() { + testVal(bareObj); +}); + +test("val(Function)", function() { + testVal(functionReturningObj); +}) + var testAddClass = function(valueObj) { expect(2); var div = jQuery("div"); diff --git a/test/unit/manipulation.js b/test/unit/manipulation.js index 9242dddb..97f1e5da 100644 --- a/test/unit/manipulation.js +++ b/test/unit/manipulation.js @@ -618,92 +618,6 @@ test("clone() on XML nodes", function() { }); } -test("val()", function() { - expect(17); - - document.getElementById('text1').value = "bla"; - equals( jQuery("#text1").val(), "bla", "Check for modified value of input element" ); - - reset(); - - equals( jQuery("#text1").val(), "Test", "Check for value of input element" ); - // ticket #1714 this caused a JS error in IE - equals( jQuery("#first").val(), "", "Check a paragraph element to see if it has a value" ); - ok( jQuery([]).val() === undefined, "Check an empty jQuery object will return undefined from val" ); - - equals( jQuery('#select2').val(), '3', 'Call val() on a single="single" select' ); - - same( jQuery('#select3').val(), ['1', '2'], 'Call val() on a multiple="multiple" select' ); - - equals( jQuery('#option3c').val(), '2', 'Call val() on a option element with value' ); - - equals( jQuery('#option3a').val(), '', 'Call val() on a option element with empty value' ); - - equals( jQuery('#option3e').val(), 'no value', 'Call val() on a option element with no value attribute' ); - - equals( jQuery('#option3a').val(), '', 'Call val() on a option element with no value attribute' ); - - jQuery('#select3').val(""); - same( jQuery('#select3').val(), [''], 'Call val() on a multiple="multiple" select' ); - - var checks = jQuery("").appendTo("#form") - .add( jQuery("").appendTo("#form") ) - .add( jQuery("").appendTo("#form") ) - .add( jQuery("").appendTo("#form") ); - - same( checks.serialize(), "", "Get unchecked values." ); - - equals( checks.eq(3).val(), "on", "Make sure a value of 'on' is provided if none is specified." ); - - checks.val([ "2" ]); - same( checks.serialize(), "test=2", "Get a single checked value." ); - - checks.val([ "1", "" ]); - same( checks.serialize(), "test=1&test=", "Get multiple checked values." ); - - checks.val([ "", "2" ]); - same( checks.serialize(), "test=2&test=", "Get multiple checked values." ); - - checks.val([ "1", "on" ]); - same( checks.serialize(), "test=1&test=on", "Get multiple checked values." ); - - checks.remove(); -}); - -var testVal = function(valueObj) { - expect(6); - - jQuery("#text1").val(valueObj( 'test' )); - equals( document.getElementById('text1').value, "test", "Check for modified (via val(String)) value of input element" ); - - jQuery("#text1").val(valueObj( 67 )); - equals( document.getElementById('text1').value, "67", "Check for modified (via val(Number)) value of input element" ); - - jQuery("#select1").val(valueObj( "3" )); - equals( jQuery("#select1").val(), "3", "Check for modified (via val(String)) value of select element" ); - - jQuery("#select1").val(valueObj( 2 )); - equals( jQuery("#select1").val(), "2", "Check for modified (via val(Number)) value of select element" ); - - jQuery("#select1").append(""); - jQuery("#select1").val(valueObj( 4 )); - equals( jQuery("#select1").val(), "4", "Should be possible to set the val() to a newly created option" ); - - // using contents will get comments regular, text, and comment nodes - var j = jQuery("#nonnodes").contents(); - j.val(valueObj( "asdf" )); - equals( j.val(), "asdf", "Check node,textnode,comment with val()" ); - j.removeAttr("value"); -} - -test("val(String/Number)", function() { - testVal(bareObj); -}); - -test("val(Function)", function() { - testVal(functionReturningObj); -}) - var testHtml = function(valueObj) { expect(22); From d36b29fa8e24820e0d1feb6a4ab46c440f54155a Mon Sep 17 00:00:00 2001 From: jeresig Date: Thu, 7 Jan 2010 11:04:21 -0500 Subject: [PATCH 05/14] Make sure the state is passed in to the toggleClass attribute function. --- src/attributes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/attributes.js b/src/attributes.js index 1dd70842..3ae05421 100644 --- a/src/attributes.js +++ b/src/attributes.js @@ -99,7 +99,7 @@ jQuery.fn.extend({ if ( jQuery.isFunction( value ) ) { return this.each(function(i) { var self = jQuery(this); - self.toggleClass( value.call(this, i, self.attr("class")), stateVal ); + self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal ); }); } From 21e15219be8e04b3fe25d05a65abfaef96830b9f Mon Sep 17 00:00:00 2001 From: jeresig Date: Thu, 7 Jan 2010 11:14:56 -0500 Subject: [PATCH 06/14] Removed .removeAttr(Function), it didn't really make sense. --- src/attributes.js | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/attributes.js b/src/attributes.js index 3ae05421..004c6b30 100644 --- a/src/attributes.js +++ b/src/attributes.js @@ -12,14 +12,7 @@ jQuery.fn.extend({ return access( this, name, value, true, jQuery.attr ); }, - removeAttr: function( name ) { - if ( jQuery.isFunction( name ) ) { - return this.each(function(i) { - var self = jQuery(this); - self.removeAttr( name.call(this, i, self.attr(name)) ); - }); - } - + removeAttr: function( name, fn ) { return this.each(function(){ jQuery.attr( this, name, "" ); if ( this.nodeType === 1 ) { From f126f1ce857f11154a8378fc7e0b04a00d803682 Mon Sep 17 00:00:00 2001 From: jeresig Date: Thu, 7 Jan 2010 11:15:40 -0500 Subject: [PATCH 07/14] Added tests for attribute function setters. --- test/unit/attributes.js | 150 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 141 insertions(+), 9 deletions(-) diff --git a/test/unit/attributes.js b/test/unit/attributes.js index e1b4c0dc..fd5b203d 100644 --- a/test/unit/attributes.js +++ b/test/unit/attributes.js @@ -292,6 +292,11 @@ test("attr('tabindex', value)", function() { equals(element.attr('tabindex'), -1, 'set negative tabindex'); }); +test("removeAttr(String)", function() { + expect(1); + equals( jQuery('#mark').removeAttr( "class" )[0].className, "", "remove class" ); +}); + test("val()", function() { expect(17); @@ -378,6 +383,57 @@ test("val(Function)", function() { testVal(functionReturningObj); }) +test("val(Function) with incoming value", function() { + expect(10); + + var oldVal = jQuery("#text1").val(); + + jQuery("#text1").val(function(i, val) { + equals( val, oldVal, "Make sure the incoming value is correct." ); + return "test"; + }); + + equals( document.getElementById('text1').value, "test", "Check for modified (via val(String)) value of input element" ); + + oldVal = jQuery("#text1").val(); + + jQuery("#text1").val(function(i, val) { + equals( val, oldVal, "Make sure the incoming value is correct." ); + return 67; + }); + + equals( document.getElementById('text1').value, "67", "Check for modified (via val(Number)) value of input element" ); + + oldVal = jQuery("#select1").val(); + + jQuery("#select1").val(function(i, val) { + equals( val, oldVal, "Make sure the incoming value is correct." ); + return "3"; + }); + + equals( jQuery("#select1").val(), "3", "Check for modified (via val(String)) value of select element" ); + + oldVal = jQuery("#select1").val(); + + jQuery("#select1").val(function(i, val) { + equals( val, oldVal, "Make sure the incoming value is correct." ); + return 2; + }); + + equals( jQuery("#select1").val(), "2", "Check for modified (via val(Number)) value of select element" ); + + jQuery("#select1").append(""); + + oldVal = jQuery("#select1").val(); + + jQuery("#select1").val(function(i, val) { + equals( val, oldVal, "Make sure the incoming value is correct." ); + return 4; + }); + + equals( jQuery("#select1").val(), "4", "Should be possible to set the val() to a newly created option" ); +}); + var testAddClass = function(valueObj) { expect(2); var div = jQuery("div"); @@ -402,6 +458,25 @@ test("addClass(Function)", function() { testAddClass(functionReturningObj); }); +test("addClass(Function) with incoming value", function() { + expect(39); + + var div = jQuery("div"), old = div.map(function(){ + return jQuery(this).attr("class"); + }); + + div.addClass(function(i, val) { + equals( val, old[i], "Make sure the incoming value is correct." ); + return "test"; + }); + + var pass = true; + for ( var i = 0; i < div.size(); i++ ) { + if ( div.get(i).className.indexOf("test") == -1 ) pass = false; + } + ok( pass, "Add Class" ); +}); + var testRemoveClass = function(valueObj) { expect(5); @@ -443,6 +518,23 @@ test("removeClass(Function) - simple", function() { testRemoveClass(functionReturningObj); }); +test("removeClass(Function) with incoming value", function() { + expect(39); + + var $divs = jQuery('div').addClass("test"), old = $divs.map(function(){ + return jQuery(this).attr("class"); + }); + + $divs.removeClass(function(i, val) { + equals( val, old[i], "Make sure the incoming value is correct." ); + return "test"; + }); + + ok( !$divs.is('.test'), "Remove Class" ); + + reset(); +}); + var testToggleClass = function(valueObj) { expect(17); @@ -503,17 +595,57 @@ test("toggleClass(Function[, boolean])", function() { testToggleClass(functionReturningObj); }); -var testRemoveAttr = function(valueObj) { - expect(1); - equals( jQuery('#mark').removeAttr( valueObj("class") )[0].className, "", "remove class" ); -}; +test("toggleClass(Fucntion[, boolean]) with incoming value", function() { + expect(14); -test("removeAttr(String)", function() { - testRemoveAttr(bareObj); -}); + var e = jQuery("#firstp"), old = e.attr("class"); + ok( !e.is(".test"), "Assert class not present" ); + + e.toggleClass(function(i, val) { + equals( val, old, "Make sure the incoming value is correct." ); + return "test"; + }); + ok( e.is(".test"), "Assert class present" ); + + old = e.attr("class"); + + e.toggleClass(function(i, val) { + equals( val, old, "Make sure the incoming value is correct." ); + return "test"; + }); + ok( !e.is(".test"), "Assert class not present" ); + + old = e.attr("class"); -test("removeAttr(Function)", function() { - testRemoveAttr(functionReturningObj); + // class name with a boolean + e.toggleClass(function(i, val, state) { + equals( val, old, "Make sure the incoming value is correct." ); + equals( state, false, "Make sure that the state is passed in." ); + return "test"; + }, false ); + ok( !e.is(".test"), "Assert class not present" ); + + old = e.attr("class"); + + e.toggleClass(function(i, val, state) { + equals( val, old, "Make sure the incoming value is correct." ); + equals( state, true, "Make sure that the state is passed in." ); + return "test"; + }, true ); + ok( e.is(".test"), "Assert class present" ); + + old = e.attr("class"); + + e.toggleClass(function(i, val, state) { + equals( val, old, "Make sure the incoming value is correct." ); + equals( state, false, "Make sure that the state is passed in." ); + return "test"; + }, false ); + ok( !e.is(".test"), "Assert class not present" ); + + // Cleanup + e.removeClass("test"); + e.removeData('__className__'); }); test("addClass, removeClass, hasClass", function() { From cc1a34852f02a9304c555fefba470b28f0a6f8b2 Mon Sep 17 00:00:00 2001 From: jeresig Date: Thu, 7 Jan 2010 11:51:48 -0500 Subject: [PATCH 08/14] Added some .text(Function) tests. --- test/unit/manipulation.js | 63 +++++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 26 deletions(-) diff --git a/test/unit/manipulation.js b/test/unit/manipulation.js index 97f1e5da..35b24af9 100644 --- a/test/unit/manipulation.js +++ b/test/unit/manipulation.js @@ -12,6 +12,42 @@ test("text()", function() { equals( jQuery(document.createTextNode("foo")).text(), "foo", "Text node was retreived from .text()." ); }); +var testText = function(valueObj) { + expect(4); + var val = valueObj("
Hello cruel world!
"); + equals( jQuery("#foo").text(val)[0].innerHTML.replace(/>/g, ">"), "<div><b>Hello</b> cruel world!</div>", "Check escaped text" ); + + // using contents will get comments regular, text, and comment nodes + var j = jQuery("#nonnodes").contents(); + j.text(valueObj("hi!")); + equals( jQuery(j[0]).text(), "hi!", "Check node,textnode,comment with text()" ); + equals( j[1].nodeValue, " there ", "Check node,textnode,comment with text()" ); + equals( j[2].nodeType, 8, "Check node,textnode,comment with text()" ); +} + +test("text(String)", function() { + testText(bareObj) +}); + +test("text(Function)", function() { + testText(functionReturningObj); +}); + +test("text(Function) with incoming value", function() { + expect(2); + + var old = "This link has class=\"blog\": Simon Willison's Weblog"; + + jQuery('#sap').text(function(i, val) { + equals( val, old, "Make sure the incoming value is correct." ); + return "foobar"; + }); + + equals( jQuery("#sap").text(), "foobar", 'Check for merged text of more then one element.' ); + + reset(); +}); + var testWrap = function(val) { expect(18); var defaultText = 'Try them out:' @@ -133,7 +169,7 @@ test("wrapInner(String|Element)", function() { // testWrapInner(functionReturningObj) // }) -var testUnwrap = function() { +test("unwrap()", function() { expect(9); jQuery("body").append(' '); @@ -158,10 +194,6 @@ var testUnwrap = function() { same( jQuery('body > span.unwrap').get(), abcdef, 'body contains 6 .unwrap child spans' ); jQuery('body > span.unwrap').remove(); -} - -test("unwrap()", function() { - testUnwrap(); }); var testAppend = function(valueObj) { @@ -682,27 +714,6 @@ test("html(Function)", function() { testHtml(functionReturningObj); }); -var testText = function(valueObj) { - expect(4); - var val = valueObj("
Hello cruel world!
"); - equals( jQuery("#foo").text(val)[0].innerHTML.replace(/>/g, ">"), "<div><b>Hello</b> cruel world!</div>", "Check escaped text" ); - - // using contents will get comments regular, text, and comment nodes - var j = jQuery("#nonnodes").contents(); - j.text(valueObj("hi!")); - equals( jQuery(j[0]).text(), "hi!", "Check node,textnode,comment with text()" ); - equals( j[1].nodeValue, " there ", "Check node,textnode,comment with text()" ); - equals( j[2].nodeType, 8, "Check node,textnode,comment with text()" ); -} - -test("text(String)", function() { - testText(bareObj) -}); - -test("text(Function)", function() { - testText(functionReturningObj); -}) - var testRemove = function(method) { expect(9); From 8fa9e9d6d0307a5af8d7478d6e030af5afabba9e Mon Sep 17 00:00:00 2001 From: jeresig Date: Thu, 7 Jan 2010 13:33:30 -0500 Subject: [PATCH 09/14] Make sure that .html(Function) gets the correct previous value. --- src/manipulation.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/manipulation.js b/src/manipulation.js index 081bb548..9ed22baa 100644 --- a/src/manipulation.js +++ b/src/manipulation.js @@ -196,6 +196,14 @@ jQuery.fn.extend({ this.empty().append( value ); } + } else if ( jQuery.isFunction( value ) ) { + this.each(function(i){ + var self = jQuery(this), old = self.html(); + self.empty().append(function(){ + return value.call( this, i, old ); + }); + }); + } else { this.empty().append( value ); } From 22ff8e9ea46be4b145aa4963083d7c2d99ce9b0c Mon Sep 17 00:00:00 2001 From: jeresig Date: Thu, 7 Jan 2010 13:34:16 -0500 Subject: [PATCH 10/14] Added manipulation tests for setter function args. --- test/unit/manipulation.js | 178 +++++++++++++++++++++++++++++++++++++- 1 file changed, 175 insertions(+), 3 deletions(-) diff --git a/test/unit/manipulation.js b/test/unit/manipulation.js index 35b24af9..a7e1f7e4 100644 --- a/test/unit/manipulation.js +++ b/test/unit/manipulation.js @@ -288,7 +288,68 @@ test("append(String|Element|Array<Element>|jQuery)", function() { test("append(Function)", function() { testAppend(functionReturningObj); -}) +}); + +test("append(Function) with incoming value", function() { + expect(12); + + var defaultText = 'Try them out:', old = jQuery("#first").html(); + + var result = jQuery('#first').append(function(i, val){ + equals( val, old, "Make sure the incoming value is correct." ); + return 'buga'; + }); + equals( result.text(), defaultText + 'buga', 'Check if text appending works' ); + + var select = jQuery('#select3'); + old = select.html(); + + equals( select.append(function(i, val){ + equals( val, old, "Make sure the incoming value is correct." ); + return ''; + }).find('option:last-child').attr('value'), 'appendTest', 'Appending html options to select element'); + + reset(); + var expected = "This link has class=\"blog\": Simon Willison's WeblogTry them out:"; + old = jQuery("#sap").html(); + + jQuery('#sap').append(function(i, val){ + equals( val, old, "Make sure the incoming value is correct." ); + return document.getElementById('first'); + }); + equals( expected, jQuery('#sap').text(), "Check for appending of element" ); + + reset(); + expected = "This link has class=\"blog\": Simon Willison's WeblogTry them out:Yahoo"; + old = jQuery("#sap").html(); + + jQuery('#sap').append(function(i, val){ + equals( val, old, "Make sure the incoming value is correct." ); + return [document.getElementById('first'), document.getElementById('yahoo')]; + }); + equals( expected, jQuery('#sap').text(), "Check for appending of array of elements" ); + + reset(); + expected = "This link has class=\"blog\": Simon Willison's WeblogYahooTry them out:"; + old = jQuery("#sap").html(); + + jQuery('#sap').append(function(i, val){ + equals( val, old, "Make sure the incoming value is correct." ); + return jQuery("#first, #yahoo"); + }); + equals( expected, jQuery('#sap').text(), "Check for appending of jQuery object" ); + + reset(); + old = jQuery("#sap").html(); + + jQuery("#sap").append(function(i, val){ + equals( val, old, "Make sure the incoming value is correct." ); + return 5; + }); + ok( jQuery("#sap")[0].innerHTML.match( /5$/ ), "Check for appending a number" ); + + reset(); +}); test("appendTo(String|Element|Array<Element>|jQuery)", function() { expect(12); @@ -362,7 +423,7 @@ var testPrepend = function(val) { expected = "YahooTry them out:This link has class=\"blog\": Simon Willison's Weblog"; jQuery('#sap').prepend(val( jQuery("#first, #yahoo") )); equals( expected, jQuery('#sap').text(), "Check for prepending of jQuery object" ); -} +}; test("prepend(String|Element|Array<Element>|jQuery)", function() { testPrepend(bareObj); @@ -370,7 +431,58 @@ test("prepend(String|Element|Array<Element>|jQuery)", function() { test("prepend(Function)", function() { testPrepend(functionReturningObj); -}) +}); + +test("prepend(Function) with incoming value", function() { + expect(10); + + var defaultText = 'Try them out:', old = jQuery('#first').html(); + var result = jQuery('#first').prepend(function(i, val) { + equals( val, old, "Make sure the incoming value is correct." ); + return 'buga'; + }); + equals( result.text(), 'buga' + defaultText, 'Check if text prepending works' ); + + old = jQuery("#select3").html(); + + equals( jQuery('#select3').prepend(function(i, val) { + equals( val, old, "Make sure the incoming value is correct." ); + return ''; + }).find('option:first-child').attr('value'), 'prependTest', 'Prepending html options to select element'); + + reset(); + var expected = "Try them out:This link has class=\"blog\": Simon Willison's Weblog"; + old = jQuery('#sap').html(); + + jQuery('#sap').prepend(function(i, val) { + equals( val, old, "Make sure the incoming value is correct." ); + return document.getElementById('first'); + }); + + equals( expected, jQuery('#sap').text(), "Check for prepending of element" ); + + reset(); + expected = "Try them out:YahooThis link has class=\"blog\": Simon Willison's Weblog"; + old = jQuery('#sap').html(); + + jQuery('#sap').prepend(function(i, val) { + equals( val, old, "Make sure the incoming value is correct." ); + return [document.getElementById('first'), document.getElementById('yahoo')]; + }); + + equals( expected, jQuery('#sap').text(), "Check for prepending of array of elements" ); + + reset(); + expected = "YahooTry them out:This link has class=\"blog\": Simon Willison's Weblog"; + old = jQuery('#sap').html(); + + jQuery('#sap').prepend(function(i, val) { + equals( val, old, "Make sure the incoming value is correct." ); + return jQuery("#first, #yahoo"); + }); + + equals( expected, jQuery('#sap').text(), "Check for prepending of jQuery object" ); +}); test("prependTo(String|Element|Array<Element>|jQuery)", function() { expect(6); @@ -714,6 +826,66 @@ test("html(Function)", function() { testHtml(functionReturningObj); }); +test("html(Function) with incoming value", function() { + expect(20); + + var div = jQuery("#main > div"), old = div.map(function(){ return jQuery(this).html() }); + + div.html(function(i, val) { + equals( val, old[i], "Make sure the incoming value is correct." ); + return "test"; + }); + + var pass = true; + div.each(function(){ + if ( this.childNodes.length !== 1 ) { + pass = false; + } + }) + ok( pass, "Set HTML" ); + + reset(); + // using contents will get comments regular, text, and comment nodes + var j = jQuery("#nonnodes").contents(); + old = j.map(function(){ return jQuery(this).html(); }); + + j.html(function(i, val) { + equals( val, old[i], "Make sure the incoming value is correct." ); + return "bold"; + }); + + j.find('b').removeData(); + equals( j.html().replace(/ xmlns="[^"]+"/g, "").toLowerCase(), "bold", "Check node,textnode,comment with html()" ); + + var $div = jQuery('
'); + + equals( $div.html(function(i, val) { + equals( val, "", "Make sure the incoming value is correct." ); + return 5; + }).html(), '5', 'Setting a number as html' ); + + equals( $div.html(function(i, val) { + equals( val, "5", "Make sure the incoming value is correct." ); + return 0; + }).html(), '0', 'Setting a zero as html' ); + + var $div2 = jQuery('
'), insert = "<div>hello1</div>"; + equals( $div2.html(function(i, val) { + equals( val, "", "Make sure the incoming value is correct." ); + return insert; + }).html(), insert, "Verify escaped insertion." ); + + equals( $div2.html(function(i, val) { + equals( val, insert, "Make sure the incoming value is correct." ); + return "x" + insert; + }).html(), "x" + insert, "Verify escaped insertion." ); + + equals( $div2.html(function(i, val) { + equals( val, "x" + insert, "Make sure the incoming value is correct." ); + return " " + insert; + }).html(), " " + insert, "Verify escaped insertion." ); +}); + var testRemove = function(method) { expect(9); From 0bb4fd0af72846467a4c86a47f9cfa72874c21ae Mon Sep 17 00:00:00 2001 From: jeresig Date: Thu, 7 Jan 2010 13:44:53 -0500 Subject: [PATCH 11/14] No need for the try/finally logic in the css tests, won't even work as expected. --- test/unit/css.js | 92 ++++++++++++++++++++++-------------------------- 1 file changed, 43 insertions(+), 49 deletions(-) diff --git a/test/unit/css.js b/test/unit/css.js index 116312e3..efcb913d 100644 --- a/test/unit/css.js +++ b/test/unit/css.js @@ -120,69 +120,63 @@ if(jQuery.browser.msie) { } test("css(String, Function)", function() { - try { - expect(3); + expect(3); - var sizes = ["10px", "20px", "30px"]; + var sizes = ["10px", "20px", "30px"]; - jQuery("
" + - "
" + - "
") - .appendTo("body"); + jQuery("
" + + "
" + + "
") + .appendTo("body"); - var index = 0; + var index = 0; - jQuery("#cssFunctionTest div").css("font-size", function() { - var size = sizes[index]; - index++; - return size; - }); + jQuery("#cssFunctionTest div").css("font-size", function() { + var size = sizes[index]; + index++; + return size; + }); - index = 0; - - jQuery("#cssFunctionTest div").each(function() { - var computedSize = jQuery(this).css("font-size") - var expectedSize = sizes[index] - equals( computedSize, expectedSize, "Div #" + index + " should be " + expectedSize ); - index++; - }); - - } finally { - jQuery("#cssFunctionTest").remove(); - } + index = 0; + + jQuery("#cssFunctionTest div").each(function() { + var computedSize = jQuery(this).css("font-size") + var expectedSize = sizes[index] + equals( computedSize, expectedSize, "Div #" + index + " should be " + expectedSize ); + index++; + }); + + jQuery("#cssFunctionTest").remove(); }); test("css(Object) where values are Functions", function() { - try { - expect(3); + expect(3); - var sizes = ["10px", "20px", "30px"]; + var sizes = ["10px", "20px", "30px"]; - jQuery("
" + - "
" + - "
") - .appendTo("body"); + jQuery("
" + + "
" + + "
") + .appendTo("body"); + + var index = 0; - var index = 0; - - jQuery("#cssFunctionTest div").css({fontSize: function() { - var size = sizes[index]; - index++; - return size; - }}); + jQuery("#cssFunctionTest div").css({fontSize: function() { + var size = sizes[index]; + index++; + return size; + }}); - index = 0; + index = 0; - jQuery("#cssFunctionTest div").each(function() { - var computedSize = jQuery(this).css("font-size") - var expectedSize = sizes[index] - equals( computedSize, expectedSize, "Div #" + index + " should be " + expectedSize ); - index++; - }); + jQuery("#cssFunctionTest div").each(function() { + var computedSize = jQuery(this).css("font-size") + var expectedSize = sizes[index] + equals( computedSize, expectedSize, "Div #" + index + " should be " + expectedSize ); + index++; + }); - } finally { - jQuery("#cssFunctionTest").remove(); - } + jQuery("#cssFunctionTest").remove(); }); test("jQuery.css(elem, 'height') doesn't clear radio buttons (bug #1095)", function () { From ebaf374f2ac02e224ff0d0775b9709579404dd58 Mon Sep 17 00:00:00 2001 From: jeresig Date: Thu, 7 Jan 2010 13:52:20 -0500 Subject: [PATCH 12/14] Add .css(Function) incoming value tests. --- test/unit/css.js | 60 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/test/unit/css.js b/test/unit/css.js index efcb913d..5f8a74ae 100644 --- a/test/unit/css.js +++ b/test/unit/css.js @@ -149,6 +149,36 @@ test("css(String, Function)", function() { jQuery("#cssFunctionTest").remove(); }); +test("css(String, Function) with incoming value", function() { + expect(3); + + var sizes = ["10px", "20px", "30px"]; + + jQuery("
" + + "
" + + "
") + .appendTo("body"); + + var index = 0; + + jQuery("#cssFunctionTest div").css("font-size", function() { + var size = sizes[index]; + index++; + return size; + }); + + index = 0; + + jQuery("#cssFunctionTest div").css("font-size", function(i, computedSize) { + var expectedSize = sizes[index] + equals( computedSize, expectedSize, "Div #" + index + " should be " + expectedSize ); + index++; + return computedSize; + }); + + jQuery("#cssFunctionTest").remove(); +}); + test("css(Object) where values are Functions", function() { expect(3); @@ -179,6 +209,36 @@ test("css(Object) where values are Functions", function() { jQuery("#cssFunctionTest").remove(); }); +test("css(Object) where values are Functions with incoming values", function() { + expect(3); + + var sizes = ["10px", "20px", "30px"]; + + jQuery("
" + + "
" + + "
") + .appendTo("body"); + + var index = 0; + + jQuery("#cssFunctionTest div").css({fontSize: function() { + var size = sizes[index]; + index++; + return size; + }}); + + index = 0; + + jQuery("#cssFunctionTest div").css({"font-size": function(i, computedSize) { + var expectedSize = sizes[index] + equals( computedSize, expectedSize, "Div #" + index + " should be " + expectedSize ); + index++; + return computedSize; + }}); + + jQuery("#cssFunctionTest").remove(); +}); + test("jQuery.css(elem, 'height') doesn't clear radio buttons (bug #1095)", function () { expect(4); From 4fa00369f00b8ee708c8962135b7aa345e3d30d0 Mon Sep 17 00:00:00 2001 From: jeresig Date: Thu, 7 Jan 2010 14:07:21 -0500 Subject: [PATCH 13/14] Added in support for .offset(Function). --- src/offset.js | 25 +++++++++++++++---------- test/unit/offset.js | 39 +++++++++++++++++++++++---------------- 2 files changed, 38 insertions(+), 26 deletions(-) diff --git a/src/offset.js b/src/offset.js index d12921df..7dd71343 100644 --- a/src/offset.js +++ b/src/offset.js @@ -7,8 +7,8 @@ if ( "getBoundingClientRect" in document.documentElement ) { } if ( options ) { - return this.each(function() { - jQuery.offset.setOffset( this, options ); + return this.each(function( i ) { + jQuery.offset.setOffset( this, i, options ); }); } @@ -33,8 +33,8 @@ if ( "getBoundingClientRect" in document.documentElement ) { } if ( options ) { - return this.each(function() { - jQuery.offset.setOffset( this, options ); + return this.each(function( i ) { + jQuery.offset.setOffset( this, i, options ); }); } @@ -137,7 +137,7 @@ jQuery.offset = { return { top: top, left: left }; }, - setOffset: function( elem, options ) { + setOffset: function( elem, i, options ) { // set position first, in-case top/left are set even on static elem if ( /static/.test( jQuery.curCSS( elem, "position" ) ) ) { elem.style.position = "relative"; @@ -145,11 +145,16 @@ jQuery.offset = { var curElem = jQuery( elem ), curOffset = curElem.offset(), curTop = parseInt( jQuery.curCSS( elem, "top", true ), 10 ) || 0, - curLeft = parseInt( jQuery.curCSS( elem, "left", true ), 10) || 0, - props = { - top: (options.top - curOffset.top) + curTop, - left: (options.left - curOffset.left) + curLeft - }; + curLeft = parseInt( jQuery.curCSS( elem, "left", true ), 10 ) || 0; + + if ( jQuery.isFunction( options ) ) { + options = options.call( elem, i, curOffset ); + } + + var props = { + top: (options.top - curOffset.top) + curTop, + left: (options.left - curOffset.left) + curLeft + }; if ( "using" in options ) { options.using.call( elem, props ); diff --git a/test/unit/offset.js b/test/unit/offset.js index 602f5e6a..dc03bc2e 100644 --- a/test/unit/offset.js +++ b/test/unit/offset.js @@ -1,6 +1,8 @@ module("offset"); testoffset("absolute", function( jQuery ) { + expect(144); + // get offset tests var tests = [ { id: '#absolute-1', top: 1, left: 1 }, @@ -51,6 +53,16 @@ testoffset("absolute", function( jQuery ) { equals( jQuery( this.id ).offset().top, this.top, "jQuery('" + this.id + "').offset({ top: " + this.top + " })" ); equals( jQuery( this.id ).offset().left, this.left, "jQuery('" + this.id + "').offset({ left: " + this.left + " })" ); + var top = this.top, left = this.left; + + jQuery( this.id ).offset(function(i, val){ + equals( val.top, top, "Verify incoming top position." ); + equals( val.left, left, "Verify incoming top position." ); + return { top: top + 1, left: left + 1 }; + }); + equals( jQuery( this.id ).offset().top, this.top + 1, "jQuery('" + this.id + "').offset({ top: " + this.top + " })" ); + equals( jQuery( this.id ).offset().left, this.left + 1, "jQuery('" + this.id + "').offset({ left: " + this.left + " })" ); + jQuery( this.id ).offset({ top: this.top, left: this.left, using: function( props ) { jQuery( this ).css({ top: props.top + 1, @@ -63,6 +75,8 @@ testoffset("absolute", function( jQuery ) { }); testoffset("relative", function( jQuery ) { + expect(60); + // IE is collapsing the top margin of 1px var ie = jQuery.browser.msie && parseInt( jQuery.browser.version ) < 8; @@ -122,6 +136,8 @@ testoffset("relative", function( jQuery ) { }); testoffset("static", function( jQuery ) { + expect(80); + // IE is collapsing the top margin of 1px var ie = jQuery.browser.msie && parseInt( jQuery.browser.version ) < 8; @@ -187,6 +203,8 @@ testoffset("static", function( jQuery ) { }); testoffset("fixed", function( jQuery ) { + expect(28); + jQuery.offset.initialize(); var tests = [ @@ -238,31 +256,18 @@ testoffset("fixed", function( jQuery ) { }); testoffset("table", function( jQuery ) { - var ie = jQuery.browser.msie; + expect(4); equals( jQuery('#table-1').offset().top, 6, "jQuery('#table-1').offset().top" ); equals( jQuery('#table-1').offset().left, 6, "jQuery('#table-1').offset().left" ); equals( jQuery('#th-1').offset().top, 10, "jQuery('#th-1').offset().top" ); equals( jQuery('#th-1').offset().left, 10, "jQuery('#th-1').offset().left" ); - - // equals( jQuery('#th-2').offset().top, 10, "jQuery('#th-2').offset().top" ); - // equals( jQuery('#th-2').offset().left, 116, "jQuery('#th-2').offset().left" ); - // - // equals( jQuery('#th-3').offset().top, 10, "jQuery('#th-3').offset().top" ); - // equals( jQuery('#th-3').offset().left, 222, "jQuery('#th-3').offset().left" ); - - // equals( jQuery('#td-1').offset().top, ie ? 116 : 112, "jQuery('#td-1').offset().top" ); - // equals( jQuery('#td-1').offset().left, 10, "jQuery('#td-1').offset().left" ); - // - // equals( jQuery('#td-2').offset().top, ie ? 116 : 112, "jQuery('#td-2').offset().top" ); - // equals( jQuery('#td-2').offset().left, 116, "jQuery('#td-2').offset().left" ); - // - // equals( jQuery('#td-3').offset().top, ie ? 116 : 112, "jQuery('#td-3').offset().top" ); - // equals( jQuery('#td-3').offset().left, 222, "jQuery('#td-3').offset().left" ); }); testoffset("scroll", function( jQuery, win ) { + expect(12); + var ie = jQuery.browser.msie && parseInt( jQuery.browser.version ) < 8; // IE is collapsing the top margin of 1px @@ -294,6 +299,8 @@ testoffset("scroll", function( jQuery, win ) { }); testoffset("body", function( jQuery ) { + expect(2); + equals( jQuery('body').offset().top, 1, "jQuery('#body').offset().top" ); equals( jQuery('body').offset().left, 1, "jQuery('#body').offset().left" ); }); From 0e5370b89c0dfe56bf2f02fdd34fd820ecd48254 Mon Sep 17 00:00:00 2001 From: jeresig Date: Thu, 7 Jan 2010 14:08:32 -0500 Subject: [PATCH 14/14] Re-ordering the args to setOffset() in case people were relying upon the old order (doubtful). --- src/offset.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/offset.js b/src/offset.js index 7dd71343..c3183743 100644 --- a/src/offset.js +++ b/src/offset.js @@ -8,7 +8,7 @@ if ( "getBoundingClientRect" in document.documentElement ) { if ( options ) { return this.each(function( i ) { - jQuery.offset.setOffset( this, i, options ); + jQuery.offset.setOffset( this, options, i ); }); } @@ -34,7 +34,7 @@ if ( "getBoundingClientRect" in document.documentElement ) { if ( options ) { return this.each(function( i ) { - jQuery.offset.setOffset( this, i, options ); + jQuery.offset.setOffset( this, options, i ); }); } @@ -137,7 +137,7 @@ jQuery.offset = { return { top: top, left: left }; }, - setOffset: function( elem, i, options ) { + setOffset: function( elem, options, i ) { // set position first, in-case top/left are set even on static elem if ( /static/.test( jQuery.curCSS( elem, "position" ) ) ) { elem.style.position = "relative";