postcss 8.2.13 → 8.3.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.

Potentially problematic release.


This version of postcss might be problematic. Click here for more details.

package/lib/at-rule.d.ts CHANGED
@@ -37,8 +37,11 @@ interface AtRuleRaws {
37
37
  }
38
38
 
39
39
  export interface AtRuleProps extends ContainerProps {
40
+ /** Name of the at-rule. */
40
41
  name: string
42
+ /** Parameters following the name of the at-rule. */
41
43
  params?: string | number
44
+ /** Information used to generate byte-to-byte equal node string as it was in the origin input. */
42
45
  raws?: AtRuleRaws
43
46
  }
44
47
 
@@ -69,6 +72,7 @@ export interface AtRuleProps extends ContainerProps {
69
72
  */
70
73
  export default class AtRule extends Container {
71
74
  type: 'atrule'
75
+ parent: Container | undefined
72
76
  raws: AtRuleRaws
73
77
 
74
78
  /**
@@ -95,6 +99,7 @@ export default class AtRule extends Container {
95
99
  params: string
96
100
 
97
101
  constructor(defaults?: AtRuleProps)
102
+ assign(overrides: object | AtRuleProps): this
98
103
  clone(overrides?: Partial<AtRuleProps>): this
99
104
  cloneBefore(overrides?: Partial<AtRuleProps>): this
100
105
  cloneAfter(overrides?: Partial<AtRuleProps>): this
package/lib/comment.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import Container from './container.js'
1
2
  import Node, { NodeProps } from './node.js'
2
3
 
3
4
  interface CommentRaws {
@@ -18,7 +19,9 @@ interface CommentRaws {
18
19
  }
19
20
 
20
21
  export interface CommentProps extends NodeProps {
22
+ /** Content of the comment. */
21
23
  text: string
24
+ /** Information used to generate byte-to-byte equal node string as it was in the origin input. */
22
25
  raws?: CommentRaws
23
26
  }
24
27
 
@@ -37,6 +40,7 @@ export interface CommentProps extends NodeProps {
37
40
  */
38
41
  export default class Comment extends Node {
39
42
  type: 'comment'
43
+ parent: Container | undefined
40
44
  raws: CommentRaws
41
45
 
42
46
  /**
@@ -45,6 +49,7 @@ export default class Comment extends Node {
45
49
  text: string
46
50
 
47
51
  constructor(defaults?: CommentProps)
52
+ assign(overrides: object | CommentProps): this
48
53
  clone(overrides?: Partial<CommentProps>): this
49
54
  cloneBefore(overrides?: Partial<CommentProps>): this
50
55
  cloneAfter(overrides?: Partial<CommentProps>): this
@@ -27,7 +27,9 @@ export interface ContainerProps extends NodeProps {
27
27
  * Note that all containers can store any content. If you write a rule inside
28
28
  * a rule, PostCSS will parse it.
29
29
  */
30
- export default abstract class Container extends Node {
30
+ export default abstract class Container<
31
+ Child extends Node = ChildNode
32
+ > extends Node {
31
33
  /**
32
34
  * An array containing the container’s children.
33
35
  *
@@ -38,7 +40,7 @@ export default abstract class Container extends Node {
38
40
  * root.nodes[0].nodes[0].prop //=> 'color'
39
41
  * ```
40
42
  */
41
- nodes: ChildNode[]
43
+ nodes: Child[]
42
44
 
43
45
  /**
44
46
  * The container’s first child.
@@ -47,7 +49,7 @@ export default abstract class Container extends Node {
47
49
  * rule.first === rules.nodes[0]
48
50
  * ```
49
51
  */
50
- get first(): ChildNode | undefined
52
+ get first(): Child | undefined
51
53
 
52
54
  /**
53
55
  * The container’s last child.
@@ -56,7 +58,7 @@ export default abstract class Container extends Node {
56
58
  * rule.last === rule.nodes[rule.nodes.length - 1]
57
59
  * ```
58
60
  */
59
- get last(): ChildNode | undefined
61
+ get last(): Child | undefined
60
62
 
61
63
  /**
62
64
  * Iterates through the container’s immediate children,
@@ -92,7 +94,7 @@ export default abstract class Container extends Node {
92
94
  * @return Returns `false` if iteration was broke.
93
95
  */
94
96
  each(
95
- callback: (node: ChildNode, index: number) => false | void
97
+ callback: (node: Child, index: number) => false | void
96
98
  ): false | undefined
97
99
 
98
100
  /**
@@ -304,7 +306,7 @@ export default abstract class Container extends Node {
304
306
  * @param child New node.
305
307
  * @return This node for methods chain.
306
308
  */
307
- push(child: ChildNode): this
309
+ push(child: Child): this
308
310
 
309
311
  /**
310
312
  * Insert new node before old node within the container.
@@ -318,14 +320,8 @@ export default abstract class Container extends Node {
318
320
  * @return This node for methods chain.
319
321
  */
320
322
  insertBefore(
321
- oldNode: ChildNode | number,
322
- newNode:
323
- | ChildNode
324
- | ChildProps
325
- | string
326
- | ChildNode[]
327
- | ChildProps[]
328
- | string[]
323
+ oldNode: Child | number,
324
+ newNode: Child | ChildProps | string | Child[] | ChildProps[] | string[]
329
325
  ): this
330
326
 
331
327
  /**
@@ -336,14 +332,8 @@ export default abstract class Container extends Node {
336
332
  * @return This node for methods chain.
337
333
  */
338
334
  insertAfter(
339
- oldNode: ChildNode | number,
340
- newNode:
341
- | ChildNode
342
- | ChildProps
343
- | string
344
- | ChildNode[]
345
- | ChildProps[]
346
- | string[]
335
+ oldNode: Child | number,
336
+ newNode: Child | ChildProps | string | Child[] | ChildProps[] | string[]
347
337
  ): this
348
338
 
349
339
  /**
@@ -360,7 +350,7 @@ export default abstract class Container extends Node {
360
350
  * @param child Child or child’s index.
361
351
  * @return This node for methods chain.
362
352
  */
363
- removeChild(child: ChildNode | number): this
353
+ removeChild(child: Child | number): this
364
354
 
365
355
  /**
366
356
  * Removes all children from the container
@@ -420,7 +410,7 @@ export default abstract class Container extends Node {
420
410
  * @return Is every child pass condition.
421
411
  */
422
412
  every(
423
- condition: (node: ChildNode, index: number, nodes: ChildNode[]) => boolean
413
+ condition: (node: Child, index: number, nodes: Child[]) => boolean
424
414
  ): boolean
425
415
 
426
416
  /**
@@ -435,7 +425,7 @@ export default abstract class Container extends Node {
435
425
  * @return Is some child pass condition.
436
426
  */
437
427
  some(
438
- condition: (node: ChildNode, index: number, nodes: ChildNode[]) => boolean
428
+ condition: (node: Child, index: number, nodes: Child[]) => boolean
439
429
  ): boolean
440
430
 
441
431
  /**
@@ -448,5 +438,5 @@ export default abstract class Container extends Node {
448
438
  * @param child Child of the current container.
449
439
  * @return Child index.
450
440
  */
451
- index(child: ChildNode | number): number
441
+ index(child: Child | number): number
452
442
  }
package/lib/container.js CHANGED
@@ -310,7 +310,7 @@ class Container extends Node {
310
310
  for (let i of nodes) {
311
311
  if (i.parent) i.parent.removeChild(i, 'ignore')
312
312
  }
313
- } else if (nodes.type === 'root') {
313
+ } else if (nodes.type === 'root' && this.type !== 'document') {
314
314
  nodes = nodes.nodes.slice(0)
315
315
  for (let i of nodes) {
316
316
  if (i.parent) i.parent.removeChild(i, 'ignore')
@@ -1,3 +1,4 @@
1
+ import Container from './container.js'
1
2
  import Node from './node.js'
2
3
 
3
4
  interface DeclarationRaws {
@@ -27,8 +28,13 @@ interface DeclarationRaws {
27
28
  }
28
29
 
29
30
  export interface DeclarationProps {
31
+ /** Name of the declaration. */
30
32
  prop: string
33
+ /** Value of the declaration. */
31
34
  value: string
35
+ /** Whether the declaration has an `!important` annotation. */
36
+ important?: boolean
37
+ /** Information used to generate byte-to-byte equal node string as it was in the origin input. */
32
38
  raws?: DeclarationRaws
33
39
  }
34
40
 
@@ -51,6 +57,7 @@ export interface DeclarationProps {
51
57
  */
52
58
  export default class Declaration extends Node {
53
59
  type: 'decl'
60
+ parent: Container | undefined
54
61
  raws: DeclarationRaws
55
62
 
56
63
  /**
@@ -110,6 +117,7 @@ export default class Declaration extends Node {
110
117
  variable: boolean
111
118
 
112
119
  constructor(defaults?: DeclarationProps)
120
+ assign(overrides: object | DeclarationProps): this
113
121
  clone(overrides?: Partial<DeclarationProps>): this
114
122
  cloneBefore(overrides?: Partial<DeclarationProps>): this
115
123
  cloneAfter(overrides?: Partial<DeclarationProps>): this
@@ -0,0 +1,57 @@
1
+ import Container, { ContainerProps } from './container.js'
2
+ import { ProcessOptions } from './postcss.js'
3
+ import Result from './result.js'
4
+ import Root, { RootProps } from './root.js'
5
+
6
+ export interface DocumentProps extends ContainerProps {
7
+ nodes?: Root[]
8
+
9
+ /**
10
+ * Information to generate byte-to-byte equal node string as it was
11
+ * in the origin input.
12
+ *
13
+ * Every parser saves its own properties.
14
+ */
15
+ raws?: Record<string, any>
16
+ }
17
+
18
+ type ChildNode = Root
19
+ type ChildProps = RootProps
20
+
21
+ /**
22
+ * Represents a file and contains all its parsed nodes.
23
+ *
24
+ * **Experimental:** some aspects of this node could change within minor
25
+ * or patch version releases.
26
+ *
27
+ * ```js
28
+ * const document = htmlParser(
29
+ * '<html><style>a{color:black}</style><style>b{z-index:2}</style>'
30
+ * )
31
+ * document.type //=> 'document'
32
+ * document.nodes.length //=> 2
33
+ * ```
34
+ */
35
+ export default class Document extends Container<Root> {
36
+ type: 'document'
37
+ parent: undefined
38
+
39
+ constructor(defaults?: DocumentProps)
40
+
41
+ /**
42
+ * Returns a `Result` instance representing the document’s CSS roots.
43
+ *
44
+ * ```js
45
+ * const root1 = postcss.parse(css1, { from: 'a.css' })
46
+ * const root2 = postcss.parse(css2, { from: 'b.css' })
47
+ * const document = postcss.document()
48
+ * document.append(root1)
49
+ * document.append(root2)
50
+ * const result = document.toResult({ to: 'all.css', map: true })
51
+ * ```
52
+ *
53
+ * @param opts Options.
54
+ * @return Result with current document’s CSS.
55
+ */
56
+ toResult(options?: ProcessOptions): Result
57
+ }
@@ -0,0 +1,33 @@
1
+ 'use strict'
2
+
3
+ let Container = require('./container')
4
+
5
+ let LazyResult, Processor
6
+
7
+ class Document extends Container {
8
+ constructor(defaults) {
9
+ // type needs to be passed to super, otherwise child roots won't be normalized correctly
10
+ super({ type: 'document', ...defaults })
11
+
12
+ if (!this.nodes) {
13
+ this.nodes = []
14
+ }
15
+ }
16
+
17
+ toResult(opts = {}) {
18
+ let lazy = new LazyResult(new Processor(), this, opts)
19
+
20
+ return lazy.stringify()
21
+ }
22
+ }
23
+
24
+ Document.registerLazyResult = dependant => {
25
+ LazyResult = dependant
26
+ }
27
+
28
+ Document.registerProcessor = dependant => {
29
+ Processor = dependant
30
+ }
31
+
32
+ module.exports = Document
33
+ Document.default = Document
package/lib/input.js CHANGED
@@ -1,5 +1,6 @@
1
1
  'use strict'
2
2
 
3
+ let { SourceMapConsumer, SourceMapGenerator } = require('source-map-js')
3
4
  let { fileURLToPath, pathToFileURL } = require('url')
4
5
  let { resolve, isAbsolute } = require('path')
5
6
  let { nanoid } = require('nanoid/non-secure')
@@ -10,6 +11,7 @@ let PreviousMap = require('./previous-map')
10
11
 
11
12
  let fromOffsetCache = Symbol('fromOffset cache')
12
13
 
14
+ let sourceMapAvailable = Boolean(SourceMapConsumer && SourceMapGenerator)
13
15
  let pathAvailable = Boolean(resolve && isAbsolute)
14
16
 
15
17
  class Input {
@@ -43,7 +45,7 @@ class Input {
43
45
  }
44
46
  }
45
47
 
46
- if (pathAvailable) {
48
+ if (pathAvailable && sourceMapAvailable) {
47
49
  let map = new PreviousMap(this.css, opts)
48
50
  if (map.text) {
49
51
  this.map = map
@@ -168,7 +170,7 @@ class Input {
168
170
  result.file = fileURLToPath(fromUrl)
169
171
  } else {
170
172
  // istanbul ignore next
171
- throw new Error(`file: protocol is not available in this PostCSS build`);
173
+ throw new Error(`file: protocol is not available in this PostCSS build`)
172
174
  }
173
175
  }
174
176
 
@@ -7,8 +7,10 @@ let warnOnce = require('./warn-once')
7
7
  let Result = require('./result')
8
8
  let parse = require('./parse')
9
9
  let Root = require('./root')
10
+ let Document = require('./document')
10
11
 
11
12
  const TYPE_TO_CLASS_NAME = {
13
+ document: 'Document',
12
14
  root: 'Root',
13
15
  atrule: 'AtRule',
14
16
  rule: 'Rule',
@@ -20,6 +22,7 @@ const PLUGIN_PROPS = {
20
22
  postcssPlugin: true,
21
23
  prepare: true,
22
24
  Once: true,
25
+ Document: true,
23
26
  Root: true,
24
27
  Declaration: true,
25
28
  Rule: true,
@@ -30,6 +33,7 @@ const PLUGIN_PROPS = {
30
33
  AtRuleExit: true,
31
34
  CommentExit: true,
32
35
  RootExit: true,
36
+ DocumentExit: true,
33
37
  OnceExit: true
34
38
  }
35
39
 
@@ -73,7 +77,9 @@ function getEvents(node) {
73
77
 
74
78
  function toStack(node) {
75
79
  let events
76
- if (node.type === 'root') {
80
+ if (node.type === 'document') {
81
+ events = ['Document', CHILDREN, 'DocumentExit']
82
+ } else if (node.type === 'root') {
77
83
  events = ['Root', CHILDREN, 'RootExit']
78
84
  } else {
79
85
  events = getEvents(node)
@@ -103,7 +109,11 @@ class LazyResult {
103
109
  this.processed = false
104
110
 
105
111
  let root
106
- if (typeof css === 'object' && css !== null && css.type === 'root') {
112
+ if (
113
+ typeof css === 'object' &&
114
+ css !== null &&
115
+ (css.type === 'root' || css.type === 'document')
116
+ ) {
107
117
  root = cleanMarks(css)
108
118
  } else if (css instanceof LazyResult || css instanceof Result) {
109
119
  root = cleanMarks(css.root)
@@ -231,7 +241,13 @@ class LazyResult {
231
241
  this.walkSync(root)
232
242
  }
233
243
  if (this.listeners.OnceExit) {
234
- this.visitSync(this.listeners.OnceExit, root)
244
+ if (root.type === 'document') {
245
+ for (let subRoot of root.nodes) {
246
+ this.visitSync(this.listeners.OnceExit, subRoot)
247
+ }
248
+ } else {
249
+ this.visitSync(this.listeners.OnceExit, root)
250
+ }
235
251
  }
236
252
  }
237
253
 
@@ -287,7 +303,9 @@ class LazyResult {
287
303
  } catch (e) {
288
304
  throw this.handleError(e, node.proxyOf)
289
305
  }
290
- if (node.type !== 'root' && !node.parent) return true
306
+ if (node.type !== 'root' && node.type !== 'document' && !node.parent) {
307
+ return true
308
+ }
291
309
  if (isPromise(promise)) {
292
310
  throw this.getAsyncError()
293
311
  }
@@ -298,6 +316,18 @@ class LazyResult {
298
316
  this.result.lastPlugin = plugin
299
317
  try {
300
318
  if (typeof plugin === 'object' && plugin.Once) {
319
+ if (this.result.root.type === 'document') {
320
+ let roots = this.result.root.nodes.map(root =>
321
+ plugin.Once(root, this.helpers)
322
+ )
323
+
324
+ if (isPromise(roots[0])) {
325
+ return Promise.all(roots)
326
+ }
327
+
328
+ return roots
329
+ }
330
+
301
331
  return plugin.Once(this.result.root, this.helpers)
302
332
  } else if (typeof plugin === 'function') {
303
333
  return plugin(this.result.root, this.result)
@@ -385,7 +415,15 @@ class LazyResult {
385
415
  for (let [plugin, visitor] of this.listeners.OnceExit) {
386
416
  this.result.lastPlugin = plugin
387
417
  try {
388
- await visitor(root, this.helpers)
418
+ if (root.type === 'document') {
419
+ let roots = root.nodes.map(subRoot =>
420
+ visitor(subRoot, this.helpers)
421
+ )
422
+
423
+ await Promise.all(roots)
424
+ } else {
425
+ await visitor(root, this.helpers)
426
+ }
389
427
  } catch (e) {
390
428
  throw this.handleError(e)
391
429
  }
@@ -439,7 +477,7 @@ class LazyResult {
439
477
  let visit = stack[stack.length - 1]
440
478
  let { node, visitors } = visit
441
479
 
442
- if (node.type !== 'root' && !node.parent) {
480
+ if (node.type !== 'root' && node.type !== 'document' && !node.parent) {
443
481
  stack.pop()
444
482
  return
445
483
  }
@@ -501,3 +539,4 @@ module.exports = LazyResult
501
539
  LazyResult.default = LazyResult
502
540
 
503
541
  Root.registerLazyResult(LazyResult)
542
+ Document.registerLazyResult(LazyResult)
package/lib/list.d.ts CHANGED
@@ -1,4 +1,19 @@
1
1
  export type List = {
2
+ /**
3
+ * Safely splits values.
4
+ *
5
+ * ```js
6
+ * Once (root, { list }) {
7
+ * list.split('1px calc(10% + 1px)', [' ', '\n', '\t']) //=> ['1px', 'calc(10% + 1px)']
8
+ * }
9
+ * ```
10
+ *
11
+ * @param string separated values.
12
+ * @param separators array of separators.
13
+ * @param last boolean indicator.
14
+ * @return Split values.
15
+ */
16
+ split(string: string, separators: string[], last: boolean): string[]
2
17
  /**
3
18
  * Safely splits space-separated values (such as those for `background`,
4
19
  * `border-radius`, and other shorthand properties).
@@ -1,9 +1,10 @@
1
1
  'use strict'
2
2
 
3
+ let { SourceMapConsumer, SourceMapGenerator } = require('source-map-js')
3
4
  let { dirname, resolve, relative, sep } = require('path')
4
5
  let { pathToFileURL } = require('url')
5
- let mozilla = require('source-map')
6
6
 
7
+ let sourceMapAvailable = Boolean(SourceMapConsumer && SourceMapGenerator)
7
8
  let pathAvailable = Boolean(dirname && resolve && relative && sep)
8
9
 
9
10
  class MapGenerator {
@@ -99,7 +100,7 @@ class MapGenerator {
99
100
  let map
100
101
 
101
102
  if (this.mapOpts.sourcesContent === false) {
102
- map = new mozilla.SourceMapConsumer(prev.text)
103
+ map = new SourceMapConsumer(prev.text)
103
104
  if (map.sourcesContent) {
104
105
  map.sourcesContent = map.sourcesContent.map(() => null)
105
106
  }
@@ -206,7 +207,9 @@ class MapGenerator {
206
207
  return pathToFileURL(node.source.input.from).toString()
207
208
  } else {
208
209
  // istanbul ignore next
209
- throw new Error('`map.absolute` option is not available in this PostCSS build')
210
+ throw new Error(
211
+ '`map.absolute` option is not available in this PostCSS build'
212
+ )
210
213
  }
211
214
  } else {
212
215
  return this.toUrl(this.path(node.source.input.from))
@@ -215,7 +218,7 @@ class MapGenerator {
215
218
 
216
219
  generateString() {
217
220
  this.css = ''
218
- this.map = new mozilla.SourceMapGenerator({ file: this.outputFile() })
221
+ this.map = new SourceMapGenerator({ file: this.outputFile() })
219
222
 
220
223
  let line = 1
221
224
  let column = 1
@@ -282,7 +285,7 @@ class MapGenerator {
282
285
  generate() {
283
286
  this.clearAnnotation()
284
287
 
285
- if (pathAvailable && this.isMap()) {
288
+ if (pathAvailable && sourceMapAvailable && this.isMap()) {
286
289
  return this.generateMap()
287
290
  }
288
291
 
package/lib/node.d.ts CHANGED
@@ -5,14 +5,15 @@ import AtRule, { AtRuleProps } from './at-rule.js'
5
5
  import Rule, { RuleProps } from './rule.js'
6
6
  import { WarningOptions } from './warning.js'
7
7
  import CssSyntaxError from './css-syntax-error.js'
8
- import Container from './container.js'
9
8
  import Result from './result.js'
10
9
  import Input from './input.js'
11
10
  import Root from './root.js'
11
+ import Document from './document.js'
12
+ import Container from './container.js'
12
13
 
13
14
  export type ChildNode = AtRule | Rule | Declaration | Comment
14
15
 
15
- export type AnyNode = AtRule | Rule | Declaration | Comment | Root
16
+ export type AnyNode = AtRule | Rule | Declaration | Comment | Root | Document
16
17
 
17
18
  export type ChildProps =
18
19
  | AtRuleProps
@@ -97,7 +98,7 @@ export default abstract class Node {
97
98
  * root.nodes[0].parent === root
98
99
  * ```
99
100
  */
100
- parent: Container | undefined
101
+ parent: Document | Container | undefined
101
102
 
102
103
  /**
103
104
  * The input source of the node.
@@ -251,6 +252,18 @@ export default abstract class Node {
251
252
  */
252
253
  toString(stringifier?: Stringifier | Syntax): string
253
254
 
255
+ /**
256
+ * Assigns properties to the current node.
257
+ *
258
+ * ```js
259
+ * decl.assign({ prop: 'word-wrap', value: 'break-word' })
260
+ * ```
261
+ *
262
+ * @param overrides New properties to override the node.
263
+ * @return Current node to methods chain.
264
+ */
265
+ assign(overrides: object): this
266
+
254
267
  /**
255
268
  * Returns an exact clone of the node.
256
269
  *
package/lib/node.js CHANGED
@@ -84,6 +84,13 @@ class Node {
84
84
  return result
85
85
  }
86
86
 
87
+ assign(overrides = {}) {
88
+ for (let name in overrides) {
89
+ this[name] = overrides[name]
90
+ }
91
+ return this
92
+ }
93
+
87
94
  clone(overrides = {}) {
88
95
  let cloned = cloneNode(this)
89
96
  for (let name in overrides) {
@@ -151,7 +158,9 @@ class Node {
151
158
 
152
159
  root() {
153
160
  let result = this
154
- while (result.parent) result = result.parent
161
+ while (result.parent && result.parent.type !== 'document') {
162
+ result = result.parent
163
+ }
155
164
  return result
156
165
  }
157
166
 
package/lib/postcss.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { SourceMapGenerator, RawSourceMap } from 'source-map'
1
+ import { SourceMapGenerator, RawSourceMap } from 'source-map-js'
2
2
 
3
3
  import Node, {
4
4
  Position,
@@ -11,6 +11,7 @@ import Node, {
11
11
  } from './node.js'
12
12
  import Declaration, { DeclarationProps } from './declaration.js'
13
13
  import Root, { RootProps } from './root.js'
14
+ import Document, { DocumentProps } from './document.js'
14
15
  import Comment, { CommentProps } from './comment.js'
15
16
  import AtRule, { AtRuleProps } from './at-rule.js'
16
17
  import Result, { Message } from './result.js'
@@ -40,6 +41,7 @@ export {
40
41
  ChildProps,
41
42
  AtRuleProps,
42
43
  RootProps,
44
+ DocumentProps,
43
45
  Warning,
44
46
  CssSyntaxError,
45
47
  Node,
@@ -50,6 +52,7 @@ export {
50
52
  AtRule,
51
53
  Rule,
52
54
  Root,
55
+ Document,
53
56
  Result,
54
57
  LazyResult,
55
58
  Input
@@ -61,6 +64,10 @@ export type SourceMap = SourceMapGenerator & {
61
64
 
62
65
  export type Helpers = { result: Result; postcss: Postcss } & Postcss
63
66
 
67
+ type DocumentProcessor = (
68
+ document: Document,
69
+ helper: Helpers
70
+ ) => Promise<void> | void
64
71
  type RootProcessor = (root: Root, helper: Helpers) => Promise<void> | void
65
72
  type DeclarationProcessor = (
66
73
  decl: Declaration,
@@ -74,6 +81,20 @@ type CommentProcessor = (
74
81
  ) => Promise<void> | void
75
82
 
76
83
  interface Processors {
84
+ /**
85
+ * Will be called on `Document` node.
86
+ *
87
+ * Will be called again on children changes.
88
+ */
89
+ Document?: DocumentProcessor
90
+
91
+ /**
92
+ * Will be called on `Document` node, when all children will be processed.
93
+ *
94
+ * Will be called again on children changes.
95
+ */
96
+ DocumentExit?: DocumentProcessor
97
+
77
98
  /**
78
99
  * Will be called on `Root` node once.
79
100
  */
@@ -200,11 +221,11 @@ export type AcceptedPlugin =
200
221
  }
201
222
  | Processor
202
223
 
203
- export interface Parser {
224
+ export interface Parser<RootNode = Root> {
204
225
  (
205
226
  css: string | { toString(): string },
206
227
  opts?: Pick<ProcessOptions, 'map' | 'from'>
207
- ): Root
228
+ ): RootNode
208
229
  }
209
230
 
210
231
  export interface Builder {
@@ -224,7 +245,7 @@ export interface Syntax {
224
245
  /**
225
246
  * Function to generate AST by string.
226
247
  */
227
- parse?: Parser
248
+ parse?: Parser<Root | Document>
228
249
 
229
250
  /**
230
251
  * Class to generate string by AST.
@@ -347,7 +368,7 @@ export interface Postcss {
347
368
  stringify: Stringifier
348
369
 
349
370
  /**
350
- * Parses source css and returns a new `Root` node,
371
+ * Parses source css and returns a new `Root` or `Document` node,
351
372
  * which contains the source CSS nodes.
352
373
  *
353
374
  * ```js
@@ -415,6 +436,14 @@ export interface Postcss {
415
436
  */
416
437
  root(defaults?: RootProps): Root
417
438
 
439
+ /**
440
+ * Creates a new `Document` node.
441
+ *
442
+ * @param defaults Properties for the new node.
443
+ * @return New document node.
444
+ */
445
+ document(defaults?: DocumentProps): Document
446
+
418
447
  CssSyntaxError: typeof CssSyntaxError
419
448
  Declaration: typeof Declaration
420
449
  Container: typeof Container
package/lib/postcss.js CHANGED
@@ -7,6 +7,7 @@ let Container = require('./container')
7
7
  let Processor = require('./processor')
8
8
  let stringify = require('./stringify')
9
9
  let fromJSON = require('./fromJSON')
10
+ let Document = require('./document')
10
11
  let Warning = require('./warning')
11
12
  let Comment = require('./comment')
12
13
  let AtRule = require('./at-rule')
@@ -73,10 +74,12 @@ postcss.atRule = defaults => new AtRule(defaults)
73
74
  postcss.decl = defaults => new Declaration(defaults)
74
75
  postcss.rule = defaults => new Rule(defaults)
75
76
  postcss.root = defaults => new Root(defaults)
77
+ postcss.document = defaults => new Document(defaults)
76
78
 
77
79
  postcss.CssSyntaxError = CssSyntaxError
78
80
  postcss.Declaration = Declaration
79
81
  postcss.Container = Container
82
+ postcss.Document = Document
80
83
  postcss.Comment = Comment
81
84
  postcss.Warning = Warning
82
85
  postcss.AtRule = AtRule
package/lib/postcss.mjs CHANGED
@@ -13,10 +13,12 @@ export const atRule = postcss.atRule
13
13
  export const rule = postcss.rule
14
14
  export const decl = postcss.decl
15
15
  export const root = postcss.root
16
+ export const document = postcss.document
16
17
 
17
18
  export const CssSyntaxError = postcss.CssSyntaxError
18
19
  export const Declaration = postcss.Declaration
19
20
  export const Container = postcss.Container
21
+ export const Document = postcss.Document
20
22
  export const Comment = postcss.Comment
21
23
  export const Warning = postcss.Warning
22
24
  export const AtRule = postcss.AtRule
@@ -1,4 +1,4 @@
1
- import { SourceMapConsumer } from 'source-map'
1
+ import { SourceMapConsumer } from 'source-map-js'
2
2
 
3
3
  import { ProcessOptions } from './postcss.js'
4
4
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  let { existsSync, readFileSync } = require('fs')
4
4
  let { dirname, join } = require('path')
5
- let mozilla = require('source-map')
5
+ let { SourceMapConsumer, SourceMapGenerator } = require('source-map-js')
6
6
 
7
7
  function fromBase64(str) {
8
8
  if (Buffer) {
@@ -30,7 +30,7 @@ class PreviousMap {
30
30
 
31
31
  consumer() {
32
32
  if (!this.consumerCache) {
33
- this.consumerCache = new mozilla.SourceMapConsumer(this.text)
33
+ this.consumerCache = new SourceMapConsumer(this.text)
34
34
  }
35
35
  return this.consumerCache
36
36
  }
@@ -48,11 +48,15 @@ class PreviousMap {
48
48
  }
49
49
 
50
50
  getAnnotationURL(sourceMapString) {
51
- return sourceMapString.match(/\/\*\s*# sourceMappingURL=((?:(?!sourceMappingURL=).)*)\*\//)[1].trim()
51
+ return sourceMapString
52
+ .match(/\/\*\s*# sourceMappingURL=((?:(?!sourceMappingURL=).)*)\*\//)[1]
53
+ .trim()
52
54
  }
53
55
 
54
56
  loadAnnotation(css) {
55
- let annotations = css.match(/\/\*\s*# sourceMappingURL=(?:(?!sourceMappingURL=).)*\*\//gm)
57
+ let annotations = css.match(
58
+ /\/\*\s*# sourceMappingURL=(?:(?!sourceMappingURL=).)*\*\//gm
59
+ )
56
60
 
57
61
  if (annotations && annotations.length > 0) {
58
62
  // Locate the last sourceMappingURL to avoid picking up
@@ -107,9 +111,9 @@ class PreviousMap {
107
111
  }
108
112
  return map
109
113
  }
110
- } else if (prev instanceof mozilla.SourceMapConsumer) {
111
- return mozilla.SourceMapGenerator.fromSourceMap(prev).toString()
112
- } else if (prev instanceof mozilla.SourceMapGenerator) {
114
+ } else if (prev instanceof SourceMapConsumer) {
115
+ return SourceMapGenerator.fromSourceMap(prev).toString()
116
+ } else if (prev instanceof SourceMapGenerator) {
113
117
  return prev.toString()
114
118
  } else if (this.isMap(prev)) {
115
119
  return JSON.stringify(prev)
package/lib/processor.js CHANGED
@@ -2,10 +2,11 @@
2
2
 
3
3
  let LazyResult = require('./lazy-result')
4
4
  let Root = require('./root')
5
+ let Document = require('./document')
5
6
 
6
7
  class Processor {
7
8
  constructor(plugins = []) {
8
- this.version = '8.2.13'
9
+ this.version = '8.3.1'
9
10
  this.plugins = this.normalize(plugins)
10
11
  }
11
12
 
@@ -17,7 +18,9 @@ class Processor {
17
18
  process(css, opts = {}) {
18
19
  if (
19
20
  this.plugins.length === 0 &&
20
- opts.parser === opts.stringifier &&
21
+ typeof opts.parser === 'undefined' &&
22
+ typeof opts.stringifier === 'undefined' &&
23
+ typeof opts.syntax === 'undefined' &&
21
24
  !opts.hideNothingWarning
22
25
  ) {
23
26
  if (process.env.NODE_ENV !== 'production') {
@@ -68,3 +71,4 @@ module.exports = Processor
68
71
  Processor.default = Processor
69
72
 
70
73
  Root.registerProcessor(Processor)
74
+ Document.registerProcessor(Processor)
package/lib/root.d.ts CHANGED
@@ -1,13 +1,30 @@
1
1
  import Container, { ContainerProps } from './container.js'
2
+ import Document from './document.js'
2
3
  import { ProcessOptions } from './postcss.js'
3
4
  import Result from './result.js'
4
5
 
5
- interface RootRaws {
6
+ interface RootRaws extends Record<string, any> {
6
7
  /**
7
8
  * The space symbols after the last child to the end of file.
8
9
  */
9
10
  after?: string
10
11
 
12
+ /**
13
+ * Non-CSS code before `Root`, when `Root` is inside `Document`.
14
+ *
15
+ * **Experimental:** some aspects of this node could change within minor
16
+ * or patch version releases.
17
+ */
18
+ codeBefore?: string
19
+
20
+ /**
21
+ * Non-CSS code after `Root`, when `Root` is inside `Document`.
22
+ *
23
+ * **Experimental:** some aspects of this node could change within minor
24
+ * or patch version releases.
25
+ */
26
+ codeAfter?: string
27
+
11
28
  /**
12
29
  * Is the last child has an (optional) semicolon.
13
30
  */
@@ -15,6 +32,10 @@ interface RootRaws {
15
32
  }
16
33
 
17
34
  export interface RootProps extends ContainerProps {
35
+ /**
36
+ * Information used to generate byte-to-byte equal node string
37
+ * as it was in the origin input.
38
+ * */
18
39
  raws?: RootRaws
19
40
  }
20
41
 
@@ -29,11 +50,9 @@ export interface RootProps extends ContainerProps {
29
50
  */
30
51
  export default class Root extends Container {
31
52
  type: 'root'
32
- parent: undefined
53
+ parent: Document | undefined
33
54
  raws: RootRaws
34
55
 
35
- constructor(defaults?: RootProps)
36
-
37
56
  /**
38
57
  * Returns a `Result` instance representing the root’s CSS.
39
58
  *
@@ -48,4 +67,7 @@ export default class Root extends Container {
48
67
  * @return Result with current root’s CSS.
49
68
  */
50
69
  toResult(options?: ProcessOptions): Result
70
+
71
+ constructor(defaults?: RootProps)
72
+ assign(overrides: object | RootProps): this
51
73
  }
package/lib/rule.d.ts CHANGED
@@ -37,8 +37,11 @@ interface RuleRaws {
37
37
  }
38
38
 
39
39
  export interface RuleProps extends ContainerProps {
40
+ /** Selector or selectors of the rule. */
40
41
  selector?: string
42
+ /** Selectors of the rule represented as an array of strings. */
41
43
  selectors?: string[]
44
+ /** Information used to generate byte-to-byte equal node string as it was in the origin input. */
42
45
  raws?: RuleRaws
43
46
  }
44
47
 
@@ -62,6 +65,7 @@ export interface RuleProps extends ContainerProps {
62
65
  */
63
66
  export default class Rule extends Container {
64
67
  type: 'rule'
68
+ parent: Container | undefined
65
69
  raws: RuleRaws
66
70
 
67
71
  /**
@@ -93,6 +97,7 @@ export default class Rule extends Container {
93
97
  selectors: string[]
94
98
 
95
99
  constructor(defaults?: RuleProps)
100
+ assign(overrides: object | RuleProps): this
96
101
  clone(overrides?: Partial<RuleProps>): this
97
102
  cloneBefore(overrides?: Partial<RuleProps>): this
98
103
  cloneAfter(overrides?: Partial<RuleProps>): this
@@ -37,6 +37,10 @@ class Stringifier {
37
37
  this[node.type](node, semicolon)
38
38
  }
39
39
 
40
+ document(node) {
41
+ this.body(node)
42
+ }
43
+
40
44
  root(node) {
41
45
  this.body(node)
42
46
  if (node.raws.after) this.builder(node.raws.after)
@@ -129,11 +133,16 @@ class Stringifier {
129
133
 
130
134
  let parent = node.parent
131
135
 
132
- // Hack for first rule in CSS
133
136
  if (detect === 'before') {
137
+ // Hack for first rule in CSS
134
138
  if (!parent || (parent.type === 'root' && parent.first === node)) {
135
139
  return ''
136
140
  }
141
+
142
+ // `root` nodes in `document` should use only their own raws
143
+ if (parent && parent.type === 'document') {
144
+ return ''
145
+ }
137
146
  }
138
147
 
139
148
  // Floating child without parent
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "postcss",
3
- "version": "8.2.13",
3
+ "version": "8.3.1",
4
4
  "description": "Tool for transforming styles with JS plugins",
5
5
  "engines": {
6
6
  "node": "^10 || ^12 || >=14"
@@ -62,14 +62,15 @@
62
62
  "repository": "postcss/postcss",
63
63
  "dependencies": {
64
64
  "colorette": "^1.2.2",
65
- "nanoid": "^3.1.22",
66
- "source-map": "^0.6.1"
65
+ "nanoid": "^3.1.23",
66
+ "source-map-js": "^0.6.2"
67
67
  },
68
68
  "browser": {
69
69
  "./lib/terminal-highlight": false,
70
+ "source-map-js": false,
70
71
  "colorette": false,
71
- "fs": false,
72
72
  "path": false,
73
- "url": false
73
+ "url": false,
74
+ "fs": false
74
75
  }
75
76
  }