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