Ensure that buildFragment clones elements properly in all browsers. Fixes #3879, #6655. Also improves form element clone tests and fixes bugs in $.fn.clone exposed by these new test cases related to the values of checkboxes and radio buttons in IE.
This commit is contained in:
parent
012f0c3b4b
commit
b14f02899e
|
@ -129,7 +129,7 @@ jQuery.fn = jQuery.prototype = {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
|
ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
|
||||||
selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;
|
selector = (ret.cacheable ? jQuery(ret.fragment).clone()[0] : ret.fragment).childNodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
return jQuery.merge( this, selector );
|
return jQuery.merge( this, selector );
|
||||||
|
|
|
@ -420,15 +420,29 @@ function cloneFixAttributes(src, dest) {
|
||||||
if ( nodeName === "object" ) {
|
if ( nodeName === "object" ) {
|
||||||
dest.outerHTML = src.outerHTML;
|
dest.outerHTML = src.outerHTML;
|
||||||
|
|
||||||
|
} else if ( nodeName === "input" && (src.type === "checkbox" || src.type === "radio") ) {
|
||||||
// IE6-8 fails to persist the checked state of a cloned checkbox
|
// IE6-8 fails to persist the checked state of a cloned checkbox
|
||||||
// or radio button
|
// or radio button. Worse, IE6-7 fail to give the cloned element
|
||||||
} else if ( nodeName === "input" && src.checked ) {
|
// a checked appearance if the defaultChecked value isn't also set
|
||||||
|
if ( src.checked ) {
|
||||||
dest.defaultChecked = dest.checked = src.checked;
|
dest.defaultChecked = dest.checked = src.checked;
|
||||||
|
}
|
||||||
|
|
||||||
|
// IE6-7 get confused and end up setting the value of a cloned
|
||||||
|
// checkbox/radio button to an empty string instead of "on"
|
||||||
|
if ( dest.value !== src.value ) {
|
||||||
|
dest.value = src.value;
|
||||||
|
}
|
||||||
|
|
||||||
// IE6-8 fails to return the selected option to the default selected
|
// IE6-8 fails to return the selected option to the default selected
|
||||||
// state when cloning options
|
// state when cloning options
|
||||||
} else if ( nodeName === "option" ) {
|
} else if ( nodeName === "option" ) {
|
||||||
dest.selected = src.defaultSelected;
|
dest.selected = src.defaultSelected;
|
||||||
|
|
||||||
|
// IE6-8 fails to set the defaultValue to the correct value when
|
||||||
|
// cloning other types of input fields
|
||||||
|
} else if ( nodeName === "input" || nodeName === "textarea" ) {
|
||||||
|
dest.defaultValue = src.defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Event data gets referenced instead of copied if the expando
|
// Event data gets referenced instead of copied if the expando
|
||||||
|
|
|
@ -12,7 +12,7 @@ test("Basic requirements", function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test("jQuery()", function() {
|
test("jQuery()", function() {
|
||||||
expect(23);
|
expect(24);
|
||||||
|
|
||||||
// Basic constructor's behavior
|
// Basic constructor's behavior
|
||||||
|
|
||||||
|
@ -84,6 +84,11 @@ test("jQuery()", function() {
|
||||||
|
|
||||||
exec = true;
|
exec = true;
|
||||||
elem.click();
|
elem.click();
|
||||||
|
|
||||||
|
for ( var i = 0; i < 3; ++i ) {
|
||||||
|
elem = jQuery("<input type='text' value='TEST' />");
|
||||||
|
}
|
||||||
|
equals( elem[0].defaultValue, "TEST", "Ensure cached nodes are cloned properly (Bug #6655)" );
|
||||||
});
|
});
|
||||||
|
|
||||||
test("selector state", function() {
|
test("selector state", function() {
|
||||||
|
|
|
@ -395,7 +395,7 @@ test("append(Function) with incoming value", function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test("append the same fragment with events (Bug #6997, 5566)", function () {
|
test("append the same fragment with events (Bug #6997, 5566)", function () {
|
||||||
expect(4 + (document.fireEvent ? 1 : 0));
|
expect(2 + (document.fireEvent ? 1 : 0));
|
||||||
stop(1000);
|
stop(1000);
|
||||||
|
|
||||||
var element;
|
var element;
|
||||||
|
@ -426,14 +426,6 @@ test("append the same fragment with events (Bug #6997, 5566)", function () {
|
||||||
|
|
||||||
jQuery("#listWithTabIndex li").before(element);
|
jQuery("#listWithTabIndex li").before(element);
|
||||||
jQuery("#listWithTabIndex li.test6997").eq(1).click();
|
jQuery("#listWithTabIndex li.test6997").eq(1).click();
|
||||||
|
|
||||||
element = jQuery("<select><option>Foo</option><option selected>Bar</option></select>");
|
|
||||||
|
|
||||||
equals( element.clone().find("option:selected").val(), element.find("option:selected").val(), "Selected option cloned correctly" );
|
|
||||||
|
|
||||||
element = jQuery("<input type='checkbox'>").attr('checked', 'checked');
|
|
||||||
|
|
||||||
equals( element.clone().is(":checked"), element.is(":checked"), "Checked input cloned correctly" );
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test("appendTo(String|Element|Array<Element>|jQuery)", function() {
|
test("appendTo(String|Element|Array<Element>|jQuery)", function() {
|
||||||
|
@ -945,6 +937,28 @@ test("clone()", function() {
|
||||||
equal( jQuery("body").clone().children()[0].id, "qunit-header", "Make sure cloning body works" );
|
equal( jQuery("body").clone().children()[0].id, "qunit-header", "Make sure cloning body works" );
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("clone(form element) (Bug #3879, #6655)", function() {
|
||||||
|
expect(6);
|
||||||
|
element = jQuery("<select><option>Foo</option><option selected>Bar</option></select>");
|
||||||
|
|
||||||
|
equals( element.clone().find("option:selected").val(), element.find("option:selected").val(), "Selected option cloned correctly" );
|
||||||
|
|
||||||
|
element = jQuery("<input type='checkbox' value='foo'>").attr('checked', 'checked');
|
||||||
|
clone = element.clone();
|
||||||
|
|
||||||
|
equals( clone.is(":checked"), element.is(":checked"), "Checked input cloned correctly" );
|
||||||
|
equals( clone[0].defaultValue, "foo", "Checked input defaultValue cloned correctly" );
|
||||||
|
equals( clone[0].defaultChecked, !jQuery.support.noCloneEvent, "Checked input defaultChecked cloned correctly" );
|
||||||
|
|
||||||
|
element = jQuery("<input type='text' value='foo'>");
|
||||||
|
clone = element.clone();
|
||||||
|
equals( clone[0].defaultValue, "foo", "Text input defaultValue cloned correctly" );
|
||||||
|
|
||||||
|
element = jQuery("<textarea>foo</textarea>");
|
||||||
|
clone = element.clone();
|
||||||
|
equals( clone[0].defaultValue, "foo", "Textarea defaultValue cloned correctly" );
|
||||||
|
});
|
||||||
|
|
||||||
if (!isLocal) {
|
if (!isLocal) {
|
||||||
test("clone() on XML nodes", function() {
|
test("clone() on XML nodes", function() {
|
||||||
expect(2);
|
expect(2);
|
||||||
|
|
Loading…
Reference in a new issue