Docs: Align CONTRIBUTING.md with `3.x-stable`
[jquery.git] / src / attributes / prop.js
blob7eef6c8f76fe5f9a6b3bb8d23d207b260a412e7d
1 import { jQuery } from "../core.js";
2 import { access } from "../core/access.js";
3 import { isIE } from "../var/isIE.js";
5 var rfocusable = /^(?:input|select|textarea|button)$/i,
6         rclickable = /^(?:a|area)$/i;
8 jQuery.fn.extend( {
9         prop: function( name, value ) {
10                 return access( this, jQuery.prop, name, value, arguments.length > 1 );
11         },
13         removeProp: function( name ) {
14                 return this.each( function() {
15                         delete this[ jQuery.propFix[ name ] || name ];
16                 } );
17         }
18 } );
20 jQuery.extend( {
21         prop: function( elem, name, value ) {
22                 var ret, hooks,
23                         nType = elem.nodeType;
25                 // Don't get/set properties on text, comment and attribute nodes
26                 if ( nType === 3 || nType === 8 || nType === 2 ) {
27                         return;
28                 }
30                 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
32                         // Fix name and attach hooks
33                         name = jQuery.propFix[ name ] || name;
34                         hooks = jQuery.propHooks[ name ];
35                 }
37                 if ( value !== undefined ) {
38                         if ( hooks && "set" in hooks &&
39                                 ( ret = hooks.set( elem, value, name ) ) !== undefined ) {
40                                 return ret;
41                         }
43                         return ( elem[ name ] = value );
44                 }
46                 if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
47                         return ret;
48                 }
50                 return elem[ name ];
51         },
53         propHooks: {
54                 tabIndex: {
55                         get: function( elem ) {
57                                 // Support: IE <=9 - 11+
58                                 // elem.tabIndex doesn't always return the
59                                 // correct value when it hasn't been explicitly set
60                                 // Use proper attribute retrieval (trac-12072)
61                                 var tabindex = elem.getAttribute( "tabindex" );
63                                 if ( tabindex ) {
64                                         return parseInt( tabindex, 10 );
65                                 }
67                                 if (
68                                         rfocusable.test( elem.nodeName ) ||
70                                         // href-less anchor's `tabIndex` property value is `0` and
71                                         // the `tabindex` attribute value: `null`. We want `-1`.
72                                         rclickable.test( elem.nodeName ) && elem.href
73                                 ) {
74                                         return 0;
75                                 }
77                                 return -1;
78                         }
79                 }
80         },
82         propFix: {
83                 "for": "htmlFor",
84                 "class": "className"
85         }
86 } );
88 // Support: IE <=11+
89 // Accessing the selectedIndex property forces the browser to respect
90 // setting selected on the option. The getter ensures a default option
91 // is selected when in an optgroup. ESLint rule "no-unused-expressions"
92 // is disabled for this code since it considers such accessions noop.
93 if ( isIE ) {
94         jQuery.propHooks.selected = {
95                 get: function( elem ) {
97                         var parent = elem.parentNode;
98                         if ( parent && parent.parentNode ) {
99                                 // eslint-disable-next-line no-unused-expressions
100                                 parent.parentNode.selectedIndex;
101                         }
102                         return null;
103                 },
104                 set: function( elem ) {
107                         var parent = elem.parentNode;
108                         if ( parent ) {
109                                 // eslint-disable-next-line no-unused-expressions
110                                 parent.selectedIndex;
112                                 if ( parent.parentNode ) {
113                                         // eslint-disable-next-line no-unused-expressions
114                                         parent.parentNode.selectedIndex;
115                                 }
116                         }
117                 }
118         };
121 jQuery.each( [
122         "tabIndex",
123         "readOnly",
124         "maxLength",
125         "cellSpacing",
126         "cellPadding",
127         "rowSpan",
128         "colSpan",
129         "useMap",
130         "frameBorder",
131         "contentEditable"
132 ], function() {
133         jQuery.propFix[ this.toLowerCase() ] = this;
134 } );