Project

General

Profile

1
define( [
2
	"../core",
3
	"../core/access",
4
	"../core/nodeName",
5
	"./support",
6
	"../var/rnothtmlwhite",
7
	"../selector"
8
], function( jQuery, access, nodeName, support, rnothtmlwhite ) {
9

    
10
"use strict";
11

    
12
var boolHook,
13
	attrHandle = jQuery.expr.attrHandle;
14

    
15
jQuery.fn.extend( {
16
	attr: function( name, value ) {
17
		return access( this, jQuery.attr, name, value, arguments.length > 1 );
18
	},
19

    
20
	removeAttr: function( name ) {
21
		return this.each( function() {
22
			jQuery.removeAttr( this, name );
23
		} );
24
	}
25
} );
26

    
27
jQuery.extend( {
28
	attr: function( elem, name, value ) {
29
		var ret, hooks,
30
			nType = elem.nodeType;
31

    
32
		// Don't get/set attributes on text, comment and attribute nodes
33
		if ( nType === 3 || nType === 8 || nType === 2 ) {
34
			return;
35
		}
36

    
37
		// Fallback to prop when attributes are not supported
38
		if ( typeof elem.getAttribute === "undefined" ) {
39
			return jQuery.prop( elem, name, value );
40
		}
41

    
42
		// Attribute hooks are determined by the lowercase version
43
		// Grab necessary hook if one is defined
44
		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
45
			hooks = jQuery.attrHooks[ name.toLowerCase() ] ||
46
				( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );
47
		}
48

    
49
		if ( value !== undefined ) {
50
			if ( value === null ) {
51
				jQuery.removeAttr( elem, name );
52
				return;
53
			}
54

    
55
			if ( hooks && "set" in hooks &&
56
				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
57
				return ret;
58
			}
59

    
60
			elem.setAttribute( name, value + "" );
61
			return value;
62
		}
63

    
64
		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
65
			return ret;
66
		}
67

    
68
		ret = jQuery.find.attr( elem, name );
69

    
70
		// Non-existent attributes return null, we normalize to undefined
71
		return ret == null ? undefined : ret;
72
	},
73

    
74
	attrHooks: {
75
		type: {
76
			set: function( elem, value ) {
77
				if ( !support.radioValue && value === "radio" &&
78
					nodeName( elem, "input" ) ) {
79
					var val = elem.value;
80
					elem.setAttribute( "type", value );
81
					if ( val ) {
82
						elem.value = val;
83
					}
84
					return value;
85
				}
86
			}
87
		}
88
	},
89

    
90
	removeAttr: function( elem, value ) {
91
		var name,
92
			i = 0,
93

    
94
			// Attribute names can contain non-HTML whitespace characters
95
			// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
96
			attrNames = value && value.match( rnothtmlwhite );
97

    
98
		if ( attrNames && elem.nodeType === 1 ) {
99
			while ( ( name = attrNames[ i++ ] ) ) {
100
				elem.removeAttribute( name );
101
			}
102
		}
103
	}
104
} );
105

    
106
// Hooks for boolean attributes
107
boolHook = {
108
	set: function( elem, value, name ) {
109
		if ( value === false ) {
110

    
111
			// Remove boolean attributes when set to false
112
			jQuery.removeAttr( elem, name );
113
		} else {
114
			elem.setAttribute( name, name );
115
		}
116
		return name;
117
	}
118
};
119

    
120
jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
121
	var getter = attrHandle[ name ] || jQuery.find.attr;
122

    
123
	attrHandle[ name ] = function( elem, name, isXML ) {
124
		var ret, handle,
125
			lowercaseName = name.toLowerCase();
126

    
127
		if ( !isXML ) {
128

    
129
			// Avoid an infinite loop by temporarily removing this function from the getter
130
			handle = attrHandle[ lowercaseName ];
131
			attrHandle[ lowercaseName ] = ret;
132
			ret = getter( elem, name, isXML ) != null ?
133
				lowercaseName :
134
				null;
135
			attrHandle[ lowercaseName ] = handle;
136
		}
137
		return ret;
138
	};
139
} );
140

    
141
} );
(1-1/5)