@master/css-compiler 2.0.0-beta.99 → 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 +34 -133
- package/dist/browser.d.ts +22 -0
- package/dist/browser.mjs +47 -0
- package/dist/core.d.ts +48 -0
- package/dist/core.mjs +2019 -0
- package/dist/css-transform.d.ts +6 -0
- package/dist/css-transform.mjs +18 -0
- package/dist/index.d.ts +46 -3
- package/dist/index.mjs +394 -10
- package/dist/lexer/imports.d.ts +13 -0
- package/dist/lexer/imports.mjs +44 -0
- package/dist/lexer/source.d.ts +3 -0
- package/dist/lexer/source.mjs +9 -0
- package/dist/lexer/standalone-master.d.ts +21 -0
- package/dist/lexer/standalone-master.mjs +233 -0
- package/dist/lower-css-directives.d.ts +16 -0
- package/dist/lower-css-directives.mjs +969 -0
- package/dist/master-css-manifest.d.ts +14 -0
- package/dist/master-css-manifest.mjs +760 -0
- package/dist/native-declaration.d.ts +2 -0
- package/dist/native-declaration.mjs +25 -0
- package/dist/utils/selectors.d.ts +3 -0
- package/dist/utils/selectors.mjs +55 -0
- package/dist/utils/unquote.d.ts +1 -0
- package/dist/utils/unquote.mjs +10 -0
- package/dist/utils/wrap-at-rules.d.ts +1 -0
- package/dist/utils/wrap-at-rules.mjs +10 -0
- package/package.json +1 -1
- package/dist/compiler.d.ts +0 -19
- package/dist/extract.d.ts +0 -3
- package/dist/index.cjs +0 -10
- package/dist/options/index.d.ts +0 -17
|
@@ -0,0 +1,969 @@
|
|
|
1
|
+
import { readCSSDirectiveVariantReference, CSSDirectiveError } from '@master/css-schema/css-directives';
|
|
2
|
+
import { createCompilerCSS, generateAt, parseAt, generateSelector, compareRulePriority, parseSelector } from '@master/css-engine/compiler';
|
|
3
|
+
import { createVariableNameResolver, createMasterCSSManifest } from './master-css-manifest.mjs';
|
|
4
|
+
import { combineStyleSelectors } from './utils/selectors.mjs';
|
|
5
|
+
import wrapAtRules from './utils/wrap-at-rules.mjs';
|
|
6
|
+
import { cssTreeNativeDeclarationMatcher } from './native-declaration.mjs';
|
|
7
|
+
|
|
8
|
+
const STYLE_AT_FEATURE_REGEX = /\(\s*(width|height|resolution)\s*(>=|<=|>|<)\s*(-?(?:\d+(?:\.\d+)?|\.\d+))([a-z%]*)\s*\)/g;
|
|
9
|
+
const MEDIA_MODE_NAMES = new Set([
|
|
10
|
+
'light',
|
|
11
|
+
'dark'
|
|
12
|
+
]);
|
|
13
|
+
const DEFAULT_MODE_NONE = 'none';
|
|
14
|
+
const CONDITION_VARIABLE_NAMESPACES = new Set([
|
|
15
|
+
'breakpoint',
|
|
16
|
+
'container'
|
|
17
|
+
]);
|
|
18
|
+
function isCSSDirectiveResult(input) {
|
|
19
|
+
return 'manifestInput' in input;
|
|
20
|
+
}
|
|
21
|
+
function getDirectiveInput(input) {
|
|
22
|
+
return isCSSDirectiveResult(input) ? input.manifestInput : input;
|
|
23
|
+
}
|
|
24
|
+
function getStyleDefinitions(input) {
|
|
25
|
+
return isCSSDirectiveResult(input) ? input.styleDefinitions : undefined;
|
|
26
|
+
}
|
|
27
|
+
function getResolutionManifest(options) {
|
|
28
|
+
return options.resolutionManifest || options.baseManifest;
|
|
29
|
+
}
|
|
30
|
+
function warn(warnings, options, message) {
|
|
31
|
+
warnings.push(message);
|
|
32
|
+
options.onWarning?.(message);
|
|
33
|
+
}
|
|
34
|
+
function isNamedDefaultMode(defaultMode) {
|
|
35
|
+
return typeof defaultMode === 'string' && defaultMode !== DEFAULT_MODE_NONE;
|
|
36
|
+
}
|
|
37
|
+
function normalizeVariable(variable, resolveVariableName) {
|
|
38
|
+
const resolved = resolveVariableName(variable);
|
|
39
|
+
if (variable.mode && resolved.namespace && CONDITION_VARIABLE_NAMESPACES.has(resolved.namespace)) {
|
|
40
|
+
throw new Error(`${resolved.namespace[0].toUpperCase()}${resolved.namespace.slice(1)} variables cannot be mode-specific: ${resolved.namespace}-${resolved.key}@${variable.mode}`);
|
|
41
|
+
}
|
|
42
|
+
if (variable.inline && variable.mode) {
|
|
43
|
+
throw new Error(`Inline theme variables cannot be mode-specific: ${resolved.name}@${variable.mode}`);
|
|
44
|
+
}
|
|
45
|
+
if (variable.inline && variable.static) {
|
|
46
|
+
throw new Error(`Inline and static theme variables cannot be combined: ${resolved.name}`);
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
name: resolved.name,
|
|
50
|
+
...resolved.namespace ? {
|
|
51
|
+
namespace: resolved.namespace
|
|
52
|
+
} : {},
|
|
53
|
+
key: resolved.key,
|
|
54
|
+
value: variable.value,
|
|
55
|
+
...variable.mode ? {
|
|
56
|
+
mode: variable.mode
|
|
57
|
+
} : {},
|
|
58
|
+
...variable.inline ? {
|
|
59
|
+
inline: true
|
|
60
|
+
} : {},
|
|
61
|
+
...variable.static ? {
|
|
62
|
+
static: true
|
|
63
|
+
} : {}
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
function variableSlot(variable) {
|
|
67
|
+
return [
|
|
68
|
+
variable.key ?? variable.name,
|
|
69
|
+
variable.namespace || '',
|
|
70
|
+
variable.mode || ''
|
|
71
|
+
].join('\0');
|
|
72
|
+
}
|
|
73
|
+
function addVariable(input, variable, resolveVariableName) {
|
|
74
|
+
const definition = normalizeVariable(variable, resolveVariableName);
|
|
75
|
+
if (definition.mode) {
|
|
76
|
+
input.modes ??= [];
|
|
77
|
+
if (!input.modes.includes(definition.mode)) input.modes.push(definition.mode);
|
|
78
|
+
}
|
|
79
|
+
input.variables ??= [];
|
|
80
|
+
const foundIndex = input.variables.findIndex((existing)=>variableSlot(existing) === variableSlot(definition));
|
|
81
|
+
if (foundIndex !== -1) input.variables.splice(foundIndex, 1);
|
|
82
|
+
input.variables.push(definition);
|
|
83
|
+
}
|
|
84
|
+
function cloneUtilityRule(rule) {
|
|
85
|
+
return {
|
|
86
|
+
declarations: {
|
|
87
|
+
...rule.declarations
|
|
88
|
+
},
|
|
89
|
+
...rule.selector ? {
|
|
90
|
+
selector: rule.selector
|
|
91
|
+
} : {},
|
|
92
|
+
...rule.atRules?.length ? {
|
|
93
|
+
atRules: [
|
|
94
|
+
...rule.atRules
|
|
95
|
+
]
|
|
96
|
+
} : {}
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
function cloneUtility(definition) {
|
|
100
|
+
return {
|
|
101
|
+
...definition,
|
|
102
|
+
type: definition.type || 'static',
|
|
103
|
+
...definition.pattern ? {
|
|
104
|
+
pattern: {
|
|
105
|
+
prefix: definition.pattern.prefix,
|
|
106
|
+
values: [
|
|
107
|
+
...definition.pattern.values
|
|
108
|
+
]
|
|
109
|
+
}
|
|
110
|
+
} : {},
|
|
111
|
+
...definition.dynamic ? {
|
|
112
|
+
dynamic: {
|
|
113
|
+
key: definition.dynamic.key,
|
|
114
|
+
...definition.dynamic.variableAliasRefs?.length ? {
|
|
115
|
+
variableAliasRefs: [
|
|
116
|
+
...definition.dynamic.variableAliasRefs
|
|
117
|
+
]
|
|
118
|
+
} : {},
|
|
119
|
+
...definition.dynamic.kind ? {
|
|
120
|
+
kind: definition.dynamic.kind
|
|
121
|
+
} : {},
|
|
122
|
+
...definition.dynamic.values?.length ? {
|
|
123
|
+
values: [
|
|
124
|
+
...definition.dynamic.values
|
|
125
|
+
]
|
|
126
|
+
} : {},
|
|
127
|
+
...definition.dynamic.arbitrary ? {
|
|
128
|
+
arbitrary: true
|
|
129
|
+
} : {}
|
|
130
|
+
}
|
|
131
|
+
} : {},
|
|
132
|
+
...definition.declarations ? {
|
|
133
|
+
declarations: {
|
|
134
|
+
...definition.declarations
|
|
135
|
+
}
|
|
136
|
+
} : {},
|
|
137
|
+
...definition.atRules?.length ? {
|
|
138
|
+
atRules: [
|
|
139
|
+
...definition.atRules
|
|
140
|
+
]
|
|
141
|
+
} : {},
|
|
142
|
+
...definition.rules?.length ? {
|
|
143
|
+
rules: definition.rules.map(cloneUtilityRule)
|
|
144
|
+
} : {}
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
function normalizeDirectiveInput(input = {}, options = {}) {
|
|
148
|
+
const source = getDirectiveInput(input);
|
|
149
|
+
const resolveVariableName = createVariableNameResolver(source, {
|
|
150
|
+
baseManifest: getResolutionManifest(options)
|
|
151
|
+
});
|
|
152
|
+
const normalized = {};
|
|
153
|
+
if (source.rootSize !== undefined) normalized.rootSize = source.rootSize;
|
|
154
|
+
if (source.baseUnit !== undefined) normalized.baseUnit = source.baseUnit;
|
|
155
|
+
if (source.defaultMode !== undefined) normalized.defaultMode = source.defaultMode;
|
|
156
|
+
if (source.modeTrigger !== undefined) normalized.modeTrigger = source.modeTrigger;
|
|
157
|
+
if (source.scope !== undefined) normalized.scope = source.scope;
|
|
158
|
+
if (source.important !== undefined) normalized.important = source.important;
|
|
159
|
+
if (source.variants?.length) normalized.variants = source.variants.map((variant)=>({
|
|
160
|
+
token: variant.token,
|
|
161
|
+
branches: variant.branches.map((branch)=>({
|
|
162
|
+
...branch,
|
|
163
|
+
...branch.atRules?.length ? {
|
|
164
|
+
atRules: [
|
|
165
|
+
...branch.atRules
|
|
166
|
+
]
|
|
167
|
+
} : {}
|
|
168
|
+
}))
|
|
169
|
+
}));
|
|
170
|
+
if (source.animations) normalized.animations = {
|
|
171
|
+
...source.animations
|
|
172
|
+
};
|
|
173
|
+
if (source.animationOptions) normalized.animationOptions = {
|
|
174
|
+
...source.animationOptions
|
|
175
|
+
};
|
|
176
|
+
if (source.utilities?.length) normalized.utilities = source.utilities.map(cloneUtility);
|
|
177
|
+
for (const mode of source.modes || []){
|
|
178
|
+
normalized.modes ??= [];
|
|
179
|
+
if (!normalized.modes.includes(mode)) normalized.modes.push(mode);
|
|
180
|
+
}
|
|
181
|
+
for (const variable of source.variables || []){
|
|
182
|
+
addVariable(normalized, variable, resolveVariableName);
|
|
183
|
+
}
|
|
184
|
+
return normalized;
|
|
185
|
+
}
|
|
186
|
+
function collectModeNames(input) {
|
|
187
|
+
const modes = new Set(input.modes || []);
|
|
188
|
+
if (isNamedDefaultMode(input.defaultMode)) modes.add(input.defaultMode);
|
|
189
|
+
return modes;
|
|
190
|
+
}
|
|
191
|
+
function collectVariablesByNamespace(input, namespace, resolveVariableName) {
|
|
192
|
+
return new Set((input.variables || []).map(resolveVariableName).filter((variable)=>variable.namespace === namespace).map((variable)=>variable.key).filter((key)=>Boolean(key)));
|
|
193
|
+
}
|
|
194
|
+
function validateTokenConflicts(input, resolveVariableName) {
|
|
195
|
+
const modes = collectModeNames(input);
|
|
196
|
+
const breakpoints = collectVariablesByNamespace(input, 'breakpoint', resolveVariableName);
|
|
197
|
+
const containers = collectVariablesByNamespace(input, 'container', resolveVariableName);
|
|
198
|
+
for (const mode of modes){
|
|
199
|
+
if (breakpoints.has(mode)) {
|
|
200
|
+
throw new Error(`Mode "${mode}" conflicts with breakpoint variable "--breakpoint-${mode}"`);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
for (const breakpoint of breakpoints){
|
|
204
|
+
if (modes.has(breakpoint)) {
|
|
205
|
+
throw new Error(`Breakpoint variable "--breakpoint-${breakpoint}" conflicts with mode "${breakpoint}"`);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
const variantNames = (input.variants || []).filter((variant)=>variant.token.startsWith('@')).map((variant)=>variant.token.slice(1));
|
|
209
|
+
for (const token of variantNames){
|
|
210
|
+
if (modes.has(token)) {
|
|
211
|
+
throw new Error(`Variant "${token}" conflicts with mode "${token}"`);
|
|
212
|
+
}
|
|
213
|
+
if (breakpoints.has(token)) {
|
|
214
|
+
throw new Error(`Variant "${token}" conflicts with breakpoint variable "--breakpoint-${token}"`);
|
|
215
|
+
}
|
|
216
|
+
if (containers.has(token)) {
|
|
217
|
+
throw new Error(`Variant "${token}" conflicts with container variable "--container-${token}"`);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
function warnUnsupportedMediaModes(input, options, warnings) {
|
|
222
|
+
if (input.modeTrigger !== 'media') return;
|
|
223
|
+
const customModes = new Set((input.modes || []).filter((mode)=>!MEDIA_MODE_NAMES.has(mode)));
|
|
224
|
+
if (isNamedDefaultMode(input.defaultMode) && !MEDIA_MODE_NAMES.has(input.defaultMode)) {
|
|
225
|
+
customModes.add(input.defaultMode);
|
|
226
|
+
}
|
|
227
|
+
if (!customModes.size) return;
|
|
228
|
+
const modeList = [
|
|
229
|
+
...customModes
|
|
230
|
+
].map((mode)=>`"${mode}"`).join(', ');
|
|
231
|
+
const subject = customModes.size === 1 ? 'mode' : 'modes';
|
|
232
|
+
warn(warnings, options, `Custom ${subject} ${modeList} will not work with mode-trigger: media. Browsers only support light and dark prefers-color-scheme values; use mode-trigger: class or host for custom modes.`);
|
|
233
|
+
}
|
|
234
|
+
function createDirectiveCSS(input, options) {
|
|
235
|
+
return createCompilerCSS(createMasterCSSManifest(input, {
|
|
236
|
+
baseManifest: getResolutionManifest(options)
|
|
237
|
+
}), undefined, {
|
|
238
|
+
nativeDeclarationMatcher: cssTreeNativeDeclarationMatcher
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
function getUtilityAtRuleDefinitions(utility) {
|
|
242
|
+
const atRules = [];
|
|
243
|
+
if (utility.atRules) {
|
|
244
|
+
for (const id of [
|
|
245
|
+
'container',
|
|
246
|
+
'starting-style',
|
|
247
|
+
'supports',
|
|
248
|
+
'media',
|
|
249
|
+
'layer'
|
|
250
|
+
]){
|
|
251
|
+
const nodes = utility.atRules[id];
|
|
252
|
+
if (!nodes) continue;
|
|
253
|
+
if (id === 'layer' && utility.explicitLayerName) continue;
|
|
254
|
+
atRules.push(generateAt({
|
|
255
|
+
id,
|
|
256
|
+
nodes
|
|
257
|
+
}));
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
return atRules;
|
|
261
|
+
}
|
|
262
|
+
function getComposedUtilitySelector(utility, css) {
|
|
263
|
+
let selector = utility.selectorTemplate ? '&' : utility.selectorNodes ? generateSelector(utility.selectorNodes, '&') : '&';
|
|
264
|
+
if (utility.selectorTemplate) {
|
|
265
|
+
selector = utility.selectorTemplate.replace(/&/g, selector);
|
|
266
|
+
}
|
|
267
|
+
if (utility.mode && css.settings.modeTrigger !== 'media') {
|
|
268
|
+
const modeSelector = css.getModeSelector(utility.mode);
|
|
269
|
+
if (modeSelector) selector = `${modeSelector} ${selector}`;
|
|
270
|
+
}
|
|
271
|
+
return selector;
|
|
272
|
+
}
|
|
273
|
+
function cloneDeclarations(declarations, important) {
|
|
274
|
+
const result = {};
|
|
275
|
+
for(const propertyName in declarations){
|
|
276
|
+
const propertyValue = declarations[propertyName];
|
|
277
|
+
const value = String(propertyValue);
|
|
278
|
+
result[propertyName] = important && !value.endsWith('!important') ? `${value}!important` : value;
|
|
279
|
+
}
|
|
280
|
+
return result;
|
|
281
|
+
}
|
|
282
|
+
function createStyleDefinitionsFromCompose(definition, css) {
|
|
283
|
+
const utilities = css.createRules(definition.className);
|
|
284
|
+
if (!utilities.length) {
|
|
285
|
+
throw new CSSDirectiveError('invalid-compose-class', `Invalid @compose class: ${definition.className}`, definition.source || definition.directiveSource);
|
|
286
|
+
}
|
|
287
|
+
return utilities.flatMap((utility)=>{
|
|
288
|
+
const selector = getComposedUtilitySelector(utility, css);
|
|
289
|
+
const layer = utility.explicitLayerName;
|
|
290
|
+
const utilityAtRules = getUtilityAtRuleDefinitions(utility);
|
|
291
|
+
const declarationRules = utility.declarationRules || (utility.declarations ? [
|
|
292
|
+
{
|
|
293
|
+
declarations: utility.declarations
|
|
294
|
+
}
|
|
295
|
+
] : []);
|
|
296
|
+
return declarationRules.map(({ declarations, atRules, selector: ruleSelector })=>({
|
|
297
|
+
utility,
|
|
298
|
+
selector: ruleSelector ? combineStyleSelectors(selector, ruleSelector) : selector,
|
|
299
|
+
declarations: cloneDeclarations(declarations, utility.important),
|
|
300
|
+
...layer ? {
|
|
301
|
+
layer
|
|
302
|
+
} : {},
|
|
303
|
+
...[
|
|
304
|
+
...utilityAtRules,
|
|
305
|
+
...atRules || []
|
|
306
|
+
].length ? {
|
|
307
|
+
atRules: [
|
|
308
|
+
...utilityAtRules,
|
|
309
|
+
...atRules || []
|
|
310
|
+
]
|
|
311
|
+
} : {}
|
|
312
|
+
}));
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
function combineSelectorWrapper(selector, wrapper) {
|
|
316
|
+
return wrapper.replace(/&/g, selector);
|
|
317
|
+
}
|
|
318
|
+
function mergeResolvedVariantReferenceBranch(branch, resolved, token) {
|
|
319
|
+
const nextLayer = resolved.layer || branch.layer;
|
|
320
|
+
if (branch.layer && resolved.layer && branch.layer !== resolved.layer) {
|
|
321
|
+
throw new Error(`@variant ${token} cannot assign multiple layers`);
|
|
322
|
+
}
|
|
323
|
+
return {
|
|
324
|
+
selector: resolved.selector ? combineSelectorWrapper(branch.selector || '&', resolved.selector) : branch.selector,
|
|
325
|
+
atRules: [
|
|
326
|
+
...branch.atRules || [],
|
|
327
|
+
...resolved.atRules || []
|
|
328
|
+
],
|
|
329
|
+
...nextLayer ? {
|
|
330
|
+
layer: nextLayer
|
|
331
|
+
} : {}
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
function cloneConfiguredVariantBranches(token, css) {
|
|
335
|
+
const configuredVariant = css.resolveVariant(token);
|
|
336
|
+
if (configuredVariant) {
|
|
337
|
+
return configuredVariant.map((branch)=>({
|
|
338
|
+
...branch.selector ? {
|
|
339
|
+
selector: branch.selector
|
|
340
|
+
} : {},
|
|
341
|
+
...branch.atRules?.length ? {
|
|
342
|
+
atRules: [
|
|
343
|
+
...branch.atRules
|
|
344
|
+
]
|
|
345
|
+
} : {},
|
|
346
|
+
...branch.layer ? {
|
|
347
|
+
layer: branch.layer
|
|
348
|
+
} : {}
|
|
349
|
+
}));
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
function findClosingParen(value, start) {
|
|
353
|
+
let depth = 0;
|
|
354
|
+
let quote = '';
|
|
355
|
+
for(let index = start; index < value.length; index++){
|
|
356
|
+
const char = value[index];
|
|
357
|
+
if (quote) {
|
|
358
|
+
if (char === '\\') {
|
|
359
|
+
index++;
|
|
360
|
+
} else if (char === quote) {
|
|
361
|
+
quote = '';
|
|
362
|
+
}
|
|
363
|
+
continue;
|
|
364
|
+
}
|
|
365
|
+
if (char === '"' || char === '\'') {
|
|
366
|
+
quote = char;
|
|
367
|
+
continue;
|
|
368
|
+
}
|
|
369
|
+
if (char === '(') depth++;
|
|
370
|
+
if (char === ')') {
|
|
371
|
+
depth--;
|
|
372
|
+
if (depth === 0) return index;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
return -1;
|
|
376
|
+
}
|
|
377
|
+
function resolveSelectorVariantStack(selectorStack, css, token) {
|
|
378
|
+
let branches = [
|
|
379
|
+
{}
|
|
380
|
+
];
|
|
381
|
+
const selectorVariantTokens = [
|
|
382
|
+
...css.variants.keys()
|
|
383
|
+
].filter((variantToken)=>variantToken.startsWith(':')).sort((a, b)=>b.length - a.length);
|
|
384
|
+
let index = 0;
|
|
385
|
+
let raw = '';
|
|
386
|
+
const flushRaw = ()=>{
|
|
387
|
+
if (!raw) return;
|
|
388
|
+
const selector = generateSelector(parseSelector(raw, css), '&');
|
|
389
|
+
branches = branches.map((branch)=>mergeResolvedVariantReferenceBranch(branch, {
|
|
390
|
+
selector
|
|
391
|
+
}, token));
|
|
392
|
+
raw = '';
|
|
393
|
+
};
|
|
394
|
+
while(index < selectorStack.length){
|
|
395
|
+
const matchedToken = selectorVariantTokens.find((variantToken)=>{
|
|
396
|
+
if (!selectorStack.startsWith(variantToken, index)) return false;
|
|
397
|
+
const next = selectorStack[index + variantToken.length];
|
|
398
|
+
return next === undefined || next === '(' || !/[-_a-zA-Z0-9]/.test(next);
|
|
399
|
+
});
|
|
400
|
+
if (!matchedToken) {
|
|
401
|
+
raw += selectorStack[index++];
|
|
402
|
+
continue;
|
|
403
|
+
}
|
|
404
|
+
const configuredBranches = cloneConfiguredVariantBranches(matchedToken, css);
|
|
405
|
+
if (!configuredBranches) {
|
|
406
|
+
raw += selectorStack[index++];
|
|
407
|
+
continue;
|
|
408
|
+
}
|
|
409
|
+
flushRaw();
|
|
410
|
+
index += matchedToken.length;
|
|
411
|
+
let suffix = '';
|
|
412
|
+
if (selectorStack[index] === '(') {
|
|
413
|
+
const end = findClosingParen(selectorStack, index);
|
|
414
|
+
if (end !== -1) {
|
|
415
|
+
suffix = selectorStack.slice(index, end + 1);
|
|
416
|
+
index = end + 1;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
branches = branches.flatMap((branch)=>configuredBranches.map((configuredBranch)=>{
|
|
420
|
+
const selector = configuredBranch.selector && suffix ? configuredBranch.selector + suffix : configuredBranch.selector;
|
|
421
|
+
return mergeResolvedVariantReferenceBranch(branch, {
|
|
422
|
+
...configuredBranch,
|
|
423
|
+
...selector ? {
|
|
424
|
+
selector
|
|
425
|
+
} : {}
|
|
426
|
+
}, token);
|
|
427
|
+
}));
|
|
428
|
+
}
|
|
429
|
+
flushRaw();
|
|
430
|
+
return branches;
|
|
431
|
+
}
|
|
432
|
+
function resolveAtVariantReference(token, css) {
|
|
433
|
+
const configuredVariant = cloneConfiguredVariantBranches(token, css);
|
|
434
|
+
if (configuredVariant) return configuredVariant;
|
|
435
|
+
const atToken = token.slice(1);
|
|
436
|
+
if (css.modes.includes(atToken)) {
|
|
437
|
+
const modeSelector = css.getModeSelector(atToken);
|
|
438
|
+
return modeSelector ? [
|
|
439
|
+
{
|
|
440
|
+
selector: `${modeSelector} &`
|
|
441
|
+
}
|
|
442
|
+
] : [
|
|
443
|
+
{
|
|
444
|
+
atRules: [
|
|
445
|
+
`@media (prefers-color-scheme:${atToken})`
|
|
446
|
+
]
|
|
447
|
+
}
|
|
448
|
+
];
|
|
449
|
+
}
|
|
450
|
+
if (/^-?[_a-zA-Z][-_a-zA-Z0-9]*$/.test(atToken) && !css.atRules.has(atToken)) {
|
|
451
|
+
throw new Error(`Unknown @variant token: ${token}`);
|
|
452
|
+
}
|
|
453
|
+
return [
|
|
454
|
+
{
|
|
455
|
+
atRules: [
|
|
456
|
+
generateAt(parseAt(atToken, css))
|
|
457
|
+
]
|
|
458
|
+
}
|
|
459
|
+
];
|
|
460
|
+
}
|
|
461
|
+
function resolveMasterVariantReference(token, css) {
|
|
462
|
+
if (!token.startsWith(':') && !token.startsWith('@')) {
|
|
463
|
+
throw new Error(`@variant requires a full variant token: ${token}`);
|
|
464
|
+
}
|
|
465
|
+
const [selectorStack = '', ...conditionStacks] = token.split('@');
|
|
466
|
+
let branches = selectorStack ? resolveSelectorVariantStack(selectorStack, css, token) : [
|
|
467
|
+
{}
|
|
468
|
+
];
|
|
469
|
+
for (const conditionStack of conditionStacks){
|
|
470
|
+
if (!conditionStack) continue;
|
|
471
|
+
const resolvedBranches = resolveAtVariantReference(`@${conditionStack}`, css);
|
|
472
|
+
branches = branches.flatMap((branch)=>resolvedBranches.map((resolved)=>mergeResolvedVariantReferenceBranch(branch, resolved, token)));
|
|
473
|
+
}
|
|
474
|
+
return branches;
|
|
475
|
+
}
|
|
476
|
+
function resolveConfiguredBranches(atRules, css, selector = '&', layer) {
|
|
477
|
+
let branches = [
|
|
478
|
+
{
|
|
479
|
+
selector,
|
|
480
|
+
...layer ? {
|
|
481
|
+
layer
|
|
482
|
+
} : {}
|
|
483
|
+
}
|
|
484
|
+
];
|
|
485
|
+
if (!atRules?.length) return branches;
|
|
486
|
+
for (const atRule of atRules){
|
|
487
|
+
const token = readCSSDirectiveVariantReference(atRule);
|
|
488
|
+
if (!token) {
|
|
489
|
+
branches = branches.map((branch)=>({
|
|
490
|
+
...branch,
|
|
491
|
+
atRules: [
|
|
492
|
+
...branch.atRules || [],
|
|
493
|
+
atRule
|
|
494
|
+
]
|
|
495
|
+
}));
|
|
496
|
+
continue;
|
|
497
|
+
}
|
|
498
|
+
const resolvedBranches = resolveMasterVariantReference(token, css);
|
|
499
|
+
branches = branches.flatMap((branch)=>resolvedBranches.map((resolved)=>{
|
|
500
|
+
const nextLayer = resolved.layer || branch.layer;
|
|
501
|
+
if (branch.layer && resolved.layer && branch.layer !== resolved.layer) {
|
|
502
|
+
throw new Error(`@variant ${token} cannot assign multiple layers`);
|
|
503
|
+
}
|
|
504
|
+
return {
|
|
505
|
+
selector: resolved.selector ? combineSelectorWrapper(branch.selector, resolved.selector) : branch.selector,
|
|
506
|
+
atRules: [
|
|
507
|
+
...branch.atRules || [],
|
|
508
|
+
...resolved.atRules || []
|
|
509
|
+
],
|
|
510
|
+
...nextLayer ? {
|
|
511
|
+
layer: nextLayer
|
|
512
|
+
} : {}
|
|
513
|
+
};
|
|
514
|
+
}));
|
|
515
|
+
}
|
|
516
|
+
return branches.map((branch)=>({
|
|
517
|
+
selector: branch.selector,
|
|
518
|
+
...branch.atRules?.length ? {
|
|
519
|
+
atRules: branch.atRules
|
|
520
|
+
} : {},
|
|
521
|
+
...branch.layer ? {
|
|
522
|
+
layer: branch.layer
|
|
523
|
+
} : {}
|
|
524
|
+
}));
|
|
525
|
+
}
|
|
526
|
+
function ensureUtilityRules(definition) {
|
|
527
|
+
if (!definition.declarations) return;
|
|
528
|
+
const declarations = definition.declarations;
|
|
529
|
+
delete definition.declarations;
|
|
530
|
+
const atRules = definition.atRules;
|
|
531
|
+
delete definition.atRules;
|
|
532
|
+
definition.rules ??= [];
|
|
533
|
+
definition.rules.push({
|
|
534
|
+
...atRules?.length ? {
|
|
535
|
+
atRules: [
|
|
536
|
+
...atRules
|
|
537
|
+
]
|
|
538
|
+
} : {},
|
|
539
|
+
declarations
|
|
540
|
+
});
|
|
541
|
+
}
|
|
542
|
+
function finalizeUtilityDefinitions(input, css) {
|
|
543
|
+
const utilities = input.utilities;
|
|
544
|
+
if (!utilities?.length) return;
|
|
545
|
+
for (const definition of utilities){
|
|
546
|
+
if (definition.atRules?.some(readCSSDirectiveVariantReference)) {
|
|
547
|
+
const resolvedBranches = resolveConfiguredBranches(definition.atRules, css);
|
|
548
|
+
delete definition.atRules;
|
|
549
|
+
if (definition.declarations) {
|
|
550
|
+
definition.rules ??= [];
|
|
551
|
+
for (const resolved of resolvedBranches){
|
|
552
|
+
definition.rules.push({
|
|
553
|
+
declarations: definition.declarations,
|
|
554
|
+
...resolved.selector !== '&' ? {
|
|
555
|
+
selector: resolved.selector
|
|
556
|
+
} : {},
|
|
557
|
+
...resolved.atRules?.length ? {
|
|
558
|
+
atRules: resolved.atRules
|
|
559
|
+
} : {}
|
|
560
|
+
});
|
|
561
|
+
}
|
|
562
|
+
delete definition.declarations;
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
if (!definition.rules?.length) continue;
|
|
566
|
+
definition.rules = definition.rules.flatMap((rule)=>{
|
|
567
|
+
const resolvedBranches = resolveConfiguredBranches(rule.atRules, css, rule.selector || '&');
|
|
568
|
+
return resolvedBranches.map((resolved)=>({
|
|
569
|
+
declarations: rule.declarations,
|
|
570
|
+
...resolved.selector !== '&' ? {
|
|
571
|
+
selector: resolved.selector
|
|
572
|
+
} : {},
|
|
573
|
+
...resolved.atRules?.length ? {
|
|
574
|
+
atRules: resolved.atRules
|
|
575
|
+
} : {}
|
|
576
|
+
}));
|
|
577
|
+
});
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
function getStyleMergeBucketKey(selector, atRules, layer) {
|
|
581
|
+
return JSON.stringify([
|
|
582
|
+
layer || '',
|
|
583
|
+
selector,
|
|
584
|
+
atRules || []
|
|
585
|
+
]);
|
|
586
|
+
}
|
|
587
|
+
function pushStyleMergeEvent(buckets, selector, atRules, layer, event) {
|
|
588
|
+
const key = getStyleMergeBucketKey(selector, atRules, layer);
|
|
589
|
+
const bucket = buckets.get(key) || {
|
|
590
|
+
selector,
|
|
591
|
+
...atRules?.length ? {
|
|
592
|
+
atRules
|
|
593
|
+
} : {},
|
|
594
|
+
...layer ? {
|
|
595
|
+
layer
|
|
596
|
+
} : {},
|
|
597
|
+
order: event.order,
|
|
598
|
+
events: []
|
|
599
|
+
};
|
|
600
|
+
bucket.order = Math.min(bucket.order, event.order);
|
|
601
|
+
bucket.events.push(event);
|
|
602
|
+
buckets.set(key, bucket);
|
|
603
|
+
}
|
|
604
|
+
function isImportantStyleDeclarationValue(value) {
|
|
605
|
+
return String(value).trim().endsWith('!important');
|
|
606
|
+
}
|
|
607
|
+
function applyStyleDeclaration(declarations, propertyName, value) {
|
|
608
|
+
const key = propertyName;
|
|
609
|
+
const currentValue = declarations[key];
|
|
610
|
+
if (currentValue !== undefined && isImportantStyleDeclarationValue(currentValue) && !isImportantStyleDeclarationValue(value)) {
|
|
611
|
+
return;
|
|
612
|
+
}
|
|
613
|
+
delete declarations[key];
|
|
614
|
+
declarations[key] = value;
|
|
615
|
+
}
|
|
616
|
+
function applyStyleDeclarations(declarations, incomingDeclarations) {
|
|
617
|
+
for(const propertyName in incomingDeclarations){
|
|
618
|
+
applyStyleDeclaration(declarations, propertyName, incomingDeclarations[propertyName]);
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
function createMergedStyleDefinition(bucket) {
|
|
622
|
+
const declarations = {};
|
|
623
|
+
const composeBatch = [];
|
|
624
|
+
const flushComposeBatch = ()=>{
|
|
625
|
+
composeBatch.sort((a, b)=>compareRulePriority(a.utility, b.utility) || a.order - b.order);
|
|
626
|
+
for (const event of composeBatch){
|
|
627
|
+
applyStyleDeclarations(declarations, event.declarations);
|
|
628
|
+
}
|
|
629
|
+
composeBatch.length = 0;
|
|
630
|
+
};
|
|
631
|
+
for (const event of [
|
|
632
|
+
...bucket.events
|
|
633
|
+
].sort((a, b)=>a.order - b.order)){
|
|
634
|
+
if (event.type === 'compose') {
|
|
635
|
+
composeBatch.push(event);
|
|
636
|
+
continue;
|
|
637
|
+
}
|
|
638
|
+
flushComposeBatch();
|
|
639
|
+
applyStyleDeclarations(declarations, event.declarations);
|
|
640
|
+
}
|
|
641
|
+
flushComposeBatch();
|
|
642
|
+
if (!Object.keys(declarations).length) return;
|
|
643
|
+
return {
|
|
644
|
+
selector: bucket.selector,
|
|
645
|
+
declarations,
|
|
646
|
+
...bucket.atRules?.length ? {
|
|
647
|
+
atRules: bucket.atRules
|
|
648
|
+
} : {},
|
|
649
|
+
...bucket.layer ? {
|
|
650
|
+
layer: bucket.layer
|
|
651
|
+
} : {}
|
|
652
|
+
};
|
|
653
|
+
}
|
|
654
|
+
function normalizeStyleAtFeatureValue(value, unit, rootSize) {
|
|
655
|
+
if (unit === 'px') return value / rootSize;
|
|
656
|
+
return value;
|
|
657
|
+
}
|
|
658
|
+
function getStyleAtRuleFeatures(atRules, rootSize) {
|
|
659
|
+
const featureMap = new Map();
|
|
660
|
+
for (const atRule of atRules || []){
|
|
661
|
+
for (const match of atRule.matchAll(STYLE_AT_FEATURE_REGEX)){
|
|
662
|
+
const [, name, operator, rawValue, unit] = match;
|
|
663
|
+
const value = normalizeStyleAtFeatureValue(Number(rawValue), unit, rootSize);
|
|
664
|
+
const entry = featureMap.get(name) ?? {};
|
|
665
|
+
switch(operator){
|
|
666
|
+
case '>':
|
|
667
|
+
entry.min = value + 0.02;
|
|
668
|
+
break;
|
|
669
|
+
case '>=':
|
|
670
|
+
entry.min = value;
|
|
671
|
+
break;
|
|
672
|
+
case '<':
|
|
673
|
+
entry.max = value - 0.02;
|
|
674
|
+
break;
|
|
675
|
+
case '<=':
|
|
676
|
+
entry.max = value;
|
|
677
|
+
break;
|
|
678
|
+
}
|
|
679
|
+
featureMap.set(name, entry);
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
return [
|
|
683
|
+
...featureMap.entries()
|
|
684
|
+
].map(([name, entry])=>[
|
|
685
|
+
name,
|
|
686
|
+
entry.min ?? 0,
|
|
687
|
+
entry.max ?? Number.MAX_SAFE_INTEGER
|
|
688
|
+
]).sort(([a], [b])=>a.localeCompare(b, undefined, {
|
|
689
|
+
numeric: true
|
|
690
|
+
}));
|
|
691
|
+
}
|
|
692
|
+
function compareStyleAtRuleFeatures(a, b) {
|
|
693
|
+
const len = Math.max(a.length, b.length);
|
|
694
|
+
for(let index = 0; index < len; index++){
|
|
695
|
+
const left = a[index];
|
|
696
|
+
const right = b[index];
|
|
697
|
+
if (!left) return -1;
|
|
698
|
+
if (!right) return 1;
|
|
699
|
+
const [nameA, minA, maxA] = left;
|
|
700
|
+
const [nameB, minB, maxB] = right;
|
|
701
|
+
const nameCompare = nameA.localeCompare(nameB, undefined, {
|
|
702
|
+
numeric: true
|
|
703
|
+
});
|
|
704
|
+
if (nameCompare !== 0) return nameCompare;
|
|
705
|
+
const rangeA = maxA - minA;
|
|
706
|
+
const rangeB = maxB - minB;
|
|
707
|
+
if (rangeA !== rangeB) return rangeB - rangeA;
|
|
708
|
+
if (minA !== minB) return minB - minA;
|
|
709
|
+
if (maxA !== maxB) return maxB - maxA;
|
|
710
|
+
}
|
|
711
|
+
return 0;
|
|
712
|
+
}
|
|
713
|
+
function compareStyleMergeBuckets(a, b, rootSize) {
|
|
714
|
+
const layerA = a.layer || 'components';
|
|
715
|
+
const layerB = b.layer || 'components';
|
|
716
|
+
if (layerA === layerB && a.selector === b.selector) {
|
|
717
|
+
const atRuleStateA = a.atRules?.length ? 1 : 0;
|
|
718
|
+
const atRuleStateB = b.atRules?.length ? 1 : 0;
|
|
719
|
+
if (atRuleStateA !== atRuleStateB) return atRuleStateA - atRuleStateB;
|
|
720
|
+
if (atRuleStateA && atRuleStateB) {
|
|
721
|
+
const featuresA = getStyleAtRuleFeatures(a.atRules, rootSize);
|
|
722
|
+
const featuresB = getStyleAtRuleFeatures(b.atRules, rootSize);
|
|
723
|
+
if (featuresA.length && featuresB.length) {
|
|
724
|
+
const featureCompare = compareStyleAtRuleFeatures(featuresA, featuresB);
|
|
725
|
+
if (featureCompare !== 0) return featureCompare;
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
return a.order - b.order;
|
|
730
|
+
}
|
|
731
|
+
function createMergedStyleDefinitions(definitions, css, targetLayer) {
|
|
732
|
+
const buckets = new Map();
|
|
733
|
+
for (const definition of definitions){
|
|
734
|
+
if (definition.type === 'compose') {
|
|
735
|
+
const composedDefinitions = createStyleDefinitionsFromCompose(definition, css);
|
|
736
|
+
for (const composedDefinition of composedDefinitions){
|
|
737
|
+
const { atRules: composedAtRules, ...composedDefinitionWithoutAtRules } = composedDefinition;
|
|
738
|
+
const selector = combineStyleSelectors(definition.selector, composedDefinition.selector);
|
|
739
|
+
const resolvedBranches = resolveConfiguredBranches([
|
|
740
|
+
...definition.atRules || [],
|
|
741
|
+
...composedAtRules || []
|
|
742
|
+
], css, selector, targetLayer || composedDefinitionWithoutAtRules.layer);
|
|
743
|
+
for (const resolved of resolvedBranches){
|
|
744
|
+
pushStyleMergeEvent(buckets, resolved.selector, resolved.atRules, resolved.layer, {
|
|
745
|
+
type: 'compose',
|
|
746
|
+
order: definition.order,
|
|
747
|
+
utility: composedDefinitionWithoutAtRules.utility,
|
|
748
|
+
declarations: composedDefinitionWithoutAtRules.declarations
|
|
749
|
+
});
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
} else {
|
|
753
|
+
const resolvedBranches = resolveConfiguredBranches(definition.atRules, css, definition.selector, targetLayer || definition.layer);
|
|
754
|
+
for (const resolved of resolvedBranches){
|
|
755
|
+
pushStyleMergeEvent(buckets, resolved.selector, resolved.atRules, resolved.layer, {
|
|
756
|
+
type: 'native',
|
|
757
|
+
order: definition.order,
|
|
758
|
+
declarations: definition.declarations
|
|
759
|
+
});
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
const rootSize = css.settings.rootSize || 16;
|
|
764
|
+
return [
|
|
765
|
+
...buckets.values()
|
|
766
|
+
].sort((a, b)=>compareStyleMergeBuckets(a, b, rootSize)).flatMap((bucket)=>{
|
|
767
|
+
const definition = createMergedStyleDefinition(bucket);
|
|
768
|
+
return definition ? [
|
|
769
|
+
definition
|
|
770
|
+
] : [];
|
|
771
|
+
});
|
|
772
|
+
}
|
|
773
|
+
function isManagedStyleDefinition(definition) {
|
|
774
|
+
return Boolean(definition.name);
|
|
775
|
+
}
|
|
776
|
+
function getManagedStyleDefinitionLayer(definition) {
|
|
777
|
+
return definition.layer || 'components';
|
|
778
|
+
}
|
|
779
|
+
function getManagedStyleDefinitionKey(definition) {
|
|
780
|
+
return `${definition.name}\0${getManagedStyleDefinitionLayer(definition)}`;
|
|
781
|
+
}
|
|
782
|
+
function splitManagedStyleDefinitionKey(key) {
|
|
783
|
+
const [name, layer] = key.split('\0');
|
|
784
|
+
return {
|
|
785
|
+
name,
|
|
786
|
+
layer: layer
|
|
787
|
+
};
|
|
788
|
+
}
|
|
789
|
+
function getManagedComposeDependencyName(className, names) {
|
|
790
|
+
const sortedNames = [
|
|
791
|
+
...names
|
|
792
|
+
].sort((a, b)=>b.length - a.length);
|
|
793
|
+
for (const name of sortedNames){
|
|
794
|
+
if (className === name) return name;
|
|
795
|
+
const next = className[name.length];
|
|
796
|
+
if (className.startsWith(name) && (next === ':' || next === '@' || next === '!')) {
|
|
797
|
+
return name;
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
function sortManagedStyleDefinitionKeys(groups, keysByName) {
|
|
802
|
+
const names = new Set(keysByName.keys());
|
|
803
|
+
const dependencies = new Map();
|
|
804
|
+
const dependencyDefinitions = new Map();
|
|
805
|
+
for (const [key, definitions] of groups){
|
|
806
|
+
const keyDependencies = new Set();
|
|
807
|
+
for (const definition of definitions){
|
|
808
|
+
if (definition.type !== 'compose') continue;
|
|
809
|
+
const dependencyName = getManagedComposeDependencyName(definition.className, names);
|
|
810
|
+
if (!dependencyName) continue;
|
|
811
|
+
for (const dependencyKey of keysByName.get(dependencyName) || []){
|
|
812
|
+
keyDependencies.add(dependencyKey);
|
|
813
|
+
dependencyDefinitions.set(`${key}\0${dependencyKey}`, definition);
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
dependencies.set(key, keyDependencies);
|
|
817
|
+
}
|
|
818
|
+
const sorted = [];
|
|
819
|
+
const seen = new Set();
|
|
820
|
+
const visiting = new Set();
|
|
821
|
+
const path = [];
|
|
822
|
+
function visit(key) {
|
|
823
|
+
if (seen.has(key)) return;
|
|
824
|
+
if (visiting.has(key)) {
|
|
825
|
+
const cycleKeys = [
|
|
826
|
+
...path.slice(path.indexOf(key)),
|
|
827
|
+
key
|
|
828
|
+
];
|
|
829
|
+
const cycle = cycleKeys.map((cycleKey)=>splitManagedStyleDefinitionKey(cycleKey).name).join(' -> ');
|
|
830
|
+
const related = cycleKeys.slice(0, -1).flatMap((cycleKey, index)=>{
|
|
831
|
+
const nextKey = cycleKeys[index + 1];
|
|
832
|
+
const definition = dependencyDefinitions.get(`${cycleKey}\0${nextKey}`);
|
|
833
|
+
const source = definition?.source || definition?.directiveSource;
|
|
834
|
+
return source ? [
|
|
835
|
+
{
|
|
836
|
+
message: `${splitManagedStyleDefinitionKey(cycleKey).name} composes ${definition.className}`,
|
|
837
|
+
source
|
|
838
|
+
}
|
|
839
|
+
] : [];
|
|
840
|
+
});
|
|
841
|
+
throw new CSSDirectiveError('circular-compose-dependency', `Circular @compose dependency detected: ${cycle}`, related[0]?.source, related);
|
|
842
|
+
}
|
|
843
|
+
visiting.add(key);
|
|
844
|
+
path.push(key);
|
|
845
|
+
for (const dependency of dependencies.get(key) || []){
|
|
846
|
+
visit(dependency);
|
|
847
|
+
}
|
|
848
|
+
path.pop();
|
|
849
|
+
visiting.delete(key);
|
|
850
|
+
seen.add(key);
|
|
851
|
+
sorted.push(key);
|
|
852
|
+
}
|
|
853
|
+
for (const key of groups.keys()){
|
|
854
|
+
visit(key);
|
|
855
|
+
}
|
|
856
|
+
return sorted;
|
|
857
|
+
}
|
|
858
|
+
function renderStyleDefinitions(definitions) {
|
|
859
|
+
return definitions.map((definition)=>{
|
|
860
|
+
const body = Object.entries(definition.declarations).map(([propertyName, value])=>`${propertyName}:${value}`).join(';');
|
|
861
|
+
return wrapAtRules(`${definition.selector}{${body}}`, definition.atRules);
|
|
862
|
+
}).join('');
|
|
863
|
+
}
|
|
864
|
+
function getStaticUtilityDefinition(input, name, layer) {
|
|
865
|
+
input.utilities ??= [];
|
|
866
|
+
const existing = input.utilities.find((utility)=>utility.name === name && (utility.layer || 'utilities') === layer);
|
|
867
|
+
if (existing) {
|
|
868
|
+
existing.type = 'static';
|
|
869
|
+
existing.layer = layer;
|
|
870
|
+
return existing;
|
|
871
|
+
}
|
|
872
|
+
const utility = {
|
|
873
|
+
name,
|
|
874
|
+
type: 'static',
|
|
875
|
+
layer
|
|
876
|
+
};
|
|
877
|
+
input.utilities.push(utility);
|
|
878
|
+
return utility;
|
|
879
|
+
}
|
|
880
|
+
function pushStaticUtilityStyleRule(definition, styleDefinition) {
|
|
881
|
+
const rule = {
|
|
882
|
+
declarations: styleDefinition.declarations,
|
|
883
|
+
...styleDefinition.selector !== '&' ? {
|
|
884
|
+
selector: styleDefinition.selector
|
|
885
|
+
} : {},
|
|
886
|
+
...styleDefinition.atRules?.length ? {
|
|
887
|
+
atRules: styleDefinition.atRules
|
|
888
|
+
} : {}
|
|
889
|
+
};
|
|
890
|
+
if (!definition.declarations && !definition.rules?.length && !rule.selector && !rule.atRules?.length) {
|
|
891
|
+
definition.declarations = rule.declarations;
|
|
892
|
+
return;
|
|
893
|
+
}
|
|
894
|
+
ensureUtilityRules(definition);
|
|
895
|
+
definition.rules ??= [];
|
|
896
|
+
definition.rules.push(rule);
|
|
897
|
+
}
|
|
898
|
+
function finalizeStyleDefinitions(input, styleDefinitions, css, options) {
|
|
899
|
+
if (!styleDefinitions?.length) return '';
|
|
900
|
+
const managedGroups = new Map();
|
|
901
|
+
const keysByName = new Map();
|
|
902
|
+
const nativeDefinitions = [];
|
|
903
|
+
for (const definition of styleDefinitions){
|
|
904
|
+
if (!isManagedStyleDefinition(definition)) {
|
|
905
|
+
nativeDefinitions.push(definition);
|
|
906
|
+
continue;
|
|
907
|
+
}
|
|
908
|
+
const key = getManagedStyleDefinitionKey(definition);
|
|
909
|
+
const group = managedGroups.get(key);
|
|
910
|
+
if (group) {
|
|
911
|
+
group.push(definition);
|
|
912
|
+
} else {
|
|
913
|
+
managedGroups.set(key, [
|
|
914
|
+
definition
|
|
915
|
+
]);
|
|
916
|
+
}
|
|
917
|
+
const nameKeys = keysByName.get(definition.name);
|
|
918
|
+
if (nameKeys) {
|
|
919
|
+
nameKeys.add(key);
|
|
920
|
+
} else {
|
|
921
|
+
keysByName.set(definition.name, new Set([
|
|
922
|
+
key
|
|
923
|
+
]));
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
for (const key of sortManagedStyleDefinitionKeys(managedGroups, keysByName)){
|
|
927
|
+
const definitions = managedGroups.get(key);
|
|
928
|
+
if (!definitions) continue;
|
|
929
|
+
const { name, layer } = splitManagedStyleDefinitionKey(key);
|
|
930
|
+
const mergedDefinitions = createMergedStyleDefinitions(definitions, css, layer);
|
|
931
|
+
for (const definition of mergedDefinitions){
|
|
932
|
+
const utilityDefinition = getStaticUtilityDefinition(input, name, layer);
|
|
933
|
+
pushStaticUtilityStyleRule(utilityDefinition, definition);
|
|
934
|
+
}
|
|
935
|
+
css.refresh(createMasterCSSManifest(input, {
|
|
936
|
+
baseManifest: getResolutionManifest(options)
|
|
937
|
+
}));
|
|
938
|
+
}
|
|
939
|
+
if (!nativeDefinitions.length) return '';
|
|
940
|
+
return renderStyleDefinitions(createMergedStyleDefinitions(nativeDefinitions, css));
|
|
941
|
+
}
|
|
942
|
+
function lowerCSSDirectives(input, options = {}) {
|
|
943
|
+
const directiveInput = normalizeDirectiveInput(input, options);
|
|
944
|
+
const resolveVariableName = createVariableNameResolver(directiveInput, {
|
|
945
|
+
baseManifest: getResolutionManifest(options)
|
|
946
|
+
});
|
|
947
|
+
const warnings = isCSSDirectiveResult(input) ? [
|
|
948
|
+
...input.warnings
|
|
949
|
+
] : [];
|
|
950
|
+
validateTokenConflicts(directiveInput, resolveVariableName);
|
|
951
|
+
warnUnsupportedMediaModes(directiveInput, options, warnings);
|
|
952
|
+
const css = createDirectiveCSS(directiveInput, options);
|
|
953
|
+
finalizeUtilityDefinitions(directiveInput, css);
|
|
954
|
+
css.refresh(createMasterCSSManifest(directiveInput, {
|
|
955
|
+
baseManifest: getResolutionManifest(options)
|
|
956
|
+
}));
|
|
957
|
+
const generatedCSS = finalizeStyleDefinitions(directiveInput, getStyleDefinitions(input), css, options);
|
|
958
|
+
const manifest = createMasterCSSManifest(directiveInput, {
|
|
959
|
+
baseManifest: options.baseManifest
|
|
960
|
+
});
|
|
961
|
+
return {
|
|
962
|
+
input: directiveInput,
|
|
963
|
+
manifest,
|
|
964
|
+
warnings,
|
|
965
|
+
generatedCSS
|
|
966
|
+
};
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
export { lowerCSSDirectives as default };
|