source: Dev/trunk/src/client/dojox/html/styles.js @ 529

Last change on this file since 529 was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

  • Property svn:executable set to *
File size: 9.5 KB
Line 
1define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/window", "dojo/_base/sniff"],
2        function(lang, ArrayUtil, Window, has) {
3        // summary:
4        //              Methods for creating and manipulating dynamic CSS Styles and Style Sheets
5        // example:
6        //      |               dojox.html.createStyle("#myDiv input", "font-size:24px");
7        //              Creates Style #myDiv input, which can now be applied to myDiv, and
8        //              the inner input will be targeted
9        //      |               dojox.html.createStyle(".myStyle", "color:#FF0000");
10        //              Now the class myStyle can be assigned to a node's className
11
12        var dh = lang.getObject("dojox.html", true);
13        var dynamicStyleMap = {};
14        var pageStyleSheets = {};
15        var titledSheets = [];
16
17        dh.insertCssRule = function(/*String*/selector, /*String*/declaration, /*String?*/styleSheetName){
18                // summary:
19                //              Creates a style and attaches it to a dynamically created stylesheet
20                // selector:
21                //              A fully qualified class name, as it would appear in
22                //              a CSS dojo.doc. Start classes with periods, target
23                //              nodes with '#'. Large selectors can also be created
24                //              like:
25                // |     "#myDiv.myClass span input"
26                // declaration:
27                //              A single string that would make up a style block, not
28                //              including the curly braces. Include semi-colons between
29                //              statements. Do not use JavaScript style declarations
30                //              in camel case, use as you would in a CSS dojo.doc:
31                //              | "color:#ffoooo;font-size:12px;margin-left:5px;"
32                // styleSheetName:
33                //              Name of the dynamic style sheet this rule should be
34                //              inserted into. If is not found by that name, it is
35                //              created. If no name is passed, the name "default" is
36                //              used.
37
38                var ss = dh.getDynamicStyleSheet(styleSheetName);
39                var styleText = selector + " {" + declaration + "}";
40                console.log("insertRule:", styleText);
41                if(has("ie")){
42                        // Note: check for if(ss.cssText) does not work
43                        ss.cssText+=styleText;
44                        console.log("ss.cssText:", ss.cssText);
45                }else if(ss.sheet){
46                        ss.sheet.insertRule(styleText, ss._indicies.length);
47                }else{
48                        ss.appendChild(Window.doc.createTextNode(styleText));
49                }
50                ss._indicies.push(selector+" "+declaration);
51                return selector; // String
52        };
53
54        dh.removeCssRule = function(/*String*/selector, /*String*/declaration, /*String*/styleSheetName){
55                // summary:
56                //              Removes a cssRule base on the selector and declaration passed
57                //              The declaration is needed for cases of dupe selectors
58                // description: Only removes DYNAMICALLY created cssRules. If you
59                //              created it with dh.insertCssRule, it can be removed.
60
61                var ss;
62                var index=-1;
63                var nm;
64                var i;
65                for(nm in dynamicStyleMap){
66                        if(styleSheetName && styleSheetName !== nm) {continue;}
67                        ss = dynamicStyleMap[nm];
68                        for(i=0;i<ss._indicies.length;i++){
69                                if(selector+" "+declaration === ss._indicies[i]){
70                                        index = i;
71                                        break;
72                                }
73                        }
74                        if(index>-1) { break; }
75                }
76                if(!ss){
77                        console.warn("No dynamic style sheet has been created from which to remove a rule.");
78                        return false;
79                }
80                if(index===-1){
81                        console.warn("The css rule was not found and could not be removed.");
82                        return false;
83                }
84                ss._indicies.splice(index, 1);
85                if(has("ie")){
86                        // Note: check for if(ss.removeRule) does not work
87                        ss.removeRule(index);
88                }else if(ss.sheet){
89                        ss.sheet.deleteRule(index);
90                }
91                return true; //Boolean
92        };
93
94        dh.modifyCssRule = function(selector, declaration, styleSheetName){
95                // summary:
96                //              Not implemented - it seems to have some merit for changing some complex
97                //              selectors. It's not much use for changing simple ones like "span".
98                //              For now, simply write a new rule which will cascade over the first.
99                //
100                //              Modifies an existing cssRule
101        };
102
103        dh.getStyleSheet = function(/*String?*/styleSheetName){
104                // summary:
105                //              Returns a style sheet based on the argument.
106                //              Searches dynamic style sheets first. If no matches,
107                //              searches document style sheets.
108                // styleSheetName:
109                //              A title or an href to a style sheet. Title can be
110                //              an attribute in a tag, or a dynamic style sheet
111                //              reference. Href can be the name of the file.
112                //              If no argument, the assumed created dynamic style
113                //              sheet is used.
114
115                // try dynamic sheets first
116                if(dynamicStyleMap[styleSheetName || "default"]){
117                        return dynamicStyleMap[styleSheetName || "default"];
118                }
119                if(!styleSheetName){
120                        // no arg is nly good for the default style sheet
121                        // and it has not been created yet.
122                        return false;
123                }
124                var allSheets = dh.getStyleSheets();
125                // now try document style sheets by name
126                if(allSheets[styleSheetName]){
127                        return dh.getStyleSheets()[styleSheetName];
128                }
129                // check for partial matches in hrefs (so that a fully
130                //qualified name does not have to be passed)
131                var nm;
132                for ( nm in allSheets){
133                        if( allSheets[nm].href && allSheets[nm].href.indexOf(styleSheetName)>-1){
134                                return allSheets[nm];
135                        }
136                }
137                return false; //StyleSheet or false
138        };
139
140        dh.getDynamicStyleSheet = function(/*String?*/styleSheetName){
141                // summary:
142                //              Creates and returns a dynamically created style sheet
143                //              used for dynamic styles
144                // styleSheetName:
145                //              The name given the style sheet so that multiple
146                //              style sheets can be created and referenced. If
147                //              no argument is given, the name "default" is used.
148
149                if(!styleSheetName){ styleSheetName="default"; }
150                if(!dynamicStyleMap[styleSheetName]){
151                        if(Window.doc.createStyleSheet){ //IE
152                                dynamicStyleMap[styleSheetName] = Window.doc.createStyleSheet();
153                                if(has("ie") < 9) {
154                                        // IE9 calls this read-only. Loving the new browser so far.
155                                        dynamicStyleMap[styleSheetName].title = styleSheetName;
156                                }
157                        }else{
158                                dynamicStyleMap[styleSheetName] = Window.doc.createElement("style");
159                                dynamicStyleMap[styleSheetName].setAttribute("type", "text/css");
160                                Window.doc.getElementsByTagName("head")[0].appendChild(dynamicStyleMap[styleSheetName]);
161                                console.log(styleSheetName, " ss created: ", dynamicStyleMap[styleSheetName].sheet);
162                        }
163                        dynamicStyleMap[styleSheetName]._indicies = [];
164                }
165                return dynamicStyleMap[styleSheetName]; //StyleSheet
166        };
167
168        dh.enableStyleSheet = function(/*String*/styleSheetName){
169                // summary:
170                //              Enables the style sheet with the name passed in the
171                //              argument. Deafults to the default style sheet.
172                //
173                var ss = dh.getStyleSheet(styleSheetName);
174                if(ss){
175                        if(ss.sheet){
176                                ss.sheet.disabled = false;
177                        }else{
178                                ss.disabled = false;
179                        }
180                }
181        };
182
183        dh.disableStyleSheet = function(/* String */styleSheetName){
184                // summary:
185                //              Disables the dynamic style sheet with the name passed in the
186                //              argument. If no arg is passed, defaults to the default style sheet.
187
188                var ss = dh.getStyleSheet(styleSheetName);
189                if(ss){
190                        if(ss.sheet){
191                                ss.sheet.disabled = true;
192                        }else{
193                                ss.disabled = true;
194                        }
195                }
196        };
197
198        dh.activeStyleSheet = function(/*String?*/title){
199                // summary:
200                //              Getter/Setter
201                // description:
202                //              If passed a title, enables a that style sheet. All other
203                //              toggle-able style sheets are disabled.
204                //              If no argument is passed, returns currently enabled
205                //              style sheet.
206
207                var sheets = dh.getToggledStyleSheets();
208                var i;
209                if(arguments.length === 1){
210                        //console.log("sheets:", sheets);
211                        ArrayUtil.forEach(sheets, function(s){
212                                s.disabled = (s.title === title) ? false : true;
213                        });
214                }else{
215                        for(i=0;i<sheets.length;i++){
216                                if(sheets[i].disabled === false){
217                                        return sheets[i];
218                                }
219                        }
220                }
221                return true; //StyleSheet or Boolean - FIXME - doesn't make a lot of sense
222        };
223
224        dh.getPreferredStyleSheet = function(){
225                // summary:
226                //              Returns the style sheet that was initially enabled
227                //              on document launch.
228                //              TODO, does not work.
229        };
230
231        //      TODO: Sets of style sheets could be grouped according to
232        //                      an ID and used in sets, much like different
233        //                      groups of radio buttons. It would not however be
234        //                      according to W3C spec
235        //
236        dh.getToggledStyleSheets = function(){
237                // summary:
238                //              Searches HTML for style sheets that are "toggle-able" -
239                //              can be enabled and disabled. These would include sheets
240                //              with the title attribute, as well as the REL attribute.
241                // returns:
242                //              An array of all toggle-able style sheets
243                var nm;
244                if(!titledSheets.length){
245                        var sObjects = dh.getStyleSheets();
246                        for(nm in sObjects){
247                                if(sObjects[nm].title){
248                                        titledSheets.push(sObjects[nm]);
249                                }
250                        }
251                }
252                return titledSheets; //Array
253        };
254
255        //TODO: Does not recursively search for @imports, so it will
256        //              only go one level deep.
257        dh.getStyleSheets = function(){
258                // summary:
259                //              Collects all the style sheets referenced in the HTML page,
260                //              including any included via @import.
261                // returns:
262                //              An hash map of all the style sheets.
263                if(pageStyleSheets.collected) {return pageStyleSheets;}
264                var sheets = Window.doc.styleSheets;
265                ArrayUtil.forEach(sheets, function(n){
266                        var s = (n.sheet) ? n.sheet : n;
267                        var name = s.title || s.href;
268                        if(has("ie")){
269                                // IE attaches a style sheet for VML - do not include this
270                                if(s.cssText.indexOf("#default#VML") === -1){
271                                        if(s.href){
272                                                // linked
273                                                pageStyleSheets[name] = s;
274                                        }else if(s.imports.length){
275                                                // Imported via @import
276                                                ArrayUtil.forEach(s.imports, function(si){
277                                                        pageStyleSheets[si.title || si.href] = si;
278                                                });
279                                        }else{
280                                                //embedded within page
281                                                pageStyleSheets[name] = s;
282                                        }
283                                }
284                        }else{
285                                //linked or embedded
286                                pageStyleSheets[name] = s;
287                                pageStyleSheets[name].id = s.ownerNode.id;
288                                ArrayUtil.forEach(s.cssRules, function(r){
289                                        if(r.href){
290                                                // imported
291                                                pageStyleSheets[r.href] = r.styleSheet;
292                                                pageStyleSheets[r.href].id = s.ownerNode.id;
293                                        }
294                                });
295                        }
296                });
297                //console.log("pageStyleSheets:", pageStyleSheets);
298                pageStyleSheets.collected = true;
299                return pageStyleSheets; //Object
300        };
301       
302        return dh;
303});
Note: See TracBrowser for help on using the repository browser.