Skip to content

Commit

Permalink
Clone fragments in domManip using jQuery.clone instead of DocumentFra…
Browse files Browse the repository at this point in the history
…gment.cloneNode in order to carry over event data. Fixes #5566, #6997.
  • Loading branch information
csnover committed Dec 7, 2010
1 parent c8be946 commit e4900df
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 57 deletions.
2 changes: 1 addition & 1 deletion src/manipulation.js
Expand Up @@ -349,7 +349,7 @@ jQuery.fn.extend({
root(this[i], first) :
this[i],
i > 0 || results.cacheable || this.length > 1 ?
fragment.cloneNode(true) :
jQuery(fragment).clone(true)[0] :
fragment
);
}
Expand Down
132 changes: 76 additions & 56 deletions test/unit/manipulation.js
Expand Up @@ -37,16 +37,16 @@ test("text(Function)", function() {

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.' );

QUnit.reset();
});

Expand Down Expand Up @@ -240,7 +240,7 @@ var testAppend = function(valueObj) {
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." );

QUnit.reset();
jQuery("form").append(valueObj('<input name="radiotest" type="radio" checked="checked" />'));
jQuery("form input[name=radiotest]").each(function(){
Expand Down Expand Up @@ -322,18 +322,18 @@ test("append(Function)", function() {

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 '<b>buga</b>';
});
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 '<option value="appendTest">Append Test</option>';
Expand All @@ -342,7 +342,7 @@ test("append(Function) with incoming value", function() {
QUnit.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');
Expand All @@ -352,7 +352,7 @@ test("append(Function) with incoming value", function() {
QUnit.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')];
Expand All @@ -362,7 +362,7 @@ test("append(Function) with incoming value", function() {
QUnit.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("#yahoo, #first");
Expand All @@ -371,16 +371,36 @@ test("append(Function) with incoming value", function() {

QUnit.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" );
ok( jQuery("#sap")[0].innerHTML.match( /5$/ ), "Check for appending a number" );

QUnit.reset();
});

test("append the same fragment with events (Bug #6997, 5566)", function () {
expect(2);
stop(1000);

var element = jQuery("<a class='test6997'></a>").click(function () {
ok(true, "Append second element events work");
});

jQuery("#listWithTabIndex li").append(element)
.find('a.test6997').eq(1).click();

element = jQuery("<li class='test6997'></li>").click(function () {
ok(true, "Before second element events work");
start();
});

jQuery("#listWithTabIndex li").before(element);
jQuery("#listWithTabIndex li.test6997").eq(1).click();
});

test("appendTo(String|Element|Array&lt;Element&gt;|jQuery)", function() {
expect(16);

Expand Down Expand Up @@ -489,16 +509,16 @@ test("prepend(Function)", function() {

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 '<b>buga</b>';
});
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 '<option value="prependTest">Prepend Test</option>';
Expand All @@ -507,35 +527,35 @@ test("prepend(Function) with incoming value", function() {
QUnit.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( jQuery('#sap').text(), expected, "Check for prepending of element" );

QUnit.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( jQuery('#sap').text(), expected, "Check for prepending of array of elements" );

QUnit.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("#yahoo, #first");
});
equals( jQuery('#sap').text(), expected, "Check for prepending of jQuery object" );

equals( jQuery('#sap').text(), expected, "Check for prepending of jQuery object" );
});

test("prependTo(String|Element|Array&lt;Element&gt;|jQuery)", function() {
Expand Down Expand Up @@ -981,14 +1001,14 @@ test("html(Function)", function() {

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 "<b>test</b>";
});

var pass = true;
div.each(function(){
if ( this.childNodes.length !== 1 ) {
Expand All @@ -1001,7 +1021,7 @@ test("html(Function) with incoming value", function() {
// 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 "<b>bold</b>";
Expand All @@ -1011,17 +1031,17 @@ test("html(Function) with incoming value", function() {
if ( j.length === 2 ) {
equals( null, null, "Make sure the incoming value is correct." );
}

j.find('b').removeData();
equals( j.html().replace(/ xmlns="[^"]+"/g, "").toLowerCase(), "<b>bold</b>", "Check node,textnode,comment with html()" );

var $div = jQuery('<div />');

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;
Expand All @@ -1032,16 +1052,16 @@ test("html(Function) with incoming value", function() {
equals( val, "", "Make sure the incoming value is correct." );
return insert;
}).html().replace(/>/g, "&gt;"), insert, "Verify escaped insertion." );

equals( $div2.html(function(i, val) {
equals( val.replace(/>/g, "&gt;"), insert, "Make sure the incoming value is correct." );
return "x" + insert;
}).html().replace(/>/g, "&gt;"), "x" + insert, "Verify escaped insertion." );

equals( $div2.html(function(i, val) {
equals( val.replace(/>/g, "&gt;"), "x" + insert, "Make sure the incoming value is correct." );
return " " + insert;
}).html().replace(/>/g, "&gt;"), " " + insert, "Verify escaped insertion." );
}).html().replace(/>/g, "&gt;"), " " + insert, "Verify escaped insertion." );
});

var testRemove = function(method) {
Expand Down Expand Up @@ -1075,9 +1095,9 @@ var testRemove = function(method) {
var count = 0;
var first = jQuery("#ap").children(":first");
var cleanUp = first.click(function() { count++ })[method]().appendTo("body").click();

equals( method == "remove" ? 0 : 1, count );

cleanUp.detach();
};

Expand All @@ -1102,58 +1122,58 @@ test("empty()", function() {

test("jQuery.cleanData", function() {
expect(14);

var type, pos, div, child;

type = "remove";

// Should trigger 4 remove event
div = getDiv().remove();

// Should both do nothing
pos = "Outer";
div.trigger("click");

pos = "Inner";
div.children().trigger("click");

type = "empty";
div = getDiv();
child = div.children();

// Should trigger 2 remove event
div.empty();

// Should trigger 1
pos = "Outer";
div.trigger("click");

// Should do nothing
pos = "Inner";
child.trigger("click");

// Should trigger 2
div.remove();

type = "html";

div = getDiv();
child = div.children();

// Should trigger 2 remove event
div.html("<div></div>");

// Should trigger 1
pos = "Outer";
div.trigger("click");

// Should do nothing
pos = "Inner";
child.trigger("click");

// Should trigger 2
div.remove();

function getDiv() {
var div = jQuery("<div class='outer'><div class='inner'></div></div>").click(function(){
ok( true, type + " " + pos + " Click event fired." );
Expand All @@ -1164,15 +1184,15 @@ test("jQuery.cleanData", function() {
}).focus(function(){
ok( false, type + " " + pos + " Focus event fired." );
}).end().appendTo("body");

div[0].detachEvent = div[0].removeEventListener = function(t){
ok( true, type + " Outer " + t + " event unbound" );
};

div[0].firstChild.detachEvent = div[0].firstChild.removeEventListener = function(t){
ok( true, type + " Inner " + t + " event unbound" );
};

return div;
}
});

0 comments on commit e4900df

Please sign in to comment.