UNPKG

@stylable/core

Version:

CSS for Components

285 lines 9.45 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.validateAllowedNodesUntil = exports.listOptions = exports.strategies = exports.groupValues = exports.getStringValue = exports.getFormatterArgs = exports.getNamedArgs = exports.SBTypesParsers = exports.STYLABLE_NAMED_MATCHER = exports.STYLABLE_VALUE_MATCHER = exports.stValuesMap = exports.stValues = exports.valueMapping = exports.rootValueMapping = exports.valueParserWarnings = void 0; const pseudo_states_1 = require("./pseudo-states"); const selector_utils_1 = require("./selector-utils"); const postcssValueParser = require('postcss-value-parser'); exports.valueParserWarnings = { VALUE_CANNOT_BE_STRING() { return 'value can not be a string (remove quotes?)'; }, CSS_MIXIN_FORCE_NAMED_PARAMS() { return 'CSS mixins must use named parameters (e.g. "func(name value, [name value, ...])")'; }, }; exports.rootValueMapping = { vars: ':vars', import: ':import', stScope: 'st-scope', namespace: 'namespace', }; exports.valueMapping = { from: '-st-from', named: '-st-named', default: '-st-default', root: '-st-root', states: '-st-states', extends: '-st-extends', mixin: '-st-mixin', global: '-st-global', }; exports.stValues = Object.keys(exports.valueMapping).map((key) => exports.valueMapping[key]); exports.stValuesMap = Object.keys(exports.valueMapping).reduce((acc, key) => { acc[exports.valueMapping[key]] = true; return acc; }, {}); exports.STYLABLE_VALUE_MATCHER = /^-st-/; exports.STYLABLE_NAMED_MATCHER = new RegExp(`^${exports.valueMapping.named}-(.+)`); exports.SBTypesParsers = { '-st-root'(value) { return value === 'false' ? false : true; }, '-st-global'(decl, _diagnostics) { // Experimental const selector = selector_utils_1.parseSelector(decl.value.replace(/^['"]/, '').replace(/['"]$/, '')); return selector.nodes[0].nodes; }, '-st-states'(value, decl, diagnostics) { if (!value) { return {}; } return pseudo_states_1.processPseudoStates(value, decl, diagnostics); }, '-st-extends'(value) { const ast = postcssValueParser(value); const types = []; ast.walk((node) => { if (node.type === 'function') { const args = getNamedArgs(node); types.push({ symbolName: node.value, args, }); return false; } else if (node.type === 'word') { types.push({ symbolName: node.value, args: null, }); } return undefined; }, false); return { ast, types, }; }, '-st-named'(value) { const namedMap = {}; if (value) { value.split(',').forEach((name) => { const parts = name.trim().split(/\s+as\s+/); if (parts.length === 1) { namedMap[parts[0]] = parts[0]; } else if (parts.length === 2) { namedMap[parts[1]] = parts[0]; } }); } return namedMap; }, '-st-mixin'(mixinNode, strategy, diagnostics) { const ast = postcssValueParser(mixinNode.value); const mixins = []; function reportWarning(message, options) { if (diagnostics) { diagnostics.warn(mixinNode, message, options); } } ast.nodes.forEach((node) => { const strat = strategy(node.value); if (node.type === 'function') { mixins.push({ type: node.value, options: exports.strategies[strat](node, reportWarning), }); } else if (node.type === 'word') { mixins.push({ type: node.value, options: strat === 'named' ? {} : [], }); } else if (node.type === 'string' && diagnostics) { diagnostics.error(mixinNode, exports.valueParserWarnings.VALUE_CANNOT_BE_STRING(), { word: mixinNode.value, }); } }); return mixins; }, }; function getNamedArgs(node) { const args = []; if (node.nodes.length) { args.push([]); node.nodes.forEach((node) => { if (node.type === 'div') { args.push([]); } else { const { sourceIndex, ...clone } = node; args[args.length - 1].push(clone); } }); } // handle trailing comma return args.length && args[args.length - 1].length === 0 ? args.slice(0, -1) : args; } exports.getNamedArgs = getNamedArgs; function getFormatterArgs(node, allowComments = false, _reportWarning, perserveQuotes = false) { const argsResult = []; let currentArg = ''; let argIndex = 0; for (const currentNode of node.nodes) { if (currentNode.type === 'div' && currentNode.value === ',') { checkEmptyArg(); argIndex++; argsResult.push(currentArg.trim()); currentArg = ''; } else if (currentNode.type === 'comment') { if (allowComments) { currentArg += currentNode.resolvedValue || postcssValueParser.stringify(currentNode); } } else if (currentNode.type === 'string') { currentArg += perserveQuotes ? postcssValueParser.stringify(currentNode) : currentNode.value; } else { currentArg += currentNode.resolvedValue || postcssValueParser.stringify(currentNode); } } checkEmptyArg(); argsResult.push(currentArg.trim()); let i = argsResult.length; while (i--) { if (argsResult[i] === '') { argsResult.pop(); } else { return argsResult; } } return argsResult; function checkEmptyArg() { if (currentArg.trim() === '' && _reportWarning) { _reportWarning(`${postcssValueParser.stringify(node)}: argument at index ${argIndex} is empty`); } } } exports.getFormatterArgs = getFormatterArgs; function getStringValue(nodes) { return postcssValueParser.stringify(nodes, (node) => { if (node.resolvedValue !== undefined) { return node.resolvedValue; } else { // TODO: warn return undefined; } }); } exports.getStringValue = getStringValue; function groupValues(nodes, divType = 'div') { const grouped = []; let current = []; nodes.forEach((n) => { if (n.type === divType) { grouped.push(current); current = []; } else { current.push(n); } }); const last = grouped[grouped.length - 1]; if ((last && last !== current && current.length) || (!last && current.length)) { grouped.push(current); } return grouped; } exports.groupValues = groupValues; exports.strategies = { named: (node, reportWarning) => { const named = {}; getNamedArgs(node).forEach((mixinArgsGroup) => { const argsDivider = mixinArgsGroup[1]; if (mixinArgsGroup.length < 3 || (argsDivider && argsDivider.type !== 'space')) { if (reportWarning) { const argValue = mixinArgsGroup[0]; reportWarning(exports.valueParserWarnings.CSS_MIXIN_FORCE_NAMED_PARAMS(), { word: argValue.value, }); } return; } named[mixinArgsGroup[0].value] = stringifyParam(mixinArgsGroup.slice(2)); }); return named; }, args: (node, reportWarning) => { return getFormatterArgs(node, true, reportWarning).map((value) => ({ value })); }, }; function stringifyParam(nodes) { return postcssValueParser.stringify(nodes, (n) => { if (n.type === 'function') { return postcssValueParser.stringify(n); } else if (n.type === 'div') { return null; } else if (n.type === 'string') { return n.value; } else { return undefined; } }); } function listOptions(node) { return groupValues(node.nodes) .map((nodes) => postcssValueParser.stringify(nodes, (n) => { if (n.type === 'div') { return null; } else if (n.type === 'string') { return n.value; } else { return undefined; } })) .filter((x) => typeof x === 'string'); } exports.listOptions = listOptions; function validateAllowedNodesUntil(node, i, untilType = 'div', allowed = ['comment']) { i = 1; let current = node.nodes[i]; while (current && current.type !== untilType) { if (!allowed.includes(current.type)) { return false; } i++; current = node.nodes[i]; } return true; } exports.validateAllowedNodesUntil = validateAllowedNodesUntil; //# sourceMappingURL=stylable-value-parsers.js.map