diff options
-rw-r--r-- | Gruntfile.js | 1 | ||||
-rw-r--r-- | README.md | 1 | ||||
-rw-r--r-- | src/manipulation.js | 65 | ||||
-rw-r--r-- | src/wrap.js | 66 | ||||
-rw-r--r-- | test/index.html | 1 | ||||
-rw-r--r-- | test/unit/core.js | 5 | ||||
-rw-r--r-- | test/unit/css.js | 2 | ||||
-rw-r--r-- | test/unit/deprecated.js | 9 | ||||
-rw-r--r-- | test/unit/manipulation.js | 249 | ||||
-rw-r--r-- | test/unit/traversing.js | 30 | ||||
-rw-r--r-- | test/unit/wrap.js | 265 |
11 files changed, 362 insertions, 332 deletions
diff --git a/Gruntfile.js b/Gruntfile.js index 24e30d2d3..27786474e 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -56,6 +56,7 @@ module.exports = function( grunt ) { "src/event.js", "src/traversing.js", "src/manipulation.js", + { flag: "wrap", src: "src/wrap.js" }, { flag: "css", src: "src/css.js" }, "src/serialize.js", { flag: "event-alias", src: "src/event-alias.js" }, @@ -84,6 +84,7 @@ For example, an app that only used JSONP for `$.ajax()` and did not need to calc - **effects**: The `.animate()` method and its shorthands such as `.slideUp()` or `.hide("slow")`. - **event-alias**: All event attaching/triggering shorthands like `.click()` or `.mouseover()`. - **offset**: The `.offset()`, `.position()`, `.offsetParent()`, `.scrollLeft()`, and `.scrollTop()` methods. +- **wrap**: The `.wrap()`, `.wrapAll()`, `.wrapInner()`, and `.unwrap()` methods. The grunt build process is aware of dependencies across modules. If you explicitly remove a module, its dependent modules will be removed as well. For example, excluding the css module also excludes effects, since the effects module uses `.css()` to animate CSS properties. These dependencies are listed in Gruntfile.js and the build process shows a message for each dependent module it excludes. diff --git a/src/manipulation.js b/src/manipulation.js index 938fb0c3a..585d261e5 100644 --- a/src/manipulation.js +++ b/src/manipulation.js @@ -60,71 +60,6 @@ jQuery.fn.extend({ }, null, value, arguments.length ); }, - wrapAll: function( html ) { - if ( jQuery.isFunction( html ) ) { - return this.each(function(i) { - jQuery(this).wrapAll( html.call(this, i) ); - }); - } - - if ( this[0] ) { - // The elements to wrap the target around - var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true); - - if ( this[0].parentNode ) { - wrap.insertBefore( this[0] ); - } - - wrap.map(function() { - var elem = this; - - while ( elem.firstChild && elem.firstChild.nodeType === 1 ) { - elem = elem.firstChild; - } - - return elem; - }).append( this ); - } - - return this; - }, - - wrapInner: function( html ) { - if ( jQuery.isFunction( html ) ) { - return this.each(function(i) { - jQuery(this).wrapInner( html.call(this, i) ); - }); - } - - return this.each(function() { - var self = jQuery( this ), - contents = self.contents(); - - if ( contents.length ) { - contents.wrapAll( html ); - - } else { - self.append( html ); - } - }); - }, - - wrap: function( html ) { - var isFunction = jQuery.isFunction( html ); - - return this.each(function(i) { - jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html ); - }); - }, - - unwrap: function() { - return this.parent().each(function() { - if ( !jQuery.nodeName( this, "body" ) ) { - jQuery( this ).replaceWith( this.childNodes ); - } - }).end(); - }, - append: function() { return this.domManip( arguments, function( elem ) { if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { diff --git a/src/wrap.js b/src/wrap.js new file mode 100644 index 000000000..6ff84c8b6 --- /dev/null +++ b/src/wrap.js @@ -0,0 +1,66 @@ +jQuery.fn.extend({ + wrapAll: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function(i) { + jQuery(this).wrapAll( html.call(this, i) ); + }); + } + + if ( this[0] ) { + // The elements to wrap the target around + var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true); + + if ( this[0].parentNode ) { + wrap.insertBefore( this[0] ); + } + + wrap.map(function() { + var elem = this; + + while ( elem.firstChild && elem.firstChild.nodeType === 1 ) { + elem = elem.firstChild; + } + + return elem; + }).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function(i) { + jQuery(this).wrapInner( html.call(this, i) ); + }); + } + + return this.each(function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + }); + }, + + wrap: function( html ) { + var isFunction = jQuery.isFunction( html ); + + return this.each(function(i) { + jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html ); + }); + }, + + unwrap: function() { + return this.parent().each(function() { + if ( !jQuery.nodeName( this, "body" ) ) { + jQuery( this ).replaceWith( this.childNodes ); + } + }).end(); + } +}); diff --git a/test/index.html b/test/index.html index 8633120e2..282c2e6ff 100644 --- a/test/index.html +++ b/test/index.html @@ -57,6 +57,7 @@ <script src="unit/selector.js"></script> <script src="unit/traversing.js"></script> <script src="unit/manipulation.js"></script> + <script src="unit/wrap.js"></script> <script src="unit/css.js"></script> <script src="unit/serialize.js"></script> <script src="unit/ajax.js"></script> diff --git a/test/unit/core.js b/test/unit/core.js index 415318ecb..0969c933e 100644 --- a/test/unit/core.js +++ b/test/unit/core.js @@ -680,11 +680,6 @@ test("length", function() { equal( jQuery("#qunit-fixture p").length, 6, "Get Number of Elements Found" ); }); -test("size()", function() { - expect(1); - equal( jQuery("#qunit-fixture p").size(), 6, "Get Number of Elements Found" ); -}); - test("get()", function() { expect(1); deepEqual( jQuery("#qunit-fixture p").get(), q("firstp","ap","sndp","en","sap","first"), "Get All Elements" ); diff --git a/test/unit/css.js b/test/unit/css.js index b71fd0962..f59c5e724 100644 --- a/test/unit/css.js +++ b/test/unit/css.js @@ -579,7 +579,7 @@ test( "show() resolves correct default display for detached nodes", function(){ equal( tr[ 0 ].style.display, trDisplay, "For detached tr elements, display should always be like for attached trs" ); tr.remove(); - span = span = jQuery("<span/>").hide().show(); + span = jQuery("<span/>").hide().show(); equal( span[ 0 ].style.display, "inline", "For detached span elements, display should always be inline" ); span.remove(); }); diff --git a/test/unit/deprecated.js b/test/unit/deprecated.js index 330bda200..5839ceec3 100644 --- a/test/unit/deprecated.js +++ b/test/unit/deprecated.js @@ -1 +1,8 @@ -module("deprecated"); +module("deprecated", { teardown: moduleTeardown }); + +if ( jQuery.fn.size ) { + test("size()", function() { + expect(1); + equal( jQuery("#qunit-fixture p").size(), 6, "Get Number of Elements Found" ); + }); +} diff --git a/test/unit/manipulation.js b/test/unit/manipulation.js index daa822ca7..8311ee134 100644 --- a/test/unit/manipulation.js +++ b/test/unit/manipulation.js @@ -103,222 +103,6 @@ test( "text(Function) with incoming value", function() { equal( jQuery("#sap").text(), "foobar", "Check for merged text of more then one element." ); }); -function testWrap( val ) { - - expect( 19 ); - - var defaultText, result, j, i, cacheLength; - - defaultText = "Try them out:", - result = jQuery("#first").wrap( val("<div class='red'><span></span></div>") ).text(); - - equal( defaultText, result, "Check for wrapping of on-the-fly html" ); - ok( jQuery("#first").parent().parent().is(".red"), "Check if wrapper has class 'red'" ); - - QUnit.reset(); - result = jQuery("#first").wrap( val(document.getElementById("empty")) ).parent(); - ok( result.is("ol"), "Check for element wrapping" ); - equal( result.text(), defaultText, "Check for element wrapping" ); - - QUnit.reset(); - jQuery("#check1").on( "click", function() { - var checkbox = this; - - ok( checkbox.checked, "Checkbox's state is erased after wrap() action, see #769" ); - jQuery( checkbox ).wrap( val("<div id='c1' style='display:none;'></div>") ); - ok( checkbox.checked, "Checkbox's state is erased after wrap() action, see #769" ); - }).prop( "checked", false )[ 0 ].click(); - - // using contents will get comments regular, text, and comment nodes - j = jQuery("#nonnodes").contents(); - j.wrap( val("<i></i>") ); - - // Blackberry 4.6 doesn't maintain comments in the DOM - equal( jQuery("#nonnodes > i").length, jQuery("#nonnodes")[ 0 ].childNodes.length, "Check node,textnode,comment wraps ok" ); - equal( jQuery("#nonnodes > i").text(), j.text(), "Check node,textnode,comment wraps doesn't hurt text" ); - - // Try wrapping a disconnected node - cacheLength = 0; - for ( i in jQuery.cache ) { - cacheLength++; - } - - j = jQuery("<label/>").wrap( val("<li/>") ); - equal( j[ 0 ] .nodeName.toUpperCase(), "LABEL", "Element is a label" ); - equal( j[ 0 ].parentNode.nodeName.toUpperCase(), "LI", "Element has been wrapped" ); - - for ( i in jQuery.cache ) { - cacheLength--; - } - equal( cacheLength, 0, "No memory leak in jQuery.cache (bug #7165)" ); - - // Wrap an element containing a text node - j = jQuery("<span/>").wrap("<div>test</div>"); - equal( j[ 0 ].previousSibling.nodeType, 3, "Make sure the previous node is a text element" ); - equal( j[ 0 ].parentNode.nodeName.toUpperCase(), "DIV", "And that we're in the div element." ); - - // Try to wrap an element with multiple elements (should fail) - j = jQuery("<div><span></span></div>").children().wrap("<p></p><div></div>"); - equal( j[ 0 ].parentNode.parentNode.childNodes.length, 1, "There should only be one element wrapping." ); - equal( j.length, 1, "There should only be one element (no cloning)." ); - equal( j[ 0 ].parentNode.nodeName.toUpperCase(), "P", "The span should be in the paragraph." ); - - // Wrap an element with a jQuery set - j = jQuery("<span/>").wrap( jQuery("<div></div>") ); - equal( j[ 0 ].parentNode.nodeName.toLowerCase(), "div", "Wrapping works." ); - - // Wrap an element with a jQuery set and event - result = jQuery("<div></div>").on( "click", function() { - ok( true, "Event triggered." ); - - // Remove handlers on detached elements - result.off(); - jQuery(this).off(); - }); - - j = jQuery("<span/>").wrap( result ); - equal( j[ 0 ].parentNode.nodeName.toLowerCase(), "div", "Wrapping works." ); - - j.parent().trigger("click"); - - // clean up attached elements - QUnit.reset(); -} - -test( "wrap(String|Element)", function() { - testWrap( manipulationBareObj ); -}); - -test( "wrap(Function)", function() { - testWrap( manipulationFunctionReturningObj ); -}); - -test( "wrap(Function) with index (#10177)", function() { - var expectedIndex = 0, - targets = jQuery("#qunit-fixture p"); - - expect( targets.length ); - targets.wrap(function(i) { - equal( i, expectedIndex, "Check if the provided index (" + i + ") is as expected (" + expectedIndex + ")" ); - expectedIndex++; - - return "<div id='wrap_index_'" + i + "'></div>"; - }); -}); - -test( "wrap(String) consecutive elements (#10177)", function() { - var targets = jQuery("#qunit-fixture p"); - - expect( targets.length * 2 ); - targets.wrap("<div class='wrapper'></div>"); - - targets.each(function() { - var $this = jQuery(this); - - ok( $this.parent().is(".wrapper"), "Check each elements parent is correct (.wrapper)" ); - equal( $this.siblings().length, 0, "Each element should be wrapped individually" ); - }); -}); - -function testWrapAll( val ) { - - expect( 8 ); - - var prev, p, result; - - prev = jQuery("#firstp")[ 0 ].previousSibling; - p = jQuery("#firstp,#first")[ 0 ].parentNode; - result = jQuery("#firstp,#first").wrapAll( val("<div class='red'><div class='tmp'></div></div>") ); - - equal( result.parent().length, 1, "Check for wrapping of on-the-fly html" ); - ok( jQuery("#first").parent().parent().is(".red"), "Check if wrapper has class 'red'" ); - ok( jQuery("#firstp").parent().parent().is(".red"), "Check if wrapper has class 'red'" ); - equal( jQuery("#first").parent().parent()[ 0 ].previousSibling, prev, "Correct Previous Sibling" ); - equal( jQuery("#first").parent().parent()[ 0 ].parentNode, p, "Correct Parent" ); - - QUnit.reset(); - prev = jQuery("#firstp")[ 0 ].previousSibling; - p = jQuery("#first")[ 0 ].parentNode; - result = jQuery("#firstp,#first").wrapAll( val(document.getElementById("empty")) ); - - equal( jQuery("#first").parent()[ 0 ], jQuery("#firstp").parent()[ 0 ], "Same Parent" ); - equal( jQuery("#first").parent()[ 0 ].previousSibling, prev, "Correct Previous Sibling" ); - equal( jQuery("#first").parent()[ 0 ].parentNode, p, "Correct Parent" ); -} - -test( "wrapAll(String|Element)", function() { - testWrapAll( manipulationBareObj ); -}); - -function testWrapInner( val ) { - - expect( 11 ); - - var num, result, div; - - num = jQuery("#first").children().length; - result = jQuery("#first").wrapInner( val("<div class='red'><div id='tmp'></div></div>") ); - - equal( jQuery("#first").children().length, 1, "Only one child" ); - ok( jQuery("#first").children().is(".red"), "Verify Right Element" ); - equal( jQuery("#first").children().children().children().length, num, "Verify Elements Intact" ); - - QUnit.reset(); - num = jQuery("#first").html("foo<div>test</div><div>test2</div>").children().length; - result = jQuery("#first").wrapInner( val("<div class='red'><div id='tmp'></div></div>") ); - equal( jQuery("#first").children().length, 1, "Only one child" ); - ok( jQuery("#first").children().is(".red"), "Verify Right Element" ); - equal( jQuery("#first").children().children().children().length, num, "Verify Elements Intact" ); - - QUnit.reset(); - num = jQuery("#first").children().length; - result = jQuery("#first").wrapInner( val(document.getElementById("empty")) ); - equal( jQuery("#first").children().length, 1, "Only one child" ); - ok( jQuery("#first").children().is("#empty"), "Verify Right Element" ); - equal( jQuery("#first").children().children().length, num, "Verify Elements Intact" ); - - div = jQuery("<div/>"); - div.wrapInner( val("<span></span>") ); - equal( div.children().length, 1, "The contents were wrapped." ); - equal( div.children()[ 0 ].nodeName.toLowerCase(), "span", "A span was inserted." ); -} - -test( "wrapInner(String|Element)", function() { - testWrapInner( manipulationBareObj ); -}); - -test( "wrapInner(Function)", function() { - testWrapInner( manipulationFunctionReturningObj ); -}); - -test( "unwrap()", function() { - - expect( 9 ); - - jQuery("body").append(" <div id='unwrap' style='display: none;'> <div id='unwrap1'> <span class='unwrap'>a</span> <span class='unwrap'>b</span> </div> <div id='unwrap2'> <span class='unwrap'>c</span> <span class='unwrap'>d</span> </div> <div id='unwrap3'> <b><span class='unwrap unwrap3'>e</span></b> <b><span class='unwrap unwrap3'>f</span></b> </div> </div>"); - - var abcd = jQuery("#unwrap1 > span, #unwrap2 > span").get(), - abcdef = jQuery("#unwrap span").get(); - - equal( jQuery("#unwrap1 span").add("#unwrap2 span:first-child").unwrap().length, 3, "make #unwrap1 and #unwrap2 go away" ); - deepEqual( jQuery("#unwrap > span").get(), abcd, "all four spans should still exist" ); - - deepEqual( jQuery("#unwrap3 span").unwrap().get(), jQuery("#unwrap3 > span").get(), "make all b in #unwrap3 go away" ); - - deepEqual( jQuery("#unwrap3 span").unwrap().get(), jQuery("#unwrap > span.unwrap3").get(), "make #unwrap3 go away" ); - - deepEqual( jQuery("#unwrap").children().get(), abcdef, "#unwrap only contains 6 child spans" ); - - deepEqual( jQuery("#unwrap > span").unwrap().get(), jQuery("body > span.unwrap").get(), "make the 6 spans become children of body" ); - - deepEqual( jQuery("body > span.unwrap").unwrap().get(), jQuery("body > span.unwrap").get(), "can't unwrap children of body" ); - deepEqual( jQuery("body > span.unwrap").unwrap().get(), abcdef, "can't unwrap children of body" ); - - deepEqual( jQuery("body > span.unwrap").get(), abcdef, "body contains 6 .unwrap child spans" ); - - jQuery("body > span.unwrap").remove(); -}); - function testAppendForObject( valueObj, isFragment ) { var $base, type = isFragment ? " (DocumentFragment)" : " (Element)", @@ -495,7 +279,9 @@ function testAppend( valueObj ) { $radioUnchecked = jQuery("<input type='radio' name='R1' checked='checked'/>").appendTo( $radioParent ); $radioChecked.trigger("click"); $radioUnchecked[ 0 ].checked = false; - $radioParent.wrap("<div></div>"); + + jQuery("<div/>").insertBefore($radioParent).append($radioParent); + equal( $radioChecked[ 0 ].checked, true, "Reappending radios uphold which radio is checked" ); equal( $radioUnchecked[ 0 ].checked, false, "Reappending radios uphold not being checked" ); @@ -670,7 +456,7 @@ test( "append HTML5 sectioning elements (Bug #6485)", function() { jQuery("#qunit-fixture").append("<article style='font-size:10px'><section><aside>HTML5 elements</aside></section></article>"); - article = jQuery("article"), + article = jQuery("article"); aside = jQuery("aside"); equal( article.get( 0 ).style.fontSize, "10px", "HTML5 elements are styleable" ); @@ -2035,19 +1821,6 @@ test( "jQuery.clone - no exceptions for object elements #9587", function() { } }); -test( "jQuery(<tag>) & wrap[Inner/All]() handle unknown elems (#10667)", function() { - - expect( 2 ); - - var $wraptarget = jQuery( "<div id='wrap-target'>Target</div>" ).appendTo( "#qunit-fixture" ), - $section = jQuery( "<section>" ).appendTo( "#qunit-fixture" ); - - $wraptarget.wrapAll("<aside style='background-color:green'></aside>"); - - notEqual( $wraptarget.parent("aside").get( 0 ).style.backgroundColor, "transparent", "HTML5 elements created with wrapAll inherit styles" ); - notEqual( $section.get( 0 ).style.backgroundColor, "transparent", "HTML5 elements create with jQuery( string ) inherit styles" ); -}); - test( "Cloned, detached HTML5 elems (#10667,10670)", function() { expect( 7 ); @@ -2282,20 +2055,6 @@ test( "jQuery._evalUrl (#12838)", function() { jQuery._evalUrl = evalUrl; }); -test( "wrapping scripts (#10470)", function() { - - expect( 2 ); - - var script = document.createElement("script"); - script.text = script.textContent = "ok( !document.eval10470, 'script evaluated once' ); document.eval10470 = true;"; - - document.eval10470 = false; - jQuery("#qunit-fixture").empty()[0].appendChild( script ); - jQuery("#qunit-fixture script").wrap("<b></b>"); - strictEqual( script.parentNode, jQuery("#qunit-fixture > b")[ 0 ], "correctly wrapped" ); - jQuery( script ).remove(); -}); - test( "insertAfter, insertBefore, etc do not work when destination is original element. Element is removed (#4087)", function() { expect( 10 ); diff --git a/test/unit/traversing.js b/test/unit/traversing.js index 709d357e6..b0e5011e8 100644 --- a/test/unit/traversing.js +++ b/test/unit/traversing.js @@ -143,14 +143,14 @@ test("is() with :has() selectors", function() { test("is() with positional selectors", function() { expect(24); - jQuery( - "<p id='posp'><a class='firsta' href='#'><em>first</em></a><a class='seconda' href='#'><b>test</b></a><em></em></p>" - ).appendTo( "#qunit-fixture" ); - var isit = function(sel, match, expect) { equal( jQuery( sel ).is( match ), expect, "jQuery('" + sel + "').is('" + match + "')" ); }; + jQuery( + "<p id='posp'><a class='firsta' href='#'><em>first</em></a><a class='seconda' href='#'><b>test</b></a><em></em></p>" + ).appendTo( "#qunit-fixture" ); + isit( "#posp", "#posp:first", true ); isit( "#posp", "#posp:eq(2)", false ); isit( "#posp", "#posp a:first", false ); @@ -272,21 +272,21 @@ test("filter(jQuery)", function() { test("filter() with positional selectors", function() { expect(19); - jQuery( "" + - "<p id='posp'>" + - "<a class='firsta' href='#'>" + - "<em>first</em>" + - "</a>" + - "<a class='seconda' href='#'>" + - "<b>test</b>" + - "</a>" + - "<em></em>" + - "</p>" ).appendTo( "#qunit-fixture" ); - var filterit = function(sel, filter, length) { equal( jQuery( sel ).filter( filter ).length, length, "jQuery( " + sel + " ).filter( " + filter + " )" ); }; + jQuery( "" + + "<p id='posp'>" + + "<a class='firsta' href='#'>" + + "<em>first</em>" + + "</a>" + + "<a class='seconda' href='#'>" + + "<b>test</b>" + + "</a>" + + "<em></em>" + + "</p>" ).appendTo( "#qunit-fixture" ); + filterit( "#posp", "#posp:first", 1); filterit( "#posp", "#posp:eq(2)", 0 ); filterit( "#posp", "#posp a:first", 0 ); diff --git a/test/unit/wrap.js b/test/unit/wrap.js new file mode 100644 index 000000000..c4c469fd9 --- /dev/null +++ b/test/unit/wrap.js @@ -0,0 +1,265 @@ +(function() { + +if ( !jQuery.fn.wrap ) { // no wrap module + return; +} + +module( "wrap", { + teardown: moduleTeardown +}); + +// See test/unit/manipulation.js for explanation about these 2 functions +function manipulationBareObj( value ) { + return value; +} + +function manipulationFunctionReturningObj( value ) { + return function() { + return value; + }; +} + +function testWrap( val ) { + + expect( 19 ); + + var defaultText, result, j, i, cacheLength; + + defaultText = "Try them out:"; + result = jQuery("#first").wrap( val("<div class='red'><span></span></div>") ).text(); + + equal( defaultText, result, "Check for wrapping of on-the-fly html" ); + ok( jQuery("#first").parent().parent().is(".red"), "Check if wrapper has class 'red'" ); + + QUnit.reset(); + result = jQuery("#first").wrap( val(document.getElementById("empty")) ).parent(); + ok( result.is("ol"), "Check for element wrapping" ); + equal( result.text(), defaultText, "Check for element wrapping" ); + + QUnit.reset(); + jQuery("#check1").on( "click", function() { + var checkbox = this; + + ok( checkbox.checked, "Checkbox's state is erased after wrap() action, see #769" ); + jQuery( checkbox ).wrap( val("<div id='c1' style='display:none;'></div>") ); + ok( checkbox.checked, "Checkbox's state is erased after wrap() action, see #769" ); + }).prop( "checked", false )[ 0 ].click(); + + // using contents will get comments regular, text, and comment nodes + j = jQuery("#nonnodes").contents(); + j.wrap( val("<i></i>") ); + + // Blackberry 4.6 doesn't maintain comments in the DOM + equal( jQuery("#nonnodes > i").length, jQuery("#nonnodes")[ 0 ].childNodes.length, "Check node,textnode,comment wraps ok" ); + equal( jQuery("#nonnodes > i").text(), j.text(), "Check node,textnode,comment wraps doesn't hurt text" ); + + // Try wrapping a disconnected node + cacheLength = 0; + for ( i in jQuery.cache ) { + cacheLength++; + } + + j = jQuery("<label/>").wrap( val("<li/>") ); + equal( j[ 0 ] .nodeName.toUpperCase(), "LABEL", "Element is a label" ); + equal( j[ 0 ].parentNode.nodeName.toUpperCase(), "LI", "Element has been wrapped" ); + + for ( i in jQuery.cache ) { + cacheLength--; + } + equal( cacheLength, 0, "No memory leak in jQuery.cache (bug #7165)" ); + + // Wrap an element containing a text node + j = jQuery("<span/>").wrap("<div>test</div>"); + equal( j[ 0 ].previousSibling.nodeType, 3, "Make sure the previous node is a text element" ); + equal( j[ 0 ].parentNode.nodeName.toUpperCase(), "DIV", "And that we're in the div element." ); + + // Try to wrap an element with multiple elements (should fail) + j = jQuery("<div><span></span></div>").children().wrap("<p></p><div></div>"); + equal( j[ 0 ].parentNode.parentNode.childNodes.length, 1, "There should only be one element wrapping." ); + equal( j.length, 1, "There should only be one element (no cloning)." ); + equal( j[ 0 ].parentNode.nodeName.toUpperCase(), "P", "The span should be in the paragraph." ); + + // Wrap an element with a jQuery set + j = jQuery("<span/>").wrap( jQuery("<div></div>") ); + equal( j[ 0 ].parentNode.nodeName.toLowerCase(), "div", "Wrapping works." ); + + // Wrap an element with a jQuery set and event + result = jQuery("<div></div>").on( "click", function() { + ok( true, "Event triggered." ); + + // Remove handlers on detached elements + result.off(); + jQuery(this).off(); + }); + + j = jQuery("<span/>").wrap( result ); + equal( j[ 0 ].parentNode.nodeName.toLowerCase(), "div", "Wrapping works." ); + + j.parent().trigger("click"); + + // clean up attached elements + QUnit.reset(); +} + +test( "wrap(String|Element)", function() { + testWrap( manipulationBareObj ); +}); + +test( "wrap(Function)", function() { + testWrap( manipulationFunctionReturningObj ); +}); + +test( "wrap(Function) with index (#10177)", function() { + var expectedIndex = 0, + targets = jQuery("#qunit-fixture p"); + + expect( targets.length ); + targets.wrap(function(i) { + equal( i, expectedIndex, "Check if the provided index (" + i + ") is as expected (" + expectedIndex + ")" ); + expectedIndex++; + + return "<div id='wrap_index_'" + i + "'></div>"; + }); +}); + +test( "wrap(String) consecutive elements (#10177)", function() { + var targets = jQuery("#qunit-fixture p"); + + expect( targets.length * 2 ); + targets.wrap("<div class='wrapper'></div>"); + + targets.each(function() { + var $this = jQuery(this); + + ok( $this.parent().is(".wrapper"), "Check each elements parent is correct (.wrapper)" ); + equal( $this.siblings().length, 0, "Each element should be wrapped individually" ); + }); +}); + +function testWrapAll( val ) { + + expect( 8 ); + + var prev, p, result; + + prev = jQuery("#firstp")[ 0 ].previousSibling; + p = jQuery("#firstp,#first")[ 0 ].parentNode; + result = jQuery("#firstp,#first").wrapAll( val("<div class='red'><div class='tmp'></div></div>") ); + + equal( result.parent().length, 1, "Check for wrapping of on-the-fly html" ); + ok( jQuery("#first").parent().parent().is(".red"), "Check if wrapper has class 'red'" ); + ok( jQuery("#firstp").parent().parent().is(".red"), "Check if wrapper has class 'red'" ); + equal( jQuery("#first").parent().parent()[ 0 ].previousSibling, prev, "Correct Previous Sibling" ); + equal( jQuery("#first").parent().parent()[ 0 ].parentNode, p, "Correct Parent" ); + + QUnit.reset(); + prev = jQuery("#firstp")[ 0 ].previousSibling; + p = jQuery("#first")[ 0 ].parentNode; + jQuery("#firstp,#first").wrapAll( val(document.getElementById("empty")) ); + + equal( jQuery("#first").parent()[ 0 ], jQuery("#firstp").parent()[ 0 ], "Same Parent" ); + equal( jQuery("#first").parent()[ 0 ].previousSibling, prev, "Correct Previous Sibling" ); + equal( jQuery("#first").parent()[ 0 ].parentNode, p, "Correct Parent" ); +} + +test( "wrapAll(String|Element)", function() { + testWrapAll( manipulationBareObj ); +}); + +function testWrapInner( val ) { + + expect( 11 ); + + var num, div; + + num = jQuery("#first").children().length; + jQuery("#first").wrapInner( val("<div class='red'><div id='tmp'></div></div>") ); + + equal( jQuery("#first").children().length, 1, "Only one child" ); + ok( jQuery("#first").children().is(".red"), "Verify Right Element" ); + equal( jQuery("#first").children().children().children().length, num, "Verify Elements Intact" ); + + QUnit.reset(); + num = jQuery("#first").html("foo<div>test</div><div>test2</div>").children().length; + jQuery("#first").wrapInner( val("<div class='red'><div id='tmp'></div></div>") ); + equal( jQuery("#first").children().length, 1, "Only one child" ); + ok( jQuery("#first").children().is(".red"), "Verify Right Element" ); + equal( jQuery("#first").children().children().children().length, num, "Verify Elements Intact" ); + + QUnit.reset(); + num = jQuery("#first").children().length; + jQuery("#first").wrapInner( val(document.getElementById("empty")) ); + equal( jQuery("#first").children().length, 1, "Only one child" ); + ok( jQuery("#first").children().is("#empty"), "Verify Right Element" ); + equal( jQuery("#first").children().children().length, num, "Verify Elements Intact" ); + + div = jQuery("<div/>"); + div.wrapInner( val("<span></span>") ); + equal( div.children().length, 1, "The contents were wrapped." ); + equal( div.children()[ 0 ].nodeName.toLowerCase(), "span", "A span was inserted." ); +} + +test( "wrapInner(String|Element)", function() { + testWrapInner( manipulationBareObj ); +}); + +test( "wrapInner(Function)", function() { + testWrapInner( manipulationFunctionReturningObj ); +}); + +test( "unwrap()", function() { + + expect( 9 ); + + jQuery("body").append(" <div id='unwrap' style='display: none;'> <div id='unwrap1'> <span class='unwrap'>a</span> <span class='unwrap'>b</span> </div> <div id='unwrap2'> <span class='unwrap'>c</span> <span class='unwrap'>d</span> </div> <div id='unwrap3'> <b><span class='unwrap unwrap3'>e</span></b> <b><span class='unwrap unwrap3'>f</span></b> </div> </div>"); + + var abcd = jQuery("#unwrap1 > span, #unwrap2 > span").get(), + abcdef = jQuery("#unwrap span").get(); + + equal( jQuery("#unwrap1 span").add("#unwrap2 span:first-child").unwrap().length, 3, "make #unwrap1 and #unwrap2 go away" ); + deepEqual( jQuery("#unwrap > span").get(), abcd, "all four spans should still exist" ); + + deepEqual( jQuery("#unwrap3 span").unwrap().get(), jQuery("#unwrap3 > span").get(), "make all b in #unwrap3 go away" ); + + deepEqual( jQuery("#unwrap3 span").unwrap().get(), jQuery("#unwrap > span.unwrap3").get(), "make #unwrap3 go away" ); + + deepEqual( jQuery("#unwrap").children().get(), abcdef, "#unwrap only contains 6 child spans" ); + + deepEqual( jQuery("#unwrap > span").unwrap().get(), jQuery("body > span.unwrap").get(), "make the 6 spans become children of body" ); + + deepEqual( jQuery("body > span.unwrap").unwrap().get(), jQuery("body > span.unwrap").get(), "can't unwrap children of body" ); + deepEqual( jQuery("body > span.unwrap").unwrap().get(), abcdef, "can't unwrap children of body" ); + + deepEqual( jQuery("body > span.unwrap").get(), abcdef, "body contains 6 .unwrap child spans" ); + + jQuery("body > span.unwrap").remove(); +}); + +test( "jQuery(<tag>) & wrap[Inner/All]() handle unknown elems (#10667)", function() { + + expect( 2 ); + + var $wraptarget = jQuery( "<div id='wrap-target'>Target</div>" ).appendTo( "#qunit-fixture" ), + $section = jQuery( "<section>" ).appendTo( "#qunit-fixture" ); + + $wraptarget.wrapAll("<aside style='background-color:green'></aside>"); + + notEqual( $wraptarget.parent("aside").get( 0 ).style.backgroundColor, "transparent", "HTML5 elements created with wrapAll inherit styles" ); + notEqual( $section.get( 0 ).style.backgroundColor, "transparent", "HTML5 elements create with jQuery( string ) inherit styles" ); +}); + +test( "wrapping scripts (#10470)", function() { + + expect( 2 ); + + var script = document.createElement("script"); + script.text = script.textContent = "ok( !document.eval10470, 'script evaluated once' ); document.eval10470 = true;"; + + document.eval10470 = false; + jQuery("#qunit-fixture").empty()[0].appendChild( script ); + jQuery("#qunit-fixture script").wrap("<b></b>"); + strictEqual( script.parentNode, jQuery("#qunit-fixture > b")[ 0 ], "correctly wrapped" ); + jQuery( script ).remove(); +}); + +})(); |