PageSourceSearch

https://writeapp.io/jss.js

js writeapp.io collected 2026-10-08 03:30:37 UTC 8,701 bytes, 274 lines download raw bytes

1/*
2 * JSS v0.3 - JavaScript Stylesheets
3 * https://github.com/Box9/jss
4 *
5 * Copyright (c) 2011, David Tang
6 * MIT Licensed (http://www.opensource.org/licenses/mit-license.php)
7 */
8
9var jss = (function (undefined) {
10    var jss,
11        Jss,
12        // Shortcuts
13        doc = document,
14        head = doc.head || doc.getElementsByTagName('head')[0],
15        sheets = doc.styleSheets,
16        adjSelAttrRgx = /((?:\.|#)[^\.\s#]+)((?:\.|#)[^\.\s#]+)/g;
17    
18    jss = function (selector, sheet) {
19        var obj = new Jss();
20        obj.init(selector, sheet);
21        return obj;
22    };
23    
24    // Core functions for manipulating stylesheets
25    
26    jss._sheetToNode = function (sheet) {
27        return sheet.ownerNode || sheet.owningElement;
28    };
29    
30    jss._nodeToSheet = function (node) {
31        var result = null,
32            i;
33        
34        for (i = 0; i < sheets.length; i++) {
35            if (node === jss._sheetToNode(sheets[i])) {
36                result = sheets[i];
37                break;
38            }
39        }
40        
41        return result;
42    };
43    
44    jss._getSheets = function (sheetSelector) {
45        var results = [],
46            node,
47            i;
48        
49        if (!sheetSelector) {
50            results = sheets;
51        } else if (typeof sheetSelector == 'number') {
52            results = [sheets[sheetSelector]];
53        } else if (typeof sheetSelector == 'object') {
54            if (sheetSelector.href) {
55                for (i = 0; i < sheets.length; i++) {
56                    node = jss._sheetToNode(sheets[i]);
57                    if (sheetSelector.href && node.href == sheetSelector.href ||
58                        sheetSelector.title && node.title == sheetSelector.title) {
59                        results.push(sheets[i]);
60                    }
61                }
62            }
63        }
64        
65        return results;
66    };
67    
68    jss._addSheet = function () {
69        var styleNode = doc.createElement('style'),
70            i;
71        
72        styleNode.type = 'text/css';
73        styleNode.rel = 'stylesheet';
74        head.appendChild(styleNode);
75        
76        return jss._nodeToSheet(styleNode);
77    };
78    
79    jss._removeSheet = function (sheet) {
80        var node = jss._sheetToNode(sheet);
81        node.parentNode.removeChild(node);
82    };
83    
84    jss._getRules = function (sheet, selector) {
85        var results = [],
86            rules,
87            i,
88            ruleText,
89            selText;
90
91        // Browsers report selectors in lowercase
92        if (selector) selector = selector.toLowerCase();
93
94        if (typeof sheet.length == 'number') {
95            // Array of sheets
96            for (i = 0; i < sheet.length; i++) {
97                results = results.concat(jss._getRules(sheet[i], selector));
98            }
99        } else {
100            // Single sheet
101            rules = sheet.cssRules || sheet.rules;
102            for (i = 0; i < rules.length; i++) {
103                // Warning, selectorText may not be correct in IE<9
104                // as it splits selectors with ',' into multiple rules.
105                // Also, certain rules (e.g. @rules) don't have selectorText
106                if (rules[i].selectorText) {
107                    ruleText = rules[i].selectorText;
108                    if (!selector || ruleText == selector || ruleText == jss._swapAdjSelAttr(selector)) {
109                        results.push({
110                            sheet: sheet,
111                            index: i,
112                            style: rules[i].style
113                        });
114                    }
115                }
116            }
117        }
118
119        return results;
120    };
121    
122    // IE9 stores rules with attributes (classes or ID's) adjacent in the opposite order as defined
123    // causing them to not be found, so this method swaps [#|.]sel1[#|.]sel2 to become [#|.]sel2[#|.]sel1
124    jss._swapAdjSelAttr = function (selector) {
125        var swap = '',
126            lastIndex = 0;
127            
128        while ((match = adjSelAttrRgx.exec(selector)) != null) {
129            if (match[0] == '') break;
130            swap += selector.substring(lastIndex, match.index);
131            swap += selector.substr(match.index + match[1].length, match[2].length);
132            swap += selector.substr(match.index, match[1].length);
133            lastIndex = match.index + match[0].length;
134        }
135        swap += selector.substr(lastIndex);
136        
137        return swap;
138    };
139
140    // Add an (empty) rule
141    jss._addRule = function (sheet, selector) {
142        var rules = sheet.cssRules || sheet.rules,
143            index = rules.length;
144
145        if (sheet.insertRule) {
146            sheet.insertRule(selector + ' { }', index);
147        } else if (sheet.addRule) {
148            sheet.addRule(selector, null, index);
149        }
150        
151        return {
152            sheet: sheet,
153            index: index,
154            style: rules[index].style
155        };
156    };
157    
158    jss._removeRule = function (rule) {
159        var sheet = rule.sheet,
160            index = rule.index;
161
162        if (sheet.deleteRule) {
163            sheet.deleteRule(index);
164        } else if (sheet.removeRule) {
165            sheet.removeRule(index);
166        }
167    };
168    
169    jss._toCamelCase = function(prop) {
170        return prop.replace(/-([a-z])/gi, function(s, group1) {return group1.toUpperCase();});
171    };
172    
173    // Object structure for some code candy
174    Jss = function () {};
175
176    Jss.prototype = {
177        init: function (selector, sheet) {
178            var i;
179
180            if (sheet == null) {
181                if (!this.sheets) this.sheets = jss._getSheets();
182            } else if (sheet === jss) {
183                if (jss.dfault === undefined)
184                    jss.dfault = jss._addSheet();
185                this.sheets = [jss.dfault];
186            } else if (typeof sheet == 'number') {
187                this.sheets = jss._getSheets(sheet);
188            } else if (typeof sheet == 'object') {
189                // Recursive call to init
190                return this.init(selector, jss).add(sheet);
191            }
192
193            this.selector = selector;
194            
195            return this;
196        },
197        add: function (prop, value) {
198            var i;
199
200            // Add new rule to every sheet that doesn't already have it
201            for (i = 0; i < this.sheets.length; i++) {
202                if (jss._getRules(this.sheets[i], this.selector).length == 0) {
203                    jss._addRule(this.sheets[i], this.selector);
204                }
205            }
206
207            this.set(prop, value);
208
209            return this;
210        },
211        set: function (prop, value) {
212            var i,
213                rules,
214                propName;
215
216            if (value === undefined) {
217                if (prop && typeof prop == 'object') {
218                    for (i in prop) {
219                        if (!prop.hasOwnProperty(i)) continue;
220                        this.set(i, prop[i]);
221                    }
222                }
223            } else {
224                rules = jss._getRules(this.sheets, this.selector);
225                propName = jss._toCamelCase(prop);
226                // Set properties for each rule
227                for (i = 0; i < rules.length; i++) {
228                    rules[i].style[propName] = value;
229                }
230            }
231
232            return this;
233        },
234        get: function (prop) {
235            var result,
236                rules = jss._getRules(this.sheets, this.selector),
237                propName,
238                i,
239                j;
240
241            if (prop !== undefined) {
242                propName = jss._toCamelCase(prop);
243                for (i = rules.length - 1; i >=0; i--) {
244                    // added test for emtpy string to handle style selector defined more than once
245                    if (rules[i].style[propName] != null && rules[i].style[propName] != '') {
246                        result = rules[i].style[propName];
247                        break;
248                    }
249                }
250            } else {
251                result = {};
252                for (i = 0; i < rules.length; i++) {
253                    for (j = 0; j < rules[i].style.length; j++) {
254                        propName = rules[i].style[j];
255                        result[propName] = rules[i].style[propName];
256                    }
257                }
258            }
259            
260            return result;
261        },
262        remove: function () {
263            var rules = jss._getRules(this.sheets, this.selector),
264                i;
265
266            // Remove backwards so indices don't shift
267            for (i = rules.length - 1; i >= 0; i--) {
268                jss._removeRule(rules[i]);
269            }
270        }
271    };
272    
273    return jss;
274})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.