UNPKG

32.9 kBJavaScriptView Raw
1"use strict";
2var __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}));
9var __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});
14var __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};
21var __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};
24var __importDefault = (this && this.__importDefault) || function (mod) {
25 return (mod && mod.__esModule) ? mod : { "default": mod };
26};
27Object.defineProperty(exports, "__esModule", { value: true });
28exports.process = exports.processNamespace = exports.createEmptyMeta = exports.validateScopingSelector = exports.StylableProcessor = exports.processorWarnings = void 0;
29const murmurhash_1 = __importDefault(require("murmurhash"));
30const path_1 = __importDefault(require("path"));
31const postcss = __importStar(require("postcss"));
32const postcss_value_parser_1 = __importDefault(require("postcss-value-parser"));
33const diagnostics_1 = require("./diagnostics");
34const selector_utils_1 = require("./selector-utils");
35const stylable_assets_1 = require("./stylable-assets");
36const stylable_meta_1 = require("./stylable-meta");
37const stylable_utils_1 = require("./stylable-utils");
38const stylable_value_parsers_1 = require("./stylable-value-parsers");
39const utils_1 = require("./utils");
40__exportStar(require("./stylable-meta"), exports); /* TEMP EXPORT */
41const parseNamed = stylable_value_parsers_1.SBTypesParsers[stylable_value_parsers_1.valueMapping.named];
42const parseStates = stylable_value_parsers_1.SBTypesParsers[stylable_value_parsers_1.valueMapping.states];
43const parseGlobal = stylable_value_parsers_1.SBTypesParsers[stylable_value_parsers_1.valueMapping.global];
44const parseExtends = stylable_value_parsers_1.SBTypesParsers[stylable_value_parsers_1.valueMapping.extends];
45exports.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};
134class 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 // TODO: add warn there are two types one is not valid name and the other is empty name.
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 // special handling for registering "root" node comments
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 // TODO: diagnostics - scoped on none class
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 // 3rd party request
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) // browser has no posix methods
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}
706exports.StylableProcessor = StylableProcessor;
707function validateScopingSelector(atRule, { selector: scopingSelector }, diagnostics) {
708 if (!scopingSelector) {
709 diagnostics.warn(atRule, exports.processorWarnings.MISSING_SCOPING_PARAM());
710 }
711}
712exports.validateScopingSelector = validateScopingSelector;
713function 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}
717exports.createEmptyMeta = createEmptyMeta;
718function processNamespace(namespace, source) {
719 return namespace + murmurhash_1.default.v3(source); // .toString(36);
720}
721exports.processNamespace = processNamespace;
722function process(root, diagnostics = new diagnostics_1.Diagnostics(), resolveNamespace) {
723 return new StylableProcessor(diagnostics, resolveNamespace).process(root);
724}
725exports.process = process;
726//# sourceMappingURL=stylable-processor.js.map
\No newline at end of file