sugar-high 2.0.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/presets/lang/css.js +81 -0
- package/package.json +1 -1
package/lib/presets/lang/css.js
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
// @ts-check
|
|
2
|
+
import {
|
|
3
|
+
T_BREAK, T_CLASS, T_COMMENT, T_IDENTIFIER, T_PROPERTY, T_SIGN, T_SPACE,
|
|
4
|
+
} from '../../shared.js'
|
|
5
|
+
import { tokenize as tokenizePlain } from '../../core.js'
|
|
6
|
+
|
|
2
7
|
export const keywords = new Set([
|
|
3
8
|
// css keywords like @media, @import, @keyframes, etc.
|
|
4
9
|
'@media', '@import', '@keyframes', '@font-face', '@supports', '@page', '@counter-style',
|
|
@@ -17,3 +22,79 @@ export const onLiteral = (curr, index, code) => {
|
|
|
17
22
|
if (curr !== '#') return 0
|
|
18
23
|
return code.slice(index).match(/^#(?:[\da-f]{8}|[\da-f]{6}|[\da-f]{4}|[\da-f]{3})(?![\w-])/i)?.[0].length || 0
|
|
19
24
|
}
|
|
25
|
+
|
|
26
|
+
const isIgnored = (type) => type === T_SPACE || type === T_BREAK || type === T_COMMENT
|
|
27
|
+
const isPropertyPart = ([type, value]) =>
|
|
28
|
+
type === T_IDENTIFIER || type === T_CLASS || (type === T_SIGN && value === '-')
|
|
29
|
+
|
|
30
|
+
/** Return true when a colon belongs to a nested selector instead of a declaration. */
|
|
31
|
+
const opensBlock = (tokens, start) => {
|
|
32
|
+
let parentheses = 0
|
|
33
|
+
let brackets = 0
|
|
34
|
+
for (let index = start; index < tokens.length; index++) {
|
|
35
|
+
const [type, value] = tokens[index]
|
|
36
|
+
if (type !== T_SIGN) continue
|
|
37
|
+
if (value === '(') parentheses++
|
|
38
|
+
else if (value === ')') parentheses--
|
|
39
|
+
else if (value === '[') brackets++
|
|
40
|
+
else if (value === ']') brackets--
|
|
41
|
+
else if (!parentheses && !brackets && value === '{') return true
|
|
42
|
+
else if (!parentheses && !brackets && (value === ';' || value === '}')) return false
|
|
43
|
+
}
|
|
44
|
+
return false
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Add CSS declaration context after the shared plain lexer runs.
|
|
49
|
+
* @param {string} code
|
|
50
|
+
* @param {import('../../core.js').ParseOptions} options
|
|
51
|
+
*/
|
|
52
|
+
export const tokenize = (code, options) => {
|
|
53
|
+
const tokens = tokenizePlain(code, { ...options, tokenize: undefined })
|
|
54
|
+
let blockDepth = 0
|
|
55
|
+
let declarationStart = false
|
|
56
|
+
|
|
57
|
+
for (let index = 0; index < tokens.length; index++) {
|
|
58
|
+
const [type, value] = tokens[index]
|
|
59
|
+
|
|
60
|
+
if (type === T_SIGN && value === '{') {
|
|
61
|
+
blockDepth++
|
|
62
|
+
declarationStart = true
|
|
63
|
+
continue
|
|
64
|
+
}
|
|
65
|
+
if (type === T_SIGN && value === '}') {
|
|
66
|
+
blockDepth--
|
|
67
|
+
declarationStart = false
|
|
68
|
+
continue
|
|
69
|
+
}
|
|
70
|
+
if (type === T_SIGN && value === ';') {
|
|
71
|
+
declarationStart = blockDepth > 0
|
|
72
|
+
continue
|
|
73
|
+
}
|
|
74
|
+
if (!declarationStart || isIgnored(type)) continue
|
|
75
|
+
|
|
76
|
+
const propertyStart = index
|
|
77
|
+
let propertyEnd = index
|
|
78
|
+
while (propertyEnd < tokens.length && isPropertyPart(tokens[propertyEnd])) {
|
|
79
|
+
propertyEnd++
|
|
80
|
+
}
|
|
81
|
+
let colon = propertyEnd
|
|
82
|
+
while (colon < tokens.length && isIgnored(tokens[colon][0])) colon++
|
|
83
|
+
|
|
84
|
+
if (
|
|
85
|
+
propertyEnd > propertyStart &&
|
|
86
|
+
tokens[colon]?.[0] === T_SIGN &&
|
|
87
|
+
tokens[colon][1] === ':' &&
|
|
88
|
+
!opensBlock(tokens, colon + 1)
|
|
89
|
+
) {
|
|
90
|
+
const property = tokens
|
|
91
|
+
.slice(propertyStart, propertyEnd)
|
|
92
|
+
.map(([, part]) => part)
|
|
93
|
+
.join('')
|
|
94
|
+
tokens.splice(propertyStart, propertyEnd - propertyStart, [T_PROPERTY, property])
|
|
95
|
+
}
|
|
96
|
+
declarationStart = false
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return tokens
|
|
100
|
+
}
|