postcss 8.1.14 → 8.2.3

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/CHANGELOG.md CHANGED
@@ -1,6 +1,20 @@
1
1
  # Change Log
2
2
  This project adheres to [Semantic Versioning](https://semver.org/).
3
3
 
4
+ ## 8.2.3
5
+ * FIx `JSON.stringify(Node[])` support (by Niklas Mischkulnig).
6
+
7
+ ## 8.2.2
8
+ * Fixed CSS-in-JS support (by James Garbutt).
9
+ * Fixed plugin types (by Ludovico Fischer).
10
+ * Fixed `Result#warn()` types.
11
+
12
+ ## 8.2.1
13
+ * Fixed `Node#toJSON()` and `postcss.fromJSON()` (by Niklas Mischkulnig).
14
+
15
+ ## 8.2 “Prince Orobas”
16
+ * Added `Node#toJSON()` and `postcss.fromJSON()` (by Niklas Mischkulnig).
17
+
4
18
  ## 8.1.14
5
19
  * Fixed parser performance regression.
6
20
 
package/README.md CHANGED
@@ -100,7 +100,8 @@ If you have any new ideas, [PostCSS plugin development] is really easy.
100
100
  * [`font-magician`] generates all the `@font-face` rules needed in CSS.
101
101
  * [`postcss-inline-svg`] allows you to inline SVG and customize its styles.
102
102
  * [`postcss-write-svg`] allows you to write simple SVG directly in your CSS.
103
-
103
+ * [`webp-in-css`] to use WebP image format in CSS background.
104
+ * [`avif-in-css`] to use AVIF image format in CSS background.
104
105
 
105
106
  ### Linters
106
107
 
@@ -136,6 +137,8 @@ If you have any new ideas, [PostCSS plugin development] is really easy.
136
137
  [`postcss-rtl`]: https://github.com/vkalinichev/postcss-rtl
137
138
  [`postcss-use`]: https://github.com/postcss/postcss-use
138
139
  [`css-modules`]: https://github.com/css-modules/css-modules
140
+ [`webp-in-css`]: https://github.com/ai/webp-in-css
141
+ [`avif-in-css`]: https://github.com/nucliweb/avif-in-css
139
142
  [`colorguard`]: https://github.com/SlexAxton/css-colorguard
140
143
  [`stylelint`]: https://github.com/stylelint/stylelint
141
144
  [`stylefmt`]: https://github.com/morishitter/stylefmt
@@ -146,7 +149,6 @@ If you have any new ideas, [PostCSS plugin development] is really easy.
146
149
  [`short`]: https://github.com/jonathantneal/postcss-short
147
150
  [`lost`]: https://github.com/peterramsing/lost
148
151
 
149
-
150
152
  ## Syntaxes
151
153
 
152
154
  PostCSS can transform styles in any syntax, not just CSS.
@@ -91,8 +91,9 @@ export default abstract class Container extends Node {
91
91
  * @param callback Iterator receives each node and index.
92
92
  * @return Returns `false` if iteration was broke.
93
93
  */
94
- each (callback: (node: ChildNode, index: number) => void): void
95
- each (callback: (node: ChildNode, index: number) => false): false
94
+ each (
95
+ callback: (node: ChildNode, index: number) => false | void
96
+ ): false | undefined
96
97
 
97
98
  /**
98
99
  * Traverses the container’s descendant nodes, calling callback
@@ -113,8 +114,9 @@ export default abstract class Container extends Node {
113
114
  * @param callback Iterator receives each node and index.
114
115
  * @return Returns `false` if iteration was broke.
115
116
  */
116
- walk (callback: (node: ChildNode, index: number) => void): void
117
- walk (callback: (node: ChildNode, index: number) => false): false
117
+ walk (
118
+ callback: (node: ChildNode, index: number) => false | void
119
+ ): false | undefined
118
120
 
119
121
  /**
120
122
  * Traverses the container’s descendant nodes, calling callback
@@ -147,14 +149,11 @@ export default abstract class Container extends Node {
147
149
  */
148
150
  walkDecls (
149
151
  propFilter: string | RegExp,
150
- callback: (decl: Declaration, index: number) => void
151
- ): void
152
- walkDecls (callback: (decl: Declaration, index: number) => void): void
152
+ callback: (decl: Declaration, index: number) => false | void
153
+ ): false | undefined
153
154
  walkDecls (
154
- propFilter: string | RegExp,
155
- callback: (decl: Declaration, index: number) => false
156
- ): false
157
- walkDecls (callback: (decl: Declaration, index: number) => false): false
155
+ callback: (decl: Declaration, index: number) => false | void
156
+ ): false | undefined
158
157
 
159
158
  /**
160
159
  * Traverses the container’s descendant nodes, calling callback
@@ -180,14 +179,11 @@ export default abstract class Container extends Node {
180
179
  */
181
180
  walkRules (
182
181
  selectorFilter: string | RegExp,
183
- callback: (atRule: Rule, index: number) => void
184
- ): void
185
- walkRules (callback: (atRule: Rule, index: number) => void): void
182
+ callback: (atRule: Rule, index: number) => false | void
183
+ ): false | undefined
186
184
  walkRules (
187
- selectorFilter: string | RegExp,
188
- callback: (atRule: Rule, index: number) => false
189
- ): false
190
- walkRules (callback: (atRule: Rule, index: number) => false): false
185
+ callback: (atRule: Rule, index: number) => false | void
186
+ ): false | undefined
191
187
 
192
188
  /**
193
189
  * Traverses the container’s descendant nodes, calling callback
@@ -220,14 +216,11 @@ export default abstract class Container extends Node {
220
216
  */
221
217
  walkAtRules (
222
218
  nameFilter: string | RegExp,
223
- callback: (atRule: AtRule, index: number) => void
224
- ): void
225
- walkAtRules (callback: (atRule: AtRule, index: number) => void): void
219
+ callback: (atRule: AtRule, index: number) => false | void
220
+ ): false | undefined
226
221
  walkAtRules (
227
- nameFilter: string | RegExp,
228
- callback: (atRule: AtRule, index: number) => false
229
- ): false
230
- walkAtRules (callback: (atRule: AtRule, index: number) => false): false
222
+ callback: (atRule: AtRule, index: number) => false | void
223
+ ): false | undefined
231
224
 
232
225
  /**
233
226
  * Traverses the container’s descendant nodes, calling callback
@@ -246,10 +239,12 @@ export default abstract class Container extends Node {
246
239
  * @return Returns `false` if iteration was broke.
247
240
  */
248
241
 
249
- walkComments (callback: (comment: Comment, indexed: number) => void): void
250
242
  walkComments (
251
- callback: (comment: Comment, indexed: number) => boolean
252
- ): boolean
243
+ callback: (comment: Comment, indexed: number) => false | void
244
+ ): false | undefined
245
+ walkComments (
246
+ callback: (comment: Comment, indexed: number) => false | void
247
+ ): false | undefined
253
248
 
254
249
  /**
255
250
  * Inserts new nodes to the end of the container.
@@ -1,4 +1,4 @@
1
- import Input, { FilePosition } from './input.js'
1
+ import { FilePosition } from './input.js'
2
2
 
3
3
  /**
4
4
  * The CSS parser throws this error for broken CSS.
@@ -0,0 +1,5 @@
1
+ import { JSONHydrator } from './postcss.js'
2
+
3
+ declare const fromJSON: JSONHydrator
4
+
5
+ export default fromJSON
@@ -0,0 +1,54 @@
1
+ 'use strict'
2
+
3
+ let Declaration = require('./declaration')
4
+ let PreviousMap = require('./previous-map')
5
+ let Comment = require('./comment')
6
+ let AtRule = require('./at-rule')
7
+ let Input = require('./input')
8
+ let Root = require('./root')
9
+ let Rule = require('./rule')
10
+
11
+ function fromJSON (json, inputs) {
12
+ if (Array.isArray(json)) return json.map(n => fromJSON(n))
13
+
14
+ let { inputs: ownInputs, ...defaults } = json
15
+ if (ownInputs) {
16
+ inputs = []
17
+ for (let input of ownInputs) {
18
+ let inputHydrated = { ...input, __proto__: Input.prototype }
19
+ if (inputHydrated.map) {
20
+ inputHydrated.map = {
21
+ ...inputHydrated.map,
22
+ __proto__: PreviousMap.prototype
23
+ }
24
+ }
25
+ inputs.push(inputHydrated)
26
+ }
27
+ }
28
+ if (defaults.nodes) {
29
+ defaults.nodes = json.nodes.map(n => fromJSON(n, inputs))
30
+ }
31
+ if (defaults.source) {
32
+ let { inputId, ...source } = defaults.source
33
+ defaults.source = source
34
+ if (inputId != null) {
35
+ defaults.source.input = inputs[inputId]
36
+ }
37
+ }
38
+ if (defaults.type === 'root') {
39
+ return new Root(defaults)
40
+ } else if (defaults.type === 'decl') {
41
+ return new Declaration(defaults)
42
+ } else if (defaults.type === 'rule') {
43
+ return new Rule(defaults)
44
+ } else if (defaults.type === 'comment') {
45
+ return new Comment(defaults)
46
+ } else if (defaults.type === 'atrule') {
47
+ return new AtRule(defaults)
48
+ } else {
49
+ throw new Error('Unknown node type: ' + json.type)
50
+ }
51
+ }
52
+
53
+ module.exports = fromJSON
54
+ fromJSON.default = fromJSON
package/lib/input.js CHANGED
@@ -8,6 +8,8 @@ let terminalHighlight = require('./terminal-highlight')
8
8
  let CssSyntaxError = require('./css-syntax-error')
9
9
  let PreviousMap = require('./previous-map')
10
10
 
11
+ let fromOffsetCache = Symbol('fromOffset cache')
12
+
11
13
  class Input {
12
14
  constructor (css, opts = {}) {
13
15
  if (
@@ -49,42 +51,45 @@ class Input {
49
51
  }
50
52
 
51
53
  fromOffset (offset) {
52
- let lines = this.css.split('\n')
53
- let lineToIndex = new Array(lines.length)
54
- let prevIndex = 0
54
+ let lastLine, lineToIndex
55
+ if (!this[fromOffsetCache]) {
56
+ let lines = this.css.split('\n')
57
+ lineToIndex = new Array(lines.length)
58
+ let prevIndex = 0
59
+
60
+ for (let i = 0, l = lines.length; i < l; i++) {
61
+ lineToIndex[i] = prevIndex
62
+ prevIndex += lines[i].length + 1
63
+ }
55
64
 
56
- for (let i = 0, l = lines.length; i < l; i++) {
57
- lineToIndex[i] = prevIndex
58
- prevIndex += lines[i].length + 1
65
+ this[fromOffsetCache] = lineToIndex
66
+ } else {
67
+ lineToIndex = this[fromOffsetCache]
59
68
  }
69
+ lastLine = lineToIndex[lineToIndex.length - 1]
60
70
 
61
- let lastLine = lineToIndex[lineToIndex.length - 1]
62
-
63
- this.fromOffset = index => {
64
- let min = 0
65
- if (index >= lastLine) {
66
- min = lineToIndex.length - 1
67
- } else {
68
- let max = lineToIndex.length - 2
69
- let mid
70
- while (min < max) {
71
- mid = min + ((max - min) >> 1)
72
- if (index < lineToIndex[mid]) {
73
- max = mid - 1
74
- } else if (index >= lineToIndex[mid + 1]) {
75
- min = mid + 1
76
- } else {
77
- min = mid
78
- break
79
- }
71
+ let min = 0
72
+ if (offset >= lastLine) {
73
+ min = lineToIndex.length - 1
74
+ } else {
75
+ let max = lineToIndex.length - 2
76
+ let mid
77
+ while (min < max) {
78
+ mid = min + ((max - min) >> 1)
79
+ if (offset < lineToIndex[mid]) {
80
+ max = mid - 1
81
+ } else if (offset >= lineToIndex[mid + 1]) {
82
+ min = mid + 1
83
+ } else {
84
+ min = mid
85
+ break
80
86
  }
81
87
  }
82
- return {
83
- line: min + 1,
84
- col: index - lineToIndex[min] + 1
85
- }
86
88
  }
87
- return this.fromOffset(offset)
89
+ return {
90
+ line: min + 1,
91
+ col: offset - lineToIndex[min] + 1
92
+ }
88
93
  }
89
94
 
90
95
  error (message, line, column, opts = {}) {
@@ -168,6 +173,22 @@ class Input {
168
173
  get from () {
169
174
  return this.file || this.id
170
175
  }
176
+
177
+ toJSON () {
178
+ let json = {}
179
+ for (let name of ['hasBOM', 'css', 'file', 'id']) {
180
+ if (this[name] != null) {
181
+ json[name] = this[name]
182
+ }
183
+ }
184
+ if (this.map) {
185
+ json.map = { ...this.map }
186
+ if (json.map.consumerCache) {
187
+ json.map.consumerCache = undefined
188
+ }
189
+ }
190
+ return json
191
+ }
171
192
  }
172
193
 
173
194
  module.exports = Input
package/lib/node.js CHANGED
@@ -166,8 +166,11 @@ class Node {
166
166
  if (!keepBetween) delete this.raws.between
167
167
  }
168
168
 
169
- toJSON () {
169
+ toJSON (_, inputs) {
170
170
  let fixed = {}
171
+ let emitInputs = inputs == null
172
+ inputs = inputs || new Map()
173
+ let inputsNextIndex = 0
171
174
 
172
175
  for (let name in this) {
173
176
  if (!Object.prototype.hasOwnProperty.call(this, name)) {
@@ -180,18 +183,34 @@ class Node {
180
183
  if (Array.isArray(value)) {
181
184
  fixed[name] = value.map(i => {
182
185
  if (typeof i === 'object' && i.toJSON) {
183
- return i.toJSON()
186
+ return i.toJSON(null, inputs)
184
187
  } else {
185
188
  return i
186
189
  }
187
190
  })
188
191
  } else if (typeof value === 'object' && value.toJSON) {
189
- fixed[name] = value.toJSON()
192
+ fixed[name] = value.toJSON(null, inputs)
193
+ } else if (name === 'source') {
194
+ let inputId = inputs.get(value.input)
195
+ if (inputId == null) {
196
+ inputId = inputsNextIndex
197
+ inputs.set(value.input, inputsNextIndex)
198
+ inputsNextIndex++
199
+ }
200
+ fixed[name] = {
201
+ inputId,
202
+ start: value.start,
203
+ end: value.end
204
+ }
190
205
  } else {
191
206
  fixed[name] = value
192
207
  }
193
208
  }
194
209
 
210
+ if (emitInputs) {
211
+ fixed.inputs = [...inputs.keys()].map(input => input.toJSON())
212
+ }
213
+
195
214
  return fixed
196
215
  }
197
216
 
package/lib/postcss.d.ts CHANGED
@@ -170,7 +170,7 @@ export interface Plugin extends Processors {
170
170
  }
171
171
 
172
172
  export interface PluginCreator<PluginOptions> {
173
- (opts?: PluginOptions): Plugin
173
+ (opts?: PluginOptions): Plugin | Processor
174
174
  postcss: true
175
175
  }
176
176
 
@@ -213,6 +213,11 @@ export interface Stringifier {
213
213
  (node: AnyNode, builder: Builder): void
214
214
  }
215
215
 
216
+ export interface JSONHydrator {
217
+ (data: object[]): Node[]
218
+ (data: object): Node
219
+ }
220
+
216
221
  export interface Syntax {
217
222
  /**
218
223
  * Function to generate AST by string.
@@ -352,6 +357,17 @@ export interface Postcss {
352
357
  */
353
358
  parse: Parser
354
359
 
360
+ /**
361
+ * Rehydrate a JSON AST (from `Node#toJSON`) back into the AST classes.
362
+ *
363
+ * ```js
364
+ * const json = root.toJSON()
365
+ * // save to file, send by network, etc
366
+ * const root2 = postcss.fromJSON(json)
367
+ * ```
368
+ */
369
+ fromJSON: JSONHydrator
370
+
355
371
  /**
356
372
  * Contains the `list` module.
357
373
  */
@@ -412,6 +428,7 @@ export interface Postcss {
412
428
 
413
429
  export const stringify: Stringifier
414
430
  export const parse: Parser
431
+ export const fromJSON: JSONHydrator
415
432
 
416
433
  export const comment: Postcss['comment']
417
434
  export const atRule: Postcss['atRule']
package/lib/postcss.js CHANGED
@@ -6,6 +6,7 @@ let LazyResult = require('./lazy-result')
6
6
  let Container = require('./container')
7
7
  let Processor = require('./processor')
8
8
  let stringify = require('./stringify')
9
+ let fromJSON = require('./fromJSON')
9
10
  let Warning = require('./warning')
10
11
  let Comment = require('./comment')
11
12
  let AtRule = require('./at-rule')
@@ -62,6 +63,7 @@ postcss.plugin = function plugin (name, initializer) {
62
63
 
63
64
  postcss.stringify = stringify
64
65
  postcss.parse = parse
66
+ postcss.fromJSON = fromJSON
65
67
  postcss.list = list
66
68
 
67
69
  postcss.comment = defaults => new Comment(defaults)
package/lib/postcss.mjs CHANGED
@@ -3,6 +3,7 @@ import postcss from './postcss.js'
3
3
  export default postcss
4
4
 
5
5
  export const stringify = postcss.stringify
6
+ export const fromJSON = postcss.fromJSON
6
7
  export const plugin = postcss.plugin
7
8
  export const parse = postcss.parse
8
9
  export const list = postcss.list
package/lib/processor.js CHANGED
@@ -5,7 +5,7 @@ let Root = require('./root')
5
5
 
6
6
  class Processor {
7
7
  constructor (plugins = []) {
8
- this.version = '8.1.14'
8
+ this.version = '8.2.3'
9
9
  this.plugins = this.normalize(plugins)
10
10
  }
11
11
 
package/lib/result.d.ts CHANGED
@@ -177,7 +177,7 @@ export default class Result {
177
177
  * @param opts Warning options.
178
178
  * @return Created warning.
179
179
  */
180
- warn (message: string, options?: WarningOptions): void
180
+ warn (message: string, options?: WarningOptions): Warning
181
181
 
182
182
  /**
183
183
  * Returns warnings from plugins. Filters `Warning` instances
package/lib/root.d.ts CHANGED
@@ -1,11 +1,6 @@
1
1
  import Container, { ContainerProps } from './container.js'
2
2
  import { ProcessOptions } from './postcss.js'
3
- import { ChildNode } from './node.js'
4
- import Declaration from './declaration.js'
5
- import Comment from './comment.js'
6
- import AtRule from './at-rule.js'
7
3
  import Result from './result.js'
8
- import Rule from './rule.js'
9
4
 
10
5
  interface RootRaws {
11
6
  /**
@@ -25,11 +25,19 @@ class Stringifier {
25
25
  }
26
26
 
27
27
  stringify (node, semicolon) {
28
+ /* istanbul ignore if */
29
+ if (!this[node.type]) {
30
+ throw new Error(
31
+ 'Unknown AST node type ' +
32
+ node.type +
33
+ '. ' +
34
+ 'Maybe you need to change PostCSS stringifier.'
35
+ )
36
+ }
28
37
  this[node.type](node, semicolon)
29
38
  }
30
39
 
31
40
  root (node) {
32
- this.root = node
33
41
  this.body(node)
34
42
  if (node.raws.after) this.builder(node.raws.after)
35
43
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "postcss",
3
- "version": "8.1.14",
3
+ "version": "8.2.3",
4
4
  "description": "Tool for transforming styles with JS plugins",
5
5
  "engines": {
6
6
  "node": "^10 || ^12 || >=14"