UNPKG

9.45 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.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;
4const pseudo_states_1 = require("./pseudo-states");
5const selector_utils_1 = require("./selector-utils");
6const postcssValueParser = require('postcss-value-parser');
7exports.valueParserWarnings = {
8 VALUE_CANNOT_BE_STRING() {
9 return 'value can not be a string (remove quotes?)';
10 },
11 CSS_MIXIN_FORCE_NAMED_PARAMS() {
12 return 'CSS mixins must use named parameters (e.g. "func(name value, [name value, ...])")';
13 },
14};
15exports.rootValueMapping = {
16 vars: ':vars',
17 import: ':import',
18 stScope: 'st-scope',
19 namespace: 'namespace',
20};
21exports.valueMapping = {
22 from: '-st-from',
23 named: '-st-named',
24 default: '-st-default',
25 root: '-st-root',
26 states: '-st-states',
27 extends: '-st-extends',
28 mixin: '-st-mixin',
29 global: '-st-global',
30};
31exports.stValues = Object.keys(exports.valueMapping).map((key) => exports.valueMapping[key]);
32exports.stValuesMap = Object.keys(exports.valueMapping).reduce((acc, key) => {
33 acc[exports.valueMapping[key]] = true;
34 return acc;
35}, {});
36exports.STYLABLE_VALUE_MATCHER = /^-st-/;
37exports.STYLABLE_NAMED_MATCHER = new RegExp(`^${exports.valueMapping.named}-(.+)`);
38exports.SBTypesParsers = {
39 '-st-root'(value) {
40 return value === 'false' ? false : true;
41 },
42 '-st-global'(decl, _diagnostics) {
43 // Experimental
44 const selector = selector_utils_1.parseSelector(decl.value.replace(/^['"]/, '').replace(/['"]$/, ''));
45 return selector.nodes[0].nodes;
46 },
47 '-st-states'(value, decl, diagnostics) {
48 if (!value) {
49 return {};
50 }
51 return pseudo_states_1.processPseudoStates(value, decl, diagnostics);
52 },
53 '-st-extends'(value) {
54 const ast = postcssValueParser(value);
55 const types = [];
56 ast.walk((node) => {
57 if (node.type === 'function') {
58 const args = getNamedArgs(node);
59 types.push({
60 symbolName: node.value,
61 args,
62 });
63 return false;
64 }
65 else if (node.type === 'word') {
66 types.push({
67 symbolName: node.value,
68 args: null,
69 });
70 }
71 return undefined;
72 }, false);
73 return {
74 ast,
75 types,
76 };
77 },
78 '-st-named'(value) {
79 const namedMap = {};
80 if (value) {
81 value.split(',').forEach((name) => {
82 const parts = name.trim().split(/\s+as\s+/);
83 if (parts.length === 1) {
84 namedMap[parts[0]] = parts[0];
85 }
86 else if (parts.length === 2) {
87 namedMap[parts[1]] = parts[0];
88 }
89 });
90 }
91 return namedMap;
92 },
93 '-st-mixin'(mixinNode, strategy, diagnostics) {
94 const ast = postcssValueParser(mixinNode.value);
95 const mixins = [];
96 function reportWarning(message, options) {
97 if (diagnostics) {
98 diagnostics.warn(mixinNode, message, options);
99 }
100 }
101 ast.nodes.forEach((node) => {
102 const strat = strategy(node.value);
103 if (node.type === 'function') {
104 mixins.push({
105 type: node.value,
106 options: exports.strategies[strat](node, reportWarning),
107 });
108 }
109 else if (node.type === 'word') {
110 mixins.push({
111 type: node.value,
112 options: strat === 'named' ? {} : [],
113 });
114 }
115 else if (node.type === 'string' && diagnostics) {
116 diagnostics.error(mixinNode, exports.valueParserWarnings.VALUE_CANNOT_BE_STRING(), {
117 word: mixinNode.value,
118 });
119 }
120 });
121 return mixins;
122 },
123};
124function getNamedArgs(node) {
125 const args = [];
126 if (node.nodes.length) {
127 args.push([]);
128 node.nodes.forEach((node) => {
129 if (node.type === 'div') {
130 args.push([]);
131 }
132 else {
133 const { sourceIndex, ...clone } = node;
134 args[args.length - 1].push(clone);
135 }
136 });
137 }
138 // handle trailing comma
139 return args.length && args[args.length - 1].length === 0 ? args.slice(0, -1) : args;
140}
141exports.getNamedArgs = getNamedArgs;
142function getFormatterArgs(node, allowComments = false, _reportWarning, perserveQuotes = false) {
143 const argsResult = [];
144 let currentArg = '';
145 let argIndex = 0;
146 for (const currentNode of node.nodes) {
147 if (currentNode.type === 'div' && currentNode.value === ',') {
148 checkEmptyArg();
149 argIndex++;
150 argsResult.push(currentArg.trim());
151 currentArg = '';
152 }
153 else if (currentNode.type === 'comment') {
154 if (allowComments) {
155 currentArg +=
156 currentNode.resolvedValue || postcssValueParser.stringify(currentNode);
157 }
158 }
159 else if (currentNode.type === 'string') {
160 currentArg += perserveQuotes
161 ? postcssValueParser.stringify(currentNode)
162 : currentNode.value;
163 }
164 else {
165 currentArg += currentNode.resolvedValue || postcssValueParser.stringify(currentNode);
166 }
167 }
168 checkEmptyArg();
169 argsResult.push(currentArg.trim());
170 let i = argsResult.length;
171 while (i--) {
172 if (argsResult[i] === '') {
173 argsResult.pop();
174 }
175 else {
176 return argsResult;
177 }
178 }
179 return argsResult;
180 function checkEmptyArg() {
181 if (currentArg.trim() === '' && _reportWarning) {
182 _reportWarning(`${postcssValueParser.stringify(node)}: argument at index ${argIndex} is empty`);
183 }
184 }
185}
186exports.getFormatterArgs = getFormatterArgs;
187function getStringValue(nodes) {
188 return postcssValueParser.stringify(nodes, (node) => {
189 if (node.resolvedValue !== undefined) {
190 return node.resolvedValue;
191 }
192 else {
193 // TODO: warn
194 return undefined;
195 }
196 });
197}
198exports.getStringValue = getStringValue;
199function groupValues(nodes, divType = 'div') {
200 const grouped = [];
201 let current = [];
202 nodes.forEach((n) => {
203 if (n.type === divType) {
204 grouped.push(current);
205 current = [];
206 }
207 else {
208 current.push(n);
209 }
210 });
211 const last = grouped[grouped.length - 1];
212 if ((last && last !== current && current.length) || (!last && current.length)) {
213 grouped.push(current);
214 }
215 return grouped;
216}
217exports.groupValues = groupValues;
218exports.strategies = {
219 named: (node, reportWarning) => {
220 const named = {};
221 getNamedArgs(node).forEach((mixinArgsGroup) => {
222 const argsDivider = mixinArgsGroup[1];
223 if (mixinArgsGroup.length < 3 || (argsDivider && argsDivider.type !== 'space')) {
224 if (reportWarning) {
225 const argValue = mixinArgsGroup[0];
226 reportWarning(exports.valueParserWarnings.CSS_MIXIN_FORCE_NAMED_PARAMS(), {
227 word: argValue.value,
228 });
229 }
230 return;
231 }
232 named[mixinArgsGroup[0].value] = stringifyParam(mixinArgsGroup.slice(2));
233 });
234 return named;
235 },
236 args: (node, reportWarning) => {
237 return getFormatterArgs(node, true, reportWarning).map((value) => ({ value }));
238 },
239};
240function stringifyParam(nodes) {
241 return postcssValueParser.stringify(nodes, (n) => {
242 if (n.type === 'function') {
243 return postcssValueParser.stringify(n);
244 }
245 else if (n.type === 'div') {
246 return null;
247 }
248 else if (n.type === 'string') {
249 return n.value;
250 }
251 else {
252 return undefined;
253 }
254 });
255}
256function listOptions(node) {
257 return groupValues(node.nodes)
258 .map((nodes) => postcssValueParser.stringify(nodes, (n) => {
259 if (n.type === 'div') {
260 return null;
261 }
262 else if (n.type === 'string') {
263 return n.value;
264 }
265 else {
266 return undefined;
267 }
268 }))
269 .filter((x) => typeof x === 'string');
270}
271exports.listOptions = listOptions;
272function validateAllowedNodesUntil(node, i, untilType = 'div', allowed = ['comment']) {
273 i = 1;
274 let current = node.nodes[i];
275 while (current && current.type !== untilType) {
276 if (!allowed.includes(current.type)) {
277 return false;
278 }
279 i++;
280 current = node.nodes[i];
281 }
282 return true;
283}
284exports.validateAllowedNodesUntil = validateAllowedNodesUntil;
285//# sourceMappingURL=stylable-value-parsers.js.map
\No newline at end of file