UNPKG

@stylable/core

Version:

CSS for Components

119 lines 4.9 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.transformInlineCustomSelectors = exports.transformInlineCustomSelectorMap = void 0; const css_selector_parser_1 = require("@tokey/css-selector-parser"); const lodash_clonedeep_1 = __importDefault(require("lodash.clonedeep")); function transformInlineCustomSelectorMap(customSelectors, report) { const result = {}; const link = (name, path) => { const ast = customSelectors[name]; if (!ast) { return; } result[name] = transformInlineCustomSelectors(ast, (nestedName) => { const selector = `:--${nestedName}`; if (path.includes(selector)) { // loop!: report & preserve source selector report({ type: 'circular', path }); return (0, css_selector_parser_1.parseCssSelector)(selector); } if (!result[nestedName]) { link(nestedName, [...path, selector]); } return result[nestedName]; }, ({ type, unknown }) => report({ type, origin: name, unknown })); }; for (const name of Object.keys(customSelectors)) { link(name, [`:--${name}`]); } return result; } exports.transformInlineCustomSelectorMap = transformInlineCustomSelectorMap; function isCustomSelectorNode(node) { return node.type === 'pseudo_class' && node.value.startsWith('--'); } /** * Takes a list of selectors and a function that returns a selector * against a custom selector name. * * Then search for inline custom selectors (e.g. ":--custom") and * replaces them with the retrieved selectors it receives */ function transformInlineCustomSelectors(inputSelectors, getCustomSelector, report) { const result = []; for (const selector of inputSelectors) { result.push(...transformInlineCustomSelector(selector, getCustomSelector, report)); } return result; } exports.transformInlineCustomSelectors = transformInlineCustomSelectors; function transformInlineCustomSelector(inputSelector, getCustomSelector, report) { const insertions = []; // get insertion points (0, css_selector_parser_1.walk)(inputSelector, (node, index, _nodes, parents) => { if (isCustomSelectorNode(node)) { const name = node.value.slice(2); const targetSelectors = getCustomSelector(name); if (!targetSelectors) { report({ type: 'unknown', origin: '', unknown: name }); } else if (targetSelectors.length !== 0) { const parent = parents[parents.length - 1]; if (parent && 'nodes' in parent && parent.nodes) { let selectorIndex = 0; insertions.push((progress) => { if (progress) { selectorIndex++; } const overflow = selectorIndex === targetSelectors.length; if (overflow) { selectorIndex = 0; } const currentSelector = targetSelectors[selectorIndex]; currentSelector.before = currentSelector.after = ''; parent.nodes[index] = currentSelector; return overflow; }); } } } }); // permute selectors const output = []; if (insertions.length) { // save first permutation insertions.forEach((updateSelector) => updateSelector(false)); output.push((0, lodash_clonedeep_1.default)(inputSelector)); // collect rest of permutations let run = true; while (run) { let progressIdx = 0; for (let i = 0; i < insertions.length; ++i) { const updateSelector = insertions[i]; const moveToNext = i === progressIdx; const overflow = updateSelector(moveToNext); if (overflow) { if (progressIdx < insertions.length - 1) { // advance next insertion point progressIdx++; } else { // finish run over all permutations run = false; return output; } } else { // no need to update any farther this round break; } } output.push((0, lodash_clonedeep_1.default)(inputSelector)); } } return [inputSelector]; } //# sourceMappingURL=custom-selector.js.map