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

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 (141) hide show
  1. package/README.md +4 -43
  2. package/dist/_virtual/_commonjsHelpers.cjs +10 -0
  3. package/dist/_virtual/_commonjsHelpers.mjs +7 -0
  4. package/dist/_virtual/css-escape.cjs +5 -0
  5. package/dist/_virtual/css-escape.mjs +3 -0
  6. package/dist/bin/index.cjs +11 -0
  7. package/dist/bin/index.d.ts +0 -1
  8. package/dist/bin/index.mjs +9 -0
  9. package/dist/common.cjs +159 -0
  10. package/dist/common.d.ts +26 -0
  11. package/dist/common.mjs +137 -0
  12. package/dist/config/animations.cjs +113 -0
  13. package/dist/config/animations.mjs +111 -0
  14. package/dist/config/at.cjs +16 -0
  15. package/dist/config/at.d.ts +13 -0
  16. package/dist/config/at.mjs +14 -0
  17. package/dist/config/functions.cjs +375 -0
  18. package/dist/config/functions.d.ts +1 -1
  19. package/dist/config/functions.mjs +373 -0
  20. package/dist/config/index.cjs +37 -0
  21. package/dist/config/index.d.ts +5 -62
  22. package/dist/config/index.mjs +27 -0
  23. package/dist/config/modes.cjs +8 -0
  24. package/dist/config/modes.d.ts +3 -0
  25. package/dist/config/modes.mjs +6 -0
  26. package/dist/config/rules.cjs +2330 -0
  27. package/dist/config/rules.d.ts +278 -274
  28. package/dist/config/rules.mjs +2328 -0
  29. package/dist/config/selectors.cjs +28 -0
  30. package/dist/config/selectors.d.ts +0 -1
  31. package/dist/config/selectors.mjs +26 -0
  32. package/dist/config/styles.cjs +2 -0
  33. package/dist/config/styles.d.ts +2 -2
  34. package/dist/config/styles.mjs +1 -0
  35. package/dist/config/utilities.cjs +204 -0
  36. package/dist/config/{semantics.d.ts → utilities.d.ts} +15 -5
  37. package/dist/config/utilities.mjs +202 -0
  38. package/dist/config/variables.cjs +484 -0
  39. package/dist/config/variables.d.ts +208 -312
  40. package/dist/config/variables.mjs +482 -0
  41. package/dist/core.cjs +739 -0
  42. package/dist/core.d.ts +97 -75
  43. package/dist/core.mjs +737 -0
  44. package/dist/factories/with-syntax-layer.cjs +308 -0
  45. package/dist/factories/with-syntax-layer.d.ts +26 -0
  46. package/dist/factories/with-syntax-layer.mjs +306 -0
  47. package/dist/index.cjs +82 -0
  48. package/dist/index.d.ts +21 -9
  49. package/dist/index.mjs +27 -0
  50. package/dist/layer.cjs +50 -0
  51. package/dist/layer.d.ts +14 -10
  52. package/dist/layer.mjs +48 -0
  53. package/dist/non-layer.cjs +64 -0
  54. package/dist/non-layer.d.ts +12 -0
  55. package/dist/non-layer.mjs +62 -0
  56. package/dist/polyfills/css-escape.cjs +9 -0
  57. package/dist/polyfills/css-escape.mjs +7 -0
  58. package/dist/polyfills/css-escape2.cjs +76 -0
  59. package/dist/polyfills/css-escape2.mjs +74 -0
  60. package/dist/register-global.cjs +7 -0
  61. package/dist/register-global.d.ts +5 -0
  62. package/dist/register-global.mjs +5 -0
  63. package/dist/rule.cjs +18 -0
  64. package/dist/rule.d.ts +9 -111
  65. package/dist/rule.mjs +16 -0
  66. package/dist/shared/utils/css-escape.cjs +56 -0
  67. package/dist/shared/utils/css-escape.mjs +54 -0
  68. package/dist/shared/utils/find-native-css-rule-index.cjs +12 -0
  69. package/dist/shared/utils/find-native-css-rule-index.mjs +10 -0
  70. package/dist/syntax-layer.cjs +8 -0
  71. package/dist/syntax-layer.d.ts +18 -0
  72. package/dist/syntax-layer.mjs +6 -0
  73. package/dist/syntax-rule-type.cjs +27 -0
  74. package/dist/syntax-rule-type.d.ts +28 -0
  75. package/dist/syntax-rule-type.mjs +25 -0
  76. package/dist/syntax-rule.cjs +644 -0
  77. package/dist/syntax-rule.d.ts +47 -0
  78. package/dist/syntax-rule.mjs +642 -0
  79. package/dist/types/common.cjs +2 -0
  80. package/dist/types/common.d.ts +1 -0
  81. package/dist/types/common.mjs +1 -0
  82. package/dist/types/config.cjs +2 -0
  83. package/dist/types/config.d.ts +70 -0
  84. package/dist/types/config.mjs +1 -0
  85. package/dist/types/syntax.cjs +2 -0
  86. package/dist/types/syntax.d.ts +106 -0
  87. package/dist/types/syntax.mjs +1 -0
  88. package/dist/utils/are-rule-at-equal.cjs +22 -0
  89. package/dist/utils/are-rule-at-equal.d.ts +2 -0
  90. package/dist/utils/are-rule-at-equal.mjs +20 -0
  91. package/dist/utils/are-rule-modes-equal.cjs +7 -0
  92. package/dist/utils/are-rule-modes-equal.d.ts +2 -0
  93. package/dist/utils/are-rule-modes-equal.mjs +5 -0
  94. package/dist/utils/are-rule-selectors-equal.cjs +29 -0
  95. package/dist/utils/are-rule-selectors-equal.d.ts +2 -0
  96. package/dist/utils/are-rule-selectors-equal.mjs +27 -0
  97. package/dist/utils/are-rule-states-equal.cjs +11 -0
  98. package/dist/utils/are-rule-states-equal.d.ts +2 -0
  99. package/dist/utils/are-rule-states-equal.mjs +9 -0
  100. package/dist/utils/are-rules-duplicated.cjs +17 -0
  101. package/dist/utils/are-rules-duplicated.d.ts +2 -0
  102. package/dist/utils/are-rules-duplicated.mjs +15 -0
  103. package/dist/utils/autofill-solid-style.cjs +31 -0
  104. package/dist/utils/autofill-solid-style.d.ts +3 -0
  105. package/dist/utils/autofill-solid-style.mjs +29 -0
  106. package/dist/utils/extend-config.cjs +59 -0
  107. package/dist/utils/extend-config.d.ts +2 -2
  108. package/dist/utils/extend-config.mjs +57 -0
  109. package/dist/utils/flatten-object.cjs +15 -0
  110. package/dist/utils/flatten-object.d.ts +1 -1
  111. package/dist/utils/flatten-object.mjs +13 -0
  112. package/dist/utils/generate-css.cjs +13 -0
  113. package/dist/utils/generate-css.d.ts +2 -0
  114. package/dist/utils/generate-css.mjs +11 -0
  115. package/dist/utils/hex-to-rgb.cjs +30 -0
  116. package/dist/utils/hex-to-rgb.d.ts +1 -1
  117. package/dist/utils/hex-to-rgb.mjs +28 -0
  118. package/dist/utils/is-core-rule.cjs +9 -0
  119. package/dist/utils/is-core-rule.d.ts +1 -0
  120. package/dist/utils/is-core-rule.mjs +7 -0
  121. package/dist/utils/reorder-for-readable-classes.cjs +62 -0
  122. package/dist/{functions → utils}/reorder-for-readable-classes.d.ts +2 -6
  123. package/dist/utils/reorder-for-readable-classes.mjs +60 -0
  124. package/package.json +1 -1
  125. package/dist/bin/index.bundle.js +0 -36
  126. package/dist/config/media-queries.d.ts +0 -1
  127. package/dist/constants/base-unit-regex.d.ts +0 -1
  128. package/dist/constants/config-esm-text.d.ts +0 -1
  129. package/dist/constants/config-text.d.ts +0 -1
  130. package/dist/constants/config-ts-text.d.ts +0 -1
  131. package/dist/constants/start-symbol.d.ts +0 -6
  132. package/dist/functions/transform-color-with-opacity.d.ts +0 -1
  133. package/dist/index.bundle.js +0 -35
  134. package/dist/index.bundle.mjs +0 -35
  135. package/dist/tokens/screen-sizes.d.ts +0 -14
  136. package/dist/types/global.d.ts +0 -5
  137. package/dist/utils/concat-arrays.d.ts +0 -1
  138. package/dist/utils/get-type.d.ts +0 -7
  139. package/dist/utils/is-plain-object.d.ts +0 -8
  140. package/dist/utils/is-symbol.d.ts +0 -7
  141. package/dist/utils/rgb-to-hex.d.ts +0 -1
package/dist/core.mjs ADDED
@@ -0,0 +1,737 @@
1
+ import { SyntaxRule } from './syntax-rule.mjs';
2
+ import { config } from './config/index.mjs';
3
+ import hexToRgb from './utils/hex-to-rgb.mjs';
4
+ import { flattenObject } from './utils/flatten-object.mjs';
5
+ import extendConfig from './utils/extend-config.mjs';
6
+ import { Rule } from './rule.mjs';
7
+ import SyntaxRuleType from './syntax-rule-type.mjs';
8
+ import Layer from './layer.mjs';
9
+ import SyntaxLayer from './syntax-layer.mjs';
10
+ import NonLayer from './non-layer.mjs';
11
+ import registerGlobal from './register-global.mjs';
12
+
13
+ class MasterCSS {
14
+ customConfig;
15
+ static config = config;
16
+ definedRules;
17
+ config;
18
+ layerStatementRule;
19
+ rules;
20
+ animationsNonLayer;
21
+ baseLayer;
22
+ themeLayer;
23
+ presetLayer;
24
+ componentsLayer;
25
+ generalLayer;
26
+ components;
27
+ selectors;
28
+ variables;
29
+ at;
30
+ animations;
31
+ constructor(customConfig){
32
+ this.customConfig = customConfig;
33
+ this.definedRules = [];
34
+ this.layerStatementRule = new Rule('layer-statement', [
35
+ {
36
+ text: '@layer base,theme,preset,components,general;'
37
+ }
38
+ ]);
39
+ this.rules = [
40
+ this.layerStatementRule
41
+ ];
42
+ this.animationsNonLayer = new NonLayer(this);
43
+ this.baseLayer = new SyntaxLayer('base', this);
44
+ this.themeLayer = new Layer('theme', this);
45
+ this.presetLayer = new SyntaxLayer('preset', this);
46
+ this.componentsLayer = new SyntaxLayer('components', this);
47
+ this.generalLayer = new SyntaxLayer('general', this);
48
+ this.components = new Map();
49
+ this.selectors = new Map();
50
+ this.variables = new Map();
51
+ this.at = new Map();
52
+ this.animations = new Map();
53
+ this.config = customConfig?.override ? extendConfig(customConfig) : extendConfig(config, customConfig);
54
+ this.resolve();
55
+ }
56
+ get text() {
57
+ return this.rules.sort((a, b)=>{
58
+ const order = [
59
+ 'layer-statement',
60
+ 'base',
61
+ 'theme',
62
+ 'preset',
63
+ 'components',
64
+ 'general'
65
+ ];
66
+ const indexA = order.indexOf(a.name) === -1 ? Infinity : order.indexOf(a.name);
67
+ const indexB = order.indexOf(b.name) === -1 ? Infinity : order.indexOf(b.name);
68
+ return indexA - indexB;
69
+ }).map(({ text })=>text).join('');
70
+ }
71
+ resolve() {
72
+ this.components.clear();
73
+ this.selectors.clear();
74
+ this.variables.clear();
75
+ this.at.clear();
76
+ this.animations.clear();
77
+ this.definedRules.length = 0;
78
+ const colorVariableNames = {
79
+ current: undefined,
80
+ currentColor: undefined,
81
+ transparent: undefined
82
+ };
83
+ const { components, selectors, variables, utilities, at, rules, animations } = this.config;
84
+ function escapeString(str) {
85
+ return str.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&');
86
+ }
87
+ if (selectors) {
88
+ const resolvedSelectors = flattenObject(selectors);
89
+ for(const eachSelectorName in resolvedSelectors){
90
+ const eachResolvedSelectorText = resolvedSelectors[eachSelectorName];
91
+ const regexp = new RegExp(escapeString(eachSelectorName) + '(?![a-z-])');
92
+ for (const eachNewSelectorText of Array.isArray(eachResolvedSelectorText) ? eachResolvedSelectorText : [
93
+ eachResolvedSelectorText
94
+ ]){
95
+ const vendor = eachNewSelectorText.match(/^:(?::)?-(webkit|moz|ms|o)-/m)?.[1] ?? '';
96
+ let selectorValues = this.selectors.get(vendor);
97
+ if (!selectorValues) {
98
+ this.selectors.set(vendor, selectorValues = []);
99
+ }
100
+ let currentSelectValue = selectorValues.find(([_valueRegexp])=>_valueRegexp === regexp);
101
+ if (!currentSelectValue) {
102
+ currentSelectValue = [
103
+ regexp,
104
+ []
105
+ ];
106
+ selectorValues.push(currentSelectValue);
107
+ }
108
+ currentSelectValue[1].push(eachNewSelectorText);
109
+ }
110
+ }
111
+ }
112
+ if (variables) {
113
+ const aliasVariableModeResolvers = new Map;
114
+ const resolveVariable = (variableDefinition, name, mode)=>{
115
+ if (variableDefinition === undefined || variableDefinition === null) return;
116
+ const addVariable = (name, variable, replacedMode, alpha)=>{
117
+ if (variable === undefined) return;
118
+ const flatName = name.join('-');
119
+ const groups = name.slice(0, -1).filter(Boolean);
120
+ const key = (name[0] === '' ? '-' : '') + name[name.length - 1];
121
+ variable.key = key;
122
+ variable.name = flatName;
123
+ if (groups.length) variable.group = groups.join('.');
124
+ if (variable.type === 'color') {
125
+ if (alpha) {
126
+ const slashIndex = variable.value.indexOf('/');
127
+ variable = {
128
+ ...variable,
129
+ value: slashIndex === -1 ? variable.value + ' / ' + (alpha.startsWith('0.') ? alpha.slice(1) : alpha) : variable.value.slice(0, slashIndex + 2) + String(+variable.value.slice(slashIndex + 2) * +alpha).slice(1)
130
+ };
131
+ }
132
+ colorVariableNames[flatName] = undefined;
133
+ }
134
+ /**
135
+ * resolve `variables.screen-*` to `at.*`
136
+ */ if (variable.name.startsWith('screen-') && variable.type === 'number') {
137
+ this.at.set(variable.name.slice(7), variable.value);
138
+ }
139
+ const currentMode = replacedMode ?? mode;
140
+ if (currentMode !== undefined) {
141
+ const foundVariable = this.variables.get(flatName);
142
+ if (foundVariable) {
143
+ if (currentMode) {
144
+ if (!foundVariable.modes) {
145
+ foundVariable.modes = {};
146
+ }
147
+ foundVariable.modes[currentMode] = variable;
148
+ } else {
149
+ foundVariable.value = variable.value;
150
+ if (variable.type === 'color') {
151
+ foundVariable.space = variable.space;
152
+ }
153
+ }
154
+ } else {
155
+ if (currentMode) {
156
+ const newVariable = {
157
+ key: variable.key,
158
+ name: variable.name,
159
+ group: variable.group,
160
+ type: variable.type,
161
+ modes: {
162
+ [currentMode]: variable
163
+ }
164
+ };
165
+ if (variable.type === 'color') {
166
+ newVariable.space = variable.space;
167
+ }
168
+ this.variables.set(flatName, newVariable);
169
+ } else {
170
+ this.variables.set(flatName, variable);
171
+ }
172
+ }
173
+ } else {
174
+ this.variables.set(flatName, variable);
175
+ }
176
+ };
177
+ if (typeof variableDefinition === 'object') {
178
+ if (Array.isArray(variableDefinition)) {
179
+ addVariable(name, {
180
+ type: 'string',
181
+ value: variableDefinition.join(',')
182
+ });
183
+ } else {
184
+ const keys = Object.keys(variableDefinition);
185
+ for (const eachKey of keys){
186
+ if (eachKey === '' || eachKey.startsWith('@')) {
187
+ resolveVariable(variableDefinition[eachKey], name, eachKey || keys.some((eachKey)=>eachKey.startsWith('@')) ? eachKey.slice(1) : undefined);
188
+ } else {
189
+ resolveVariable(variableDefinition[eachKey], [
190
+ ...name,
191
+ eachKey
192
+ ]);
193
+ }
194
+ }
195
+ }
196
+ } else if (typeof variableDefinition === 'number') {
197
+ addVariable(name, {
198
+ type: 'number',
199
+ value: variableDefinition
200
+ });
201
+ addVariable([
202
+ '',
203
+ ...name
204
+ ], {
205
+ type: 'number',
206
+ value: variableDefinition * -1
207
+ });
208
+ } else if (typeof variableDefinition === 'string') {
209
+ const aliasResult = /^\$\((.*?)\)(?: ?\/ ?(.+?))?$/.exec(variableDefinition);
210
+ const flatName = name.join('-');
211
+ if (aliasResult) {
212
+ let aliasVariableModeResolver = aliasVariableModeResolvers.get(flatName);
213
+ if (!aliasVariableModeResolver) {
214
+ aliasVariableModeResolvers.set(flatName, aliasVariableModeResolver = {});
215
+ }
216
+ aliasVariableModeResolver[mode] = ()=>{
217
+ delete aliasVariableModeResolver[mode];
218
+ const [alias, aliasMode] = aliasResult[1].split('@');
219
+ if (alias) {
220
+ const eachAliasModeVariableResolver = aliasVariableModeResolvers.get(alias);
221
+ if (eachAliasModeVariableResolver) {
222
+ for (const mode of Object.keys(eachAliasModeVariableResolver)){
223
+ eachAliasModeVariableResolver[mode]?.();
224
+ }
225
+ }
226
+ const aliasVariable = this.variables.get(alias);
227
+ if (aliasVariable) {
228
+ if (aliasMode === undefined && aliasVariable.modes) {
229
+ addVariable(name, {
230
+ type: aliasVariable.type,
231
+ value: aliasVariable.value,
232
+ space: aliasVariable.space
233
+ }, '', aliasResult[2]);
234
+ for(const mode in aliasVariable.modes){
235
+ addVariable(name, aliasVariable.modes[mode], mode, aliasResult[2]);
236
+ }
237
+ } else {
238
+ const variable = aliasMode !== undefined ? aliasVariable.modes?.[aliasMode] : aliasVariable;
239
+ if (variable) {
240
+ const newVariable = {
241
+ type: variable.type,
242
+ value: variable.value
243
+ };
244
+ if (variable.type === 'color') {
245
+ newVariable.space = variable.space;
246
+ }
247
+ addVariable(name, newVariable, undefined, aliasResult[2]);
248
+ }
249
+ }
250
+ }
251
+ }
252
+ };
253
+ } else {
254
+ const hexColorResult = /^#([A-Fa-f0-9]{3,4}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$/.exec(variableDefinition);
255
+ if (hexColorResult) {
256
+ const [r, g, b, a] = hexToRgb(hexColorResult[1]);
257
+ addVariable(name, {
258
+ type: 'color',
259
+ value: `${r} ${g} ${b}${a === 1 ? '' : ' / ' + a}`,
260
+ space: 'rgb'
261
+ });
262
+ } else {
263
+ const rgbFunctionResult = /^rgb\( *([0-9]{1,3})(?: *, *| +)([0-9]{1,3})(?: *, *| +)([0-9]{1,3}) *(?:(?:,|\/) *(.*?) *)?\)$/.exec(variableDefinition);
264
+ if (rgbFunctionResult) {
265
+ addVariable(name, {
266
+ type: 'color',
267
+ value: rgbFunctionResult[1] + ' ' + rgbFunctionResult[2] + ' ' + rgbFunctionResult[3] + (rgbFunctionResult[4] ? ' / ' + (rgbFunctionResult[4].startsWith('0.') ? rgbFunctionResult[4].slice(1) : rgbFunctionResult[4]) : ''),
268
+ space: 'rgb'
269
+ });
270
+ } else {
271
+ const hslFunctionResult = /^hsl\((.*?)\)$/.exec(variableDefinition);
272
+ if (hslFunctionResult) {
273
+ addVariable(name, {
274
+ type: 'color',
275
+ value: hslFunctionResult[1],
276
+ space: 'hsl'
277
+ });
278
+ } else {
279
+ addVariable(name, {
280
+ type: 'string',
281
+ value: variableDefinition
282
+ });
283
+ }
284
+ }
285
+ }
286
+ }
287
+ }
288
+ };
289
+ for(const parnetKey in variables){
290
+ resolveVariable(variables[parnetKey], [
291
+ parnetKey
292
+ ]);
293
+ }
294
+ // todo: address to the target variable
295
+ aliasVariableModeResolvers.forEach((aliasVariableModeResolver)=>{
296
+ for (const mode of Object.keys(aliasVariableModeResolver)){
297
+ aliasVariableModeResolver[mode]?.();
298
+ }
299
+ });
300
+ }
301
+ if (at) {
302
+ const resolvedAt = flattenObject(at);
303
+ for(const eachAt in resolvedAt){
304
+ this.at.set(eachAt, resolvedAt[eachAt]);
305
+ }
306
+ }
307
+ if (animations) {
308
+ for(const animationName in animations){
309
+ const eachAnimation = {};
310
+ this.animations.set(animationName, eachAnimation);
311
+ const eachKeyframes = animations[animationName];
312
+ for(const eachKeyframeValue in eachKeyframes){
313
+ const newValueByPropertyName = eachAnimation[eachKeyframeValue] = {};
314
+ const eachKeyframeDeclarations = eachKeyframes[eachKeyframeValue];
315
+ for(const propertyName in eachKeyframeDeclarations){
316
+ newValueByPropertyName[propertyName] = eachKeyframeDeclarations[propertyName];
317
+ }
318
+ }
319
+ }
320
+ }
321
+ const flattedStyles = components ? flattenObject(components) : {};
322
+ const utilityNames = Object.keys(flattedStyles);
323
+ const handleUtilityName = (utilityName)=>{
324
+ if (this.components.has(utilityName)) return;
325
+ const currentClass = [];
326
+ this.components.set(utilityName, currentClass);
327
+ const className = flattedStyles[utilityName];
328
+ if (!className) return;
329
+ const classNames = className.replace(/(?:\n(?:\s*))+/g, ' ').trim().split(' ');
330
+ for (const eachClassName of classNames){
331
+ const handle = (className)=>{
332
+ if (!currentClass.includes(className)) {
333
+ currentClass.push(className);
334
+ }
335
+ };
336
+ if (utilityNames.includes(eachClassName)) {
337
+ handleUtilityName(eachClassName);
338
+ const componentClasses = this.components.get(eachClassName);
339
+ componentClasses?.forEach(handle);
340
+ } else {
341
+ handle(eachClassName);
342
+ }
343
+ }
344
+ };
345
+ for (const eachUtilityName of utilityNames){
346
+ handleUtilityName(eachUtilityName);
347
+ }
348
+ if (rules || utilities) {
349
+ const rulesEntries = [];
350
+ if (utilities) {
351
+ for(const utilityName in utilities){
352
+ const declarations = utilities[utilityName];
353
+ rulesEntries.push([
354
+ utilityName,
355
+ {
356
+ declarations,
357
+ type: SyntaxRuleType.Utility
358
+ }
359
+ ]);
360
+ }
361
+ }
362
+ if (rules) {
363
+ rulesEntries.push(...Object.entries(rules));
364
+ }
365
+ const rulesEntriesLength = rulesEntries.length;
366
+ const colorNames = Object.keys(colorVariableNames);
367
+ rulesEntries.sort((a, b)=>{
368
+ if (a[1].type !== b[1].type) {
369
+ return (b[1].type || 0) - (a[1].type || 0);
370
+ }
371
+ return b[0].localeCompare(a[0]);
372
+ }).forEach(([id, eachSyntaxRuleDefinition], index)=>{
373
+ const syntax = {
374
+ id,
375
+ keys: [],
376
+ variables: {},
377
+ matchers: {},
378
+ order: rulesEntriesLength - 1 - index,
379
+ definition: eachSyntaxRuleDefinition
380
+ };
381
+ if (!eachSyntaxRuleDefinition.unit) {
382
+ eachSyntaxRuleDefinition.unit = '';
383
+ }
384
+ if (!eachSyntaxRuleDefinition.separators) {
385
+ eachSyntaxRuleDefinition.separators = [
386
+ ','
387
+ ];
388
+ }
389
+ this.definedRules.push(syntax);
390
+ const { matcher, type, subkey, ambiguousKeys, ambiguousValues, sign } = eachSyntaxRuleDefinition;
391
+ if (type === SyntaxRuleType.Utility) {
392
+ syntax.id = '.' + id;
393
+ syntax.matchers.arbitrary = new RegExp('^' + escapeString(id) + '(?=!|\\*|>|\\+|~|:|\\[|@|_|\\.|$)', 'm');
394
+ }
395
+ // todo: 不可使用 startsWith 判斷,應改為更精準的從 config.variables 取得目標變數群組,但 config.variables 中的值還沒被 resolve 像是 Array
396
+ const addResolvedVariables = (groupName)=>{
397
+ this.variables.forEach((eachVariable)=>{
398
+ if (eachVariable.group === groupName) {
399
+ syntax.variables[eachVariable.key] = eachVariable;
400
+ }
401
+ });
402
+ };
403
+ // 1. custom `config.rules[id].variables`
404
+ if (eachSyntaxRuleDefinition.variables) {
405
+ for (const eachVariableGroup of eachSyntaxRuleDefinition.variables){
406
+ addResolvedVariables(eachVariableGroup);
407
+ }
408
+ }
409
+ // 2. custom `config.variables`
410
+ addResolvedVariables(id);
411
+ const keys = [];
412
+ let { key } = eachSyntaxRuleDefinition;
413
+ if (type === SyntaxRuleType.NativeShorthand || type === SyntaxRuleType.Native) {
414
+ if (!key) eachSyntaxRuleDefinition.key = key = id;
415
+ keys.push(id);
416
+ }
417
+ if (sign) {
418
+ syntax.matchers.arbitrary = new RegExp(`^${sign}[^!*>+~:[@_]+\\|`);
419
+ } else if (!matcher) {
420
+ const colorsPatten = colorNames.join('|');
421
+ if (!key && !subkey) {
422
+ keys.push(id);
423
+ } else {
424
+ if (key && !keys.includes(key)) keys.push(key);
425
+ if (subkey) keys.push(subkey);
426
+ if (type === SyntaxRuleType.Shorthand) {
427
+ keys.push(id);
428
+ }
429
+ }
430
+ if (ambiguousKeys?.length) {
431
+ const ambiguousKeyPattern = ambiguousKeys.length > 1 ? `(?:${ambiguousKeys.join('|')})` : ambiguousKeys[0];
432
+ const variableKeys = Object.keys(syntax.variables);
433
+ if (ambiguousValues?.length) {
434
+ const ambiguousValuePatterns = [];
435
+ for (const eachAmbiguousValue of ambiguousValues){
436
+ if (eachAmbiguousValue instanceof RegExp) {
437
+ ambiguousValuePatterns.push(eachAmbiguousValue.source.replace('\\$colors', colorsPatten));
438
+ } else {
439
+ ambiguousValuePatterns.unshift(`${eachAmbiguousValue}(?:\\b|_)`);
440
+ }
441
+ }
442
+ syntax.matchers.value = new RegExp(`^${ambiguousKeyPattern}:(?:${ambiguousValuePatterns.join('|')})[^|]*?(?:@|$)`);
443
+ }
444
+ if (variableKeys.length) {
445
+ syntax.matchers.variable = new RegExp(`^${ambiguousKeyPattern}:(?:${variableKeys.join('|')}(?![a-zA-Z0-9-]))[^|]*?(?:@|$)`);
446
+ }
447
+ }
448
+ } else {
449
+ syntax.matchers.arbitrary = matcher;
450
+ }
451
+ if (keys.length) {
452
+ syntax.keys = keys;
453
+ syntax.matchers.key = new RegExp(`^${keys.length > 1 ? `(${keys.join('|')})` : keys[0]}:.`);
454
+ }
455
+ });
456
+ }
457
+ this.components.forEach((componentClasses, componentClass)=>{
458
+ const syntaxRulesByStateToken = componentClasses.map((eachSyntax)=>this.create(eachSyntax)).filter((eachSyntax)=>eachSyntax?.text).reduce((obj, eachSyntaxRule)=>{
459
+ if (eachSyntaxRule.stateToken in obj) {
460
+ obj[eachSyntaxRule.stateToken].push(eachSyntaxRule);
461
+ } else {
462
+ obj[eachSyntaxRule.stateToken] = [
463
+ eachSyntaxRule
464
+ ];
465
+ }
466
+ return obj;
467
+ }, {});
468
+ this.components.set(componentClass, Object.keys(syntaxRulesByStateToken).map((stateToken)=>{
469
+ const syntaxRules = syntaxRulesByStateToken[stateToken];
470
+ return syntaxRules.length === 1 ? syntaxRules[0].name : '{' + syntaxRulesByStateToken[stateToken].map((eachSyntaxRule)=>eachSyntaxRule.name.slice(0, eachSyntaxRule.name.length - eachSyntaxRule.stateToken.length)).join(';') + '}' + stateToken;
471
+ }));
472
+ });
473
+ }
474
+ /**
475
+ * Match check if Master CSS syntax
476
+ * @param className
477
+ * @returns css text
478
+ */ match(className) {
479
+ /**
480
+ * 1. variable
481
+ * @example fg:primary bg:blue
482
+ */ for (const eachSyntax of this.definedRules){
483
+ if (eachSyntax.matchers.variable?.test(className)) return eachSyntax;
484
+ }
485
+ /**
486
+ * 2. value (ambiguous.key * ambiguous.values)
487
+ * @example bg:current box:content font:12
488
+ */ for (const eachSyntax of this.definedRules){
489
+ if (eachSyntax.matchers.value?.test(className)) return eachSyntax;
490
+ }
491
+ /**
492
+ * 3. full key
493
+ * @example text-align:center color:blue-40
494
+ */ for (const eachSyntax of this.definedRules){
495
+ if (eachSyntax.matchers.key?.test(className)) return eachSyntax;
496
+ }
497
+ /**
498
+ * 4. arbitrary
499
+ * @example custom RegExp, utility
500
+ */ for (const eachSyntax of this.definedRules){
501
+ if (eachSyntax.matchers.arbitrary?.test(className)) return eachSyntax;
502
+ }
503
+ }
504
+ /**
505
+ * Generate syntax rules from class name
506
+ * @param className
507
+ * @returns SyntaxRule[]
508
+ */ generate(className, mode) {
509
+ let syntaxRules = [];
510
+ const componentClasses = this.components.get(className);
511
+ if (componentClasses) {
512
+ componentClasses.forEach((eachSyntax)=>{
513
+ const syntaxRule = this.create(eachSyntax, className, mode);
514
+ if (syntaxRule?.text) syntaxRules.push(syntaxRule);
515
+ });
516
+ } else {
517
+ const atIndex = className.indexOf('@');
518
+ if (atIndex !== -1) {
519
+ const name = className.slice(0, atIndex);
520
+ const componentClasses = this.components.get(name);
521
+ if (componentClasses) {
522
+ const atToken = className.slice(atIndex);
523
+ componentClasses.forEach((eachSyntax)=>{
524
+ const syntaxRule = this.create(eachSyntax + atToken, className, mode);
525
+ if (syntaxRule?.text) syntaxRules.push(syntaxRule);
526
+ });
527
+ }
528
+ }
529
+ const syntaxRule = this.create(className, undefined, mode);
530
+ if (syntaxRule?.text) syntaxRules.push(syntaxRule);
531
+ }
532
+ return syntaxRules;
533
+ }
534
+ generateVendorSelectors(selectorText) {
535
+ const vendorSelectors = {};
536
+ const transformSelector = (selectorText, selectorValues, selectors, matched)=>{
537
+ for (const [regexp, newSelectorTexts] of selectorValues){
538
+ if (regexp.test(selectorText)) {
539
+ for (const eachNewSelectorText of newSelectorTexts){
540
+ transformSelector(selectorText.replace(regexp, eachNewSelectorText), selectorValues, selectors, true);
541
+ }
542
+ return;
543
+ }
544
+ }
545
+ if (matched) {
546
+ selectors.push(selectorText);
547
+ }
548
+ };
549
+ const spacedSelectorToken = (selectorText)=>{
550
+ // 1. \'123\'
551
+ // 2. [href='http://localhost']
552
+ const transformedSelectorText = selectorText.split(/(\\'(?:.*?)[^\\]\\')(?=[*_>~+,)])|(\[[^=]+='(?:.*?)[^\\]'\])/).map((eachToken, i)=>i % 3 ? eachToken : eachToken.replace(/(^|[^_])_(?!_)/g, '$1 ')).join('');
553
+ const selectors = [];
554
+ let currentSelector = '';
555
+ let symbolCount = 0;
556
+ for(let i = 0; i < transformedSelectorText.length; i++){
557
+ const char = transformedSelectorText[i];
558
+ if (char === '\\') {
559
+ currentSelector += char + transformedSelectorText[++i];
560
+ continue;
561
+ }
562
+ if (!symbolCount && char === ',') {
563
+ selectors.push(currentSelector);
564
+ currentSelector = '';
565
+ } else {
566
+ currentSelector += char;
567
+ if (symbolCount && char === ')') {
568
+ symbolCount--;
569
+ } else if (char === '(') {
570
+ symbolCount++;
571
+ }
572
+ }
573
+ }
574
+ if (currentSelector) {
575
+ selectors.push(currentSelector);
576
+ }
577
+ return selectors;
578
+ };
579
+ const transformedSelectors = [];
580
+ const selectorValues = this.selectors.get('');
581
+ if (selectorValues) {
582
+ transformSelector(selectorText, selectorValues, transformedSelectors, true);
583
+ } else {
584
+ transformedSelectors.push(selectorText);
585
+ }
586
+ const unspacedVendorSelectors = {};
587
+ this.selectors.forEach((selectorValues, vendor)=>{
588
+ if (!vendor) return;
589
+ const newUnspacedVendorSelectors = [];
590
+ for (const eachTransformedSelector of transformedSelectors){
591
+ transformSelector(eachTransformedSelector, selectorValues, newUnspacedVendorSelectors, false);
592
+ }
593
+ if (newUnspacedVendorSelectors.length) {
594
+ unspacedVendorSelectors[vendor] = newUnspacedVendorSelectors;
595
+ }
596
+ });
597
+ const insertVendorSelectors = (vendor, selectorTexts)=>{
598
+ const groupedSelectorTexts = selectorTexts.reduce((arr, eachSuffixSelector)=>{
599
+ arr.push(...spacedSelectorToken(eachSuffixSelector));
600
+ return arr;
601
+ }, []);
602
+ if (vendor in vendorSelectors) {
603
+ vendorSelectors[vendor].push(...groupedSelectorTexts);
604
+ } else {
605
+ vendorSelectors[vendor] = groupedSelectorTexts;
606
+ }
607
+ };
608
+ const vendors = Object.keys(unspacedVendorSelectors);
609
+ if (vendors.length) {
610
+ for (const eachVendor of vendors){
611
+ insertVendorSelectors(eachVendor, unspacedVendorSelectors[eachVendor]);
612
+ }
613
+ } else {
614
+ insertVendorSelectors('', transformedSelectors);
615
+ }
616
+ return vendorSelectors;
617
+ }
618
+ /**
619
+ * Create syntax rule from given class name
620
+ * @param className
621
+ * @returns SyntaxRule
622
+ */ create(className, fixedClass, mode) {
623
+ const syntaxRule = this.generalLayer.rules.find(({ key })=>key === (fixedClass ? fixedClass + ' ' : '') + className);
624
+ if (syntaxRule) return syntaxRule;
625
+ const registeredRule = this.match(className);
626
+ if (registeredRule) return new SyntaxRule(className, this, registeredRule, fixedClass, mode);
627
+ }
628
+ /**
629
+ * Create syntax rule from given selector text
630
+ * @param selectorText
631
+ */ createFromSelectorText(selectorText) {
632
+ const selectorTextSplits = selectorText.split(' ');
633
+ const stopChars = /[.#\[!\*>+~:,\s]/;
634
+ for(let i = 0; i < selectorTextSplits.length; i++){
635
+ const eachField = selectorTextSplits[i];
636
+ const modeSelector = this.getModeSelector(eachField);
637
+ if (i === 0 && eachField === modeSelector) continue;
638
+ if (eachField.startsWith('.')) {
639
+ const eachFieldName = eachField.slice(1);
640
+ let className = '';
641
+ let l = 0;
642
+ while(l < eachFieldName.length){
643
+ const char = eachFieldName[l];
644
+ const nextChar = eachFieldName[l + 1];
645
+ if (char === '\\' && nextChar) {
646
+ className += nextChar;
647
+ l += 2;
648
+ continue;
649
+ }
650
+ if (stopChars.test(char)) break;
651
+ className += char;
652
+ l++;
653
+ }
654
+ const syntaxRules = this.generate(className);
655
+ if (syntaxRules.length) return syntaxRules;
656
+ }
657
+ }
658
+ }
659
+ /**
660
+ * 根據蒐集到的所有 DOM class 重新 create
661
+ */ refresh(customConfig) {
662
+ this.reset();
663
+ if (customConfig) {
664
+ this.customConfig = customConfig;
665
+ } else {
666
+ customConfig = this.customConfig;
667
+ }
668
+ // @ts-ignore
669
+ this.config = customConfig?.override ? extendConfig(customConfig) : extendConfig(config, customConfig);
670
+ this.resolve();
671
+ return this;
672
+ }
673
+ reset() {
674
+ this.baseLayer.reset();
675
+ this.themeLayer.reset();
676
+ this.presetLayer.reset();
677
+ this.componentsLayer.reset();
678
+ this.generalLayer.reset();
679
+ this.animationsNonLayer.reset();
680
+ return this;
681
+ }
682
+ destroy() {
683
+ this.reset();
684
+ return this;
685
+ }
686
+ add(...classNames) {
687
+ for (const className of classNames){
688
+ this.generate(className).forEach((eachSyntaxRule)=>eachSyntaxRule.layer.insert(eachSyntaxRule));
689
+ }
690
+ return this;
691
+ }
692
+ remove(...classNames) {
693
+ /**
694
+ * class name 從 DOM tree 中被移除,
695
+ * 匹配並刪除對應的 rule
696
+ */ for (const className of classNames){
697
+ const componentClasses = this.components.get(className);
698
+ if (componentClasses) {
699
+ componentClasses.forEach((componentClass)=>{
700
+ this.componentsLayer.delete(className + ' ' + componentClass);
701
+ });
702
+ } else {
703
+ const atIndex = className.indexOf('@');
704
+ if (atIndex !== -1) {
705
+ const name = className.slice(0, atIndex);
706
+ const componentClasses = this.components.get(name);
707
+ if (componentClasses) {
708
+ const atToken = className.slice(atIndex);
709
+ componentClasses.forEach((componentClass)=>{
710
+ this.componentsLayer.delete(componentClass + atToken + ' ' + className);
711
+ });
712
+ } else {
713
+ this.generalLayer.delete(className);
714
+ }
715
+ } else {
716
+ this.generalLayer.delete(className);
717
+ }
718
+ }
719
+ }
720
+ }
721
+ getModeSelector(modeName) {
722
+ const mode = this.config.modes?.[modeName];
723
+ if (mode) {
724
+ switch(mode){
725
+ case 'class':
726
+ return '.' + modeName;
727
+ case 'host':
728
+ return ':host(.' + modeName + ')';
729
+ }
730
+ }
731
+ }
732
+ }
733
+ (function(MasterCSS) {
734
+ registerGlobal(MasterCSS);
735
+ })(MasterCSS);
736
+
737
+ export { MasterCSS as default };