Landing pull request 332. Appending disconnected radio or checkbox inputs and keeping checked setting Fixes #8060, #8500.
More Details: - https://github.com/jquery/jquery/pull/332 - http://bugs.jquery.com/ticket/8060 - http://bugs.jquery.com/ticket/8500
This commit is contained in:
parent
3ac9eb7ce3
commit
d274b7b9f7
4 changed files with 95 additions and 44 deletions
|
@ -731,7 +731,7 @@ jQuery.extend({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Go thorugh every key on the object,
|
// Go through every key on the object,
|
||||||
} else {
|
} else {
|
||||||
for ( key in elems ) {
|
for ( key in elems ) {
|
||||||
value = callback( elems[ key ], key, arg );
|
value = callback( elems[ key ], key, arg );
|
||||||
|
|
|
@ -70,7 +70,7 @@ jQuery.fn.extend({
|
||||||
}
|
}
|
||||||
|
|
||||||
return elem;
|
return elem;
|
||||||
}).append(this);
|
}).append( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
|
@ -379,13 +379,13 @@ function cloneCopyEvent( src, dest ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function cloneFixAttributes( src, dest ) {
|
function cloneFixAttributes( src, dest ) {
|
||||||
|
var nodeName;
|
||||||
|
|
||||||
// We do not need to do anything for non-Elements
|
// We do not need to do anything for non-Elements
|
||||||
if ( dest.nodeType !== 1 ) {
|
if ( dest.nodeType !== 1 ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var nodeName = dest.nodeName.toLowerCase();
|
|
||||||
|
|
||||||
// clearAttributes removes the attributes, which we don't want,
|
// clearAttributes removes the attributes, which we don't want,
|
||||||
// but also removes the attachEvent events, which we *do* want
|
// but also removes the attachEvent events, which we *do* want
|
||||||
if ( dest.clearAttributes ) {
|
if ( dest.clearAttributes ) {
|
||||||
|
@ -398,6 +398,8 @@ function cloneFixAttributes( src, dest ) {
|
||||||
dest.mergeAttributes( src );
|
dest.mergeAttributes( src );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nodeName = dest.nodeName.toLowerCase();
|
||||||
|
|
||||||
// IE6-8 fail to clone children inside object elements that use
|
// IE6-8 fail to clone children inside object elements that use
|
||||||
// the proprietary classid attribute value (rather than the type
|
// the proprietary classid attribute value (rather than the type
|
||||||
// attribute) to identify the type of content to display
|
// attribute) to identify the type of content to display
|
||||||
|
@ -446,11 +448,10 @@ jQuery.buildFragment = function( args, nodes, scripts ) {
|
||||||
args[0].charAt(0) === "<" && !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
|
args[0].charAt(0) === "<" && !rnocache.test( args[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 && cacheresults !== 1 ) {
|
||||||
if ( cacheresults !== 1 ) {
|
fragment = cacheresults;
|
||||||
fragment = cacheresults;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -508,6 +509,21 @@ function getAll( elem ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Used in clean, fixes the defaultChecked property
|
||||||
|
function fixDefaultChecked( elem ) {
|
||||||
|
if ( elem.type === "checkbox" || elem.type === "radio" ) {
|
||||||
|
elem.defaultChecked = elem.checked;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Finds all inputs and passes them to fixDefaultChecked
|
||||||
|
function findInputs( elem ) {
|
||||||
|
if ( jQuery.nodeName( elem, "input" ) ) {
|
||||||
|
fixDefaultChecked( elem );
|
||||||
|
} else if ( elem.getElementsByTagName ) {
|
||||||
|
jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
jQuery.extend({
|
jQuery.extend({
|
||||||
clone: function( elem, dataAndEvents, deepDataAndEvents ) {
|
clone: function( elem, dataAndEvents, deepDataAndEvents ) {
|
||||||
var clone = elem.cloneNode(true),
|
var clone = elem.cloneNode(true),
|
||||||
|
@ -578,54 +594,67 @@ jQuery.extend({
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert html string into DOM nodes
|
// Convert html string into DOM nodes
|
||||||
if ( typeof elem === "string" && !rhtml.test( elem ) ) {
|
if ( typeof elem === "string" ) {
|
||||||
elem = context.createTextNode( elem );
|
if ( !rhtml.test( elem ) ) {
|
||||||
|
elem = context.createTextNode( elem );
|
||||||
|
} else {
|
||||||
|
// Fix "XHTML"-style tags in all browsers
|
||||||
|
elem = elem.replace(rxhtmlTag, "<$1></$2>");
|
||||||
|
|
||||||
} else if ( typeof elem === "string" ) {
|
// Trim whitespace, otherwise indexOf won't work as expected
|
||||||
// Fix "XHTML"-style tags in all browsers
|
var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(),
|
||||||
elem = elem.replace(rxhtmlTag, "<$1></$2>");
|
wrap = wrapMap[ tag ] || wrapMap._default,
|
||||||
|
depth = wrap[0],
|
||||||
|
div = context.createElement("div");
|
||||||
|
|
||||||
// Trim whitespace, otherwise indexOf won't work as expected
|
// Go to html and back, then peel off extra wrappers
|
||||||
var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(),
|
div.innerHTML = wrap[1] + elem + wrap[2];
|
||||||
wrap = wrapMap[ tag ] || wrapMap._default,
|
|
||||||
depth = wrap[0],
|
|
||||||
div = context.createElement("div");
|
|
||||||
|
|
||||||
// Go to html and back, then peel off extra wrappers
|
// Move to the right depth
|
||||||
div.innerHTML = wrap[1] + elem + wrap[2];
|
while ( depth-- ) {
|
||||||
|
div = div.lastChild;
|
||||||
|
}
|
||||||
|
|
||||||
// Move to the right depth
|
// Remove IE's autoinserted <tbody> from table fragments
|
||||||
while ( depth-- ) {
|
if ( !jQuery.support.tbody ) {
|
||||||
div = div.lastChild;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove IE's autoinserted <tbody> from table fragments
|
// String was a <table>, *may* have spurious <tbody>
|
||||||
if ( !jQuery.support.tbody ) {
|
var hasBody = rtbody.test(elem),
|
||||||
|
tbody = tag === "table" && !hasBody ?
|
||||||
|
div.firstChild && div.firstChild.childNodes :
|
||||||
|
|
||||||
// String was a <table>, *may* have spurious <tbody>
|
// String was a bare <thead> or <tfoot>
|
||||||
var hasBody = rtbody.test(elem),
|
wrap[1] === "<table>" && !hasBody ?
|
||||||
tbody = tag === "table" && !hasBody ?
|
div.childNodes :
|
||||||
div.firstChild && div.firstChild.childNodes :
|
[];
|
||||||
|
|
||||||
// String was a bare <thead> or <tfoot>
|
for ( var j = tbody.length - 1; j >= 0 ; --j ) {
|
||||||
wrap[1] === "<table>" && !hasBody ?
|
if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
|
||||||
div.childNodes :
|
tbody[ j ].parentNode.removeChild( tbody[ j ] );
|
||||||
[];
|
}
|
||||||
|
|
||||||
for ( var j = tbody.length - 1; j >= 0 ; --j ) {
|
|
||||||
if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
|
|
||||||
tbody[ j ].parentNode.removeChild( tbody[ j ] );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
// IE completely kills leading whitespace when innerHTML is used
|
||||||
|
if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
|
||||||
|
div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
|
||||||
|
}
|
||||||
|
|
||||||
// IE completely kills leading whitespace when innerHTML is used
|
elem = div.childNodes;
|
||||||
if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
|
|
||||||
div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
elem = div.childNodes;
|
// Resets defaultChecked for any radios and checkboxes
|
||||||
|
// about to be appended to the DOM in IE 6/7 (#8060)
|
||||||
|
var len;
|
||||||
|
if ( !jQuery.support.appendChecked ) {
|
||||||
|
if ( elem[0] && typeof (len = elem.length) === "number" ) {
|
||||||
|
for ( i = 0; i < len; i++ ) {
|
||||||
|
findInputs( elem[i] );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
findInputs( elem );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( elem.nodeType ) {
|
if ( elem.nodeType ) {
|
||||||
|
|
|
@ -186,6 +186,14 @@ jQuery.support = (function() {
|
||||||
support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
|
support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
|
||||||
div.innerHTML = "";
|
div.innerHTML = "";
|
||||||
|
|
||||||
|
// Check if a disconnected checkbox will retain its checked
|
||||||
|
// value of true after appended to the DOM
|
||||||
|
input = document.createElement("input");
|
||||||
|
input.setAttribute("type", "checkbox");
|
||||||
|
input.checked = true;
|
||||||
|
div.appendChild( input );
|
||||||
|
support.appendChecked = input.checked;
|
||||||
|
|
||||||
// Check if div with explicit width and no margin-right incorrectly
|
// Check if div with explicit width and no margin-right incorrectly
|
||||||
// gets computed margin-right based on width of container. For more
|
// gets computed margin-right based on width of container. For more
|
||||||
// info see bug #3333
|
// info see bug #3333
|
||||||
|
|
|
@ -227,7 +227,7 @@ test("unwrap()", function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
var testAppend = function(valueObj) {
|
var testAppend = function(valueObj) {
|
||||||
expect(37);
|
expect(40);
|
||||||
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" );
|
||||||
|
@ -330,6 +330,20 @@ var testAppend = function(valueObj) {
|
||||||
d.contents().appendTo("#nonnodes");
|
d.contents().appendTo("#nonnodes");
|
||||||
d.remove();
|
d.remove();
|
||||||
ok( jQuery("#nonnodes").contents().length >= 2, "Check node,textnode,comment append cleanup worked" );
|
ok( jQuery("#nonnodes").contents().length >= 2, "Check node,textnode,comment append cleanup worked" );
|
||||||
|
|
||||||
|
QUnit.reset();
|
||||||
|
var $input = jQuery("<input />").attr({ "type": "checkbox", "checked": true }).appendTo('#testForm');
|
||||||
|
equals( $input[0].checked, true, "A checked checkbox that is appended stays checked" );
|
||||||
|
|
||||||
|
QUnit.reset();
|
||||||
|
var $radios = jQuery("input:radio[name='R1']"),
|
||||||
|
$radioNot = jQuery("<input type='radio' name='R1' checked='checked'/>").insertAfter( $radios ),
|
||||||
|
$radio = $radios.eq(1).click();
|
||||||
|
$radioNot[0].checked = false;
|
||||||
|
$radios.parent().wrap("<div></div>");
|
||||||
|
equals( $radio[0].checked, true, "Reappending radios uphold which radio is checked" );
|
||||||
|
equals( $radioNot[0].checked, false, "Reappending radios uphold not being checked" );
|
||||||
|
QUnit.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
test("append(String|Element|Array<Element>|jQuery)", function() {
|
test("append(String|Element|Array<Element>|jQuery)", function() {
|
||||||
|
|
Loading…
Add table
Reference in a new issue