@master/css 2.0.0-rc.47 → 2.0.0-rc.48

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/dist/common.cjs +1 -1
  2. package/dist/common.mjs +1 -1
  3. package/dist/config/functions.d.ts +1 -1
  4. package/dist/config/index.cjs +3 -3
  5. package/dist/config/index.d.ts +3 -48
  6. package/dist/config/index.mjs +3 -3
  7. package/dist/config/modes.d.ts +1 -1
  8. package/dist/config/{syntaxes.cjs → rules.cjs} +282 -282
  9. package/dist/config/rules.d.ts +282 -0
  10. package/dist/config/{syntaxes.mjs → rules.mjs} +282 -282
  11. package/dist/core.cjs +225 -607
  12. package/dist/core.d.ts +36 -67
  13. package/dist/core.mjs +225 -607
  14. package/dist/index.cjs +14 -6
  15. package/dist/index.d.ts +8 -4
  16. package/dist/index.mjs +7 -3
  17. package/dist/layer.cjs +107 -23
  18. package/dist/layer.d.ts +13 -27
  19. package/dist/layer.mjs +107 -23
  20. package/dist/non-layer.cjs +65 -0
  21. package/dist/non-layer.d.ts +12 -0
  22. package/dist/non-layer.mjs +63 -0
  23. package/dist/rule.cjs +8 -708
  24. package/dist/rule.d.ts +6 -147
  25. package/dist/rule.mjs +8 -708
  26. package/dist/shared/utils/find-native-css-rule-index.cjs +12 -0
  27. package/dist/shared/utils/find-native-css-rule-index.mjs +10 -0
  28. package/dist/syntax-layer.cjs +291 -0
  29. package/dist/syntax-layer.d.ts +17 -0
  30. package/dist/syntax-layer.mjs +289 -0
  31. package/dist/syntax-rule-type.cjs +27 -0
  32. package/dist/syntax-rule-type.d.ts +28 -0
  33. package/dist/syntax-rule-type.mjs +25 -0
  34. package/dist/syntax-rule.cjs +717 -0
  35. package/dist/syntax-rule.d.ts +47 -0
  36. package/dist/syntax-rule.mjs +715 -0
  37. package/dist/types/config.cjs +2 -0
  38. package/dist/types/config.d.ts +70 -0
  39. package/dist/types/config.mjs +1 -0
  40. package/dist/types/syntax.cjs +2 -0
  41. package/dist/types/syntax.d.ts +106 -0
  42. package/dist/types/syntax.mjs +1 -0
  43. package/dist/utils/are-rule-at-equal.cjs +7 -7
  44. package/dist/utils/are-rule-at-equal.d.ts +2 -2
  45. package/dist/utils/are-rule-at-equal.mjs +7 -7
  46. package/dist/utils/are-rule-modes-equal.cjs +2 -2
  47. package/dist/utils/are-rule-modes-equal.d.ts +2 -2
  48. package/dist/utils/are-rule-modes-equal.mjs +2 -2
  49. package/dist/utils/are-rule-selectors-equal.cjs +11 -11
  50. package/dist/utils/are-rule-selectors-equal.d.ts +2 -2
  51. package/dist/utils/are-rule-selectors-equal.mjs +11 -11
  52. package/dist/utils/are-rule-states-equal.cjs +2 -2
  53. package/dist/utils/are-rule-states-equal.d.ts +2 -2
  54. package/dist/utils/are-rule-states-equal.mjs +2 -2
  55. package/dist/utils/are-rules-duplicated.cjs +17 -0
  56. package/dist/utils/are-rules-duplicated.d.ts +2 -0
  57. package/dist/utils/are-rules-duplicated.mjs +15 -0
  58. package/dist/utils/autofill-solid-style.d.ts +2 -2
  59. package/dist/utils/extend-config.cjs +5 -5
  60. package/dist/utils/extend-config.d.ts +1 -1
  61. package/dist/utils/extend-config.mjs +5 -5
  62. package/dist/utils/generate-css.cjs +1 -1
  63. package/dist/utils/generate-css.mjs +1 -1
  64. package/dist/utils/is-core-rule.cjs +2 -2
  65. package/dist/utils/is-core-rule.mjs +2 -2
  66. package/dist/utils/reorder-for-readable-classes.cjs +11 -11
  67. package/dist/utils/reorder-for-readable-classes.mjs +11 -11
  68. package/package.json +1 -1
  69. package/dist/config/syntaxes.d.ts +0 -282
  70. package/dist/utils/are-syntaxes-duplicated.cjs +0 -17
  71. package/dist/utils/are-syntaxes-duplicated.d.ts +0 -2
  72. package/dist/utils/are-syntaxes-duplicated.mjs +0 -15
package/dist/core.mjs CHANGED
@@ -1,50 +1,80 @@
1
- import { Rule } from './rule.mjs';
1
+ import { SyntaxRule } from './syntax-rule.mjs';
2
2
  import { config } from './config/index.mjs';
3
- import Layer from './layer.mjs';
4
3
  import hexToRgb from './utils/hex-to-rgb.mjs';
5
4
  import { flattenObject } from './utils/flatten-object.mjs';
6
5
  import extendConfig from './utils/extend-config.mjs';
6
+ import SyntaxLayer from './syntax-layer.mjs';
7
+ import { Rule } from './rule.mjs';
8
+ import SyntaxRuleType from './syntax-rule-type.mjs';
9
+ import Layer from './layer.mjs';
10
+ import NonLayer from './non-layer.mjs';
7
11
 
8
12
  class MasterCSS {
9
13
  customConfig;
10
14
  static config = config;
11
- syntaxes;
12
- ruleBy;
13
- classesUsage;
15
+ definedRules;
14
16
  config;
15
- Rules;
17
+ classesUsage;
18
+ layerStatementRule;
19
+ rules;
20
+ animationsNonLayer;
21
+ baseLayer;
22
+ themeLayer;
23
+ presetLayer;
24
+ stylesLayer;
25
+ generalLayer;
26
+ get text() {
27
+ return this.rules.sort((a, b)=>{
28
+ const order = [
29
+ 'layer-statement',
30
+ 'base',
31
+ 'theme',
32
+ 'preset',
33
+ 'components',
34
+ 'general'
35
+ ];
36
+ const indexA = order.indexOf(a.name) === -1 ? Infinity : order.indexOf(a.name);
37
+ const indexB = order.indexOf(b.name) === -1 ? Infinity : order.indexOf(b.name);
38
+ return indexA - indexB;
39
+ }).map(({ text })=>text).join('');
40
+ }
16
41
  constructor(customConfig){
17
42
  this.customConfig = customConfig;
18
- this.syntaxes = [];
19
- this.ruleBy = {};
43
+ this.definedRules = [];
20
44
  this.classesUsage = {};
21
- this.Rules = [];
22
- if (!customConfig?.override) {
23
- this.config = extendConfig(config, customConfig);
24
- } else {
25
- this.config = extendConfig(customConfig);
26
- }
45
+ this.layerStatementRule = new Rule('layer-statement', [
46
+ {
47
+ text: '@layer base,theme,preset,components,general;'
48
+ }
49
+ ]);
50
+ this.rules = [
51
+ this.layerStatementRule
52
+ ];
53
+ this.animationsNonLayer = new NonLayer(this);
54
+ this.baseLayer = new SyntaxLayer('base', this);
55
+ this.themeLayer = new Layer('theme', this);
56
+ this.presetLayer = new SyntaxLayer('preset', this);
57
+ this.stylesLayer = new SyntaxLayer('components', this);
58
+ this.generalLayer = new SyntaxLayer('general', this);
59
+ this.config = customConfig?.override ? extendConfig(customConfig) : extendConfig(config, customConfig);
27
60
  this.resolve();
28
61
  if (this.constructor === MasterCSS) {
29
62
  masterCSSs.push(this);
30
63
  }
31
64
  }
32
65
  resolve() {
33
- this.styles = {};
34
- this.stylesBy = {};
66
+ this.components = {};
35
67
  this.selectors = {};
36
68
  this.variables = {};
37
69
  this.at = {};
38
70
  this.animations = {};
39
- this.Rules.length = 0;
40
- this.variablesNativeRules = {};
41
- this.hasKeyframesRule = false;
71
+ this.definedRules.length = 0;
42
72
  const colorVariableNames = {
43
73
  current: undefined,
44
74
  currentColor: undefined,
45
75
  transparent: undefined
46
76
  };
47
- const { styles, selectors, variables, utilities, at, syntaxes, animations } = this.config;
77
+ const { components, selectors, variables, utilities, at, rules, animations } = this.config;
48
78
  function escapeString(str) {
49
79
  return str.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&');
50
80
  }
@@ -276,33 +306,23 @@ class MasterCSS {
276
306
  }
277
307
  }
278
308
  }
279
- const flattedStyles = styles ? flattenObject(styles) : {};
309
+ const flattedStyles = components ? flattenObject(components) : {};
280
310
  const utilityNames = Object.keys(flattedStyles);
281
311
  const handleUtilityName = (utilityName)=>{
282
- if (Object.prototype.hasOwnProperty.call(this.styles, utilityName)) return;
283
- const currentClass = this.styles[utilityName] = [];
312
+ if (Object.prototype.hasOwnProperty.call(this.components, utilityName)) return;
313
+ const currentClass = this.components[utilityName] = [];
284
314
  const className = flattedStyles[utilityName];
285
315
  if (!className) return;
286
316
  const classNames = className.replace(/(?:\n(?:\s*))+/g, ' ').trim().split(' ');
287
317
  for (const eachClassName of classNames){
288
318
  const handle = (className)=>{
289
- if (Object.prototype.hasOwnProperty.call(this.stylesBy, className)) {
290
- const currentRelation = this.stylesBy[className];
291
- if (!currentRelation.includes(utilityName)) {
292
- currentRelation.push(utilityName);
293
- }
294
- } else {
295
- this.stylesBy[className] = [
296
- utilityName
297
- ];
298
- }
299
319
  if (!currentClass.includes(className)) {
300
320
  currentClass.push(className);
301
321
  }
302
322
  };
303
323
  if (utilityNames.includes(eachClassName)) {
304
324
  handleUtilityName(eachClassName);
305
- for (const parentClassName of this.styles[eachClassName]){
325
+ for (const parentClassName of this.components[eachClassName]){
306
326
  handle(parentClassName);
307
327
  }
308
328
  } else {
@@ -313,7 +333,7 @@ class MasterCSS {
313
333
  for (const eachUtilityName of utilityNames){
314
334
  handleUtilityName(eachUtilityName);
315
335
  }
316
- if (syntaxes || utilities) {
336
+ if (rules || utilities) {
317
337
  const rulesEntries = [];
318
338
  if (utilities) {
319
339
  for(const utilityName in utilities){
@@ -322,61 +342,69 @@ class MasterCSS {
322
342
  utilityName,
323
343
  {
324
344
  declarations,
325
- layer: Layer.Utility
345
+ type: SyntaxRuleType.Utility
326
346
  }
327
347
  ]);
328
348
  }
329
349
  }
330
- if (syntaxes) {
331
- rulesEntries.push(...Object.entries(syntaxes));
350
+ if (rules) {
351
+ rulesEntries.push(...Object.entries(rules));
332
352
  }
333
353
  const rulesEntriesLength = rulesEntries.length;
334
354
  const colorNames = Object.keys(colorVariableNames);
335
355
  rulesEntries.sort((a, b)=>{
336
- if (a[1].layer !== b[1].layer) {
337
- return (b[1].layer || 0) - (a[1].layer || 0);
356
+ if (a[1].type !== b[1].type) {
357
+ return (b[1].type || 0) - (a[1].type || 0);
338
358
  }
339
359
  return b[0].localeCompare(a[0]);
340
- }).forEach(([id, eachSyntaxDefinition], index)=>{
341
- const EachRule = {
360
+ }).forEach(([id, eachSyntaxRuleDefinition], index)=>{
361
+ const syntax = {
342
362
  id,
343
363
  keys: [],
344
364
  variables: {},
345
365
  matchers: {},
346
366
  order: rulesEntriesLength - 1 - index,
347
- definition: eachSyntaxDefinition
367
+ definition: eachSyntaxRuleDefinition
348
368
  };
349
- this.Rules.push(EachRule);
350
- const { matcher, layer, subkey, ambiguousKeys, ambiguousValues, sign } = eachSyntaxDefinition;
351
- if (layer === Layer.Utility) {
352
- EachRule.id = '.' + id;
353
- EachRule.matchers.arbitrary = new RegExp('^' + escapeString(id) + '(?=!|\\*|>|\\+|~|:|\\[|@|_|\\.|$)', 'm');
369
+ if (!eachSyntaxRuleDefinition.unit) {
370
+ eachSyntaxRuleDefinition.unit = '';
371
+ }
372
+ if (!eachSyntaxRuleDefinition.separators) {
373
+ eachSyntaxRuleDefinition.separators = [
374
+ ','
375
+ ];
376
+ }
377
+ this.definedRules.push(syntax);
378
+ const { matcher, type, subkey, ambiguousKeys, ambiguousValues, sign } = eachSyntaxRuleDefinition;
379
+ if (type === SyntaxRuleType.Utility) {
380
+ syntax.id = '.' + id;
381
+ syntax.matchers.arbitrary = new RegExp('^' + escapeString(id) + '(?=!|\\*|>|\\+|~|:|\\[|@|_|\\.|$)', 'm');
354
382
  }
355
383
  // todo: 不可使用 startsWith 判斷,應改為更精準的從 config.variables 取得目標變數群組,但 config.variables 中的值還沒被 resolve 像是 Array
356
384
  const addResolvedVariables = (groupName)=>{
357
385
  for(const eachVariableName in this.variables){
358
386
  const eachVariable = this.variables[eachVariableName];
359
387
  if (eachVariable.group === groupName) {
360
- EachRule.variables[eachVariable.key] = eachVariable;
388
+ syntax.variables[eachVariable.key] = eachVariable;
361
389
  }
362
390
  }
363
391
  };
364
- // 1. custom `config.syntaxes[id].variables`
365
- if (eachSyntaxDefinition.variables) {
366
- for (const eachVariableGroup of eachSyntaxDefinition.variables){
392
+ // 1. custom `config.rules[id].variables`
393
+ if (eachSyntaxRuleDefinition.variables) {
394
+ for (const eachVariableGroup of eachSyntaxRuleDefinition.variables){
367
395
  addResolvedVariables(eachVariableGroup);
368
396
  }
369
397
  }
370
398
  // 2. custom `config.variables`
371
399
  addResolvedVariables(id);
372
400
  const keys = [];
373
- let { key } = eachSyntaxDefinition;
374
- if (layer === Layer.NativeShorthand || layer === Layer.Native) {
375
- if (!key) eachSyntaxDefinition.key = key = id;
401
+ let { key } = eachSyntaxRuleDefinition;
402
+ if (type === SyntaxRuleType.NativeShorthand || type === SyntaxRuleType.Native) {
403
+ if (!key) eachSyntaxRuleDefinition.key = key = id;
376
404
  keys.push(id);
377
405
  }
378
406
  if (sign) {
379
- EachRule.matchers.arbitrary = new RegExp(`^${sign}[^!*>+~:[@_]+\\|`);
407
+ syntax.matchers.arbitrary = new RegExp(`^${sign}[^!*>+~:[@_]+\\|`);
380
408
  } else if (!matcher) {
381
409
  const colorsPatten = colorNames.join('|');
382
410
  if (!key && !subkey) {
@@ -384,13 +412,13 @@ class MasterCSS {
384
412
  } else {
385
413
  if (key && !keys.includes(key)) keys.push(key);
386
414
  if (subkey) keys.push(subkey);
387
- if (layer === Layer.Shorthand) {
415
+ if (type === SyntaxRuleType.Shorthand) {
388
416
  keys.push(id);
389
417
  }
390
418
  }
391
419
  if (ambiguousKeys?.length) {
392
420
  const ambiguousKeyPattern = ambiguousKeys.length > 1 ? `(?:${ambiguousKeys.join('|')})` : ambiguousKeys[0];
393
- const variableKeys = Object.keys(EachRule.variables);
421
+ const variableKeys = Object.keys(syntax.variables);
394
422
  if (ambiguousValues?.length) {
395
423
  const ambiguousValuePatterns = [];
396
424
  for (const eachAmbiguousValue of ambiguousValues){
@@ -400,21 +428,37 @@ class MasterCSS {
400
428
  ambiguousValuePatterns.unshift(`${eachAmbiguousValue}(?:\\b|_)`);
401
429
  }
402
430
  }
403
- EachRule.matchers.value = new RegExp(`^${ambiguousKeyPattern}:(?:${ambiguousValuePatterns.join('|')})[^|]*?(?:@|$)`);
431
+ syntax.matchers.value = new RegExp(`^${ambiguousKeyPattern}:(?:${ambiguousValuePatterns.join('|')})[^|]*?(?:@|$)`);
404
432
  }
405
433
  if (variableKeys.length) {
406
- EachRule.matchers.variable = new RegExp(`^${ambiguousKeyPattern}:(?:${variableKeys.join('|')}(?![a-zA-Z0-9-]))[^|]*?(?:@|$)`);
434
+ syntax.matchers.variable = new RegExp(`^${ambiguousKeyPattern}:(?:${variableKeys.join('|')}(?![a-zA-Z0-9-]))[^|]*?(?:@|$)`);
407
435
  }
408
436
  }
409
437
  } else {
410
- EachRule.matchers.arbitrary = matcher;
438
+ syntax.matchers.arbitrary = matcher;
411
439
  }
412
440
  if (keys.length) {
413
- EachRule.keys = keys;
414
- EachRule.matchers.key = new RegExp(`^${keys.length > 1 ? `(${keys.join('|')})` : keys[0]}:.`);
441
+ syntax.keys = keys;
442
+ syntax.matchers.key = new RegExp(`^${keys.length > 1 ? `(${keys.join('|')})` : keys[0]}:.`);
415
443
  }
416
444
  });
417
445
  }
446
+ for(const utilityName in this.components){
447
+ const syntaxRulesByStateToken = this.components[utilityName].map((eachSyntax)=>this.create(eachSyntax)).filter((eachSyntax)=>eachSyntax?.text).reduce((obj, eachSyntaxRule)=>{
448
+ if (eachSyntaxRule.stateToken in obj) {
449
+ obj[eachSyntaxRule.stateToken].push(eachSyntaxRule);
450
+ } else {
451
+ obj[eachSyntaxRule.stateToken] = [
452
+ eachSyntaxRule
453
+ ];
454
+ }
455
+ return obj;
456
+ }, {});
457
+ this.components[utilityName] = Object.keys(syntaxRulesByStateToken).map((stateToken)=>{
458
+ const syntaxRules = syntaxRulesByStateToken[stateToken];
459
+ return syntaxRules.length === 1 ? syntaxRules[0].name : '{' + syntaxRulesByStateToken[stateToken].map((eachSyntaxRule)=>eachSyntaxRule.name.slice(0, eachSyntaxRule.name.length - eachSyntaxRule.stateToken.length)).join(';') + '}' + stateToken;
460
+ });
461
+ }
418
462
  }
419
463
  /**
420
464
  * Match check if Master CSS syntax
@@ -424,613 +468,187 @@ class MasterCSS {
424
468
  /**
425
469
  * 1. variable
426
470
  * @example fg:primary bg:blue
427
- */ for (const EachRule of this.Rules){
428
- if (EachRule.matchers.variable?.test(className)) return EachRule;
471
+ */ for (const eachSyntax of this.definedRules){
472
+ if (eachSyntax.matchers.variable?.test(className)) return eachSyntax;
429
473
  }
430
474
  /**
431
475
  * 2. value (ambiguous.key * ambiguous.values)
432
476
  * @example bg:current box:content font:12
433
- */ for (const EachRule of this.Rules){
434
- if (EachRule.matchers.value?.test(className)) return EachRule;
477
+ */ for (const eachSyntax of this.definedRules){
478
+ if (eachSyntax.matchers.value?.test(className)) return eachSyntax;
435
479
  }
436
480
  /**
437
481
  * 3. full key
438
482
  * @example text-align:center color:blue-40
439
- */ for (const EachRule of this.Rules){
440
- if (EachRule.matchers.key?.test(className)) return EachRule;
483
+ */ for (const eachSyntax of this.definedRules){
484
+ if (eachSyntax.matchers.key?.test(className)) return eachSyntax;
441
485
  }
442
486
  /**
443
487
  * 4. arbitrary
444
488
  * @example custom RegExp, utility
445
- */ for (const EachRule of this.Rules){
446
- if (EachRule.matchers.arbitrary?.test(className)) return EachRule;
489
+ */ for (const eachSyntax of this.definedRules){
490
+ if (eachSyntax.matchers.arbitrary?.test(className)) return eachSyntax;
447
491
  }
448
492
  }
449
493
  /**
450
- * Generate syntaxes from class name
494
+ * Generate syntax rules from class name
451
495
  * @param className
452
- * @returns Rule[]
453
- */ generate(className) {
454
- return (Object.prototype.hasOwnProperty.call(this.styles, className) ? this.styles[className].map((eachSyntax)=>this.create(eachSyntax)) : [
455
- this.create(className)
456
- ]).filter((eachSyntax)=>eachSyntax && eachSyntax?.text);
496
+ * @returns SyntaxRule[]
497
+ */ generate(className, mode) {
498
+ let syntaxRules = [];
499
+ if (Object.prototype.hasOwnProperty.call(this.components, className)) {
500
+ syntaxRules = this.components[className].map((eachSyntax)=>this.create(eachSyntax, className, mode));
501
+ } else {
502
+ const atIndex = className.indexOf('@');
503
+ if (atIndex !== -1) {
504
+ const name = className.slice(0, atIndex);
505
+ if (Object.prototype.hasOwnProperty.call(this.components, name)) {
506
+ const atToken = className.slice(atIndex);
507
+ syntaxRules = this.components[name].map((eachSyntax)=>this.create(eachSyntax + atToken, className, mode));
508
+ } else {
509
+ syntaxRules = [
510
+ this.create(className, undefined, mode)
511
+ ];
512
+ }
513
+ } else {
514
+ syntaxRules = [
515
+ this.create(className, undefined, mode)
516
+ ];
517
+ }
518
+ }
519
+ return syntaxRules.filter((eachSyntax)=>eachSyntax?.text);
457
520
  }
458
521
  /**
459
- * Create rule from given syntax
460
- * @param syntax
461
- * @returns Rule
462
- */ create(syntax) {
463
- if (Object.prototype.hasOwnProperty.call(this.ruleBy, syntax)) return this.ruleBy[syntax];
464
- const RegisteredRule = this.match(syntax);
465
- if (RegisteredRule) {
466
- return new Rule(syntax, RegisteredRule, this);
522
+ * Create syntax rule from given class name
523
+ * @param className
524
+ * @returns SyntaxRule
525
+ */ create(className, fixedClass, mode) {
526
+ const syntaxRule = this.generalLayer.rules.find(({ key })=>key === (fixedClass ? fixedClass + ' ' : '') + className);
527
+ if (syntaxRule) return syntaxRule;
528
+ const registeredRule = this.match(className);
529
+ if (registeredRule) return new SyntaxRule(className, this, registeredRule, fixedClass, mode);
530
+ }
531
+ /**
532
+ * Create syntax rule from given selector text
533
+ * @param selectorText
534
+ */ createFromSelectorText(selectorText) {
535
+ const selectorTextSplits = selectorText.split(' ');
536
+ for(let i = 0; i < selectorTextSplits.length; i++){
537
+ const eachField = selectorTextSplits[i];
538
+ const modeSelector = this.getModeSelector(eachField);
539
+ if (i === 0 && eachField === modeSelector) continue;
540
+ if (eachField[0] === '.') {
541
+ const eachFieldName = eachField.slice(1);
542
+ let className = '';
543
+ for(let l = 0; l < eachFieldName.length; l++){
544
+ const char = eachFieldName[l];
545
+ const nextChar = eachFieldName[l + 1];
546
+ if (char === '\\') {
547
+ l++;
548
+ if (nextChar !== '\\') {
549
+ className += nextChar;
550
+ continue;
551
+ }
552
+ } else if ([
553
+ '.',
554
+ '#',
555
+ '[',
556
+ '!',
557
+ '*',
558
+ '>',
559
+ '+',
560
+ '~',
561
+ ':'
562
+ ].includes(char)) {
563
+ break;
564
+ }
565
+ className += char;
566
+ }
567
+ const syntaxRules = this.generate(className);
568
+ if (syntaxRules.length) return syntaxRules;
569
+ }
467
570
  }
571
+ return [];
468
572
  }
469
573
  /**
470
574
  * 根據蒐集到的所有 DOM class 重新 create
471
575
  */ refresh(customConfig) {
576
+ this.reset();
472
577
  if (customConfig) {
473
578
  this.customConfig = customConfig;
474
579
  } else {
475
580
  customConfig = this.customConfig;
476
581
  }
477
- if (!customConfig?.override) {
478
- // @ts-ignore
479
- this.config = extendConfig(config, customConfig);
480
- } else {
481
- // @ts-ignore
482
- this.config = extendConfig(customConfig);
483
- }
484
- this.resolve();
485
- this.syntaxes.length = 0;
486
582
  // @ts-ignore
487
- this.ruleBy = {};
583
+ this.config = customConfig?.override ? extendConfig(customConfig) : extendConfig(config, customConfig);
584
+ this.resolve();
488
585
  /**
489
- * 拿當前所有的 classNames 按照最新的 colors, config.syntaxes 匹配並生成新的 style
490
- * 所以 refresh 過後 syntaxes 可能會變多也可能會變少
586
+ * 拿當前所有的 classNames 按照最新的 colors, config.rules 匹配並生成新的 style
587
+ * 所以 refresh 過後 rules 可能會變多也可能會變少
491
588
  */ for(const name in this.classesUsage){
492
589
  this.add(name);
493
590
  }
494
591
  return this;
495
592
  }
496
593
  reset() {
497
- // @ts-ignore
498
- this.ruleBy = {};
499
- // @ts-ignore
500
- this.classesUsage = {};
501
- this.syntaxes.length = 0;
502
- this.hasKeyframesRule = false;
503
- this.variablesNativeRules = {};
504
- for(const keyframeName in this.animations){
505
- const animation = this.animations[keyframeName];
506
- animation.usage = 0;
507
- animation.native = undefined;
508
- }
509
- for(const variableName in this.variables){
510
- const variable = this.variables[variableName];
511
- variable.usage = 0;
512
- }
594
+ this.baseLayer.reset();
595
+ this.themeLayer.reset();
596
+ this.presetLayer.reset();
597
+ this.stylesLayer.reset();
598
+ this.generalLayer.reset();
599
+ this.animationsNonLayer.reset();
513
600
  return this;
514
601
  }
515
602
  destroy() {
516
- this.reset();
603
+ // @ts-ignore
604
+ this.classesUsage = {};
517
605
  masterCSSs.splice(masterCSSs.indexOf(this), 1);
518
606
  return this;
519
607
  }
520
608
  add(...classNames) {
521
609
  for (const className of classNames){
522
- const syntaxes = this.generate(className);
523
- if (syntaxes.length) {
524
- for (const rule of syntaxes){
525
- this.insert(rule);
526
- }
527
- }
610
+ this.generate(className).forEach((eachSyntaxRule)=>eachSyntaxRule.layer.insert(eachSyntaxRule));
528
611
  }
529
612
  return this;
530
613
  }
531
- delete(...classNames) {
614
+ remove(...classNames) {
532
615
  /**
533
616
  * class name 從 DOM tree 中被移除,
534
617
  * 匹配並刪除對應的 rule
535
- */ const sheet = this.style?.sheet;
536
- const deleteRule = (name)=>{
537
- const rule = this.ruleBy[name];
538
- if (!rule || Object.prototype.hasOwnProperty.call(this.stylesBy, name) && this.stylesBy[name].some((eachClassName)=>Object.prototype.hasOwnProperty.call(this.classesUsage, eachClassName))) return;
539
- if (sheet && rule.natives.length) {
540
- const firstNative = rule.natives[0];
541
- for(let index = 0; index < sheet.cssRules.length; index++){
542
- const eachCSSRule = sheet.cssRules[index];
543
- if (eachCSSRule === firstNative.cssRule) {
544
- for (const {} of rule.natives){
545
- sheet.deleteRule(index);
546
- }
547
- break;
548
- }
549
- }
550
- }
551
- this.syntaxes.splice(this.syntaxes.indexOf(rule), 1);
552
- delete this.ruleBy[name];
553
- // variables
554
- if (rule.variableNames) {
555
- for (const eachVariableName of rule.variableNames){
556
- const variable = this.variables[eachVariableName];
557
- if (!variable.usage) variable.usage = 0;
558
- if (!--variable.usage) {
559
- const removeProperty = (mode)=>{
560
- const nativeRule = this.variablesNativeRules[mode];
561
- nativeRule.cssRule.style.removeProperty('--' + eachVariableName);
562
- if (!nativeRule.cssRule.style.length) {
563
- const variablesRule = this.syntaxes[0];
564
- const index = variablesRule.natives.indexOf(nativeRule);
565
- sheet?.deleteRule(index);
566
- variablesRule.natives.splice(index, 1);
567
- delete this.variablesNativeRules[mode];
568
- if (!variablesRule.natives.length) {
569
- this.syntaxes.splice(0, 1);
570
- this.variablesNativeRules = {};
571
- }
572
- }
573
- };
574
- if (variable.value) {
575
- removeProperty('');
576
- }
577
- if (variable.modes) {
578
- for(const mode in variable.modes){
579
- removeProperty(mode);
580
- }
581
- }
582
- }
583
- }
584
- }
585
- // animations
586
- if (rule.animationNames) {
587
- const keyframeRulesIndex = Object.keys(this.variablesNativeRules).length ? 1 : 0;
588
- const keyframeRule = this.syntaxes[keyframeRulesIndex];
589
- for (const eachKeyframeName of rule.animationNames){
590
- const keyframe = this.animations[eachKeyframeName];
591
- if (!keyframe.usage) keyframe.usage = 0;
592
- if (!--keyframe.usage && keyframe.native) {
593
- const nativeIndex = keyframeRule.natives.indexOf(keyframe.native);
594
- sheet?.deleteRule(Object.keys(this.variablesNativeRules).length + nativeIndex);
595
- keyframeRule.natives.splice(nativeIndex, 1);
596
- keyframe.native = undefined;
597
- }
598
- }
599
- if (!keyframeRule.natives.length) {
600
- this.syntaxes.splice(keyframeRulesIndex, 1);
601
- this.hasKeyframesRule = false;
618
+ */ for (const className of classNames){
619
+ if (Object.prototype.hasOwnProperty.call(this.components, className)) {
620
+ for (const eachSyntax of this.components[className]){
621
+ this.stylesLayer.delete(className + ' ' + eachSyntax);
602
622
  }
603
- }
604
- rule.definition.delete?.call(rule, name);
605
- };
606
- for (const className of classNames){
607
- if (Object.prototype.hasOwnProperty.call(this.styles, className)) {
608
- for (const eachClassName of this.styles[className]){
609
- if (!Object.prototype.hasOwnProperty.call(this.classesUsage, eachClassName)) {
610
- deleteRule(eachClassName);
611
- }
612
- }
613
- delete this.ruleBy[className];
614
623
  } else {
615
- deleteRule(className);
616
- }
617
- }
618
- }
619
- /**
620
- * 加工插入規則
621
- * 1. where
622
- * 2. normal
623
- * 3. where selectors
624
- * 4. normal selectors
625
- * 5. media where
626
- * 6. media normal
627
- * 7. media where selectors
628
- * 8. media selectors
629
- * 9. media width where
630
- * 10. media width
631
- * 11. media width where selectors
632
- * 12. media width selectors
633
- */ insert(rule) {
634
- if (this.ruleBy[rule.className]) return;
635
- let index;
636
- /**
637
- * 必須按斷點值遞增,並透過索引插入,
638
- * 以實現響應式先後套用的規則
639
- * @example <1 <2 <3 ALL >=1 >=2 >=3
640
- * @description
641
- */ const endIndex = this.syntaxes.length - 1;
642
- const { at, atToken, order, priority, hasWhere, className } = rule;
643
- const findIndex = (startIndex, stopCheck, matchCheck)=>{
644
- let i = startIndex;
645
- for(; i <= endIndex; i++){
646
- const eachSyntax = this.syntaxes[i];
647
- if (stopCheck?.(eachSyntax)) return matchCheck ? -1 : i - 1;
648
- if (matchCheck?.(eachSyntax)) return i;
649
- }
650
- return matchCheck ? -1 : i - 1;
651
- };
652
- let matchStartIndex;
653
- let matchEndIndex;
654
- if (atToken) {
655
- const mediaStartIndex = this.syntaxes.findIndex((eachSyntax)=>eachSyntax.at?.media);
656
- if (mediaStartIndex === -1) {
657
- index = endIndex + 1;
658
- } else {
659
- const maxWidthFeature = at.media?.find(({ name })=>name === 'max-width');
660
- const minWidthFeature = at.media?.find(({ name })=>name === 'min-width');
661
- if (maxWidthFeature || minWidthFeature) {
662
- const mediaWidthStartIndex = this.syntaxes.findIndex((eachSyntax)=>eachSyntax.at?.media?.find(({ name })=>name === 'max-width' || name === 'min-width'));
663
- if (mediaWidthStartIndex === -1) {
664
- index = endIndex + 1;
665
- } else {
666
- if (maxWidthFeature && minWidthFeature) {
667
- /**
668
- * 範圍越小 ( 越限定 越侷限 ) 越優先,
669
- * 按照範圍 max-width - min-width 遞減排序
670
- * find 第一個所遇到同樣 feature 且範圍值比自己大的 rule,
671
- * 並插入在該 rule 之後,讓自己優先被套用
672
- */ if (priority === -1) {
673
- matchStartIndex = findIndex(mediaWidthStartIndex, (eachSyntax)=>eachSyntax.priority !== -1, (eachSyntax)=>eachSyntax.at.media?.find(({ name })=>name === 'max-width') && eachSyntax.at.media?.find(({ name })=>name === 'min-width'));
674
- matchEndIndex = findIndex(mediaWidthStartIndex, (eachSyntax)=>eachSyntax.priority !== -1);
675
- } else {
676
- matchStartIndex = findIndex(mediaWidthStartIndex, undefined, (eachSyntax)=>eachSyntax.at.media?.find(({ name })=>name === 'max-width') && eachSyntax.at.media?.find(({ name })=>name === 'min-width') && eachSyntax.priority !== -1);
677
- matchEndIndex = endIndex;
678
- }
679
- if (matchStartIndex !== -1) {
680
- const range = maxWidthFeature.value - minWidthFeature.value;
681
- let i = matchEndIndex;
682
- const endI = matchStartIndex;
683
- matchStartIndex = matchEndIndex + 1;
684
- for(; i >= endI; i--){
685
- const eachSyntax = this.syntaxes[i];
686
- const eachMaxWidthFeature = eachSyntax.at.media?.find(({ name })=>name === 'max-width');
687
- const eachMinWidthFeature = eachSyntax.at.media?.find(({ name })=>name === 'min-width');
688
- if (!eachMaxWidthFeature || !eachMinWidthFeature) {
689
- break;
690
- } else {
691
- const eachRange = eachMaxWidthFeature.value - eachMinWidthFeature.value;
692
- if (eachRange < range) {
693
- matchEndIndex = i - 1;
694
- } else if (eachRange === range) {
695
- matchStartIndex = i;
696
- } else {
697
- break;
698
- }
699
- }
700
- }
701
- }
702
- } else if (minWidthFeature) {
703
- /**
704
- * find 第一個所遇到同樣 feature 且值比自己大的 rule,
705
- * 並插入在該 rule 之後,讓自己優先被套用
706
- */ if (priority === -1) {
707
- matchStartIndex = findIndex(mediaWidthStartIndex, (eachSyntax)=>eachSyntax.at.media?.find(({ name })=>name === 'max-width') && eachSyntax.at.media?.find(({ name })=>name === 'min-width') || eachSyntax.priority !== -1, (eachSyntax)=>!eachSyntax.at.media?.find(({ name })=>name === 'max-width') && eachSyntax.at.media?.find(({ name })=>name === 'min-width'));
708
- matchEndIndex = findIndex(mediaWidthStartIndex, (eachSyntax)=>eachSyntax.at.media?.find(({ name })=>name === 'max-width') && eachSyntax.at.media?.find(({ name })=>name === 'min-width') || eachSyntax.priority !== -1);
709
- } else {
710
- matchStartIndex = findIndex(mediaWidthStartIndex, (eachSyntax)=>eachSyntax.at.media?.find(({ name })=>name === 'max-width') && eachSyntax.at.media?.find(({ name })=>name === 'min-width') && eachSyntax.priority !== -1, (eachSyntax)=>!eachSyntax.at.media?.find(({ name })=>name === 'max-width') && eachSyntax.at.media?.find(({ name })=>name === 'min-width') && eachSyntax.priority !== -1);
711
- matchEndIndex = findIndex(mediaWidthStartIndex, (eachSyntax)=>eachSyntax.at.media?.find(({ name })=>name === 'max-width') && eachSyntax.at.media?.find(({ name })=>name === 'min-width') && eachSyntax.priority !== -1);
712
- }
713
- if (matchStartIndex !== -1) {
714
- for(let i = matchEndIndex; i >= matchStartIndex; i--){
715
- const value = (this.syntaxes[i].at.media?.find(({ name })=>name === 'min-width')).value;
716
- if (value > minWidthFeature.value) {
717
- matchEndIndex = i - 1;
718
- } else if (value < minWidthFeature.value) {
719
- matchStartIndex = i + 1;
720
- break;
721
- }
722
- }
723
- }
724
- } else {
725
- /**
726
- * find 第一個所遇到同樣 feature 且值比自己大的 rule,
727
- * 並插入在該 rule 之後,讓自己優先被套用
728
- */ if (priority === -1) {
729
- matchStartIndex = findIndex(mediaWidthStartIndex, (eachSyntax)=>eachSyntax.at.media?.find(({ name })=>name === 'min-width') || eachSyntax.priority !== -1, (eachSyntax)=>eachSyntax.at.media?.find(({ name })=>name === 'max-width'));
730
- matchEndIndex = findIndex(mediaWidthStartIndex, (eachSyntax)=>eachSyntax.at.media?.find(({ name })=>name === 'min-width') || eachSyntax.priority !== -1);
731
- } else {
732
- matchStartIndex = findIndex(mediaWidthStartIndex, (eachSyntax)=>eachSyntax.at.media?.find(({ name })=>name === 'min-width') && eachSyntax.priority !== -1, (eachSyntax)=>eachSyntax.at.media?.find(({ name })=>name === 'max-width') && eachSyntax.priority !== -1);
733
- matchEndIndex = findIndex(mediaWidthStartIndex, (eachSyntax)=>eachSyntax.at.media?.find(({ name })=>name === 'min-width') && eachSyntax.priority !== -1);
734
- }
735
- if (matchStartIndex !== -1) {
736
- for(let i = matchEndIndex; i >= matchStartIndex; i--){
737
- const value = (this.syntaxes[i].at.media?.find(({ name })=>name === 'max-width')).value;
738
- if (value < maxWidthFeature.value) {
739
- matchEndIndex = i - 1;
740
- } else if (value > maxWidthFeature.value) {
741
- matchStartIndex = i + 1;
742
- break;
743
- }
744
- }
745
- }
624
+ const atIndex = className.indexOf('@');
625
+ if (atIndex !== -1) {
626
+ const name = className.slice(0, atIndex);
627
+ if (Object.prototype.hasOwnProperty.call(this.components, name)) {
628
+ const atToken = className.slice(atIndex);
629
+ for (const eachSyntax of this.components[name]){
630
+ this.stylesLayer.delete(eachSyntax + atToken + ' ' + className);
746
631
  }
747
- }
748
- } else {
749
- if (priority === -1) {
750
- matchStartIndex = mediaStartIndex;
751
- matchEndIndex = findIndex(mediaStartIndex, (eachSyntax)=>eachSyntax.at.media?.find(({ name })=>name === 'max-width' || name === 'min-width') || eachSyntax.priority !== -1);
752
632
  } else {
753
- matchStartIndex = findIndex(mediaStartIndex, (eachSyntax)=>eachSyntax.at.media?.find(({ name })=>name === 'max-width' || name === 'min-width'), (eachSyntax)=>eachSyntax.priority !== -1);
754
- matchEndIndex = findIndex(mediaStartIndex, (eachSyntax)=>eachSyntax.at.media?.find(({ name })=>name === 'max-width' || name === 'min-width'));
755
- }
756
- }
757
- }
758
- } else {
759
- const findStartIndex = Object.keys(this.variablesNativeRules).length ? this.hasKeyframesRule ? 2 : 1 : this.hasKeyframesRule ? 1 : 0;
760
- if (priority === -1) {
761
- matchStartIndex = findStartIndex;
762
- matchEndIndex = findIndex(findStartIndex, (eachSyntax)=>eachSyntax.atToken || eachSyntax.priority !== -1);
763
- } else {
764
- matchStartIndex = findIndex(findStartIndex, (eachSyntax)=>eachSyntax.atToken, (eachSyntax)=>eachSyntax.priority !== -1);
765
- matchEndIndex = findIndex(findStartIndex, (eachSyntax)=>eachSyntax.atToken);
766
- }
767
- }
768
- if (index === undefined && matchEndIndex !== undefined && matchStartIndex !== undefined) {
769
- if (matchStartIndex === -1) {
770
- index = matchEndIndex + 1;
771
- } else {
772
- if (priority === -1) {
773
- for(let i = matchStartIndex; i <= matchEndIndex; i++){
774
- const currentRule = this.syntaxes[i];
775
- if (!hasWhere && currentRule.hasWhere) continue;
776
- if (hasWhere && !currentRule.hasWhere || currentRule.order >= order) {
777
- index = i;
778
- break;
779
- }
633
+ this.generalLayer.delete(className);
780
634
  }
781
635
  } else {
782
- for(let i = matchStartIndex; i <= matchEndIndex; i++){
783
- const currentRule = this.syntaxes[i];
784
- if (!hasWhere && currentRule.hasWhere) continue;
785
- if (hasWhere && !currentRule.hasWhere) {
786
- index = i;
787
- break;
788
- }
789
- if (currentRule.priority < priority) {
790
- index = i;
791
- break;
792
- } else if (currentRule.priority === priority) {
793
- if (currentRule.order >= order) {
794
- index = i;
795
- break;
796
- }
797
- } else {
798
- index = i + 1;
799
- }
800
- }
801
- }
802
- if (index === undefined) {
803
- index = matchEndIndex + 1;
804
- }
805
- }
806
- }
807
- this.syntaxes.splice(index, 0, rule);
808
- this.ruleBy[className] = rule;
809
- if (this.style) {
810
- const sheet = this.style.sheet;
811
- let cssRuleIndex = 0;
812
- const getCssRuleIndex = (index)=>{
813
- const previousRule = this.syntaxes[index];
814
- if (previousRule) {
815
- if (!previousRule.natives.length) return getCssRuleIndex(index - 1);
816
- const lastNative = previousRule.natives[previousRule.natives.length - 1];
817
- const lastNativeCssRule = lastNative.cssRule?.parentRule ?? lastNative.cssRule;
818
- if (sheet) for(let i = 0; i < sheet.cssRules.length; i++){
819
- if (sheet.cssRules[i] === lastNativeCssRule) {
820
- cssRuleIndex = i + 1;
821
- break;
822
- }
823
- }
824
- }
825
- };
826
- getCssRuleIndex(index - 1);
827
- for(let i = 0; i < rule.natives.length;){
828
- try {
829
- const native = rule.natives[i];
830
- sheet?.insertRule(native.text, cssRuleIndex);
831
- native.cssRule = sheet?.cssRules[cssRuleIndex++];
832
- i++;
833
- } catch (error) {
834
- console.error(error);
835
- rule.natives.splice(i, 1);
836
- }
837
- }
838
- }
839
- // variables
840
- this.handleRuleWithVariableNames(rule);
841
- // animations
842
- this.handleRuleWithAnimationNames(rule);
843
- rule.definition.insert?.call(rule);
844
- return index;
845
- }
846
- get text() {
847
- return this.syntaxes.map((eachSyntax)=>eachSyntax.text).join('');
848
- }
849
- handleRuleWithAnimationNames(rule, initializing = false) {
850
- if (rule.animationNames) {
851
- const sheet = this.style?.sheet;
852
- for (const eachKeyframeName of rule.animationNames){
853
- const animation = this.animations[eachKeyframeName];
854
- if (animation.usage) {
855
- animation.usage++;
856
- } else {
857
- const nativeRule = {
858
- text: `@keyframes ${eachKeyframeName}{` + Object.entries(animation).filter(([key])=>key !== 'usage' && key !== 'native').map(([key, variables])=>`${key}{${Object.entries(variables).map(([name, value])=>name + ':' + value).join(';')}}`).join('') + '}'
859
- };
860
- const keyframeRulesIndex = Object.keys(this.variablesNativeRules).length ? 1 : 0;
861
- let keyframeRule;
862
- if (this.hasKeyframesRule) {
863
- (keyframeRule = this.syntaxes[keyframeRulesIndex]).natives.push(nativeRule);
864
- } else {
865
- this.syntaxes.splice(keyframeRulesIndex, 0, keyframeRule = {
866
- natives: [
867
- nativeRule
868
- ],
869
- get text () {
870
- return this.natives.map((eachNative)=>eachNative.text).join('');
871
- }
872
- });
873
- this.hasKeyframesRule = true;
874
- }
875
- if (sheet) {
876
- let cssRule;
877
- if (initializing) {
878
- for (const eachCSSRule of sheet.cssRules){
879
- if (eachCSSRule.constructor.name === 'CSSKeyframesRule' && eachCSSRule.name === eachKeyframeName) {
880
- cssRule = eachCSSRule;
881
- break;
882
- }
883
- }
884
- }
885
- if (cssRule) {
886
- nativeRule.cssRule = cssRule;
887
- } else {
888
- const cssRuleIndex = Object.keys(this.variablesNativeRules).length + keyframeRule.natives.length - 1;
889
- sheet.insertRule(nativeRule.text, cssRuleIndex);
890
- nativeRule.cssRule = sheet.cssRules[cssRuleIndex];
891
- }
892
- }
893
- animation.usage = 1;
894
- animation.native = nativeRule;
636
+ this.generalLayer.delete(className);
895
637
  }
896
638
  }
897
639
  }
898
640
  }
899
- handleRuleWithVariableNames(rule, initializing = false) {
900
- if (rule.variableNames) {
901
- const sheet = this.style?.sheet;
902
- for (const eachVariableName of rule.variableNames){
903
- const variable = this.variables[eachVariableName];
904
- if (variable.usage) {
905
- variable.usage++;
906
- } else {
907
- const addProperty = (mode, variable)=>{
908
- let nativeRule = this.variablesNativeRules[mode];
909
- if (!nativeRule) {
910
- let cssRule;
911
- let mediaConditionText;
912
- let selectorText;
913
- if (mode) {
914
- switch(this.config.modes?.[mode]){
915
- case 'media':
916
- mediaConditionText = `@media(prefers-color-scheme:${mode})`;
917
- selectorText = ':root';
918
- break;
919
- case 'host':
920
- selectorText = `:host(.${mode})`;
921
- if (this.config.defaultMode === mode) {
922
- selectorText += ',:host';
923
- }
924
- break;
925
- case 'class':
926
- selectorText = '.' + mode;
927
- if (this.config.defaultMode === mode) {
928
- selectorText += ',:root';
929
- }
930
- break;
931
- default:
932
- return;
933
- }
934
- } else {
935
- selectorText = ':root';
936
- }
937
- if (sheet) {
938
- const newCSSRuleIndex = Object.keys(this.variablesNativeRules).length ? this.syntaxes[0].natives.length : 0;
939
- sheet.insertRule((mediaConditionText ? mediaConditionText + '{' : '') + selectorText + '{}' + (mediaConditionText ? mediaConditionText + '}' : ''), newCSSRuleIndex);
940
- cssRule = mediaConditionText ? sheet.cssRules[newCSSRuleIndex].cssRules[0] : sheet.cssRules[newCSSRuleIndex];
941
- } else {
942
- const styleMap = new Map();
943
- const style = Object.defineProperties({}, {
944
- getPropertyValue: {
945
- value: (property)=>styleMap.get(property)
946
- },
947
- removeProperty: {
948
- value: (property)=>{
949
- styleMap.delete(property);
950
- for(let i = 0; i < style.length; i++){
951
- if (style[i] === property) {
952
- delete style[i];
953
- }
954
- }
955
- }
956
- },
957
- setProperty: {
958
- value: (property, value)=>{
959
- style[style.length] = property;
960
- styleMap.set(property, value);
961
- }
962
- },
963
- length: {
964
- get () {
965
- return Object.keys(style).length;
966
- }
967
- }
968
- });
969
- cssRule = {
970
- selectorText,
971
- style,
972
- styleMap
973
- };
974
- if (mediaConditionText) {
975
- // @ts-ignore
976
- cssRule.parentRule = {
977
- conditionText: mediaConditionText
978
- };
979
- }
980
- }
981
- nativeRule = this.pushVariableNativeRule(mode, cssRule);
982
- }
983
- const propertyName = '--' + eachVariableName;
984
- if (!initializing || !nativeRule.cssRule.style.getPropertyValue(propertyName)) {
985
- nativeRule.cssRule.style.setProperty(propertyName, String(variable.value));
986
- }
987
- };
988
- if (variable.value) {
989
- addProperty('', variable);
990
- }
991
- if (variable.modes) {
992
- for(const mode in variable.modes){
993
- addProperty(mode, variable.modes[mode]);
994
- }
995
- }
996
- variable.usage = 1;
997
- }
641
+ getModeSelector(modeName) {
642
+ const mode = this.config.modes?.[modeName];
643
+ if (mode) {
644
+ switch(mode){
645
+ case 'class':
646
+ return '.' + modeName;
647
+ case 'host':
648
+ return ':host(.' + modeName + ')';
998
649
  }
999
650
  }
1000
651
  }
1001
- pushVariableNativeRule(mode, variableCSSRule) {
1002
- if (!Object.keys(this.variablesNativeRules).length) {
1003
- this.variablesNativeRules = {};
1004
- const newRule = {
1005
- natives: [],
1006
- get text () {
1007
- return this.natives.map((eachNative)=>eachNative.text).join('');
1008
- }
1009
- };
1010
- this.syntaxes.splice(0, 0, newRule);
1011
- }
1012
- let prefix = '';
1013
- let suffix = '}';
1014
- if (variableCSSRule.parentRule) {
1015
- prefix += '@media' + variableCSSRule.parentRule.conditionText.replace(/ /g, '') + '{';
1016
- suffix += '}';
1017
- }
1018
- prefix += variableCSSRule.selectorText + '{';
1019
- const nativeRule = {
1020
- cssRule: variableCSSRule,
1021
- get text () {
1022
- const properties = [];
1023
- // eslint-disable-next-line @typescript-eslint/prefer-for-of
1024
- for(let i = 0; i < variableCSSRule.style.length; i++){
1025
- const property = variableCSSRule.style[i];
1026
- properties.push(property + ':' + variableCSSRule.style.getPropertyValue(property));
1027
- }
1028
- return prefix + properties.join(';') + suffix;
1029
- }
1030
- };
1031
- this.syntaxes[0].natives.push(this.variablesNativeRules[mode] = nativeRule);
1032
- return nativeRule;
1033
- }
1034
652
  }
1035
653
  const masterCSSs = [];
1036
654
  (()=>{