postcss 8.1.12 → 8.2.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/CHANGELOG.md CHANGED
@@ -1,6 +1,18 @@
1
1
  # Change Log
2
2
  This project adheres to [Semantic Versioning](https://semver.org/).
3
3
 
4
+ ## 8.2.1
5
+ * Fixed `Node#toJSON()` and `postcss.fromJSON()` (by Niklas Mischkulnig).
6
+
7
+ ## 8.2 “Prince Orobas”
8
+ * Added `Node#toJSON()` and `postcss.fromJSON()` (by Niklas Mischkulnig).
9
+
10
+ ## 8.1.14
11
+ * Fixed parser performance regression.
12
+
13
+ ## 8.1.13
14
+ * Fixed broken AST after moving nodes in visitor API.
15
+
4
16
  ## 8.1.12
5
17
  * Fixed Autoprefixer regression.
6
18
 
package/lib/container.js CHANGED
@@ -337,6 +337,7 @@ class Container extends Node {
337
337
  let processed = nodes.map(i => {
338
338
  // istanbul ignore next
339
339
  if (typeof i.markDirty !== 'function') rebuild(i)
340
+ i = i.proxyOf
340
341
  if (i.parent) i.parent.removeChild(i)
341
342
  if (i[isClean]) markDirtyUp(i)
342
343
  if (typeof i.raws.before === 'undefined') {
@@ -0,0 +1,5 @@
1
+ import { JSONHydrator } from './postcss.js'
2
+
3
+ declare const fromJSON: JSONHydrator
4
+
5
+ export default fromJSON
@@ -0,0 +1,52 @@
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
+ let { inputs: ownInputs, ...defaults } = json
13
+ if (ownInputs) {
14
+ inputs = []
15
+ for (let input of ownInputs) {
16
+ let inputHydrated = { ...input, __proto__: Input.prototype }
17
+ if (inputHydrated.map) {
18
+ inputHydrated.map = {
19
+ ...inputHydrated.map,
20
+ __proto__: PreviousMap.prototype
21
+ }
22
+ }
23
+ inputs.push(inputHydrated)
24
+ }
25
+ }
26
+ if (defaults.nodes) {
27
+ defaults.nodes = json.nodes.map(n => fromJSON(n, inputs))
28
+ }
29
+ if (defaults.source) {
30
+ let { inputId, ...source } = defaults.source
31
+ defaults.source = source
32
+ if (inputId != null) {
33
+ defaults.source.input = inputs[inputId]
34
+ }
35
+ }
36
+ if (defaults.type === 'root') {
37
+ return new Root(defaults)
38
+ } else if (defaults.type === 'decl') {
39
+ return new Declaration(defaults)
40
+ } else if (defaults.type === 'rule') {
41
+ return new Rule(defaults)
42
+ } else if (defaults.type === 'comment') {
43
+ return new Comment(defaults)
44
+ } else if (defaults.type === 'atrule') {
45
+ return new AtRule(defaults)
46
+ } else {
47
+ throw new Error('Unknown node type: ' + json.type)
48
+ }
49
+ }
50
+
51
+ module.exports = fromJSON
52
+ fromJSON.default = fromJSON
package/lib/input.js CHANGED
@@ -3,12 +3,13 @@
3
3
  let { fileURLToPath, pathToFileURL } = require('url')
4
4
  let { resolve, isAbsolute } = require('path')
5
5
  let { nanoid } = require('nanoid/non-secure')
6
- let vfileLocation = require('vfile-location')
7
6
 
8
7
  let terminalHighlight = require('./terminal-highlight')
9
8
  let CssSyntaxError = require('./css-syntax-error')
10
9
  let PreviousMap = require('./previous-map')
11
10
 
11
+ let fromOffsetCache = Symbol('fromOffset cache')
12
+
12
13
  class Input {
13
14
  constructor (css, opts = {}) {
14
15
  if (
@@ -50,15 +51,45 @@ class Input {
50
51
  }
51
52
 
52
53
  fromOffset (offset) {
53
- let finder = vfileLocation(this.css)
54
- this.fromOffset = i => {
55
- let position = finder.toPoint(i)
56
- return {
57
- line: position.line,
58
- col: position.column
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
+ }
64
+
65
+ this[fromOffsetCache] = lineToIndex
66
+ } else {
67
+ lineToIndex = this[fromOffsetCache]
68
+ }
69
+ lastLine = lineToIndex[lineToIndex.length - 1]
70
+
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
86
+ }
59
87
  }
60
88
  }
61
- return this.fromOffset(offset)
89
+ return {
90
+ line: min + 1,
91
+ col: offset - lineToIndex[min] + 1
92
+ }
62
93
  }
63
94
 
64
95
  error (message, line, column, opts = {}) {
@@ -142,6 +173,22 @@ class Input {
142
173
  get from () {
143
174
  return this.file || this.id
144
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
+ }
145
192
  }
146
193
 
147
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(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(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
@@ -213,6 +213,10 @@ export interface Stringifier {
213
213
  (node: AnyNode, builder: Builder): void
214
214
  }
215
215
 
216
+ export interface JSONHydrator {
217
+ (data: object): Node
218
+ }
219
+
216
220
  export interface Syntax {
217
221
  /**
218
222
  * Function to generate AST by string.
@@ -352,6 +356,17 @@ export interface Postcss {
352
356
  */
353
357
  parse: Parser
354
358
 
359
+ /**
360
+ * Rehydrate a JSON AST (from `Node#toJSON`) back into the AST classes.
361
+ *
362
+ * ```js
363
+ * const json = root.toJSON()
364
+ * // save to file, send by network, etc
365
+ * const root2 = postcss.fromJSON(json)
366
+ * ```
367
+ */
368
+ fromJSON: JSONHydrator
369
+
355
370
  /**
356
371
  * Contains the `list` module.
357
372
  */
@@ -412,6 +427,7 @@ export interface Postcss {
412
427
 
413
428
  export const stringify: Stringifier
414
429
  export const parse: Parser
430
+ export const fromJSON: JSONHydrator
415
431
 
416
432
  export const comment: Postcss['comment']
417
433
  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.12'
8
+ this.version = '8.2.1'
9
9
  this.plugins = this.normalize(plugins)
10
10
  }
11
11
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "postcss",
3
- "version": "8.1.12",
3
+ "version": "8.2.1",
4
4
  "description": "Tool for transforming styles with JS plugins",
5
5
  "engines": {
6
6
  "node": "^10 || ^12 || >=14"
@@ -37,8 +37,7 @@
37
37
  "dependencies": {
38
38
  "colorette": "^1.2.1",
39
39
  "nanoid": "^3.1.20",
40
- "source-map": "^0.6.1",
41
- "vfile-location": "^3.2.0"
40
+ "source-map": "^0.6.1"
42
41
  },
43
42
  "browser": {
44
43
  "./lib/terminal-highlight": false,