Make sure that checked state is cloned properly. Based upon the patch by Michael...
authorMichael Monteleone <michael@michaelmonteleone.net>
Mon, 25 Jan 2010 23:43:33 +0000 (18:43 -0500)
committerjeresig <jeresig@gmail.com>
Mon, 25 Jan 2010 23:43:33 +0000 (18:43 -0500)
src/manipulation.js
src/support.js
test/unit/manipulation.js

index 23463d1..4d0ffd0 100644 (file)
@@ -5,6 +5,7 @@ var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
        rtagName = /<([\w:]+)/,
        rtbody = /<tbody/i,
        rhtml = /<|&\w+;/,
+       rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,  // checked="checked" or checked (html5)
        fcloseTag = function( all, front, tag ) {
                return rselfClosing.test( tag ) ?
                        all :
@@ -35,7 +36,7 @@ jQuery.fn.extend({
                if ( jQuery.isFunction(text) ) {
                        return this.each(function(i) {
                                var self = jQuery(this);
-                               return self.text( text.call(this, i, self.text()) );
+                               self.text( text.call(this, i, self.text()) );
                        });
                }
 
@@ -251,11 +252,18 @@ jQuery.fn.extend({
        domManip: function( args, table, callback ) {
                var results, first, value = args[0], scripts = [];
 
+               // We can't cloneNode fragments that contain checked, in WebKit
+               if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
+                       return this.each(function() {
+                               jQuery(this).domManip( args, table, callback, true );
+                       });
+               }
+
                if ( jQuery.isFunction(value) ) {
                        return this.each(function(i) {
                                var self = jQuery(this);
                                args[0] = value.call(this, i, table ? self.html() : undefined);
-                               return self.domManip( args, table, callback );
+                               self.domManip( args, table, callback );
                        });
                }
 
@@ -326,7 +334,8 @@ function cloneCopyEvent(orig, ret) {
 function buildFragment( args, nodes, scripts ) {
        var fragment, cacheable, cacheresults, doc;
 
-       if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && args[0].indexOf("<option") < 0 ) {
+       // webkit does not clone 'checked' attribute of radio inputs on cloneNode, so don't cache if string has a checked
+       if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && args[0].indexOf("<option") < 0 && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
                cacheable = true;
                cacheresults = jQuery.fragments[ args[0] ];
                if ( cacheresults ) {
index 3e99772..befc532 100644 (file)
@@ -57,6 +57,7 @@
                optSelected: document.createElement("select").appendChild( document.createElement("option") ).selected,
 
                // Will be defined later
+               checkClone: false,
                scriptEval: false,
                noCloneEvent: true,
                boxModel: null
                div.cloneNode(true).fireEvent("onclick");
        }
 
+       div = document.createElement("div");
+       div.innerHTML = "<input type='radio' name='radiotest' checked='checked'/>";
+
+       var fragment = document.createDocumentFragment();
+       fragment.appendChild( div.firstChild );
+
+       // WebKit doesn't clone checked state correctly in fragments
+       jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked;
+
        // Figure out if the W3C box model works as expected
        // document.body must exist before we can do this
-       // TODO: This timeout is temporary until I move ready into core.js.
        jQuery(function() {
                var div = document.createElement("div");
                div.style.width = div.style.paddingLeft = "1px";
index 031bf5b..b0a1c71 100644 (file)
@@ -197,7 +197,7 @@ test("unwrap()", function() {
 });
 
 var testAppend = function(valueObj) {
-       expect(22);
+       expect(37);
        var defaultText = 'Try them out:'
        var result = jQuery('#first').append(valueObj('<b>buga</b>'));
        equals( result.text(), defaultText + 'buga', 'Check if text appending works' );
@@ -230,6 +230,24 @@ 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." );
+       
+       reset();
+       jQuery("form").append(valueObj('<input name="radiotest" type="radio" checked="checked" />'));
+       jQuery("form input[name=radiotest]").each(function(){
+               ok( jQuery(this).is(':checked'), "Append checked radio");
+       }).remove();
+
+       reset();
+       jQuery("form").append(valueObj('<input name="radiotest" type="radio" checked    =   \'checked\' />'));
+       jQuery("form input[name=radiotest]").each(function(){
+               ok( jQuery(this).is(':checked'), "Append alternately formated checked radio");
+       }).remove();
+
+       reset();
+       jQuery("form").append(valueObj('<input name="radiotest" type="radio" checked />'));
+       jQuery("form input[name=radiotest]").each(function(){
+               ok( jQuery(this).is(':checked'), "Append HTML5-formated checked radio");
+       }).remove();
 
        reset();
        jQuery("#sap").append(valueObj( document.getElementById('form') ));