@master/css-engine 2.0.0-rc.70
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/README.md +57 -0
- package/dist/animation-rule.d.ts +12 -0
- package/dist/animation-rule.mjs +38 -0
- package/dist/common.d.ts +40 -0
- package/dist/common.mjs +114 -0
- package/dist/compile-manifest.d.ts +54 -0
- package/dist/compile-manifest.mjs +451 -0
- package/dist/compiler.d.ts +32 -0
- package/dist/compiler.mjs +38 -0
- package/dist/core.d.ts +141 -0
- package/dist/core.mjs +848 -0
- package/dist/emitted-globals.d.ts +4 -0
- package/dist/emitted-globals.mjs +1 -0
- package/dist/hydration-manifest.d.ts +4 -0
- package/dist/hydration-manifest.mjs +61 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.mjs +15 -0
- package/dist/key-aliases.d.ts +4 -0
- package/dist/key-aliases.mjs +95 -0
- package/dist/layer.d.ts +17 -0
- package/dist/layer.mjs +78 -0
- package/dist/namespaces.d.ts +5 -0
- package/dist/namespaces.mjs +28 -0
- package/dist/native-value-namespaces.d.ts +9 -0
- package/dist/native-value-namespaces.mjs +346 -0
- package/dist/non-layer.d.ts +12 -0
- package/dist/non-layer.mjs +53 -0
- package/dist/rule.d.ts +7 -0
- package/dist/rule.mjs +14 -0
- package/dist/theme-layer.d.ts +21 -0
- package/dist/theme-layer.mjs +52 -0
- package/dist/utility-layer.d.ts +10 -0
- package/dist/utility-layer.mjs +118 -0
- package/dist/utility.d.ts +102 -0
- package/dist/utility.mjs +1263 -0
- package/dist/utils/collect-animation-names.d.ts +10 -0
- package/dist/utils/collect-animation-names.mjs +61 -0
- package/dist/utils/collect-variable-names.d.ts +3 -0
- package/dist/utils/collect-variable-names.mjs +18 -0
- package/dist/utils/compare-rule-priority.d.ts +14 -0
- package/dist/utils/compare-rule-priority.mjs +136 -0
- package/dist/utils/css-variables.d.ts +12 -0
- package/dist/utils/css-variables.mjs +197 -0
- package/dist/utils/find-native-css-rule-index.d.ts +1 -0
- package/dist/utils/find-native-css-rule-index.mjs +10 -0
- package/dist/utils/generate-at.d.ts +2 -0
- package/dist/utils/generate-at.mjs +32 -0
- package/dist/utils/generate-selector.d.ts +2 -0
- package/dist/utils/generate-selector.mjs +48 -0
- package/dist/utils/natural-compare.d.ts +2 -0
- package/dist/utils/natural-compare.mjs +6 -0
- package/dist/utils/parse-at.d.ts +44 -0
- package/dist/utils/parse-at.mjs +179 -0
- package/dist/utils/parse-pair.d.ts +8 -0
- package/dist/utils/parse-pair.mjs +46 -0
- package/dist/utils/parse-selector.d.ts +19 -0
- package/dist/utils/parse-selector.mjs +124 -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.d.ts +1 -0
- package/dist/utils/replace-char-outside-quotes.mjs +19 -0
- package/dist/utils/split-char-outside-quotes.d.ts +1 -0
- package/dist/utils/split-char-outside-quotes.mjs +27 -0
- package/dist/utils/wrap-at-rules.d.ts +1 -0
- package/dist/utils/wrap-at-rules.mjs +10 -0
- package/dist/variable-rule.d.ts +26 -0
- package/dist/variable-rule.mjs +105 -0
- package/package.json +1 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { PropertiesHyphen } from 'csstype';
|
|
2
|
+
import type { Variable } from '@master/css-schema/css-syntax';
|
|
3
|
+
export interface CollectAnimationNamesOptions {
|
|
4
|
+
animationNames: Iterable<string>;
|
|
5
|
+
variables?: Map<string, Variable>;
|
|
6
|
+
variableNames?: Iterable<string>;
|
|
7
|
+
}
|
|
8
|
+
export declare function collectAnimationNamesFromValue(value: string | number | undefined, animationNames: Iterable<string>): Set<string>;
|
|
9
|
+
export declare function collectAnimationNamesFromDeclaration(propertyName: string, value: string | number | undefined, options: CollectAnimationNamesOptions): Set<string>;
|
|
10
|
+
export default function collectAnimationNames(declarations: PropertiesHyphen, options: CollectAnimationNamesOptions): Set<string> | undefined;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { normalizeVariableValue } from './css-variables.mjs';
|
|
2
|
+
|
|
3
|
+
function isAnimationDeclaration(propertyName) {
|
|
4
|
+
return propertyName === 'animation' || propertyName === 'animation-name';
|
|
5
|
+
}
|
|
6
|
+
function addAnimationName(references, animationNames, animationName) {
|
|
7
|
+
if (animationNames.has(animationName)) {
|
|
8
|
+
references.add(animationName);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
function collectAnimationNamesFromValue(value, animationNames) {
|
|
12
|
+
const references = new Set();
|
|
13
|
+
if (value === undefined) return references;
|
|
14
|
+
const names = new Set(animationNames);
|
|
15
|
+
if (!names.size) return references;
|
|
16
|
+
const normalizedValue = normalizeVariableValue(value).value;
|
|
17
|
+
for (const rawValue of normalizedValue.split(/[\s,]+/)){
|
|
18
|
+
addAnimationName(references, names, rawValue);
|
|
19
|
+
}
|
|
20
|
+
return references;
|
|
21
|
+
}
|
|
22
|
+
function collectAnimationNamesFromVariable(references, variable, animationNames, variables, visited = new Set()) {
|
|
23
|
+
if (!variable || visited.has(variable.name)) return;
|
|
24
|
+
visited.add(variable.name);
|
|
25
|
+
for (const animationName of collectAnimationNamesFromValue(variable.value, animationNames)){
|
|
26
|
+
references.add(animationName);
|
|
27
|
+
}
|
|
28
|
+
for (const modeVariable of Object.values(variable.modes || {})){
|
|
29
|
+
for (const animationName of collectAnimationNamesFromValue(modeVariable.value, animationNames)){
|
|
30
|
+
references.add(animationName);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
variable.dependencies?.forEach((dependency)=>{
|
|
34
|
+
collectAnimationNamesFromVariable(references, variables?.get(dependency), animationNames, variables, visited);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
function collectAnimationNamesFromDeclaration(propertyName, value, options) {
|
|
38
|
+
const references = new Set();
|
|
39
|
+
if (!isAnimationDeclaration(propertyName)) return references;
|
|
40
|
+
const animationNames = new Set(options.animationNames);
|
|
41
|
+
if (!animationNames.size) return references;
|
|
42
|
+
for (const animationName of collectAnimationNamesFromValue(value, animationNames)){
|
|
43
|
+
references.add(animationName);
|
|
44
|
+
}
|
|
45
|
+
for (const variableName of options.variableNames || []){
|
|
46
|
+
collectAnimationNamesFromVariable(references, options.variables?.get(variableName), animationNames, options.variables);
|
|
47
|
+
}
|
|
48
|
+
return references;
|
|
49
|
+
}
|
|
50
|
+
function collectAnimationNames(declarations, options) {
|
|
51
|
+
const references = new Set();
|
|
52
|
+
for(const propertyName in declarations){
|
|
53
|
+
const propertyValue = declarations[propertyName];
|
|
54
|
+
for (const animationName of collectAnimationNamesFromDeclaration(propertyName, propertyValue, options)){
|
|
55
|
+
references.add(animationName);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return references.size ? references : undefined;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export { collectAnimationNamesFromDeclaration, collectAnimationNamesFromValue, collectAnimationNames as default };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { CSS_VARIABLE_REFERENCE } from './css-variables.mjs';
|
|
2
|
+
|
|
3
|
+
function collectVariableNames(declarations, variables) {
|
|
4
|
+
const variableNames = new Set();
|
|
5
|
+
for(const propertyName in declarations){
|
|
6
|
+
const propertyValue = declarations[propertyName];
|
|
7
|
+
if (!propertyValue) continue;
|
|
8
|
+
for (const match of String(propertyValue).matchAll(CSS_VARIABLE_REFERENCE)){
|
|
9
|
+
const variable = variables.get(match[1]);
|
|
10
|
+
if (variable && !variable.inline) {
|
|
11
|
+
variableNames.add(match[1]);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return variableNames.size ? variableNames : undefined;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export { collectVariableNames as default };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Utility } from '../utility';
|
|
2
|
+
export type RulePriority = {
|
|
3
|
+
features?: [string, number, number][];
|
|
4
|
+
selector: number;
|
|
5
|
+
};
|
|
6
|
+
type ComparableRule = Pick<Utility, 'priority' | 'type' | 'key'> & Partial<Pick<Utility, 'atRules' | 'mode' | 'selectorNodes'>> & {
|
|
7
|
+
sortTier?: number;
|
|
8
|
+
};
|
|
9
|
+
export declare function calcRulePriority(rule: Utility): RulePriority;
|
|
10
|
+
export declare function getRuleSortTier(rule: Partial<Pick<Utility, 'atRules' | 'mode' | 'selectorNodes'>> & {
|
|
11
|
+
sortTier?: number;
|
|
12
|
+
}): number;
|
|
13
|
+
export default function compareRulePriority(a: ComparableRule, b: ComparableRule): number;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import naturalCompare from './natural-compare.mjs';
|
|
2
|
+
|
|
3
|
+
// ✅ Pseudo-class priority (lower = weaker)
|
|
4
|
+
const selectorPriority = {
|
|
5
|
+
hover: 1,
|
|
6
|
+
focus: 2,
|
|
7
|
+
'focus-visible': 2,
|
|
8
|
+
active: 3,
|
|
9
|
+
disabled: 4
|
|
10
|
+
};
|
|
11
|
+
function extractSelectorPriority(nodes = []) {
|
|
12
|
+
let priority = 0;
|
|
13
|
+
for (const node of nodes){
|
|
14
|
+
if ('value' in node && typeof node.value === 'string') {
|
|
15
|
+
priority += selectorPriority[node.value] ?? 0;
|
|
16
|
+
}
|
|
17
|
+
if ('children' in node && Array.isArray(node.children)) {
|
|
18
|
+
priority += extractSelectorPriority(node.children);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return priority;
|
|
22
|
+
}
|
|
23
|
+
const NOT_COMPARISON_OPERATORS = {
|
|
24
|
+
'>=': '<',
|
|
25
|
+
'<=': '>',
|
|
26
|
+
'>': '<=',
|
|
27
|
+
'<': '>='
|
|
28
|
+
};
|
|
29
|
+
function getAtRuleEntries(nestNodes) {
|
|
30
|
+
const featureMap = new Map();
|
|
31
|
+
const walk = (list, isOutsideNot = false)=>{
|
|
32
|
+
(list ?? []).forEach((node, i, arr)=>{
|
|
33
|
+
const prev = arr[i - 1];
|
|
34
|
+
if ('operator' in node) {
|
|
35
|
+
const entry = featureMap.get(node.name) ?? {};
|
|
36
|
+
let operator = node.operator;
|
|
37
|
+
if (isOutsideNot) operator = NOT_COMPARISON_OPERATORS[operator];
|
|
38
|
+
if (prev?.type === 'logical' && prev.value === 'not') operator = NOT_COMPARISON_OPERATORS[operator];
|
|
39
|
+
switch(operator){
|
|
40
|
+
case '>':
|
|
41
|
+
entry.min = node.value + 0.02;
|
|
42
|
+
break;
|
|
43
|
+
case '>=':
|
|
44
|
+
entry.min = node.value;
|
|
45
|
+
break;
|
|
46
|
+
case '<':
|
|
47
|
+
entry.max = node.value - 0.02;
|
|
48
|
+
break;
|
|
49
|
+
case '<=':
|
|
50
|
+
entry.max = node.value;
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
featureMap.set(node.name, entry);
|
|
54
|
+
}
|
|
55
|
+
if ('children' in node && Array.isArray(node.children)) {
|
|
56
|
+
walk(node.children, prev?.type === 'logical' && prev.value === 'not');
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
};
|
|
60
|
+
walk(nestNodes);
|
|
61
|
+
return featureMap;
|
|
62
|
+
}
|
|
63
|
+
// ✅ Calculate RulePriority from AST
|
|
64
|
+
function calcRulePriority(rule) {
|
|
65
|
+
const features = [];
|
|
66
|
+
const extractFeatures = (nodes)=>{
|
|
67
|
+
const featureMap = getAtRuleEntries(nodes);
|
|
68
|
+
for (const [name, entry] of featureMap.entries()){
|
|
69
|
+
const max = entry.max ?? Number.MAX_SAFE_INTEGER;
|
|
70
|
+
const min = entry.min ?? 0;
|
|
71
|
+
features.push([
|
|
72
|
+
name,
|
|
73
|
+
min,
|
|
74
|
+
max
|
|
75
|
+
]);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
if (rule.atRules?.media) extractFeatures(rule.atRules.media);
|
|
79
|
+
if (rule.atRules?.container) extractFeatures(rule.atRules.container);
|
|
80
|
+
features.sort(([a], [b])=>naturalCompare(a, b));
|
|
81
|
+
const selector = extractSelectorPriority(rule.selectorNodes ?? []);
|
|
82
|
+
return {
|
|
83
|
+
features,
|
|
84
|
+
selector
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
function compareFeatureTuples(a, b) {
|
|
88
|
+
const len = Math.max(a.length, b.length);
|
|
89
|
+
for(let i = 0; i < len; i++){
|
|
90
|
+
const aa = a[i];
|
|
91
|
+
const bb = b[i];
|
|
92
|
+
if (!aa) return -1;
|
|
93
|
+
if (!bb) return 1;
|
|
94
|
+
const [nameA, minA, maxA] = aa;
|
|
95
|
+
const [nameB, minB, maxB] = bb;
|
|
96
|
+
const nameCmp = naturalCompare(nameA, nameB);
|
|
97
|
+
if (nameCmp !== 0) return nameCmp;
|
|
98
|
+
const rangeA = maxA - minA;
|
|
99
|
+
const rangeB = maxB - minB;
|
|
100
|
+
if (rangeA !== rangeB) return rangeB - rangeA;
|
|
101
|
+
if (minA !== minB) return minB - minA;
|
|
102
|
+
if (maxA !== maxB) return maxB - maxA;
|
|
103
|
+
}
|
|
104
|
+
return 0;
|
|
105
|
+
}
|
|
106
|
+
function getRuleSortTier(rule) {
|
|
107
|
+
if (typeof rule.sortTier === 'number') return rule.sortTier;
|
|
108
|
+
const hasSelector = rule.selectorNodes?.length;
|
|
109
|
+
const hasAtRules = !!rule.atRules;
|
|
110
|
+
const hasMode = !!rule.mode;
|
|
111
|
+
if (hasAtRules) return 3;
|
|
112
|
+
if (hasMode) return 2;
|
|
113
|
+
if (hasSelector) return 1;
|
|
114
|
+
return 0;
|
|
115
|
+
}
|
|
116
|
+
// ✅ Compare function
|
|
117
|
+
function compareRulePriority(a, b) {
|
|
118
|
+
const aTier = getRuleSortTier(a);
|
|
119
|
+
const bTier = getRuleSortTier(b);
|
|
120
|
+
if (aTier !== bTier) return aTier - bTier;
|
|
121
|
+
// 1. features
|
|
122
|
+
const fa = a.priority.features || [];
|
|
123
|
+
const fb = b.priority.features || [];
|
|
124
|
+
const featureCmp = compareFeatureTuples(fa, fb);
|
|
125
|
+
if (featureCmp !== 0) return featureCmp;
|
|
126
|
+
// 2. selector
|
|
127
|
+
const selectorCmp = a.priority.selector - b.priority.selector;
|
|
128
|
+
if (selectorCmp !== 0) return selectorCmp;
|
|
129
|
+
// 3. rule.type
|
|
130
|
+
const typeCmp = a.type - b.type;
|
|
131
|
+
if (typeCmp !== 0) return typeCmp;
|
|
132
|
+
// 4. fallback: name
|
|
133
|
+
return naturalCompare(a.key, b.key);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export { calcRulePriority, compareRulePriority as default, getRuleSortTier };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Variable } from '@master/css-schema/css-syntax';
|
|
2
|
+
export declare const CSS_VARIABLE_REFERENCE: RegExp;
|
|
3
|
+
export declare function createCSSVariableReference(name: string, alpha?: number, fallback?: string): string;
|
|
4
|
+
export declare function createAlphaColorValue(value: string, alpha: number): string;
|
|
5
|
+
export declare function createNumberVariableReference(variable: Variable, unit: string, rootSize?: number): string;
|
|
6
|
+
export declare function createNegativeNumberVariableReference(variable: Variable, unit: string, rootSize?: number): string;
|
|
7
|
+
export declare function collectCSSVariableReferences(value: string): Set<string>;
|
|
8
|
+
export declare function replaceCSSVariableReferences(value: string, replacer: (name: string, text: string) => string | undefined): string;
|
|
9
|
+
export declare function normalizeVariableValue(value: string | number): {
|
|
10
|
+
value: string;
|
|
11
|
+
dependencies: Set<string>;
|
|
12
|
+
};
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
const CSS_VARIABLE_REFERENCE = /var\(\s*--([_a-zA-Z0-9-]+)\b/g;
|
|
2
|
+
function createCSSVariableReference(name, alpha, fallback) {
|
|
3
|
+
const reference = `var(--${name}${fallback ? ',' + fallback : ''})`;
|
|
4
|
+
return alpha !== undefined ? createAlphaColorValue(reference, alpha) : reference;
|
|
5
|
+
}
|
|
6
|
+
function createAlphaColorValue(value, alpha) {
|
|
7
|
+
return `color-mix(in oklab,${value} ${Number(alpha) * 100}%,transparent)`;
|
|
8
|
+
}
|
|
9
|
+
function createNumberVariableReference(variable, unit, rootSize = 16) {
|
|
10
|
+
return createCSSVariableReference(variable.name);
|
|
11
|
+
}
|
|
12
|
+
function createNegativeNumberVariableReference(variable, unit, rootSize = 16) {
|
|
13
|
+
const reference = createCSSVariableReference(variable.name);
|
|
14
|
+
return `calc(${reference} * -1)`;
|
|
15
|
+
}
|
|
16
|
+
function collectCSSVariableReferences(value) {
|
|
17
|
+
const references = new Set();
|
|
18
|
+
for (const match of value.matchAll(CSS_VARIABLE_REFERENCE)){
|
|
19
|
+
references.add(match[1]);
|
|
20
|
+
}
|
|
21
|
+
return references;
|
|
22
|
+
}
|
|
23
|
+
function replaceCSSVariableReferences(value, replacer) {
|
|
24
|
+
let result = '';
|
|
25
|
+
let quote = '';
|
|
26
|
+
for(let i = 0; i < value.length;){
|
|
27
|
+
const char = value[i];
|
|
28
|
+
if (quote) {
|
|
29
|
+
result += char;
|
|
30
|
+
if (char === '\\') {
|
|
31
|
+
result += value[i + 1] || '';
|
|
32
|
+
i += 2;
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
if (char === quote) quote = '';
|
|
36
|
+
i++;
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
if (char === '"' || char === '\'') {
|
|
40
|
+
quote = char;
|
|
41
|
+
result += char;
|
|
42
|
+
i++;
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
if (value.startsWith('var(', i)) {
|
|
46
|
+
let cursor = i + 4;
|
|
47
|
+
while(value[cursor] === ' ')cursor++;
|
|
48
|
+
if (value.slice(cursor, cursor + 2) !== '--') {
|
|
49
|
+
result += char;
|
|
50
|
+
i++;
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
cursor += 2;
|
|
54
|
+
const nameStart = cursor;
|
|
55
|
+
while(/[_a-zA-Z0-9-]/.test(value[cursor] || ''))cursor++;
|
|
56
|
+
const name = value.slice(nameStart, cursor);
|
|
57
|
+
if (!name) {
|
|
58
|
+
result += char;
|
|
59
|
+
i++;
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
let depth = 1;
|
|
63
|
+
let innerQuote = '';
|
|
64
|
+
let closeIndex = -1;
|
|
65
|
+
for(let j = cursor; j < value.length; j++){
|
|
66
|
+
const nextChar = value[j];
|
|
67
|
+
if (innerQuote) {
|
|
68
|
+
if (nextChar === '\\') {
|
|
69
|
+
j++;
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
if (nextChar === innerQuote) innerQuote = '';
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (nextChar === '"' || nextChar === '\'') {
|
|
76
|
+
innerQuote = nextChar;
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
if (nextChar === '(') {
|
|
80
|
+
depth++;
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
if (nextChar === ')') {
|
|
84
|
+
depth--;
|
|
85
|
+
if (depth === 0) {
|
|
86
|
+
closeIndex = j;
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
if (closeIndex === -1) {
|
|
92
|
+
result += value.slice(i);
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
const text = value.slice(i, closeIndex + 1);
|
|
96
|
+
result += replacer(name, text) ?? text;
|
|
97
|
+
i = closeIndex + 1;
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
result += char;
|
|
101
|
+
i++;
|
|
102
|
+
}
|
|
103
|
+
return result;
|
|
104
|
+
}
|
|
105
|
+
function readAliasName(value, start) {
|
|
106
|
+
if (value[start + 1] === '(') {
|
|
107
|
+
let i = start + 2;
|
|
108
|
+
let name = '';
|
|
109
|
+
for(; i < value.length; i++){
|
|
110
|
+
if (value[i] === ')') break;
|
|
111
|
+
name += value[i];
|
|
112
|
+
}
|
|
113
|
+
return name ? {
|
|
114
|
+
name,
|
|
115
|
+
end: i + 1
|
|
116
|
+
} : undefined;
|
|
117
|
+
}
|
|
118
|
+
let i = start + 1;
|
|
119
|
+
let name = '';
|
|
120
|
+
for(; i < value.length; i++){
|
|
121
|
+
const char = value[i];
|
|
122
|
+
if (!/[a-zA-Z0-9-]/.test(char)) break;
|
|
123
|
+
name += char;
|
|
124
|
+
}
|
|
125
|
+
return name ? {
|
|
126
|
+
name,
|
|
127
|
+
end: i
|
|
128
|
+
} : undefined;
|
|
129
|
+
}
|
|
130
|
+
function readAliasAlpha(value, start) {
|
|
131
|
+
let i = start;
|
|
132
|
+
while(value[i] === ' ')i++;
|
|
133
|
+
if (value[i] !== '/') return;
|
|
134
|
+
i++;
|
|
135
|
+
while(value[i] === ' ')i++;
|
|
136
|
+
const alphaStart = i;
|
|
137
|
+
for(; i < value.length; i++){
|
|
138
|
+
if (/[\s,);|]/.test(value[i])) break;
|
|
139
|
+
}
|
|
140
|
+
const alpha = value.slice(alphaStart, i);
|
|
141
|
+
return alpha ? {
|
|
142
|
+
alpha: Number(alpha),
|
|
143
|
+
end: i
|
|
144
|
+
} : undefined;
|
|
145
|
+
}
|
|
146
|
+
function normalizeVariableValue(value) {
|
|
147
|
+
if (typeof value === 'number') {
|
|
148
|
+
return {
|
|
149
|
+
value: String(value),
|
|
150
|
+
dependencies: new Set()
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
let result = '';
|
|
154
|
+
let inSingle = false;
|
|
155
|
+
let inDouble = false;
|
|
156
|
+
const dependencies = new Set();
|
|
157
|
+
for(let i = 0; i < value.length; i++){
|
|
158
|
+
const char = value[i];
|
|
159
|
+
const previous = value[i - 1];
|
|
160
|
+
if (char === '\'' && previous !== '\\' && !inDouble) {
|
|
161
|
+
inSingle = !inSingle;
|
|
162
|
+
result += char;
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
if (char === '"' && previous !== '\\' && !inSingle) {
|
|
166
|
+
inDouble = !inDouble;
|
|
167
|
+
result += char;
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
if (!inSingle && !inDouble) {
|
|
171
|
+
if (char === '|') {
|
|
172
|
+
result += ' ';
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
if (char === '$') {
|
|
176
|
+
const alias = readAliasName(value, i);
|
|
177
|
+
if (alias) {
|
|
178
|
+
const alpha = readAliasAlpha(value, alias.end);
|
|
179
|
+
dependencies.add(alias.name);
|
|
180
|
+
result += createCSSVariableReference(alias.name, alpha?.alpha);
|
|
181
|
+
i = (alpha?.end ?? alias.end) - 1;
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
result += char;
|
|
187
|
+
}
|
|
188
|
+
for (const reference of collectCSSVariableReferences(result)){
|
|
189
|
+
dependencies.add(reference);
|
|
190
|
+
}
|
|
191
|
+
return {
|
|
192
|
+
value: result,
|
|
193
|
+
dependencies
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
export { CSS_VARIABLE_REFERENCE, collectCSSVariableReferences, createAlphaColorValue, createCSSVariableReference, createNegativeNumberVariableReference, createNumberVariableReference, normalizeVariableValue, replaceCSSVariableReferences };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function findNativeCSSRuleIndex(cssRules: CSSRuleList, nativeRule: CSSRule): number;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
function generateAt(atRule) {
|
|
2
|
+
const generate = (nodes)=>{
|
|
3
|
+
let text = nodes.map((comp)=>{
|
|
4
|
+
let current = '';
|
|
5
|
+
if ('children' in comp) {
|
|
6
|
+
const body = generate(comp.children);
|
|
7
|
+
current = comp.type === 'group' ? '(' + body + ')' : body;
|
|
8
|
+
} else {
|
|
9
|
+
if (comp.type === 'boolean') {
|
|
10
|
+
current = `(${comp.name})`;
|
|
11
|
+
return current;
|
|
12
|
+
}
|
|
13
|
+
const value = comp.type === 'number' ? String(comp.value) + (comp.unit || '') : comp.value;
|
|
14
|
+
if ('name' in comp) {
|
|
15
|
+
if ('operator' in comp) {
|
|
16
|
+
current = '(' + `${comp.name}${comp.operator}${value}` + ')';
|
|
17
|
+
} else {
|
|
18
|
+
current = '(' + `${comp.name}:${value}` + ')';
|
|
19
|
+
}
|
|
20
|
+
} else {
|
|
21
|
+
current = value;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return current;
|
|
25
|
+
}).filter(Boolean).join(atRule.id === 'layer' ? '.' : ' ');
|
|
26
|
+
return text;
|
|
27
|
+
};
|
|
28
|
+
const result = generate(atRule.nodes);
|
|
29
|
+
return '@' + atRule.id + (result ? ' ' + result : '');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export { generateAt as default };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { SELECTOR_COMBINATORS } from '../common.mjs';
|
|
2
|
+
|
|
3
|
+
const prefixMap = {
|
|
4
|
+
'class': '.',
|
|
5
|
+
'pseudo-class': ':',
|
|
6
|
+
'pseudo-element': '::',
|
|
7
|
+
'attribute': '',
|
|
8
|
+
'combinator': '',
|
|
9
|
+
'id': '#'
|
|
10
|
+
};
|
|
11
|
+
function generateSelector(nodes, body = '') {
|
|
12
|
+
const generate = (node)=>{
|
|
13
|
+
if (node.type === 'attribute') return `[${node.value}]`;
|
|
14
|
+
if (node.type === 'combinator') return node.value;
|
|
15
|
+
const prefix = node.type && prefixMap[node.type] || '';
|
|
16
|
+
const base = node.value ? prefix + node.value : '';
|
|
17
|
+
if ('children' in node && node.children?.length) {
|
|
18
|
+
const childrenText = node.children.map(generate).join('');
|
|
19
|
+
return node.value ? base + `(${childrenText})` : base + childrenText;
|
|
20
|
+
}
|
|
21
|
+
return base;
|
|
22
|
+
};
|
|
23
|
+
let pre = '';
|
|
24
|
+
let current = '';
|
|
25
|
+
const groups = [];
|
|
26
|
+
const flatNodes = nodes.flatMap((node)=>!('value' in node) && 'children' in node && node.children?.length ? node.children : node);
|
|
27
|
+
flatNodes.forEach((node)=>{
|
|
28
|
+
if (node.value === ',') {
|
|
29
|
+
groups.push(current);
|
|
30
|
+
current = '';
|
|
31
|
+
} else if (node.value === 'of' && 'children' in node) {
|
|
32
|
+
pre += node.children.map(generate).join('');
|
|
33
|
+
} else {
|
|
34
|
+
current += generate(node);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
if (current) groups.push(current);
|
|
38
|
+
if (pre) {
|
|
39
|
+
const lastChar = pre.charAt(pre.length - 1);
|
|
40
|
+
if (!SELECTOR_COMBINATORS.includes(lastChar) && lastChar !== ' ') {
|
|
41
|
+
pre += ' ';
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
const result = groups.length ? groups.map((text)=>pre + body + text).join(',') : pre + body;
|
|
45
|
+
return result;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export { generateSelector as default };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type MasterCSS from '../core';
|
|
2
|
+
import type { MasterCSSManifestAtIdentifier } from '@master/css-schema/manifest';
|
|
3
|
+
export type AtRule = {
|
|
4
|
+
id: MasterCSSManifestAtIdentifier;
|
|
5
|
+
nodes: AtRuleNode[];
|
|
6
|
+
};
|
|
7
|
+
export declare type AtRuleBooleanNode = {
|
|
8
|
+
raw?: string;
|
|
9
|
+
name: string;
|
|
10
|
+
type: 'boolean';
|
|
11
|
+
};
|
|
12
|
+
export declare type AtRuleNumberNode = {
|
|
13
|
+
raw?: string;
|
|
14
|
+
name: string;
|
|
15
|
+
type: 'number';
|
|
16
|
+
value: number;
|
|
17
|
+
unit?: string;
|
|
18
|
+
operator?: string;
|
|
19
|
+
};
|
|
20
|
+
export declare type AtRuleStringNode = {
|
|
21
|
+
raw?: string;
|
|
22
|
+
name: string;
|
|
23
|
+
type: 'string';
|
|
24
|
+
value: string;
|
|
25
|
+
};
|
|
26
|
+
export declare type AtRuleValueNode = AtRuleNumberNode | AtRuleStringNode;
|
|
27
|
+
export interface AtRuleComparisonOperatorNode {
|
|
28
|
+
type: 'comparison';
|
|
29
|
+
raw?: string;
|
|
30
|
+
value: string;
|
|
31
|
+
}
|
|
32
|
+
export interface AtRuleLogicalOperatorNode {
|
|
33
|
+
type: 'logical';
|
|
34
|
+
raw?: string;
|
|
35
|
+
value: string;
|
|
36
|
+
}
|
|
37
|
+
export type AtRuleOperatorNode = AtRuleComparisonOperatorNode | AtRuleLogicalOperatorNode;
|
|
38
|
+
export interface AtRuleGroupNode {
|
|
39
|
+
type?: 'group';
|
|
40
|
+
raw?: string;
|
|
41
|
+
children: AtRuleNode[];
|
|
42
|
+
}
|
|
43
|
+
export type AtRuleNode = AtRuleBooleanNode | AtRuleValueNode | AtRuleComparisonOperatorNode | AtRuleLogicalOperatorNode | AtRuleGroupNode;
|
|
44
|
+
export default function parseAt(token: string, css: MasterCSS, isRaw?: boolean): AtRule;
|