@master/css 2.0.0-rc.25 → 2.0.0-rc.27

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 (93) hide show
  1. package/dist/common.cjs +124 -0
  2. package/dist/common.d.ts +22 -0
  3. package/dist/common.mjs +106 -0
  4. package/dist/config/functions.cjs +40 -41
  5. package/dist/config/functions.mjs +39 -40
  6. package/dist/config/index.cjs +7 -7
  7. package/dist/config/index.d.ts +12 -13
  8. package/dist/config/index.mjs +6 -6
  9. package/dist/config/queries.cjs +17 -0
  10. package/dist/config/queries.d.ts +22 -0
  11. package/dist/config/queries.mjs +15 -0
  12. package/dist/config/rules.cjs +964 -851
  13. package/dist/config/rules.d.ts +8 -5
  14. package/dist/config/rules.mjs +966 -852
  15. package/dist/config/selectors.cjs +0 -1
  16. package/dist/config/selectors.d.ts +0 -1
  17. package/dist/config/selectors.mjs +0 -1
  18. package/dist/config/{semantics.cjs → utilities.cjs} +2 -5
  19. package/dist/config/{semantics.d.ts → utilities.d.ts} +2 -5
  20. package/dist/config/{semantics.mjs → utilities.mjs} +2 -5
  21. package/dist/config/variables.mjs +2 -2
  22. package/dist/core.cjs +260 -195
  23. package/dist/core.d.ts +20 -16
  24. package/dist/core.mjs +258 -193
  25. package/dist/index.cjs +45 -15
  26. package/dist/index.d.ts +13 -3
  27. package/dist/index.mjs +15 -7
  28. package/dist/layer.cjs +25 -20
  29. package/dist/layer.d.ts +26 -9
  30. package/dist/layer.mjs +22 -19
  31. package/dist/rule.cjs +147 -125
  32. package/dist/rule.d.ts +58 -20
  33. package/dist/rule.mjs +147 -125
  34. package/dist/tokens/screen-sizes.cjs +2 -2
  35. package/dist/tokens/screen-sizes.mjs +2 -2
  36. package/dist/utils/are-rule-modes-equal.cjs +7 -0
  37. package/dist/utils/are-rule-modes-equal.d.ts +2 -0
  38. package/dist/utils/are-rule-modes-equal.mjs +5 -0
  39. package/dist/utils/are-rule-queries-equal.cjs +22 -0
  40. package/dist/utils/are-rule-queries-equal.d.ts +2 -0
  41. package/dist/utils/are-rule-queries-equal.mjs +20 -0
  42. package/dist/utils/are-rule-selectors-equal.cjs +29 -0
  43. package/dist/utils/are-rule-selectors-equal.d.ts +2 -0
  44. package/dist/utils/are-rule-selectors-equal.mjs +27 -0
  45. package/dist/utils/are-rule-states-equal.cjs +11 -0
  46. package/dist/utils/are-rule-states-equal.d.ts +2 -0
  47. package/dist/utils/are-rule-states-equal.mjs +9 -0
  48. package/dist/utils/are-rules-duplicated.cjs +17 -0
  49. package/dist/utils/are-rules-duplicated.d.ts +2 -0
  50. package/dist/utils/are-rules-duplicated.mjs +15 -0
  51. package/dist/utils/extend-config.cjs +27 -14
  52. package/dist/utils/extend-config.d.ts +1 -1
  53. package/dist/utils/extend-config.mjs +27 -14
  54. package/dist/utils/generate-css.cjs +13 -0
  55. package/dist/utils/generate-css.d.ts +2 -0
  56. package/dist/utils/generate-css.mjs +11 -0
  57. package/dist/utils/hex-to-rgb.cjs +1 -1
  58. package/dist/utils/hex-to-rgb.d.ts +1 -1
  59. package/dist/utils/hex-to-rgb.mjs +1 -1
  60. package/dist/utils/is-core-rule.cjs +9 -0
  61. package/dist/utils/is-core-rule.d.ts +1 -0
  62. package/dist/utils/is-core-rule.mjs +7 -0
  63. package/dist/{functions → utils}/reorder-for-readable-classes.cjs +12 -18
  64. package/dist/{functions → utils}/reorder-for-readable-classes.d.ts +1 -5
  65. package/dist/{functions → utils}/reorder-for-readable-classes.mjs +13 -19
  66. package/package.json +1 -1
  67. package/dist/config/media-queries.cjs +0 -7
  68. package/dist/config/media-queries.d.ts +0 -1
  69. package/dist/config/media-queries.mjs +0 -1
  70. package/dist/constants/base-unit-regex.cjs +0 -5
  71. package/dist/constants/base-unit-regex.d.ts +0 -1
  72. package/dist/constants/base-unit-regex.mjs +0 -3
  73. package/dist/constants/start-symbol.cjs +0 -10
  74. package/dist/constants/start-symbol.d.ts +0 -6
  75. package/dist/constants/start-symbol.mjs +0 -8
  76. package/dist/functions/transform-color-with-opacity.cjs +0 -9
  77. package/dist/functions/transform-color-with-opacity.d.ts +0 -1
  78. package/dist/functions/transform-color-with-opacity.mjs +0 -7
  79. package/dist/utils/concat-arrays.cjs +0 -12
  80. package/dist/utils/concat-arrays.d.ts +0 -1
  81. package/dist/utils/concat-arrays.mjs +0 -10
  82. package/dist/utils/get-type.cjs +0 -12
  83. package/dist/utils/get-type.d.ts +0 -7
  84. package/dist/utils/get-type.mjs +0 -10
  85. package/dist/utils/is-plain-object.cjs +0 -15
  86. package/dist/utils/is-plain-object.d.ts +0 -8
  87. package/dist/utils/is-plain-object.mjs +0 -13
  88. package/dist/utils/is-symbol.cjs +0 -14
  89. package/dist/utils/is-symbol.d.ts +0 -7
  90. package/dist/utils/is-symbol.mjs +0 -12
  91. package/dist/utils/rgb-to-hex.cjs +0 -7
  92. package/dist/utils/rgb-to-hex.d.ts +0 -1
  93. package/dist/utils/rgb-to-hex.mjs +0 -5
package/dist/rule.mjs CHANGED
@@ -1,23 +1,22 @@
1
- import { START_SYMBOLS } from './constants/start-symbol.mjs';
2
1
  import cssEscape from './shared/utils/css-escape.mjs';
3
- import { Layer } from './layer.mjs';
4
- import { BASE_UNIT_REGEX } from './constants/base-unit-regex.mjs';
2
+ import Layer from './layer.mjs';
3
+ import { VALUE_DELIMITERS, UNIT_REGEX, BASE_UNIT_REGEX } from './common.mjs';
5
4
 
6
- const atRuleRegExp = /^(media|supports|page|font-face|keyframes|counter-style|font-feature-values|property|layer|container)(?=\||{|\(|$)/;
7
5
  class Rule {
8
6
  className;
7
+ RegisteredRule;
9
8
  css;
10
9
  at;
11
10
  priority;
12
11
  natives;
13
12
  order;
14
13
  layer;
15
- stateToken;
16
14
  declarations;
17
15
  animationNames;
18
16
  variableNames;
19
17
  constructor(className, RegisteredRule, css){
20
18
  this.className = className;
19
+ this.RegisteredRule = RegisteredRule;
21
20
  this.css = css;
22
21
  this.at = {};
23
22
  this.priority = -1;
@@ -34,20 +33,20 @@ class Rule {
34
33
  const functionDefinition = functions && functions[eachValueComponent.name];
35
34
  if (functionDefinition?.transform && !eachValueComponent.bypassTransform) {
36
35
  const result = functionDefinition.transform.call(this, this.resolveValue(eachValueComponent.children, functionDefinition.unit ?? unit, bypassVariableNames, bypassParsing || eachValueComponent.name === 'calc'), bypassVariableNames);
37
- currentValue += eachValueComponent.text = typeof result === 'string' ? result : this.resolveValue(result, functionDefinition?.unit ?? unit, bypassVariableNames, bypassParsing);
36
+ currentValue += eachValueComponent.token = eachValueComponent.text = typeof result === 'string' ? result : this.resolveValue(result, functionDefinition?.unit ?? unit, bypassVariableNames, bypassParsing);
38
37
  } else {
39
- currentValue += eachValueComponent.text = eachValueComponent.name + eachValueComponent.symbol + this.resolveValue(eachValueComponent.children, functionDefinition?.unit ?? unit, bypassVariableNames, bypassParsing) + START_SYMBOLS[eachValueComponent.symbol];
38
+ currentValue += eachValueComponent.token = eachValueComponent.text = eachValueComponent.name + eachValueComponent.symbol + this.resolveValue(eachValueComponent.children, functionDefinition?.unit ?? unit, bypassVariableNames, bypassParsing) + VALUE_DELIMITERS[eachValueComponent.symbol];
40
39
  }
41
40
  break;
42
- // todo: 應挪到 parseValue 階段處理才能支援 variables: { x: 'calc(20vw-30px)' } 這種情況,並且解析上可能會比較合理、精簡
41
+ // todo: 應挪到 parseValues 階段處理才能支援 variables: { x: 'calc(20vw-30px)' } 這種情況,並且解析上可能會比較合理、精簡
43
42
  case 'variable':
44
43
  // eslint-disable-next-line no-case-declarations
45
44
  const variable = this.css.variables[eachValueComponent.name];
46
45
  if (variable) {
47
46
  const handleVariable = (normalHandler, varHandler)=>{
48
- if (variable.themes) {
49
- if (this.theme) {
50
- const themeVariable = variable.themes[this.theme] ?? variable;
47
+ if (variable.modes) {
48
+ if (this.mode) {
49
+ const themeVariable = variable.modes[this.mode] ?? variable;
51
50
  if (themeVariable?.value) {
52
51
  normalHandler(themeVariable);
53
52
  }
@@ -68,7 +67,7 @@ class Rule {
68
67
  case 'string':
69
68
  handleVariable((variable)=>{
70
69
  const valueComponents = [];
71
- this.parseValue(valueComponents, 0, variable.value, unit, '', undefined, bypassParsing, [
70
+ this.parseValues(valueComponents, 0, variable.value, unit, '', undefined, bypassParsing, [
72
71
  ...bypassVariableNames,
73
72
  eachValueComponent.name
74
73
  ]);
@@ -83,9 +82,9 @@ class Rule {
83
82
  case 'number':
84
83
  handleVariable((variable)=>{
85
84
  if (bypassParsing) {
86
- currentValue += eachValueComponent.text = variable.value;
85
+ currentValue += eachValueComponent.text = String(variable.value);
87
86
  } else {
88
- const valueComponent = this.parseValueComponent(variable.value, unit);
87
+ const valueComponent = this.parseValue(variable.value, unit);
89
88
  currentValue += eachValueComponent.text = valueComponent.value + (valueComponent.unit ?? '');
90
89
  }
91
90
  }, ()=>{
@@ -119,7 +118,7 @@ class Rule {
119
118
  }
120
119
  return currentValue;
121
120
  };
122
- this.parseValue = (currentValueComponents, i, value, unit, endSymbol, parentFunctionName, bypassParsing = false, bypassVariableNames = [])=>{
121
+ this.parseValues = (currentValueComponents, i, value, unit, endSymbol, parentFunctionName, bypassParsing = false, bypassVariableNames = [])=>{
123
122
  const root = parentFunctionName === undefined;
124
123
  const isVarFunction = !root && (parentFunctionName.endsWith('$') || parentFunctionName.endsWith('var'));
125
124
  const checkIsString = (value)=>value === '\'' || value === '"';
@@ -144,7 +143,8 @@ class Rule {
144
143
  const valueComponent = {
145
144
  type: 'variable',
146
145
  name,
147
- variable: this.css.variables[name]
146
+ variable: this.css.variables[name],
147
+ token: currentValue
148
148
  };
149
149
  if (alpha) valueComponent.alpha = alpha;
150
150
  currentValueComponents.push(valueComponent);
@@ -152,7 +152,7 @@ class Rule {
152
152
  }
153
153
  };
154
154
  handleVariable(currentValue);
155
- if (!handled && this.colored) {
155
+ if (!handled) {
156
156
  const [colorName, alpha] = currentValue.split('/');
157
157
  handleVariable(colorName, alpha);
158
158
  }
@@ -167,10 +167,14 @@ class Rule {
167
167
  if (bypassParsing) {
168
168
  currentValueComponents.push({
169
169
  type: 'string',
170
- value: currentValue
170
+ value: currentValue,
171
+ token: currentValue
171
172
  });
172
173
  } else {
173
- currentValueComponents.push(this.parseValueComponent(currentValue, unit));
174
+ currentValueComponents.push({
175
+ ...this.parseValue(currentValue, unit),
176
+ token: currentValue
177
+ });
174
178
  }
175
179
  }
176
180
  currentValue = '';
@@ -195,27 +199,25 @@ class Rule {
195
199
  parse();
196
200
  }
197
201
  return i;
198
- } else if (!isString && val in START_SYMBOLS) {
202
+ } else if (!isString && val in VALUE_DELIMITERS) {
199
203
  const functionName = currentValue;
200
204
  const newValueComponent = {
201
205
  type: 'function',
202
206
  name: functionName,
203
207
  symbol: val,
204
- children: []
208
+ children: [],
209
+ token: ''
205
210
  };
206
211
  currentValueComponents.push(newValueComponent);
207
212
  currentValue = '';
208
213
  const functionDefinition = val === '(' ? this.css.config.functions?.[functionName] : undefined;
209
- if (!this.colored && functionDefinition?.colored) {
210
- // @ts-ignore
211
- this.colored = true;
212
- }
213
- i = this.parseValue(newValueComponent.children, ++i, value, functionDefinition?.unit ?? unit, START_SYMBOLS[val], functionName || parentFunctionName || '', bypassParsing || functionName === 'calc');
214
+ i = this.parseValues(newValueComponent.children, ++i, value, functionDefinition?.unit ?? unit, VALUE_DELIMITERS[val], functionName || parentFunctionName || '', bypassParsing || functionName === 'calc');
214
215
  } else if ((val === '|' || val === ' ') && endSymbol !== '}' && (!isString || parentFunctionName === 'path')) {
215
216
  parse();
216
217
  currentValueComponents.push({
217
218
  type: 'separator',
218
- value: ' '
219
+ value: ' ',
220
+ token: val
219
221
  });
220
222
  } else {
221
223
  if (!isString) {
@@ -230,7 +232,8 @@ class Rule {
230
232
  currentValueComponents.push({
231
233
  type: 'separator',
232
234
  value: val,
233
- text: (val === ',' ? '' : ' ') + val + (val === ',' ? '' : ' ')
235
+ text: (val === ',' ? '' : ' ') + val + (val === ',' ? '' : ' '),
236
+ token: val
234
237
  });
235
238
  continue;
236
239
  } else if (root && (val === '#' && (currentValue || currentValueComponents.length && currentValueComponents[currentValueComponents.length - 1]['type'] !== 'separator') || [
@@ -255,22 +258,21 @@ class Rule {
255
258
  };
256
259
  Object.assign(this, RegisteredRule);
257
260
  const { id, definition } = RegisteredRule;
258
- const { analyze, transformValue, declare, transformValueComponents, create, layer, unit, colored } = definition;
261
+ const { analyze, transformValue, declare, transformValueComponents, create, layer, unit } = definition;
259
262
  this.layer = layer;
260
- this.colored = !!colored;
261
263
  if (!definition.unit) definition.unit = '';
262
264
  if (!definition.separators) definition.separators = [
263
265
  ','
264
266
  ];
265
- const { scope, important, themeDriver } = css.config;
266
- const { selectors, mediaQueries, stylesBy, animations } = css;
267
+ const { scope, important, modeDriver } = css.config;
268
+ const { selectors, queries, stylesBy, animations } = css;
267
269
  const classNames = stylesBy[className];
268
270
  if (create) create.call(this, className);
269
271
  // 1. value / selectorToken
270
272
  this.declarations = definition.declarations;
271
273
  let stateToken;
272
274
  let prefixToken;
273
- if (layer === Layer.Semantic) {
275
+ if (layer === Layer.Utility) {
274
276
  // TODO: id 使用其他方式傳遞
275
277
  stateToken = className.slice(id.length - 1);
276
278
  } else {
@@ -279,11 +281,13 @@ class Rule {
279
281
  [valueToken, prefixToken] = analyze.call(this, className);
280
282
  } else {
281
283
  const indexOfColon = className.indexOf(':');
282
- this.prefix = className.slice(0, indexOfColon + 1);
284
+ this.keyToken = className.slice(0, indexOfColon + 1);
283
285
  valueToken = className.slice(indexOfColon + 1);
284
286
  }
285
287
  this.valueComponents = [];
286
- stateToken = valueToken.slice(this.parseValue(this.valueComponents, 0, valueToken, unit, '', undefined, false, id === 'animation' || id === 'animation-name' ? Object.keys(this.css.animations) : []));
288
+ const parsedValueIndex = this.parseValues(this.valueComponents, 0, valueToken, unit, '', undefined, false, definition.includeAnimations ? Object.keys(this.css.animations) : []);
289
+ this.valueToken = valueToken.slice(0, parsedValueIndex);
290
+ stateToken = valueToken.slice(parsedValueIndex);
287
291
  }
288
292
  // 2. !important
289
293
  if (stateToken[0] === '!') {
@@ -448,110 +452,118 @@ class Rule {
448
452
  // 5. atTokens
449
453
  for(let i = 1; i < stateTokens.length; i++){
450
454
  const atToken = stateTokens[i];
455
+ this.atToken = (this.atToken || '') + '@' + atToken;
451
456
  if (atToken) {
452
457
  if (atToken === 'rtl' || atToken === 'ltr') {
453
458
  this.direction = atToken;
454
459
  } else {
455
- let type = '';
456
- let queryText;
457
- const atRuleResult = atRuleRegExp.exec(atToken);
460
+ let queryType;
461
+ const atComponents = [];
462
+ // x font-face, counter-style, keyframes, font-feature-values, property, layer
463
+ const queryTypeRegExp = /^(media|supports|container)/;
464
+ const atRuleResult = queryTypeRegExp.exec(atToken);
458
465
  if (atRuleResult) {
459
- type = atRuleResult[1];
460
- queryText = atToken.slice(type.length);
461
- } else {
462
- this.media = {
466
+ queryType = atRuleResult[1];
467
+ atComponents.push({
468
+ type: 'arbitrary',
463
469
  token: atToken,
464
- features: {}
465
- };
466
- const queryTexts = [];
467
- const analyzeToken = (typeOrFeatureToken)=>{
468
- if (typeOrFeatureToken === 'all' || typeOrFeatureToken === 'print' || typeOrFeatureToken === 'screen' || typeOrFeatureToken === 'speech') {
469
- this.media.type = typeOrFeatureToken;
470
- } else if (typeOrFeatureToken.startsWith('')) {
471
- if (typeOrFeatureToken === 'landscape' || typeOrFeatureToken === 'portrait') {
472
- queryTexts.push('(orientation:' + typeOrFeatureToken + ')');
473
- } else if (typeOrFeatureToken === 'motion' || typeOrFeatureToken === 'reduced-motion') {
474
- queryTexts.push('(prefers-reduced-motion:' + (typeOrFeatureToken === 'motion' ? 'no-preference' : 'reduce') + ')');
470
+ value: atToken.slice(queryType.length).replace(/\|/g, ' ')
471
+ });
472
+ } else {
473
+ const analyzeToken = (atComponentToken)=>{
474
+ if (atComponentToken === '&') {
475
+ atComponents.push({
476
+ type: 'operator',
477
+ token: atComponentToken,
478
+ value: 'and'
479
+ });
480
+ } else if (atComponentToken.startsWith('')) {
481
+ const targetQuery = queries[atComponentToken];
482
+ if (targetQuery && typeof targetQuery === 'string') {
483
+ const match = targetQuery.match(queryTypeRegExp);
484
+ queryType = match ? match[1] : '';
485
+ if (!queryType) throw new Error(`Invalid query '${atComponentToken}': '${targetQuery}'`);
486
+ atComponents.push({
487
+ type: 'arbitrary',
488
+ value: targetQuery.slice(match ? match[1].length + 1 : 0)
489
+ });
475
490
  } else {
476
- const targetMediaQuery = mediaQueries[typeOrFeatureToken];
477
- if (targetMediaQuery && typeof targetMediaQuery === 'string') {
478
- queryTexts.push(targetMediaQuery);
479
- } else {
480
- let featureName = '';
481
- let extremumOperator = '';
482
- let correction = 0;
483
- if (typeOrFeatureToken.startsWith('<=')) {
484
- extremumOperator = '<=';
485
- featureName = 'max-width';
486
- } else if (typeOrFeatureToken.startsWith('>=') || targetMediaQuery) {
487
- extremumOperator = '>=';
488
- featureName = 'min-width';
489
- } else if (typeOrFeatureToken.startsWith('>')) {
490
- extremumOperator = '>';
491
- featureName = 'min-width';
492
- correction = .02;
493
- } else if (typeOrFeatureToken.startsWith('<')) {
494
- extremumOperator = '<';
495
- featureName = 'max-width';
496
- correction = -.02;
497
- }
498
- const token = extremumOperator ? typeOrFeatureToken.replace(extremumOperator, '') : typeOrFeatureToken;
499
- const viewport = mediaQueries[token];
500
- switch(featureName){
501
- case 'max-width':
502
- case 'min-width':
503
- // eslint-disable-next-line no-case-declarations
504
- let featureComponent = {};
505
- if (typeof viewport === 'number') {
506
- featureComponent = {
507
- type: 'number',
508
- value: viewport + correction,
509
- unit: 'px'
510
- };
511
- } else {
512
- featureComponent = this.parseValueComponent(token, 'px');
513
- if (featureComponent.type === 'number' && featureComponent.unit === 'px') {
514
- featureComponent.value += correction;
515
- }
516
- }
517
- this.media.features[featureName] = featureComponent;
518
- if (featureComponent.type === 'number') {
519
- queryTexts.push('(' + featureName + ':' + (featureComponent.value + featureComponent.unit) + ')');
491
+ // todo: container queries
492
+ queryType = 'media';
493
+ let featureName = '';
494
+ let extremumOperator = '';
495
+ let correction = 0;
496
+ if (atComponentToken.startsWith('<=')) {
497
+ extremumOperator = '<=';
498
+ featureName = 'max-width';
499
+ } else if (atComponentToken.startsWith('>=') || targetQuery) {
500
+ extremumOperator = '>=';
501
+ featureName = 'min-width';
502
+ } else if (atComponentToken.startsWith('>')) {
503
+ extremumOperator = '>';
504
+ featureName = 'min-width';
505
+ correction = .02;
506
+ } else if (atComponentToken.startsWith('<')) {
507
+ extremumOperator = '<';
508
+ featureName = 'max-width';
509
+ correction = -.02;
510
+ }
511
+ const token = extremumOperator ? atComponentToken.replace(extremumOperator, '') : atComponentToken;
512
+ const viewport = queries[token];
513
+ switch(featureName){
514
+ case 'max-width':
515
+ case 'min-width':
516
+ // eslint-disable-next-line no-case-declarations
517
+ if (typeof viewport === 'number') {
518
+ atComponents.push({
519
+ type: 'feature',
520
+ name: featureName,
521
+ valueType: 'number',
522
+ value: viewport + correction,
523
+ unit: 'px'
524
+ });
525
+ } else {
526
+ const valueComponent = this.parseValue(token, 'px');
527
+ if (valueComponent.type === 'number') {
528
+ atComponents.push({
529
+ type: 'feature',
530
+ name: featureName,
531
+ valueType: 'number',
532
+ value: valueComponent.value + correction,
533
+ unit: valueComponent.unit
534
+ });
520
535
  } else {
521
- queryTexts.push('(' + featureName + ':' + featureComponent.value + ')');
536
+ atComponents.push({
537
+ type: 'feature',
538
+ name: featureName,
539
+ valueType: 'string',
540
+ value: token
541
+ });
522
542
  }
523
- break;
524
- }
543
+ }
544
+ break;
525
545
  }
526
546
  }
527
547
  }
528
548
  };
529
549
  const isAmpersandIncluded = atToken.includes('&');
530
550
  if (isAmpersandIncluded) {
531
- const typeOrFeatureTokens = atToken.split('&');
532
- for (const typeOrFeatureToken of typeOrFeatureTokens){
533
- analyzeToken(typeOrFeatureToken);
551
+ const typeOrFeatureTokens = atToken.split(/(&|,)/);
552
+ for (const atComponentToken of typeOrFeatureTokens){
553
+ analyzeToken(atComponentToken);
534
554
  }
535
555
  } else {
536
556
  analyzeToken(atToken);
537
557
  }
538
- if (this.media.type) {
539
- queryText = this.media.type;
540
- }
541
- if (queryTexts.length) {
542
- queryText = queryTexts.join(' and ');
543
- }
544
- if (!queryText) {
558
+ if (!atComponents.length) {
545
559
  if (!isAmpersandIncluded) {
546
- this.theme = atToken;
560
+ this.mode = atToken;
547
561
  continue;
548
562
  }
549
- } else {
550
- type = 'media';
551
563
  }
552
564
  }
553
- if (queryText) {
554
- this.at[type] = (type in this.at ? this.at[type] + ' and ' : '') + queryText.replace(/\|/g, ' ');
565
+ if (queryType) {
566
+ this.at[queryType] = atComponents;
555
567
  }
556
568
  }
557
569
  }
@@ -589,14 +601,14 @@ class Rule {
589
601
  }
590
602
  propertiesText.push(propertyText + ((this.important || important) && !propertyText.endsWith('!important') ? '!important' : ''));
591
603
  };
592
- const prefix = propertyName + ':';
604
+ const keyToken = propertyName + ':';
593
605
  const declarations = this.declarations[propertyName];
594
606
  if (Array.isArray(declarations)) {
595
607
  for (const value of declarations){
596
- push(prefix + String(value));
608
+ push(keyToken + String(value));
597
609
  }
598
610
  } else {
599
- push(prefix + String(declarations));
611
+ push(keyToken + String(declarations));
600
612
  }
601
613
  }
602
614
  // 創建 Natives
@@ -610,7 +622,7 @@ class Rule {
610
622
  const prefixSelectors = this.vendorPrefixSelectors[prefixSelectorVendor];
611
623
  const suffixSelectors = this.vendorSuffixSelectors[eachSuffixSelectorVendor];
612
624
  const prefixTexts = prefixSelectors.map((eachPrefixSelector)=>eachPrefixSelector + prefixText);
613
- const getCssText = (name)=>prefixTexts.map((eachPrefixText)=>(this.theme && themeDriver !== 'media' ? themeDriver === 'host' ? `:host(.${this.theme}) ` : `.${this.theme} ` : '') + (scope ? scope + ' ' : '') + eachPrefixText).reduce((arr, eachPrefixText)=>{
625
+ const getCssText = (name)=>prefixTexts.map((eachPrefixText)=>(this.mode && modeDriver !== 'media' ? modeDriver === 'host' ? `:host(.${this.mode}) ` : `.${this.mode} ` : '') + (scope ? scope + ' ' : '') + eachPrefixText).reduce((arr, eachPrefixText)=>{
614
626
  arr.push(suffixSelectors.reduce((_arr, eachSuffixSelector)=>{
615
627
  _arr.push(eachPrefixText + '.' + cssEscape(name) + eachSuffixSelector);
616
628
  return _arr;
@@ -619,10 +631,10 @@ class Rule {
619
631
  }, []).join(',');
620
632
  let cssText = getCssText(className) + (classNames ? classNames.reduce((str, className)=>str + ',' + getCssText(className), '') : '') + '{' + propertiesText.join(';') + '}';
621
633
  for (const key of Object.keys(this.at).sort((_a, b)=>b === 'supports' ? -1 : 1)){
622
- cssText = '@' + key + (key.includes(' ') ? '' : ' ') + this.at[key] + '{' + cssText + '}';
634
+ cssText = '@' + key + (key.includes(' ') ? '' : ' ') + this.at[key].map((eachAtComponent)=>this.resolveAtComponent(eachAtComponent)).join(' ') + '{' + cssText + '}';
623
635
  }
624
- if (this.theme && themeDriver === 'media') {
625
- cssText = `@media(prefers-color-scheme:${this.theme}){` + cssText + '}';
636
+ if (this.mode && modeDriver === 'media') {
637
+ cssText = `@media(prefers-color-scheme:${this.mode}){` + cssText + '}';
626
638
  }
627
639
  this.natives.push({
628
640
  text: cssText
@@ -631,12 +643,22 @@ class Rule {
631
643
  }
632
644
  }
633
645
  }
646
+ resolveAtComponent(atComponent) {
647
+ switch(atComponent.type){
648
+ case 'arbitrary':
649
+ return atComponent.value;
650
+ case 'feature':
651
+ return '(' + atComponent.name + ':' + atComponent.value + (atComponent.unit || '') + ')';
652
+ case 'operator':
653
+ return atComponent.value;
654
+ }
655
+ }
634
656
  resolveValue;
635
657
  get text() {
636
658
  return this.natives.map((eachNative)=>eachNative.text).join('');
637
659
  }
638
- parseValue;
639
- parseValueComponent(token, unit = this.definition.unit) {
660
+ parseValues;
661
+ parseValue(token, unit = this.definition.unit) {
640
662
  const defaultUnit = unit ?? this.definition.unit;
641
663
  let newUnit = '';
642
664
  let value;
@@ -667,7 +689,7 @@ class Rule {
667
689
  type: 'number'
668
690
  };
669
691
  }
670
- const matches = token.match(/^([+-.]?\d+(\.?\d+)?)(%|cm|mm|q|in|pt|pc|px|em|rem|ex|rex|cap|rcap|ch|rch|ic|ric|lh|rlh|vw|svw|lvw|dvw|vh|svh|lvh|dvh|vi|svi|lvi|dvi|vb|svb|lvb|dvb|vmin|svmin|lvmin|dvmin|vmax|svmax|lvmax|dvmax|cqw|cqh|cqi|cqb|cqmin|cqmax|deg|grad|rad|turn|s|ms|hz|khz|dpi|dpcm|dppx|x|fr|db|st)?$/);
692
+ const matches = token.match(UNIT_REGEX);
671
693
  // ['0.5deg', '0.5', 'deg', index: 0, input: '0.5deg', groups: undefined]
672
694
  if (matches) {
673
695
  value = +matches[1];
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var mediaQueries = {
3
+ var screenSizes = {
4
4
  '4xs': 360,
5
5
  '3xs': 480,
6
6
  '2xs': 600,
@@ -14,4 +14,4 @@ var mediaQueries = {
14
14
  '4xl': 2560
15
15
  };
16
16
 
17
- module.exports = mediaQueries;
17
+ module.exports = screenSizes;
@@ -1,4 +1,4 @@
1
- var mediaQueries = {
1
+ var screenSizes = {
2
2
  '4xs': 360,
3
3
  '3xs': 480,
4
4
  '2xs': 600,
@@ -12,4 +12,4 @@ var mediaQueries = {
12
12
  '4xl': 2560
13
13
  };
14
14
 
15
- export { mediaQueries as default };
15
+ export { screenSizes as default };
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+
3
+ function areRuleModesEqual(aRule, bRule) {
4
+ return aRule.mode === bRule.mode;
5
+ }
6
+
7
+ module.exports = areRuleModesEqual;
@@ -0,0 +1,2 @@
1
+ import type { Rule } from '../rule';
2
+ export default function areRuleModesEqual(aRule: Rule, bRule: Rule): boolean;
@@ -0,0 +1,5 @@
1
+ function areRuleModesEqual(aRule, bRule) {
2
+ return aRule.mode === bRule.mode;
3
+ }
4
+
5
+ export { areRuleModesEqual as default };
@@ -0,0 +1,22 @@
1
+ 'use strict';
2
+
3
+ function areRuleQueriesEqual(aRule, bRule) {
4
+ const aQueryTypes = Object.keys(aRule.at);
5
+ const bQueryTypes = Object.keys(bRule.at);
6
+ if (aQueryTypes.length !== bQueryTypes.length) {
7
+ return false;
8
+ }
9
+ for (const aQueryType of aQueryTypes){
10
+ const aAtComponents = aRule.at[aQueryType];
11
+ const bAtComponents = bRule.at[aQueryType];
12
+ for (const aAtComponent of aAtComponents){
13
+ const aAtComponentToken = aRule.resolveAtComponent(aAtComponent);
14
+ if (!bAtComponents.find((bAtComponent)=>bRule.resolveAtComponent(bAtComponent) === aAtComponentToken)) {
15
+ return false;
16
+ }
17
+ }
18
+ }
19
+ return true;
20
+ }
21
+
22
+ module.exports = areRuleQueriesEqual;
@@ -0,0 +1,2 @@
1
+ import type { Rule } from '../rule';
2
+ export default function areRuleQueriesEqual(aRule: Rule, bRule: Rule): boolean;
@@ -0,0 +1,20 @@
1
+ function areRuleQueriesEqual(aRule, bRule) {
2
+ const aQueryTypes = Object.keys(aRule.at);
3
+ const bQueryTypes = Object.keys(bRule.at);
4
+ if (aQueryTypes.length !== bQueryTypes.length) {
5
+ return false;
6
+ }
7
+ for (const aQueryType of aQueryTypes){
8
+ const aAtComponents = aRule.at[aQueryType];
9
+ const bAtComponents = bRule.at[aQueryType];
10
+ for (const aAtComponent of aAtComponents){
11
+ const aAtComponentToken = aRule.resolveAtComponent(aAtComponent);
12
+ if (!bAtComponents.find((bAtComponent)=>bRule.resolveAtComponent(bAtComponent) === aAtComponentToken)) {
13
+ return false;
14
+ }
15
+ }
16
+ }
17
+ return true;
18
+ }
19
+
20
+ export { areRuleQueriesEqual as default };
@@ -0,0 +1,29 @@
1
+ 'use strict';
2
+
3
+ function areRuleSelectorsEqual(aRule, bRule) {
4
+ // suffix
5
+ const aVendorSuffixSelectorKeys = Object.keys(aRule.vendorSuffixSelectors);
6
+ const bVendorSuffixSelectorKeys = Object.keys(bRule.vendorSuffixSelectors);
7
+ if (aVendorSuffixSelectorKeys.length !== bVendorSuffixSelectorKeys.length) return false;
8
+ const isSameVendorSuffixSelectors = aVendorSuffixSelectorKeys.every((eachAKey)=>{
9
+ if (!Object.prototype.hasOwnProperty.call(bRule.vendorSuffixSelectors, eachAKey)) return false;
10
+ const aValues = aRule.vendorSuffixSelectors[eachAKey];
11
+ const bValues = bRule.vendorSuffixSelectors[eachAKey];
12
+ return aValues.length === bValues.length && aValues.every((eachAValue)=>bValues.includes(eachAValue));
13
+ });
14
+ if (!isSameVendorSuffixSelectors) return false;
15
+ // prefix
16
+ const aVendorPrefixSelectorKeys = Object.keys(aRule.vendorPrefixSelectors);
17
+ const bVendorPrefixSelectorKeys = Object.keys(bRule.vendorPrefixSelectors);
18
+ if (aVendorPrefixSelectorKeys.length !== bVendorPrefixSelectorKeys.length) return false;
19
+ const isSameVendorPrefixSelectors = aVendorPrefixSelectorKeys.every((eachAKey)=>{
20
+ if (!Object.prototype.hasOwnProperty.call(bRule.vendorPrefixSelectors, eachAKey)) return false;
21
+ const aValues = aRule.vendorPrefixSelectors[eachAKey];
22
+ const bValues = bRule.vendorPrefixSelectors[eachAKey];
23
+ return aValues.length === bValues.length && aValues.every((eachAValue)=>bValues.includes(eachAValue));
24
+ });
25
+ if (!isSameVendorPrefixSelectors) return false;
26
+ return true;
27
+ }
28
+
29
+ module.exports = areRuleSelectorsEqual;
@@ -0,0 +1,2 @@
1
+ import type { Rule } from '../rule';
2
+ export default function areRuleSelectorsEqual(aRule: Rule, bRule: Rule): boolean;