@master/css 2.0.0-rc.47 → 2.0.0-rc.49
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/common.cjs +1 -1
- package/dist/common.mjs +1 -1
- package/dist/config/functions.d.ts +1 -1
- package/dist/config/index.cjs +3 -3
- package/dist/config/index.d.ts +3 -48
- package/dist/config/index.mjs +3 -3
- package/dist/config/modes.d.ts +1 -1
- package/dist/config/{syntaxes.cjs → rules.cjs} +282 -282
- package/dist/config/rules.d.ts +282 -0
- package/dist/config/{syntaxes.mjs → rules.mjs} +282 -282
- package/dist/core.cjs +229 -611
- package/dist/core.d.ts +36 -67
- package/dist/core.mjs +229 -611
- package/dist/index.cjs +14 -6
- package/dist/index.d.ts +8 -4
- package/dist/index.mjs +7 -3
- package/dist/layer.cjs +107 -23
- package/dist/layer.d.ts +13 -27
- package/dist/layer.mjs +107 -23
- package/dist/non-layer.cjs +65 -0
- package/dist/non-layer.d.ts +12 -0
- package/dist/non-layer.mjs +63 -0
- package/dist/rule.cjs +8 -708
- package/dist/rule.d.ts +6 -147
- package/dist/rule.mjs +8 -708
- package/dist/shared/utils/find-native-css-rule-index.cjs +12 -0
- package/dist/shared/utils/find-native-css-rule-index.mjs +10 -0
- package/dist/syntax-layer.cjs +291 -0
- package/dist/syntax-layer.d.ts +17 -0
- package/dist/syntax-layer.mjs +289 -0
- package/dist/syntax-rule-type.cjs +27 -0
- package/dist/syntax-rule-type.d.ts +28 -0
- package/dist/syntax-rule-type.mjs +25 -0
- package/dist/syntax-rule.cjs +717 -0
- package/dist/syntax-rule.d.ts +47 -0
- package/dist/syntax-rule.mjs +715 -0
- package/dist/types/config.cjs +2 -0
- package/dist/types/config.d.ts +70 -0
- package/dist/types/config.mjs +1 -0
- package/dist/types/syntax.cjs +2 -0
- package/dist/types/syntax.d.ts +106 -0
- package/dist/types/syntax.mjs +1 -0
- package/dist/utils/are-rule-at-equal.cjs +7 -7
- package/dist/utils/are-rule-at-equal.d.ts +2 -2
- package/dist/utils/are-rule-at-equal.mjs +7 -7
- package/dist/utils/are-rule-modes-equal.cjs +2 -2
- package/dist/utils/are-rule-modes-equal.d.ts +2 -2
- package/dist/utils/are-rule-modes-equal.mjs +2 -2
- package/dist/utils/are-rule-selectors-equal.cjs +11 -11
- package/dist/utils/are-rule-selectors-equal.d.ts +2 -2
- package/dist/utils/are-rule-selectors-equal.mjs +11 -11
- package/dist/utils/are-rule-states-equal.cjs +2 -2
- package/dist/utils/are-rule-states-equal.d.ts +2 -2
- package/dist/utils/are-rule-states-equal.mjs +2 -2
- package/dist/utils/are-rules-duplicated.cjs +17 -0
- package/dist/utils/are-rules-duplicated.d.ts +2 -0
- package/dist/utils/are-rules-duplicated.mjs +15 -0
- package/dist/utils/autofill-solid-style.d.ts +2 -2
- package/dist/utils/extend-config.cjs +5 -5
- package/dist/utils/extend-config.d.ts +1 -1
- package/dist/utils/extend-config.mjs +5 -5
- package/dist/utils/generate-css.cjs +1 -1
- package/dist/utils/generate-css.mjs +1 -1
- package/dist/utils/is-core-rule.cjs +2 -2
- package/dist/utils/is-core-rule.mjs +2 -2
- package/dist/utils/reorder-for-readable-classes.cjs +11 -11
- package/dist/utils/reorder-for-readable-classes.mjs +11 -11
- package/package.json +1 -1
- package/dist/config/syntaxes.d.ts +0 -282
- package/dist/utils/are-syntaxes-duplicated.cjs +0 -17
- package/dist/utils/are-syntaxes-duplicated.d.ts +0 -2
- package/dist/utils/are-syntaxes-duplicated.mjs +0 -15
package/dist/core.mjs
CHANGED
|
@@ -1,50 +1,80 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SyntaxRule } from './syntax-rule.mjs';
|
|
2
2
|
import { config } from './config/index.mjs';
|
|
3
|
-
import Layer from './layer.mjs';
|
|
4
3
|
import hexToRgb from './utils/hex-to-rgb.mjs';
|
|
5
4
|
import { flattenObject } from './utils/flatten-object.mjs';
|
|
6
5
|
import extendConfig from './utils/extend-config.mjs';
|
|
6
|
+
import SyntaxLayer from './syntax-layer.mjs';
|
|
7
|
+
import { Rule } from './rule.mjs';
|
|
8
|
+
import SyntaxRuleType from './syntax-rule-type.mjs';
|
|
9
|
+
import Layer from './layer.mjs';
|
|
10
|
+
import NonLayer from './non-layer.mjs';
|
|
7
11
|
|
|
8
12
|
class MasterCSS {
|
|
9
13
|
customConfig;
|
|
10
14
|
static config = config;
|
|
11
|
-
|
|
12
|
-
ruleBy;
|
|
13
|
-
classesUsage;
|
|
15
|
+
definedRules;
|
|
14
16
|
config;
|
|
15
|
-
|
|
17
|
+
classUsages;
|
|
18
|
+
layerStatementRule;
|
|
19
|
+
rules;
|
|
20
|
+
animationsNonLayer;
|
|
21
|
+
baseLayer;
|
|
22
|
+
themeLayer;
|
|
23
|
+
presetLayer;
|
|
24
|
+
componentsLayer;
|
|
25
|
+
generalLayer;
|
|
26
|
+
get text() {
|
|
27
|
+
return this.rules.sort((a, b)=>{
|
|
28
|
+
const order = [
|
|
29
|
+
'layer-statement',
|
|
30
|
+
'base',
|
|
31
|
+
'theme',
|
|
32
|
+
'preset',
|
|
33
|
+
'components',
|
|
34
|
+
'general'
|
|
35
|
+
];
|
|
36
|
+
const indexA = order.indexOf(a.name) === -1 ? Infinity : order.indexOf(a.name);
|
|
37
|
+
const indexB = order.indexOf(b.name) === -1 ? Infinity : order.indexOf(b.name);
|
|
38
|
+
return indexA - indexB;
|
|
39
|
+
}).map(({ text })=>text).join('');
|
|
40
|
+
}
|
|
16
41
|
constructor(customConfig){
|
|
17
42
|
this.customConfig = customConfig;
|
|
18
|
-
this.
|
|
19
|
-
this.
|
|
20
|
-
this.
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
43
|
+
this.definedRules = [];
|
|
44
|
+
this.classUsages = new Map();
|
|
45
|
+
this.layerStatementRule = new Rule('layer-statement', [
|
|
46
|
+
{
|
|
47
|
+
text: '@layer base,theme,preset,components,general;'
|
|
48
|
+
}
|
|
49
|
+
]);
|
|
50
|
+
this.rules = [
|
|
51
|
+
this.layerStatementRule
|
|
52
|
+
];
|
|
53
|
+
this.animationsNonLayer = new NonLayer(this);
|
|
54
|
+
this.baseLayer = new SyntaxLayer('base', this);
|
|
55
|
+
this.themeLayer = new Layer('theme', this);
|
|
56
|
+
this.presetLayer = new SyntaxLayer('preset', this);
|
|
57
|
+
this.componentsLayer = new SyntaxLayer('components', this);
|
|
58
|
+
this.generalLayer = new SyntaxLayer('general', this);
|
|
59
|
+
this.config = customConfig?.override ? extendConfig(customConfig) : extendConfig(config, customConfig);
|
|
27
60
|
this.resolve();
|
|
28
61
|
if (this.constructor === MasterCSS) {
|
|
29
62
|
masterCSSs.push(this);
|
|
30
63
|
}
|
|
31
64
|
}
|
|
32
65
|
resolve() {
|
|
33
|
-
this.
|
|
34
|
-
this.stylesBy = {};
|
|
66
|
+
this.components = {};
|
|
35
67
|
this.selectors = {};
|
|
36
68
|
this.variables = {};
|
|
37
69
|
this.at = {};
|
|
38
70
|
this.animations = {};
|
|
39
|
-
this.
|
|
40
|
-
this.variablesNativeRules = {};
|
|
41
|
-
this.hasKeyframesRule = false;
|
|
71
|
+
this.definedRules.length = 0;
|
|
42
72
|
const colorVariableNames = {
|
|
43
73
|
current: undefined,
|
|
44
74
|
currentColor: undefined,
|
|
45
75
|
transparent: undefined
|
|
46
76
|
};
|
|
47
|
-
const {
|
|
77
|
+
const { components, selectors, variables, utilities, at, rules, animations } = this.config;
|
|
48
78
|
function escapeString(str) {
|
|
49
79
|
return str.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&');
|
|
50
80
|
}
|
|
@@ -276,33 +306,23 @@ class MasterCSS {
|
|
|
276
306
|
}
|
|
277
307
|
}
|
|
278
308
|
}
|
|
279
|
-
const flattedStyles =
|
|
309
|
+
const flattedStyles = components ? flattenObject(components) : {};
|
|
280
310
|
const utilityNames = Object.keys(flattedStyles);
|
|
281
311
|
const handleUtilityName = (utilityName)=>{
|
|
282
|
-
if (Object.prototype.hasOwnProperty.call(this.
|
|
283
|
-
const currentClass = this.
|
|
312
|
+
if (Object.prototype.hasOwnProperty.call(this.components, utilityName)) return;
|
|
313
|
+
const currentClass = this.components[utilityName] = [];
|
|
284
314
|
const className = flattedStyles[utilityName];
|
|
285
315
|
if (!className) return;
|
|
286
316
|
const classNames = className.replace(/(?:\n(?:\s*))+/g, ' ').trim().split(' ');
|
|
287
317
|
for (const eachClassName of classNames){
|
|
288
318
|
const handle = (className)=>{
|
|
289
|
-
if (Object.prototype.hasOwnProperty.call(this.stylesBy, className)) {
|
|
290
|
-
const currentRelation = this.stylesBy[className];
|
|
291
|
-
if (!currentRelation.includes(utilityName)) {
|
|
292
|
-
currentRelation.push(utilityName);
|
|
293
|
-
}
|
|
294
|
-
} else {
|
|
295
|
-
this.stylesBy[className] = [
|
|
296
|
-
utilityName
|
|
297
|
-
];
|
|
298
|
-
}
|
|
299
319
|
if (!currentClass.includes(className)) {
|
|
300
320
|
currentClass.push(className);
|
|
301
321
|
}
|
|
302
322
|
};
|
|
303
323
|
if (utilityNames.includes(eachClassName)) {
|
|
304
324
|
handleUtilityName(eachClassName);
|
|
305
|
-
for (const parentClassName of this.
|
|
325
|
+
for (const parentClassName of this.components[eachClassName]){
|
|
306
326
|
handle(parentClassName);
|
|
307
327
|
}
|
|
308
328
|
} else {
|
|
@@ -313,7 +333,7 @@ class MasterCSS {
|
|
|
313
333
|
for (const eachUtilityName of utilityNames){
|
|
314
334
|
handleUtilityName(eachUtilityName);
|
|
315
335
|
}
|
|
316
|
-
if (
|
|
336
|
+
if (rules || utilities) {
|
|
317
337
|
const rulesEntries = [];
|
|
318
338
|
if (utilities) {
|
|
319
339
|
for(const utilityName in utilities){
|
|
@@ -322,61 +342,69 @@ class MasterCSS {
|
|
|
322
342
|
utilityName,
|
|
323
343
|
{
|
|
324
344
|
declarations,
|
|
325
|
-
|
|
345
|
+
type: SyntaxRuleType.Utility
|
|
326
346
|
}
|
|
327
347
|
]);
|
|
328
348
|
}
|
|
329
349
|
}
|
|
330
|
-
if (
|
|
331
|
-
rulesEntries.push(...Object.entries(
|
|
350
|
+
if (rules) {
|
|
351
|
+
rulesEntries.push(...Object.entries(rules));
|
|
332
352
|
}
|
|
333
353
|
const rulesEntriesLength = rulesEntries.length;
|
|
334
354
|
const colorNames = Object.keys(colorVariableNames);
|
|
335
355
|
rulesEntries.sort((a, b)=>{
|
|
336
|
-
if (a[1].
|
|
337
|
-
return (b[1].
|
|
356
|
+
if (a[1].type !== b[1].type) {
|
|
357
|
+
return (b[1].type || 0) - (a[1].type || 0);
|
|
338
358
|
}
|
|
339
359
|
return b[0].localeCompare(a[0]);
|
|
340
|
-
}).forEach(([id,
|
|
341
|
-
const
|
|
360
|
+
}).forEach(([id, eachSyntaxRuleDefinition], index)=>{
|
|
361
|
+
const syntax = {
|
|
342
362
|
id,
|
|
343
363
|
keys: [],
|
|
344
364
|
variables: {},
|
|
345
365
|
matchers: {},
|
|
346
366
|
order: rulesEntriesLength - 1 - index,
|
|
347
|
-
definition:
|
|
367
|
+
definition: eachSyntaxRuleDefinition
|
|
348
368
|
};
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
369
|
+
if (!eachSyntaxRuleDefinition.unit) {
|
|
370
|
+
eachSyntaxRuleDefinition.unit = '';
|
|
371
|
+
}
|
|
372
|
+
if (!eachSyntaxRuleDefinition.separators) {
|
|
373
|
+
eachSyntaxRuleDefinition.separators = [
|
|
374
|
+
','
|
|
375
|
+
];
|
|
376
|
+
}
|
|
377
|
+
this.definedRules.push(syntax);
|
|
378
|
+
const { matcher, type, subkey, ambiguousKeys, ambiguousValues, sign } = eachSyntaxRuleDefinition;
|
|
379
|
+
if (type === SyntaxRuleType.Utility) {
|
|
380
|
+
syntax.id = '.' + id;
|
|
381
|
+
syntax.matchers.arbitrary = new RegExp('^' + escapeString(id) + '(?=!|\\*|>|\\+|~|:|\\[|@|_|\\.|$)', 'm');
|
|
354
382
|
}
|
|
355
383
|
// todo: 不可使用 startsWith 判斷,應改為更精準的從 config.variables 取得目標變數群組,但 config.variables 中的值還沒被 resolve 像是 Array
|
|
356
384
|
const addResolvedVariables = (groupName)=>{
|
|
357
385
|
for(const eachVariableName in this.variables){
|
|
358
386
|
const eachVariable = this.variables[eachVariableName];
|
|
359
387
|
if (eachVariable.group === groupName) {
|
|
360
|
-
|
|
388
|
+
syntax.variables[eachVariable.key] = eachVariable;
|
|
361
389
|
}
|
|
362
390
|
}
|
|
363
391
|
};
|
|
364
|
-
// 1. custom `config.
|
|
365
|
-
if (
|
|
366
|
-
for (const eachVariableGroup of
|
|
392
|
+
// 1. custom `config.rules[id].variables`
|
|
393
|
+
if (eachSyntaxRuleDefinition.variables) {
|
|
394
|
+
for (const eachVariableGroup of eachSyntaxRuleDefinition.variables){
|
|
367
395
|
addResolvedVariables(eachVariableGroup);
|
|
368
396
|
}
|
|
369
397
|
}
|
|
370
398
|
// 2. custom `config.variables`
|
|
371
399
|
addResolvedVariables(id);
|
|
372
400
|
const keys = [];
|
|
373
|
-
let { key } =
|
|
374
|
-
if (
|
|
375
|
-
if (!key)
|
|
401
|
+
let { key } = eachSyntaxRuleDefinition;
|
|
402
|
+
if (type === SyntaxRuleType.NativeShorthand || type === SyntaxRuleType.Native) {
|
|
403
|
+
if (!key) eachSyntaxRuleDefinition.key = key = id;
|
|
376
404
|
keys.push(id);
|
|
377
405
|
}
|
|
378
406
|
if (sign) {
|
|
379
|
-
|
|
407
|
+
syntax.matchers.arbitrary = new RegExp(`^${sign}[^!*>+~:[@_]+\\|`);
|
|
380
408
|
} else if (!matcher) {
|
|
381
409
|
const colorsPatten = colorNames.join('|');
|
|
382
410
|
if (!key && !subkey) {
|
|
@@ -384,13 +412,13 @@ class MasterCSS {
|
|
|
384
412
|
} else {
|
|
385
413
|
if (key && !keys.includes(key)) keys.push(key);
|
|
386
414
|
if (subkey) keys.push(subkey);
|
|
387
|
-
if (
|
|
415
|
+
if (type === SyntaxRuleType.Shorthand) {
|
|
388
416
|
keys.push(id);
|
|
389
417
|
}
|
|
390
418
|
}
|
|
391
419
|
if (ambiguousKeys?.length) {
|
|
392
420
|
const ambiguousKeyPattern = ambiguousKeys.length > 1 ? `(?:${ambiguousKeys.join('|')})` : ambiguousKeys[0];
|
|
393
|
-
const variableKeys = Object.keys(
|
|
421
|
+
const variableKeys = Object.keys(syntax.variables);
|
|
394
422
|
if (ambiguousValues?.length) {
|
|
395
423
|
const ambiguousValuePatterns = [];
|
|
396
424
|
for (const eachAmbiguousValue of ambiguousValues){
|
|
@@ -400,19 +428,35 @@ class MasterCSS {
|
|
|
400
428
|
ambiguousValuePatterns.unshift(`${eachAmbiguousValue}(?:\\b|_)`);
|
|
401
429
|
}
|
|
402
430
|
}
|
|
403
|
-
|
|
431
|
+
syntax.matchers.value = new RegExp(`^${ambiguousKeyPattern}:(?:${ambiguousValuePatterns.join('|')})[^|]*?(?:@|$)`);
|
|
404
432
|
}
|
|
405
433
|
if (variableKeys.length) {
|
|
406
|
-
|
|
434
|
+
syntax.matchers.variable = new RegExp(`^${ambiguousKeyPattern}:(?:${variableKeys.join('|')}(?![a-zA-Z0-9-]))[^|]*?(?:@|$)`);
|
|
407
435
|
}
|
|
408
436
|
}
|
|
409
437
|
} else {
|
|
410
|
-
|
|
438
|
+
syntax.matchers.arbitrary = matcher;
|
|
411
439
|
}
|
|
412
440
|
if (keys.length) {
|
|
413
|
-
|
|
414
|
-
|
|
441
|
+
syntax.keys = keys;
|
|
442
|
+
syntax.matchers.key = new RegExp(`^${keys.length > 1 ? `(${keys.join('|')})` : keys[0]}:.`);
|
|
443
|
+
}
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
for(const utilityName in this.components){
|
|
447
|
+
const syntaxRulesByStateToken = this.components[utilityName].map((eachSyntax)=>this.create(eachSyntax)).filter((eachSyntax)=>eachSyntax?.text).reduce((obj, eachSyntaxRule)=>{
|
|
448
|
+
if (eachSyntaxRule.stateToken in obj) {
|
|
449
|
+
obj[eachSyntaxRule.stateToken].push(eachSyntaxRule);
|
|
450
|
+
} else {
|
|
451
|
+
obj[eachSyntaxRule.stateToken] = [
|
|
452
|
+
eachSyntaxRule
|
|
453
|
+
];
|
|
415
454
|
}
|
|
455
|
+
return obj;
|
|
456
|
+
}, {});
|
|
457
|
+
this.components[utilityName] = Object.keys(syntaxRulesByStateToken).map((stateToken)=>{
|
|
458
|
+
const syntaxRules = syntaxRulesByStateToken[stateToken];
|
|
459
|
+
return syntaxRules.length === 1 ? syntaxRules[0].name : '{' + syntaxRulesByStateToken[stateToken].map((eachSyntaxRule)=>eachSyntaxRule.name.slice(0, eachSyntaxRule.name.length - eachSyntaxRule.stateToken.length)).join(';') + '}' + stateToken;
|
|
416
460
|
});
|
|
417
461
|
}
|
|
418
462
|
}
|
|
@@ -424,613 +468,187 @@ class MasterCSS {
|
|
|
424
468
|
/**
|
|
425
469
|
* 1. variable
|
|
426
470
|
* @example fg:primary bg:blue
|
|
427
|
-
*/ for (const
|
|
428
|
-
if (
|
|
471
|
+
*/ for (const eachSyntax of this.definedRules){
|
|
472
|
+
if (eachSyntax.matchers.variable?.test(className)) return eachSyntax;
|
|
429
473
|
}
|
|
430
474
|
/**
|
|
431
475
|
* 2. value (ambiguous.key * ambiguous.values)
|
|
432
476
|
* @example bg:current box:content font:12
|
|
433
|
-
*/ for (const
|
|
434
|
-
if (
|
|
477
|
+
*/ for (const eachSyntax of this.definedRules){
|
|
478
|
+
if (eachSyntax.matchers.value?.test(className)) return eachSyntax;
|
|
435
479
|
}
|
|
436
480
|
/**
|
|
437
481
|
* 3. full key
|
|
438
482
|
* @example text-align:center color:blue-40
|
|
439
|
-
*/ for (const
|
|
440
|
-
if (
|
|
483
|
+
*/ for (const eachSyntax of this.definedRules){
|
|
484
|
+
if (eachSyntax.matchers.key?.test(className)) return eachSyntax;
|
|
441
485
|
}
|
|
442
486
|
/**
|
|
443
487
|
* 4. arbitrary
|
|
444
488
|
* @example custom RegExp, utility
|
|
445
|
-
*/ for (const
|
|
446
|
-
if (
|
|
489
|
+
*/ for (const eachSyntax of this.definedRules){
|
|
490
|
+
if (eachSyntax.matchers.arbitrary?.test(className)) return eachSyntax;
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
/**
|
|
494
|
+
* Generate syntax rules from class name
|
|
495
|
+
* @param className
|
|
496
|
+
* @returns SyntaxRule[]
|
|
497
|
+
*/ generate(className, mode) {
|
|
498
|
+
let syntaxRules = [];
|
|
499
|
+
if (Object.prototype.hasOwnProperty.call(this.components, className)) {
|
|
500
|
+
syntaxRules = this.components[className].map((eachSyntax)=>this.create(eachSyntax, className, mode));
|
|
501
|
+
} else {
|
|
502
|
+
const atIndex = className.indexOf('@');
|
|
503
|
+
if (atIndex !== -1) {
|
|
504
|
+
const name = className.slice(0, atIndex);
|
|
505
|
+
if (Object.prototype.hasOwnProperty.call(this.components, name)) {
|
|
506
|
+
const atToken = className.slice(atIndex);
|
|
507
|
+
syntaxRules = this.components[name].map((eachSyntax)=>this.create(eachSyntax + atToken, className, mode));
|
|
508
|
+
} else {
|
|
509
|
+
syntaxRules = [
|
|
510
|
+
this.create(className, undefined, mode)
|
|
511
|
+
];
|
|
512
|
+
}
|
|
513
|
+
} else {
|
|
514
|
+
syntaxRules = [
|
|
515
|
+
this.create(className, undefined, mode)
|
|
516
|
+
];
|
|
517
|
+
}
|
|
447
518
|
}
|
|
519
|
+
return syntaxRules.filter((eachSyntax)=>eachSyntax?.text);
|
|
448
520
|
}
|
|
449
521
|
/**
|
|
450
|
-
*
|
|
522
|
+
* Create syntax rule from given class name
|
|
451
523
|
* @param className
|
|
452
|
-
* @returns
|
|
453
|
-
*/
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
524
|
+
* @returns SyntaxRule
|
|
525
|
+
*/ create(className, fixedClass, mode) {
|
|
526
|
+
const syntaxRule = this.generalLayer.rules.find(({ key })=>key === (fixedClass ? fixedClass + ' ' : '') + className);
|
|
527
|
+
if (syntaxRule) return syntaxRule;
|
|
528
|
+
const registeredRule = this.match(className);
|
|
529
|
+
if (registeredRule) return new SyntaxRule(className, this, registeredRule, fixedClass, mode);
|
|
457
530
|
}
|
|
458
531
|
/**
|
|
459
|
-
* Create rule from given
|
|
460
|
-
* @param
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
532
|
+
* Create syntax rule from given selector text
|
|
533
|
+
* @param selectorText
|
|
534
|
+
*/ createFromSelectorText(selectorText) {
|
|
535
|
+
const selectorTextSplits = selectorText.split(' ');
|
|
536
|
+
for(let i = 0; i < selectorTextSplits.length; i++){
|
|
537
|
+
const eachField = selectorTextSplits[i];
|
|
538
|
+
const modeSelector = this.getModeSelector(eachField);
|
|
539
|
+
if (i === 0 && eachField === modeSelector) continue;
|
|
540
|
+
if (eachField[0] === '.') {
|
|
541
|
+
const eachFieldName = eachField.slice(1);
|
|
542
|
+
let className = '';
|
|
543
|
+
for(let l = 0; l < eachFieldName.length; l++){
|
|
544
|
+
const char = eachFieldName[l];
|
|
545
|
+
const nextChar = eachFieldName[l + 1];
|
|
546
|
+
if (char === '\\') {
|
|
547
|
+
l++;
|
|
548
|
+
if (nextChar !== '\\') {
|
|
549
|
+
className += nextChar;
|
|
550
|
+
continue;
|
|
551
|
+
}
|
|
552
|
+
} else if ([
|
|
553
|
+
'.',
|
|
554
|
+
'#',
|
|
555
|
+
'[',
|
|
556
|
+
'!',
|
|
557
|
+
'*',
|
|
558
|
+
'>',
|
|
559
|
+
'+',
|
|
560
|
+
'~',
|
|
561
|
+
':'
|
|
562
|
+
].includes(char)) {
|
|
563
|
+
break;
|
|
564
|
+
}
|
|
565
|
+
className += char;
|
|
566
|
+
}
|
|
567
|
+
const syntaxRules = this.generate(className);
|
|
568
|
+
if (syntaxRules.length) return syntaxRules;
|
|
569
|
+
}
|
|
467
570
|
}
|
|
571
|
+
return [];
|
|
468
572
|
}
|
|
469
573
|
/**
|
|
470
574
|
* 根據蒐集到的所有 DOM class 重新 create
|
|
471
575
|
*/ refresh(customConfig) {
|
|
576
|
+
this.reset();
|
|
472
577
|
if (customConfig) {
|
|
473
578
|
this.customConfig = customConfig;
|
|
474
579
|
} else {
|
|
475
580
|
customConfig = this.customConfig;
|
|
476
581
|
}
|
|
477
|
-
if (!customConfig?.override) {
|
|
478
|
-
// @ts-ignore
|
|
479
|
-
this.config = extendConfig(config, customConfig);
|
|
480
|
-
} else {
|
|
481
|
-
// @ts-ignore
|
|
482
|
-
this.config = extendConfig(customConfig);
|
|
483
|
-
}
|
|
484
|
-
this.resolve();
|
|
485
|
-
this.syntaxes.length = 0;
|
|
486
582
|
// @ts-ignore
|
|
487
|
-
this.
|
|
583
|
+
this.config = customConfig?.override ? extendConfig(customConfig) : extendConfig(config, customConfig);
|
|
584
|
+
this.resolve();
|
|
488
585
|
/**
|
|
489
|
-
* 拿當前所有的 classNames 按照最新的 colors, config.
|
|
490
|
-
* 所以 refresh 過後
|
|
491
|
-
*/
|
|
492
|
-
this.add(
|
|
493
|
-
}
|
|
586
|
+
* 拿當前所有的 classNames 按照最新的 colors, config.rules 匹配並生成新的 style
|
|
587
|
+
* 所以 refresh 過後 rules 可能會變多也可能會變少
|
|
588
|
+
*/ this.classUsages.forEach((_, className)=>{
|
|
589
|
+
this.add(className);
|
|
590
|
+
});
|
|
494
591
|
return this;
|
|
495
592
|
}
|
|
496
593
|
reset() {
|
|
497
|
-
|
|
498
|
-
this.
|
|
499
|
-
|
|
500
|
-
this.
|
|
501
|
-
this.
|
|
502
|
-
this.
|
|
503
|
-
this.variablesNativeRules = {};
|
|
504
|
-
for(const keyframeName in this.animations){
|
|
505
|
-
const animation = this.animations[keyframeName];
|
|
506
|
-
animation.usage = 0;
|
|
507
|
-
animation.native = undefined;
|
|
508
|
-
}
|
|
509
|
-
for(const variableName in this.variables){
|
|
510
|
-
const variable = this.variables[variableName];
|
|
511
|
-
variable.usage = 0;
|
|
512
|
-
}
|
|
594
|
+
this.baseLayer.reset();
|
|
595
|
+
this.themeLayer.reset();
|
|
596
|
+
this.presetLayer.reset();
|
|
597
|
+
this.componentsLayer.reset();
|
|
598
|
+
this.generalLayer.reset();
|
|
599
|
+
this.animationsNonLayer.reset();
|
|
513
600
|
return this;
|
|
514
601
|
}
|
|
515
602
|
destroy() {
|
|
516
|
-
|
|
603
|
+
// @ts-ignore
|
|
604
|
+
this.classUsages = new Map();
|
|
517
605
|
masterCSSs.splice(masterCSSs.indexOf(this), 1);
|
|
518
606
|
return this;
|
|
519
607
|
}
|
|
520
608
|
add(...classNames) {
|
|
521
609
|
for (const className of classNames){
|
|
522
|
-
|
|
523
|
-
if (syntaxes.length) {
|
|
524
|
-
for (const rule of syntaxes){
|
|
525
|
-
this.insert(rule);
|
|
526
|
-
}
|
|
527
|
-
}
|
|
610
|
+
this.generate(className).forEach((eachSyntaxRule)=>eachSyntaxRule.layer.insert(eachSyntaxRule));
|
|
528
611
|
}
|
|
529
612
|
return this;
|
|
530
613
|
}
|
|
531
|
-
|
|
614
|
+
remove(...classNames) {
|
|
532
615
|
/**
|
|
533
616
|
* class name 從 DOM tree 中被移除,
|
|
534
617
|
* 匹配並刪除對應的 rule
|
|
535
|
-
*/ const
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
if (sheet && rule.natives.length) {
|
|
540
|
-
const firstNative = rule.natives[0];
|
|
541
|
-
for(let index = 0; index < sheet.cssRules.length; index++){
|
|
542
|
-
const eachCSSRule = sheet.cssRules[index];
|
|
543
|
-
if (eachCSSRule === firstNative.cssRule) {
|
|
544
|
-
for (const {} of rule.natives){
|
|
545
|
-
sheet.deleteRule(index);
|
|
546
|
-
}
|
|
547
|
-
break;
|
|
548
|
-
}
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
this.syntaxes.splice(this.syntaxes.indexOf(rule), 1);
|
|
552
|
-
delete this.ruleBy[name];
|
|
553
|
-
// variables
|
|
554
|
-
if (rule.variableNames) {
|
|
555
|
-
for (const eachVariableName of rule.variableNames){
|
|
556
|
-
const variable = this.variables[eachVariableName];
|
|
557
|
-
if (!variable.usage) variable.usage = 0;
|
|
558
|
-
if (!--variable.usage) {
|
|
559
|
-
const removeProperty = (mode)=>{
|
|
560
|
-
const nativeRule = this.variablesNativeRules[mode];
|
|
561
|
-
nativeRule.cssRule.style.removeProperty('--' + eachVariableName);
|
|
562
|
-
if (!nativeRule.cssRule.style.length) {
|
|
563
|
-
const variablesRule = this.syntaxes[0];
|
|
564
|
-
const index = variablesRule.natives.indexOf(nativeRule);
|
|
565
|
-
sheet?.deleteRule(index);
|
|
566
|
-
variablesRule.natives.splice(index, 1);
|
|
567
|
-
delete this.variablesNativeRules[mode];
|
|
568
|
-
if (!variablesRule.natives.length) {
|
|
569
|
-
this.syntaxes.splice(0, 1);
|
|
570
|
-
this.variablesNativeRules = {};
|
|
571
|
-
}
|
|
572
|
-
}
|
|
573
|
-
};
|
|
574
|
-
if (variable.value) {
|
|
575
|
-
removeProperty('');
|
|
576
|
-
}
|
|
577
|
-
if (variable.modes) {
|
|
578
|
-
for(const mode in variable.modes){
|
|
579
|
-
removeProperty(mode);
|
|
580
|
-
}
|
|
581
|
-
}
|
|
582
|
-
}
|
|
583
|
-
}
|
|
584
|
-
}
|
|
585
|
-
// animations
|
|
586
|
-
if (rule.animationNames) {
|
|
587
|
-
const keyframeRulesIndex = Object.keys(this.variablesNativeRules).length ? 1 : 0;
|
|
588
|
-
const keyframeRule = this.syntaxes[keyframeRulesIndex];
|
|
589
|
-
for (const eachKeyframeName of rule.animationNames){
|
|
590
|
-
const keyframe = this.animations[eachKeyframeName];
|
|
591
|
-
if (!keyframe.usage) keyframe.usage = 0;
|
|
592
|
-
if (!--keyframe.usage && keyframe.native) {
|
|
593
|
-
const nativeIndex = keyframeRule.natives.indexOf(keyframe.native);
|
|
594
|
-
sheet?.deleteRule(Object.keys(this.variablesNativeRules).length + nativeIndex);
|
|
595
|
-
keyframeRule.natives.splice(nativeIndex, 1);
|
|
596
|
-
keyframe.native = undefined;
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
if (!keyframeRule.natives.length) {
|
|
600
|
-
this.syntaxes.splice(keyframeRulesIndex, 1);
|
|
601
|
-
this.hasKeyframesRule = false;
|
|
618
|
+
*/ for (const className of classNames){
|
|
619
|
+
if (Object.prototype.hasOwnProperty.call(this.components, className)) {
|
|
620
|
+
for (const eachSyntax of this.components[className]){
|
|
621
|
+
this.componentsLayer.delete(className + ' ' + eachSyntax);
|
|
602
622
|
}
|
|
603
|
-
}
|
|
604
|
-
rule.definition.delete?.call(rule, name);
|
|
605
|
-
};
|
|
606
|
-
for (const className of classNames){
|
|
607
|
-
if (Object.prototype.hasOwnProperty.call(this.styles, className)) {
|
|
608
|
-
for (const eachClassName of this.styles[className]){
|
|
609
|
-
if (!Object.prototype.hasOwnProperty.call(this.classesUsage, eachClassName)) {
|
|
610
|
-
deleteRule(eachClassName);
|
|
611
|
-
}
|
|
612
|
-
}
|
|
613
|
-
delete this.ruleBy[className];
|
|
614
|
-
} else {
|
|
615
|
-
deleteRule(className);
|
|
616
|
-
}
|
|
617
|
-
}
|
|
618
|
-
}
|
|
619
|
-
/**
|
|
620
|
-
* 加工插入規則
|
|
621
|
-
* 1. where
|
|
622
|
-
* 2. normal
|
|
623
|
-
* 3. where selectors
|
|
624
|
-
* 4. normal selectors
|
|
625
|
-
* 5. media where
|
|
626
|
-
* 6. media normal
|
|
627
|
-
* 7. media where selectors
|
|
628
|
-
* 8. media selectors
|
|
629
|
-
* 9. media width where
|
|
630
|
-
* 10. media width
|
|
631
|
-
* 11. media width where selectors
|
|
632
|
-
* 12. media width selectors
|
|
633
|
-
*/ insert(rule) {
|
|
634
|
-
if (this.ruleBy[rule.className]) return;
|
|
635
|
-
let index;
|
|
636
|
-
/**
|
|
637
|
-
* 必須按斷點值遞增,並透過索引插入,
|
|
638
|
-
* 以實現響應式先後套用的規則
|
|
639
|
-
* @example <1 <2 <3 ALL >=1 >=2 >=3
|
|
640
|
-
* @description
|
|
641
|
-
*/ const endIndex = this.syntaxes.length - 1;
|
|
642
|
-
const { at, atToken, order, priority, hasWhere, className } = rule;
|
|
643
|
-
const findIndex = (startIndex, stopCheck, matchCheck)=>{
|
|
644
|
-
let i = startIndex;
|
|
645
|
-
for(; i <= endIndex; i++){
|
|
646
|
-
const eachSyntax = this.syntaxes[i];
|
|
647
|
-
if (stopCheck?.(eachSyntax)) return matchCheck ? -1 : i - 1;
|
|
648
|
-
if (matchCheck?.(eachSyntax)) return i;
|
|
649
|
-
}
|
|
650
|
-
return matchCheck ? -1 : i - 1;
|
|
651
|
-
};
|
|
652
|
-
let matchStartIndex;
|
|
653
|
-
let matchEndIndex;
|
|
654
|
-
if (atToken) {
|
|
655
|
-
const mediaStartIndex = this.syntaxes.findIndex((eachSyntax)=>eachSyntax.at?.media);
|
|
656
|
-
if (mediaStartIndex === -1) {
|
|
657
|
-
index = endIndex + 1;
|
|
658
623
|
} else {
|
|
659
|
-
const
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
if (maxWidthFeature && minWidthFeature) {
|
|
667
|
-
/**
|
|
668
|
-
* 範圍越小 ( 越限定 越侷限 ) 越優先,
|
|
669
|
-
* 按照範圍 max-width - min-width 遞減排序
|
|
670
|
-
* find 第一個所遇到同樣 feature 且範圍值比自己大的 rule,
|
|
671
|
-
* 並插入在該 rule 之後,讓自己優先被套用
|
|
672
|
-
*/ if (priority === -1) {
|
|
673
|
-
matchStartIndex = findIndex(mediaWidthStartIndex, (eachSyntax)=>eachSyntax.priority !== -1, (eachSyntax)=>eachSyntax.at.media?.find(({ name })=>name === 'max-width') && eachSyntax.at.media?.find(({ name })=>name === 'min-width'));
|
|
674
|
-
matchEndIndex = findIndex(mediaWidthStartIndex, (eachSyntax)=>eachSyntax.priority !== -1);
|
|
675
|
-
} else {
|
|
676
|
-
matchStartIndex = findIndex(mediaWidthStartIndex, undefined, (eachSyntax)=>eachSyntax.at.media?.find(({ name })=>name === 'max-width') && eachSyntax.at.media?.find(({ name })=>name === 'min-width') && eachSyntax.priority !== -1);
|
|
677
|
-
matchEndIndex = endIndex;
|
|
678
|
-
}
|
|
679
|
-
if (matchStartIndex !== -1) {
|
|
680
|
-
const range = maxWidthFeature.value - minWidthFeature.value;
|
|
681
|
-
let i = matchEndIndex;
|
|
682
|
-
const endI = matchStartIndex;
|
|
683
|
-
matchStartIndex = matchEndIndex + 1;
|
|
684
|
-
for(; i >= endI; i--){
|
|
685
|
-
const eachSyntax = this.syntaxes[i];
|
|
686
|
-
const eachMaxWidthFeature = eachSyntax.at.media?.find(({ name })=>name === 'max-width');
|
|
687
|
-
const eachMinWidthFeature = eachSyntax.at.media?.find(({ name })=>name === 'min-width');
|
|
688
|
-
if (!eachMaxWidthFeature || !eachMinWidthFeature) {
|
|
689
|
-
break;
|
|
690
|
-
} else {
|
|
691
|
-
const eachRange = eachMaxWidthFeature.value - eachMinWidthFeature.value;
|
|
692
|
-
if (eachRange < range) {
|
|
693
|
-
matchEndIndex = i - 1;
|
|
694
|
-
} else if (eachRange === range) {
|
|
695
|
-
matchStartIndex = i;
|
|
696
|
-
} else {
|
|
697
|
-
break;
|
|
698
|
-
}
|
|
699
|
-
}
|
|
700
|
-
}
|
|
701
|
-
}
|
|
702
|
-
} else if (minWidthFeature) {
|
|
703
|
-
/**
|
|
704
|
-
* find 第一個所遇到同樣 feature 且值比自己大的 rule,
|
|
705
|
-
* 並插入在該 rule 之後,讓自己優先被套用
|
|
706
|
-
*/ if (priority === -1) {
|
|
707
|
-
matchStartIndex = findIndex(mediaWidthStartIndex, (eachSyntax)=>eachSyntax.at.media?.find(({ name })=>name === 'max-width') && eachSyntax.at.media?.find(({ name })=>name === 'min-width') || eachSyntax.priority !== -1, (eachSyntax)=>!eachSyntax.at.media?.find(({ name })=>name === 'max-width') && eachSyntax.at.media?.find(({ name })=>name === 'min-width'));
|
|
708
|
-
matchEndIndex = findIndex(mediaWidthStartIndex, (eachSyntax)=>eachSyntax.at.media?.find(({ name })=>name === 'max-width') && eachSyntax.at.media?.find(({ name })=>name === 'min-width') || eachSyntax.priority !== -1);
|
|
709
|
-
} else {
|
|
710
|
-
matchStartIndex = findIndex(mediaWidthStartIndex, (eachSyntax)=>eachSyntax.at.media?.find(({ name })=>name === 'max-width') && eachSyntax.at.media?.find(({ name })=>name === 'min-width') && eachSyntax.priority !== -1, (eachSyntax)=>!eachSyntax.at.media?.find(({ name })=>name === 'max-width') && eachSyntax.at.media?.find(({ name })=>name === 'min-width') && eachSyntax.priority !== -1);
|
|
711
|
-
matchEndIndex = findIndex(mediaWidthStartIndex, (eachSyntax)=>eachSyntax.at.media?.find(({ name })=>name === 'max-width') && eachSyntax.at.media?.find(({ name })=>name === 'min-width') && eachSyntax.priority !== -1);
|
|
712
|
-
}
|
|
713
|
-
if (matchStartIndex !== -1) {
|
|
714
|
-
for(let i = matchEndIndex; i >= matchStartIndex; i--){
|
|
715
|
-
const value = (this.syntaxes[i].at.media?.find(({ name })=>name === 'min-width')).value;
|
|
716
|
-
if (value > minWidthFeature.value) {
|
|
717
|
-
matchEndIndex = i - 1;
|
|
718
|
-
} else if (value < minWidthFeature.value) {
|
|
719
|
-
matchStartIndex = i + 1;
|
|
720
|
-
break;
|
|
721
|
-
}
|
|
722
|
-
}
|
|
723
|
-
}
|
|
724
|
-
} else {
|
|
725
|
-
/**
|
|
726
|
-
* find 第一個所遇到同樣 feature 且值比自己大的 rule,
|
|
727
|
-
* 並插入在該 rule 之後,讓自己優先被套用
|
|
728
|
-
*/ if (priority === -1) {
|
|
729
|
-
matchStartIndex = findIndex(mediaWidthStartIndex, (eachSyntax)=>eachSyntax.at.media?.find(({ name })=>name === 'min-width') || eachSyntax.priority !== -1, (eachSyntax)=>eachSyntax.at.media?.find(({ name })=>name === 'max-width'));
|
|
730
|
-
matchEndIndex = findIndex(mediaWidthStartIndex, (eachSyntax)=>eachSyntax.at.media?.find(({ name })=>name === 'min-width') || eachSyntax.priority !== -1);
|
|
731
|
-
} else {
|
|
732
|
-
matchStartIndex = findIndex(mediaWidthStartIndex, (eachSyntax)=>eachSyntax.at.media?.find(({ name })=>name === 'min-width') && eachSyntax.priority !== -1, (eachSyntax)=>eachSyntax.at.media?.find(({ name })=>name === 'max-width') && eachSyntax.priority !== -1);
|
|
733
|
-
matchEndIndex = findIndex(mediaWidthStartIndex, (eachSyntax)=>eachSyntax.at.media?.find(({ name })=>name === 'min-width') && eachSyntax.priority !== -1);
|
|
734
|
-
}
|
|
735
|
-
if (matchStartIndex !== -1) {
|
|
736
|
-
for(let i = matchEndIndex; i >= matchStartIndex; i--){
|
|
737
|
-
const value = (this.syntaxes[i].at.media?.find(({ name })=>name === 'max-width')).value;
|
|
738
|
-
if (value < maxWidthFeature.value) {
|
|
739
|
-
matchEndIndex = i - 1;
|
|
740
|
-
} else if (value > maxWidthFeature.value) {
|
|
741
|
-
matchStartIndex = i + 1;
|
|
742
|
-
break;
|
|
743
|
-
}
|
|
744
|
-
}
|
|
745
|
-
}
|
|
624
|
+
const atIndex = className.indexOf('@');
|
|
625
|
+
if (atIndex !== -1) {
|
|
626
|
+
const name = className.slice(0, atIndex);
|
|
627
|
+
if (Object.prototype.hasOwnProperty.call(this.components, name)) {
|
|
628
|
+
const atToken = className.slice(atIndex);
|
|
629
|
+
for (const eachSyntax of this.components[name]){
|
|
630
|
+
this.componentsLayer.delete(eachSyntax + atToken + ' ' + className);
|
|
746
631
|
}
|
|
747
|
-
}
|
|
748
|
-
} else {
|
|
749
|
-
if (priority === -1) {
|
|
750
|
-
matchStartIndex = mediaStartIndex;
|
|
751
|
-
matchEndIndex = findIndex(mediaStartIndex, (eachSyntax)=>eachSyntax.at.media?.find(({ name })=>name === 'max-width' || name === 'min-width') || eachSyntax.priority !== -1);
|
|
752
632
|
} else {
|
|
753
|
-
|
|
754
|
-
matchEndIndex = findIndex(mediaStartIndex, (eachSyntax)=>eachSyntax.at.media?.find(({ name })=>name === 'max-width' || name === 'min-width'));
|
|
755
|
-
}
|
|
756
|
-
}
|
|
757
|
-
}
|
|
758
|
-
} else {
|
|
759
|
-
const findStartIndex = Object.keys(this.variablesNativeRules).length ? this.hasKeyframesRule ? 2 : 1 : this.hasKeyframesRule ? 1 : 0;
|
|
760
|
-
if (priority === -1) {
|
|
761
|
-
matchStartIndex = findStartIndex;
|
|
762
|
-
matchEndIndex = findIndex(findStartIndex, (eachSyntax)=>eachSyntax.atToken || eachSyntax.priority !== -1);
|
|
763
|
-
} else {
|
|
764
|
-
matchStartIndex = findIndex(findStartIndex, (eachSyntax)=>eachSyntax.atToken, (eachSyntax)=>eachSyntax.priority !== -1);
|
|
765
|
-
matchEndIndex = findIndex(findStartIndex, (eachSyntax)=>eachSyntax.atToken);
|
|
766
|
-
}
|
|
767
|
-
}
|
|
768
|
-
if (index === undefined && matchEndIndex !== undefined && matchStartIndex !== undefined) {
|
|
769
|
-
if (matchStartIndex === -1) {
|
|
770
|
-
index = matchEndIndex + 1;
|
|
771
|
-
} else {
|
|
772
|
-
if (priority === -1) {
|
|
773
|
-
for(let i = matchStartIndex; i <= matchEndIndex; i++){
|
|
774
|
-
const currentRule = this.syntaxes[i];
|
|
775
|
-
if (!hasWhere && currentRule.hasWhere) continue;
|
|
776
|
-
if (hasWhere && !currentRule.hasWhere || currentRule.order >= order) {
|
|
777
|
-
index = i;
|
|
778
|
-
break;
|
|
779
|
-
}
|
|
633
|
+
this.generalLayer.delete(className);
|
|
780
634
|
}
|
|
781
635
|
} else {
|
|
782
|
-
|
|
783
|
-
const currentRule = this.syntaxes[i];
|
|
784
|
-
if (!hasWhere && currentRule.hasWhere) continue;
|
|
785
|
-
if (hasWhere && !currentRule.hasWhere) {
|
|
786
|
-
index = i;
|
|
787
|
-
break;
|
|
788
|
-
}
|
|
789
|
-
if (currentRule.priority < priority) {
|
|
790
|
-
index = i;
|
|
791
|
-
break;
|
|
792
|
-
} else if (currentRule.priority === priority) {
|
|
793
|
-
if (currentRule.order >= order) {
|
|
794
|
-
index = i;
|
|
795
|
-
break;
|
|
796
|
-
}
|
|
797
|
-
} else {
|
|
798
|
-
index = i + 1;
|
|
799
|
-
}
|
|
800
|
-
}
|
|
801
|
-
}
|
|
802
|
-
if (index === undefined) {
|
|
803
|
-
index = matchEndIndex + 1;
|
|
636
|
+
this.generalLayer.delete(className);
|
|
804
637
|
}
|
|
805
638
|
}
|
|
806
639
|
}
|
|
807
|
-
this.syntaxes.splice(index, 0, rule);
|
|
808
|
-
this.ruleBy[className] = rule;
|
|
809
|
-
if (this.style) {
|
|
810
|
-
const sheet = this.style.sheet;
|
|
811
|
-
let cssRuleIndex = 0;
|
|
812
|
-
const getCssRuleIndex = (index)=>{
|
|
813
|
-
const previousRule = this.syntaxes[index];
|
|
814
|
-
if (previousRule) {
|
|
815
|
-
if (!previousRule.natives.length) return getCssRuleIndex(index - 1);
|
|
816
|
-
const lastNative = previousRule.natives[previousRule.natives.length - 1];
|
|
817
|
-
const lastNativeCssRule = lastNative.cssRule?.parentRule ?? lastNative.cssRule;
|
|
818
|
-
if (sheet) for(let i = 0; i < sheet.cssRules.length; i++){
|
|
819
|
-
if (sheet.cssRules[i] === lastNativeCssRule) {
|
|
820
|
-
cssRuleIndex = i + 1;
|
|
821
|
-
break;
|
|
822
|
-
}
|
|
823
|
-
}
|
|
824
|
-
}
|
|
825
|
-
};
|
|
826
|
-
getCssRuleIndex(index - 1);
|
|
827
|
-
for(let i = 0; i < rule.natives.length;){
|
|
828
|
-
try {
|
|
829
|
-
const native = rule.natives[i];
|
|
830
|
-
sheet?.insertRule(native.text, cssRuleIndex);
|
|
831
|
-
native.cssRule = sheet?.cssRules[cssRuleIndex++];
|
|
832
|
-
i++;
|
|
833
|
-
} catch (error) {
|
|
834
|
-
console.error(error);
|
|
835
|
-
rule.natives.splice(i, 1);
|
|
836
|
-
}
|
|
837
|
-
}
|
|
838
|
-
}
|
|
839
|
-
// variables
|
|
840
|
-
this.handleRuleWithVariableNames(rule);
|
|
841
|
-
// animations
|
|
842
|
-
this.handleRuleWithAnimationNames(rule);
|
|
843
|
-
rule.definition.insert?.call(rule);
|
|
844
|
-
return index;
|
|
845
|
-
}
|
|
846
|
-
get text() {
|
|
847
|
-
return this.syntaxes.map((eachSyntax)=>eachSyntax.text).join('');
|
|
848
640
|
}
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
const nativeRule = {
|
|
858
|
-
text: `@keyframes ${eachKeyframeName}{` + Object.entries(animation).filter(([key])=>key !== 'usage' && key !== 'native').map(([key, variables])=>`${key}{${Object.entries(variables).map(([name, value])=>name + ':' + value).join(';')}}`).join('') + '}'
|
|
859
|
-
};
|
|
860
|
-
const keyframeRulesIndex = Object.keys(this.variablesNativeRules).length ? 1 : 0;
|
|
861
|
-
let keyframeRule;
|
|
862
|
-
if (this.hasKeyframesRule) {
|
|
863
|
-
(keyframeRule = this.syntaxes[keyframeRulesIndex]).natives.push(nativeRule);
|
|
864
|
-
} else {
|
|
865
|
-
this.syntaxes.splice(keyframeRulesIndex, 0, keyframeRule = {
|
|
866
|
-
natives: [
|
|
867
|
-
nativeRule
|
|
868
|
-
],
|
|
869
|
-
get text () {
|
|
870
|
-
return this.natives.map((eachNative)=>eachNative.text).join('');
|
|
871
|
-
}
|
|
872
|
-
});
|
|
873
|
-
this.hasKeyframesRule = true;
|
|
874
|
-
}
|
|
875
|
-
if (sheet) {
|
|
876
|
-
let cssRule;
|
|
877
|
-
if (initializing) {
|
|
878
|
-
for (const eachCSSRule of sheet.cssRules){
|
|
879
|
-
if (eachCSSRule.constructor.name === 'CSSKeyframesRule' && eachCSSRule.name === eachKeyframeName) {
|
|
880
|
-
cssRule = eachCSSRule;
|
|
881
|
-
break;
|
|
882
|
-
}
|
|
883
|
-
}
|
|
884
|
-
}
|
|
885
|
-
if (cssRule) {
|
|
886
|
-
nativeRule.cssRule = cssRule;
|
|
887
|
-
} else {
|
|
888
|
-
const cssRuleIndex = Object.keys(this.variablesNativeRules).length + keyframeRule.natives.length - 1;
|
|
889
|
-
sheet.insertRule(nativeRule.text, cssRuleIndex);
|
|
890
|
-
nativeRule.cssRule = sheet.cssRules[cssRuleIndex];
|
|
891
|
-
}
|
|
892
|
-
}
|
|
893
|
-
animation.usage = 1;
|
|
894
|
-
animation.native = nativeRule;
|
|
895
|
-
}
|
|
641
|
+
getModeSelector(modeName) {
|
|
642
|
+
const mode = this.config.modes?.[modeName];
|
|
643
|
+
if (mode) {
|
|
644
|
+
switch(mode){
|
|
645
|
+
case 'class':
|
|
646
|
+
return '.' + modeName;
|
|
647
|
+
case 'host':
|
|
648
|
+
return ':host(.' + modeName + ')';
|
|
896
649
|
}
|
|
897
650
|
}
|
|
898
651
|
}
|
|
899
|
-
handleRuleWithVariableNames(rule, initializing = false) {
|
|
900
|
-
if (rule.variableNames) {
|
|
901
|
-
const sheet = this.style?.sheet;
|
|
902
|
-
for (const eachVariableName of rule.variableNames){
|
|
903
|
-
const variable = this.variables[eachVariableName];
|
|
904
|
-
if (variable.usage) {
|
|
905
|
-
variable.usage++;
|
|
906
|
-
} else {
|
|
907
|
-
const addProperty = (mode, variable)=>{
|
|
908
|
-
let nativeRule = this.variablesNativeRules[mode];
|
|
909
|
-
if (!nativeRule) {
|
|
910
|
-
let cssRule;
|
|
911
|
-
let mediaConditionText;
|
|
912
|
-
let selectorText;
|
|
913
|
-
if (mode) {
|
|
914
|
-
switch(this.config.modes?.[mode]){
|
|
915
|
-
case 'media':
|
|
916
|
-
mediaConditionText = `@media(prefers-color-scheme:${mode})`;
|
|
917
|
-
selectorText = ':root';
|
|
918
|
-
break;
|
|
919
|
-
case 'host':
|
|
920
|
-
selectorText = `:host(.${mode})`;
|
|
921
|
-
if (this.config.defaultMode === mode) {
|
|
922
|
-
selectorText += ',:host';
|
|
923
|
-
}
|
|
924
|
-
break;
|
|
925
|
-
case 'class':
|
|
926
|
-
selectorText = '.' + mode;
|
|
927
|
-
if (this.config.defaultMode === mode) {
|
|
928
|
-
selectorText += ',:root';
|
|
929
|
-
}
|
|
930
|
-
break;
|
|
931
|
-
default:
|
|
932
|
-
return;
|
|
933
|
-
}
|
|
934
|
-
} else {
|
|
935
|
-
selectorText = ':root';
|
|
936
|
-
}
|
|
937
|
-
if (sheet) {
|
|
938
|
-
const newCSSRuleIndex = Object.keys(this.variablesNativeRules).length ? this.syntaxes[0].natives.length : 0;
|
|
939
|
-
sheet.insertRule((mediaConditionText ? mediaConditionText + '{' : '') + selectorText + '{}' + (mediaConditionText ? mediaConditionText + '}' : ''), newCSSRuleIndex);
|
|
940
|
-
cssRule = mediaConditionText ? sheet.cssRules[newCSSRuleIndex].cssRules[0] : sheet.cssRules[newCSSRuleIndex];
|
|
941
|
-
} else {
|
|
942
|
-
const styleMap = new Map();
|
|
943
|
-
const style = Object.defineProperties({}, {
|
|
944
|
-
getPropertyValue: {
|
|
945
|
-
value: (property)=>styleMap.get(property)
|
|
946
|
-
},
|
|
947
|
-
removeProperty: {
|
|
948
|
-
value: (property)=>{
|
|
949
|
-
styleMap.delete(property);
|
|
950
|
-
for(let i = 0; i < style.length; i++){
|
|
951
|
-
if (style[i] === property) {
|
|
952
|
-
delete style[i];
|
|
953
|
-
}
|
|
954
|
-
}
|
|
955
|
-
}
|
|
956
|
-
},
|
|
957
|
-
setProperty: {
|
|
958
|
-
value: (property, value)=>{
|
|
959
|
-
style[style.length] = property;
|
|
960
|
-
styleMap.set(property, value);
|
|
961
|
-
}
|
|
962
|
-
},
|
|
963
|
-
length: {
|
|
964
|
-
get () {
|
|
965
|
-
return Object.keys(style).length;
|
|
966
|
-
}
|
|
967
|
-
}
|
|
968
|
-
});
|
|
969
|
-
cssRule = {
|
|
970
|
-
selectorText,
|
|
971
|
-
style,
|
|
972
|
-
styleMap
|
|
973
|
-
};
|
|
974
|
-
if (mediaConditionText) {
|
|
975
|
-
// @ts-ignore
|
|
976
|
-
cssRule.parentRule = {
|
|
977
|
-
conditionText: mediaConditionText
|
|
978
|
-
};
|
|
979
|
-
}
|
|
980
|
-
}
|
|
981
|
-
nativeRule = this.pushVariableNativeRule(mode, cssRule);
|
|
982
|
-
}
|
|
983
|
-
const propertyName = '--' + eachVariableName;
|
|
984
|
-
if (!initializing || !nativeRule.cssRule.style.getPropertyValue(propertyName)) {
|
|
985
|
-
nativeRule.cssRule.style.setProperty(propertyName, String(variable.value));
|
|
986
|
-
}
|
|
987
|
-
};
|
|
988
|
-
if (variable.value) {
|
|
989
|
-
addProperty('', variable);
|
|
990
|
-
}
|
|
991
|
-
if (variable.modes) {
|
|
992
|
-
for(const mode in variable.modes){
|
|
993
|
-
addProperty(mode, variable.modes[mode]);
|
|
994
|
-
}
|
|
995
|
-
}
|
|
996
|
-
variable.usage = 1;
|
|
997
|
-
}
|
|
998
|
-
}
|
|
999
|
-
}
|
|
1000
|
-
}
|
|
1001
|
-
pushVariableNativeRule(mode, variableCSSRule) {
|
|
1002
|
-
if (!Object.keys(this.variablesNativeRules).length) {
|
|
1003
|
-
this.variablesNativeRules = {};
|
|
1004
|
-
const newRule = {
|
|
1005
|
-
natives: [],
|
|
1006
|
-
get text () {
|
|
1007
|
-
return this.natives.map((eachNative)=>eachNative.text).join('');
|
|
1008
|
-
}
|
|
1009
|
-
};
|
|
1010
|
-
this.syntaxes.splice(0, 0, newRule);
|
|
1011
|
-
}
|
|
1012
|
-
let prefix = '';
|
|
1013
|
-
let suffix = '}';
|
|
1014
|
-
if (variableCSSRule.parentRule) {
|
|
1015
|
-
prefix += '@media' + variableCSSRule.parentRule.conditionText.replace(/ /g, '') + '{';
|
|
1016
|
-
suffix += '}';
|
|
1017
|
-
}
|
|
1018
|
-
prefix += variableCSSRule.selectorText + '{';
|
|
1019
|
-
const nativeRule = {
|
|
1020
|
-
cssRule: variableCSSRule,
|
|
1021
|
-
get text () {
|
|
1022
|
-
const properties = [];
|
|
1023
|
-
// eslint-disable-next-line @typescript-eslint/prefer-for-of
|
|
1024
|
-
for(let i = 0; i < variableCSSRule.style.length; i++){
|
|
1025
|
-
const property = variableCSSRule.style[i];
|
|
1026
|
-
properties.push(property + ':' + variableCSSRule.style.getPropertyValue(property));
|
|
1027
|
-
}
|
|
1028
|
-
return prefix + properties.join(';') + suffix;
|
|
1029
|
-
}
|
|
1030
|
-
};
|
|
1031
|
-
this.syntaxes[0].natives.push(this.variablesNativeRules[mode] = nativeRule);
|
|
1032
|
-
return nativeRule;
|
|
1033
|
-
}
|
|
1034
652
|
}
|
|
1035
653
|
const masterCSSs = [];
|
|
1036
654
|
(()=>{
|