]> source.dussan.org Git - jquery.git/commitdiff
Attributes: fix IE8 issues
authorGilad Peleg <giladp007@gmail.com>
Tue, 23 Jun 2015 16:42:25 +0000 (19:42 +0300)
committerOleg Gaidarenko <markelog@gmail.com>
Thu, 25 Jun 2015 00:07:24 +0000 (03:07 +0300)
Follow-up for d0388e9e806ca3b30e7bbaaa1c336b7c98dc5f88

src/attributes/attr.js
src/attributes/prop.js

index 07576738a10dacee124bfa524a7ffa66b1b9b73e..689b567cb375901824331f968d927b1c248f69a7 100644 (file)
@@ -3,11 +3,14 @@ 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 ) {
@@ -15,7 +18,7 @@ jQuery.fn.extend({
        },
 
        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 + "" );
+               }
+       };
+}
 
 });
index 4c7b51e8c8fea821dda74f068e9f60d8be00f802..9fad50e41e31691c90673d06d274efcf167fc978 100644 (file)
@@ -5,7 +5,8 @@ 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 ) {
@@ -13,8 +14,13 @@ jQuery.fn.extend({
        },
 
        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;
                }