1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | 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;
|
4 | const pseudo_states_1 = require("./pseudo-states");
|
5 | const selector_utils_1 = require("./selector-utils");
|
6 | const postcssValueParser = require('postcss-value-parser');
|
7 | exports.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 | };
|
15 | exports.rootValueMapping = {
|
16 | vars: ':vars',
|
17 | import: ':import',
|
18 | stScope: 'st-scope',
|
19 | namespace: 'namespace',
|
20 | };
|
21 | exports.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 | };
|
31 | exports.stValues = Object.keys(exports.valueMapping).map((key) => exports.valueMapping[key]);
|
32 | exports.stValuesMap = Object.keys(exports.valueMapping).reduce((acc, key) => {
|
33 | acc[exports.valueMapping[key]] = true;
|
34 | return acc;
|
35 | }, {});
|
36 | exports.STYLABLE_VALUE_MATCHER = /^-st-/;
|
37 | exports.STYLABLE_NAMED_MATCHER = new RegExp(`^${exports.valueMapping.named}-(.+)`);
|
38 | exports.SBTypesParsers = {
|
39 | '-st-root'(value) {
|
40 | return value === 'false' ? false : true;
|
41 | },
|
42 | '-st-global'(decl, _diagnostics) {
|
43 |
|
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 | };
|
124 | function 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 |
|
139 | return args.length && args[args.length - 1].length === 0 ? args.slice(0, -1) : args;
|
140 | }
|
141 | exports.getNamedArgs = getNamedArgs;
|
142 | function 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 | }
|
186 | exports.getFormatterArgs = getFormatterArgs;
|
187 | function getStringValue(nodes) {
|
188 | return postcssValueParser.stringify(nodes, (node) => {
|
189 | if (node.resolvedValue !== undefined) {
|
190 | return node.resolvedValue;
|
191 | }
|
192 | else {
|
193 |
|
194 | return undefined;
|
195 | }
|
196 | });
|
197 | }
|
198 | exports.getStringValue = getStringValue;
|
199 | function 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 | }
|
217 | exports.groupValues = groupValues;
|
218 | exports.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 | };
|
240 | function 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 | }
|
256 | function 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 | }
|
271 | exports.listOptions = listOptions;
|
272 | function 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 | }
|
284 | exports.validateAllowedNodesUntil = validateAllowedNodesUntil;
|
285 |
|
\ | No newline at end of file |