UNPKG

@stylable/core

Version:

CSS for Components

211 lines 9.3 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.findRule = exports.isStMixinMarker = exports.stMixinMarker = exports.createSubsetAst = exports.isInConditionalGroup = exports.isChildOfAtRule = void 0; const selector_1 = require("./selector"); const css_selector_parser_1 = require("@tokey/css-selector-parser"); const postcss = __importStar(require("postcss")); const custom_selector_1 = require("./custom-selector"); function isChildOfAtRule(rule, atRuleName) { let currentParent = rule.parent; while (currentParent) { if (currentParent.type === 'atrule' && currentParent.name === atRuleName) { return true; } currentParent = currentParent.parent; } return false; } exports.isChildOfAtRule = isChildOfAtRule; function isInConditionalGroup(node, includeRoot = true) { // https://www.w3.org/TR/css-conditional-3/#contents-of const parent = node.parent; return (parent && ((includeRoot && parent.type === `root`) || (parent.type === `atrule` && (parent.name === `media` || parent.name === `supports`)))); } exports.isInConditionalGroup = isInConditionalGroup; function createSubsetAst(root, selectorPrefix, mixinTarget, isRoot = false, getCustomSelector, isNestedInMixin = false) { // keyframes on class mixin? const prefixSelectorList = (0, selector_1.parseSelectorWithCache)(selectorPrefix); const prefixType = prefixSelectorList[0].nodes[0]; const containsPrefix = containsMatchInFirstChunk.bind(null, prefixType); const mixinRoot = mixinTarget ? mixinTarget : postcss.root(); root.nodes?.forEach((node) => { if (node.type === 'decl') { mixinTarget?.append(node.clone()); } else if (node.type === `rule` && (node.selector === ':vars' || node.selector === ':import')) { // nodes that don't mix return; } else if (node.type === `rule`) { const selectorAst = (0, selector_1.parseSelectorWithCache)(node.selector, { clone: true }); let ast = isRoot ? (0, selector_1.scopeNestedSelector)(prefixSelectorList, selectorAst, true).ast : selectorAst; if (getCustomSelector) { ast = (0, custom_selector_1.transformInlineCustomSelectors)(ast, getCustomSelector, () => { /*don't report*/ }); } const matchesSelectors = isRoot || isNestedInMixin ? ast : ast.filter((node) => containsPrefix(node)); if (matchesSelectors.length) { const selector = (0, selector_1.stringifySelector)(matchesSelectors.map((selectorNode) => { if (!isRoot) { selectorNode = fixChunkOrdering(selectorNode, prefixType); } replaceTargetWithMixinAnchor(selectorNode, prefixType); return selectorNode; })); const clonedRule = createSubsetAst(node, selectorPrefix, node.clone({ selector, nodes: [] }), isRoot, getCustomSelector, true /*isNestedInMixin*/); mixinRoot.append(clonedRule); } } else if (node.type === `atrule`) { if (node.name === 'media' || node.name === 'supports' || node.name === 'st-scope' || node.name === 'layer' || node.name === 'container') { let scopeSelector = node.name === 'st-scope' ? node.params : ''; let atruleHasMixin = isNestedInMixin || false; if (scopeSelector) { const ast = (0, selector_1.parseSelectorWithCache)(scopeSelector, { clone: true }); const matchesSelectors = isRoot ? ast : ast.filter((node) => containsPrefix(node)); if (matchesSelectors.length) { atruleHasMixin = true; scopeSelector = (0, selector_1.stringifySelector)(matchesSelectors.map((selectorNode) => { if (!isRoot) { selectorNode = fixChunkOrdering(selectorNode, prefixType); } replaceTargetWithMixinAnchor(selectorNode, prefixType); return selectorNode; })); } } const atRuleSubset = createSubsetAst(node, selectorPrefix, postcss.atRule({ params: scopeSelector || node.params, name: node.name, }), isRoot, getCustomSelector, atruleHasMixin); if (atRuleSubset.nodes) { mixinRoot.append(atRuleSubset); } } else if (isRoot) { mixinRoot.append(node.clone()); } } else { // TODO: add warn? } }); return mixinRoot; } exports.createSubsetAst = createSubsetAst; exports.stMixinMarker = 'st-mixin-marker'; const isStMixinMarker = (node) => node.type === 'attribute' && node.value === exports.stMixinMarker; exports.isStMixinMarker = isStMixinMarker; function replaceTargetWithMixinAnchor(selectorNode, prefixType) { (0, selector_1.walkSelector)(selectorNode, (node) => { if ((0, selector_1.matchTypeAndValue)(node, prefixType)) { (0, selector_1.convertToSelector)(node).nodes = [ { type: `attribute`, value: exports.stMixinMarker, start: node.start, end: node.end, }, ]; } }); } function fixChunkOrdering(selectorNode, prefixType) { const compound = (0, css_selector_parser_1.groupCompoundSelectors)(selectorNode, { deep: true, splitPseudoElements: false, }); (0, selector_1.walkSelector)(compound, (node) => { if (node.type === `compound_selector`) { const simpleNodes = node.nodes; for (let i = 1; i < simpleNodes.length; i++) { const childNode = simpleNodes[i]; if ((0, selector_1.matchTypeAndValue)(childNode, prefixType)) { const chunk = simpleNodes.splice(i, simpleNodes.length - i); simpleNodes.unshift(...chunk); break; } } } }); return compound; } function containsMatchInFirstChunk(prefixType, selectorNode) { let isMatch = false; (0, selector_1.walkSelector)(selectorNode, (node) => { if (node.type === `combinator`) { return selector_1.walkSelector.stopAll; } else if (node.type === 'pseudo_class') { // handle nested match :is(.mix) if (node.nodes) { for (const innerSelectorNode of node.nodes) { if (containsMatchInFirstChunk(prefixType, innerSelectorNode)) { isMatch = true; } } } return selector_1.walkSelector.skipNested; } else if ((0, selector_1.matchTypeAndValue)(node, prefixType)) { isMatch = true; return selector_1.walkSelector.stopAll; } return; }); return isMatch; } /** @deprecated internal for transformer */ function findRule(root, selector, test = (statement) => statement.prop === `-st-extends`) { let found = null; root.walkRules(selector, (rule) => { const declarationIndex = rule.nodes ? rule.nodes.findIndex(test) : -1; const isSimplePerSelector = (0, selector_1.isSimpleSelector)(rule.selector); // This will assume that a selector that contains .a, .b:hover is simple! (for backward compatibility) const isSimple = isSimplePerSelector.reduce((acc, { isSimple }) => { return !isSimple ? false : acc; }, true); if (isSimple && !!~declarationIndex) { found = rule.nodes[declarationIndex]; } }); return found; } exports.findRule = findRule; //# sourceMappingURL=rule.js.map