postcss-nesting
Advanced tools
Comparing version 6.0.0 to 7.0.0
# Changes to PostCSS Nesting | ||
### 7.0.0 (September 17, 2018) | ||
- Updated: Support for PostCSS v7+ | ||
- Updated: Support for Node v6+ | ||
In a comment, a CSSWG member expressed interest in handling nested `@media` | ||
while handling selector nesting. Since the specification has yet to be added | ||
to the official CSSWG repository, nested at-rule deprecation is further delayed. | ||
### 6.0.0 (June 9, 2018) | ||
@@ -4,0 +13,0 @@ |
123
index.cjs.js
@@ -9,20 +9,18 @@ 'use strict'; | ||
function shiftNodesBeforeParent(node) { | ||
const parent = node.parent; | ||
const index = parent.index(node); | ||
const parent = node.parent; | ||
const index = parent.index(node); // conditionally move previous siblings into a clone of the parent | ||
// conditionally move previous siblings into a clone of the parent | ||
if (index) { | ||
parent.cloneBefore().removeAll().append(parent.nodes.slice(0, index)); | ||
} | ||
if (index) { | ||
parent.cloneBefore().removeAll().append(parent.nodes.slice(0, index)); | ||
} // move the current node before the parent (and after the conditional clone) | ||
// move the current node before the parent (and after the conditional clone) | ||
parent.before(node); | ||
return parent; | ||
parent.before(node); | ||
return parent; | ||
} | ||
function cleanupParent(parent) { | ||
if (!parent.nodes.length) { | ||
parent.remove(); | ||
} | ||
if (!parent.nodes.length) { | ||
parent.remove(); | ||
} | ||
} | ||
@@ -32,45 +30,33 @@ | ||
var validSelector = /&(?:[^\w-|]|$)/; | ||
const replaceable = /&/g; | ||
function mergeSelectors(fromSelectors, toSelectors) { | ||
return fromSelectors.reduce((selectors, fromSelector) => selectors.concat(toSelectors.map(toSelector => toSelector.replace(replaceable, fromSelector))), []); | ||
return fromSelectors.reduce((selectors, fromSelector) => selectors.concat(toSelectors.map(toSelector => toSelector.replace(replaceable, fromSelector))), []); | ||
} | ||
function transformRuleWithinRule(node) { | ||
// move previous siblings and the node to before the parent | ||
const parent = shiftNodesBeforeParent(node); | ||
// move previous siblings and the node to before the parent | ||
const parent = shiftNodesBeforeParent(node); // update the selectors of the node to be merged with the parent | ||
// update the selectors of the node to be merged with the parent | ||
node.selectors = mergeSelectors(parent.selectors, node.selectors); | ||
node.selectors = mergeSelectors(parent.selectors, node.selectors); // conditionally cleanup an empty parent rule | ||
// conditionally cleanup an empty parent rule | ||
cleanupParent(parent); | ||
cleanupParent(parent); | ||
} | ||
const isRuleWithinRule = node => node.type === 'rule' && Object(node.parent).type === 'rule' && node.selectors.every(selector => selector.trim().lastIndexOf('&') === 0 && validSelector.test(selector)); | ||
const comma = postcss.list.comma; | ||
function transformNestRuleWithinRule(node) { | ||
// move previous siblings and the node to before the parent | ||
const parent = shiftNodesBeforeParent(node); | ||
// move previous siblings and the node to before the parent | ||
const parent = shiftNodesBeforeParent(node); // clone the parent as a new rule with children appended to it | ||
// clone the parent as a new rule with children appended to it | ||
const rule = parent.clone().removeAll().append(node.nodes); | ||
const rule = parent.clone().removeAll().append(node.nodes); // replace the node with the new rule | ||
// replace the node with the new rule | ||
node.replaceWith(rule); | ||
node.replaceWith(rule); // update the selectors of the node to be merged with the parent | ||
// update the selectors of the node to be merged with the parent | ||
rule.selectors = mergeSelectors(parent.selectors, comma(node.params)); | ||
rule.selectors = mergeSelectors(parent.selectors, comma(node.params)); // conditionally cleanup an empty parent rule | ||
// conditionally cleanup an empty parent rule | ||
cleanupParent(parent); | ||
cleanupParent(parent); // walk the children of the new rule | ||
// walk the children of the new rule | ||
walk(rule); | ||
walk(rule); | ||
} | ||
const isNestRuleWithinRule = node => node.type === 'atrule' && node.name === 'nest' && Object(node.parent).type === 'rule' && comma(node.params).every(selector => selector.split('&').length === 2 && validSelector.test(selector)); | ||
@@ -86,25 +72,18 @@ | ||
function atruleWithinRule(node) { | ||
// move previous siblings and the node to before the parent | ||
const parent = shiftNodesBeforeParent(node); | ||
// move previous siblings and the node to before the parent | ||
const parent = shiftNodesBeforeParent(node); // clone the parent as a new rule with children appended to it | ||
// clone the parent as a new rule with children appended to it | ||
const rule = parent.clone().removeAll().append(node.nodes); | ||
const rule = parent.clone().removeAll().append(node.nodes); // append the new rule to the node | ||
// append the new rule to the node | ||
node.append(rule); | ||
node.append(rule); // conditionally cleanup an empty parent rule | ||
// conditionally cleanup an empty parent rule | ||
cleanupParent(parent); | ||
cleanupParent(parent); // walk the children of the new rule | ||
// walk the children of the new rule | ||
walk(rule); | ||
walk(rule); | ||
} | ||
const isAtruleWithinRule = node => node.type === 'atrule' && validAtrules.indexOf(node.name) !== -1 && Object(node.parent).type === 'rule'; | ||
const comma$1 = postcss.list.comma; | ||
function mergeParams(fromParams, toParams) { | ||
return comma$1(fromParams).map(params1 => comma$1(toParams).map(params2 => `${params1} and ${params2}`).join(', ')).join(', '); | ||
return comma$1(fromParams).map(params1 => comma$1(toParams).map(params2 => `${params1} and ${params2}`).join(', ')).join(', '); | ||
} | ||
@@ -118,32 +97,29 @@ | ||
function transformAtruleWithinAtrule(node) { | ||
// move previous siblings and the node to before the parent | ||
const parent = shiftNodesBeforeParent(node); | ||
// move previous siblings and the node to before the parent | ||
const parent = shiftNodesBeforeParent(node); // update the params of the node to be merged with the parent | ||
// update the params of the node to be merged with the parent | ||
node.params = mergeParams(parent.params, node.params); | ||
node.params = mergeParams(parent.params, node.params); // conditionally cleanup an empty parent rule | ||
// conditionally cleanup an empty parent rule | ||
cleanupParent(parent); | ||
cleanupParent(parent); | ||
} | ||
const isAtruleWithinAtrule = node => node.type === 'atrule' && validAtrules.indexOf(node.name) !== -1 && Object(node.parent).type === 'atrule' && node.name === node.parent.name; | ||
function walk(node) { | ||
node.nodes.slice(0).forEach(child => { | ||
if (child.parent === node) { | ||
if (isRuleWithinRule(child)) { | ||
transformRuleWithinRule(child); | ||
} else if (isNestRuleWithinRule(child)) { | ||
transformNestRuleWithinRule(child); | ||
} else if (isAtruleWithinRule(child)) { | ||
atruleWithinRule(child); | ||
} else if (isAtruleWithinAtrule(child)) { | ||
transformAtruleWithinAtrule(child); | ||
} | ||
node.nodes.slice(0).forEach(child => { | ||
if (child.parent === node) { | ||
if (isRuleWithinRule(child)) { | ||
transformRuleWithinRule(child); | ||
} else if (isNestRuleWithinRule(child)) { | ||
transformNestRuleWithinRule(child); | ||
} else if (isAtruleWithinRule(child)) { | ||
atruleWithinRule(child); | ||
} else if (isAtruleWithinAtrule(child)) { | ||
transformAtruleWithinAtrule(child); | ||
} | ||
if (Object(child.nodes).length) { | ||
walk(child); | ||
} | ||
} | ||
}); | ||
if (Object(child.nodes).length) { | ||
walk(child); | ||
} | ||
} | ||
}); | ||
} | ||
@@ -154,1 +130,2 @@ | ||
module.exports = index; | ||
//# sourceMappingURL=index.cjs.js.map |
{ | ||
"name": "postcss-nesting", | ||
"version": "6.0.0", | ||
"version": "7.0.0", | ||
"description": "Nest style rules inside each other", | ||
@@ -27,15 +27,15 @@ "author": "Jonathan Neal <jonathantneal@hotmail.com>", | ||
"dependencies": { | ||
"postcss": "^6.0.22" | ||
"postcss": "^7.0.2" | ||
}, | ||
"devDependencies": { | ||
"babel-core": "^6.26.3", | ||
"babel-eslint": "^8.2.3", | ||
"@babel/core": "^7.0.0", | ||
"@babel/preset-env": "^7.0.0", | ||
"babel-eslint": "^9.0.0", | ||
"babel-plugin-array-includes": "^2.0.3", | ||
"babel-preset-env": "^1.7.0", | ||
"eslint": "^4.19.1", | ||
"eslint": "^5.6.0", | ||
"eslint-config-dev": "^2.0.0", | ||
"postcss-tape": "^2.2.0", | ||
"pre-commit": "^1.2.2", | ||
"rollup": "^0.60.1", | ||
"rollup-plugin-babel": "^3.0.4" | ||
"rollup": "^0.66.0", | ||
"rollup-plugin-babel": "^4.0.1" | ||
}, | ||
@@ -42,0 +42,0 @@ "eslintConfig": { |
# PostCSS Nesting [<img src="https://postcss.github.io/postcss/logo.svg" alt="PostCSS" width="90" height="90" align="right">][postcss] | ||
[![NPM Version][npm-img]][npm-url] | ||
[![CSS Standard Status][css-img]][css-url] | ||
[![NPM Version][npm-img]][npm-url] | ||
[![Build Status][cli-img]][cli-url] | ||
@@ -6,0 +6,0 @@ [![Support Chat][git-img]][git-url] |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
0
18205
5
92
+ Addedpicocolors@0.2.1(transitive)
+ Addedpostcss@7.0.39(transitive)
- Removedansi-styles@3.2.1(transitive)
- Removedchalk@2.4.2(transitive)
- Removedcolor-convert@1.9.3(transitive)
- Removedcolor-name@1.1.3(transitive)
- Removedescape-string-regexp@1.0.5(transitive)
- Removedhas-flag@3.0.0(transitive)
- Removedpostcss@6.0.23(transitive)
- Removedsupports-color@5.5.0(transitive)
Updatedpostcss@^7.0.2