aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Monteleone <michael@michaelmonteleone.net>2010-01-25 18:43:33 -0500
committerjeresig <jeresig@gmail.com>2010-01-25 18:43:33 -0500
commitbed759c95ca6d796125653b540e8611dc63b38bb (patch)
treebc8fcc3811466fd18913fd2604586b8c6a96bb04
parent390186b902c4c1ac13e23754d33ed4d8b3d5fa38 (diff)
downloadjquery-bed759c95ca6d796125653b540e8611dc63b38bb.tar.gz
jquery-bed759c95ca6d796125653b540e8611dc63b38bb.zip
Make sure that checked state is cloned properly. Based upon the patch by Michael, required better test cases and in doing so found more edge cases. Introduced a new check into jQuery.support as a result. Fixes #5929.
-rw-r--r--src/manipulation.js15
-rw-r--r--src/support.js11
-rw-r--r--test/unit/manipulation.js20
3 files changed, 41 insertions, 5 deletions
diff --git a/src/manipulation.js b/src/manipulation.js
index 23463d16e..4d0ffd057 100644
--- a/src/manipulation.js
+++ b/src/manipulation.js
@@ -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 ) {
diff --git a/src/support.js b/src/support.js
index 3e9977278..befc53272 100644
--- a/src/support.js
+++ b/src/support.js
@@ -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
@@ -89,9 +90,17 @@
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";
diff --git a/test/unit/manipulation.js b/test/unit/manipulation.js
index 031bf5b72..b0a1c71af 100644
--- a/test/unit/manipulation.js
+++ b/test/unit/manipulation.js
@@ -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') ));