From: Yehuda Katz Date: Sun, 12 Jul 2009 20:19:43 +0000 (+0000) Subject: Support for .foo(Function) and testing. TODO: More tests X-Git-Url: http://git.asbjorn.biz/?p=jquery.git;a=commitdiff_plain;h=7d7a960035b7431887581c9cef09eaaef28e3d27 Support for .foo(Function) and testing. TODO: More tests --- diff --git a/src/attributes.js b/src/attributes.js index f7fb0a2..9e66df0 100644 --- a/src/attributes.js +++ b/src/attributes.js @@ -82,19 +82,29 @@ jQuery.fn.extend({ return undefined; } + // Typecast once if the value is a number if ( typeof value === "number" ) value += ''; + + var val = value; return this.each(function(){ + if(jQuery.isFunction(value)) { + val = value.call(this); + // Typecast each time if the value is a Function and the appended + // value is therefore different each time. + if( typeof val === "number" ) val += ''; + } + if ( this.nodeType != 1 ) return; - if ( jQuery.isArray(value) && /radio|checkbox/.test( this.type ) ) - this.checked = (jQuery.inArray(this.value, value) >= 0 || - jQuery.inArray(this.name, value) >= 0); + if ( jQuery.isArray(val) && /radio|checkbox/.test( this.type ) ) + this.checked = (jQuery.inArray(this.value, val) >= 0 || + jQuery.inArray(this.name, val) >= 0); else if ( jQuery.nodeName( this, "select" ) ) { - var values = jQuery.makeArray(value); + var values = jQuery.makeArray(val); jQuery( "option", this ).each(function(){ this.selected = (jQuery.inArray( this.value, values ) >= 0 || @@ -105,7 +115,7 @@ jQuery.fn.extend({ this.selectedIndex = -1; } else - this.value = value; + this.value = val; }); } }); diff --git a/src/manipulation.js b/src/manipulation.js index 233cb82..59973de 100644 --- a/src/manipulation.js +++ b/src/manipulation.js @@ -138,6 +138,14 @@ jQuery.fn.extend({ domManip: function( args, table, callback ) { var fragment, scripts, cacheable, cached, cacheresults, first; + var value = args[0]; + + if ( jQuery.isFunction(value) ) { + return this.each(function() { + args[0] = value.call(this); + return jQuery(this).domManip( args, table, callback ); + }); + }; if ( this[0] ) { if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && args[0].indexOf("
'); @@ -72,52 +75,60 @@ test("wrapInner(String|Element)", function() { var result = jQuery('#first').wrapInner(document.getElementById('empty')); equals( jQuery("#first").children().length, 1, "Only one child" ); ok( jQuery("#first").children().is("#empty"), "Verify Right Element" ); - equals( jQuery("#first").children().children().length, num, "Verify Elements Intact" ); + equals( jQuery("#first").children().children().length, num, "Verify Elements Intact" ); +} + +test("wrapInner(String|Element)", function() { + testWrapInner(bareObj); }); -test("append(String|Element|Array<Element>|jQuery)", function() { +/* test("wrapInner(Function)", function() { + testWrapInner(functionReturningObj) +}) */ + +var testAppend = function(valueObj) { expect(21); var defaultText = 'Try them out:' - var result = jQuery('#first').append('buga'); + var result = jQuery('#first').append(valueObj('buga')); equals( result.text(), defaultText + 'buga', 'Check if text appending works' ); - equals( jQuery('#select3').append('').find('option:last-child').attr('value'), 'appendTest', 'Appending html options to select element'); + equals( jQuery('#select3').append(valueObj('')).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:"; - jQuery('#sap').append(document.getElementById('first')); + jQuery('#sap').append(valueObj(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"; - jQuery('#sap').append([document.getElementById('first'), document.getElementById('yahoo')]); + jQuery('#sap').append(valueObj([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:"; - jQuery('#sap').append(jQuery("#first, #yahoo")); + jQuery('#sap').append(valueObj(jQuery("#first, #yahoo"))); equals( expected, jQuery('#sap').text(), "Check for appending of jQuery object" ); reset(); - jQuery("#sap").append( 5 ); + jQuery("#sap").append(valueObj( 5 )); ok( jQuery("#sap")[0].innerHTML.match( /5$/ ), "Check for appending a number" ); reset(); - jQuery("#sap").append( " text with spaces " ); + jQuery("#sap").append(valueObj( " text with spaces " )); ok( jQuery("#sap")[0].innerHTML.match(/ text with spaces $/), "Check for appending text with spaces" ); reset(); - ok( jQuery("#sap").append([]), "Check for appending an empty array." ); - ok( jQuery("#sap").append(""), "Check for appending an empty string." ); - ok( jQuery("#sap").append(document.getElementsByTagName("foo")), "Check for appending an empty nodelist." ); + ok( jQuery("#sap").append(valueObj( [] )), "Check for appending an empty array." ); + ok( jQuery("#sap").append(valueObj( "" )), "Check for appending an empty string." ); + ok( jQuery("#sap").append(valueObj( document.getElementsByTagName("foo") )), "Check for appending an empty nodelist." ); reset(); - jQuery("#sap").append(document.getElementById('form')); + jQuery("#sap").append(valueObj( document.getElementById('form') )); equals( jQuery("#sap>form").size(), 1, "Check for appending a form" ); // Bug #910 reset(); var pass = true; try { - jQuery( jQuery("#iframe")[0].contentWindow.document.body ).append("
test
"); + jQuery( jQuery("#iframe")[0].contentWindow.document.body ).append(valueObj( "
test
" )); } catch(e) { pass = false; } @@ -125,27 +136,27 @@ test("append(String|Element|Array<Element>|jQuery)", function() { ok( pass, "Test for appending a DOM node to the contents of an IFrame" ); reset(); - jQuery('
').appendTo('#form').append('test'); + jQuery('
').appendTo('#form').append(valueObj( 'test' )); t( 'Append legend', '#legend', ['legend'] ); reset(); - jQuery('#select1').append(''); + jQuery('#select1').append(valueObj( '' )); equals( jQuery('#select1 option:last').text(), "Test", "Appending <OPTION> (all caps)" ); - jQuery('#table').append(''); + jQuery('#table').append(valueObj( '' )); ok( jQuery('#table colgroup').length, "Append colgroup" ); - jQuery('#table colgroup').append(''); + jQuery('#table colgroup').append(valueObj( '' )); ok( jQuery('#table colgroup col').length, "Append col" ); reset(); - jQuery('#table').append(''); + jQuery('#table').append(valueObj( '' )); ok( jQuery('#table caption').length, "Append caption" ); reset(); jQuery('form:last') - .append('') - .append(''); + .append(valueObj( '' )) + .append(valueObj( '' )); t( "Append Select", "#appendSelect1, #appendSelect2", ["appendSelect1", "appendSelect2"] ); @@ -157,8 +168,16 @@ test("append(String|Element|Array<Element>|jQuery)", function() { d.contents().appendTo("#nonnodes"); d.remove(); ok( jQuery("#nonnodes").contents().length >= 2, "Check node,textnode,comment append cleanup worked" ); +} + +test("append(String|Element|Array<Element>|jQuery)", function() { + testAppend(bareObj); }); +test("append(Function)", function() { + testAppend(functionReturningObj); +}) + test("appendTo(String|Element|Array<Element>|jQuery)", function() { expect(12); var defaultText = 'Try them out:' @@ -210,29 +229,37 @@ test("appendTo(String|Element|Array<Element>|jQuery)", function() { reset(); }); -test("prepend(String|Element|Array<Element>|jQuery)", function() { +var testPrepend = function(val) { expect(5); var defaultText = 'Try them out:' - var result = jQuery('#first').prepend('buga'); + var result = jQuery('#first').prepend(val( 'buga' )); equals( result.text(), 'buga' + defaultText, 'Check if text prepending works' ); - equals( jQuery('#select3').prepend('').find('option:first-child').attr('value'), 'prependTest', 'Prepending html options to select element'); + equals( jQuery('#select3').prepend(val( '' )).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"; - jQuery('#sap').prepend(document.getElementById('first')); + jQuery('#sap').prepend(val( 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"; - jQuery('#sap').prepend([document.getElementById('first'), document.getElementById('yahoo')]); + jQuery('#sap').prepend(val( [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"; - jQuery('#sap').prepend(jQuery("#first, #yahoo")); + 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); }); +test("prepend(Function)", function() { + testPrepend(functionReturningObj); +}) + test("prependTo(String|Element|Array<Element>|jQuery)", function() { expect(6); var defaultText = 'Try them out:' @@ -262,28 +289,36 @@ test("prependTo(String|Element|Array<Element>|jQuery)", function() { t( "Prepend Select", "#prependSelect2, #prependSelect1", ["prependSelect2", "prependSelect1"] ); }); -test("before(String|Element|Array<Element>|jQuery)", function() { +var testBefore = function(val) { expect(4); var expected = 'This is a normal link: bugaYahoo'; - jQuery('#yahoo').before('buga'); + jQuery('#yahoo').before(val( 'buga' )); equals( expected, jQuery('#en').text(), 'Insert String before' ); reset(); expected = "This is a normal link: Try them out:Yahoo"; - jQuery('#yahoo').before(document.getElementById('first')); + jQuery('#yahoo').before(val( document.getElementById('first') )); equals( expected, jQuery('#en').text(), "Insert element before" ); reset(); expected = "This is a normal link: Try them out:diveintomarkYahoo"; - jQuery('#yahoo').before([document.getElementById('first'), document.getElementById('mark')]); + jQuery('#yahoo').before(val( [document.getElementById('first'), document.getElementById('mark')] )); equals( expected, jQuery('#en').text(), "Insert array of elements before" ); reset(); expected = "This is a normal link: diveintomarkTry them out:Yahoo"; - jQuery('#yahoo').before(jQuery("#first, #mark")); + jQuery('#yahoo').before(val( jQuery("#first, #mark") )); equals( expected, jQuery('#en').text(), "Insert jQuery before" ); +} + +test("before(String|Element|Array<Element>|jQuery)", function() { + testBefore(bareObj); }); +test("before(Function)", function() { + testBefore(functionReturningObj); +}) + test("insertBefore(String|Element|Array<Element>|jQuery)", function() { expect(4); var expected = 'This is a normal link: bugaYahoo'; @@ -306,28 +341,36 @@ test("insertBefore(String|Element|Array<Element>|jQuery)", function() { equals( expected, jQuery('#en').text(), "Insert jQuery before" ); }); -test("after(String|Element|Array<Element>|jQuery)", function() { +var testAfter = function(val) { expect(4); var expected = 'This is a normal link: Yahoobuga'; - jQuery('#yahoo').after('buga'); + jQuery('#yahoo').after(val( 'buga' )); equals( expected, jQuery('#en').text(), 'Insert String after' ); reset(); expected = "This is a normal link: YahooTry them out:"; - jQuery('#yahoo').after(document.getElementById('first')); + jQuery('#yahoo').after(val( document.getElementById('first') )); equals( expected, jQuery('#en').text(), "Insert element after" ); reset(); expected = "This is a normal link: YahooTry them out:diveintomark"; - jQuery('#yahoo').after([document.getElementById('first'), document.getElementById('mark')]); + jQuery('#yahoo').after(val( [document.getElementById('first'), document.getElementById('mark')] )); equals( expected, jQuery('#en').text(), "Insert array of elements after" ); reset(); expected = "This is a normal link: YahoodiveintomarkTry them out:"; - jQuery('#yahoo').after(jQuery("#first, #mark")); - equals( expected, jQuery('#en').text(), "Insert jQuery after" ); + jQuery('#yahoo').after(val( jQuery("#first, #mark") )); + equals( expected, jQuery('#en').text(), "Insert jQuery after" ); +}; + +test("after(String|Element|Array<Element>|jQuery)", function() { + testAfter(bareObj); }); +test("after(Function)", function() { + testAfter(functionReturningObj); +}) + test("insertAfter(String|Element|Array<Element>|jQuery)", function() { expect(4); var expected = 'This is a normal link: Yahoobuga'; @@ -379,7 +422,7 @@ test("replaceAll(String|Element|Array<Element>|jQuery)", function() { jQuery('buga').replaceAll("#yahoo"); ok( jQuery("#replace")[0], 'Replace element with string' ); ok( !jQuery("#yahoo")[0], 'Verify that original element is gone, after string' ); - + reset(); jQuery(document.getElementById('first')).replaceAll("#yahoo"); ok( jQuery("#first")[0], 'Replace element with element' ); @@ -464,7 +507,12 @@ test("clone() on XML nodes", function() { } test("val()", function() { - expect(8); + expect(9); + + 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 @@ -483,77 +531,95 @@ test("val()", function() { }); -test("val(String/Number)", function() { - expect(6); - document.getElementById('text1').value = "bla"; - equals( jQuery("#text1").val(), "bla", "Check for modified value of input element" ); - - jQuery("#text1").val('test'); +var testVal = function(valueObj) { + expect(5); + + jQuery("#text1").val(valueObj( 'test' )); equals( document.getElementById('text1').value, "test", "Check for modified (via val(String)) value of input element" ); - jQuery("#text1").val(67); + jQuery("#text1").val(valueObj( 67 )); equals( document.getElementById('text1').value, "67", "Check for modified (via val(Number)) value of input element" ); - jQuery("#select1").val("3"); + jQuery("#select1").val(valueObj( "3" )); equals( jQuery("#select1").val(), "3", "Check for modified (via val(String)) value of select element" ); - jQuery("#select1").val(2); + jQuery("#select1").val(valueObj( 2 )); equals( jQuery("#select1").val(), "2", "Check for modified (via val(Number)) value of select element" ); // using contents will get comments regular, text, and comment nodes var j = jQuery("#nonnodes").contents(); - j.val("asdf"); + 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("html(String)", function() { +test("val(Function)", function() { + testVal(functionReturningObj); +}) + +var testHtml = function(valueObj) { expect(17); + window.debug = true; + jQuery.scriptorder = 0; var div = jQuery("#main > div"); - div.html("test"); + div.html(valueObj("test")); var pass = true; for ( var i = 0; i < div.size(); i++ ) { if ( div.get(i).childNodes.length != 1 ) pass = false; } ok( pass, "Set HTML" ); + + window.debug = false; reset(); // using contents will get comments regular, text, and comment nodes var j = jQuery("#nonnodes").contents(); - j.html("bold"); - + j.html(valueObj("bold")); + // this is needed, or the expando added by jQuery unique will yield a different html j.find('b').removeData(); equals( j.html().replace(/ xmlns="[^"]+"/g, "").toLowerCase(), "bold", "Check node,textnode,comment with html()" ); - - jQuery("#main").html("")); + jQuery("#main select").html(valueObj("")); equals( jQuery("#main select").val(), "O2", "Selected option correct" ); - + var $div = jQuery('
'); - equals( $div.html( 5 ).html(), '5', 'Setting a number as html' ); - equals( $div.html( 0 ).html(), '0', 'Setting a zero as html' ); - + equals( $div.html(valueObj( 5 )).html(), '5', 'Setting a number as html' ); + equals( $div.html(valueObj( 0 )).html(), '0', 'Setting a zero as html' ); + reset(); - - jQuery("#main").html('
'); - + + jQuery("#main").html(valueObj('
')); + stop(); - - jQuery("#main").html(''); - - jQuery("#main").html('foo
'); - + + jQuery("#main").html(valueObj('')); + + jQuery("#main").html(valueObj('foo
')); + // it was decided that waiting to execute ALL scripts makes sense since nested ones have to wait anyway so this test case is changed, see #1959 - jQuery("#main").html("