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