source: Dev/branches/rest-dojo-ui/client/dojox/html/styles.js @ 256

Last change on this file since 256 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

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