Make a new jQuery.support.noCloneChecked - splitting apart the previous feature detec...
authorjeresig <jeresig@gmail.com>
Wed, 23 Feb 2011 18:18:44 +0000 (13:18 -0500)
committerjeresig <jeresig@gmail.com>
Wed, 23 Feb 2011 18:18:44 +0000 (13:18 -0500)
src/manipulation.js
src/support.js
test/unit/manipulation.js

index cd0732c..ba31697 100644 (file)
@@ -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;
 },
index 97b4a42..7470b33 100644 (file)
@@ -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)
                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;
index 1313783..34425ed 100644 (file)
@@ -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("<input type='text' value='foo'>");
        clone = element.clone();