UNPKG

@stylable/core

Version:

CSS for Components

165 lines 7.98 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.transformCustomSelectorInline = exports.getCustomSelectorNames = exports.getCustomSelectorExpended = exports.getCustomSelectors = exports.getCustomSelector = exports.isScoped = exports.hooks = exports.CUSTOM_SELECTOR_RE = exports.diagnostics = void 0; const plugable_record_1 = require("../helpers/plugable-record"); const feature_1 = require("./feature"); const custom_selector_1 = require("../helpers/custom-selector"); const selector_1 = require("../helpers/selector"); const postcss = __importStar(require("postcss")); const css_selector_parser_1 = require("@tokey/css-selector-parser"); const diagnostics_1 = require("../diagnostics"); exports.diagnostics = { UNKNOWN_CUSTOM_SELECTOR: (0, diagnostics_1.createDiagnosticReporter)('18001', 'error', (selector) => `The selector '${selector}' is undefined`), }; const dataKey = plugable_record_1.plugableRecord.key('st-custom-selector'); exports.CUSTOM_SELECTOR_RE = /:--[\w-]+/g; // HOOKS exports.hooks = (0, feature_1.createFeature)({ metaInit({ meta }) { plugable_record_1.plugableRecord.set(meta.data, dataKey, {}); }, analyzeAtRule({ context, atRule, analyzeRule }) { const params = atRule.params.split(/\s/); const customSelector = params.shift(); if (customSelector && customSelector.match(exports.CUSTOM_SELECTOR_RE)) { const selector = atRule.params.replace(customSelector, '').trim(); const ast = (0, selector_1.parseSelectorWithCache)(selector, { clone: true }); const isScoped = analyzeRule(postcss.rule({ selector, source: atRule.source }), { isScoped: false, originalNode: atRule, }); const analyzed = plugable_record_1.plugableRecord.getUnsafe(context.meta.data, dataKey); const name = customSelector.slice(3); analyzed[name] = { selector, ast, isScoped, def: atRule }; } else { // TODO: add warn there are two types one is not valid name and the other is empty name. } }, analyzeDone(context) { const analyzed = plugable_record_1.plugableRecord.getUnsafe(context.meta.data, dataKey); const customSelectors = {}; for (const [name, data] of Object.entries(analyzed)) { customSelectors[name] = data.ast; } const inlined = (0, custom_selector_1.transformInlineCustomSelectorMap)(customSelectors, (report) => { if (report.type === 'unknown' && analyzed[report.origin]) { const unknownSelector = `:--${report.unknown}`; context.diagnostics.report(exports.diagnostics.UNKNOWN_CUSTOM_SELECTOR(unknownSelector), { node: analyzed[report.origin].def, word: unknownSelector, }); } else if (report.type === 'circular') { // ToDo: report error } }); // cache inlined selector for (const [name, ast] of Object.entries(inlined)) { analyzed[name].ast = ast; analyzed[name].selector = (0, css_selector_parser_1.stringifySelectorAst)(ast); } }, prepareAST({ context, node, toRemove }) { // called with experimentalSelectorInference=false // split selectors & remove definitions if (node.type === 'rule' && node.selector.match(exports.CUSTOM_SELECTOR_RE)) { node.selector = transformCustomSelectorInline(context.meta, node.selector, { diagnostics: context.diagnostics, node, }); } else if (node.type === 'atrule' && node.name === 'custom-selector') { toRemove.push(node); } }, transformSelectorNode({ context, selectorContext, node }) { const customSelector = node.value.startsWith('--') && getCustomSelectorExpended(context.meta, node.value.slice(2)); if (customSelector) { const mappedSelectorAst = (0, selector_1.parseSelectorWithCache)(customSelector, { clone: true }); const mappedContext = selectorContext.createNestedContext(mappedSelectorAst); selectorContext.scopeSelectorAst(mappedContext); const inferredSelector = selectorContext.experimentalSelectorInference ? mappedContext.inferredMultipleSelectors : mappedContext.inferredSelector; selectorContext.setNextSelectorScope(inferredSelector, node); // doesn't add to the resolved elements if (selectorContext.transform) { selectorContext.transformIntoMultiSelector(node, mappedSelectorAst); } } return !!customSelector; }, transformAtRuleNode({ atRule }) { if (atRule.name === 'custom-selector') { atRule.remove(); } }, }); // API function isScoped(meta, name) { const analyzed = plugable_record_1.plugableRecord.getUnsafe(meta.data, dataKey); return analyzed[name]?.isScoped; } exports.isScoped = isScoped; function getCustomSelector(meta, name) { return plugable_record_1.plugableRecord.getUnsafe(meta.data, dataKey)[name]?.ast; } exports.getCustomSelector = getCustomSelector; function getCustomSelectors(meta) { const analyzed = plugable_record_1.plugableRecord.getUnsafe(meta.data, dataKey); return Object.entries(analyzed).reduce((acc, [name, { ast }]) => { acc[name] = ast; return acc; }, {}); } exports.getCustomSelectors = getCustomSelectors; function getCustomSelectorExpended(meta, name) { const analyzed = plugable_record_1.plugableRecord.getUnsafe(meta.data, dataKey); return analyzed[name]?.selector; } exports.getCustomSelectorExpended = getCustomSelectorExpended; function getCustomSelectorNames(meta) { const analyzed = plugable_record_1.plugableRecord.getUnsafe(meta.data, dataKey); return Object.keys(analyzed).map((name) => `:--${name}`); } exports.getCustomSelectorNames = getCustomSelectorNames; function transformCustomSelectorInline(meta, selector, options = {}) { const ast = (0, selector_1.parseSelectorWithCache)(selector, { clone: true }); const analyzed = plugable_record_1.plugableRecord.getUnsafe(meta.data, dataKey); const inlined = (0, custom_selector_1.transformInlineCustomSelectors)(ast, (name) => analyzed[name]?.ast, (report) => { if (options.diagnostics && options.node) { const unknownSelector = `:--${report.unknown}`; options.diagnostics.report(exports.diagnostics.UNKNOWN_CUSTOM_SELECTOR(unknownSelector), { node: options.node, word: unknownSelector, }); } }); return (0, css_selector_parser_1.stringifySelectorAst)(inlined); } exports.transformCustomSelectorInline = transformCustomSelectorInline; //# sourceMappingURL=st-custom-selector.js.map