postcss-nested 6.2.0 → 7.0.0

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.
Files changed (2) hide show
  1. package/index.js +93 -65
  2. package/package.json +3 -3
package/index.js CHANGED
@@ -53,12 +53,12 @@ function interpolateAmpInSelector(nodes, parent) {
53
53
  */
54
54
  function mergeSelectors(parent, child) {
55
55
  let merged = []
56
- parent.selectors.forEach(sel => {
56
+ for (let sel of parent.selectors) {
57
57
  let parentNode = parse(sel, parent)
58
58
 
59
- child.selectors.forEach(selector => {
59
+ for (let selector of child.selectors) {
60
60
  if (!selector) {
61
- return
61
+ continue
62
62
  }
63
63
  let node = parse(selector, child)
64
64
  let replaced = interpolateAmpInSelector(node, parentNode)
@@ -67,22 +67,43 @@ function mergeSelectors(parent, child) {
67
67
  node.prepend(parentNode.clone({}))
68
68
  }
69
69
  merged.push(node.toString())
70
- })
71
- })
70
+ }
71
+ }
72
72
  return merged
73
73
  }
74
74
 
75
75
  /**
76
- * Move a child and its preceeding comment(s) to after "after"
76
+ * Move a child and its preceding comment(s) to after "after"
77
+ * ! It is necessary to clarify the comment
77
78
  */
78
79
  function breakOut(child, after) {
79
- let prev = child.prev()
80
- after.after(child)
81
- while (prev && prev.type === 'comment') {
82
- let nextPrev = prev.prev()
83
- after.after(prev)
84
- prev = nextPrev
80
+ let changeParent = true
81
+
82
+ for (let node of after.nodes) {
83
+ if (!node.nodes) continue
84
+
85
+ let prevNode = node.prev()
86
+ if (prevNode?.type !== 'comment') continue
87
+
88
+ let parentRule = after.toString()
89
+
90
+ /* Checking that the comment "describes" the rule following. Like this:
91
+ /* comment about the rule below /*
92
+ .rule {}
93
+ */
94
+ let regexp = new RegExp(`${prevNode.toString()} *\n *${node.toString()}`)
95
+
96
+ if (parentRule.match(regexp)) {
97
+ changeParent = false
98
+ after.after(node).after(prevNode)
99
+ }
100
+ }
101
+
102
+ // It is necessary if the above child has never been moved
103
+ if (changeParent) {
104
+ after.after(child)
85
105
  }
106
+
86
107
  return child
87
108
  }
88
109
 
@@ -104,14 +125,12 @@ function createFnAtruleChilds(bubble) {
104
125
  children.push(child)
105
126
  }
106
127
  })
107
- if (bubbling) {
108
- if (children.length) {
109
- let clone = rule.clone({ nodes: [] })
110
- for (let child of children) {
111
- clone.append(child)
112
- }
113
- atrule.prepend(clone)
128
+ if (bubbling && children.length) {
129
+ let clone = rule.clone({ nodes: [] })
130
+ for (let child of children) {
131
+ clone.append(child)
114
132
  }
133
+ atrule.prepend(clone)
115
134
  }
116
135
  }
117
136
  }
@@ -125,16 +144,23 @@ function pickDeclarations(selector, declarations, after) {
125
144
  after.after(parent)
126
145
  return parent
127
146
  }
147
+ function pickAndClearDeclarations(ruleSelector, declarations, after, clear = true) {
148
+ if (!declarations.length) return [after, declarations]
128
149
 
129
- function atruleNames(defaults, custom) {
130
- let list = {}
131
- for (let name of defaults) {
132
- list[name] = true
150
+ after = pickDeclarations(ruleSelector, declarations, after)
151
+
152
+ if (clear) {
153
+ declarations = []
133
154
  }
134
- if (custom) {
135
- for (let name of custom) {
136
- list[name.replace(/^@/, '')] = true
137
- }
155
+
156
+ return [after, declarations]
157
+ }
158
+
159
+ function atruleNames(defaults, custom = '') {
160
+ let names = defaults.concat(custom)
161
+ let list = {}
162
+ for (let name of names) {
163
+ list[name.replace(/^@/, '')] = true
138
164
  }
139
165
  return list
140
166
  }
@@ -297,10 +323,10 @@ module.exports = (opts = {}) => {
297
323
  postcssPlugin: 'postcss-nested',
298
324
 
299
325
  RootExit(root) {
300
- if (root[hasRootRule]) {
301
- root.walkAtRules(rootRuleName, unwrapRootRule)
302
- root[hasRootRule] = false
303
- }
326
+ if (!root[hasRootRule]) return
327
+
328
+ root.walkAtRules(rootRuleName, unwrapRootRule)
329
+ root[hasRootRule] = false
304
330
  },
305
331
 
306
332
  Rule(rule) {
@@ -310,46 +336,48 @@ module.exports = (opts = {}) => {
310
336
  let declarations = []
311
337
 
312
338
  rule.each(child => {
313
- if (child.type === 'rule') {
314
- if (declarations.length) {
315
- after = pickDeclarations(rule.selector, declarations, after)
316
- declarations = []
317
- }
318
-
319
- copyDeclarations = true
320
- unwrapped = true
321
- child.selectors = mergeSelectors(rule, child)
322
- after = breakOut(child, after)
323
- } else if (child.type === 'atrule') {
324
- if (declarations.length) {
325
- after = pickDeclarations(rule.selector, declarations, after)
326
- declarations = []
327
- }
328
- if (child.name === rootRuleName) {
329
- unwrapped = true
330
- atruleChilds(rule, child, true, child[rootRuleMergeSel])
331
- after = breakOut(child, after)
332
- } else if (bubble[child.name]) {
333
- copyDeclarations = true
334
- unwrapped = true
335
- atruleChilds(rule, child, true)
336
- after = breakOut(child, after)
337
- } else if (unwrap[child.name]) {
339
+ switch (child.type) {
340
+ case 'atrule':
341
+ [after, declarations] = pickAndClearDeclarations(rule.selector, declarations, after)
342
+
343
+ if (child.name === rootRuleName) {
344
+ unwrapped = true
345
+ atruleChilds(rule, child, true, child[rootRuleMergeSel])
346
+ after = breakOut(child, after)
347
+ } else if (bubble[child.name]) {
348
+ copyDeclarations = true
349
+ unwrapped = true
350
+ atruleChilds(rule, child, true)
351
+ after = breakOut(child, after)
352
+ } else if (unwrap[child.name]) {
353
+ copyDeclarations = true
354
+ unwrapped = true
355
+ atruleChilds(rule, child, false)
356
+ after = breakOut(child, after)
357
+ } else if (copyDeclarations) {
358
+ declarations.push(child)
359
+ }
360
+
361
+ break
362
+ case 'decl':
363
+ if (copyDeclarations) {
364
+ declarations.push(child)
365
+ }
366
+
367
+ break
368
+ case 'rule':
369
+ [after, declarations] = pickAndClearDeclarations(rule.selector, declarations, after)
370
+
338
371
  copyDeclarations = true
339
372
  unwrapped = true
340
- atruleChilds(rule, child, false)
373
+ child.selectors = mergeSelectors(rule, child)
341
374
  after = breakOut(child, after)
342
- } else if (copyDeclarations) {
343
- declarations.push(child)
344
- }
345
- } else if (child.type === 'decl' && copyDeclarations) {
346
- declarations.push(child)
375
+
376
+ break
347
377
  }
348
378
  })
349
379
 
350
- if (declarations.length) {
351
- after = pickDeclarations(rule.selector, declarations, after)
352
- }
380
+ pickAndClearDeclarations(rule.selector, declarations, after, false)
353
381
 
354
382
  if (unwrapped && preserveEmpty !== true) {
355
383
  rule.raws.semicolon = true
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "postcss-nested",
3
- "version": "6.2.0",
3
+ "version": "7.0.0",
4
4
  "description": "PostCSS plugin to unwrap nested rules like how Sass does it",
5
5
  "keywords": [
6
6
  "postcss",
@@ -13,7 +13,7 @@
13
13
  "license": "MIT",
14
14
  "repository": "postcss/postcss-nested",
15
15
  "engines": {
16
- "node": ">=12.0"
16
+ "node": ">=18.0"
17
17
  },
18
18
  "funding": [
19
19
  {
@@ -29,6 +29,6 @@
29
29
  "postcss": "^8.2.14"
30
30
  },
31
31
  "dependencies": {
32
- "postcss-selector-parser": "^6.1.1"
32
+ "postcss-selector-parser": "^7.0.0"
33
33
  }
34
34
  }