1 | "use strict";
|
2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
3 | if (k2 === undefined) k2 = k;
|
4 | Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
5 | }) : (function(o, m, k, k2) {
|
6 | if (k2 === undefined) k2 = k;
|
7 | o[k2] = m[k];
|
8 | }));
|
9 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
10 | Object.defineProperty(o, "default", { enumerable: true, value: v });
|
11 | }) : function(o, v) {
|
12 | o["default"] = v;
|
13 | });
|
14 | var __importStar = (this && this.__importStar) || function (mod) {
|
15 | if (mod && mod.__esModule) return mod;
|
16 | var result = {};
|
17 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
18 | __setModuleDefault(result, mod);
|
19 | return result;
|
20 | };
|
21 | var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
22 | for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
23 | };
|
24 | var __importDefault = (this && this.__importDefault) || function (mod) {
|
25 | return (mod && mod.__esModule) ? mod : { "default": mod };
|
26 | };
|
27 | Object.defineProperty(exports, "__esModule", { value: true });
|
28 | exports.process = exports.processNamespace = exports.createEmptyMeta = exports.validateScopingSelector = exports.StylableProcessor = exports.processorWarnings = void 0;
|
29 | const murmurhash_1 = __importDefault(require("murmurhash"));
|
30 | const path_1 = __importDefault(require("path"));
|
31 | const postcss = __importStar(require("postcss"));
|
32 | const postcss_value_parser_1 = __importDefault(require("postcss-value-parser"));
|
33 | const diagnostics_1 = require("./diagnostics");
|
34 | const selector_utils_1 = require("./selector-utils");
|
35 | const stylable_assets_1 = require("./stylable-assets");
|
36 | const stylable_meta_1 = require("./stylable-meta");
|
37 | const stylable_utils_1 = require("./stylable-utils");
|
38 | const stylable_value_parsers_1 = require("./stylable-value-parsers");
|
39 | const utils_1 = require("./utils");
|
40 | __exportStar(require("./stylable-meta"), exports);
|
41 | const parseNamed = stylable_value_parsers_1.SBTypesParsers[stylable_value_parsers_1.valueMapping.named];
|
42 | const parseStates = stylable_value_parsers_1.SBTypesParsers[stylable_value_parsers_1.valueMapping.states];
|
43 | const parseGlobal = stylable_value_parsers_1.SBTypesParsers[stylable_value_parsers_1.valueMapping.global];
|
44 | const parseExtends = stylable_value_parsers_1.SBTypesParsers[stylable_value_parsers_1.valueMapping.extends];
|
45 | exports.processorWarnings = {
|
46 | UNSCOPED_CLASS(name) {
|
47 | return `unscoped class "${name}" will affect all elements of the same type in the document`;
|
48 | },
|
49 | UNSCOPED_ELEMENT(name) {
|
50 | return `unscoped element "${name}" will affect all elements of the same type in the document`;
|
51 | },
|
52 | FORBIDDEN_DEF_IN_COMPLEX_SELECTOR(name) {
|
53 | return `cannot define "${name}" inside a complex selector`;
|
54 | },
|
55 | ROOT_AFTER_SPACING() {
|
56 | return '".root" class cannot be used after native elements or selectors external to the stylesheet';
|
57 | },
|
58 | DEFAULT_IMPORT_IS_LOWER_CASE() {
|
59 | return 'Default import of a Stylable stylesheet must start with an upper-case letter';
|
60 | },
|
61 | ILLEGAL_PROP_IN_IMPORT(propName) {
|
62 | return `"${propName}" css attribute cannot be used inside ${stylable_value_parsers_1.rootValueMapping.import} block`;
|
63 | },
|
64 | STATE_DEFINITION_IN_ELEMENT() {
|
65 | return 'cannot define pseudo states inside element selectors';
|
66 | },
|
67 | STATE_DEFINITION_IN_COMPLEX() {
|
68 | return 'cannot define pseudo states inside complex selectors';
|
69 | },
|
70 | REDECLARE_SYMBOL(name) {
|
71 | return `redeclare symbol "${name}"`;
|
72 | },
|
73 | REDECLARE_SYMBOL_KEYFRAMES(name) {
|
74 | return `redeclare keyframes symbol "${name}"`;
|
75 | },
|
76 | CANNOT_RESOLVE_EXTEND(name) {
|
77 | return `cannot resolve '${stylable_value_parsers_1.valueMapping.extends}' type for '${name}'`;
|
78 | },
|
79 | CANNOT_EXTEND_IN_COMPLEX() {
|
80 | return `cannot define "${stylable_value_parsers_1.valueMapping.extends}" inside a complex selector`;
|
81 | },
|
82 | UNKNOWN_MIXIN(name) {
|
83 | return `unknown mixin: "${name}"`;
|
84 | },
|
85 | OVERRIDE_MIXIN(mixinType) {
|
86 | return `override ${mixinType} on same rule`;
|
87 | },
|
88 | OVERRIDE_TYPED_RULE(key, name) {
|
89 | return `override "${key}" on typed rule "${name}"`;
|
90 | },
|
91 | PARTIAL_MIXIN_MISSING_ARGUMENTS(type) {
|
92 | return `"${stylable_value_parsers_1.valueMapping.partialMixin}" can only be used with override arguments provided, missing overrides on "${type}"`;
|
93 | },
|
94 | FROM_PROP_MISSING_IN_IMPORT() {
|
95 | return `"${stylable_value_parsers_1.valueMapping.from}" is missing in ${stylable_value_parsers_1.rootValueMapping.import} block`;
|
96 | },
|
97 | INVALID_NAMESPACE_DEF() {
|
98 | return 'invalid @namespace';
|
99 | },
|
100 | EMPTY_NAMESPACE_DEF() {
|
101 | return '@namespace must contain at least one character or digit';
|
102 | },
|
103 | EMPTY_IMPORT_FROM() {
|
104 | return '"-st-from" cannot be empty';
|
105 | },
|
106 | MULTIPLE_FROM_IN_IMPORT() {
|
107 | return `cannot define multiple "${stylable_value_parsers_1.valueMapping.from}" declarations in a single import`;
|
108 | },
|
109 | NO_VARS_DEF_IN_ST_SCOPE() {
|
110 | return `cannot define "${stylable_value_parsers_1.rootValueMapping.vars}" inside of "@st-scope"`;
|
111 | },
|
112 | NO_IMPORT_IN_ST_SCOPE() {
|
113 | return `cannot use "${stylable_value_parsers_1.rootValueMapping.import}" inside of "@st-scope"`;
|
114 | },
|
115 | NO_KEYFRAMES_IN_ST_SCOPE() {
|
116 | return `cannot use "@keyframes" inside of "@st-scope"`;
|
117 | },
|
118 | MISSING_SCOPING_PARAM() {
|
119 | return '"@st-scope" missing scoping selector parameter';
|
120 | },
|
121 | ILLEGAL_GLOBAL_CSS_VAR(name) {
|
122 | return `"@st-global-custom-property" received the value "${name}", but it must begin with "--" (double-dash)`;
|
123 | },
|
124 | GLOBAL_CSS_VAR_MISSING_COMMA(name) {
|
125 | return `"@st-global-custom-property" received the value "${name}", but its values must be comma separated`;
|
126 | },
|
127 | ILLEGAL_CSS_VAR_USE(name) {
|
128 | return `a custom css property must begin with "--" (double-dash), but received "${name}"`;
|
129 | },
|
130 | ILLEGAL_CSS_VAR_ARGS(name) {
|
131 | return `css variable "${name}" usage (var()) must receive comma separated values`;
|
132 | },
|
133 | };
|
134 | class StylableProcessor {
|
135 | constructor(diagnostics = new diagnostics_1.Diagnostics(), resolveNamespace = processNamespace) {
|
136 | this.diagnostics = diagnostics;
|
137 | this.resolveNamespace = resolveNamespace;
|
138 | }
|
139 | process(root) {
|
140 | this.meta = new stylable_meta_1.StylableMeta(root, this.diagnostics);
|
141 | this.handleAtRules(root);
|
142 | const stubs = this.insertCustomSelectorsStubs();
|
143 | root.walkRules((rule) => {
|
144 | if (!selector_utils_1.isChildOfAtRule(rule, 'keyframes')) {
|
145 | this.handleCustomSelectors(rule);
|
146 | this.handleRule(rule, selector_utils_1.isChildOfAtRule(rule, stylable_value_parsers_1.rootValueMapping.stScope));
|
147 | }
|
148 | });
|
149 | root.walkDecls((decl) => {
|
150 | if (stylable_value_parsers_1.stValuesMap[decl.prop]) {
|
151 | this.handleDirectives(decl.parent, decl);
|
152 | }
|
153 | else if (stylable_utils_1.isCSSVarProp(decl.prop)) {
|
154 | this.addCSSVarFromProp(decl);
|
155 | }
|
156 | if (decl.value.includes('var(')) {
|
157 | this.handleCSSVarUse(decl);
|
158 | }
|
159 | stylable_assets_1.processDeclarationUrls(decl, (node) => {
|
160 | this.meta.urls.push(node.url);
|
161 | }, false);
|
162 | });
|
163 | this.meta.scopes.forEach((atRule) => {
|
164 | const scopingRule = postcss.rule({ selector: atRule.params });
|
165 | this.handleRule(scopingRule, true);
|
166 | validateScopingSelector(atRule, scopingRule, this.diagnostics);
|
167 | if (scopingRule.selector) {
|
168 | atRule.walkRules((rule) => {
|
169 | const scopedRule = rule.clone({
|
170 | selector: stylable_utils_1.scopeSelector(scopingRule.selector, rule.selector, false)
|
171 | .selector,
|
172 | });
|
173 | scopedRule.stScopeSelector = atRule.params;
|
174 | rule.replaceWith(scopedRule);
|
175 | });
|
176 | }
|
177 | atRule.replaceWith(atRule.nodes || []);
|
178 | });
|
179 | stubs.forEach((s) => s && s.remove());
|
180 | return this.meta;
|
181 | }
|
182 | insertCustomSelectorsStubs() {
|
183 | return Object.keys(this.meta.customSelectors).map((selector) => {
|
184 | if (this.meta.customSelectors[selector]) {
|
185 | const rule = postcss.rule({ selector });
|
186 | this.meta.ast.append(rule);
|
187 | return rule;
|
188 | }
|
189 | return null;
|
190 | });
|
191 | }
|
192 | handleCustomSelectors(rule) {
|
193 | stylable_utils_1.expandCustomSelectors(rule, this.meta.customSelectors, this.meta.diagnostics);
|
194 | }
|
195 | handleAtRules(root) {
|
196 | let namespace = '';
|
197 | const toRemove = [];
|
198 | root.walkAtRules((atRule) => {
|
199 | switch (atRule.name) {
|
200 | case 'namespace': {
|
201 | const match = atRule.params.match(/["'](.*?)['"]/);
|
202 | if (match) {
|
203 | if (match[1].trim()) {
|
204 | namespace = match[1];
|
205 | }
|
206 | else {
|
207 | this.diagnostics.error(atRule, exports.processorWarnings.EMPTY_NAMESPACE_DEF());
|
208 | }
|
209 | toRemove.push(atRule);
|
210 | }
|
211 | else {
|
212 | this.diagnostics.error(atRule, exports.processorWarnings.INVALID_NAMESPACE_DEF());
|
213 | }
|
214 | break;
|
215 | }
|
216 | case 'keyframes':
|
217 | if (!selector_utils_1.isChildOfAtRule(atRule, stylable_value_parsers_1.rootValueMapping.stScope)) {
|
218 | this.meta.keyframes.push(atRule);
|
219 | const { params: name } = atRule;
|
220 | this.checkRedeclareKeyframes(name, atRule);
|
221 | this.meta.mappedKeyframes[name] = {
|
222 | _kind: 'keyframes',
|
223 | alias: name,
|
224 | name: name,
|
225 | };
|
226 | }
|
227 | else {
|
228 | this.diagnostics.warn(atRule, exports.processorWarnings.NO_KEYFRAMES_IN_ST_SCOPE());
|
229 | }
|
230 | break;
|
231 | case 'custom-selector': {
|
232 | const params = atRule.params.split(/\s/);
|
233 | const customName = params.shift();
|
234 | toRemove.push(atRule);
|
235 | if (customName && customName.match(stylable_utils_1.CUSTOM_SELECTOR_RE)) {
|
236 | this.meta.customSelectors[customName] = atRule.params
|
237 | .replace(customName, '')
|
238 | .trim();
|
239 | }
|
240 | else {
|
241 |
|
242 | }
|
243 | break;
|
244 | }
|
245 | case 'st-scope':
|
246 | this.meta.scopes.push(atRule);
|
247 | break;
|
248 | case 'st-global-custom-property': {
|
249 | const cssVars = atRule.params.split(',');
|
250 | if (atRule.params.trim().split(/\s+/g).length > cssVars.length) {
|
251 | this.diagnostics.warn(atRule, exports.processorWarnings.GLOBAL_CSS_VAR_MISSING_COMMA(atRule.params), { word: atRule.params });
|
252 | break;
|
253 | }
|
254 | for (const entry of cssVars) {
|
255 | const cssVar = entry.trim();
|
256 | if (stylable_utils_1.isCSSVarProp(cssVar)) {
|
257 | if (!this.meta.cssVars[cssVar]) {
|
258 | this.meta.cssVars[cssVar] = {
|
259 | _kind: 'cssVar',
|
260 | name: cssVar,
|
261 | global: true,
|
262 | };
|
263 | this.meta.mappedSymbols[cssVar] = this.meta.cssVars[cssVar];
|
264 | }
|
265 | }
|
266 | else {
|
267 | this.diagnostics.warn(atRule, exports.processorWarnings.ILLEGAL_GLOBAL_CSS_VAR(cssVar), { word: cssVar });
|
268 | }
|
269 | }
|
270 | toRemove.push(atRule);
|
271 | break;
|
272 | }
|
273 | }
|
274 | });
|
275 | toRemove.forEach((node) => node.remove());
|
276 | namespace = namespace || utils_1.filename2varname(path_1.default.basename(this.meta.source)) || 's';
|
277 | this.meta.namespace = this.handleNamespaceReference(namespace);
|
278 | }
|
279 | handleNamespaceReference(namespace) {
|
280 | let pathToSource;
|
281 | this.meta.ast.walkComments((comment) => {
|
282 | if (comment.text.includes('st-namespace-reference')) {
|
283 | const namespaceReferenceParts = comment.text.split('=');
|
284 | pathToSource = utils_1.stripQuotation(namespaceReferenceParts[namespaceReferenceParts.length - 1]);
|
285 | return false;
|
286 | }
|
287 | return undefined;
|
288 | });
|
289 | return this.resolveNamespace(namespace, pathToSource
|
290 | ? path_1.default.resolve(path_1.default.dirname(this.meta.source), pathToSource)
|
291 | : this.meta.source);
|
292 | }
|
293 | handleRule(rule, inStScope = false) {
|
294 | rule.selectorAst = selector_utils_1.parseSelector(rule.selector);
|
295 | const checker = selector_utils_1.createSimpleSelectorChecker();
|
296 | const validRoot = selector_utils_1.isRootValid(rule.selectorAst, 'root');
|
297 | let locallyScoped = false;
|
298 | selector_utils_1.traverseNode(rule.selectorAst, (node, _index, _nodes) => {
|
299 | if (!checker(node)) {
|
300 | rule.isSimpleSelector = false;
|
301 | }
|
302 | const { name, type } = node;
|
303 | if (type === 'pseudo-class') {
|
304 | if (name === 'import') {
|
305 | if (rule.selector === stylable_value_parsers_1.rootValueMapping.import) {
|
306 | if (selector_utils_1.isChildOfAtRule(rule, stylable_value_parsers_1.rootValueMapping.stScope)) {
|
307 | this.diagnostics.warn(rule, exports.processorWarnings.NO_IMPORT_IN_ST_SCOPE());
|
308 | rule.remove();
|
309 | return false;
|
310 | }
|
311 | const _import = this.handleImport(rule);
|
312 | this.meta.imports.push(_import);
|
313 | this.addImportSymbols(_import);
|
314 | return false;
|
315 | }
|
316 | else {
|
317 | this.diagnostics.warn(rule, exports.processorWarnings.FORBIDDEN_DEF_IN_COMPLEX_SELECTOR(stylable_value_parsers_1.rootValueMapping.import));
|
318 | }
|
319 | }
|
320 | else if (name === 'vars') {
|
321 | if (rule.selector === stylable_value_parsers_1.rootValueMapping.vars) {
|
322 | if (selector_utils_1.isChildOfAtRule(rule, stylable_value_parsers_1.rootValueMapping.stScope)) {
|
323 | this.diagnostics.warn(rule, exports.processorWarnings.NO_VARS_DEF_IN_ST_SCOPE());
|
324 | rule.remove();
|
325 | return false;
|
326 | }
|
327 | this.addVarSymbols(rule);
|
328 | return false;
|
329 | }
|
330 | else {
|
331 | this.diagnostics.warn(rule, exports.processorWarnings.FORBIDDEN_DEF_IN_COMPLEX_SELECTOR(stylable_value_parsers_1.rootValueMapping.vars));
|
332 | }
|
333 | }
|
334 | }
|
335 | else if (type === 'class') {
|
336 | this.addClassSymbolOnce(name, rule);
|
337 | if (this.meta.classes[name]) {
|
338 | if (!this.meta.classes[name].alias) {
|
339 | locallyScoped = true;
|
340 | }
|
341 | else if (locallyScoped === false && !inStScope) {
|
342 | this.diagnostics.warn(rule, exports.processorWarnings.UNSCOPED_CLASS(name), {
|
343 | word: name,
|
344 | });
|
345 | }
|
346 | }
|
347 | }
|
348 | else if (type === 'element') {
|
349 | this.addElementSymbolOnce(name, rule);
|
350 | if (locallyScoped === false && !inStScope) {
|
351 | this.diagnostics.warn(rule, exports.processorWarnings.UNSCOPED_ELEMENT(name), {
|
352 | word: name,
|
353 | });
|
354 | }
|
355 | }
|
356 | else if (type === 'nested-pseudo-class' && name === 'global') {
|
357 | return true;
|
358 | }
|
359 | return void 0;
|
360 | });
|
361 | if (rule.isSimpleSelector !== false) {
|
362 | rule.isSimpleSelector = true;
|
363 | rule.selectorType = rule.selector.match(/^\./) ? 'class' : 'element';
|
364 | }
|
365 | else {
|
366 | rule.selectorType = 'complex';
|
367 | }
|
368 | if (!validRoot) {
|
369 | this.diagnostics.warn(rule, exports.processorWarnings.ROOT_AFTER_SPACING());
|
370 | }
|
371 | }
|
372 | checkRedeclareSymbol(symbolName, node) {
|
373 | const symbol = this.meta.mappedSymbols[symbolName];
|
374 | if (symbol) {
|
375 | this.diagnostics.warn(node, exports.processorWarnings.REDECLARE_SYMBOL(symbolName), {
|
376 | word: symbolName,
|
377 | });
|
378 | }
|
379 | }
|
380 | checkRedeclareKeyframes(symbolName, node) {
|
381 | const symbol = this.meta.mappedKeyframes[symbolName];
|
382 | if (symbol) {
|
383 | this.diagnostics.warn(node, exports.processorWarnings.REDECLARE_SYMBOL_KEYFRAMES(symbolName), {
|
384 | word: symbolName,
|
385 | });
|
386 | }
|
387 | return symbol;
|
388 | }
|
389 | addElementSymbolOnce(name, rule) {
|
390 | if (selector_utils_1.isCompRoot(name) && !this.meta.elements[name]) {
|
391 | let alias = this.meta.mappedSymbols[name];
|
392 | if (alias && alias._kind !== 'import') {
|
393 | this.checkRedeclareSymbol(name, rule);
|
394 | alias = undefined;
|
395 | }
|
396 | this.meta.elements[name] = this.meta.mappedSymbols[name] = {
|
397 | _kind: 'element',
|
398 | name,
|
399 | alias,
|
400 | };
|
401 | this.meta.simpleSelectors[name] = {
|
402 | node: rule,
|
403 | symbol: this.meta.elements[name],
|
404 | };
|
405 | }
|
406 | }
|
407 | addClassSymbolOnce(name, rule) {
|
408 | if (!this.meta.classes[name]) {
|
409 | let alias = this.meta.mappedSymbols[name];
|
410 | if (alias && alias._kind !== 'import') {
|
411 | this.checkRedeclareSymbol(name, rule);
|
412 | alias = undefined;
|
413 | }
|
414 | this.meta.classes[name] = this.meta.mappedSymbols[name] = {
|
415 | _kind: 'class',
|
416 | name,
|
417 | alias,
|
418 | };
|
419 | this.meta.simpleSelectors[name] = {
|
420 | node: rule,
|
421 | symbol: this.meta.mappedSymbols[name],
|
422 | };
|
423 | }
|
424 | else if (name === this.meta.root && !this.meta.simpleSelectors[name]) {
|
425 |
|
426 | this.meta.simpleSelectors[name] = {
|
427 | node: rule,
|
428 | symbol: this.meta.classes[name],
|
429 | };
|
430 | }
|
431 | }
|
432 | addImportSymbols(importDef) {
|
433 | if (importDef.defaultExport) {
|
434 | this.checkRedeclareSymbol(importDef.defaultExport, importDef.rule);
|
435 | this.meta.mappedSymbols[importDef.defaultExport] = {
|
436 | _kind: 'import',
|
437 | type: 'default',
|
438 | name: 'default',
|
439 | import: importDef,
|
440 | context: path_1.default.dirname(this.meta.source),
|
441 | };
|
442 | }
|
443 | Object.keys(importDef.named).forEach((name) => {
|
444 | this.checkRedeclareSymbol(name, importDef.rule);
|
445 | this.meta.mappedSymbols[name] = {
|
446 | _kind: 'import',
|
447 | type: 'named',
|
448 | name: importDef.named[name],
|
449 | import: importDef,
|
450 | context: path_1.default.dirname(this.meta.source),
|
451 | };
|
452 | });
|
453 | Object.keys(importDef.keyframes).forEach((name) => {
|
454 | if (!this.checkRedeclareKeyframes(name, importDef.rule)) {
|
455 | this.meta.mappedKeyframes[name] = {
|
456 | _kind: 'keyframes',
|
457 | alias: name,
|
458 | name: importDef.keyframes[name],
|
459 | import: importDef,
|
460 | };
|
461 | }
|
462 | });
|
463 | }
|
464 | addVarSymbols(rule) {
|
465 | rule.walkDecls((decl) => {
|
466 | this.checkRedeclareSymbol(decl.prop, decl);
|
467 | let type = null;
|
468 | const prev = decl.prev();
|
469 | if (prev && prev.type === 'comment') {
|
470 | const typeMatch = prev.text.match(/^@type (.+)$/);
|
471 | if (typeMatch) {
|
472 | type = typeMatch[1];
|
473 | }
|
474 | }
|
475 | const varSymbol = {
|
476 | _kind: 'var',
|
477 | name: decl.prop,
|
478 | value: '',
|
479 | text: decl.value,
|
480 | node: decl,
|
481 | valueType: type,
|
482 | };
|
483 | this.meta.vars.push(varSymbol);
|
484 | this.meta.mappedSymbols[decl.prop] = varSymbol;
|
485 | });
|
486 | rule.remove();
|
487 | }
|
488 | handleCSSVarUse(decl) {
|
489 | const parsed = postcss_value_parser_1.default(decl.value);
|
490 | parsed.walk((node) => {
|
491 | if (node.type === 'function' && node.value === 'var' && node.nodes) {
|
492 | const varName = node.nodes[0];
|
493 | if (!stylable_value_parsers_1.validateAllowedNodesUntil(node, 1)) {
|
494 | const args = postcss_value_parser_1.default.stringify(node.nodes);
|
495 | this.diagnostics.warn(decl, exports.processorWarnings.ILLEGAL_CSS_VAR_ARGS(args), {
|
496 | word: args,
|
497 | });
|
498 | }
|
499 | this.addCSSVar(postcss_value_parser_1.default.stringify(varName).trim(), decl);
|
500 | }
|
501 | });
|
502 | }
|
503 | addCSSVarFromProp(decl) {
|
504 | const varName = decl.prop.trim();
|
505 | this.addCSSVar(varName, decl);
|
506 | }
|
507 | addCSSVar(varName, decl) {
|
508 | if (stylable_utils_1.isCSSVarProp(varName)) {
|
509 | if (!this.meta.cssVars[varName]) {
|
510 | const cssVarSymbol = {
|
511 | _kind: 'cssVar',
|
512 | name: varName,
|
513 | };
|
514 | this.meta.cssVars[varName] = cssVarSymbol;
|
515 | if (!this.meta.mappedSymbols[varName]) {
|
516 | this.meta.mappedSymbols[varName] = cssVarSymbol;
|
517 | }
|
518 | }
|
519 | }
|
520 | else {
|
521 | this.diagnostics.warn(decl, exports.processorWarnings.ILLEGAL_CSS_VAR_USE(varName), {
|
522 | word: varName,
|
523 | });
|
524 | }
|
525 | }
|
526 | handleDirectives(rule, decl) {
|
527 | if (decl.prop === stylable_value_parsers_1.valueMapping.states) {
|
528 | if (rule.isSimpleSelector && rule.selectorType !== 'element') {
|
529 | this.extendTypedRule(decl, rule.selector, stylable_value_parsers_1.valueMapping.states, parseStates(decl.value, decl, this.diagnostics));
|
530 | }
|
531 | else {
|
532 | if (rule.selectorType === 'element') {
|
533 | this.diagnostics.warn(decl, exports.processorWarnings.STATE_DEFINITION_IN_ELEMENT());
|
534 | }
|
535 | else {
|
536 | this.diagnostics.warn(decl, exports.processorWarnings.STATE_DEFINITION_IN_COMPLEX());
|
537 | }
|
538 | }
|
539 | }
|
540 | else if (decl.prop === stylable_value_parsers_1.valueMapping.extends) {
|
541 | if (rule.isSimpleSelector) {
|
542 | const parsed = parseExtends(decl.value);
|
543 | const symbolName = parsed.types[0] && parsed.types[0].symbolName;
|
544 | const extendsRefSymbol = this.meta.mappedSymbols[symbolName];
|
545 | if ((extendsRefSymbol &&
|
546 | (extendsRefSymbol._kind === 'import' ||
|
547 | extendsRefSymbol._kind === 'class' ||
|
548 | extendsRefSymbol._kind === 'element')) ||
|
549 | decl.value === this.meta.root) {
|
550 | this.extendTypedRule(decl, rule.selector, stylable_value_parsers_1.valueMapping.extends, stylable_utils_1.getAlias(extendsRefSymbol) || extendsRefSymbol);
|
551 | }
|
552 | else {
|
553 | this.diagnostics.warn(decl, exports.processorWarnings.CANNOT_RESOLVE_EXTEND(decl.value), { word: decl.value });
|
554 | }
|
555 | }
|
556 | else {
|
557 | this.diagnostics.warn(decl, exports.processorWarnings.CANNOT_EXTEND_IN_COMPLEX());
|
558 | }
|
559 | }
|
560 | else if (decl.prop === stylable_value_parsers_1.valueMapping.mixin || decl.prop === stylable_value_parsers_1.valueMapping.partialMixin) {
|
561 | const mixins = [];
|
562 | stylable_value_parsers_1.SBTypesParsers[decl.prop](decl, (type) => {
|
563 | const mixinRefSymbol = this.meta.mappedSymbols[type];
|
564 | if (mixinRefSymbol &&
|
565 | mixinRefSymbol._kind === 'import' &&
|
566 | !mixinRefSymbol.import.from.match(/.css$/)) {
|
567 | return 'args';
|
568 | }
|
569 | return 'named';
|
570 | }, this.diagnostics).forEach((mixin) => {
|
571 | const mixinRefSymbol = this.meta.mappedSymbols[mixin.type];
|
572 | if (mixinRefSymbol &&
|
573 | (mixinRefSymbol._kind === 'import' || mixinRefSymbol._kind === 'class')) {
|
574 | if (mixin.partial && Object.keys(mixin.options).length === 0) {
|
575 | this.diagnostics.warn(decl, exports.processorWarnings.PARTIAL_MIXIN_MISSING_ARGUMENTS(mixin.type), {
|
576 | word: mixin.type,
|
577 | });
|
578 | }
|
579 | const refedMixin = {
|
580 | mixin,
|
581 | ref: mixinRefSymbol,
|
582 | };
|
583 | mixins.push(refedMixin);
|
584 | this.meta.mixins.push(refedMixin);
|
585 | }
|
586 | else {
|
587 | this.diagnostics.warn(decl, exports.processorWarnings.UNKNOWN_MIXIN(mixin.type), {
|
588 | word: mixin.type,
|
589 | });
|
590 | }
|
591 | });
|
592 | if (rule.mixins) {
|
593 | const partials = rule.mixins.filter((r) => r.mixin.partial);
|
594 | const nonPartials = rule.mixins.filter((r) => !r.mixin.partial);
|
595 | const isInPartial = decl.prop === stylable_value_parsers_1.valueMapping.partialMixin;
|
596 | if ((partials.length && decl.prop === stylable_value_parsers_1.valueMapping.partialMixin) ||
|
597 | (nonPartials.length && decl.prop === stylable_value_parsers_1.valueMapping.mixin)) {
|
598 | this.diagnostics.warn(decl, exports.processorWarnings.OVERRIDE_MIXIN(decl.prop));
|
599 | }
|
600 | if (partials.length && nonPartials.length) {
|
601 | rule.mixins = isInPartial
|
602 | ? nonPartials.concat(mixins)
|
603 | : partials.concat(mixins);
|
604 | }
|
605 | else if (partials.length) {
|
606 | rule.mixins = isInPartial ? mixins : partials.concat(mixins);
|
607 | }
|
608 | else if (nonPartials.length) {
|
609 | rule.mixins = isInPartial ? nonPartials.concat(mixins) : mixins;
|
610 | }
|
611 | }
|
612 | else if (mixins.length) {
|
613 | rule.mixins = mixins;
|
614 | }
|
615 | }
|
616 | else if (decl.prop === stylable_value_parsers_1.valueMapping.global) {
|
617 | if (rule.isSimpleSelector && rule.selectorType !== 'element') {
|
618 | this.setClassGlobalMapping(decl, rule);
|
619 | }
|
620 | else {
|
621 |
|
622 | }
|
623 | }
|
624 | }
|
625 | setClassGlobalMapping(decl, rule) {
|
626 | const name = rule.selector.replace('.', '');
|
627 | const typedRule = this.meta.classes[name];
|
628 | if (typedRule) {
|
629 | typedRule[stylable_value_parsers_1.valueMapping.global] = parseGlobal(decl, this.diagnostics);
|
630 | }
|
631 | }
|
632 | extendTypedRule(node, selector, key, value) {
|
633 | const name = selector.replace('.', '');
|
634 | const typedRule = this.meta.mappedSymbols[name];
|
635 | if (typedRule && typedRule[key]) {
|
636 | this.diagnostics.warn(node, exports.processorWarnings.OVERRIDE_TYPED_RULE(key, name), {
|
637 | word: name,
|
638 | });
|
639 | }
|
640 | if (typedRule) {
|
641 | typedRule[key] = value;
|
642 | }
|
643 | }
|
644 | handleImport(rule) {
|
645 | let fromExists = false;
|
646 | const importObj = {
|
647 | defaultExport: '',
|
648 | from: '',
|
649 | fromRelative: '',
|
650 | named: {},
|
651 | keyframes: {},
|
652 | rule,
|
653 | context: path_1.default.dirname(this.meta.source),
|
654 | };
|
655 | rule.walkDecls((decl) => {
|
656 | switch (decl.prop) {
|
657 | case stylable_value_parsers_1.valueMapping.from: {
|
658 | const importPath = utils_1.stripQuotation(decl.value);
|
659 | if (!importPath.trim()) {
|
660 | this.diagnostics.error(decl, exports.processorWarnings.EMPTY_IMPORT_FROM());
|
661 | }
|
662 | if (fromExists) {
|
663 | this.diagnostics.warn(rule, exports.processorWarnings.MULTIPLE_FROM_IN_IMPORT());
|
664 | }
|
665 | if (!path_1.default.isAbsolute(importPath) && !importPath.startsWith('.')) {
|
666 |
|
667 | importObj.fromRelative = importPath;
|
668 | importObj.from = importPath;
|
669 | }
|
670 | else {
|
671 | importObj.fromRelative = importPath;
|
672 | const dirPath = path_1.default.dirname(this.meta.source);
|
673 | importObj.from =
|
674 | path_1.default.posix && path_1.default.posix.isAbsolute(dirPath)
|
675 | ? path_1.default.posix.resolve(dirPath, importPath)
|
676 | : path_1.default.resolve(dirPath, importPath);
|
677 | }
|
678 | fromExists = true;
|
679 | break;
|
680 | }
|
681 | case stylable_value_parsers_1.valueMapping.default:
|
682 | importObj.defaultExport = decl.value;
|
683 | if (!selector_utils_1.isCompRoot(importObj.defaultExport) && importObj.from.match(/\.css$/)) {
|
684 | this.diagnostics.warn(decl, exports.processorWarnings.DEFAULT_IMPORT_IS_LOWER_CASE(), { word: importObj.defaultExport });
|
685 | }
|
686 | break;
|
687 | case stylable_value_parsers_1.valueMapping.named:
|
688 | {
|
689 | const { keyframesMap, namedMap } = parseNamed(decl.value, decl, this.diagnostics);
|
690 | importObj.named = namedMap;
|
691 | importObj.keyframes = keyframesMap;
|
692 | }
|
693 | break;
|
694 | default:
|
695 | this.diagnostics.warn(decl, exports.processorWarnings.ILLEGAL_PROP_IN_IMPORT(decl.prop), { word: decl.prop });
|
696 | break;
|
697 | }
|
698 | });
|
699 | if (!importObj.from) {
|
700 | this.diagnostics.error(rule, exports.processorWarnings.FROM_PROP_MISSING_IN_IMPORT());
|
701 | }
|
702 | rule.remove();
|
703 | return importObj;
|
704 | }
|
705 | }
|
706 | exports.StylableProcessor = StylableProcessor;
|
707 | function validateScopingSelector(atRule, { selector: scopingSelector }, diagnostics) {
|
708 | if (!scopingSelector) {
|
709 | diagnostics.warn(atRule, exports.processorWarnings.MISSING_SCOPING_PARAM());
|
710 | }
|
711 | }
|
712 | exports.validateScopingSelector = validateScopingSelector;
|
713 | function createEmptyMeta(root, diagnostics) {
|
714 | utils_1.deprecated('createEmptyMeta is deprecated and will be removed in the next version. Use "new StylableMeta()"');
|
715 | return new stylable_meta_1.StylableMeta(root, diagnostics);
|
716 | }
|
717 | exports.createEmptyMeta = createEmptyMeta;
|
718 | function processNamespace(namespace, source) {
|
719 | return namespace + murmurhash_1.default.v3(source);
|
720 | }
|
721 | exports.processNamespace = processNamespace;
|
722 | function process(root, diagnostics = new diagnostics_1.Diagnostics(), resolveNamespace) {
|
723 | return new StylableProcessor(diagnostics, resolveNamespace).process(root);
|
724 | }
|
725 | exports.process = process;
|
726 |
|
\ | No newline at end of file |