From: jeresig Date: Wed, 23 Feb 2011 18:18:44 +0000 (-0500) Subject: Make a new jQuery.support.noCloneChecked - splitting apart the previous feature detec... X-Git-Url: http://git.asbjorn.biz/?a=commitdiff_plain;ds=sidebyside;h=292acd97a226ec15af2adc069d02973d59c6bc59;p=jquery.git Make a new jQuery.support.noCloneChecked - splitting apart the previous feature detect relating to clone in IE, fixes the last remaining issue with IE 9 RC. Fixes #8365. --- diff --git a/src/manipulation.js b/src/manipulation.js index cd0732c..ba31697 100644 --- a/src/manipulation.js +++ b/src/manipulation.js @@ -489,6 +489,18 @@ jQuery.each({ }; }); +function getAll( elem ) { + if ( "getElementsByTagName" in elem ) { + return elem.getElementsByTagName( "*" ); + + } else if ( "querySelectorAll" in elem ) { + return elem.querySelectorAll( "*" ); + + } else { + return []; + } +} + jQuery.extend({ clone: function( elem, dataAndEvents, deepDataAndEvents ) { var clone = elem.cloneNode(true), @@ -496,7 +508,8 @@ jQuery.extend({ destElements, i; - if ( !jQuery.support.noCloneEvent && (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { + if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) && + (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { // IE copies events bound via attachEvent when using cloneNode. // Calling detachEvent on the clone will also remove the events // from the original. In order to get around this, we use some @@ -507,8 +520,8 @@ jQuery.extend({ // Using Sizzle here is crazy slow, so we use getElementsByTagName // instead - srcElements = elem.getElementsByTagName("*"); - destElements = clone.getElementsByTagName("*"); + srcElements = getAll( elem ); + destElements = getAll( clone ); // Weird iteration because IE will replace the length property // with an element if you are cloning the body and one of the @@ -520,21 +533,18 @@ jQuery.extend({ // Copy the events from the original to the clone if ( dataAndEvents ) { - cloneCopyEvent( elem, clone ); - if ( deepDataAndEvents && "getElementsByTagName" in elem ) { - - srcElements = elem.getElementsByTagName("*"); - destElements = clone.getElementsByTagName("*"); + if ( deepDataAndEvents ) { + srcElements = getAll( elem ); + destElements = getAll( clone ); - if ( srcElements.length ) { - for ( i = 0; srcElements[i]; ++i ) { - cloneCopyEvent( srcElements[i], destElements[i] ); - } + for ( i = 0; srcElements[i]; ++i ) { + cloneCopyEvent( srcElements[i], destElements[i] ); } } } + // Return the cloned set return clone; }, diff --git a/src/support.js b/src/support.js index 97b4a42..7470b33 100644 --- a/src/support.js +++ b/src/support.js @@ -12,7 +12,8 @@ var all = div.getElementsByTagName("*"), a = div.getElementsByTagName("a")[0], select = document.createElement("select"), - opt = select.appendChild( document.createElement("option") ); + opt = select.appendChild( document.createElement("option") ), + input = div.getElementsByTagName("input")[0]; // Can't get basic test support if ( !all || !all.length || !a ) { @@ -51,7 +52,7 @@ // Make sure that if no value is specified for a checkbox // that it defaults to "on". // (WebKit defaults to "" instead) - checkOn: div.getElementsByTagName("input")[0].value === "on", + checkOn: input.value === "on", // Make sure that a selected-by-default option has a working selected property. // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) @@ -62,12 +63,16 @@ optDisabled: false, checkClone: false, noCloneEvent: true, + noCloneChecked: true, boxModel: null, inlineBlockNeedsLayout: false, shrinkWrapBlocks: false, reliableHiddenOffsets: true }; + input.checked = true; + jQuery.support.noCloneChecked = input.cloneNode( true ).checked; + // Make sure that the options inside disabled selects aren't marked as disabled // (WebKit marks them as diabled) select.disabled = true; diff --git a/test/unit/manipulation.js b/test/unit/manipulation.js index 1313783..34425ed 100644 --- a/test/unit/manipulation.js +++ b/test/unit/manipulation.js @@ -402,7 +402,8 @@ test("append(Function) with incoming value", function() { }); test("append the same fragment with events (Bug #6997, 5566)", function () { - expect(2 + (document.fireEvent ? 1 : 0)); + var doExtra = !jQuery.support.noCloneEvent && document.fireEvent; + expect(2 + (doExtra ? 1 : 0)); stop(1000); var element; @@ -410,7 +411,7 @@ test("append the same fragment with events (Bug #6997, 5566)", function () { // This patch modified the way that cloning occurs in IE; we need to make sure that // native event handlers on the original object don't get disturbed when they are // modified on the clone - if (!jQuery.support.noCloneEvent && document.fireEvent) { + if ( doExtra ) { element = jQuery("div:first").click(function () { ok(true, "Event exists on original after being unbound on clone"); jQuery(this).unbind('click'); @@ -1015,7 +1016,7 @@ test("clone(form element) (Bug #3879, #6655)", function() { 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" ); + equals( clone[0].defaultChecked, !jQuery.support.noCloneChecked, "Checked input defaultChecked cloned correctly" ); element = jQuery(""); clone = element.clone();