]>
Commit | Line | Data |
---|---|---|
f0cfe83e AD |
1 | define("dojo/dom-class", ["./_base/lang", "./_base/array", "./dom"], function(lang, array, dom){ |
2 | // module: | |
3 | // dojo/dom-class | |
4 | ||
5 | var className = "className"; | |
6 | ||
7 | /* Part I of classList-based implementation is preserved here for posterity | |
8 | var classList = "classList"; | |
9 | has.add("dom-classList", function(){ | |
10 | return classList in document.createElement("p"); | |
11 | }); | |
12 | */ | |
13 | ||
14 | // ============================= | |
15 | // (CSS) Class Functions | |
16 | // ============================= | |
17 | ||
18 | var cls, // exports object | |
19 | spaces = /\s+/, a1 = [""]; | |
20 | ||
21 | function str2array(s){ | |
22 | if(typeof s == "string" || s instanceof String){ | |
23 | if(s && !spaces.test(s)){ | |
24 | a1[0] = s; | |
25 | return a1; | |
26 | } | |
27 | var a = s.split(spaces); | |
28 | if(a.length && !a[0]){ | |
29 | a.shift(); | |
30 | } | |
31 | if(a.length && !a[a.length - 1]){ | |
32 | a.pop(); | |
33 | } | |
34 | return a; | |
35 | } | |
36 | // assumed to be an array | |
37 | if(!s){ | |
38 | return []; | |
39 | } | |
40 | return array.filter(s, function(x){ return x; }); | |
41 | } | |
42 | ||
43 | /* Part II of classList-based implementation is preserved here for posterity | |
44 | if(has("dom-classList")){ | |
45 | // new classList version | |
46 | cls = { | |
47 | contains: function containsClass(node, classStr){ | |
48 | var clslst = classStr && dom.byId(node)[classList]; | |
49 | return clslst && clslst.contains(classStr); // Boolean | |
50 | }, | |
51 | ||
52 | add: function addClass(node, classStr){ | |
53 | node = dom.byId(node); | |
54 | classStr = str2array(classStr); | |
55 | for(var i = 0, len = classStr.length; i < len; ++i){ | |
56 | node[classList].add(classStr[i]); | |
57 | } | |
58 | }, | |
59 | ||
60 | remove: function removeClass(node, classStr){ | |
61 | node = dom.byId(node); | |
62 | if(classStr === undefined){ | |
63 | node[className] = ""; | |
64 | }else{ | |
65 | classStr = str2array(classStr); | |
66 | for(var i = 0, len = classStr.length; i < len; ++i){ | |
67 | node[classList].remove(classStr[i]); | |
68 | } | |
69 | } | |
70 | }, | |
71 | ||
72 | replace: function replaceClass(node, addClassStr, removeClassStr){ | |
73 | node = dom.byId(node); | |
74 | if(removeClassStr === undefined){ | |
75 | node[className] = ""; | |
76 | }else{ | |
77 | removeClassStr = str2array(removeClassStr); | |
78 | for(var i = 0, len = removeClassStr.length; i < len; ++i){ | |
79 | node[classList].remove(removeClassStr[i]); | |
80 | } | |
81 | } | |
82 | addClassStr = str2array(addClassStr); | |
83 | for(i = 0, len = addClassStr.length; i < len; ++i){ | |
84 | node[classList].add(addClassStr[i]); | |
85 | } | |
86 | }, | |
87 | ||
88 | toggle: function toggleClass(node, classStr, condition){ | |
89 | node = dom.byId(node); | |
90 | if(condition === undefined){ | |
91 | classStr = str2array(classStr); | |
92 | for(var i = 0, len = classStr.length; i < len; ++i){ | |
93 | node[classList].toggle(classStr[i]); | |
94 | } | |
95 | }else{ | |
96 | cls[condition ? "add" : "remove"](node, classStr); | |
97 | } | |
98 | return condition; // Boolean | |
99 | } | |
100 | } | |
101 | } | |
102 | */ | |
103 | ||
104 | // regular DOM version | |
105 | var fakeNode = {}; // for effective replacement | |
106 | cls = { | |
107 | // summary: | |
108 | // This module defines the core dojo DOM class API. | |
109 | ||
110 | contains: function containsClass(/*DomNode|String*/ node, /*String*/ classStr){ | |
111 | // summary: | |
112 | // Returns whether or not the specified classes are a portion of the | |
113 | // class list currently applied to the node. | |
114 | // node: String|DOMNode | |
115 | // String ID or DomNode reference to check the class for. | |
116 | // classStr: String | |
117 | // A string class name to look for. | |
118 | // example: | |
119 | // Do something if a node with id="someNode" has class="aSillyClassName" present | |
120 | // | if(dojo.hasClass("someNode","aSillyClassName")){ ... } | |
121 | ||
122 | return ((" " + dom.byId(node)[className] + " ").indexOf(" " + classStr + " ") >= 0); // Boolean | |
123 | }, | |
124 | ||
125 | add: function addClass(/*DomNode|String*/ node, /*String|Array*/ classStr){ | |
126 | // summary: | |
127 | // Adds the specified classes to the end of the class list on the | |
128 | // passed node. Will not re-apply duplicate classes. | |
129 | // | |
130 | // node: String|DOMNode | |
131 | // String ID or DomNode reference to add a class string too | |
132 | // | |
133 | // classStr: String|Array | |
134 | // A String class name to add, or several space-separated class names, | |
135 | // or an array of class names. | |
136 | // | |
137 | // example: | |
138 | // Add a class to some node: | |
139 | // | require(["dojo/dom-class"], function(domClass){ | |
140 | // | domClass.add("someNode", "anewClass"); | |
141 | // | }); | |
142 | // | |
143 | // example: | |
144 | // Add two classes at once: | |
145 | // | require(["dojo/dom-class"], function(domClass){ | |
146 | // | domClass.add("someNode", "firstClass secondClass"); | |
147 | // | }); | |
148 | // | |
149 | // example: | |
150 | // Add two classes at once (using array): | |
151 | // | require(["dojo/dom-class"], function(domClass){ | |
152 | // | domClass.add("someNode", ["firstClass", "secondClass"]); | |
153 | // | }); | |
154 | // | |
155 | // example: | |
156 | // Available in `dojo/NodeList` for multiple additions | |
157 | // | require(["dojo/query"], function(query){ | |
158 | // | query("ul > li").addClass("firstLevel"); | |
159 | // | }); | |
160 | ||
161 | node = dom.byId(node); | |
162 | classStr = str2array(classStr); | |
163 | var cls = node[className], oldLen; | |
164 | cls = cls ? " " + cls + " " : " "; | |
165 | oldLen = cls.length; | |
166 | for(var i = 0, len = classStr.length, c; i < len; ++i){ | |
167 | c = classStr[i]; | |
168 | if(c && cls.indexOf(" " + c + " ") < 0){ | |
169 | cls += c + " "; | |
170 | } | |
171 | } | |
172 | if(oldLen < cls.length){ | |
173 | node[className] = cls.substr(1, cls.length - 2); | |
174 | } | |
175 | }, | |
176 | ||
177 | remove: function removeClass(/*DomNode|String*/ node, /*String|Array?*/ classStr){ | |
178 | // summary: | |
179 | // Removes the specified classes from node. No `contains()` | |
180 | // check is required. | |
181 | // | |
182 | // node: String|DOMNode | |
183 | // String ID or DomNode reference to remove the class from. | |
184 | // | |
185 | // classStr: String|Array | |
186 | // An optional String class name to remove, or several space-separated | |
187 | // class names, or an array of class names. If omitted, all class names | |
188 | // will be deleted. | |
189 | // | |
190 | // example: | |
191 | // Remove a class from some node: | |
192 | // | require(["dojo/dom-class"], function(domClass){ | |
193 | // | domClass.remove("someNode", "firstClass"); | |
194 | // | }); | |
195 | // | |
196 | // example: | |
197 | // Remove two classes from some node: | |
198 | // | require(["dojo/dom-class"], function(domClass){ | |
199 | // | domClass.remove("someNode", "firstClass secondClass"); | |
200 | // | }); | |
201 | // | |
202 | // example: | |
203 | // Remove two classes from some node (using array): | |
204 | // | require(["dojo/dom-class"], function(domClass){ | |
205 | // | domClass.remove("someNode", ["firstClass", "secondClass"]); | |
206 | // | }); | |
207 | // | |
208 | // example: | |
209 | // Remove all classes from some node: | |
210 | // | require(["dojo/dom-class"], function(domClass){ | |
211 | // | domClass.remove("someNode"); | |
212 | // | }); | |
213 | // | |
214 | // example: | |
215 | // Available in `dojo/NodeList` for multiple removal | |
216 | // | require(["dojo/query"], function(query){ | |
217 | // | query("ul > li").removeClass("foo"); | |
218 | // | }); | |
219 | ||
220 | node = dom.byId(node); | |
221 | var cls; | |
222 | if(classStr !== undefined){ | |
223 | classStr = str2array(classStr); | |
224 | cls = " " + node[className] + " "; | |
225 | for(var i = 0, len = classStr.length; i < len; ++i){ | |
226 | cls = cls.replace(" " + classStr[i] + " ", " "); | |
227 | } | |
228 | cls = lang.trim(cls); | |
229 | }else{ | |
230 | cls = ""; | |
231 | } | |
232 | if(node[className] != cls){ node[className] = cls; } | |
233 | }, | |
234 | ||
235 | replace: function replaceClass(/*DomNode|String*/ node, /*String|Array*/ addClassStr, /*String|Array?*/ removeClassStr){ | |
236 | // summary: | |
237 | // Replaces one or more classes on a node if not present. | |
238 | // Operates more quickly than calling dojo.removeClass and dojo.addClass | |
239 | // | |
240 | // node: String|DOMNode | |
241 | // String ID or DomNode reference to remove the class from. | |
242 | // | |
243 | // addClassStr: String|Array | |
244 | // A String class name to add, or several space-separated class names, | |
245 | // or an array of class names. | |
246 | // | |
247 | // removeClassStr: String|Array? | |
248 | // A String class name to remove, or several space-separated class names, | |
249 | // or an array of class names. | |
250 | // | |
251 | // example: | |
252 | // | require(["dojo/dom-class"], function(domClass){ | |
253 | // | domClass.replace("someNode", "add1 add2", "remove1 remove2"); | |
254 | // | }); | |
255 | // | |
256 | // example: | |
257 | // Replace all classes with addMe | |
258 | // | require(["dojo/dom-class"], function(domClass){ | |
259 | // | domClass.replace("someNode", "addMe"); | |
260 | // | }); | |
261 | // | |
262 | // example: | |
263 | // Available in `dojo/NodeList` for multiple toggles | |
264 | // | require(["dojo/query"], function(query){ | |
265 | // | query(".findMe").replaceClass("addMe", "removeMe"); | |
266 | // | }); | |
267 | ||
268 | node = dom.byId(node); | |
269 | fakeNode[className] = node[className]; | |
270 | cls.remove(fakeNode, removeClassStr); | |
271 | cls.add(fakeNode, addClassStr); | |
272 | if(node[className] !== fakeNode[className]){ | |
273 | node[className] = fakeNode[className]; | |
274 | } | |
275 | }, | |
276 | ||
277 | toggle: function toggleClass(/*DomNode|String*/ node, /*String|Array*/ classStr, /*Boolean?*/ condition){ | |
278 | // summary: | |
279 | // Adds a class to node if not present, or removes if present. | |
280 | // Pass a boolean condition if you want to explicitly add or remove. | |
281 | // Returns the condition that was specified directly or indirectly. | |
282 | // | |
283 | // node: String|DOMNode | |
284 | // String ID or DomNode reference to toggle a class string | |
285 | // | |
286 | // classStr: String|Array | |
287 | // A String class name to toggle, or several space-separated class names, | |
288 | // or an array of class names. | |
289 | // | |
290 | // condition: | |
291 | // If passed, true means to add the class, false means to remove. | |
292 | // Otherwise dojo.hasClass(node, classStr) is used to detect the class presence. | |
293 | // | |
294 | // example: | |
295 | // | require(["dojo/dom-class"], function(domClass){ | |
296 | // | domClass.toggle("someNode", "hovered"); | |
297 | // | }); | |
298 | // | |
299 | // example: | |
300 | // Forcefully add a class | |
301 | // | require(["dojo/dom-class"], function(domClass){ | |
302 | // | domClass.toggle("someNode", "hovered", true); | |
303 | // | }); | |
304 | // | |
305 | // example: | |
306 | // Available in `dojo/NodeList` for multiple toggles | |
307 | // | require(["dojo/query"], function(query){ | |
308 | // | query(".toggleMe").toggleClass("toggleMe"); | |
309 | // | }); | |
310 | ||
311 | node = dom.byId(node); | |
312 | if(condition === undefined){ | |
313 | classStr = str2array(classStr); | |
314 | for(var i = 0, len = classStr.length, c; i < len; ++i){ | |
315 | c = classStr[i]; | |
316 | cls[cls.contains(node, c) ? "remove" : "add"](node, c); | |
317 | } | |
318 | }else{ | |
319 | cls[condition ? "add" : "remove"](node, classStr); | |
320 | } | |
321 | return condition; // Boolean | |
322 | } | |
323 | }; | |
324 | ||
325 | return cls; | |
326 | }); |