diff options
| author | littleblack111 <littleblack11111@gmail.com> | 2026-05-18 23:10:59 +0800 |
|---|---|---|
| committer | littleblack111 <littleblack11111@gmail.com> | 2026-05-18 23:41:44 +0800 |
| commit | fc87c009806dcc98867f6b58efe29b042aa01dee (patch) | |
| tree | 8f59b3f4a5b66e9dfef2d40c8d318e258a521228 /node_modules/postcss-nested/index.js | |
| parent | 3336b2356ee6152d9c6ae59bd9b87ccbc0958407 (diff) | |
node: updatemain
Diffstat (limited to 'node_modules/postcss-nested/index.js')
| -rw-r--r-- | node_modules/postcss-nested/index.js | 361 |
1 files changed, 0 insertions, 361 deletions
diff --git a/node_modules/postcss-nested/index.js b/node_modules/postcss-nested/index.js deleted file mode 100644 index 79831b6c..00000000 --- a/node_modules/postcss-nested/index.js +++ /dev/null @@ -1,361 +0,0 @@ -const { AtRule, Rule } = require('postcss') -let parser = require('postcss-selector-parser') - -/** - * Run a selector string through postcss-selector-parser - */ -function parse(rawSelector, rule) { - let nodes - try { - parser(parsed => { - nodes = parsed - }).processSync(rawSelector) - } catch (e) { - if (rawSelector.includes(':')) { - throw rule ? rule.error('Missed semicolon') : e - } else { - throw rule ? rule.error(e.message) : e - } - } - return nodes.at(0) -} - -/** - * Replaces the "&" token in a node's selector with the parent selector - * similar to what SCSS does. - * - * Mutates the nodes list - */ -function interpolateAmpInSelector(nodes, parent) { - let replaced = false - nodes.each(node => { - if (node.type === 'nesting') { - let clonedParent = parent.clone({}) - if (node.value !== '&') { - node.replaceWith( - parse(node.value.replace('&', clonedParent.toString())) - ) - } else { - node.replaceWith(clonedParent) - } - replaced = true - } else if ('nodes' in node && node.nodes) { - if (interpolateAmpInSelector(node, parent)) { - replaced = true - } - } - }) - return replaced -} - -/** - * Combines parent and child selectors, in a SCSS-like way - */ -function mergeSelectors(parent, child) { - let merged = [] - parent.selectors.forEach(sel => { - let parentNode = parse(sel, parent) - - child.selectors.forEach(selector => { - if (!selector) { - return - } - let node = parse(selector, child) - let replaced = interpolateAmpInSelector(node, parentNode) - if (!replaced) { - node.prepend(parser.combinator({ value: ' ' })) - node.prepend(parentNode.clone({})) - } - merged.push(node.toString()) - }) - }) - return merged -} - -/** - * Move a child and its preceeding comment(s) to after "after" - */ -function breakOut(child, after) { - let prev = child.prev() - after.after(child) - while (prev && prev.type === 'comment') { - let nextPrev = prev.prev() - after.after(prev) - prev = nextPrev - } - return child -} - -function createFnAtruleChilds(bubble) { - return function atruleChilds(rule, atrule, bubbling, mergeSels = bubbling) { - let children = [] - atrule.each(child => { - if (child.type === 'rule' && bubbling) { - if (mergeSels) { - child.selectors = mergeSelectors(rule, child) - } - } else if (child.type === 'atrule' && child.nodes) { - if (bubble[child.name]) { - atruleChilds(rule, child, mergeSels) - } else if (atrule[rootRuleMergeSel] !== false) { - children.push(child) - } - } else { - children.push(child) - } - }) - if (bubbling) { - if (children.length) { - let clone = rule.clone({ nodes: [] }) - for (let child of children) { - clone.append(child) - } - atrule.prepend(clone) - } - } - } -} - -function pickDeclarations(selector, declarations, after) { - let parent = new Rule({ - nodes: [], - selector - }) - parent.append(declarations) - after.after(parent) - return parent -} - -function atruleNames(defaults, custom) { - let list = {} - for (let name of defaults) { - list[name] = true - } - if (custom) { - for (let name of custom) { - list[name.replace(/^@/, '')] = true - } - } - return list -} - -function parseRootRuleParams(params) { - params = params.trim() - let braceBlock = params.match(/^\((.*)\)$/) - if (!braceBlock) { - return { selector: params, type: 'basic' } - } - let bits = braceBlock[1].match(/^(with(?:out)?):(.+)$/) - if (bits) { - let allowlist = bits[1] === 'with' - let rules = Object.fromEntries( - bits[2] - .trim() - .split(/\s+/) - .map(name => [name, true]) - ) - if (allowlist && rules.all) { - return { type: 'noop' } - } - let escapes = rule => !!rules[rule] - if (rules.all) { - escapes = () => true - } else if (allowlist) { - escapes = rule => (rule === 'all' ? false : !rules[rule]) - } - - return { - escapes, - type: 'withrules' - } - } - // Unrecognized brace block - return { type: 'unknown' } -} - -function getAncestorRules(leaf) { - let lineage = [] - let parent = leaf.parent - - while (parent && parent instanceof AtRule) { - lineage.push(parent) - parent = parent.parent - } - return lineage -} - -function unwrapRootRule(rule) { - let escapes = rule[rootRuleEscapes] - - if (!escapes) { - rule.after(rule.nodes) - } else { - let nodes = rule.nodes - - let topEscaped - let topEscapedIdx = -1 - let breakoutLeaf - let breakoutRoot - let clone - - let lineage = getAncestorRules(rule) - lineage.forEach((parent, i) => { - if (escapes(parent.name)) { - topEscaped = parent - topEscapedIdx = i - breakoutRoot = clone - } else { - let oldClone = clone - clone = parent.clone({ nodes: [] }) - oldClone && clone.append(oldClone) - breakoutLeaf = breakoutLeaf || clone - } - }) - - if (!topEscaped) { - rule.after(nodes) - } else if (!breakoutRoot) { - topEscaped.after(nodes) - } else { - let leaf = breakoutLeaf - leaf.append(nodes) - topEscaped.after(breakoutRoot) - } - - if (rule.next() && topEscaped) { - let restRoot - lineage.slice(0, topEscapedIdx + 1).forEach((parent, i, arr) => { - let oldRoot = restRoot - restRoot = parent.clone({ nodes: [] }) - oldRoot && restRoot.append(oldRoot) - - let nextSibs = [] - let _child = arr[i - 1] || rule - let next = _child.next() - while (next) { - nextSibs.push(next) - next = next.next() - } - restRoot.append(nextSibs) - }) - restRoot && (breakoutRoot || nodes[nodes.length - 1]).after(restRoot) - } - } - - rule.remove() -} - -const rootRuleMergeSel = Symbol('rootRuleMergeSel') -const rootRuleEscapes = Symbol('rootRuleEscapes') - -function normalizeRootRule(rule) { - let { params } = rule - let { escapes, selector, type } = parseRootRuleParams(params) - if (type === 'unknown') { - throw rule.error( - `Unknown @${rule.name} parameter ${JSON.stringify(params)}` - ) - } - if (type === 'basic' && selector) { - let selectorBlock = new Rule({ nodes: rule.nodes, selector }) - rule.removeAll() - rule.append(selectorBlock) - } - rule[rootRuleEscapes] = escapes - rule[rootRuleMergeSel] = escapes ? !escapes('all') : type === 'noop' -} - -const hasRootRule = Symbol('hasRootRule') - -module.exports = (opts = {}) => { - let bubble = atruleNames( - ['media', 'supports', 'layer', 'container', 'starting-style'], - opts.bubble - ) - let atruleChilds = createFnAtruleChilds(bubble) - let unwrap = atruleNames( - [ - 'document', - 'font-face', - 'keyframes', - '-webkit-keyframes', - '-moz-keyframes' - ], - opts.unwrap - ) - let rootRuleName = (opts.rootRuleName || 'at-root').replace(/^@/, '') - let preserveEmpty = opts.preserveEmpty - - return { - Once(root) { - root.walkAtRules(rootRuleName, node => { - normalizeRootRule(node) - root[hasRootRule] = true - }) - }, - - postcssPlugin: 'postcss-nested', - - RootExit(root) { - if (root[hasRootRule]) { - root.walkAtRules(rootRuleName, unwrapRootRule) - root[hasRootRule] = false - } - }, - - Rule(rule) { - let unwrapped = false - let after = rule - let copyDeclarations = false - let declarations = [] - - rule.each(child => { - if (child.type === 'rule') { - if (declarations.length) { - after = pickDeclarations(rule.selector, declarations, after) - declarations = [] - } - - copyDeclarations = true - unwrapped = true - child.selectors = mergeSelectors(rule, child) - after = breakOut(child, after) - } else if (child.type === 'atrule') { - if (declarations.length) { - after = pickDeclarations(rule.selector, declarations, after) - declarations = [] - } - if (child.name === rootRuleName) { - unwrapped = true - atruleChilds(rule, child, true, child[rootRuleMergeSel]) - after = breakOut(child, after) - } else if (bubble[child.name]) { - copyDeclarations = true - unwrapped = true - atruleChilds(rule, child, true) - after = breakOut(child, after) - } else if (unwrap[child.name]) { - copyDeclarations = true - unwrapped = true - atruleChilds(rule, child, false) - after = breakOut(child, after) - } else if (copyDeclarations) { - declarations.push(child) - } - } else if (child.type === 'decl' && copyDeclarations) { - declarations.push(child) - } - }) - - if (declarations.length) { - after = pickDeclarations(rule.selector, declarations, after) - } - - if (unwrapped && preserveEmpty !== true) { - rule.raws.semicolon = true - if (rule.nodes.length === 0) rule.remove() - } - } - } -} -module.exports.postcss = true |
