postcss 8.5.9 → 8.5.11
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/lazy-result.js +10 -0
- package/lib/processor.js +1 -1
- package/lib/stringifier.js +69 -28
- package/lib/tokenize.js +4 -0
- package/package.json +1 -1
package/lib/lazy-result.js
CHANGED
|
@@ -378,6 +378,16 @@ class LazyResult {
|
|
|
378
378
|
if (opts.stringifier) str = opts.stringifier
|
|
379
379
|
if (str.stringify) str = str.stringify
|
|
380
380
|
|
|
381
|
+
let rootSource = this.result.root.source
|
|
382
|
+
if (opts.map === undefined && !(rootSource && rootSource.input && rootSource.input.map)) {
|
|
383
|
+
let result = ''
|
|
384
|
+
str(this.result.root, i => {
|
|
385
|
+
result += i
|
|
386
|
+
})
|
|
387
|
+
this.result.css = result
|
|
388
|
+
return this.result
|
|
389
|
+
}
|
|
390
|
+
|
|
381
391
|
let map = new MapGenerator(str, this.result.root, this.result.opts)
|
|
382
392
|
let data = map.generate()
|
|
383
393
|
this.result.css = data[0]
|
package/lib/processor.js
CHANGED
package/lib/stringifier.js
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
// Escapes sequences that could break out of an HTML <style> context.
|
|
4
|
+
// Uses CSS unicode escaping (\3c = '<') which is valid CSS and parsed
|
|
5
|
+
// correctly by all compliant CSS consumers.
|
|
6
|
+
const STYLE_TAG = /(<)(\/?style\b)/gi
|
|
7
|
+
const COMMENT_OPEN = /(<)(!--)/g
|
|
8
|
+
|
|
9
|
+
function escapeHTMLInCSS(str) {
|
|
10
|
+
if (typeof str !== 'string') return str
|
|
11
|
+
if (!str.includes('<')) return str
|
|
12
|
+
return str.replace(STYLE_TAG, '\\3c $2').replace(COMMENT_OPEN, '\\3c $2')
|
|
13
|
+
}
|
|
14
|
+
|
|
3
15
|
const DEFAULT_RAW = {
|
|
4
16
|
after: '\n',
|
|
5
17
|
beforeClose: '\n',
|
|
@@ -25,11 +37,12 @@ class Stringifier {
|
|
|
25
37
|
}
|
|
26
38
|
|
|
27
39
|
atrule(node, semicolon) {
|
|
40
|
+
let raws = node.raws
|
|
28
41
|
let name = '@' + node.name
|
|
29
42
|
let params = node.params ? this.rawValue(node, 'params') : ''
|
|
30
43
|
|
|
31
|
-
if (typeof
|
|
32
|
-
name +=
|
|
44
|
+
if (typeof raws.afterName !== 'undefined') {
|
|
45
|
+
name += raws.afterName
|
|
33
46
|
} else if (params) {
|
|
34
47
|
name += ' '
|
|
35
48
|
}
|
|
@@ -37,8 +50,8 @@ class Stringifier {
|
|
|
37
50
|
if (node.nodes) {
|
|
38
51
|
this.block(node, name + params)
|
|
39
52
|
} else {
|
|
40
|
-
let end = (
|
|
41
|
-
this.builder(name + params + end, node)
|
|
53
|
+
let end = (raws.between || '') + (semicolon ? ';' : '')
|
|
54
|
+
this.builder(escapeHTMLInCSS(name + params + end), node)
|
|
42
55
|
}
|
|
43
56
|
}
|
|
44
57
|
|
|
@@ -72,53 +85,77 @@ class Stringifier {
|
|
|
72
85
|
}
|
|
73
86
|
|
|
74
87
|
block(node, start) {
|
|
75
|
-
let
|
|
76
|
-
|
|
88
|
+
let raws = node.raws
|
|
89
|
+
let between = typeof raws.between !== 'undefined'
|
|
90
|
+
? raws.between
|
|
91
|
+
: this.raw(node, 'between', 'beforeOpen')
|
|
92
|
+
this.builder(escapeHTMLInCSS(start + between) + '{', node, 'start')
|
|
77
93
|
|
|
78
94
|
let after
|
|
79
95
|
if (node.nodes && node.nodes.length) {
|
|
80
96
|
this.body(node)
|
|
81
|
-
after =
|
|
97
|
+
after = typeof raws.after !== 'undefined'
|
|
98
|
+
? raws.after
|
|
99
|
+
: this.raw(node, 'after')
|
|
82
100
|
} else {
|
|
83
|
-
after =
|
|
101
|
+
after = typeof raws.after !== 'undefined'
|
|
102
|
+
? raws.after
|
|
103
|
+
: this.raw(node, 'after', 'emptyBody')
|
|
84
104
|
}
|
|
85
105
|
|
|
86
|
-
if (after) this.builder(after)
|
|
106
|
+
if (after) this.builder(escapeHTMLInCSS(after))
|
|
87
107
|
this.builder('}', node, 'end')
|
|
88
108
|
}
|
|
89
109
|
|
|
90
110
|
body(node) {
|
|
91
|
-
let
|
|
111
|
+
let nodes = node.nodes
|
|
112
|
+
let last = nodes.length - 1
|
|
92
113
|
while (last > 0) {
|
|
93
|
-
if (
|
|
114
|
+
if (nodes[last].type !== 'comment') break
|
|
94
115
|
last -= 1
|
|
95
116
|
}
|
|
96
117
|
|
|
97
118
|
let semicolon = this.raw(node, 'semicolon')
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
let
|
|
101
|
-
|
|
119
|
+
let isDocument = node.type === 'document'
|
|
120
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
121
|
+
let child = nodes[i]
|
|
122
|
+
let before = child.raws.before
|
|
123
|
+
if (typeof before === 'undefined') {
|
|
124
|
+
before = this.raw(child, 'before')
|
|
125
|
+
}
|
|
126
|
+
if (before) this.builder(isDocument ? before : escapeHTMLInCSS(before))
|
|
102
127
|
this.stringify(child, last !== i || semicolon)
|
|
103
128
|
}
|
|
104
129
|
}
|
|
105
130
|
|
|
106
131
|
comment(node) {
|
|
107
|
-
let
|
|
108
|
-
let
|
|
109
|
-
|
|
132
|
+
let raws = node.raws
|
|
133
|
+
let left = typeof raws.left !== 'undefined'
|
|
134
|
+
? raws.left
|
|
135
|
+
: this.raw(node, 'left', 'commentLeft')
|
|
136
|
+
let right = typeof raws.right !== 'undefined'
|
|
137
|
+
? raws.right
|
|
138
|
+
: this.raw(node, 'right', 'commentRight')
|
|
139
|
+
this.builder(escapeHTMLInCSS('/*' + left + node.text + right + '*/'), node)
|
|
110
140
|
}
|
|
111
141
|
|
|
112
142
|
decl(node, semicolon) {
|
|
113
|
-
let
|
|
114
|
-
let
|
|
143
|
+
let raws = node.raws
|
|
144
|
+
let between = typeof raws.between !== 'undefined'
|
|
145
|
+
? raws.between
|
|
146
|
+
: this.raw(node, 'between', 'colon')
|
|
147
|
+
|
|
148
|
+
let rawVal = raws.value
|
|
149
|
+
let value = rawVal && rawVal.value === node.value ? rawVal.raw : node.value
|
|
150
|
+
|
|
151
|
+
let string = node.prop + between + value
|
|
115
152
|
|
|
116
153
|
if (node.important) {
|
|
117
|
-
string +=
|
|
154
|
+
string += raws.important || ' !important'
|
|
118
155
|
}
|
|
119
156
|
|
|
120
157
|
if (semicolon) string += ';'
|
|
121
|
-
this.builder(string, node)
|
|
158
|
+
this.builder(escapeHTMLInCSS(string), node)
|
|
122
159
|
}
|
|
123
160
|
|
|
124
161
|
document(node) {
|
|
@@ -154,9 +191,9 @@ class Stringifier {
|
|
|
154
191
|
|
|
155
192
|
// Detect style by other nodes
|
|
156
193
|
let root = node.root()
|
|
157
|
-
|
|
158
|
-
if (typeof
|
|
159
|
-
return
|
|
194
|
+
let cache = root.rawCache || (root.rawCache = {})
|
|
195
|
+
if (typeof cache[detect] !== 'undefined') {
|
|
196
|
+
return cache[detect]
|
|
160
197
|
}
|
|
161
198
|
|
|
162
199
|
if (detect === 'before' || detect === 'after') {
|
|
@@ -175,7 +212,7 @@ class Stringifier {
|
|
|
175
212
|
|
|
176
213
|
if (typeof value === 'undefined') value = DEFAULT_RAW[detect]
|
|
177
214
|
|
|
178
|
-
|
|
215
|
+
cache[detect] = value
|
|
179
216
|
return value
|
|
180
217
|
}
|
|
181
218
|
|
|
@@ -324,13 +361,17 @@ class Stringifier {
|
|
|
324
361
|
|
|
325
362
|
root(node) {
|
|
326
363
|
this.body(node)
|
|
327
|
-
if (node.raws.after)
|
|
364
|
+
if (node.raws.after) {
|
|
365
|
+
let after = node.raws.after
|
|
366
|
+
let isDocument = node.parent && node.parent.type === 'document'
|
|
367
|
+
this.builder(isDocument ? after : escapeHTMLInCSS(after))
|
|
368
|
+
}
|
|
328
369
|
}
|
|
329
370
|
|
|
330
371
|
rule(node) {
|
|
331
372
|
this.block(node, this.rawValue(node, 'selector'))
|
|
332
373
|
if (node.raws.ownSemicolon) {
|
|
333
|
-
this.builder(node.raws.ownSemicolon, node, 'end')
|
|
374
|
+
this.builder(escapeHTMLInCSS(node.raws.ownSemicolon), node, 'end')
|
|
334
375
|
}
|
|
335
376
|
}
|
|
336
377
|
|
package/lib/tokenize.js
CHANGED
|
@@ -36,6 +36,7 @@ module.exports = function tokenizer(input, options = {}) {
|
|
|
36
36
|
let pos = 0
|
|
37
37
|
let buffer = []
|
|
38
38
|
let returned = []
|
|
39
|
+
let lastBadParen = -1
|
|
39
40
|
|
|
40
41
|
function position() {
|
|
41
42
|
return pos
|
|
@@ -127,11 +128,14 @@ module.exports = function tokenizer(input, options = {}) {
|
|
|
127
128
|
currentToken = ['brackets', css.slice(pos, next + 1), pos, next]
|
|
128
129
|
|
|
129
130
|
pos = next
|
|
131
|
+
} else if (pos <= lastBadParen) {
|
|
132
|
+
currentToken = ['(', '(', pos]
|
|
130
133
|
} else {
|
|
131
134
|
next = css.indexOf(')', pos + 1)
|
|
132
135
|
content = css.slice(pos, next + 1)
|
|
133
136
|
|
|
134
137
|
if (next === -1 || RE_BAD_BRACKET.test(content)) {
|
|
138
|
+
lastBadParen = next === -1 ? length : next
|
|
135
139
|
currentToken = ['(', '(', pos]
|
|
136
140
|
} else {
|
|
137
141
|
currentToken = ['brackets', content, pos, next]
|