-
Notifications
You must be signed in to change notification settings - Fork 46
Expand file tree
/
Copy pathmonolithic.js
More file actions
90 lines (74 loc) · 2.06 KB
/
monolithic.js
File metadata and controls
90 lines (74 loc) · 2.06 KB
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
let cache = {}
let prefix = '_cxs'
const cssRules = []
let insert = rule => cssRules.push(rule)
const hyph = s => s.replace(/[A-Z]|^ms/g, '-$&').toLowerCase()
const mx = (rule, media) => media ? `${media}{${rule}}` : rule
const noAnd = s => s.replace(/&/g, '')
const createDeclaration = (key, value) => hyph(key) + ':' + value
const createRule = ({
className,
child,
media,
declarations
}) => mx(`.${className + child}{${declarations.join(';')}}`, media)
const parseRules = (obj, child = '', media) => {
const rules = []
const declarations = []
for (let key in obj) {
const value = obj[key]
if (value === null) continue
if (typeof value === 'object') {
const _media = /^@/.test(key) ? key : null
const _child = _media ? child : child + noAnd(key)
parseRules(value, _child, _media)
.forEach(r => rules.push(r))
continue
}
const dec = createDeclaration(key, value)
declarations.push(dec)
}
rules.unshift({
media,
child,
declarations
})
return rules
}
const parse = obj => {
const rules = parseRules(obj)
const classNames = []
rules.forEach(rule => {
const key = JSON.stringify(rule)
if (cache[key]) {
classNames.push(cache[key])
return
}
const className = prefix + cssRules.length.toString(36)
classNames.push(className)
const ruleset = createRule(Object.assign(rule, { className }))
insert(ruleset)
cache[key] = className
})
return classNames.join(' ')
}
module.exports = (...styles) =>
styles.map(style => parse(style))
.join(' ').trim()
module.exports.css = () => cssRules.sort().join('')
module.exports.reset = () => {
cache = {}
while (cssRules.length) cssRules.pop()
}
module.exports.prefix = val => prefix = val
if (typeof document !== 'undefined') {
const s = document.createElement('style')
if (window) s.nonce = window.__webpack_nonce__
const style = document.head.appendChild(s)
const sheet = style.sheet
style.id = '_cxs_'
insert = rule => {
cssRules.push(rule)
sheet.insertRule(rule, sheet.cssRules.length)
}
}