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.
@@ -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
@@ -7,7 +7,7 @@ let Root = require('./root')
7
7
 
8
8
  class Processor {
9
9
  constructor(plugins = []) {
10
- this.version = '8.5.9'
10
+ this.version = '8.5.11'
11
11
  this.plugins = this.normalize(plugins)
12
12
  }
13
13
 
@@ -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 node.raws.afterName !== 'undefined') {
32
- name += node.raws.afterName
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 = (node.raws.between || '') + (semicolon ? ';' : '')
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 between = this.raw(node, 'between', 'beforeOpen')
76
- this.builder(start + between + '{', node, 'start')
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 = this.raw(node, 'after')
97
+ after = typeof raws.after !== 'undefined'
98
+ ? raws.after
99
+ : this.raw(node, 'after')
82
100
  } else {
83
- after = this.raw(node, 'after', 'emptyBody')
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 last = node.nodes.length - 1
111
+ let nodes = node.nodes
112
+ let last = nodes.length - 1
92
113
  while (last > 0) {
93
- if (node.nodes[last].type !== 'comment') break
114
+ if (nodes[last].type !== 'comment') break
94
115
  last -= 1
95
116
  }
96
117
 
97
118
  let semicolon = this.raw(node, 'semicolon')
98
- for (let i = 0; i < node.nodes.length; i++) {
99
- let child = node.nodes[i]
100
- let before = this.raw(child, 'before')
101
- if (before) this.builder(before)
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 left = this.raw(node, 'left', 'commentLeft')
108
- let right = this.raw(node, 'right', 'commentRight')
109
- this.builder('/*' + left + node.text + right + '*/', node)
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 between = this.raw(node, 'between', 'colon')
114
- let string = node.prop + between + this.rawValue(node, 'value')
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 += node.raws.important || ' !important'
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
- if (!root.rawCache) root.rawCache = {}
158
- if (typeof root.rawCache[detect] !== 'undefined') {
159
- return root.rawCache[detect]
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
- root.rawCache[detect] = value
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) this.builder(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]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "postcss",
3
- "version": "8.5.9",
3
+ "version": "8.5.11",
4
4
  "description": "Tool for transforming styles with JS plugins",
5
5
  "keywords": [
6
6
  "css",