Merge branch '2.0-attributes-rebased'

* 2.0-attributes-rebased:
  2.0: Remove getSetAttribute and getSetInput and oldIE attroperties hooks
  Resolved conflict
  2.0: Remove style->cssText attroproties fallback
  Remove outdated support tests
  2.0: Remove support.optSelected
  2.0: Remove oldIE enctype propFix
This commit is contained in:
Rick Waldron 2012-12-31 13:26:27 -05:00
commit a205aac7f0
4 changed files with 8 additions and 530 deletions

View File

@ -3,10 +3,7 @@ var nodeHook, boolHook,
rreturn = /\r/g,
rfocusable = /^(?:input|select|textarea|button|object)$/i,
rclickable = /^(?:a|area)$/i,
rboolean = /^(?:checked|selected|autofocus|autoplay|async|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped)$/i,
ruseDefault = /^(?:checked|selected)$/i,
getSetAttribute = jQuery.support.getSetAttribute,
getSetInput = jQuery.support.input;
rboolean = /^(?:checked|selected|autofocus|autoplay|async|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped)$/i;
jQuery.fn.extend({
attr: function( name, value ) {
@ -349,22 +346,12 @@ jQuery.extend({
propName = jQuery.propFix[ name ] || name;
// Boolean attributes get special treatment (#10870)
// Set corresponding property to false for boolean attributes
if ( rboolean.test( name ) ) {
// Set corresponding property to false for boolean attributes
// Also clear defaultChecked/defaultSelected (if appropriate) for IE<8
if ( !getSetAttribute && ruseDefault.test( name ) ) {
elem[ jQuery.camelCase( "default-" + name ) ] =
elem[ propName ] = false;
} else {
elem[ propName ] = false;
}
// See #9699 for explanation of this approach (setting first, then removal)
} else {
jQuery.attr( elem, name, "" );
elem[ propName ] = false;
}
elem.removeAttribute( getSetAttribute ? name : propName );
elem.removeAttribute( name );
}
}
},
@ -456,26 +443,7 @@ jQuery.extend({
// Hook for boolean attributes
boolHook = {
get: function( elem, name ) {
var
// Use .prop to determine if this attribute is understood as boolean
prop = jQuery.prop( elem, name ),
// Fetch it accordingly
attr = typeof prop === "boolean" && elem.getAttribute( name ),
detail = typeof prop === "boolean" ?
getSetInput && getSetAttribute ?
attr != null :
// oldIE fabricates an empty string for missing boolean attributes
// and conflates checked/selected into attroperties
ruseDefault.test( name ) ?
elem[ jQuery.camelCase( "default-" + name ) ] :
!!attr :
// fetch an attribute node for properties not recognized as boolean
elem.getAttributeNode( name );
return detail && detail.value !== false ?
return elem.getAttribute( name ) !== null ?
name.toLowerCase() :
undefined;
},
@ -483,158 +451,13 @@ boolHook = {
if ( value === false ) {
// Remove boolean attributes when set to false
jQuery.removeAttr( elem, name );
} else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
// IE<8 needs the *property* name
elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name );
// Use defaultChecked and defaultSelected for oldIE
} else {
elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true;
elem.setAttribute( name, name );
}
return name;
}
};
// fix oldIE value attroperty
if ( !getSetInput || !getSetAttribute ) {
jQuery.attrHooks.value = {
get: function( elem, name ) {
var ret = elem.getAttributeNode( name );
return jQuery.nodeName( elem, "input" ) ?
// Ignore the value *property* by using defaultValue
elem.defaultValue :
ret && ret.specified ? ret.value : undefined;
},
set: function( elem, value, name ) {
if ( jQuery.nodeName( elem, "input" ) ) {
// Does not return so that setAttribute is also used
elem.defaultValue = value;
} else {
// Use nodeHook if defined (#1954); otherwise setAttribute is fine
return nodeHook && nodeHook.set( elem, value, name );
}
}
};
}
// IE6/7 do not support getting/setting some attributes with get/setAttribute
if ( !getSetAttribute ) {
// Use this for any attribute in IE6/7
// This fixes almost every IE6/7 issue
nodeHook = jQuery.valHooks.button = {
get: function( elem, name ) {
var ret = elem.getAttributeNode( name );
return ret && ( name === "id" || name === "name" || name === "coords" ? ret.value !== "" : ret.specified ) ?
ret.value :
undefined;
},
set: function( elem, value, name ) {
// Set the existing or create a new attribute node
var ret = elem.getAttributeNode( name );
if ( !ret ) {
elem.setAttributeNode(
(ret = elem.ownerDocument.createAttribute( name ))
);
}
ret.value = value += "";
// Break association with cloned elements by also using setAttribute (#9646)
return name === "value" || value === elem.getAttribute( name ) ?
value :
undefined;
}
};
// Set contenteditable to false on removals(#10429)
// Setting to empty string throws an error as an invalid value
jQuery.attrHooks.contenteditable = {
get: nodeHook.get,
set: function( elem, value, name ) {
nodeHook.set( elem, value === "" ? false : value, name );
}
};
// Set width and height to auto instead of 0 on empty string( Bug #8150 )
// This is for removals
jQuery.each([ "width", "height" ], function( i, name ) {
jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
set: function( elem, value ) {
if ( value === "" ) {
elem.setAttribute( name, "auto" );
return value;
}
}
});
});
}
// Some attributes require a special call on IE
// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
if ( !jQuery.support.hrefNormalized ) {
jQuery.each([ "href", "src", "width", "height" ], function( i, name ) {
jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
get: function( elem ) {
var ret = elem.getAttribute( name, 2 );
return ret == null ? undefined : ret;
}
});
});
// href/src property should get the full normalized URL (#10299/#12915)
jQuery.each([ "href", "src" ], function( i, name ) {
jQuery.propHooks[ name ] = {
get: function( elem ) {
return elem.getAttribute( name, 4 );
}
};
});
}
if ( !jQuery.support.style ) {
jQuery.attrHooks.style = {
get: function( elem ) {
// Return undefined in the case of empty string
// Note: IE uppercases css property names, but if we were to .toLowerCase()
// .cssText, that would destroy case senstitivity in URL's, like in "background"
return elem.style.cssText || undefined;
},
set: function( elem, value ) {
return ( elem.style.cssText = value + "" );
}
};
}
// Safari mis-reports the default selected property of an option
// Accessing the parent's selectedIndex property fixes it
if ( !jQuery.support.optSelected ) {
jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {
get: function( elem ) {
var parent = elem.parentNode;
if ( parent ) {
parent.selectedIndex;
// Make sure that it also works with optgroups, see #5701
if ( parent.parentNode ) {
parent.parentNode.selectedIndex;
}
}
return null;
}
});
}
// IE6/7 call enctype encoding
if ( !jQuery.support.enctype ) {
jQuery.propFix.enctype = "encoding";
}
// Radios and checkboxes getter/setter
if ( !jQuery.support.checkOn ) {
jQuery.each([ "radio", "checkbox" ], function() {

View File

@ -5,7 +5,7 @@ jQuery.support = (function() {
// Setup
div.setAttribute( "className", "t" );
div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
div.innerHTML = " <link/><table></table><a>a</a><input type='checkbox'/>";
// Support tests won't run in some limited or non-browser environments
all = div.getElementsByTagName("*");
@ -19,7 +19,7 @@ jQuery.support = (function() {
opt = select.appendChild( document.createElement("option") );
input = div.getElementsByTagName("input")[ 0 ];
a.style.cssText = "top:1px;float:left;opacity:.5";
a.style.cssText = "float:left;opacity:.5";
support = {
// Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
getSetAttribute: div.className !== "t",
@ -35,14 +35,6 @@ jQuery.support = (function() {
// This requires a wrapper element in IE
htmlSerialize: !!div.getElementsByTagName("link").length,
// Get the style information from getAttribute
// (IE uses .cssText instead)
style: /top/.test( a.getAttribute("style") ),
// Make sure that URLs aren't manipulated
// (IE normalizes it by default)
hrefNormalized: a.getAttribute("href") === "/a",
// Make sure that element opacity exists
// (IE uses filter instead)
// Use a regex to work around a WebKit issue. See #5145
@ -55,13 +47,6 @@ jQuery.support = (function() {
// Check the default checkbox/radio value ("" on WebKit; "on" elsewhere)
checkOn: !!input.value,
// 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)
optSelected: opt.selected,
// Tests for enctype support on a form (#6743)
enctype: !!document.createElement("form").enctype,
// Makes sure cloning an html5 element does not cause problems
// Where outerHTML is undefined, this still works
html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav></:nav>",
@ -95,11 +80,6 @@ jQuery.support = (function() {
support.deleteExpando = false;
}
// Check if we can trust getAttribute("value")
input = document.createElement("input");
input.setAttribute( "value", "" );
support.input = input.getAttribute( "value" ) === "";
// Check if an input maintains its value after becoming a radio
input.value = "t";
input.setAttribute( "type", "radio" );

View File

@ -46,10 +46,6 @@ test( "jQuery.propFix integrity test", function() {
"contenteditable": "contentEditable"
};
if ( !jQuery.support.enctype ) {
props.enctype = "encoding";
}
deepEqual( props, jQuery.propFix, "jQuery.propFix passes integrity check" );
});

View File

@ -43,324 +43,3 @@ testIframeWithCallback( "box-sizing does not affect jQuery.support.shrinkWrapBlo
expect( 1 );
strictEqual( shrinkWrapBlocks, jQuery.support.shrinkWrapBlocks, "jQuery.support.shrinkWrapBlocks properties are the same" );
});
(function() {
var expected,
userAgent = window.navigator.userAgent;
// These tests do not have to stay
// They are here to help with upcoming support changes for 1.8
if ( /chrome/i.test( userAgent ) ) {
expected = {
"leadingWhitespace":true,
"tbody":true,
"htmlSerialize":true,
"style":true,
"hrefNormalized":true,
"opacity":true,
"cssFloat":true,
"checkOn":true,
"optSelected":true,
"getSetAttribute":true,
"enctype":true,
"html5Clone":true,
"submitBubbles":true,
"changeBubbles":true,
"focusinBubbles":false,
"deleteExpando":true,
"noCloneEvent":true,
"inlineBlockNeedsLayout":false,
"shrinkWrapBlocks":false,
"reliableMarginRight":true,
"noCloneChecked":true,
"optDisabled":true,
"radioValue":true,
"checkClone":true,
"appendChecked":true,
"boxModel":true,
"reliableHiddenOffsets":true,
"ajax":true,
"cors":true,
"doesNotIncludeMarginInBodyOffset":true
};
} else if ( /opera.*version\/12\.1/i.test( userAgent ) ) {
expected = {
"leadingWhitespace":true,
"tbody":true,
"htmlSerialize":true,
"style":true,
"hrefNormalized":true,
"opacity":true,
"cssFloat":true,
"checkOn":true,
"optSelected":true,
"getSetAttribute":true,
"enctype":true,
"html5Clone":true,
"submitBubbles":true,
"changeBubbles":true,
"focusinBubbles":false,
"deleteExpando":true,
"noCloneEvent":true,
"inlineBlockNeedsLayout":false,
"shrinkWrapBlocks":false,
"reliableMarginRight":true,
"noCloneChecked":true,
"optDisabled":true,
"radioValue":false,
"checkClone":true,
"appendChecked":true,
"boxModel":true,
"reliableHiddenOffsets":true,
"ajax":true,
"cors":true,
"doesNotIncludeMarginInBodyOffset":true
};
} else if ( /msie 10\.0/i.test( userAgent ) ) {
expected = {
"leadingWhitespace":true,
"tbody":true,
"htmlSerialize":true,
"style":true,
"hrefNormalized":true,
"opacity":true,
"cssFloat":true,
"checkOn":true,
"optSelected":false,
"getSetAttribute":true,
"enctype":true,
"html5Clone":true,
"submitBubbles":true,
"changeBubbles":true,
"focusinBubbles":true,
"deleteExpando":true,
"noCloneEvent":true,
"inlineBlockNeedsLayout":false,
"shrinkWrapBlocks":false,
"reliableMarginRight":true,
"noCloneChecked":false,
"optDisabled":true,
"radioValue":false,
"checkClone":true,
"appendChecked":true,
"boxModel":true,
"reliableHiddenOffsets":true,
"ajax":true,
"cors":true,
"doesNotIncludeMarginInBodyOffset":true
};
} else if ( /msie 9\.0/i.test( userAgent ) ) {
expected = {
"leadingWhitespace":true,
"tbody":true,
"htmlSerialize":true,
"style":true,
"hrefNormalized":true,
"opacity":true,
"cssFloat":true,
"checkOn":true,
"optSelected":false,
"getSetAttribute":true,
"enctype":true,
"html5Clone":true,
"submitBubbles":true,
"changeBubbles":true,
"focusinBubbles":true,
"deleteExpando":true,
"noCloneEvent":true,
"inlineBlockNeedsLayout":false,
"shrinkWrapBlocks":false,
"reliableMarginRight":true,
"noCloneChecked":false,
"optDisabled":true,
"radioValue":false,
"checkClone":true,
"appendChecked":true,
"boxModel":true,
"reliableHiddenOffsets":true,
"ajax":true,
"cors":false,
"doesNotIncludeMarginInBodyOffset":true
};
} else if ( /msie 8\.0/i.test( userAgent ) ) {
expected = {
"leadingWhitespace":false,
"tbody":true,
"htmlSerialize":false,
"style":false,
"hrefNormalized":true,
"opacity":false,
"cssFloat":false,
"checkOn":true,
"optSelected":false,
"getSetAttribute":true,
"enctype":true,
"html5Clone":false,
"submitBubbles":false,
"changeBubbles":false,
"focusinBubbles":true,
"deleteExpando":false,
"noCloneEvent":false,
"inlineBlockNeedsLayout":false,
"shrinkWrapBlocks":false,
"reliableMarginRight":true,
"noCloneChecked":false,
"optDisabled":true,
"radioValue":false,
"checkClone":true,
"appendChecked":true,
"boxModel":true,
"reliableHiddenOffsets":false,
"ajax":true,
"cors":false,
"doesNotIncludeMarginInBodyOffset":true
};
} else if ( /msie 7\.0/i.test( userAgent ) ) {
expected = {
"ajax": true,
"appendChecked": false,
"boxModel": true,
"changeBubbles": false,
"checkClone": false,
"checkOn": true,
"cors": false,
"cssFloat": false,
"deleteExpando": false,
"doesNotIncludeMarginInBodyOffset": true,
"enctype": true,
"focusinBubbles": true,
"getSetAttribute": false,
"hrefNormalized": false,
"html5Clone": false,
"htmlSerialize": false,
"inlineBlockNeedsLayout": true,
"leadingWhitespace": false,
"noCloneChecked": false,
"noCloneEvent": false,
"opacity": false,
"optDisabled": true,
"optSelected": false,
"radioValue": false,
"reliableHiddenOffsets": false,
"reliableMarginRight": true,
"shrinkWrapBlocks": false,
"submitBubbles": false,
"tbody": false,
"style": false
};
} else if ( /msie 6\.0/i.test( userAgent ) ) {
expected = {
"leadingWhitespace":false,
"tbody":false,
"htmlSerialize":false,
"style":false,
"hrefNormalized":false,
"opacity":false,
"cssFloat":false,
"checkOn":true,
"optSelected":false,
"getSetAttribute":false,
"enctype":true,
"html5Clone":false,
"submitBubbles":false,
"changeBubbles":false,
"focusinBubbles":true,
"deleteExpando":false,
"noCloneEvent":false,
"inlineBlockNeedsLayout":true,
"shrinkWrapBlocks":true,
"reliableMarginRight":true,
"noCloneChecked":false,
"optDisabled":true,
"radioValue":false,
"checkClone":false,
"appendChecked":false,
"boxModel":true,
"reliableHiddenOffsets":false,
"ajax":true,
"cors":false,
"doesNotIncludeMarginInBodyOffset":true
};
} else if ( /5\.1\.1 safari/i.test( userAgent ) ) {
expected = {
"leadingWhitespace":true,
"tbody":true,
"htmlSerialize":true,
"style":true,
"hrefNormalized":true,
"opacity":true,
"cssFloat":true,
"checkOn":false,
"optSelected":true,
"getSetAttribute":true,
"enctype":true,
"html5Clone":true,
"submitBubbles":true,
"changeBubbles":true,
"focusinBubbles":false,
"deleteExpando":true,
"noCloneEvent":true,
"inlineBlockNeedsLayout":false,
"shrinkWrapBlocks":false,
"reliableMarginRight":true,
"noCloneChecked":true,
"optDisabled":true,
"radioValue":true,
"checkClone":false,
"appendChecked":false,
"boxModel":true,
"reliableHiddenOffsets":true,
"ajax":true,
"cors":true,
"doesNotIncludeMarginInBodyOffset":true
};
} else if ( /firefox/i.test( userAgent ) ) {
expected = {
"leadingWhitespace":true,
"tbody":true,
"htmlSerialize":true,
"style":true,
"hrefNormalized":true,
"opacity":true,
"cssFloat":true,
"checkOn":true,
"optSelected":true,
"getSetAttribute":true,
"enctype":true,
"html5Clone":true,
"submitBubbles":true,
"changeBubbles":true,
"focusinBubbles":false,
"deleteExpando":true,
"noCloneEvent":true,
"inlineBlockNeedsLayout":false,
"shrinkWrapBlocks":false,
"reliableMarginRight":true,
"noCloneChecked":true,
"optDisabled":true,
"radioValue":true,
"checkClone":true,
"appendChecked":true,
"boxModel":true,
"reliableHiddenOffsets":true,
"ajax":true,
"cors":true,
"doesNotIncludeMarginInBodyOffset":true
};
}
if ( expected ) {
test("Verify that the support tests resolve as expected per browser", function() {
expect( 30 );
for ( var i in expected ) {
if ( jQuery.ajax || i !== "ajax" && i !== "cors" ) {
equal( jQuery.support[i], expected[i], "jQuery.support['" + i + "']: " + jQuery.support[i] + ", expected['" + i + "']: " + expected[i]);
} else {
ok( true, "no ajax; skipping jQuery.support['" + i + "']" );
}
}
});
}
})();