1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.evalDeclarationValue = exports.processDeclarationValue = exports.resolveArgumentsValue = exports.functionWarnings = void 0;
|
4 | const custom_values_1 = require("./custom-values");
|
5 | const native_reserved_lists_1 = require("./native-reserved-lists");
|
6 | const stylable_utils_1 = require("./stylable-utils");
|
7 | const stylable_value_parsers_1 = require("./stylable-value-parsers");
|
8 | const utils_1 = require("./utils");
|
9 | const postcssValueParser = require('postcss-value-parser');
|
10 | exports.functionWarnings = {
|
11 | FAIL_TO_EXECUTE_FORMATTER: (resolvedValue, message) => `failed to execute formatter "${resolvedValue}" with error: "${message}"`,
|
12 | CYCLIC_VALUE: (cyclicChain) => `Cyclic value definition detected: "${cyclicChain
|
13 | .map((s, i) => (i === cyclicChain.length - 1 ? '↻ ' : i === 0 ? '→ ' : '↪ ') + s)
|
14 | .join('\n')}"`,
|
15 | CANNOT_USE_AS_VALUE: (type, varName) => `${type} "${varName}" cannot be used as a variable`,
|
16 | CANNOT_USE_JS_AS_VALUE: (varName) => `JavaScript import "${varName}" cannot be used as a variable`,
|
17 | CANNOT_FIND_IMPORTED_VAR: (varName) => `cannot use unknown imported "${varName}"`,
|
18 | MULTI_ARGS_IN_VALUE: (args) => `value function accepts only a single argument: "value(${args})"`,
|
19 | COULD_NOT_RESOLVE_VALUE: (args) => `cannot resolve value function using the arguments provided: "${args}"`,
|
20 | UNKNOWN_FORMATTER: (name) => `cannot find native function or custom formatter called ${name}`,
|
21 | UNKNOWN_VAR: (name) => `unknown var "${name}"`,
|
22 | };
|
23 | function resolveArgumentsValue(options, transformer, meta, diagnostics, node, variableOverride, path, cssVarsMapping) {
|
24 | const resolvedArgs = {};
|
25 | for (const k in options) {
|
26 | resolvedArgs[k] = evalDeclarationValue(transformer.resolver, options[k], meta, node, variableOverride, transformer.replaceValueHook, diagnostics, path, cssVarsMapping);
|
27 | }
|
28 | return resolvedArgs;
|
29 | }
|
30 | exports.resolveArgumentsValue = resolveArgumentsValue;
|
31 | function processDeclarationValue(resolver, value, meta, node, variableOverride, valueHook, diagnostics, passedThrough = [], cssVarsMapping, args = []) {
|
32 | diagnostics = node ? diagnostics : undefined;
|
33 | const customValues = custom_values_1.resolveCustomValues(meta, resolver);
|
34 | const parsedValue = postcssValueParser(value);
|
35 | parsedValue.walk((parsedNode) => {
|
36 | const { type, value } = parsedNode;
|
37 | switch (type) {
|
38 | case 'function':
|
39 | if (value === 'value') {
|
40 | const parsedArgs = stylable_value_parsers_1.strategies.args(parsedNode).map((x) => x.value);
|
41 | if (parsedArgs.length >= 1) {
|
42 | const varName = parsedArgs[0];
|
43 | const getArgs = parsedArgs
|
44 | .slice(1)
|
45 | .map((arg) => evalDeclarationValue(resolver, arg, meta, node, variableOverride, valueHook, diagnostics, passedThrough.concat(createUniqID(meta.source, varName)), cssVarsMapping));
|
46 | if (variableOverride && variableOverride[varName]) {
|
47 | return (parsedNode.resolvedValue = variableOverride[varName]);
|
48 | }
|
49 | const refUniqID = createUniqID(meta.source, varName);
|
50 | if (passedThrough.includes(refUniqID)) {
|
51 |
|
52 | return handleCyclicValues(passedThrough, refUniqID, diagnostics, node, value, parsedNode);
|
53 | }
|
54 | const varSymbol = meta.mappedSymbols[varName];
|
55 | if (varSymbol && varSymbol._kind === 'var') {
|
56 | const resolved = processDeclarationValue(resolver, utils_1.stripQuotation(varSymbol.text), meta, varSymbol.node, variableOverride, valueHook, diagnostics, passedThrough.concat(createUniqID(meta.source, varName)), cssVarsMapping, getArgs);
|
57 | const { outputValue, topLevelType, typeError } = resolved;
|
58 | if (diagnostics && node) {
|
59 | const argsAsString = parsedArgs.join(', ');
|
60 | if (typeError) {
|
61 | diagnostics.warn(node, exports.functionWarnings.COULD_NOT_RESOLVE_VALUE(argsAsString));
|
62 | }
|
63 | else if (!topLevelType && parsedArgs.length > 1) {
|
64 | diagnostics.warn(node, exports.functionWarnings.MULTI_ARGS_IN_VALUE(argsAsString));
|
65 | }
|
66 | }
|
67 | parsedNode.resolvedValue = valueHook
|
68 | ? valueHook(outputValue, varName, true, passedThrough)
|
69 | : outputValue;
|
70 | }
|
71 | else if (varSymbol && varSymbol._kind === 'import') {
|
72 | const resolvedVar = resolver.deepResolve(varSymbol);
|
73 | if (resolvedVar && resolvedVar.symbol) {
|
74 | const resolvedVarSymbol = resolvedVar.symbol;
|
75 | if (resolvedVar._kind === 'css') {
|
76 | if (resolvedVarSymbol._kind === 'var') {
|
77 | const resolvedValue = evalDeclarationValue(resolver, utils_1.stripQuotation(resolvedVarSymbol.text), resolvedVar.meta, resolvedVarSymbol.node, variableOverride, valueHook, diagnostics, passedThrough.concat(createUniqID(meta.source, varName)), cssVarsMapping, getArgs);
|
78 | parsedNode.resolvedValue = valueHook
|
79 | ? valueHook(resolvedValue, varName, false, passedThrough)
|
80 | : resolvedValue;
|
81 | }
|
82 | else {
|
83 | const errorKind = resolvedVarSymbol._kind === 'class' &&
|
84 | resolvedVarSymbol[stylable_value_parsers_1.valueMapping.root]
|
85 | ? 'stylesheet'
|
86 | : resolvedVarSymbol._kind;
|
87 | if (diagnostics && node) {
|
88 | diagnostics.warn(node, exports.functionWarnings.CANNOT_USE_AS_VALUE(errorKind, varName), { word: varName });
|
89 | }
|
90 | }
|
91 | }
|
92 | else if (resolvedVar._kind === 'js' && diagnostics && node) {
|
93 |
|
94 | diagnostics.warn(node, exports.functionWarnings.CANNOT_USE_JS_AS_VALUE(varName), {
|
95 | word: varName,
|
96 | });
|
97 | }
|
98 | }
|
99 | else {
|
100 | const namedDecl = varSymbol.import.rule.nodes.find((node) => {
|
101 | return node.type === 'decl' && node.prop === stylable_value_parsers_1.valueMapping.named;
|
102 | });
|
103 | if (namedDecl && diagnostics && node) {
|
104 |
|
105 | diagnostics.error(node, exports.functionWarnings.CANNOT_FIND_IMPORTED_VAR(varName), { word: varName });
|
106 | }
|
107 | }
|
108 | }
|
109 | else if (diagnostics && node) {
|
110 | diagnostics.warn(node, exports.functionWarnings.UNKNOWN_VAR(varName), {
|
111 | word: varName,
|
112 | });
|
113 | }
|
114 | }
|
115 | }
|
116 | else if (value === '') {
|
117 | parsedNode.resolvedValue = stringifyFunction(value, parsedNode);
|
118 | }
|
119 | else {
|
120 | if (customValues[value]) {
|
121 |
|
122 | }
|
123 | else if (value === 'url') {
|
124 |
|
125 |
|
126 | }
|
127 | else if (value === 'format') {
|
128 |
|
129 | parsedNode.resolvedValue = stringifyFunction(value, parsedNode, true);
|
130 | }
|
131 | else {
|
132 | const formatterRef = meta.mappedSymbols[value];
|
133 | const formatter = resolver.deepResolve(formatterRef);
|
134 | const formatterArgs = stylable_value_parsers_1.getFormatterArgs(parsedNode);
|
135 | if (formatter && formatter._kind === 'js') {
|
136 | try {
|
137 | parsedNode.resolvedValue = formatter.symbol.apply(null, formatterArgs);
|
138 | if (valueHook && typeof parsedNode.resolvedValue === 'string') {
|
139 | parsedNode.resolvedValue = valueHook(parsedNode.resolvedValue, { name: parsedNode.value, args: formatterArgs }, true, passedThrough);
|
140 | }
|
141 | }
|
142 | catch (error) {
|
143 | parsedNode.resolvedValue = stringifyFunction(value, parsedNode);
|
144 | if (diagnostics && node) {
|
145 | diagnostics.warn(node, exports.functionWarnings.FAIL_TO_EXECUTE_FORMATTER(parsedNode.resolvedValue, error.message), { word: node.value });
|
146 | }
|
147 | }
|
148 | }
|
149 | else if (value === 'var') {
|
150 | const varWithPrefix = parsedNode.nodes[0].value;
|
151 | if (stylable_utils_1.isCSSVarProp(varWithPrefix)) {
|
152 | if (cssVarsMapping && cssVarsMapping[varWithPrefix]) {
|
153 | parsedNode.nodes[0].value = cssVarsMapping[varWithPrefix];
|
154 | }
|
155 | }
|
156 |
|
157 | if (parsedNode.nodes.length > 2) {
|
158 | parsedNode.resolvedValue = stringifyFunction(value, parsedNode);
|
159 | }
|
160 | }
|
161 | else if (native_reserved_lists_1.isCssNativeFunction(value)) {
|
162 | parsedNode.resolvedValue = stringifyFunction(value, parsedNode);
|
163 | }
|
164 | else if (diagnostics && node) {
|
165 | parsedNode.resolvedValue = stringifyFunction(value, parsedNode);
|
166 | diagnostics.warn(node, exports.functionWarnings.UNKNOWN_FORMATTER(value), {
|
167 | word: value,
|
168 | });
|
169 | }
|
170 | }
|
171 | }
|
172 | break;
|
173 | default: {
|
174 | return postcssValueParser.stringify(parsedNode);
|
175 | }
|
176 | }
|
177 | }, true);
|
178 | let outputValue = '';
|
179 | let topLevelType = null;
|
180 | let typeError = null;
|
181 | for (const n of parsedValue.nodes) {
|
182 | if (n.type === 'function') {
|
183 | const matchingType = customValues[n.value];
|
184 | if (matchingType) {
|
185 | topLevelType = matchingType.evalVarAst(n, customValues);
|
186 | try {
|
187 | outputValue += matchingType.getValue(args, topLevelType, n, customValues);
|
188 | }
|
189 | catch (e) {
|
190 | typeError = e;
|
191 |
|
192 | }
|
193 | }
|
194 | else {
|
195 | outputValue += stylable_value_parsers_1.getStringValue([n]);
|
196 | }
|
197 | }
|
198 | else {
|
199 | outputValue += stylable_value_parsers_1.getStringValue([n]);
|
200 | }
|
201 | }
|
202 | return { outputValue, topLevelType, typeError };
|
203 |
|
204 |
|
205 |
|
206 |
|
207 | }
|
208 | exports.processDeclarationValue = processDeclarationValue;
|
209 | function evalDeclarationValue(resolver, value, meta, node, variableOverride, valueHook, diagnostics, passedThrough = [], cssVarsMapping, args = []) {
|
210 | return processDeclarationValue(resolver, value, meta, node, variableOverride, valueHook, diagnostics, passedThrough, cssVarsMapping, args).outputValue;
|
211 | }
|
212 | exports.evalDeclarationValue = evalDeclarationValue;
|
213 | function handleCyclicValues(passedThrough, refUniqID, diagnostics, node, value, parsedNode) {
|
214 | const cyclicChain = passedThrough.map((variable) => variable || '');
|
215 | cyclicChain.push(refUniqID);
|
216 | if (diagnostics && node) {
|
217 | diagnostics.warn(node, exports.functionWarnings.CYCLIC_VALUE(cyclicChain), {
|
218 | word: refUniqID,
|
219 | });
|
220 | }
|
221 | return stringifyFunction(value, parsedNode);
|
222 | }
|
223 | function stringifyFunction(name, parsedNode, perserveQuotes = false) {
|
224 | return `${name}(${stylable_value_parsers_1.getFormatterArgs(parsedNode, false, undefined, perserveQuotes).join(', ')})`;
|
225 | }
|
226 | function createUniqID(source, varName) {
|
227 | return `${source}: ${varName}`;
|
228 | }
|
229 |
|
\ | No newline at end of file |