Skip to content

Commit d0388e9

Browse files
pgiladmarkelog
authored andcommitted
Core: organize prop & attr code to be similar
Ref 5153b53 Closes gh-2426
1 parent 6df1bf9 commit d0388e9

File tree

2 files changed

+81
-154
lines changed

2 files changed

+81
-154
lines changed

src/attributes/attr.js

Lines changed: 50 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
define([
22
"../core",
3-
"../var/rnotwhite",
43
"../core/access",
54
"./support",
6-
"./val",
5+
"../var/rnotwhite",
76
"../selector"
8-
], function( jQuery, rnotwhite, access, support ) {
7+
], function( jQuery, access, support, rnotwhite ) {
98

109
var boolHook,
11-
attrHandle = jQuery.expr.attrHandle,
12-
ruseDefault = /^(?:checked|selected)$/i,
13-
getSetInput = support.input;
10+
attrHandle = jQuery.expr.attrHandle;
1411

1512
jQuery.fn.extend({
1613
attr: function( name, value ) {
@@ -26,10 +23,10 @@ jQuery.fn.extend({
2623

2724
jQuery.extend({
2825
attr: function( elem, name, value ) {
29-
var hooks, ret,
26+
var ret, hooks,
3027
nType = elem.nodeType;
3128

32-
// don't get/set attributes on text, comment and attribute nodes
29+
// Don't get/set attributes on text, comment and attribute nodes
3330
if ( nType === 3 || nType === 8 || nType === 2 ) {
3431
return;
3532
}
@@ -48,30 +45,43 @@ jQuery.extend({
4845
}
4946

5047
if ( value !== undefined ) {
51-
5248
if ( value === null ) {
5349
jQuery.removeAttr( elem, name );
50+
return;
51+
}
5452

55-
} else if ( hooks && "set" in hooks &&
56-
(ret = hooks.set( elem, value, name )) !== undefined ) {
57-
53+
if ( hooks && "set" in hooks &&
54+
( ret = hooks.set( elem, value, name ) ) !== undefined ) {
5855
return ret;
59-
60-
} else {
61-
elem.setAttribute( name, value + "" );
62-
return value;
6356
}
6457

65-
} else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
58+
elem.setAttribute( name, value + "" );
59+
return value;
60+
}
61+
62+
if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
6663
return ret;
64+
}
6765

68-
} else {
69-
ret = jQuery.find.attr( elem, name );
66+
ret = jQuery.find.attr( elem, name );
7067

71-
// Non-existent attributes return null, we normalize to undefined
72-
return ret == null ?
73-
undefined :
74-
ret;
68+
// Non-existent attributes return null, we normalize to undefined
69+
return ret == null ? undefined : ret;
70+
},
71+
72+
attrHooks: {
73+
type: {
74+
set: function( elem, value ) {
75+
if ( !support.radioValue && value === "radio" &&
76+
jQuery.nodeName( elem, "input" ) ) {
77+
var val = elem.value;
78+
elem.setAttribute( "type", value );
79+
if ( val ) {
80+
elem.value = val;
81+
}
82+
return value;
83+
}
84+
}
7585
}
7686
},
7787

@@ -81,116 +91,50 @@ jQuery.extend({
8191
attrNames = value && value.match( rnotwhite );
8292

8393
if ( attrNames && elem.nodeType === 1 ) {
84-
while ( (name = attrNames[i++]) ) {
94+
while ( ( name = attrNames[i++] ) ) {
8595
propName = jQuery.propFix[ name ] || name;
8696

8797
// Boolean attributes get special treatment (#10870)
8898
if ( jQuery.expr.match.bool.test( name ) ) {
99+
89100
// Set corresponding property to false
90-
if ( getSetInput || !ruseDefault.test( name ) ) {
91-
elem[ propName ] = false;
92-
// Support: IE<9
93-
// Also clear defaultChecked/defaultSelected (if appropriate)
94-
} else {
95-
elem[ jQuery.camelCase( "default-" + name ) ] =
96-
elem[ propName ] = false;
97-
}
101+
elem[ propName ] = false;
98102
}
99103

100104
elem.removeAttribute( name );
101105
}
102106
}
103-
},
104-
105-
attrHooks: {
106-
type: {
107-
set: function( elem, value ) {
108-
if ( !support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
109-
// Setting the type on a radio button after the value resets the value in IE8-9
110-
// Reset value to default in case type is set after value during creation
111-
var val = elem.value;
112-
elem.setAttribute( "type", value );
113-
if ( val ) {
114-
elem.value = val;
115-
}
116-
return value;
117-
}
118-
}
119-
}
120107
}
121108
});
122109

123-
// Hook for boolean attributes
110+
// Hooks for boolean attributes
124111
boolHook = {
125112
set: function( elem, value, name ) {
126113
if ( value === false ) {
127114
// Remove boolean attributes when set to false
128115
jQuery.removeAttr( elem, name );
129-
} else if ( getSetInput || !ruseDefault.test( name ) ) {
130-
elem.setAttribute( jQuery.propFix[ name ] || name, name );
131-
132116
} else {
133-
// Support: IE<9
134-
// Use defaultChecked and defaultSelected for oldIE
135-
elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true;
117+
elem.setAttribute( name, name );
136118
}
137-
138119
return name;
139120
}
140121
};
141-
142-
// Retrieve booleans specially
143122
jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
144-
145123
var getter = attrHandle[ name ] || jQuery.find.attr;
146124

147-
attrHandle[ name ] = getSetInput || !ruseDefault.test( name ) ?
148-
function( elem, name, isXML ) {
149-
var ret, handle;
150-
if ( !isXML ) {
151-
// Avoid an infinite loop by temporarily removing this function from the getter
152-
handle = attrHandle[ name ];
153-
attrHandle[ name ] = ret;
154-
ret = getter( elem, name, isXML ) != null ?
155-
name.toLowerCase() :
156-
null;
157-
attrHandle[ name ] = handle;
158-
}
159-
return ret;
160-
} :
161-
function( elem, name, isXML ) {
162-
if ( !isXML ) {
163-
return elem[ jQuery.camelCase( "default-" + name ) ] ?
164-
name.toLowerCase() :
165-
null;
166-
}
167-
};
168-
});
169-
170-
// fix oldIE attroperties
171-
if ( !getSetInput ) {
172-
jQuery.attrHooks.value = {
173-
set: function( elem, value ) {
174-
if ( jQuery.nodeName( elem, "input" ) ) {
175-
// Does not return so that setAttribute is also used
176-
elem.defaultValue = value;
177-
}
125+
attrHandle[ name ] = function( elem, name, isXML ) {
126+
var ret, handle;
127+
if ( !isXML ) {
128+
// Avoid an infinite loop by temporarily removing this function from the getter
129+
handle = attrHandle[ name ];
130+
attrHandle[ name ] = ret;
131+
ret = getter( elem, name, isXML ) != null ?
132+
name.toLowerCase() :
133+
null;
134+
attrHandle[ name ] = handle;
178135
}
136+
return ret;
179137
};
180-
}
181-
182-
if ( !support.style ) {
183-
jQuery.attrHooks.style = {
184-
get: function( elem ) {
185-
// Return undefined in the case of empty string
186-
// Note: IE uppercases css property names, but if we were to .toLowerCase()
187-
// .cssText, that would destroy case senstitivity in URL's, like in "background"
188-
return elem.style.cssText || undefined;
189-
},
190-
set: function( elem, value ) {
191-
return ( elem.style.cssText = value + "" );
192-
}
193-
};
194-
}
138+
});
195139

196140
});

src/attributes/prop.js

Lines changed: 31 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,97 +1,80 @@
11
define([
22
"../core",
33
"../core/access",
4-
"./support"
4+
"./support",
5+
"../selector"
56
], function( jQuery, access, support ) {
67

7-
var rfocusable = /^(?:input|select|textarea|button|object)$/i,
8-
rclickable = /^(?:a|area)$/i;
8+
var rfocusable = /^(?:input|select|textarea|button)$/i;
99

1010
jQuery.fn.extend({
1111
prop: function( name, value ) {
1212
return access( this, jQuery.prop, name, value, arguments.length > 1 );
1313
},
1414

1515
removeProp: function( name ) {
16-
name = jQuery.propFix[ name ] || name;
1716
return this.each(function() {
18-
// try/catch handles cases where IE balks (such as removing a property on window)
19-
try {
20-
this[ name ] = undefined;
21-
delete this[ name ];
22-
} catch ( e ) {}
17+
delete this[ jQuery.propFix[ name ] || name ];
2318
});
2419
}
2520
});
2621

2722
jQuery.extend({
28-
propFix: {
29-
"for": "htmlFor",
30-
"class": "className"
31-
},
32-
3323
prop: function( elem, name, value ) {
34-
var ret, hooks, notxml,
24+
var ret, hooks,
3525
nType = elem.nodeType;
3626

37-
// don't get/set properties on text, comment and attribute nodes
38-
if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
27+
// Don't get/set properties on text, comment and attribute nodes
28+
if ( nType === 3 || nType === 8 || nType === 2 ) {
3929
return;
4030
}
4131

42-
notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
32+
if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
4333

44-
if ( notxml ) {
4534
// Fix name and attach hooks
4635
name = jQuery.propFix[ name ] || name;
4736
hooks = jQuery.propHooks[ name ];
4837
}
4938

5039
if ( value !== undefined ) {
51-
return hooks && "set" in hooks &&
52-
(ret = hooks.set( elem, value, name )) !== undefined ?
53-
ret :
54-
( elem[ name ] = value );
55-
56-
} else {
57-
return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ?
58-
ret :
59-
elem[ name ];
40+
if ( hooks && "set" in hooks &&
41+
( ret = hooks.set( elem, value, name ) ) !== undefined ) {
42+
return ret;
43+
}
44+
45+
return ( elem[ name ] = value );
46+
}
47+
48+
if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
49+
return ret;
6050
}
51+
52+
return elem[ name ];
6153
},
6254

6355
propHooks: {
6456
tabIndex: {
6557
get: function( elem ) {
66-
// elem.tabIndex doesn't always return the
67-
// correct value when it hasn't been explicitly set
68-
// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
69-
// Use proper attribute retrieval(#12072)
70-
var tabindex = jQuery.find.attr( elem, "tabindex" );
71-
72-
return tabindex ?
73-
parseInt( tabindex, 10 ) :
74-
rfocusable.test( elem.nodeName ) ||
75-
rclickable.test( elem.nodeName ) && elem.href ?
76-
0 :
77-
-1;
58+
return elem.hasAttribute( "tabindex" ) ||
59+
rfocusable.test( elem.nodeName ) || elem.href ?
60+
elem.tabIndex :
61+
-1;
7862
}
7963
}
64+
},
65+
66+
propFix: {
67+
"for": "htmlFor",
68+
"class": "className"
8069
}
8170
});
8271

8372
if ( !support.optSelected ) {
8473
jQuery.propHooks.selected = {
8574
get: function( elem ) {
8675
var parent = elem.parentNode;
87-
88-
if ( parent ) {
89-
parent.selectedIndex;
90-
91-
// Make sure that it also works with optgroups, see #5701
92-
if ( parent.parentNode ) {
93-
parent.parentNode.selectedIndex;
94-
}
76+
if ( parent && parent.parentNode ) {
77+
parent.parentNode.selectedIndex;
9578
}
9679
return null;
9780
}

0 commit comments

Comments
 (0)