1 define("dojo/dom-class", ["./_base/lang", "./_base/array", "./dom"], function(lang, array, dom){
5 // This module defines the core dojo DOM class API.
7 var className = "className";
9 /* Part I of classList-based implementation is preserved here for posterity
10 var classList = "classList";
11 has.add("dom-classList", function(){
12 return classList in document.createElement("p");
16 // =============================
17 // (CSS) Class Functions
18 // =============================
21 dojo.hasClass = function(node, classStr){
23 // Returns whether or not the specified classes are a portion of the
24 // class list currently applied to the node.
26 // node: String|DOMNode
27 // String ID or DomNode reference to check the class for.
30 // A string class name to look for.
35 // Do something if a node with id="someNode" has class="aSillyClassName" present
36 // | if(dojo.hasClass("someNode","aSillyClassName")){ ... }
41 dojo.addClass = function(node, classStr){
43 // Adds the specified classes to the end of the class list on the
44 // passed node. Will not re-apply duplicate classes.
46 // node: String|DOMNode
47 // String ID or DomNode reference to add a class string too
49 // classStr: String|Array
50 // A String class name to add, or several space-separated class names,
51 // or an array of class names.
54 // Add a class to some node:
55 // | dojo.addClass("someNode", "anewClass");
58 // Add two classes at once:
59 // | dojo.addClass("someNode", "firstClass secondClass");
62 // Add two classes at once (using array):
63 // | dojo.addClass("someNode", ["firstClass", "secondClass"]);
66 // Available in `dojo.NodeList` for multiple additions
67 // | dojo.query("ul > li").addClass("firstLevel");
72 dojo.removeClass = function(node, classStr){
74 // Removes the specified classes from node. No `dojo.hasClass`
77 // node: String|DOMNode
78 // String ID or DomNode reference to remove the class from.
80 // classStr: String|Array
81 // An optional String class name to remove, or several space-separated
82 // class names, or an array of class names. If omitted, all class names
86 // Remove a class from some node:
87 // | dojo.removeClass("someNode", "firstClass");
90 // Remove two classes from some node:
91 // | dojo.removeClass("someNode", "firstClass secondClass");
94 // Remove two classes from some node (using array):
95 // | dojo.removeClass("someNode", ["firstClass", "secondClass"]);
98 // Remove all classes from some node:
99 // | dojo.removeClass("someNode");
102 // Available in `dojo.NodeList()` for multiple removal
103 // | dojo.query(".foo").removeClass("foo");
108 dojo.replaceClass = function(node, addClassStr, removeClassStr){
110 // Replaces one or more classes on a node if not present.
111 // Operates more quickly than calling dojo.removeClass and dojo.addClass
113 // node: String|DOMNode
114 // String ID or DomNode reference to remove the class from.
116 // addClassStr: String|Array
117 // A String class name to add, or several space-separated class names,
118 // or an array of class names.
120 // removeClassStr: String|Array?
121 // A String class name to remove, or several space-separated class names,
122 // or an array of class names.
125 // | dojo.replaceClass("someNode", "add1 add2", "remove1 remove2");
128 // Replace all classes with addMe
129 // | dojo.replaceClass("someNode", "addMe");
132 // Available in `dojo.NodeList()` for multiple toggles
133 // | dojo.query(".findMe").replaceClass("addMe", "removeMe");
138 dojo.toggleClass = function(node, classStr, condition){
140 // Adds a class to node if not present, or removes if present.
141 // Pass a boolean condition if you want to explicitly add or remove.
142 // Returns the condition that was specified directly or indirectly.
144 // node: String|DOMNode
145 // String ID or DomNode reference to toggle a class string
147 // classStr: String|Array
148 // A String class name to toggle, or several space-separated class names,
149 // or an array of class names.
152 // If passed, true means to add the class, false means to remove.
153 // Otherwise dojo.hasClass(node, classStr) is used to detect the class presence.
156 // | dojo.toggleClass("someNode", "hovered");
159 // Forcefully add a class
160 // | dojo.toggleClass("someNode", "hovered", true);
163 // Available in `dojo.NodeList()` for multiple toggles
164 // | dojo.query(".toggleMe").toggleClass("toggleMe");
168 var cls, // exports object
169 spaces = /\s+/, a1 = [""];
171 function str2array(s){
172 if(typeof s == "string" || s instanceof String){
173 if(s && !spaces.test(s)){
177 var a = s.split(spaces);
178 if(a.length && !a[0]){
181 if(a.length && !a[a.length - 1]){
186 // assumed to be an array
190 return array.filter(s, function(x){ return x; });
193 /* Part II of classList-based implementation is preserved here for posterity
194 if(has("dom-classList")){
195 // new classList version
197 contains: function containsClass(node, classStr){
198 var clslst = classStr && dom.byId(node)[classList];
199 return clslst && clslst.contains(classStr); // Boolean
202 add: function addClass(node, classStr){
203 node = dom.byId(node);
204 classStr = str2array(classStr);
205 for(var i = 0, len = classStr.length; i < len; ++i){
206 node[classList].add(classStr[i]);
210 remove: function removeClass(node, classStr){
211 node = dom.byId(node);
212 if(classStr === undefined){
213 node[className] = "";
215 classStr = str2array(classStr);
216 for(var i = 0, len = classStr.length; i < len; ++i){
217 node[classList].remove(classStr[i]);
222 replace: function replaceClass(node, addClassStr, removeClassStr){
223 node = dom.byId(node);
224 if(removeClassStr === undefined){
225 node[className] = "";
227 removeClassStr = str2array(removeClassStr);
228 for(var i = 0, len = removeClassStr.length; i < len; ++i){
229 node[classList].remove(removeClassStr[i]);
232 addClassStr = str2array(addClassStr);
233 for(i = 0, len = addClassStr.length; i < len; ++i){
234 node[classList].add(addClassStr[i]);
238 toggle: function toggleClass(node, classStr, condition){
239 node = dom.byId(node);
240 if(condition === undefined){
241 classStr = str2array(classStr);
242 for(var i = 0, len = classStr.length; i < len; ++i){
243 node[classList].toggle(classStr[i]);
246 cls[condition ? "add" : "remove"](node, classStr);
248 return condition; // Boolean
254 // regular DOM version
255 var fakeNode = {}; // for effective replacement
257 contains: function containsClass(/*DomNode|String*/node, /*String*/classStr){
258 return ((" " + dom.byId(node)[className] + " ").indexOf(" " + classStr + " ") >= 0); // Boolean
261 add: function addClass(/*DomNode|String*/node, /*String|Array*/classStr){
262 node = dom.byId(node);
263 classStr = str2array(classStr);
264 var cls = node[className], oldLen;
265 cls = cls ? " " + cls + " " : " ";
267 for(var i = 0, len = classStr.length, c; i < len; ++i){
269 if(c && cls.indexOf(" " + c + " ") < 0){
273 if(oldLen < cls.length){
274 node[className] = cls.substr(1, cls.length - 2);
278 remove: function removeClass(/*DomNode|String*/node, /*String|Array?*/classStr){
279 node = dom.byId(node);
281 if(classStr !== undefined){
282 classStr = str2array(classStr);
283 cls = " " + node[className] + " ";
284 for(var i = 0, len = classStr.length; i < len; ++i){
285 cls = cls.replace(" " + classStr[i] + " ", " ");
287 cls = lang.trim(cls);
291 if(node[className] != cls){ node[className] = cls; }
294 replace: function replaceClass(/*DomNode|String*/node, /*String|Array*/addClassStr, /*String|Array?*/removeClassStr){
295 node = dom.byId(node);
296 fakeNode[className] = node[className];
297 cls.remove(fakeNode, removeClassStr);
298 cls.add(fakeNode, addClassStr);
299 if(node[className] !== fakeNode[className]){
300 node[className] = fakeNode[className];
304 toggle: function toggleClass(/*DomNode|String*/node, /*String|Array*/classStr, /*Boolean?*/condition){
305 node = dom.byId(node);
306 if(condition === undefined){
307 classStr = str2array(classStr);
308 for(var i = 0, len = classStr.length, c; i < len; ++i){
310 cls[cls.contains(node, c) ? "remove" : "add"](node, c);
313 cls[condition ? "add" : "remove"](node, classStr);
315 return condition; // Boolean