@master/css 2.0.0-rc.61 → 2.0.0-rc.63
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 +52 -1
- package/dist/common.d.ts +15 -0
- package/dist/common.mjs +46 -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 +25 -13
- package/dist/config/rules.d.ts +4 -2
- package/dist/config/rules.mjs +25 -13
- 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 +13 -4
- 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 +39 -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 +116 -328
- package/dist/syntax-rule.d.ts +18 -25
- package/dist/syntax-rule.mjs +117 -329
- 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 +114 -0
- package/dist/utils/parse-selector.d.ts +19 -0
- package/dist/utils/parse-selector.mjs +112 -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 +86 -0
- package/dist/utils/{reorder-for-readable-classes.d.ts → sort-readable-classes.d.ts} +1 -1
- package/dist/utils/sort-readable-classes.mjs +84 -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/rule-node.cjs +0 -18
- package/dist/rule-node.d.ts +0 -14
- package/dist/rule-node.mjs +0 -16
- package/dist/utils/are-rule-at-equal.cjs +0 -12
- package/dist/utils/are-rule-at-equal.d.ts +0 -2
- package/dist/utils/are-rule-at-equal.mjs +0 -10
- 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
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { SELECTOR_COMBINATORS } from '../common.mjs';
|
|
2
|
+
import MasterCSS from '../core.mjs';
|
|
3
|
+
import parsePair from './parse-pair.mjs';
|
|
4
|
+
|
|
5
|
+
const SELECTOR_REGEX = new RegExp(`(?:[a-zA-Z0-9-]+)|([${SELECTOR_COMBINATORS.join('')}.:,*])|(a-zA-Z0-9-)`, 'g');
|
|
6
|
+
function parseSelector(token, css = new MasterCSS(), isRaw = true) {
|
|
7
|
+
const resolve = (eachToken)=>{
|
|
8
|
+
const nodes = [];
|
|
9
|
+
let currentPrefix = '';
|
|
10
|
+
let tokenIndex = 0;
|
|
11
|
+
for (const match of eachToken.matchAll(SELECTOR_REGEX)){
|
|
12
|
+
const raw = match[0];
|
|
13
|
+
tokenIndex += raw.length;
|
|
14
|
+
if (raw === ':' || raw === '.') {
|
|
15
|
+
currentPrefix += raw;
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
let type;
|
|
19
|
+
let value = raw;
|
|
20
|
+
const definedNodes = css.selectors.get(currentPrefix + raw);
|
|
21
|
+
if (definedNodes) {
|
|
22
|
+
const firstNode = definedNodes[definedNodes.length - 1];
|
|
23
|
+
nodes.push(definedNodes.length === 1 && firstNode.type ? {
|
|
24
|
+
...firstNode,
|
|
25
|
+
raw: currentPrefix + raw
|
|
26
|
+
} : {
|
|
27
|
+
children: definedNodes,
|
|
28
|
+
raw: currentPrefix + raw
|
|
29
|
+
});
|
|
30
|
+
currentPrefix = '';
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
if (SELECTOR_COMBINATORS.includes(raw)) {
|
|
34
|
+
type = 'combinator';
|
|
35
|
+
if (raw === '_') {
|
|
36
|
+
const nextRawValue = eachToken[tokenIndex];
|
|
37
|
+
const prevRawValue = eachToken[tokenIndex - raw.length - 1];
|
|
38
|
+
if (prevRawValue !== '_' && nextRawValue !== '_') {
|
|
39
|
+
value = ' ' // support BEM __
|
|
40
|
+
;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
} else if (raw === ',') {
|
|
44
|
+
type = 'separator';
|
|
45
|
+
} else if (raw === '*') {
|
|
46
|
+
type = 'universal';
|
|
47
|
+
} else if (currentPrefix === ':') {
|
|
48
|
+
type = 'pseudo-class';
|
|
49
|
+
} else if (currentPrefix === '::') {
|
|
50
|
+
type = 'pseudo-element';
|
|
51
|
+
} else if (currentPrefix === '.') {
|
|
52
|
+
type = 'class';
|
|
53
|
+
}
|
|
54
|
+
nodes.push({
|
|
55
|
+
value,
|
|
56
|
+
...isRaw && {
|
|
57
|
+
raw: currentPrefix + raw
|
|
58
|
+
},
|
|
59
|
+
...type && {
|
|
60
|
+
type
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
currentPrefix = '';
|
|
64
|
+
}
|
|
65
|
+
return nodes;
|
|
66
|
+
};
|
|
67
|
+
const pair = (eachToken, nodes = [])=>{
|
|
68
|
+
const paired = parsePair(eachToken);
|
|
69
|
+
if (paired) {
|
|
70
|
+
let { pre, body, post } = paired;
|
|
71
|
+
let name;
|
|
72
|
+
if (body) {
|
|
73
|
+
const lastColonIndex = pre.lastIndexOf(':');
|
|
74
|
+
if (lastColonIndex !== -1) {
|
|
75
|
+
name = pre.slice(lastColonIndex);
|
|
76
|
+
pre = pre.slice(0, lastColonIndex);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (pre) nodes.push(...pair(pre));
|
|
80
|
+
if (body) {
|
|
81
|
+
const children = pair(body);
|
|
82
|
+
if (name) {
|
|
83
|
+
const node = resolve(name)[0];
|
|
84
|
+
if (children.length) node.children = children;
|
|
85
|
+
nodes.push(node);
|
|
86
|
+
} else {
|
|
87
|
+
nodes.push(...children);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (post) nodes.push(...pair(post));
|
|
91
|
+
return nodes;
|
|
92
|
+
}
|
|
93
|
+
const attrPaired = parsePair(eachToken, '[', ']');
|
|
94
|
+
if (attrPaired) {
|
|
95
|
+
const { pre, body, post } = attrPaired;
|
|
96
|
+
if (pre) nodes.push(...pair(pre));
|
|
97
|
+
nodes.push({
|
|
98
|
+
value: body,
|
|
99
|
+
type: 'attribute',
|
|
100
|
+
...isRaw && {
|
|
101
|
+
raw: `[${body}]`
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
if (post) nodes.push(...pair(post));
|
|
105
|
+
return nodes;
|
|
106
|
+
}
|
|
107
|
+
return resolve(eachToken);
|
|
108
|
+
};
|
|
109
|
+
return pair(token);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export { parseSelector as default };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var common = require('../common.cjs');
|
|
4
|
+
|
|
5
|
+
function parseValue(token, unit = '', rootSize = 1) {
|
|
6
|
+
const isNumber = typeof token === 'number';
|
|
7
|
+
const defaultUnit = unit;
|
|
8
|
+
// 如果是純數字
|
|
9
|
+
if (isNumber) {
|
|
10
|
+
return {
|
|
11
|
+
unit: defaultUnit,
|
|
12
|
+
type: 'number',
|
|
13
|
+
value: defaultUnit === 'rem' || defaultUnit === 'em' ? token / rootSize : token
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
const matches = token.match(common.UNIT_REGEX);
|
|
17
|
+
if (matches) {
|
|
18
|
+
let value = parseFloat(matches[1]);
|
|
19
|
+
let parsedUnit = matches[2] || '';
|
|
20
|
+
if (!parsedUnit && (defaultUnit === 'rem' || defaultUnit === 'em')) {
|
|
21
|
+
value = value / rootSize;
|
|
22
|
+
parsedUnit = defaultUnit;
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
token,
|
|
26
|
+
value,
|
|
27
|
+
unit: parsedUnit || defaultUnit,
|
|
28
|
+
type: 'number'
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
// 無法解析則當作純字串
|
|
32
|
+
return {
|
|
33
|
+
token,
|
|
34
|
+
value: token,
|
|
35
|
+
type: 'string'
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
module.exports = parseValue;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { UNIT_REGEX } from '../common.mjs';
|
|
2
|
+
|
|
3
|
+
function parseValue(token, unit = '', rootSize = 1) {
|
|
4
|
+
const isNumber = typeof token === 'number';
|
|
5
|
+
const defaultUnit = unit;
|
|
6
|
+
// 如果是純數字
|
|
7
|
+
if (isNumber) {
|
|
8
|
+
return {
|
|
9
|
+
unit: defaultUnit,
|
|
10
|
+
type: 'number',
|
|
11
|
+
value: defaultUnit === 'rem' || defaultUnit === 'em' ? token / rootSize : token
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
const matches = token.match(UNIT_REGEX);
|
|
15
|
+
if (matches) {
|
|
16
|
+
let value = parseFloat(matches[1]);
|
|
17
|
+
let parsedUnit = matches[2] || '';
|
|
18
|
+
if (!parsedUnit && (defaultUnit === 'rem' || defaultUnit === 'em')) {
|
|
19
|
+
value = value / rootSize;
|
|
20
|
+
parsedUnit = defaultUnit;
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
token,
|
|
24
|
+
value,
|
|
25
|
+
unit: parsedUnit || defaultUnit,
|
|
26
|
+
type: 'number'
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
// 無法解析則當作純字串
|
|
30
|
+
return {
|
|
31
|
+
token,
|
|
32
|
+
value: token,
|
|
33
|
+
type: 'string'
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export { parseValue as default };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
function replaceCharOutsideQuotes(str, target, replace) {
|
|
4
|
+
let result = '';
|
|
5
|
+
let inSingle = false;
|
|
6
|
+
let inDouble = false;
|
|
7
|
+
for(let i = 0; i < str.length; i++){
|
|
8
|
+
const char = str[i];
|
|
9
|
+
const prev = str[i - 1];
|
|
10
|
+
if (char === '\'' && prev !== '\\' && !inDouble) inSingle = !inSingle;
|
|
11
|
+
else if (char === '"' && prev !== '\\' && !inSingle) inDouble = !inDouble;
|
|
12
|
+
if (char === target && !inSingle && !inDouble) {
|
|
13
|
+
result += replace;
|
|
14
|
+
} else {
|
|
15
|
+
result += char;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return result;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
module.exports = replaceCharOutsideQuotes;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function replaceCharOutsideQuotes(str: string, target: string, replace: string): string;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
function replaceCharOutsideQuotes(str, target, replace) {
|
|
2
|
+
let result = '';
|
|
3
|
+
let inSingle = false;
|
|
4
|
+
let inDouble = false;
|
|
5
|
+
for(let i = 0; i < str.length; i++){
|
|
6
|
+
const char = str[i];
|
|
7
|
+
const prev = str[i - 1];
|
|
8
|
+
if (char === '\'' && prev !== '\\' && !inDouble) inSingle = !inSingle;
|
|
9
|
+
else if (char === '"' && prev !== '\\' && !inSingle) inDouble = !inDouble;
|
|
10
|
+
if (char === target && !inSingle && !inDouble) {
|
|
11
|
+
result += replace;
|
|
12
|
+
} else {
|
|
13
|
+
result += char;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return result;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export { replaceCharOutsideQuotes as default };
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var syntaxRuleType = require('../syntax-rule-type.cjs');
|
|
4
|
+
var core = require('../core.cjs');
|
|
5
|
+
var compareRulePriority = require('./compare-rule-priority.cjs');
|
|
6
|
+
var common = require('../common.cjs');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Sorts classes in a consistent order
|
|
10
|
+
* @param classes
|
|
11
|
+
* @param options
|
|
12
|
+
* @returns consistent classes
|
|
13
|
+
*/ function sortReadableClasses(classes, css = new core()) {
|
|
14
|
+
const shouldSortClasses = [];
|
|
15
|
+
const unsortedClasses = [];
|
|
16
|
+
for (const className of classes){
|
|
17
|
+
if (className.includes(common.__UNSORTED__)) {
|
|
18
|
+
unsortedClasses.push(className);
|
|
19
|
+
} else {
|
|
20
|
+
shouldSortClasses.push(className);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
css.add(...shouldSortClasses);
|
|
24
|
+
// 先去重 fixedClass for componentsLayer
|
|
25
|
+
const seenFixed = new Set();
|
|
26
|
+
const dedupedComponentRules = css.componentsLayer.rules.filter((rule)=>{
|
|
27
|
+
if (!rule.fixedClass) return true;
|
|
28
|
+
if (seenFixed.has(rule.fixedClass)) return false;
|
|
29
|
+
seenFixed.add(rule.fixedClass);
|
|
30
|
+
return true;
|
|
31
|
+
});
|
|
32
|
+
const allRules = [
|
|
33
|
+
...dedupedComponentRules,
|
|
34
|
+
...css.generalLayer.rules,
|
|
35
|
+
...css.baseLayer.rules,
|
|
36
|
+
...css.presetLayer.rules
|
|
37
|
+
];
|
|
38
|
+
const baseSet = new Set(css.baseLayer.rules);
|
|
39
|
+
const presetSet = new Set(css.presetLayer.rules);
|
|
40
|
+
const getGroupIndex = (rule)=>{
|
|
41
|
+
if (baseSet.has(rule)) return 4;
|
|
42
|
+
if (presetSet.has(rule)) return 5;
|
|
43
|
+
if (rule.atRules) return 3;
|
|
44
|
+
if (rule.mode) return 2;
|
|
45
|
+
if (rule.selectorNodes?.length) return 1;
|
|
46
|
+
return 0;
|
|
47
|
+
};
|
|
48
|
+
const getTypeScore = (rule)=>{
|
|
49
|
+
if (rule.fixedClass) return 0;
|
|
50
|
+
if (rule.type === syntaxRuleType.Utility) return 1;
|
|
51
|
+
return 2;
|
|
52
|
+
};
|
|
53
|
+
const rulesWithSortKey = allRules.map((rule)=>({
|
|
54
|
+
rule,
|
|
55
|
+
sortKey: [
|
|
56
|
+
getGroupIndex(rule),
|
|
57
|
+
getTypeScore(rule)
|
|
58
|
+
]
|
|
59
|
+
}));
|
|
60
|
+
const sortedRules = rulesWithSortKey.sort((a, b)=>{
|
|
61
|
+
for(let i = 0; i < a.sortKey.length; i++){
|
|
62
|
+
if (a.sortKey[i] !== b.sortKey[i]) {
|
|
63
|
+
return a.sortKey[i] - b.sortKey[i];
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if (a.rule.fixedClass && b.rule.fixedClass) {
|
|
67
|
+
return a.rule.fixedClass.localeCompare(b.rule.fixedClass, undefined, {
|
|
68
|
+
numeric: true
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
return compareRulePriority.default(a.rule, b.rule);
|
|
72
|
+
});
|
|
73
|
+
const orderedClasses = sortedRules.map((entry)=>entry.rule.fixedClass || entry.rule.name);
|
|
74
|
+
css.remove(...shouldSortClasses);
|
|
75
|
+
return [
|
|
76
|
+
...orderedClasses,
|
|
77
|
+
...[
|
|
78
|
+
...shouldSortClasses.filter((className)=>orderedClasses.indexOf(className) === -1),
|
|
79
|
+
...unsortedClasses
|
|
80
|
+
].sort((a, b)=>a.localeCompare(b, undefined, {
|
|
81
|
+
numeric: true
|
|
82
|
+
}))
|
|
83
|
+
];
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
module.exports = sortReadableClasses;
|
|
@@ -5,4 +5,4 @@ import MasterCSS from '../core';
|
|
|
5
5
|
* @param options
|
|
6
6
|
* @returns consistent classes
|
|
7
7
|
*/
|
|
8
|
-
export default function
|
|
8
|
+
export default function sortReadableClasses(classes: string[], css?: MasterCSS): string[];
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import SyntaxRuleType from '../syntax-rule-type.mjs';
|
|
2
|
+
import MasterCSS from '../core.mjs';
|
|
3
|
+
import compareRulePriority from './compare-rule-priority.mjs';
|
|
4
|
+
import { __UNSORTED__ } from '../common.mjs';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Sorts classes in a consistent order
|
|
8
|
+
* @param classes
|
|
9
|
+
* @param options
|
|
10
|
+
* @returns consistent classes
|
|
11
|
+
*/ function sortReadableClasses(classes, css = new MasterCSS()) {
|
|
12
|
+
const shouldSortClasses = [];
|
|
13
|
+
const unsortedClasses = [];
|
|
14
|
+
for (const className of classes){
|
|
15
|
+
if (className.includes(__UNSORTED__)) {
|
|
16
|
+
unsortedClasses.push(className);
|
|
17
|
+
} else {
|
|
18
|
+
shouldSortClasses.push(className);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
css.add(...shouldSortClasses);
|
|
22
|
+
// 先去重 fixedClass for componentsLayer
|
|
23
|
+
const seenFixed = new Set();
|
|
24
|
+
const dedupedComponentRules = css.componentsLayer.rules.filter((rule)=>{
|
|
25
|
+
if (!rule.fixedClass) return true;
|
|
26
|
+
if (seenFixed.has(rule.fixedClass)) return false;
|
|
27
|
+
seenFixed.add(rule.fixedClass);
|
|
28
|
+
return true;
|
|
29
|
+
});
|
|
30
|
+
const allRules = [
|
|
31
|
+
...dedupedComponentRules,
|
|
32
|
+
...css.generalLayer.rules,
|
|
33
|
+
...css.baseLayer.rules,
|
|
34
|
+
...css.presetLayer.rules
|
|
35
|
+
];
|
|
36
|
+
const baseSet = new Set(css.baseLayer.rules);
|
|
37
|
+
const presetSet = new Set(css.presetLayer.rules);
|
|
38
|
+
const getGroupIndex = (rule)=>{
|
|
39
|
+
if (baseSet.has(rule)) return 4;
|
|
40
|
+
if (presetSet.has(rule)) return 5;
|
|
41
|
+
if (rule.atRules) return 3;
|
|
42
|
+
if (rule.mode) return 2;
|
|
43
|
+
if (rule.selectorNodes?.length) return 1;
|
|
44
|
+
return 0;
|
|
45
|
+
};
|
|
46
|
+
const getTypeScore = (rule)=>{
|
|
47
|
+
if (rule.fixedClass) return 0;
|
|
48
|
+
if (rule.type === SyntaxRuleType.Utility) return 1;
|
|
49
|
+
return 2;
|
|
50
|
+
};
|
|
51
|
+
const rulesWithSortKey = allRules.map((rule)=>({
|
|
52
|
+
rule,
|
|
53
|
+
sortKey: [
|
|
54
|
+
getGroupIndex(rule),
|
|
55
|
+
getTypeScore(rule)
|
|
56
|
+
]
|
|
57
|
+
}));
|
|
58
|
+
const sortedRules = rulesWithSortKey.sort((a, b)=>{
|
|
59
|
+
for(let i = 0; i < a.sortKey.length; i++){
|
|
60
|
+
if (a.sortKey[i] !== b.sortKey[i]) {
|
|
61
|
+
return a.sortKey[i] - b.sortKey[i];
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (a.rule.fixedClass && b.rule.fixedClass) {
|
|
65
|
+
return a.rule.fixedClass.localeCompare(b.rule.fixedClass, undefined, {
|
|
66
|
+
numeric: true
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
return compareRulePriority(a.rule, b.rule);
|
|
70
|
+
});
|
|
71
|
+
const orderedClasses = sortedRules.map((entry)=>entry.rule.fixedClass || entry.rule.name);
|
|
72
|
+
css.remove(...shouldSortClasses);
|
|
73
|
+
return [
|
|
74
|
+
...orderedClasses,
|
|
75
|
+
...[
|
|
76
|
+
...shouldSortClasses.filter((className)=>orderedClasses.indexOf(className) === -1),
|
|
77
|
+
...unsortedClasses
|
|
78
|
+
].sort((a, b)=>a.localeCompare(b, undefined, {
|
|
79
|
+
numeric: true
|
|
80
|
+
}))
|
|
81
|
+
];
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export { sortReadableClasses as default };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
function splitCharOutsideQuotes(str, char) {
|
|
4
|
+
const result = [];
|
|
5
|
+
let current = '';
|
|
6
|
+
let inSingle = false;
|
|
7
|
+
let inDouble = false;
|
|
8
|
+
for(let i = 0; i < str.length; i++){
|
|
9
|
+
const c = str[i];
|
|
10
|
+
const prev = str[i - 1];
|
|
11
|
+
// 處理 quote 開關
|
|
12
|
+
if (c === '\'' && !inDouble && prev !== '\\') {
|
|
13
|
+
inSingle = !inSingle;
|
|
14
|
+
} else if (c === '"' && !inSingle && prev !== '\\') {
|
|
15
|
+
inDouble = !inDouble;
|
|
16
|
+
}
|
|
17
|
+
// 在引號之外遇到目標字元就切分
|
|
18
|
+
if (c === char && !inSingle && !inDouble) {
|
|
19
|
+
result.push(current.trim());
|
|
20
|
+
current = '';
|
|
21
|
+
} else {
|
|
22
|
+
current += c;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (current) result.push(current.trim());
|
|
26
|
+
return result;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
module.exports = splitCharOutsideQuotes;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function splitCharOutsideQuotes(str: string, char: string): string[];
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
function splitCharOutsideQuotes(str, char) {
|
|
2
|
+
const result = [];
|
|
3
|
+
let current = '';
|
|
4
|
+
let inSingle = false;
|
|
5
|
+
let inDouble = false;
|
|
6
|
+
for(let i = 0; i < str.length; i++){
|
|
7
|
+
const c = str[i];
|
|
8
|
+
const prev = str[i - 1];
|
|
9
|
+
// 處理 quote 開關
|
|
10
|
+
if (c === '\'' && !inDouble && prev !== '\\') {
|
|
11
|
+
inSingle = !inSingle;
|
|
12
|
+
} else if (c === '"' && !inSingle && prev !== '\\') {
|
|
13
|
+
inDouble = !inDouble;
|
|
14
|
+
}
|
|
15
|
+
// 在引號之外遇到目標字元就切分
|
|
16
|
+
if (c === char && !inSingle && !inDouble) {
|
|
17
|
+
result.push(current.trim());
|
|
18
|
+
current = '';
|
|
19
|
+
} else {
|
|
20
|
+
current += c;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
if (current) result.push(current.trim());
|
|
24
|
+
return result;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export { splitCharOutsideQuotes as default };
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
class VariableRule {
|
|
6
|
+
name;
|
|
7
|
+
variable;
|
|
8
|
+
css;
|
|
9
|
+
nodes;
|
|
10
|
+
constructor(name, variable, css){
|
|
11
|
+
this.name = name;
|
|
12
|
+
this.variable = variable;
|
|
13
|
+
this.css = css;
|
|
14
|
+
this.nodes = [];
|
|
15
|
+
const hasDefaultValue = variable.value !== undefined;
|
|
16
|
+
if (hasDefaultValue) {
|
|
17
|
+
this.nodes.push(new VariableRuleNode(this.name, variable, css));
|
|
18
|
+
}
|
|
19
|
+
if (variable.modes) {
|
|
20
|
+
for(const mode in variable.modes){
|
|
21
|
+
const modeVariable = variable.modes[mode];
|
|
22
|
+
const variableRule = new VariableRuleNode(this.name, modeVariable, css, mode);
|
|
23
|
+
if (variableRule.modeTrigger) {
|
|
24
|
+
const isDefaultMode = hasDefaultValue ? false : this.css.config.defaultMode === mode;
|
|
25
|
+
variableRule.isDefaultMode = isDefaultMode;
|
|
26
|
+
if (isDefaultMode) {
|
|
27
|
+
this.nodes.unshift(variableRule);
|
|
28
|
+
} else {
|
|
29
|
+
this.nodes.push(variableRule);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
get key() {
|
|
36
|
+
return this.name;
|
|
37
|
+
}
|
|
38
|
+
get text() {
|
|
39
|
+
return this.nodes.map(({ text })=>text).join('');
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
class VariableRuleNode {
|
|
43
|
+
name;
|
|
44
|
+
variable;
|
|
45
|
+
css;
|
|
46
|
+
mode;
|
|
47
|
+
native;
|
|
48
|
+
isDefaultMode;
|
|
49
|
+
constructor(name, variable, css, mode){
|
|
50
|
+
this.name = name;
|
|
51
|
+
this.variable = variable;
|
|
52
|
+
this.css = css;
|
|
53
|
+
this.mode = mode;
|
|
54
|
+
this.isDefaultMode = false;
|
|
55
|
+
}
|
|
56
|
+
get modeTrigger() {
|
|
57
|
+
return this.mode ? this.css.config.modes?.[this.mode] : undefined;
|
|
58
|
+
}
|
|
59
|
+
get selectorText() {
|
|
60
|
+
const isDefaultMode = this.isDefaultMode;
|
|
61
|
+
if (this.mode) {
|
|
62
|
+
switch(this.modeTrigger){
|
|
63
|
+
case 'media':
|
|
64
|
+
return ':root';
|
|
65
|
+
case 'host':
|
|
66
|
+
return `:host(.${this.mode})` + (isDefaultMode ? ',:host' : '');
|
|
67
|
+
case 'class':
|
|
68
|
+
return `.${this.mode}` + (isDefaultMode ? ',:root' : '');
|
|
69
|
+
default:
|
|
70
|
+
return '';
|
|
71
|
+
}
|
|
72
|
+
} else {
|
|
73
|
+
return ':root';
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
get text() {
|
|
77
|
+
let text = `${this.selectorText}{--${this.name}:${String(this.variable.value)}}`;
|
|
78
|
+
if (this.modeTrigger === 'media') {
|
|
79
|
+
text = `@media (prefers-color-scheme:${this.mode}){${text}}`;
|
|
80
|
+
}
|
|
81
|
+
return text;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
exports.VariableRuleNode = VariableRuleNode;
|
|
86
|
+
exports.default = VariableRule;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import MasterCSS from './core';
|
|
2
|
+
import { LiteralVariable, Variable } from './types/syntax';
|
|
3
|
+
export default class VariableRule {
|
|
4
|
+
readonly name: string;
|
|
5
|
+
readonly variable: Variable;
|
|
6
|
+
readonly css: MasterCSS;
|
|
7
|
+
nodes: VariableRuleNode[];
|
|
8
|
+
constructor(name: string, variable: Variable, css: MasterCSS);
|
|
9
|
+
get key(): string;
|
|
10
|
+
get text(): string;
|
|
11
|
+
}
|
|
12
|
+
export declare class VariableRuleNode {
|
|
13
|
+
readonly name: string;
|
|
14
|
+
readonly variable: LiteralVariable;
|
|
15
|
+
readonly css: MasterCSS;
|
|
16
|
+
readonly mode?: string | undefined;
|
|
17
|
+
native?: CSSRule;
|
|
18
|
+
isDefaultMode: boolean;
|
|
19
|
+
constructor(name: string, variable: LiteralVariable, css: MasterCSS, mode?: string | undefined);
|
|
20
|
+
get modeTrigger(): false | "class" | "media" | "host" | undefined;
|
|
21
|
+
get selectorText(): string;
|
|
22
|
+
get text(): string;
|
|
23
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
class VariableRule {
|
|
2
|
+
name;
|
|
3
|
+
variable;
|
|
4
|
+
css;
|
|
5
|
+
nodes;
|
|
6
|
+
constructor(name, variable, css){
|
|
7
|
+
this.name = name;
|
|
8
|
+
this.variable = variable;
|
|
9
|
+
this.css = css;
|
|
10
|
+
this.nodes = [];
|
|
11
|
+
const hasDefaultValue = variable.value !== undefined;
|
|
12
|
+
if (hasDefaultValue) {
|
|
13
|
+
this.nodes.push(new VariableRuleNode(this.name, variable, css));
|
|
14
|
+
}
|
|
15
|
+
if (variable.modes) {
|
|
16
|
+
for(const mode in variable.modes){
|
|
17
|
+
const modeVariable = variable.modes[mode];
|
|
18
|
+
const variableRule = new VariableRuleNode(this.name, modeVariable, css, mode);
|
|
19
|
+
if (variableRule.modeTrigger) {
|
|
20
|
+
const isDefaultMode = hasDefaultValue ? false : this.css.config.defaultMode === mode;
|
|
21
|
+
variableRule.isDefaultMode = isDefaultMode;
|
|
22
|
+
if (isDefaultMode) {
|
|
23
|
+
this.nodes.unshift(variableRule);
|
|
24
|
+
} else {
|
|
25
|
+
this.nodes.push(variableRule);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
get key() {
|
|
32
|
+
return this.name;
|
|
33
|
+
}
|
|
34
|
+
get text() {
|
|
35
|
+
return this.nodes.map(({ text })=>text).join('');
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
class VariableRuleNode {
|
|
39
|
+
name;
|
|
40
|
+
variable;
|
|
41
|
+
css;
|
|
42
|
+
mode;
|
|
43
|
+
native;
|
|
44
|
+
isDefaultMode;
|
|
45
|
+
constructor(name, variable, css, mode){
|
|
46
|
+
this.name = name;
|
|
47
|
+
this.variable = variable;
|
|
48
|
+
this.css = css;
|
|
49
|
+
this.mode = mode;
|
|
50
|
+
this.isDefaultMode = false;
|
|
51
|
+
}
|
|
52
|
+
get modeTrigger() {
|
|
53
|
+
return this.mode ? this.css.config.modes?.[this.mode] : undefined;
|
|
54
|
+
}
|
|
55
|
+
get selectorText() {
|
|
56
|
+
const isDefaultMode = this.isDefaultMode;
|
|
57
|
+
if (this.mode) {
|
|
58
|
+
switch(this.modeTrigger){
|
|
59
|
+
case 'media':
|
|
60
|
+
return ':root';
|
|
61
|
+
case 'host':
|
|
62
|
+
return `:host(.${this.mode})` + (isDefaultMode ? ',:host' : '');
|
|
63
|
+
case 'class':
|
|
64
|
+
return `.${this.mode}` + (isDefaultMode ? ',:root' : '');
|
|
65
|
+
default:
|
|
66
|
+
return '';
|
|
67
|
+
}
|
|
68
|
+
} else {
|
|
69
|
+
return ':root';
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
get text() {
|
|
73
|
+
let text = `${this.selectorText}{--${this.name}:${String(this.variable.value)}}`;
|
|
74
|
+
if (this.modeTrigger === 'media') {
|
|
75
|
+
text = `@media (prefers-color-scheme:${this.mode}){${text}}`;
|
|
76
|
+
}
|
|
77
|
+
return text;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export { VariableRuleNode, VariableRule as default };
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"@master/css","type":"module","scripts":{"build":"techor build \"src/**/*.ts\"","dev":"pnpm build --watch","test":"vitest","type-check":"tsc --noEmit","lint":"eslint"},"license":"MIT","description":"The CSS language and framework for rapidly building modern and high-performance websites","author":"Aoyue Design LLC.","funding":"https://rc.css.master.co/sponsor","homepage":"https://css.master.co","bugs":{"url":"https://github.com/master-co/css/issues"},"repository":{"type":"git","url":"https://github.com/master-co/css.git","directory":"packages/core"},"keywords":["style","styles","html","variants","virtual","virtual-css","utility","css","ui","lightweight","class","webpack","plugin","integration","vite","parcel","build-tools","mastercss"],"sideEffects":false,"main":"./dist/index.cjs","jsnext:main":"./dist/index.mjs","esnext":"./dist/index.mjs","module":"./dist/index.mjs","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","require":"./dist/index.cjs","import":"./dist/index.mjs"}},"bin":"./dist/bin/index.mjs","files":["dist"],"publishConfig":{"access":"public","provenance":true},"dependencies":{"@master/colors":"^2.1.
|
|
1
|
+
{"name":"@master/css","type":"module","scripts":{"build":"techor build \"src/**/*.ts\"","dev":"pnpm build --watch","test":"vitest","type-check":"tsc --noEmit","lint":"eslint"},"license":"MIT","description":"The CSS language and framework for rapidly building modern and high-performance websites","author":"Aoyue Design LLC.","funding":"https://rc.css.master.co/sponsor","homepage":"https://css.master.co","bugs":{"url":"https://github.com/master-co/css/issues"},"repository":{"type":"git","url":"https://github.com/master-co/css.git","directory":"packages/core"},"keywords":["style","styles","html","variants","virtual","virtual-css","utility","css","ui","lightweight","class","webpack","plugin","integration","vite","parcel","build-tools","mastercss"],"sideEffects":false,"main":"./dist/index.cjs","jsnext:main":"./dist/index.mjs","esnext":"./dist/index.mjs","module":"./dist/index.mjs","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","require":"./dist/index.cjs","import":"./dist/index.mjs"}},"bin":"./dist/bin/index.mjs","files":["dist"],"publishConfig":{"access":"public","provenance":true},"dependencies":{"@master/colors":"^2.1.1","@master/normal.css":"^3.1.0","@techor/extend":"^3.2.0","csstype":"^3.1.3"},"devDependencies":{"shared":"^2.0.0-rc.63"},"version":"2.0.0-rc.63"}
|