@master/css 2.0.0-rc.60 → 2.0.0-rc.62

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 (122) hide show
  1. package/dist/animation-rule.cjs +24 -0
  2. package/dist/animation-rule.d.ts +11 -0
  3. package/dist/animation-rule.mjs +22 -0
  4. package/dist/common.cjs +50 -1
  5. package/dist/common.d.ts +14 -0
  6. package/dist/common.mjs +45 -2
  7. package/dist/config/at.cjs +13 -10
  8. package/dist/config/at.d.ts +4 -1
  9. package/dist/config/at.mjs +13 -10
  10. package/dist/config/index.cjs +3 -0
  11. package/dist/config/index.d.ts +2 -1
  12. package/dist/config/index.mjs +3 -1
  13. package/dist/config/modes.d.ts +4 -2
  14. package/dist/config/rules.cjs +28 -46
  15. package/dist/config/rules.d.ts +4 -2
  16. package/dist/config/rules.mjs +28 -46
  17. package/dist/config/screens.cjs +17 -0
  18. package/dist/config/screens.d.ts +14 -0
  19. package/dist/config/screens.mjs +15 -0
  20. package/dist/config/selectors.cjs +11 -15
  21. package/dist/config/selectors.d.ts +10 -8
  22. package/dist/config/selectors.mjs +11 -15
  23. package/dist/config/utilities.cjs +3 -0
  24. package/dist/config/utilities.d.ts +3 -0
  25. package/dist/config/utilities.mjs +3 -0
  26. package/dist/config/variables.cjs +0 -13
  27. package/dist/config/variables.d.ts +0 -13
  28. package/dist/config/variables.mjs +0 -13
  29. package/dist/core.cjs +438 -476
  30. package/dist/core.d.ts +14 -6
  31. package/dist/core.mjs +438 -476
  32. package/dist/factories/with-syntax-layer.cjs +37 -260
  33. package/dist/factories/with-syntax-layer.mjs +37 -260
  34. package/dist/index.cjs +38 -12
  35. package/dist/index.d.ts +19 -7
  36. package/dist/index.mjs +17 -7
  37. package/dist/layer.cjs +11 -7
  38. package/dist/layer.d.ts +4 -3
  39. package/dist/layer.mjs +11 -7
  40. package/dist/non-layer.cjs +10 -17
  41. package/dist/non-layer.d.ts +1 -1
  42. package/dist/non-layer.mjs +10 -17
  43. package/dist/rule.cjs +4 -6
  44. package/dist/rule.d.ts +3 -10
  45. package/dist/rule.mjs +4 -6
  46. package/dist/syntax-rule-type.cjs +7 -8
  47. package/dist/syntax-rule-type.d.ts +7 -7
  48. package/dist/syntax-rule-type.mjs +7 -8
  49. package/dist/syntax-rule.cjs +125 -315
  50. package/dist/syntax-rule.d.ts +18 -21
  51. package/dist/syntax-rule.mjs +126 -316
  52. package/dist/types/common.d.ts +2 -0
  53. package/dist/types/config.d.ts +12 -7
  54. package/dist/types/syntax.d.ts +5 -24
  55. package/dist/utils/compare-rule-priority.cjs +143 -0
  56. package/dist/utils/compare-rule-priority.d.ts +7 -0
  57. package/dist/utils/compare-rule-priority.mjs +138 -0
  58. package/dist/utils/equal-at-rules.cjs +22 -0
  59. package/dist/utils/equal-at-rules.d.ts +2 -0
  60. package/dist/utils/equal-at-rules.mjs +20 -0
  61. package/dist/utils/equal-declarations.cjs +10 -0
  62. package/dist/utils/equal-declarations.d.ts +2 -0
  63. package/dist/utils/equal-declarations.mjs +8 -0
  64. package/dist/utils/equal-selectors.cjs +70 -0
  65. package/dist/utils/equal-selectors.d.ts +2 -0
  66. package/dist/utils/equal-selectors.mjs +68 -0
  67. package/dist/utils/equal-variants.cjs +10 -0
  68. package/dist/utils/equal-variants.d.ts +2 -0
  69. package/dist/utils/equal-variants.mjs +8 -0
  70. package/dist/utils/extend-config.cjs +0 -1
  71. package/dist/utils/extend-config.mjs +0 -1
  72. package/dist/utils/generate-at.cjs +30 -0
  73. package/dist/utils/generate-at.d.ts +2 -0
  74. package/dist/utils/generate-at.mjs +28 -0
  75. package/dist/utils/generate-selector.cjs +49 -0
  76. package/dist/utils/generate-selector.d.ts +2 -0
  77. package/dist/utils/generate-selector.mjs +47 -0
  78. package/dist/utils/get-single-at-number-rule-node.cjs +9 -0
  79. package/dist/utils/get-single-at-number-rule-node.d.ts +2 -0
  80. package/dist/utils/get-single-at-number-rule-node.mjs +7 -0
  81. package/dist/utils/parse-at.cjs +157 -0
  82. package/dist/utils/parse-at.d.ts +39 -0
  83. package/dist/utils/parse-at.mjs +155 -0
  84. package/dist/utils/parse-pair.cjs +51 -0
  85. package/dist/utils/parse-pair.d.ts +8 -0
  86. package/dist/utils/parse-pair.mjs +49 -0
  87. package/dist/utils/parse-selector.cjs +112 -0
  88. package/dist/utils/parse-selector.d.ts +19 -0
  89. package/dist/utils/parse-selector.mjs +110 -0
  90. package/dist/utils/parse-value.cjs +39 -0
  91. package/dist/utils/parse-value.d.ts +2 -0
  92. package/dist/utils/parse-value.mjs +37 -0
  93. package/dist/utils/replace-char-outside-quotes.cjs +21 -0
  94. package/dist/utils/replace-char-outside-quotes.d.ts +1 -0
  95. package/dist/utils/replace-char-outside-quotes.mjs +19 -0
  96. package/dist/utils/sort-readable-classes.cjs +74 -0
  97. package/dist/utils/{reorder-for-readable-classes.d.ts → sort-readable-classes.d.ts} +1 -1
  98. package/dist/utils/sort-readable-classes.mjs +72 -0
  99. package/dist/utils/split-char-outside-quotes.cjs +29 -0
  100. package/dist/utils/split-char-outside-quotes.d.ts +1 -0
  101. package/dist/utils/split-char-outside-quotes.mjs +27 -0
  102. package/dist/variable-rule.cjs +86 -0
  103. package/dist/variable-rule.d.ts +23 -0
  104. package/dist/variable-rule.mjs +81 -0
  105. package/package.json +1 -1
  106. package/dist/utils/are-rule-at-equal.cjs +0 -22
  107. package/dist/utils/are-rule-at-equal.d.ts +0 -2
  108. package/dist/utils/are-rule-at-equal.mjs +0 -20
  109. package/dist/utils/are-rule-modes-equal.cjs +0 -7
  110. package/dist/utils/are-rule-modes-equal.d.ts +0 -2
  111. package/dist/utils/are-rule-modes-equal.mjs +0 -5
  112. package/dist/utils/are-rule-selectors-equal.cjs +0 -29
  113. package/dist/utils/are-rule-selectors-equal.d.ts +0 -2
  114. package/dist/utils/are-rule-selectors-equal.mjs +0 -27
  115. package/dist/utils/are-rule-states-equal.cjs +0 -11
  116. package/dist/utils/are-rule-states-equal.d.ts +0 -2
  117. package/dist/utils/are-rule-states-equal.mjs +0 -9
  118. package/dist/utils/are-rules-duplicated.cjs +0 -17
  119. package/dist/utils/are-rules-duplicated.d.ts +0 -2
  120. package/dist/utils/are-rules-duplicated.mjs +0 -15
  121. package/dist/utils/reorder-for-readable-classes.cjs +0 -62
  122. package/dist/utils/reorder-for-readable-classes.mjs +0 -60
@@ -1,23 +1,35 @@
1
1
  import cssEscape from './shared/utils/css-escape.mjs';
2
2
  import SyntaxRuleType from './syntax-rule-type.mjs';
3
- import { VALUE_DELIMITERS, UNIT_REGEX, BASE_UNIT_REGEX } from './common.mjs';
4
- import { Rule } from './rule.mjs';
3
+ import { VALUE_DELIMITERS, AT_IDENTIFIERS, BASE_UNIT_REGEX } from './common.mjs';
4
+ import parseValue from './utils/parse-value.mjs';
5
+ import parseAt from './utils/parse-at.mjs';
6
+ import generateAt from './utils/generate-at.mjs';
7
+ import parseSelector from './utils/parse-selector.mjs';
8
+ import generateSelector from './utils/generate-selector.mjs';
9
+ import { calcRulePriority } from './utils/compare-rule-priority.mjs';
5
10
 
6
- class SyntaxRule extends Rule {
11
+ class SyntaxRule {
7
12
  name;
8
13
  css;
9
14
  registeredSyntax;
10
15
  fixedClass;
11
- at;
16
+ native;
17
+ atRules;
12
18
  priority;
13
- order;
14
19
  type;
15
20
  declarations;
16
21
  layer;
22
+ valid;
17
23
  animationNames;
18
24
  variableNames;
19
25
  constructor(name, css, registeredSyntax, fixedClass, mode){
20
- super(name), this.name = name, this.css = css, this.registeredSyntax = registeredSyntax, this.fixedClass = fixedClass, this.at = {}, this.priority = -1, this.order = 0, this.type = 0, this.resolveValue = (valueComponents, unit, bypassVariableNames, bypassParsing)=>{
26
+ this.name = name;
27
+ this.css = css;
28
+ this.registeredSyntax = registeredSyntax;
29
+ this.fixedClass = fixedClass;
30
+ this.type = SyntaxRuleType.Normal;
31
+ this.valid = true;
32
+ this.resolveValue = (valueComponents, unit, bypassVariableNames, bypassParsing)=>{
21
33
  const { functions } = this.css.config;
22
34
  let currentValue = '';
23
35
  for (const eachValueComponent of valueComponents){
@@ -43,11 +55,12 @@ class SyntaxRule extends Rule {
43
55
  normalHandler(themeVariable);
44
56
  }
45
57
  } else {
46
- if (!this.variableNames) {
47
- this.variableNames = [];
48
- }
49
- if (!this.variableNames.includes(eachValueComponent.name)) {
50
- this.variableNames.push(eachValueComponent.name);
58
+ if (this.variableNames) {
59
+ this.variableNames.add(eachValueComponent.name);
60
+ } else {
61
+ this.variableNames = new Set([
62
+ eachValueComponent.name
63
+ ]);
51
64
  }
52
65
  varHandler();
53
66
  }
@@ -108,7 +121,8 @@ class SyntaxRule extends Rule {
108
121
  }
109
122
  }
110
123
  return currentValue;
111
- }, this.parseValues = (currentValueComponents, i, value, unit, endSymbol, parentFunctionName, bypassParsing = false, bypassVariableNames = [])=>{
124
+ };
125
+ this.parseValues = (currentValueComponents, i, value, unit, endSymbol, parentFunctionName, bypassParsing = false, bypassVariableNames = [])=>{
112
126
  const root = parentFunctionName === undefined;
113
127
  const isVarFunction = !root && (parentFunctionName.endsWith('$') || parentFunctionName.endsWith('var'));
114
128
  const checkIsString = (value)=>value === '\'' || value === '"';
@@ -162,8 +176,9 @@ class SyntaxRule extends Rule {
162
176
  token: currentValue
163
177
  });
164
178
  } else {
179
+ const parsedValue = this.parseValue(currentValue, unit);
165
180
  currentValueComponents.push({
166
- ...this.parseValue(currentValue, unit),
181
+ ...parsedValue,
167
182
  token: currentValue
168
183
  });
169
184
  }
@@ -253,20 +268,17 @@ class SyntaxRule extends Rule {
253
268
  const { id, definition } = registeredSyntax;
254
269
  const { analyze, transformValue, declare, transformValueComponents, create, type, unit } = definition;
255
270
  this.type = type;
256
- const { scope, important, modes } = css.config;
257
- const { at, animations } = css;
258
271
  if (create) create.call(this, name);
259
272
  // 1. value / selectorToken
260
273
  this.declarations = definition.declarations;
261
274
  let stateToken;
262
- let prefixToken;
263
275
  if (this.type === SyntaxRuleType.Utility) {
264
276
  // TODO: id 使用其他方式傳遞
265
277
  stateToken = name.slice(id.length - 1);
266
278
  } else {
267
279
  let valueToken;
268
280
  if (analyze) {
269
- [valueToken, prefixToken] = analyze.call(this, name);
281
+ [valueToken] = analyze.call(this, name);
270
282
  } else {
271
283
  const indexOfColon = name.indexOf(':');
272
284
  this.keyToken = name.slice(0, indexOfColon + 1);
@@ -283,186 +295,57 @@ class SyntaxRule extends Rule {
283
295
  stateToken = stateToken.slice(1);
284
296
  }
285
297
  this.stateToken = stateToken;
286
- // 3. prefix selector
287
- if (prefixToken) {
288
- this.vendorPrefixSelectors = css.generateVendorSelectors(prefixToken);
289
- }
290
298
  // 4. suffix selector
291
299
  const stateTokens = stateToken.split('@');
292
300
  const suffixSelector = stateTokens[0];
293
301
  if (suffixSelector) {
294
- this.vendorSuffixSelectors = css.generateVendorSelectors(suffixSelector);
295
- for (const suffixSelectors of Object.values(this.vendorSuffixSelectors)){
296
- for (const eachSuffixSelector of suffixSelectors){
297
- const SORTED_SELECTORS = [
298
- ':disabled',
299
- ':active',
300
- ':focus',
301
- ':hover'
302
- ];
303
- for(let i = 0; i < SORTED_SELECTORS.length; i++){
304
- if (eachSuffixSelector.includes(SORTED_SELECTORS[i])) {
305
- if (this.priority === -1 || this.priority > i) {
306
- this.priority = i;
307
- }
308
- break;
309
- }
310
- }
311
- }
312
- }
313
- }
314
- // selector combinations
315
- const suffixSelectorVendorsByPrefixSelectorVendor = {};
316
- if (this.vendorPrefixSelectors) {
317
- if (this.vendorSuffixSelectors) {
318
- for(const prefixSelectorVendor in this.vendorPrefixSelectors){
319
- const suffixSelectorVendors = suffixSelectorVendorsByPrefixSelectorVendor[prefixSelectorVendor] = [];
320
- if (Object.prototype.hasOwnProperty.call(this.vendorSuffixSelectors, prefixSelectorVendor)) {
321
- suffixSelectorVendors.push(prefixSelectorVendor);
322
- } else {
323
- for(const suffixVendor in this.vendorSuffixSelectors){
324
- suffixSelectorVendors.push(suffixVendor);
325
- }
326
- }
327
- }
328
- } else {
329
- for(const vendor in this.vendorPrefixSelectors){
330
- suffixSelectorVendorsByPrefixSelectorVendor[vendor] = [
331
- ''
332
- ];
333
- }
334
- }
335
- } else {
336
- suffixSelectorVendorsByPrefixSelectorVendor[''] = this.vendorSuffixSelectors ? Object.keys(this.vendorSuffixSelectors) : [
337
- ''
338
- ];
302
+ this.selectorNodes = parseSelector(suffixSelector, css);
339
303
  }
340
304
  // 5. atTokens
341
305
  for(let i = 1; i < stateTokens.length; i++){
342
306
  const atToken = stateTokens[i];
307
+ if (css.config.modes?.[atToken]) {
308
+ this.mode = atToken;
309
+ continue;
310
+ }
343
311
  this.atToken = (this.atToken || '') + '@' + atToken;
344
- if (atToken) {
345
- if (atToken === 'base' && !this.fixedClass) {
312
+ const atRule = parseAt(atToken, css);
313
+ const targetNodes = this.atRules?.[atRule.id];
314
+ if (targetNodes) {
315
+ targetNodes.push(...atRule.nodes);
316
+ } else {
317
+ this.atRules = {
318
+ ...this.atRules,
319
+ [atRule.id]: atRule.nodes
320
+ };
321
+ }
322
+ }
323
+ if (this.mode && css.config.modes?.[this.mode] === 'media') {
324
+ const atComp = {
325
+ name: 'prefers-color-scheme',
326
+ value: this.mode
327
+ };
328
+ if (this.atRules?.media) {
329
+ this.atRules.media.push(atComp);
330
+ } else {
331
+ this.atRules = {
332
+ media: [
333
+ atComp
334
+ ]
335
+ };
336
+ }
337
+ }
338
+ if (this.fixedClass) {
339
+ this.layer = css.componentsLayer;
340
+ } else {
341
+ const onlyNode = this.atRules?.layer?.length === 1 && this.atRules.layer[0];
342
+ if (onlyNode) {
343
+ if (onlyNode.value === 'base') {
346
344
  this.layer = css.baseLayer;
347
- continue;
348
- } else if (atToken === 'preset' && !this.fixedClass) {
345
+ this.atRules.layer = undefined;
346
+ } else if (onlyNode.value === 'preset') {
349
347
  this.layer = css.presetLayer;
350
- continue;
351
- } else if (atToken === 'rtl' || atToken === 'ltr') {
352
- this.direction = atToken;
353
- } else {
354
- let queryType;
355
- const atComponents = [];
356
- // x font-face, counter-style, keyframes, font-feature-values, property, layer
357
- const queryTypeRegExp = /^(media|supports|container|layer)/;
358
- const atRuleResult = queryTypeRegExp.exec(atToken);
359
- if (atRuleResult) {
360
- queryType = atRuleResult[1];
361
- atComponents.push({
362
- type: 'arbitrary',
363
- token: atToken,
364
- value: atToken.slice(queryType.length).replace(/\|/g, ' ')
365
- });
366
- } else {
367
- const analyzeToken = (atComponentToken)=>{
368
- if (atComponentToken === '&') {
369
- atComponents.push({
370
- type: 'operator',
371
- token: atComponentToken,
372
- value: 'and'
373
- });
374
- } else if (atComponentToken.startsWith('')) {
375
- const targetAt = at.get(atComponentToken);
376
- if (typeof targetAt === 'string') {
377
- const match = targetAt.match(queryTypeRegExp);
378
- queryType = match ? match[1] : '';
379
- if (!queryType) throw new Error(`Invalid query '${atComponentToken}': '${targetAt}'`);
380
- atComponents.push({
381
- type: 'arbitrary',
382
- value: targetAt.slice(match ? match[1].length + 1 : 0)
383
- });
384
- } else {
385
- // todo: container queries
386
- queryType = 'media';
387
- let featureName = '';
388
- let extremumOperator = '';
389
- let correction = 0;
390
- if (atComponentToken.startsWith('<=')) {
391
- extremumOperator = '<=';
392
- featureName = 'max-width';
393
- } else if (atComponentToken.startsWith('>') && !atComponentToken.startsWith('>=')) {
394
- extremumOperator = '>';
395
- featureName = 'min-width';
396
- correction = .02;
397
- } else if (atComponentToken.startsWith('<')) {
398
- extremumOperator = '<';
399
- featureName = 'max-width';
400
- correction = -0.02;
401
- } else if (atComponentToken.startsWith('>=') || targetAt) {
402
- extremumOperator = '>=';
403
- featureName = 'min-width';
404
- }
405
- const token = extremumOperator ? atComponentToken.replace(extremumOperator, '') : atComponentToken;
406
- const viewport = at.get(token);
407
- switch(featureName){
408
- case 'max-width':
409
- case 'min-width':
410
- if (typeof viewport === 'number') {
411
- atComponents.push({
412
- type: 'feature',
413
- name: featureName,
414
- valueType: 'number',
415
- value: viewport + correction,
416
- unit: 'px'
417
- });
418
- } else {
419
- const valueComponent = this.parseValue(token, 'px');
420
- if (valueComponent.type === 'number') {
421
- atComponents.push({
422
- type: 'feature',
423
- name: featureName,
424
- valueType: 'number',
425
- value: valueComponent.value + correction,
426
- unit: valueComponent.unit
427
- });
428
- } else {
429
- atComponents.push({
430
- type: 'feature',
431
- name: featureName,
432
- valueType: 'string',
433
- value: token
434
- });
435
- }
436
- }
437
- break;
438
- }
439
- }
440
- }
441
- };
442
- const isAmpersandIncluded = atToken.includes('&');
443
- if (isAmpersandIncluded) {
444
- const typeOrFeatureTokens = atToken.split(/(&|,)/);
445
- for (const atComponentToken of typeOrFeatureTokens){
446
- analyzeToken(atComponentToken);
447
- }
448
- } else {
449
- analyzeToken(atToken);
450
- }
451
- if (!atComponents.length) {
452
- if (!isAmpersandIncluded && modes?.[atToken]) {
453
- this.mode = atToken;
454
- continue;
455
- }
456
- }
457
- }
458
- if (queryType) {
459
- const eachAtComponents = this.at[queryType];
460
- if (eachAtComponents) {
461
- eachAtComponents.push(...atComponents);
462
- } else {
463
- this.at[queryType] = atComponents;
464
- }
465
- }
348
+ this.atRules.layer = undefined;
466
349
  }
467
350
  }
468
351
  }
@@ -484,155 +367,82 @@ class SyntaxRule extends Rule {
484
367
  };
485
368
  }
486
369
  }
487
- const propertiesText = [];
488
- for(const propertyName in this.declarations){
489
- const push = (propertyText)=>{
490
- // animations
491
- if (animations && (propertyText.startsWith('animation') || propertyText.startsWith('animation-name'))) {
492
- const animationNames = propertyText.split(':')[1].split('!important')[0].split(' ').filter((eachValue)=>this.css.animations.has(eachValue) && (!this.animationNames || !this.animationNames.includes(eachValue)));
493
- if (animationNames.length) {
494
- if (!this.animationNames) {
495
- this.animationNames = [];
496
- }
497
- this.animationNames = animationNames;
498
- }
499
- }
500
- propertiesText.push(propertyText + ((this.important || important) && !propertyText.endsWith('!important') ? '!important' : ''));
501
- };
502
- const keyToken = propertyName + ':';
503
- const declarations = this.declarations[propertyName];
504
- if (Array.isArray(declarations)) {
505
- for (const value of declarations){
506
- push(keyToken + String(value));
507
- }
508
- } else {
509
- push(keyToken + String(declarations));
510
- }
511
- }
512
- // 創建 Natives
513
- if (propertiesText.length) {
514
- for(const prefixSelectorVendor in suffixSelectorVendorsByPrefixSelectorVendor){
515
- for (const eachSuffixSelectorVendor of suffixSelectorVendorsByPrefixSelectorVendor[prefixSelectorVendor]){
516
- const prefixSelectors = this.vendorPrefixSelectors?.[prefixSelectorVendor];
517
- const suffixSelectors = this.vendorSuffixSelectors?.[eachSuffixSelectorVendor];
518
- if (this.css.supportVendors) {
519
- if (prefixSelectorVendor && !this.css.supportVendors?.has(prefixSelectorVendor) || eachSuffixSelectorVendor && !this.css.supportVendors?.has(eachSuffixSelectorVendor)) {
370
+ if (!Object.entries(this.declarations ?? {}).length) {
371
+ this.valid = false;
372
+ } else {
373
+ for(const propertyName in this.declarations){
374
+ if (this.css.animations && (propertyName === 'animation' || propertyName === 'animation-name')) {
375
+ const propertyValue = this.declarations[propertyName];
376
+ if (!propertyValue) continue;
377
+ const rawValues = propertyValue.split(' ');
378
+ for (const rawValue of rawValues){
379
+ if (this.css.animations.has(rawValue)) {
380
+ if (!this.animationNames) {
381
+ this.animationNames = new Set([
382
+ rawValue
383
+ ]);
384
+ } else {
385
+ this.animationNames.add(rawValue);
386
+ }
520
387
  continue;
521
388
  }
522
389
  }
523
- let prefixText = '';
524
- if (this.direction) {
525
- prefixText += '[dir=' + this.direction + '] ';
526
- }
527
- const prefixTexts = prefixSelectors ? prefixSelectors.map((eachPrefixSelector)=>eachPrefixSelector + prefixText) : [
528
- prefixText
529
- ];
530
- const getCssText = (name)=>prefixTexts.map((eachPrefixText)=>{
531
- let modePrefix = '';
532
- if (this.mode) {
533
- const modeSelector = this.css.getModeSelector(this.mode);
534
- if (modeSelector) {
535
- modePrefix = modeSelector + ' ';
536
- }
537
- }
538
- return modePrefix + (scope ? scope + ' ' : '') + eachPrefixText;
539
- }).reduce((arr, eachPrefixText)=>{
540
- arr.push(suffixSelectors ? suffixSelectors.reduce((_arr, eachSuffixSelector)=>{
541
- _arr.push(eachPrefixText + '.' + cssEscape(name) + eachSuffixSelector);
542
- return _arr;
543
- }, []).join(',') : eachPrefixText + '.' + cssEscape(name));
544
- return arr;
545
- }, []).join(',');
546
- const selectorText = getCssText(fixedClass ?? name);
547
- let cssText = selectorText + '{' + propertiesText.join(';') + '}';
548
- for (const key of Object.keys(this.at).sort((_a, b)=>b === 'supports' ? -1 : 1)){
549
- cssText = '@' + key + (key.includes(' ') ? '' : ' ') + this.at[key].map((eachAtComponent)=>this.resolveAtComponent(eachAtComponent)).join(' ') + '{' + cssText + '}';
550
- }
551
- if (this.mode && modes?.[this.mode] === 'media') {
552
- cssText = `@media(prefers-color-scheme:${this.mode}){` + cssText + '}';
553
- }
554
- const node = {
555
- text: cssText,
556
- selectorText
557
- };
558
- if (prefixSelectors) node.prefixSelectors = prefixSelectors;
559
- if (suffixSelectors) node.suffixSelectors = suffixSelectors;
560
- this.nodes.push(node);
561
390
  }
562
391
  }
392
+ this.priority = calcRulePriority(this);
563
393
  }
564
- if (this.fixedClass) {
565
- this.layer = css.componentsLayer;
394
+ }
395
+ get text() {
396
+ if (!this.valid) return '';
397
+ const propertiesText = [];
398
+ for(const propertyName in this.declarations){
399
+ const propertyValue = this.declarations[propertyName];
400
+ const propertyText = propertyName + ':' + String(propertyValue);
401
+ propertiesText.push(propertyText + ((this.important || this.css.config.important) && !propertyText.endsWith('!important') ? '!important' : ''));
566
402
  }
403
+ let text = this.selectorText + '{' + propertiesText.join(';') + '}';
404
+ if (this.atRules !== undefined) AT_IDENTIFIERS.forEach((id)=>{
405
+ const nodes = this.atRules?.[id];
406
+ if (!nodes) return;
407
+ text = generateAt({
408
+ id,
409
+ nodes
410
+ }) + '{' + text + '}';
411
+ });
412
+ return text;
567
413
  }
568
- resolveAtComponent(atComponent) {
569
- switch(atComponent.type){
570
- case 'arbitrary':
571
- return atComponent.value;
572
- case 'feature':
573
- return '(' + atComponent.name + ':' + atComponent.value + (atComponent.unit || '') + ')';
574
- case 'operator':
575
- return atComponent.value;
414
+ get selectorText() {
415
+ let pre = '';
416
+ if (this.css.config.scope) {
417
+ pre = this.css.config.scope + ' ' + pre;
576
418
  }
419
+ if (this.mode) {
420
+ const modeSelector = this.css.getModeSelector(this.mode);
421
+ if (modeSelector) {
422
+ pre = modeSelector + ' ' + pre;
423
+ }
424
+ }
425
+ const body = pre + '.' + cssEscape(this.fixedClass ?? this.name);
426
+ return this.selectorNodes ? generateSelector(this.selectorNodes, body) : body;
577
427
  }
578
428
  resolveValue;
579
429
  parseValues;
580
430
  parseValue(token, unit = this.definition.unit) {
581
- const defaultUnit = unit ?? this.definition.unit;
582
- let newUnit = '';
583
- let value;
584
- if (typeof token === 'number') {
585
- /**
586
- * 當無單位值且 defaultUnit === 'rem',
587
- * 將 pxValue / 16 轉為 remValue
588
- */ if (defaultUnit && !newUnit) {
589
- if (defaultUnit === 'rem' || defaultUnit === 'em') {
590
- value = token / (this.css.config.rootSize || 1);
591
- }
592
- newUnit = defaultUnit || '';
593
- } else {
594
- value = token;
595
- }
596
- return {
597
- value,
598
- unit: newUnit,
599
- type: 'number'
600
- };
601
- } else if (defaultUnit) {
602
- // w:1/2 -> width: 50%
603
- if (/^\d+\/\d+/.test(token)) {
604
- const [dividend, divisor] = token.split('/');
431
+ const parsed = parseValue(token, unit, this.css.config.rootSize);
432
+ // exclude like `aspect:1/2` from being parsed as 50%
433
+ if (this.definition.unit && parsed.type === 'string') {
434
+ // 1/2 → 50%
435
+ if (/^\d+\/\d+$/.test(parsed.value)) {
436
+ const [numerator, denominator] = parsed.value.split('/').map(Number);
605
437
  return {
606
- value: +dividend / +divisor * 100,
438
+ token,
439
+ value: numerator / denominator * 100,
607
440
  unit: '%',
608
441
  type: 'number'
609
442
  };
610
443
  }
611
- const matches = token.match(UNIT_REGEX);
612
- // ['0.5deg', '0.5', 'deg', index: 0, input: '0.5deg', groups: undefined]
613
- if (matches) {
614
- value = +matches[1];
615
- newUnit = matches[3] || '';
616
- /**
617
- * 當無單位值且 defaultUnit === 'rem',
618
- * 將 pxValue / 16 轉為 remValue
619
- */ if (!newUnit) {
620
- if (defaultUnit === 'rem' || defaultUnit === 'em') {
621
- value = value / (this.css.config.rootSize || 1);
622
- }
623
- newUnit = defaultUnit || '';
624
- }
625
- return {
626
- value,
627
- unit: newUnit,
628
- type: 'number'
629
- };
630
- }
631
444
  }
632
- return {
633
- value: token,
634
- type: 'string'
635
- };
445
+ return parsed;
636
446
  }
637
447
  get key() {
638
448
  return (this.fixedClass ? this.fixedClass + ' ' : '') + this.name;
@@ -1 +1,3 @@
1
+ import SyntaxRuleType from '../syntax-rule-type';
1
2
  export type Vendors = 'webkit' | 'moz' | 'ms' | 'o';
3
+ export type SyntaxRuleTypeValue = typeof SyntaxRuleType[keyof typeof SyntaxRuleType];
@@ -1,10 +1,11 @@
1
1
  import type { PropertiesHyphen } from 'csstype';
2
- import type SyntaxRuleType from '../syntax-rule-type';
3
2
  import type { SyntaxRule } from '../syntax-rule';
4
3
  import type { ValueComponent } from './syntax';
5
4
  import type { rules, utilities } from '../config';
5
+ import { AT_IDENTIFIERS } from '../common';
6
+ import { SyntaxRuleTypeValue } from './common';
6
7
  export interface SyntaxRuleDefinition {
7
- type?: SyntaxRuleType;
8
+ type?: SyntaxRuleTypeValue;
8
9
  matcher?: RegExp;
9
10
  sign?: string;
10
11
  key?: string;
@@ -30,13 +31,16 @@ export type VariableDefinition = {
30
31
  } | VariableValue;
31
32
  export type CSSKeyframes = Record<'from' | 'to' | string, PropertiesHyphen>;
32
33
  export type AnimationDefinitions = Record<string, CSSKeyframes>;
33
- export type SelectorDefinitions = Record<string, string | string[]>;
34
+ export type SelectorDefinitions = Record<string, string>;
35
+ export type AtIdentifier = typeof AT_IDENTIFIERS[number];
36
+ export type AtDefinition = number | string;
34
37
  export interface AtDefinitions {
35
- [key: string]: number | string | AtDefinitions;
38
+ [key: string]: AtDefinition | AtDefinitions;
36
39
  }
37
- export interface StyleDefinitions {
38
- [key: string]: string | StyleDefinitions;
40
+ export interface ComponentDefinitions {
41
+ [key: string]: string | ComponentDefinitions;
39
42
  }
43
+ export type ScreenDefinitions = Record<string, number>;
40
44
  export type SyntaxRuleDefinitions = Partial<Record<keyof typeof rules | string, SyntaxRuleDefinition>>;
41
45
  export type VariableDefinitions = {
42
46
  [key in keyof typeof rules]?: VariableDefinition;
@@ -52,12 +56,13 @@ export interface FunctionDefinition {
52
56
  export type FunctionDefinitions = Record<string, FunctionDefinition>;
53
57
  export interface Config {
54
58
  extends?: (Config | any)[];
55
- components?: StyleDefinitions;
59
+ components?: ComponentDefinitions;
56
60
  at?: AtDefinitions;
57
61
  selectors?: SelectorDefinitions;
58
62
  utilities?: UtilityDefinitions;
59
63
  variables?: VariableDefinitions;
60
64
  rules?: SyntaxRuleDefinitions;
65
+ screens?: ScreenDefinitions;
61
66
  rootSize?: number;
62
67
  baseUnit?: number;
63
68
  defaultMode?: 'light' | 'dark' | string | false;
@@ -1,31 +1,12 @@
1
1
  import { SyntaxRuleDefinition } from './config';
2
- export type AtComponent = AtArbitraryComponent | AtFeatureComponent | AtOperatorComponent;
3
- export interface AtArbitraryComponent {
4
- type: 'arbitrary';
5
- token?: string;
6
- value: string;
7
- }
8
- export interface AtFeatureComponent {
9
- type: 'feature';
10
- token?: string;
11
- name: string;
12
- valueType: 'number' | 'string';
13
- value: string | number;
14
- unit?: string;
15
- }
16
- export interface AtOperatorComponent {
17
- type: 'operator';
18
- token: '&';
19
- value: 'and';
20
- }
21
- export type ValueComponent = StringValueComponent | NumericValueComponent | FunctionValueComponent | VariableValueComponent | SeparatorValueComponent;
2
+ export type ValueComponent = StringValueComponent | NumberValueComponent | FunctionValueComponent | VariableValueComponent | SeparatorValueComponent;
22
3
  export interface StringValueComponent {
23
4
  text?: string;
24
5
  token: string;
25
6
  type: 'string';
26
7
  value: string;
27
8
  }
28
- export interface NumericValueComponent {
9
+ export interface NumberValueComponent {
29
10
  text?: string;
30
11
  token: string;
31
12
  type: 'number';
@@ -86,7 +67,7 @@ type VariableCommon = {
86
67
  group?: string;
87
68
  name: string;
88
69
  key: string;
89
- modes?: Record<string, TypeVariable>;
70
+ modes?: Record<string, LiteralVariable>;
90
71
  };
91
72
  export interface StringVariable {
92
73
  type: 'string';
@@ -101,6 +82,6 @@ export interface ColorVariable {
101
82
  value: string;
102
83
  space: 'rgb' | 'hsl';
103
84
  }
104
- export type TypeVariable = StringVariable | NumberVariable | ColorVariable;
105
- export type Variable = TypeVariable & VariableCommon;
85
+ export type LiteralVariable = StringVariable | NumberVariable | ColorVariable;
86
+ export type Variable = LiteralVariable & VariableCommon;
106
87
  export {};