-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
103 lines (83 loc) · 2.5 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
(function() {
'use strict';
var indexedStyles = {};
var _sheet = null;
var tackClasses = new Set();
const COMPLEX_SELECTOR_TOKENS = [' ', '.', ':', '[', ']'];
function isClassSelector(selectorText) {
if (selectorText[0] !== '.') {
return false;
}
for (var i = 1; i < selectorText.length; i++) {
if (COMPLEX_SELECTOR_TOKENS.indexOf(selectorText[i]) !== -1) {
return false;
}
}
return true;
}
function sheet() {
if (_sheet) {
return _sheet;
}
var style = document.createElement('style');
// WebKit support.
style.appendChild(document.createTextNode(''));
document.head.appendChild(style);
_sheet = style.sheet;
return _sheet;
}
var Tack = function(pseudoClass) {
const classes = [].splice.call(arguments, 1);
return classes
.map(className => {
if (!className) {
return null;
}
if (className[0] !== '.') {
className = '.' + className;
}
const style = indexedStyles[className];
if (!style) {
// Unknown style.
return null;
}
const tackClassName = className + '--tack-' + pseudoClass;
if (!tackClasses.has(tackClassName)) {
// Generate CSS class.
const rulesIndex = style.cssText.indexOf('{');
if (rulesIndex === -1) {
// Couldn't find CSS rules.
return null;
}
const rules = style.cssText.substring(rulesIndex);
sheet().insertRule(tackClassName + ':' + pseudoClass + ' ' + rules);
tackClasses.add(tackClassName);
}
return tackClassName.substring(1);
})
.filter(tackClassName => !!tackClassName)
.join(' ');
}
Tack.hash = function() {
indexedStyles = {};
Array.prototype.forEach.call(document.styleSheets, function(styleSheet) {
Array.prototype.forEach.call(styleSheet.cssRules || [], function(cssRule) {
const selectorText = cssRule.selectorText;
if (!selectorText || !isClassSelector(selectorText)) {
return;
}
indexedStyles[selectorText] = cssRule;
});
});
}
if (typeof module !== 'undefined' && module.exports) {
module.exports = Tack;
} else if (typeof define === 'function' && typeof define.amd === 'object' && define.amd) {
// Register as 'tack-css', consistent with npm package name.
define('tack-css', [], function () {
return Tack;
});
} else {
window.tack = Tack;
}
}());