initial import
[roojs1] / Roo / util / CSS.js
1 /*
2  * Based on:
3  * Ext JS Library 1.1.1
4  * Copyright(c) 2006-2007, Ext JS, LLC.
5  *
6  * Originally Released Under LGPL - original licence link has changed is not relivant.
7  *
8  * Fork - LGPL
9  * <script type="text/javascript">
10  */
11
12  
13 /**
14  * @class Roo.util.CSS
15  * Utility class for manipulating CSS rules
16  * @singleton
17  */
18 Roo.util.CSS = function(){
19         var rules = null;
20         var doc = document;
21
22     var camelRe = /(-[a-z])/gi;
23     var camelFn = function(m, a){ return a.charAt(1).toUpperCase(); };
24
25    return {
26    /**
27     * Very simple dynamic creation of stylesheets from a text blob of rules.  The text will wrapped in a style
28     * tag and appended to the HEAD of the document.
29     * @param {String} cssText The text containing the css rules
30     * @param {String} id An id to add to the stylesheet for later removal
31     * @return {StyleSheet}
32     */
33    createStyleSheet : function(cssText, id){
34        var ss;
35        var head = doc.getElementsByTagName("head")[0];
36        var rules = doc.createElement("style");
37        rules.setAttribute("type", "text/css");
38        if(id){
39            rules.setAttribute("id", id);
40        }
41        if(Roo.isIE){
42            head.appendChild(rules);
43            ss = rules.styleSheet;
44            ss.cssText = cssText;
45        }else{
46            try{
47                 rules.appendChild(doc.createTextNode(cssText));
48            }catch(e){
49                rules.cssText = cssText; 
50            }
51            head.appendChild(rules);
52            ss = rules.styleSheet ? rules.styleSheet : (rules.sheet || doc.styleSheets[doc.styleSheets.length-1]);
53        }
54        this.cacheStyleSheet(ss);
55        return ss;
56    },
57
58    /**
59     * Removes a style or link tag by id
60     * @param {String} id The id of the tag
61     */
62    removeStyleSheet : function(id){
63        var existing = doc.getElementById(id);
64        if(existing){
65            existing.parentNode.removeChild(existing);
66        }
67    },
68
69    /**
70     * Dynamically swaps an existing stylesheet reference for a new one
71     * @param {String} id The id of an existing link tag to remove
72     * @param {String} url The href of the new stylesheet to include
73     */
74    swapStyleSheet : function(id, url){
75        this.removeStyleSheet(id);
76        var ss = doc.createElement("link");
77        ss.setAttribute("rel", "stylesheet");
78        ss.setAttribute("type", "text/css");
79        ss.setAttribute("id", id);
80        ss.setAttribute("href", url);
81        doc.getElementsByTagName("head")[0].appendChild(ss);
82    },
83    
84    /**
85     * Refresh the rule cache if you have dynamically added stylesheets
86     * @return {Object} An object (hash) of rules indexed by selector
87     */
88    refreshCache : function(){
89        return this.getRules(true);
90    },
91
92    // private
93    cacheStyleSheet : function(ss){
94        if(!rules){
95            rules = {};
96        }
97        try{// try catch for cross domain access issue
98            var ssRules = ss.cssRules || ss.rules;
99            for(var j = ssRules.length-1; j >= 0; --j){
100                rules[ssRules[j].selectorText] = ssRules[j];
101            }
102        }catch(e){}
103    },
104    
105    /**
106     * Gets all css rules for the document
107     * @param {Boolean} refreshCache true to refresh the internal cache
108     * @return {Object} An object (hash) of rules indexed by selector
109     */
110    getRules : function(refreshCache){
111                 if(rules == null || refreshCache){
112                         rules = {};
113                         var ds = doc.styleSheets;
114                         for(var i =0, len = ds.length; i < len; i++){
115                             try{
116                         this.cacheStyleSheet(ds[i]);
117                     }catch(e){} 
118                 }
119                 }
120                 return rules;
121         },
122         
123         /**
124     * Gets an an individual CSS rule by selector(s)
125     * @param {String/Array} selector The CSS selector or an array of selectors to try. The first selector that is found is returned.
126     * @param {Boolean} refreshCache true to refresh the internal cache if you have recently updated any rules or added styles dynamically
127     * @return {CSSRule} The CSS rule or null if one is not found
128     */
129    getRule : function(selector, refreshCache){
130                 var rs = this.getRules(refreshCache);
131                 if(!(selector instanceof Array)){
132                     return rs[selector];
133                 }
134                 for(var i = 0; i < selector.length; i++){
135                         if(rs[selector[i]]){
136                                 return rs[selector[i]];
137                         }
138                 }
139                 return null;
140         },
141         
142         
143         /**
144     * Updates a rule property
145     * @param {String/Array} selector If it's an array it tries each selector until it finds one. Stops immediately once one is found.
146     * @param {String} property The css property
147     * @param {String} value The new value for the property
148     * @return {Boolean} true If a rule was found and updated
149     */
150    updateRule : function(selector, property, value){
151                 if(!(selector instanceof Array)){
152                         var rule = this.getRule(selector);
153                         if(rule){
154                                 rule.style[property.replace(camelRe, camelFn)] = value;
155                                 return true;
156                         }
157                 }else{
158                         for(var i = 0; i < selector.length; i++){
159                                 if(this.updateRule(selector[i], property, value)){
160                                         return true;
161                                 }
162                         }
163                 }
164                 return false;
165         }
166    };   
167 }();