postcss-nested 6.2.0 → 7.0.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.
Files changed (2) hide show
  1. package/index.js +96 -66
  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,45 @@ 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
77
  */
78
- 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
78
+ function breakOut(child, parent) {
79
+ let changeParent = true
80
+ let lastNode = parent
81
+
82
+ for (let node of parent.nodes) {
83
+ if (!node.nodes) continue
84
+
85
+ let prevNode = node.prev()
86
+ if (prevNode?.type !== 'comment') continue
87
+
88
+ let parentRule = parent.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 = /[*]\/ *\n.*{/
95
+
96
+ if (parentRule.match(regexp)) {
97
+ changeParent = false
98
+ lastNode.after(node).after(prevNode)
99
+
100
+ lastNode = node
101
+ }
102
+ }
103
+
104
+ // It is necessary if the above child has never been moved
105
+ if (changeParent) {
106
+ parent.after(child)
85
107
  }
108
+
86
109
  return child
87
110
  }
88
111
 
@@ -104,14 +127,12 @@ function createFnAtruleChilds(bubble) {
104
127
  children.push(child)
105
128
  }
106
129
  })
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)
130
+ if (bubbling && children.length) {
131
+ let clone = rule.clone({ nodes: [] })
132
+ for (let child of children) {
133
+ clone.append(child)
114
134
  }
135
+ atrule.prepend(clone)
115
136
  }
116
137
  }
117
138
  }
@@ -125,16 +146,23 @@ function pickDeclarations(selector, declarations, after) {
125
146
  after.after(parent)
126
147
  return parent
127
148
  }
149
+ function pickAndClearDeclarations(ruleSelector, declarations, after, clear = true) {
150
+ if (!declarations.length) return [after, declarations]
128
151
 
129
- function atruleNames(defaults, custom) {
130
- let list = {}
131
- for (let name of defaults) {
132
- list[name] = true
152
+ after = pickDeclarations(ruleSelector, declarations, after)
153
+
154
+ if (clear) {
155
+ declarations = []
133
156
  }
134
- if (custom) {
135
- for (let name of custom) {
136
- list[name.replace(/^@/, '')] = true
137
- }
157
+
158
+ return [after, declarations]
159
+ }
160
+
161
+ function atruleNames(defaults, custom = '') {
162
+ let names = defaults.concat(custom)
163
+ let list = {}
164
+ for (let name of names) {
165
+ list[name.replace(/^@/, '')] = true
138
166
  }
139
167
  return list
140
168
  }
@@ -297,10 +325,10 @@ module.exports = (opts = {}) => {
297
325
  postcssPlugin: 'postcss-nested',
298
326
 
299
327
  RootExit(root) {
300
- if (root[hasRootRule]) {
301
- root.walkAtRules(rootRuleName, unwrapRootRule)
302
- root[hasRootRule] = false
303
- }
328
+ if (!root[hasRootRule]) return
329
+
330
+ root.walkAtRules(rootRuleName, unwrapRootRule)
331
+ root[hasRootRule] = false
304
332
  },
305
333
 
306
334
  Rule(rule) {
@@ -310,46 +338,48 @@ module.exports = (opts = {}) => {
310
338
  let declarations = []
311
339
 
312
340
  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]) {
341
+ switch (child.type) {
342
+ case 'atrule':
343
+ [after, declarations] = pickAndClearDeclarations(rule.selector, declarations, after)
344
+
345
+ if (child.name === rootRuleName) {
346
+ unwrapped = true
347
+ atruleChilds(rule, child, true, child[rootRuleMergeSel])
348
+ after = breakOut(child, after)
349
+ } else if (bubble[child.name]) {
350
+ copyDeclarations = true
351
+ unwrapped = true
352
+ atruleChilds(rule, child, true)
353
+ after = breakOut(child, after)
354
+ } else if (unwrap[child.name]) {
355
+ copyDeclarations = true
356
+ unwrapped = true
357
+ atruleChilds(rule, child, false)
358
+ after = breakOut(child, after)
359
+ } else if (copyDeclarations) {
360
+ declarations.push(child)
361
+ }
362
+
363
+ break
364
+ case 'decl':
365
+ if (copyDeclarations) {
366
+ declarations.push(child)
367
+ }
368
+
369
+ break
370
+ case 'rule':
371
+ [after, declarations] = pickAndClearDeclarations(rule.selector, declarations, after)
372
+
338
373
  copyDeclarations = true
339
374
  unwrapped = true
340
- atruleChilds(rule, child, false)
375
+ child.selectors = mergeSelectors(rule, child)
341
376
  after = breakOut(child, after)
342
- } else if (copyDeclarations) {
343
- declarations.push(child)
344
- }
345
- } else if (child.type === 'decl' && copyDeclarations) {
346
- declarations.push(child)
377
+
378
+ break
347
379
  }
348
380
  })
349
381
 
350
- if (declarations.length) {
351
- after = pickDeclarations(rule.selector, declarations, after)
352
- }
382
+ pickAndClearDeclarations(rule.selector, declarations, after, false)
353
383
 
354
384
  if (unwrapped && preserveEmpty !== true) {
355
385
  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.1",
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
  }