blob: 0c90a8dffdb95ec4678f18e07623f9d111c32540 [file] [log] [blame]
Copybara botbe50d492023-11-30 00:16:42 +01001define( [
2 "../core",
3 "../core/stripAndCollapse",
4 "../var/isFunction",
5 "../var/rnothtmlwhite",
6 "../data/var/dataPriv",
7 "../core/init"
8], function( jQuery, stripAndCollapse, isFunction, rnothtmlwhite, dataPriv ) {
9
10"use strict";
11
12function getClass( elem ) {
13 return elem.getAttribute && elem.getAttribute( "class" ) || "";
14}
15
16function classesToArray( value ) {
17 if ( Array.isArray( value ) ) {
18 return value;
19 }
20 if ( typeof value === "string" ) {
21 return value.match( rnothtmlwhite ) || [];
22 }
23 return [];
24}
25
26jQuery.fn.extend( {
27 addClass: function( value ) {
28 var classes, elem, cur, curValue, clazz, j, finalValue,
29 i = 0;
30
31 if ( isFunction( value ) ) {
32 return this.each( function( j ) {
33 jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
34 } );
35 }
36
37 classes = classesToArray( value );
38
39 if ( classes.length ) {
40 while ( ( elem = this[ i++ ] ) ) {
41 curValue = getClass( elem );
42 cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
43
44 if ( cur ) {
45 j = 0;
46 while ( ( clazz = classes[ j++ ] ) ) {
47 if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
48 cur += clazz + " ";
49 }
50 }
51
52 // Only assign if different to avoid unneeded rendering.
53 finalValue = stripAndCollapse( cur );
54 if ( curValue !== finalValue ) {
55 elem.setAttribute( "class", finalValue );
56 }
57 }
58 }
59 }
60
61 return this;
62 },
63
64 removeClass: function( value ) {
65 var classes, elem, cur, curValue, clazz, j, finalValue,
66 i = 0;
67
68 if ( isFunction( value ) ) {
69 return this.each( function( j ) {
70 jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
71 } );
72 }
73
74 if ( !arguments.length ) {
75 return this.attr( "class", "" );
76 }
77
78 classes = classesToArray( value );
79
80 if ( classes.length ) {
81 while ( ( elem = this[ i++ ] ) ) {
82 curValue = getClass( elem );
83
84 // This expression is here for better compressibility (see addClass)
85 cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
86
87 if ( cur ) {
88 j = 0;
89 while ( ( clazz = classes[ j++ ] ) ) {
90
91 // Remove *all* instances
92 while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
93 cur = cur.replace( " " + clazz + " ", " " );
94 }
95 }
96
97 // Only assign if different to avoid unneeded rendering.
98 finalValue = stripAndCollapse( cur );
99 if ( curValue !== finalValue ) {
100 elem.setAttribute( "class", finalValue );
101 }
102 }
103 }
104 }
105
106 return this;
107 },
108
109 toggleClass: function( value, stateVal ) {
110 var type = typeof value,
111 isValidValue = type === "string" || Array.isArray( value );
112
113 if ( typeof stateVal === "boolean" && isValidValue ) {
114 return stateVal ? this.addClass( value ) : this.removeClass( value );
115 }
116
117 if ( isFunction( value ) ) {
118 return this.each( function( i ) {
119 jQuery( this ).toggleClass(
120 value.call( this, i, getClass( this ), stateVal ),
121 stateVal
122 );
123 } );
124 }
125
126 return this.each( function() {
127 var className, i, self, classNames;
128
129 if ( isValidValue ) {
130
131 // Toggle individual class names
132 i = 0;
133 self = jQuery( this );
134 classNames = classesToArray( value );
135
136 while ( ( className = classNames[ i++ ] ) ) {
137
138 // Check each className given, space separated list
139 if ( self.hasClass( className ) ) {
140 self.removeClass( className );
141 } else {
142 self.addClass( className );
143 }
144 }
145
146 // Toggle whole class name
147 } else if ( value === undefined || type === "boolean" ) {
148 className = getClass( this );
149 if ( className ) {
150
151 // Store className if set
152 dataPriv.set( this, "__className__", className );
153 }
154
155 // If the element has a class name or if we're passed `false`,
156 // then remove the whole classname (if there was one, the above saved it).
157 // Otherwise bring back whatever was previously saved (if anything),
158 // falling back to the empty string if nothing was stored.
159 if ( this.setAttribute ) {
160 this.setAttribute( "class",
161 className || value === false ?
162 "" :
163 dataPriv.get( this, "__className__" ) || ""
164 );
165 }
166 }
167 } );
168 },
169
170 hasClass: function( selector ) {
171 var className, elem,
172 i = 0;
173
174 className = " " + selector + " ";
175 while ( ( elem = this[ i++ ] ) ) {
176 if ( elem.nodeType === 1 &&
177 ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) {
178 return true;
179 }
180 }
181
182 return false;
183 }
184} );
185
186} );