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