@stylable/core
Version:
CSS for Components
211 lines • 9.3 kB
JavaScript
;
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