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.
This commit is contained in:
parent
390186b902
commit
bed759c95c
|
@ -5,6 +5,7 @@ var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
|
||||||
rtagName = /<([\w:]+)/,
|
rtagName = /<([\w:]+)/,
|
||||||
rtbody = /<tbody/i,
|
rtbody = /<tbody/i,
|
||||||
rhtml = /<|&\w+;/,
|
rhtml = /<|&\w+;/,
|
||||||
|
rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, // checked="checked" or checked (html5)
|
||||||
fcloseTag = function( all, front, tag ) {
|
fcloseTag = function( all, front, tag ) {
|
||||||
return rselfClosing.test( tag ) ?
|
return rselfClosing.test( tag ) ?
|
||||||
all :
|
all :
|
||||||
|
@ -35,7 +36,7 @@ jQuery.fn.extend({
|
||||||
if ( jQuery.isFunction(text) ) {
|
if ( jQuery.isFunction(text) ) {
|
||||||
return this.each(function(i) {
|
return this.each(function(i) {
|
||||||
var self = jQuery(this);
|
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 ) {
|
domManip: function( args, table, callback ) {
|
||||||
var results, first, value = args[0], scripts = [];
|
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) ) {
|
if ( jQuery.isFunction(value) ) {
|
||||||
return this.each(function(i) {
|
return this.each(function(i) {
|
||||||
var self = jQuery(this);
|
var self = jQuery(this);
|
||||||
args[0] = value.call(this, i, table ? self.html() : undefined);
|
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 ) {
|
function buildFragment( args, nodes, scripts ) {
|
||||||
var fragment, cacheable, cacheresults, doc;
|
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;
|
cacheable = true;
|
||||||
cacheresults = jQuery.fragments[ args[0] ];
|
cacheresults = jQuery.fragments[ args[0] ];
|
||||||
if ( cacheresults ) {
|
if ( cacheresults ) {
|
||||||
|
|
|
@ -57,6 +57,7 @@
|
||||||
optSelected: document.createElement("select").appendChild( document.createElement("option") ).selected,
|
optSelected: document.createElement("select").appendChild( document.createElement("option") ).selected,
|
||||||
|
|
||||||
// Will be defined later
|
// Will be defined later
|
||||||
|
checkClone: false,
|
||||||
scriptEval: false,
|
scriptEval: false,
|
||||||
noCloneEvent: true,
|
noCloneEvent: true,
|
||||||
boxModel: null
|
boxModel: null
|
||||||
|
@ -89,9 +90,17 @@
|
||||||
div.cloneNode(true).fireEvent("onclick");
|
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
|
// Figure out if the W3C box model works as expected
|
||||||
// document.body must exist before we can do this
|
// document.body must exist before we can do this
|
||||||
// TODO: This timeout is temporary until I move ready into core.js.
|
|
||||||
jQuery(function() {
|
jQuery(function() {
|
||||||
var div = document.createElement("div");
|
var div = document.createElement("div");
|
||||||
div.style.width = div.style.paddingLeft = "1px";
|
div.style.width = div.style.paddingLeft = "1px";
|
||||||
|
|
|
@ -197,7 +197,7 @@ test("unwrap()", function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
var testAppend = function(valueObj) {
|
var testAppend = function(valueObj) {
|
||||||
expect(22);
|
expect(37);
|
||||||
var defaultText = 'Try them out:'
|
var defaultText = 'Try them out:'
|
||||||
var result = jQuery('#first').append(valueObj('<b>buga</b>'));
|
var result = jQuery('#first').append(valueObj('<b>buga</b>'));
|
||||||
equals( result.text(), defaultText + 'buga', 'Check if text appending works' );
|
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 array." );
|
||||||
ok( jQuery("#sap").append(valueObj( "" )), "Check for appending an empty string." );
|
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." );
|
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();
|
reset();
|
||||||
jQuery("#sap").append(valueObj( document.getElementById('form') ));
|
jQuery("#sap").append(valueObj( document.getElementById('form') ));
|
||||||
|
|
Loading…
Reference in a new issue