Permalink
Browse files

Attributes: fix IE8 issues

Follow-up for d0388e9
  • Loading branch information...
pgilad authored and markelog committed Jun 23, 2015
1 parent d0388e9 commit f2bcf87c25155fd8361c744c684a0d526bd184a5
Showing with 105 additions and 24 deletions.
  1. +77 −16 src/attributes/attr.js
  2. +28 −8 src/attributes/prop.js
View
@@ -3,19 +3,22 @@ define([
"../core/access",
"./support",
"../var/rnotwhite",
+ "./val",
"../selector"
], function( jQuery, access, support, rnotwhite ) {
var boolHook,
- attrHandle = jQuery.expr.attrHandle;
+ attrHandle = jQuery.expr.attrHandle,
+ ruseDefault = /^(?:checked|selected)$/i,
+ getSetInput = support.input;
jQuery.fn.extend({
attr: function( name, value ) {
return access( this, jQuery.attr, name, value, arguments.length > 1 );
},
removeAttr: function( name ) {
- return this.each(function() {
+ return this.each( function() {
jQuery.removeAttr( this, name );
});
}
@@ -74,6 +77,9 @@ jQuery.extend({
set: function( elem, value ) {
if ( !support.radioValue && value === "radio" &&
jQuery.nodeName( elem, "input" ) ) {
+
+ // Setting the type on a radio button after the value resets the value in IE8-9
+ // Reset value to default in case type is set after value during creation
var val = elem.value;
elem.setAttribute( "type", value );
if ( val ) {
@@ -98,7 +104,15 @@ jQuery.extend({
if ( jQuery.expr.match.bool.test( name ) ) {
// Set corresponding property to false
- elem[ propName ] = false;
+ if ( getSetInput || !ruseDefault.test( name ) ) {
+ elem[ propName ] = false;
+
+ // Support: IE<9
+ // Also clear defaultChecked/defaultSelected (if appropriate)
+ } else {
+ elem[ jQuery.camelCase( "default-" + name ) ] =
+ elem[ propName ] = false;
+ }
}
elem.removeAttribute( name );
@@ -111,30 +125,77 @@ jQuery.extend({
boolHook = {
set: function( elem, value, name ) {
if ( value === false ) {
+
// Remove boolean attributes when set to false
jQuery.removeAttr( elem, name );
+ } else if ( getSetInput || !ruseDefault.test( name ) ) {
+ elem.setAttribute( jQuery.propFix[ name ] || name, name );
+
} else {
- elem.setAttribute( name, name );
+
+ // Support: IE<9
+ // Use defaultChecked and defaultSelected for oldIE
+ elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true;
}
return name;
}
};
+
jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
var getter = attrHandle[ name ] || jQuery.find.attr;
- attrHandle[ name ] = function( elem, name, isXML ) {
- var ret, handle;
- if ( !isXML ) {
- // Avoid an infinite loop by temporarily removing this function from the getter
- handle = attrHandle[ name ];
- attrHandle[ name ] = ret;
- ret = getter( elem, name, isXML ) != null ?
- name.toLowerCase() :
- null;
- attrHandle[ name ] = handle;
+ if ( getSetInput || !ruseDefault.test( name ) ) {
+ attrHandle[ name ] = function( elem, name, isXML ) {
+ var ret, handle;
+ if ( !isXML ) {
+
+ // Avoid an infinite loop by temporarily removing this function from the getter
+ handle = attrHandle[ name ];
+ attrHandle[ name ] = ret;
+ ret = getter( elem, name, isXML ) != null ?
+ name.toLowerCase() :
+ null;
+ attrHandle[ name ] = handle;
+ }
+ return ret;
+ };
+ } else {
+ attrHandle[ name ] = function( elem, name, isXML ) {
+ if ( !isXML ) {
+ return elem[ jQuery.camelCase( "default-" + name ) ] ?
+ name.toLowerCase() :
+ null;
+ }
+ };
+ }
+});
+
+// fix oldIE attroperties
+if ( !getSetInput ) {
+ jQuery.attrHooks.value = {
+ set: function( elem, value ) {
+ if ( jQuery.nodeName( elem, "input" ) ) {
+
+ // Does not return so that setAttribute is also used
+ elem.defaultValue = value;
+ }
}
- return ret;
};
-});
+}
+
+if ( !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 sensitivity in URL's, like in "background"
+ return elem.style.cssText || undefined;
+ },
+ set: function( elem, value ) {
+ return ( elem.style.cssText = value + "" );
+ }
+ };
+}
});
View
@@ -5,16 +5,22 @@ define([
"../selector"
], function( jQuery, access, support ) {
-var rfocusable = /^(?:input|select|textarea|button)$/i;
+var rfocusable = /^(?:input|select|textarea|button|object)$/i,
+ rclickable = /^(?:a|area)$/i;
jQuery.fn.extend({
prop: function( name, value ) {
return access( this, jQuery.prop, name, value, arguments.length > 1 );
},
removeProp: function( name ) {
+ name = jQuery.propFix[ name ] || name;
return this.each(function() {
- delete this[ jQuery.propFix[ name ] || name ];
+ // try/catch handles cases where IE balks (such as removing a property on window)
+ try {
+ this[ name ] = undefined;
+ delete this[ name ];
+ } catch ( e ) {}
});
}
});
@@ -55,10 +61,18 @@ jQuery.extend({
propHooks: {
tabIndex: {
get: function( elem ) {
- return elem.hasAttribute( "tabindex" ) ||
- rfocusable.test( elem.nodeName ) || elem.href ?
- elem.tabIndex :
- -1;
+ // elem.tabIndex doesn't always return the
+ // correct value when it hasn't been explicitly set
+ // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
+ // Use proper attribute retrieval(#12072)
+ var tabindex = jQuery.find.attr( elem, "tabindex" );
+
+ return tabindex ?
+ parseInt( tabindex, 10 ) :
+ rfocusable.test( elem.nodeName ) ||
+ rclickable.test( elem.nodeName ) && elem.href ?
+ 0 :
+ -1;
}
}
},
@@ -73,8 +87,14 @@ if ( !support.optSelected ) {
jQuery.propHooks.selected = {
get: function( elem ) {
var parent = elem.parentNode;
- if ( parent && parent.parentNode ) {
- parent.parentNode.selectedIndex;
+
+ if ( parent ) {
+ parent.selectedIndex;
+
+ // Make sure that it also works with optgroups, see #5701
+ if ( parent.parentNode ) {
+ parent.parentNode.selectedIndex;
+ }
}
return null;
}

0 comments on commit f2bcf87

Please sign in to comment.