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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/dist/common.cjs +1 -1
  2. package/dist/common.mjs +1 -1
  3. package/dist/config/functions.d.ts +1 -1
  4. package/dist/config/index.cjs +3 -3
  5. package/dist/config/index.d.ts +3 -48
  6. package/dist/config/index.mjs +3 -3
  7. package/dist/config/modes.d.ts +1 -1
  8. package/dist/config/{syntaxes.cjs → rules.cjs} +282 -282
  9. package/dist/config/rules.d.ts +282 -0
  10. package/dist/config/{syntaxes.mjs → rules.mjs} +282 -282
  11. package/dist/core.cjs +225 -607
  12. package/dist/core.d.ts +36 -67
  13. package/dist/core.mjs +225 -607
  14. package/dist/index.cjs +14 -6
  15. package/dist/index.d.ts +8 -4
  16. package/dist/index.mjs +7 -3
  17. package/dist/layer.cjs +107 -23
  18. package/dist/layer.d.ts +13 -27
  19. package/dist/layer.mjs +107 -23
  20. package/dist/non-layer.cjs +65 -0
  21. package/dist/non-layer.d.ts +12 -0
  22. package/dist/non-layer.mjs +63 -0
  23. package/dist/rule.cjs +8 -708
  24. package/dist/rule.d.ts +6 -147
  25. package/dist/rule.mjs +8 -708
  26. package/dist/shared/utils/find-native-css-rule-index.cjs +12 -0
  27. package/dist/shared/utils/find-native-css-rule-index.mjs +10 -0
  28. package/dist/syntax-layer.cjs +291 -0
  29. package/dist/syntax-layer.d.ts +17 -0
  30. package/dist/syntax-layer.mjs +289 -0
  31. package/dist/syntax-rule-type.cjs +27 -0
  32. package/dist/syntax-rule-type.d.ts +28 -0
  33. package/dist/syntax-rule-type.mjs +25 -0
  34. package/dist/syntax-rule.cjs +717 -0
  35. package/dist/syntax-rule.d.ts +47 -0
  36. package/dist/syntax-rule.mjs +715 -0
  37. package/dist/types/config.cjs +2 -0
  38. package/dist/types/config.d.ts +70 -0
  39. package/dist/types/config.mjs +1 -0
  40. package/dist/types/syntax.cjs +2 -0
  41. package/dist/types/syntax.d.ts +106 -0
  42. package/dist/types/syntax.mjs +1 -0
  43. package/dist/utils/are-rule-at-equal.cjs +7 -7
  44. package/dist/utils/are-rule-at-equal.d.ts +2 -2
  45. package/dist/utils/are-rule-at-equal.mjs +7 -7
  46. package/dist/utils/are-rule-modes-equal.cjs +2 -2
  47. package/dist/utils/are-rule-modes-equal.d.ts +2 -2
  48. package/dist/utils/are-rule-modes-equal.mjs +2 -2
  49. package/dist/utils/are-rule-selectors-equal.cjs +11 -11
  50. package/dist/utils/are-rule-selectors-equal.d.ts +2 -2
  51. package/dist/utils/are-rule-selectors-equal.mjs +11 -11
  52. package/dist/utils/are-rule-states-equal.cjs +2 -2
  53. package/dist/utils/are-rule-states-equal.d.ts +2 -2
  54. package/dist/utils/are-rule-states-equal.mjs +2 -2
  55. package/dist/utils/are-rules-duplicated.cjs +17 -0
  56. package/dist/utils/are-rules-duplicated.d.ts +2 -0
  57. package/dist/utils/are-rules-duplicated.mjs +15 -0
  58. package/dist/utils/autofill-solid-style.d.ts +2 -2
  59. package/dist/utils/extend-config.cjs +5 -5
  60. package/dist/utils/extend-config.d.ts +1 -1
  61. package/dist/utils/extend-config.mjs +5 -5
  62. package/dist/utils/generate-css.cjs +1 -1
  63. package/dist/utils/generate-css.mjs +1 -1
  64. package/dist/utils/is-core-rule.cjs +2 -2
  65. package/dist/utils/is-core-rule.mjs +2 -2
  66. package/dist/utils/reorder-for-readable-classes.cjs +11 -11
  67. package/dist/utils/reorder-for-readable-classes.mjs +11 -11
  68. package/package.json +1 -1
  69. package/dist/config/syntaxes.d.ts +0 -282
  70. package/dist/utils/are-syntaxes-duplicated.cjs +0 -17
  71. package/dist/utils/are-syntaxes-duplicated.d.ts +0 -2
  72. package/dist/utils/are-syntaxes-duplicated.mjs +0 -15
package/dist/rule.mjs CHANGED
@@ -1,715 +1,15 @@
1
- import cssEscape from './shared/utils/css-escape.mjs';
2
- import Layer from './layer.mjs';
3
- import { VALUE_DELIMITERS, UNIT_REGEX, BASE_UNIT_REGEX } from './common.mjs';
4
-
5
1
  class Rule {
6
- className;
7
- RegisteredRule;
8
- css;
9
- at;
10
- priority;
11
- natives;
12
- order;
13
- layer;
14
- declarations;
15
- animationNames;
16
- variableNames;
17
- constructor(className, RegisteredRule, css){
18
- this.className = className;
19
- this.RegisteredRule = RegisteredRule;
20
- this.css = css;
21
- this.at = {};
22
- this.priority = -1;
23
- this.natives = [];
24
- this.order = 0;
25
- this.layer = 0;
26
- this.resolveValue = (valueComponents, unit, bypassVariableNames, bypassParsing)=>{
27
- const { functions } = this.css.config;
28
- let currentValue = '';
29
- for (const eachValueComponent of valueComponents){
30
- switch(eachValueComponent.type){
31
- case 'function':
32
- const functionDefinition = functions && functions[eachValueComponent.name];
33
- if (functionDefinition?.transform && !eachValueComponent.bypassTransform) {
34
- const result = functionDefinition.transform.call(this, this.resolveValue(eachValueComponent.children, functionDefinition.unit ?? unit, bypassVariableNames, bypassParsing || eachValueComponent.name === 'calc'), bypassVariableNames);
35
- currentValue += eachValueComponent.token = eachValueComponent.text = typeof result === 'string' ? result : this.resolveValue(result, functionDefinition?.unit ?? unit, bypassVariableNames, bypassParsing);
36
- } else {
37
- currentValue += eachValueComponent.token = eachValueComponent.text = eachValueComponent.name + eachValueComponent.symbol + this.resolveValue(eachValueComponent.children, functionDefinition?.unit ?? unit, bypassVariableNames, bypassParsing) + VALUE_DELIMITERS[eachValueComponent.symbol];
38
- }
39
- break;
40
- // todo: 應挪到 parseValues 階段處理才能支援 variables: { x: 'calc(20vw-30px)' } 這種情況,並且解析上可能會比較合理、精簡
41
- case 'variable':
42
- const variable = this.css.variables[eachValueComponent.name];
43
- if (variable) {
44
- const handleVariable = (normalHandler, varHandler)=>{
45
- if (variable.modes) {
46
- if (this.mode) {
47
- const themeVariable = variable.modes[this.mode] ?? variable;
48
- if (themeVariable?.value) {
49
- normalHandler(themeVariable);
50
- }
51
- } else {
52
- if (!this.variableNames) {
53
- this.variableNames = [];
54
- }
55
- if (!this.variableNames.includes(eachValueComponent.name)) {
56
- this.variableNames.push(eachValueComponent.name);
57
- }
58
- varHandler();
59
- }
60
- } else {
61
- normalHandler(variable);
62
- }
63
- };
64
- switch(variable.type){
65
- case 'string':
66
- handleVariable((variable)=>{
67
- const valueComponents = [];
68
- this.parseValues(valueComponents, 0, variable.value, unit, '', undefined, bypassParsing, [
69
- ...bypassVariableNames,
70
- eachValueComponent.name
71
- ]);
72
- currentValue += eachValueComponent.text = this.resolveValue(valueComponents, unit, [
73
- ...bypassVariableNames,
74
- eachValueComponent.name
75
- ], bypassParsing);
76
- }, ()=>{
77
- currentValue += eachValueComponent.text = `var(--${eachValueComponent.name})`;
78
- });
79
- break;
80
- case 'number':
81
- handleVariable((variable)=>{
82
- if (bypassParsing) {
83
- currentValue += eachValueComponent.text = String(variable.value);
84
- } else {
85
- const valueComponent = this.parseValue(variable.value, unit);
86
- currentValue += eachValueComponent.text = valueComponent.value + (valueComponent.unit ?? '');
87
- }
88
- }, ()=>{
89
- currentValue += eachValueComponent.text = unit ? `calc(var(--${eachValueComponent.name}) / 16 * 1rem)` : `var(--${eachValueComponent.name})`;
90
- });
91
- break;
92
- case 'color':
93
- const alpha = eachValueComponent.alpha ? '/' + eachValueComponent.alpha : '';
94
- handleVariable((variable)=>{
95
- currentValue += eachValueComponent.text = `${variable['space']}(${variable.value}${alpha})`;
96
- }, ()=>{
97
- currentValue += eachValueComponent.text = `${variable.space}(var(--${eachValueComponent.name})${alpha})`;
98
- });
99
- break;
100
- }
101
- } else {
102
- currentValue += eachValueComponent.text = `var(--${eachValueComponent.name}${eachValueComponent.fallback ? ',' + eachValueComponent.fallback : ''})`;
103
- }
104
- break;
105
- case 'separator':
106
- currentValue += eachValueComponent.text ? eachValueComponent.text : eachValueComponent.text = eachValueComponent.value;
107
- break;
108
- case 'number':
109
- currentValue += eachValueComponent.text = eachValueComponent.value + (eachValueComponent.unit || '');
110
- break;
111
- default:
112
- currentValue += eachValueComponent.text = eachValueComponent.value;
113
- break;
114
- }
115
- }
116
- return currentValue;
117
- };
118
- this.parseValues = (currentValueComponents, i, value, unit, endSymbol, parentFunctionName, bypassParsing = false, bypassVariableNames = [])=>{
119
- const root = parentFunctionName === undefined;
120
- const isVarFunction = !root && (parentFunctionName.endsWith('$') || parentFunctionName.endsWith('var'));
121
- const checkIsString = (value)=>value === '\'' || value === '"';
122
- const isString = checkIsString(endSymbol);
123
- const separators = [
124
- ','
125
- ];
126
- if (this.definition.separators?.length) {
127
- separators.push(...this.definition.separators);
128
- }
129
- let currentValue = '';
130
- const parse = ()=>{
131
- if (currentValue) {
132
- let handled = false;
133
- if (!isVarFunction || currentValueComponents.length) {
134
- const handleVariable = (variableName, alpha)=>{
135
- const variable = Object.prototype.hasOwnProperty.call(this.variables, variableName) ? this.variables[variableName] : Object.prototype.hasOwnProperty.call(this.css.variables, variableName) ? this.css.variables[variableName] : undefined;
136
- if (variable) {
137
- const name = variable.name ?? variableName;
138
- if (!bypassVariableNames.includes(name)) {
139
- handled = true;
140
- const valueComponent = {
141
- type: 'variable',
142
- name,
143
- variable: this.css.variables[name],
144
- token: currentValue
145
- };
146
- if (alpha) valueComponent.alpha = alpha;
147
- currentValueComponents.push(valueComponent);
148
- }
149
- }
150
- };
151
- handleVariable(currentValue);
152
- if (!handled) {
153
- const [colorName, alpha] = currentValue.split('/');
154
- handleVariable(colorName, alpha);
155
- }
156
- }
157
- if (!handled) {
158
- if (!isVarFunction) {
159
- const result = BASE_UNIT_REGEX.exec(currentValue);
160
- if (result) {
161
- currentValue = String(+result[1] * (this.css.config.baseUnit ?? 1));
162
- }
163
- }
164
- if (bypassParsing) {
165
- currentValueComponents.push({
166
- type: 'string',
167
- value: currentValue,
168
- token: currentValue
169
- });
170
- } else {
171
- currentValueComponents.push({
172
- ...this.parseValue(currentValue, unit),
173
- token: currentValue
174
- });
175
- }
176
- }
177
- currentValue = '';
178
- }
179
- };
180
- for(; i < value.length; i++){
181
- const val = value[i];
182
- if (val === endSymbol) {
183
- if (isString) {
184
- let count = 0;
185
- for(let j = currentValue.length - 1;; j--){
186
- if (currentValue[j] !== '\\') break;
187
- count++;
188
- }
189
- if (count % 2) {
190
- currentValue += val;
191
- continue;
192
- } else {
193
- parse();
194
- }
195
- } else {
196
- parse();
197
- }
198
- return i;
199
- } else if (!isString && val in VALUE_DELIMITERS) {
200
- const functionName = currentValue;
201
- const newValueComponent = {
202
- type: 'function',
203
- name: functionName,
204
- symbol: val,
205
- children: [],
206
- token: ''
207
- };
208
- currentValueComponents.push(newValueComponent);
209
- currentValue = '';
210
- const functionDefinition = val === '(' ? this.css.config.functions?.[functionName] : undefined;
211
- i = this.parseValues(newValueComponent.children, ++i, value, functionDefinition?.unit ?? unit, VALUE_DELIMITERS[val], functionName || parentFunctionName || '', bypassParsing || functionName === 'calc');
212
- } else if ((val === '|' || val === ' ') && endSymbol !== '}' && (!isString || parentFunctionName === 'path')) {
213
- parse();
214
- currentValueComponents.push({
215
- type: 'separator',
216
- value: ' ',
217
- token: val
218
- });
219
- } else {
220
- if (!isString) {
221
- if (val === '.') {
222
- if (isNaN(+value[i + 1])) {
223
- if (root) break;
224
- } else if (value[i - 1] === '-') {
225
- currentValue += '0';
226
- }
227
- } else if (separators.includes(val)) {
228
- parse();
229
- currentValueComponents.push({
230
- type: 'separator',
231
- value: val,
232
- text: (val === ',' ? '' : ' ') + val + (val === ',' ? '' : ' '),
233
- token: val
234
- });
235
- continue;
236
- } else if (root && (val === '#' && (currentValue || currentValueComponents.length && currentValueComponents[currentValueComponents.length - 1]['type'] !== 'separator') || [
237
- '!',
238
- '*',
239
- '>',
240
- '+',
241
- '~',
242
- ':',
243
- '[',
244
- '@',
245
- '_'
246
- ].includes(val))) {
247
- break;
248
- }
249
- }
250
- currentValue += val;
251
- }
252
- }
253
- parse();
254
- return i;
255
- };
256
- Object.assign(this, RegisteredRule);
257
- const { id, definition } = RegisteredRule;
258
- const { analyze, transformValue, declare, transformValueComponents, create, layer, unit } = definition;
259
- this.layer = layer;
260
- if (!definition.unit) definition.unit = '';
261
- if (!definition.separators) definition.separators = [
262
- ','
263
- ];
264
- const { scope, important, modes } = css.config;
265
- const { selectors, at, stylesBy, animations } = css;
266
- const classNames = stylesBy[className];
267
- if (create) create.call(this, className);
268
- // 1. value / selectorToken
269
- this.declarations = definition.declarations;
270
- let stateToken;
271
- let prefixToken;
272
- if (layer === Layer.Utility) {
273
- // TODO: id 使用其他方式傳遞
274
- stateToken = className.slice(id.length - 1);
275
- } else {
276
- let valueToken;
277
- if (analyze) {
278
- [valueToken, prefixToken] = analyze.call(this, className);
279
- } else {
280
- const indexOfColon = className.indexOf(':');
281
- this.keyToken = className.slice(0, indexOfColon + 1);
282
- valueToken = className.slice(indexOfColon + 1);
283
- }
284
- this.valueComponents = [];
285
- const parsedValueIndex = this.parseValues(this.valueComponents, 0, valueToken, unit, '', undefined, false, definition.includeAnimations ? Object.keys(this.css.animations) : []);
286
- this.valueToken = valueToken.slice(0, parsedValueIndex);
287
- stateToken = valueToken.slice(parsedValueIndex);
288
- }
289
- // 2. !important
290
- if (stateToken[0] === '!') {
291
- this.important = true;
292
- stateToken = stateToken.slice(1);
293
- }
294
- this.stateToken = stateToken;
295
- // 3. prefix selector
296
- const generateVendorSelectors = (selectorText, vendorSelectors)=>{
297
- const transformSelector = (selectorText, selectorValues, selectors, matched)=>{
298
- for (const [regexp, newSelectorTexts] of selectorValues){
299
- if (regexp.test(selectorText)) {
300
- for (const eachNewSelectorText of newSelectorTexts){
301
- transformSelector(selectorText.replace(regexp, eachNewSelectorText), selectorValues, selectors, true);
302
- }
303
- return;
304
- }
305
- }
306
- if (matched) {
307
- selectors.push(selectorText);
308
- }
309
- };
310
- const spacedSelectorToken = (selectorText)=>{
311
- // 1. \'123\'
312
- // 2. [href='http://localhost']
313
- const transformedSelectorText = selectorText.split(/(\\'(?:.*?)[^\\]\\')(?=[*_>~+,)])|(\[[^=]+='(?:.*?)[^\\]'\])/).map((eachToken, i)=>i % 3 ? eachToken : eachToken.replace(/(^|[^_])_(?!_)/g, '$1 ')).join('');
314
- const selectors = [];
315
- let currentSelector = '';
316
- let symbolCount = 0;
317
- for(let i = 0; i < transformedSelectorText.length; i++){
318
- const char = transformedSelectorText[i];
319
- if (char === '\\') {
320
- currentSelector += char + transformedSelectorText[++i];
321
- continue;
322
- }
323
- if (!symbolCount && char === ',') {
324
- selectors.push(currentSelector);
325
- currentSelector = '';
326
- } else {
327
- currentSelector += char;
328
- if (symbolCount && char === ')') {
329
- symbolCount--;
330
- } else if (char === '(') {
331
- symbolCount++;
332
- }
333
- }
334
- }
335
- if (currentSelector) {
336
- selectors.push(currentSelector);
337
- }
338
- return selectors;
339
- };
340
- const transformedSelectors = [];
341
- if ('' in selectors) {
342
- transformSelector(selectorText, selectors[''], transformedSelectors, true);
343
- } else {
344
- transformedSelectors.push(selectorText);
345
- }
346
- const unspacedVendorSelectors = {};
347
- for (const [vendor, selectorValues] of Object.entries(selectors)){
348
- if (!vendor) continue;
349
- const newUnspacedVendorSelectors = [];
350
- for (const eachTransformedSelector of transformedSelectors){
351
- transformSelector(eachTransformedSelector, selectorValues, newUnspacedVendorSelectors, false);
352
- }
353
- if (newUnspacedVendorSelectors.length) {
354
- unspacedVendorSelectors[vendor] = newUnspacedVendorSelectors;
355
- }
356
- }
357
- const insertVendorSelectors = (vendor, selectorTexts)=>{
358
- const groupedSelectorTexts = selectorTexts.reduce((arr, eachSuffixSelector)=>{
359
- arr.push(...spacedSelectorToken(eachSuffixSelector));
360
- return arr;
361
- }, []);
362
- if (vendor in vendorSelectors) {
363
- vendorSelectors[vendor].push(...groupedSelectorTexts);
364
- } else {
365
- vendorSelectors[vendor] = groupedSelectorTexts;
366
- }
367
- };
368
- const vendors = Object.keys(unspacedVendorSelectors);
369
- if (vendors.length) {
370
- for (const eachVendor of vendors){
371
- insertVendorSelectors(eachVendor, unspacedVendorSelectors[eachVendor]);
372
- }
373
- } else {
374
- insertVendorSelectors('', transformedSelectors);
375
- }
376
- };
377
- if (prefixToken) {
378
- this.vendorPrefixSelectors = {};
379
- generateVendorSelectors(prefixToken, this.vendorPrefixSelectors);
380
- } else {
381
- this.vendorPrefixSelectors = {
382
- '': [
383
- ''
384
- ]
385
- };
386
- }
387
- // 4. suffix selector
388
- const stateTokens = stateToken.split('@');
389
- const suffixSelector = stateTokens[0];
390
- if (suffixSelector) {
391
- this.vendorSuffixSelectors = {};
392
- generateVendorSelectors(suffixSelector, this.vendorSuffixSelectors);
393
- for (const suffixSelectors of Object.values(this.vendorSuffixSelectors)){
394
- for (const eachSuffixSelector of suffixSelectors){
395
- if (this.hasWhere !== false) {
396
- this.hasWhere = eachSuffixSelector.includes(':where(');
397
- }
398
- const SORTED_SELECTORS = [
399
- ':disabled',
400
- ':active',
401
- ':focus',
402
- ':hover'
403
- ];
404
- for(let i = 0; i < SORTED_SELECTORS.length; i++){
405
- if (eachSuffixSelector.includes(SORTED_SELECTORS[i])) {
406
- if (this.priority === -1 || this.priority > i) {
407
- this.priority = i;
408
- }
409
- break;
410
- }
411
- }
412
- }
413
- }
414
- } else {
415
- this.vendorSuffixSelectors = {
416
- '': [
417
- ''
418
- ]
419
- };
420
- }
421
- // selector combinations
422
- const suffixSelectorVendorsByPrefixSelectorVendor = {};
423
- const isPrefixSelectorWithoutVendor = Object.prototype.hasOwnProperty.call(this.vendorPrefixSelectors, '');
424
- const isSuffixSelectorWithoutVendor = Object.prototype.hasOwnProperty.call(this.vendorSuffixSelectors, '');
425
- if (isPrefixSelectorWithoutVendor) {
426
- suffixSelectorVendorsByPrefixSelectorVendor[''] = isSuffixSelectorWithoutVendor ? [
427
- ''
428
- ] : Object.keys(this.vendorSuffixSelectors);
429
- } else {
430
- if (isSuffixSelectorWithoutVendor) {
431
- for(const vendor in this.vendorPrefixSelectors){
432
- suffixSelectorVendorsByPrefixSelectorVendor[vendor] = [
433
- ''
434
- ];
435
- }
436
- } else {
437
- for(const prefixSelectorVendor in this.vendorPrefixSelectors){
438
- const suffixSelectorVendors = suffixSelectorVendorsByPrefixSelectorVendor[prefixSelectorVendor] = [];
439
- if (Object.prototype.hasOwnProperty.call(this.vendorSuffixSelectors, prefixSelectorVendor)) {
440
- suffixSelectorVendors.push(prefixSelectorVendor);
441
- } else {
442
- for(const suffixVendor in this.vendorSuffixSelectors){
443
- suffixSelectorVendors.push(suffixVendor);
444
- }
445
- }
446
- }
447
- }
448
- }
449
- // 5. atTokens
450
- for(let i = 1; i < stateTokens.length; i++){
451
- const atToken = stateTokens[i];
452
- this.atToken = (this.atToken || '') + '@' + atToken;
453
- if (atToken) {
454
- if (atToken === 'rtl' || atToken === 'ltr') {
455
- this.direction = atToken;
456
- } else {
457
- let queryType;
458
- const atComponents = [];
459
- // x font-face, counter-style, keyframes, font-feature-values, property, layer
460
- const queryTypeRegExp = /^(media|supports|container|layer)/;
461
- const atRuleResult = queryTypeRegExp.exec(atToken);
462
- if (atRuleResult) {
463
- queryType = atRuleResult[1];
464
- atComponents.push({
465
- type: 'arbitrary',
466
- token: atToken,
467
- value: atToken.slice(queryType.length).replace(/\|/g, ' ')
468
- });
469
- } else {
470
- const analyzeToken = (atComponentToken)=>{
471
- if (atComponentToken === '&') {
472
- atComponents.push({
473
- type: 'operator',
474
- token: atComponentToken,
475
- value: 'and'
476
- });
477
- } else if (atComponentToken.startsWith('')) {
478
- const targetAt = at[atComponentToken];
479
- if (targetAt && typeof targetAt === 'string') {
480
- const match = targetAt.match(queryTypeRegExp);
481
- queryType = match ? match[1] : '';
482
- if (!queryType) throw new Error(`Invalid query '${atComponentToken}': '${targetAt}'`);
483
- atComponents.push({
484
- type: 'arbitrary',
485
- value: targetAt.slice(match ? match[1].length + 1 : 0)
486
- });
487
- } else {
488
- // todo: container queries
489
- queryType = 'media';
490
- let featureName = '';
491
- let extremumOperator = '';
492
- let correction = 0;
493
- if (atComponentToken.startsWith('<=')) {
494
- extremumOperator = '<=';
495
- featureName = 'max-width';
496
- } else if (atComponentToken.startsWith('>') && !atComponentToken.startsWith('>=')) {
497
- extremumOperator = '>';
498
- featureName = 'min-width';
499
- correction = .02;
500
- } else if (atComponentToken.startsWith('<')) {
501
- extremumOperator = '<';
502
- featureName = 'max-width';
503
- correction = -.02;
504
- } else if (atComponentToken.startsWith('>=') || targetAt) {
505
- extremumOperator = '>=';
506
- featureName = 'min-width';
507
- }
508
- const token = extremumOperator ? atComponentToken.replace(extremumOperator, '') : atComponentToken;
509
- const viewport = at[token];
510
- switch(featureName){
511
- case 'max-width':
512
- case 'min-width':
513
- if (typeof viewport === 'number') {
514
- atComponents.push({
515
- type: 'feature',
516
- name: featureName,
517
- valueType: 'number',
518
- value: viewport + correction,
519
- unit: 'px'
520
- });
521
- } else {
522
- const valueComponent = this.parseValue(token, 'px');
523
- if (valueComponent.type === 'number') {
524
- atComponents.push({
525
- type: 'feature',
526
- name: featureName,
527
- valueType: 'number',
528
- value: valueComponent.value + correction,
529
- unit: valueComponent.unit
530
- });
531
- } else {
532
- atComponents.push({
533
- type: 'feature',
534
- name: featureName,
535
- valueType: 'string',
536
- value: token
537
- });
538
- }
539
- }
540
- break;
541
- }
542
- }
543
- }
544
- };
545
- const isAmpersandIncluded = atToken.includes('&');
546
- if (isAmpersandIncluded) {
547
- const typeOrFeatureTokens = atToken.split(/(&|,)/);
548
- for (const atComponentToken of typeOrFeatureTokens){
549
- analyzeToken(atComponentToken);
550
- }
551
- } else {
552
- analyzeToken(atToken);
553
- }
554
- if (!atComponents.length) {
555
- if (!isAmpersandIncluded && modes?.[atToken]) {
556
- this.mode = atToken;
557
- continue;
558
- }
559
- }
560
- }
561
- if (queryType) {
562
- this.at[queryType] = atComponents;
563
- }
564
- }
565
- }
566
- }
567
- // 7. value
568
- let newValue;
569
- if (this.valueComponents) {
570
- if (transformValueComponents) {
571
- this.valueComponents = transformValueComponents.call(this, this.valueComponents);
572
- }
573
- newValue = this.resolveValue(this.valueComponents, unit, [], false);
574
- if (transformValue) {
575
- newValue = transformValue.call(this, newValue);
576
- }
577
- if (declare) {
578
- this.declarations = declare.call(this, newValue, this.valueComponents);
579
- } else if (id) {
580
- this.declarations = {
581
- [id]: newValue
582
- };
583
- }
584
- }
585
- const propertiesText = [];
586
- for(const propertyName in this.declarations){
587
- const push = (propertyText)=>{
588
- // animations
589
- if (animations && (propertyText.startsWith('animation') || propertyText.startsWith('animation-name'))) {
590
- const animationNames = propertyText.split(':')[1].split('!important')[0].split(' ').filter((eachValue)=>eachValue in this.css.animations && (!this.animationNames || !this.animationNames.includes(eachValue)));
591
- if (animationNames.length) {
592
- if (!this.animationNames) {
593
- this.animationNames = [];
594
- }
595
- this.animationNames = animationNames;
596
- }
597
- }
598
- propertiesText.push(propertyText + ((this.important || important) && !propertyText.endsWith('!important') ? '!important' : ''));
599
- };
600
- const keyToken = propertyName + ':';
601
- const declarations = this.declarations[propertyName];
602
- if (Array.isArray(declarations)) {
603
- for (const value of declarations){
604
- push(keyToken + String(value));
605
- }
606
- } else {
607
- push(keyToken + String(declarations));
608
- }
609
- }
610
- // 創建 Natives
611
- if (propertiesText.length) {
612
- for(const prefixSelectorVendor in suffixSelectorVendorsByPrefixSelectorVendor){
613
- for (const eachSuffixSelectorVendor of suffixSelectorVendorsByPrefixSelectorVendor[prefixSelectorVendor]){
614
- let prefixText = '';
615
- if (this.direction) {
616
- prefixText += '[dir=' + this.direction + '] ';
617
- }
618
- const prefixSelectors = this.vendorPrefixSelectors[prefixSelectorVendor];
619
- const suffixSelectors = this.vendorSuffixSelectors[eachSuffixSelectorVendor];
620
- const prefixTexts = prefixSelectors.map((eachPrefixSelector)=>eachPrefixSelector + prefixText);
621
- const getCssText = (name)=>prefixTexts.map((eachPrefixText)=>(this.mode && modes?.[this.mode] !== 'media' ? modes?.[this.mode] === 'host' ? `:host(.${this.mode}) ` : `.${this.mode} ` : '') + (scope ? scope + ' ' : '') + eachPrefixText).reduce((arr, eachPrefixText)=>{
622
- arr.push(suffixSelectors.reduce((_arr, eachSuffixSelector)=>{
623
- _arr.push(eachPrefixText + '.' + cssEscape(name) + eachSuffixSelector);
624
- return _arr;
625
- }, []).join(','));
626
- return arr;
627
- }, []).join(',');
628
- let cssText = getCssText(className) + (classNames ? classNames.reduce((str, className)=>str + ',' + getCssText(className), '') : '') + '{' + propertiesText.join(';') + '}';
629
- for (const key of Object.keys(this.at).sort((_a, b)=>b === 'supports' ? -1 : 1)){
630
- cssText = '@' + key + (key.includes(' ') ? '' : ' ') + this.at[key].map((eachAtComponent)=>this.resolveAtComponent(eachAtComponent)).join(' ') + '{' + cssText + '}';
631
- }
632
- if (this.mode && modes?.[this.mode] === 'media') {
633
- cssText = `@media(prefers-color-scheme:${this.mode}){` + cssText + '}';
634
- }
635
- this.natives.push({
636
- text: cssText
637
- });
638
- }
639
- }
640
- }
2
+ name;
3
+ nodes;
4
+ constructor(name, nodes = []){
5
+ this.name = name;
6
+ this.nodes = nodes;
641
7
  }
642
- resolveAtComponent(atComponent) {
643
- switch(atComponent.type){
644
- case 'arbitrary':
645
- return atComponent.value;
646
- case 'feature':
647
- return '(' + atComponent.name + ':' + atComponent.value + (atComponent.unit || '') + ')';
648
- case 'operator':
649
- return atComponent.value;
650
- }
8
+ get key() {
9
+ return this.name;
651
10
  }
652
- resolveValue;
653
11
  get text() {
654
- return this.natives.map((eachNative)=>eachNative.text).join('');
655
- }
656
- parseValues;
657
- parseValue(token, unit = this.definition.unit) {
658
- const defaultUnit = unit ?? this.definition.unit;
659
- let newUnit = '';
660
- let value;
661
- if (typeof token === 'number') {
662
- /**
663
- * 當無單位值且 defaultUnit === 'rem',
664
- * 將 pxValue / 16 轉為 remValue
665
- */ if (defaultUnit && !newUnit) {
666
- if (defaultUnit === 'rem' || defaultUnit === 'em') {
667
- value = token / (this.css.config.rootSize || 1);
668
- }
669
- newUnit = defaultUnit || '';
670
- } else {
671
- value = token;
672
- }
673
- return {
674
- value,
675
- unit: newUnit,
676
- type: 'number'
677
- };
678
- } else if (defaultUnit) {
679
- // w:1/2 -> width: 50%
680
- if (/^\d+\/\d+/.test(token)) {
681
- const [dividend, divisor] = token.split('/');
682
- return {
683
- value: +dividend / +divisor * 100,
684
- unit: '%',
685
- type: 'number'
686
- };
687
- }
688
- const matches = token.match(UNIT_REGEX);
689
- // ['0.5deg', '0.5', 'deg', index: 0, input: '0.5deg', groups: undefined]
690
- if (matches) {
691
- value = +matches[1];
692
- newUnit = matches[3] || '';
693
- /**
694
- * 當無單位值且 defaultUnit === 'rem',
695
- * 將 pxValue / 16 轉為 remValue
696
- */ if (!newUnit) {
697
- if (defaultUnit === 'rem' || defaultUnit === 'em') {
698
- value = value / (this.css.config.rootSize || 1);
699
- }
700
- newUnit = defaultUnit || '';
701
- }
702
- return {
703
- value,
704
- unit: newUnit,
705
- type: 'number'
706
- };
707
- }
708
- }
709
- return {
710
- value: token,
711
- type: 'string'
712
- };
12
+ return this.nodes.map(({ text })=>text).join('');
713
13
  }
714
14
  }
715
15