@master/css 2.0.0-rc.61 → 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 (125) 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 +25 -13
  15. package/dist/config/rules.d.ts +4 -2
  16. package/dist/config/rules.mjs +25 -13
  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 +13 -4
  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 +116 -328
  50. package/dist/syntax-rule.d.ts +18 -25
  51. package/dist/syntax-rule.mjs +117 -329
  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/rule-node.cjs +0 -18
  107. package/dist/rule-node.d.ts +0 -14
  108. package/dist/rule-node.mjs +0 -16
  109. package/dist/utils/are-rule-at-equal.cjs +0 -12
  110. package/dist/utils/are-rule-at-equal.d.ts +0 -2
  111. package/dist/utils/are-rule-at-equal.mjs +0 -10
  112. package/dist/utils/are-rule-modes-equal.cjs +0 -7
  113. package/dist/utils/are-rule-modes-equal.d.ts +0 -2
  114. package/dist/utils/are-rule-modes-equal.mjs +0 -5
  115. package/dist/utils/are-rule-selectors-equal.cjs +0 -29
  116. package/dist/utils/are-rule-selectors-equal.d.ts +0 -2
  117. package/dist/utils/are-rule-selectors-equal.mjs +0 -27
  118. package/dist/utils/are-rule-states-equal.cjs +0 -11
  119. package/dist/utils/are-rule-states-equal.d.ts +0 -2
  120. package/dist/utils/are-rule-states-equal.mjs +0 -9
  121. package/dist/utils/are-rules-duplicated.cjs +0 -17
  122. package/dist/utils/are-rules-duplicated.d.ts +0 -2
  123. package/dist/utils/are-rules-duplicated.mjs +0 -15
  124. package/dist/utils/reorder-for-readable-classes.cjs +0 -62
  125. package/dist/utils/reorder-for-readable-classes.mjs +0 -60
@@ -1,27 +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
- layerAtComponents;
12
- supportsAtComponents;
13
- mediaAtComponents;
14
- containerAtComponents;
16
+ native;
17
+ atRules;
15
18
  priority;
16
- order;
17
19
  type;
18
20
  declarations;
19
21
  layer;
20
- supportUnknown;
22
+ valid;
21
23
  animationNames;
22
24
  variableNames;
23
25
  constructor(name, css, registeredSyntax, fixedClass, mode){
24
- super(name), this.name = name, this.css = css, this.registeredSyntax = registeredSyntax, this.fixedClass = fixedClass, 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)=>{
25
33
  const { functions } = this.css.config;
26
34
  let currentValue = '';
27
35
  for (const eachValueComponent of valueComponents){
@@ -47,11 +55,12 @@ class SyntaxRule extends Rule {
47
55
  normalHandler(themeVariable);
48
56
  }
49
57
  } else {
50
- if (!this.variableNames) {
51
- this.variableNames = [];
52
- }
53
- if (!this.variableNames.includes(eachValueComponent.name)) {
54
- 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
+ ]);
55
64
  }
56
65
  varHandler();
57
66
  }
@@ -112,7 +121,8 @@ class SyntaxRule extends Rule {
112
121
  }
113
122
  }
114
123
  return currentValue;
115
- }, this.parseValues = (currentValueComponents, i, value, unit, endSymbol, parentFunctionName, bypassParsing = false, bypassVariableNames = [])=>{
124
+ };
125
+ this.parseValues = (currentValueComponents, i, value, unit, endSymbol, parentFunctionName, bypassParsing = false, bypassVariableNames = [])=>{
116
126
  const root = parentFunctionName === undefined;
117
127
  const isVarFunction = !root && (parentFunctionName.endsWith('$') || parentFunctionName.endsWith('var'));
118
128
  const checkIsString = (value)=>value === '\'' || value === '"';
@@ -166,8 +176,9 @@ class SyntaxRule extends Rule {
166
176
  token: currentValue
167
177
  });
168
178
  } else {
179
+ const parsedValue = this.parseValue(currentValue, unit);
169
180
  currentValueComponents.push({
170
- ...this.parseValue(currentValue, unit),
181
+ ...parsedValue,
171
182
  token: currentValue
172
183
  });
173
184
  }
@@ -257,20 +268,17 @@ class SyntaxRule extends Rule {
257
268
  const { id, definition } = registeredSyntax;
258
269
  const { analyze, transformValue, declare, transformValueComponents, create, type, unit } = definition;
259
270
  this.type = type;
260
- const { scope, important, modes } = css.config;
261
- const { at, animations } = css;
262
271
  if (create) create.call(this, name);
263
272
  // 1. value / selectorToken
264
273
  this.declarations = definition.declarations;
265
274
  let stateToken;
266
- let prefixToken;
267
275
  if (this.type === SyntaxRuleType.Utility) {
268
276
  // TODO: id 使用其他方式傳遞
269
277
  stateToken = name.slice(id.length - 1);
270
278
  } else {
271
279
  let valueToken;
272
280
  if (analyze) {
273
- [valueToken, prefixToken] = analyze.call(this, name);
281
+ [valueToken] = analyze.call(this, name);
274
282
  } else {
275
283
  const indexOfColon = name.indexOf(':');
276
284
  this.keyToken = name.slice(0, indexOfColon + 1);
@@ -287,222 +295,57 @@ class SyntaxRule extends Rule {
287
295
  stateToken = stateToken.slice(1);
288
296
  }
289
297
  this.stateToken = stateToken;
290
- // 3. prefix selector
291
- if (prefixToken) {
292
- this.vendorPrefixSelectors = css.generateVendorSelectors(prefixToken);
293
- }
294
298
  // 4. suffix selector
295
299
  const stateTokens = stateToken.split('@');
296
300
  const suffixSelector = stateTokens[0];
297
301
  if (suffixSelector) {
298
- this.vendorSuffixSelectors = css.generateVendorSelectors(suffixSelector);
299
- for (const suffixSelectors of Object.values(this.vendorSuffixSelectors)){
300
- for (const eachSuffixSelector of suffixSelectors){
301
- const SORTED_SELECTORS = [
302
- ':disabled',
303
- ':active',
304
- ':focus',
305
- ':hover'
306
- ];
307
- for(let i = 0; i < SORTED_SELECTORS.length; i++){
308
- if (eachSuffixSelector.includes(SORTED_SELECTORS[i])) {
309
- if (this.priority === -1 || this.priority > i) {
310
- this.priority = i;
311
- }
312
- break;
313
- }
314
- }
315
- }
316
- }
317
- }
318
- // selector combinations
319
- const suffixSelectorVendorsByPrefixSelectorVendor = {};
320
- if (this.vendorPrefixSelectors) {
321
- if (this.vendorSuffixSelectors) {
322
- for(const prefixSelectorVendor in this.vendorPrefixSelectors){
323
- const suffixSelectorVendors = suffixSelectorVendorsByPrefixSelectorVendor[prefixSelectorVendor] = [];
324
- if (Object.prototype.hasOwnProperty.call(this.vendorSuffixSelectors, prefixSelectorVendor)) {
325
- suffixSelectorVendors.push(prefixSelectorVendor);
326
- } else {
327
- for(const suffixVendor in this.vendorSuffixSelectors){
328
- suffixSelectorVendors.push(suffixVendor);
329
- }
330
- }
331
- }
332
- } else {
333
- for(const vendor in this.vendorPrefixSelectors){
334
- suffixSelectorVendorsByPrefixSelectorVendor[vendor] = [
335
- ''
336
- ];
337
- }
338
- }
339
- } else {
340
- suffixSelectorVendorsByPrefixSelectorVendor[''] = this.vendorSuffixSelectors ? Object.keys(this.vendorSuffixSelectors) : [
341
- ''
342
- ];
302
+ this.selectorNodes = parseSelector(suffixSelector, css);
343
303
  }
344
304
  // 5. atTokens
345
305
  for(let i = 1; i < stateTokens.length; i++){
346
306
  const atToken = stateTokens[i];
307
+ if (css.config.modes?.[atToken]) {
308
+ this.mode = atToken;
309
+ continue;
310
+ }
347
311
  this.atToken = (this.atToken || '') + '@' + atToken;
348
- if (atToken) {
349
- if (atToken === 'base' || atToken === 'preset') {
350
- const atComponent = {
351
- type: 'arbitrary',
352
- value: atToken
353
- };
354
- if (this.layerAtComponents) {
355
- this.layerAtComponents.push(atComponent);
356
- } else {
357
- this.layerAtComponents = [
358
- atComponent
359
- ];
360
- }
361
- continue;
362
- } else if (atToken === 'rtl' || atToken === 'ltr') {
363
- this.direction = atToken;
364
- } else {
365
- let queryType;
366
- const atComponents = [];
367
- // x font-face, counter-style, keyframes, font-feature-values, property, layer
368
- const queryTypeRegExp = /^(media|supports|container|layer)/;
369
- const atRuleResult = queryTypeRegExp.exec(atToken);
370
- if (atRuleResult) {
371
- queryType = atRuleResult[1];
372
- atComponents.push({
373
- type: 'arbitrary',
374
- token: atToken,
375
- value: atToken.slice(queryType.length).replace(/\|/g, ' ')
376
- });
377
- } else {
378
- const analyzeToken = (atComponentToken)=>{
379
- if (atComponentToken === '&') {
380
- atComponents.push({
381
- type: 'operator',
382
- token: atComponentToken,
383
- value: 'and'
384
- });
385
- } else if (atComponentToken.startsWith('')) {
386
- const targetAt = at.get(atComponentToken);
387
- if (typeof targetAt === 'string') {
388
- const match = targetAt.match(queryTypeRegExp);
389
- queryType = match ? match[1] : '';
390
- if (!queryType) throw new Error(`Invalid query '${atComponentToken}': '${targetAt}'`);
391
- atComponents.push({
392
- type: 'arbitrary',
393
- value: targetAt.slice(match ? match[1].length + 1 : 0)
394
- });
395
- } else {
396
- // todo: container queries
397
- queryType = 'media';
398
- let featureName = '';
399
- let extremumOperator = '';
400
- let correction = 0;
401
- if (atComponentToken.startsWith('<=')) {
402
- extremumOperator = '<=';
403
- featureName = 'max-width';
404
- } else if (atComponentToken.startsWith('>') && !atComponentToken.startsWith('>=')) {
405
- extremumOperator = '>';
406
- featureName = 'min-width';
407
- correction = .02;
408
- } else if (atComponentToken.startsWith('<')) {
409
- extremumOperator = '<';
410
- featureName = 'max-width';
411
- correction = -0.02;
412
- } else if (atComponentToken.startsWith('>=') || targetAt) {
413
- extremumOperator = '>=';
414
- featureName = 'min-width';
415
- }
416
- const token = extremumOperator ? atComponentToken.replace(extremumOperator, '') : atComponentToken;
417
- const viewport = at.get(token);
418
- switch(featureName){
419
- case 'max-width':
420
- case 'min-width':
421
- if (typeof viewport === 'number') {
422
- atComponents.push({
423
- type: 'feature',
424
- name: featureName,
425
- valueType: 'number',
426
- value: viewport + correction,
427
- unit: 'px'
428
- });
429
- } else {
430
- const valueComponent = this.parseValue(token, 'px');
431
- if (valueComponent.type === 'number') {
432
- atComponents.push({
433
- type: 'feature',
434
- name: featureName,
435
- valueType: 'number',
436
- value: valueComponent.value + correction,
437
- unit: valueComponent.unit
438
- });
439
- } else {
440
- atComponents.push({
441
- type: 'feature',
442
- name: featureName,
443
- valueType: 'string',
444
- value: token
445
- });
446
- }
447
- }
448
- break;
449
- }
450
- }
451
- }
452
- };
453
- const isAmpersandIncluded = atToken.includes('&');
454
- if (isAmpersandIncluded) {
455
- const typeOrFeatureTokens = atToken.split(/(&|,)/);
456
- for (const atComponentToken of typeOrFeatureTokens){
457
- analyzeToken(atComponentToken);
458
- }
459
- } else {
460
- analyzeToken(atToken);
461
- }
462
- if (!atComponents.length) {
463
- if (!isAmpersandIncluded && modes?.[atToken]) {
464
- this.mode = atToken;
465
- continue;
466
- }
467
- }
468
- }
469
- if (queryType) {
470
- const targetAtComponents = this[`${queryType}AtComponents`];
471
- if (targetAtComponents) {
472
- targetAtComponents.push(...atComponents);
473
- } else {
474
- this[`${queryType}AtComponents`] = atComponents;
475
- }
476
- }
477
- }
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
+ };
478
321
  }
479
322
  }
480
- if (this.mode && modes?.[this.mode] === 'media') {
481
- const atFeatureComponent = {
482
- type: 'feature',
323
+ if (this.mode && css.config.modes?.[this.mode] === 'media') {
324
+ const atComp = {
483
325
  name: 'prefers-color-scheme',
484
- valueType: 'string',
485
326
  value: this.mode
486
327
  };
487
- if (this.mediaAtComponents) {
488
- this.mediaAtComponents.push(atFeatureComponent);
328
+ if (this.atRules?.media) {
329
+ this.atRules.media.push(atComp);
489
330
  } else {
490
- this.mediaAtComponents = [
491
- atFeatureComponent
492
- ];
331
+ this.atRules = {
332
+ media: [
333
+ atComp
334
+ ]
335
+ };
493
336
  }
494
337
  }
495
338
  if (this.fixedClass) {
496
339
  this.layer = css.componentsLayer;
497
340
  } else {
498
- const onlyLayerComponent = this.layerAtComponents?.length === 1 && this.layerAtComponents[0];
499
- if (onlyLayerComponent) {
500
- if (onlyLayerComponent.value === 'base') {
341
+ const onlyNode = this.atRules?.layer?.length === 1 && this.atRules.layer[0];
342
+ if (onlyNode) {
343
+ if (onlyNode.value === 'base') {
501
344
  this.layer = css.baseLayer;
502
- this.layerAtComponents = undefined;
503
- } else if (onlyLayerComponent.value === 'preset') {
345
+ this.atRules.layer = undefined;
346
+ } else if (onlyNode.value === 'preset') {
504
347
  this.layer = css.presetLayer;
505
- this.layerAtComponents = undefined;
348
+ this.atRules.layer = undefined;
506
349
  }
507
350
  }
508
351
  }
@@ -524,137 +367,82 @@ class SyntaxRule extends Rule {
524
367
  };
525
368
  }
526
369
  }
527
- const propertiesText = [];
528
- for(const propertyName in this.declarations){
529
- const propertyValue = this.declarations[propertyName];
530
- const propertyText = propertyName + ':' + String(propertyValue);
531
- if (animations && (propertyText.startsWith('animation') || propertyText.startsWith('animation-name'))) {
532
- const animationNames = propertyText.split(':')[1].split('!important')[0].split(' ').filter((eachValue)=>this.css.animations.has(eachValue) && (!this.animationNames || !this.animationNames.includes(eachValue)));
533
- if (animationNames.length) {
534
- if (!this.animationNames) {
535
- this.animationNames = [];
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
+ }
387
+ continue;
388
+ }
536
389
  }
537
- this.animationNames = animationNames;
538
390
  }
539
391
  }
540
- propertiesText.push(propertyText + ((this.important || important) && !propertyText.endsWith('!important') ? '!important' : ''));
392
+ this.priority = calcRulePriority(this);
541
393
  }
542
- // 創建 Natives
543
- if (propertiesText.length) {
544
- for(const prefixSelectorVendor in suffixSelectorVendorsByPrefixSelectorVendor){
545
- for (const eachSuffixSelectorVendor of suffixSelectorVendorsByPrefixSelectorVendor[prefixSelectorVendor]){
546
- const prefixSelectors = this.vendorPrefixSelectors?.[prefixSelectorVendor];
547
- const suffixSelectors = this.vendorSuffixSelectors?.[eachSuffixSelectorVendor];
548
- let prefixText = '';
549
- if (this.direction) {
550
- prefixText += '[dir=' + this.direction + '] ';
551
- }
552
- const prefixTexts = prefixSelectors ? prefixSelectors.map((eachPrefixSelector)=>eachPrefixSelector + prefixText) : [
553
- prefixText
554
- ];
555
- const getCssText = (name)=>prefixTexts.map((eachPrefixText)=>{
556
- let modePrefix = '';
557
- if (this.mode) {
558
- const modeSelector = this.css.getModeSelector(this.mode);
559
- if (modeSelector) {
560
- modePrefix = modeSelector + ' ';
561
- }
562
- }
563
- return modePrefix + (scope ? scope + ' ' : '') + eachPrefixText;
564
- }).reduce((arr, eachPrefixText)=>{
565
- arr.push(suffixSelectors ? suffixSelectors.reduce((_arr, eachSuffixSelector)=>{
566
- _arr.push(eachPrefixText + '.' + cssEscape(name) + eachSuffixSelector);
567
- return _arr;
568
- }, []).join(',') : eachPrefixText + '.' + cssEscape(name));
569
- return arr;
570
- }, []).join(',');
571
- const selectorText = getCssText(fixedClass ?? name);
572
- let cssText = selectorText + '{' + propertiesText.join(';') + '}';
573
- const resolveAtComponents = (atComponents, separator)=>atComponents.map((atComponent, i)=>{
574
- const value = this.resolveAtComponent(atComponent);
575
- return (i === 0 ? value.charAt(0) !== '(' ? ' ' : '' : '') + value;
576
- }).join(separator) + '{' + cssText + '}';
577
- if (this.containerAtComponents) cssText = '@container' + resolveAtComponents(this.containerAtComponents, ' ');
578
- if (this.mediaAtComponents) cssText = '@media' + resolveAtComponents(this.mediaAtComponents, ' ');
579
- if (this.supportsAtComponents) cssText = '@supports' + resolveAtComponents(this.supportsAtComponents, ' ');
580
- if (this.layerAtComponents) cssText = '@layer' + resolveAtComponents(this.layerAtComponents, '.');
581
- const node = {
582
- text: cssText,
583
- selectorText
584
- };
585
- if (prefixSelectors) node.prefixSelectors = prefixSelectors;
586
- if (suffixSelectors) node.suffixSelectors = suffixSelectors;
587
- this.nodes.push(node);
588
- }
589
- }
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' : ''));
590
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;
591
413
  }
592
- resolveAtComponent(atComponent) {
593
- switch(atComponent.type){
594
- case 'feature':
595
- return '(' + atComponent.name + ':' + atComponent.value + (atComponent.unit || '') + ')';
596
- default:
597
- return atComponent.value;
414
+ get selectorText() {
415
+ let pre = '';
416
+ if (this.css.config.scope) {
417
+ pre = this.css.config.scope + ' ' + pre;
418
+ }
419
+ if (this.mode) {
420
+ const modeSelector = this.css.getModeSelector(this.mode);
421
+ if (modeSelector) {
422
+ pre = modeSelector + ' ' + pre;
423
+ }
598
424
  }
425
+ const body = pre + '.' + cssEscape(this.fixedClass ?? this.name);
426
+ return this.selectorNodes ? generateSelector(this.selectorNodes, body) : body;
599
427
  }
600
428
  resolveValue;
601
429
  parseValues;
602
430
  parseValue(token, unit = this.definition.unit) {
603
- const defaultUnit = unit ?? this.definition.unit;
604
- let newUnit = '';
605
- let value;
606
- if (typeof token === 'number') {
607
- /**
608
- * 當無單位值且 defaultUnit === 'rem',
609
- * 將 pxValue / 16 轉為 remValue
610
- */ if (defaultUnit && !newUnit) {
611
- if (defaultUnit === 'rem' || defaultUnit === 'em') {
612
- value = token / (this.css.config.rootSize || 1);
613
- }
614
- newUnit = defaultUnit || '';
615
- } else {
616
- value = token;
617
- }
618
- return {
619
- value,
620
- unit: newUnit,
621
- type: 'number'
622
- };
623
- } else if (defaultUnit) {
624
- // w:1/2 -> width: 50%
625
- if (/^\d+\/\d+/.test(token)) {
626
- 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);
627
437
  return {
628
- value: +dividend / +divisor * 100,
438
+ token,
439
+ value: numerator / denominator * 100,
629
440
  unit: '%',
630
441
  type: 'number'
631
442
  };
632
443
  }
633
- const matches = token.match(UNIT_REGEX);
634
- // ['0.5deg', '0.5', 'deg', index: 0, input: '0.5deg', groups: undefined]
635
- if (matches) {
636
- value = +matches[1];
637
- newUnit = matches[3] || '';
638
- /**
639
- * 當無單位值且 defaultUnit === 'rem',
640
- * 將 pxValue / 16 轉為 remValue
641
- */ if (!newUnit) {
642
- if (defaultUnit === 'rem' || defaultUnit === 'em') {
643
- value = value / (this.css.config.rootSize || 1);
644
- }
645
- newUnit = defaultUnit || '';
646
- }
647
- return {
648
- value,
649
- unit: newUnit,
650
- type: 'number'
651
- };
652
- }
653
444
  }
654
- return {
655
- value: token,
656
- type: 'string'
657
- };
445
+ return parsed;
658
446
  }
659
447
  get key() {
660
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 interface AtArbitraryComponent {
3
- type: 'arbitrary';
4
- token?: string;
5
- value: string;
6
- }
7
- export interface AtFeatureComponent {
8
- type: 'feature';
9
- token?: string;
10
- name: string;
11
- valueType: 'number' | 'string';
12
- value: string | number;
13
- unit?: string;
14
- }
15
- export interface AtOperatorComponent {
16
- type: 'operator';
17
- token: '&';
18
- value: 'and';
19
- }
20
- export type AtComponent = AtArbitraryComponent | AtFeatureComponent | AtOperatorComponent;
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 {};