@tenphi/tasty 0.0.0-snapshot.b3fbcbb → 0.0.0-snapshot.bae20d4
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 +130 -7
- package/dist/chunks/cacheKey.js +16 -8
- package/dist/chunks/cacheKey.js.map +1 -1
- package/dist/chunks/definitions.js +1 -2
- package/dist/chunks/definitions.js.map +1 -1
- package/dist/chunks/renderChunk.js +31 -32
- package/dist/chunks/renderChunk.js.map +1 -1
- package/dist/config.d.ts +45 -10
- package/dist/config.js +75 -13
- package/dist/config.js.map +1 -1
- package/dist/core/index.d.ts +9 -8
- package/dist/core/index.js +7 -6
- package/dist/hooks/useGlobalStyles.d.ts +3 -0
- package/dist/hooks/useGlobalStyles.js +28 -1
- package/dist/hooks/useGlobalStyles.js.map +1 -1
- package/dist/hooks/useKeyframes.js +18 -3
- package/dist/hooks/useKeyframes.js.map +1 -1
- package/dist/hooks/useProperty.js +36 -13
- package/dist/hooks/useProperty.js.map +1 -1
- package/dist/hooks/useRawCSS.js +13 -1
- package/dist/hooks/useRawCSS.js.map +1 -1
- package/dist/hooks/useStyles.d.ts +5 -0
- package/dist/hooks/useStyles.js +87 -7
- package/dist/hooks/useStyles.js.map +1 -1
- package/dist/index.d.ts +9 -8
- package/dist/index.js +7 -6
- package/dist/injector/index.d.ts +9 -1
- package/dist/injector/index.js +9 -1
- package/dist/injector/index.js.map +1 -1
- package/dist/injector/injector.d.ts +9 -0
- package/dist/injector/injector.js +21 -17
- package/dist/injector/injector.js.map +1 -1
- package/dist/injector/sheet-manager.d.ts +1 -0
- package/dist/injector/sheet-manager.js +1 -0
- package/dist/injector/sheet-manager.js.map +1 -1
- package/dist/parser/classify.js +2 -1
- package/dist/parser/classify.js.map +1 -1
- package/dist/parser/parser.js +1 -1
- package/dist/pipeline/index.d.ts +1 -1
- package/dist/pipeline/index.js +24 -14
- package/dist/pipeline/index.js.map +1 -1
- package/dist/pipeline/materialize.js +380 -119
- package/dist/pipeline/materialize.js.map +1 -1
- package/dist/pipeline/parseStateKey.d.ts +1 -1
- package/dist/pipeline/parseStateKey.js +20 -11
- package/dist/pipeline/parseStateKey.js.map +1 -1
- package/dist/plugins/okhsl-plugin.js +2 -275
- package/dist/plugins/okhsl-plugin.js.map +1 -1
- package/dist/plugins/types.d.ts +9 -2
- package/dist/properties/index.js +14 -28
- package/dist/properties/index.js.map +1 -1
- package/dist/properties/property-type-resolver.js +12 -0
- package/dist/properties/property-type-resolver.js.map +1 -1
- package/dist/ssr/astro.d.ts +29 -0
- package/dist/ssr/astro.js +65 -0
- package/dist/ssr/astro.js.map +1 -0
- package/dist/ssr/async-storage.d.ts +17 -0
- package/dist/ssr/async-storage.js +35 -0
- package/dist/ssr/async-storage.js.map +1 -0
- package/dist/ssr/collect-auto-properties.js +40 -0
- package/dist/ssr/collect-auto-properties.js.map +1 -0
- package/dist/ssr/collector.d.ts +85 -0
- package/dist/ssr/collector.js +183 -0
- package/dist/ssr/collector.js.map +1 -0
- package/dist/ssr/context.d.ts +8 -0
- package/dist/ssr/context.js +14 -0
- package/dist/ssr/context.js.map +1 -0
- package/dist/ssr/format-global-rules.js +22 -0
- package/dist/ssr/format-global-rules.js.map +1 -0
- package/dist/ssr/format-keyframes.js +70 -0
- package/dist/ssr/format-keyframes.js.map +1 -0
- package/dist/ssr/format-property.js +50 -0
- package/dist/ssr/format-property.js.map +1 -0
- package/dist/ssr/format-rules.js +70 -0
- package/dist/ssr/format-rules.js.map +1 -0
- package/dist/ssr/hydrate.d.ts +22 -0
- package/dist/ssr/hydrate.js +50 -0
- package/dist/ssr/hydrate.js.map +1 -0
- package/dist/ssr/index.d.ts +5 -0
- package/dist/ssr/index.js +12 -0
- package/dist/ssr/index.js.map +1 -0
- package/dist/ssr/next.d.ts +45 -0
- package/dist/ssr/next.js +71 -0
- package/dist/ssr/next.js.map +1 -0
- package/dist/ssr/ssr-collector-ref.js +12 -0
- package/dist/ssr/ssr-collector-ref.js.map +1 -0
- package/dist/states/index.js +10 -257
- package/dist/states/index.js.map +1 -1
- package/dist/styles/color.js +9 -5
- package/dist/styles/color.js.map +1 -1
- package/dist/styles/createStyle.js +24 -21
- package/dist/styles/createStyle.js.map +1 -1
- package/dist/styles/index.js +1 -1
- package/dist/styles/predefined.d.ts +0 -2
- package/dist/styles/predefined.js +0 -3
- package/dist/styles/predefined.js.map +1 -1
- package/dist/styles/preset.js +1 -1
- package/dist/styles/preset.js.map +1 -1
- package/dist/styles/scrollbar.d.ts +9 -5
- package/dist/styles/scrollbar.js +25 -89
- package/dist/styles/scrollbar.js.map +1 -1
- package/dist/styles/transition.js +1 -1
- package/dist/styles/transition.js.map +1 -1
- package/dist/styles/types.d.ts +24 -14
- package/dist/tasty.d.ts +20 -21
- package/dist/tasty.js +24 -11
- package/dist/tasty.js.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/utils/cache-wrapper.js +4 -8
- package/dist/utils/cache-wrapper.js.map +1 -1
- package/dist/utils/color-math.d.ts +45 -0
- package/dist/utils/color-math.js +749 -0
- package/dist/utils/color-math.js.map +1 -0
- package/dist/utils/color-space.d.ts +5 -0
- package/dist/utils/color-space.js +228 -0
- package/dist/utils/color-space.js.map +1 -0
- package/dist/utils/colors.js +3 -1
- package/dist/utils/colors.js.map +1 -1
- package/dist/utils/has-keys.js +13 -0
- package/dist/utils/has-keys.js.map +1 -0
- package/dist/utils/mod-attrs.js +1 -1
- package/dist/utils/process-tokens.d.ts +3 -13
- package/dist/utils/process-tokens.js +17 -97
- package/dist/utils/process-tokens.js.map +1 -1
- package/dist/utils/selector-transform.js +32 -0
- package/dist/utils/selector-transform.js.map +1 -0
- package/dist/utils/styles.d.ts +2 -79
- package/dist/utils/styles.js +26 -554
- package/dist/utils/styles.js.map +1 -1
- package/dist/utils/typography.d.ts +24 -13
- package/dist/utils/typography.js +6 -16
- package/dist/utils/typography.js.map +1 -1
- package/dist/zero/babel.d.ts +48 -6
- package/dist/zero/babel.js +63 -5
- package/dist/zero/babel.js.map +1 -1
- package/dist/zero/next.d.ts +44 -30
- package/dist/zero/next.js +102 -38
- package/dist/zero/next.js.map +1 -1
- package/docs/PIPELINE.md +519 -0
- package/docs/adoption.md +286 -0
- package/docs/comparison.md +413 -0
- package/docs/configuration.md +263 -0
- package/docs/debug.md +505 -0
- package/docs/design-system.md +401 -0
- package/docs/dsl.md +540 -0
- package/docs/getting-started.md +201 -0
- package/docs/injector.md +528 -0
- package/docs/methodology.md +501 -0
- package/docs/runtime.md +291 -0
- package/docs/ssr.md +382 -0
- package/docs/styles.md +574 -0
- package/docs/tasty-static.md +420 -0
- package/package.json +50 -30
- package/dist/styles/styledScrollbar.d.ts +0 -47
- package/dist/styles/styledScrollbar.js +0 -38
- package/dist/styles/styledScrollbar.js.map +0 -1
- package/dist/tokens/typography.d.ts +0 -19
- package/dist/tokens/typography.js +0 -237
- package/dist/tokens/typography.js.map +0 -1
- package/dist/utils/hsl-to-rgb.js +0 -38
- package/dist/utils/hsl-to-rgb.js.map +0 -1
- package/dist/utils/okhsl-to-rgb.js +0 -296
- package/dist/utils/okhsl-to-rgb.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Lru } from "../parser/lru.js";
|
|
2
|
-
import { getConditionUniqueId
|
|
2
|
+
import { getConditionUniqueId } from "./conditions.js";
|
|
3
3
|
|
|
4
4
|
//#region src/pipeline/materialize.ts
|
|
5
5
|
/**
|
|
@@ -24,11 +24,12 @@ function emptyVariant() {
|
|
|
24
24
|
return {
|
|
25
25
|
modifierConditions: [],
|
|
26
26
|
pseudoConditions: [],
|
|
27
|
-
|
|
27
|
+
selectorGroups: [],
|
|
28
|
+
ownGroups: [],
|
|
28
29
|
mediaConditions: [],
|
|
29
30
|
containerConditions: [],
|
|
30
31
|
supportsConditions: [],
|
|
31
|
-
|
|
32
|
+
rootGroups: [],
|
|
32
33
|
parentGroups: [],
|
|
33
34
|
startingStyle: false
|
|
34
35
|
};
|
|
@@ -63,9 +64,9 @@ function stateToCSS(state) {
|
|
|
63
64
|
}),
|
|
64
65
|
isImpossible: false
|
|
65
66
|
};
|
|
66
|
-
case "root": return innerConditionToVariants(state.innerCondition, state.negated ?? false, "
|
|
67
|
+
case "root": return innerConditionToVariants(state.innerCondition, state.negated ?? false, "rootGroups");
|
|
67
68
|
case "parent": return parentConditionToVariants(state.innerCondition, state.negated ?? false, state.direct);
|
|
68
|
-
case "own": return innerConditionToVariants(state.innerCondition, state.negated ?? false, "
|
|
69
|
+
case "own": return innerConditionToVariants(state.innerCondition, state.negated ?? false, "ownGroups");
|
|
69
70
|
case "modifier": {
|
|
70
71
|
const v = emptyVariant();
|
|
71
72
|
v.modifierConditions.push(modifierToParsed(state));
|
|
@@ -141,14 +142,31 @@ function pseudoToParsed(state) {
|
|
|
141
142
|
};
|
|
142
143
|
}
|
|
143
144
|
/**
|
|
144
|
-
* Convert parsed pseudo to CSS selector string (for final output)
|
|
145
|
+
* Convert parsed pseudo to CSS selector string (for final output).
|
|
146
|
+
*
|
|
147
|
+
* :not() is normalized to negated :is() at parse time, so pseudo.pseudo
|
|
148
|
+
* never starts with ':not(' here. When negated:
|
|
149
|
+
* - :is(X) → :not(X) (unwrap :is)
|
|
150
|
+
* - :where(X) → :not(X) (unwrap :where)
|
|
151
|
+
* - :has(X) → :not(:has(X))
|
|
152
|
+
* - other → :not(other)
|
|
153
|
+
*
|
|
154
|
+
* When not negated, single-argument :is()/:where() is unwrapped when the
|
|
155
|
+
* inner content is a simple compound selector that can safely append to
|
|
156
|
+
* the base selector (this happens after double-negation of :not()).
|
|
145
157
|
*/
|
|
146
158
|
function pseudoToCSS(pseudo) {
|
|
159
|
+
const p = pseudo.pseudo;
|
|
147
160
|
if (pseudo.negated) {
|
|
148
|
-
if (
|
|
149
|
-
return `:not(${
|
|
161
|
+
if (p.startsWith(":is(") || p.startsWith(":where(")) return `:not(${p.slice(p.indexOf("(") + 1, -1)})`;
|
|
162
|
+
return `:not(${p})`;
|
|
150
163
|
}
|
|
151
|
-
|
|
164
|
+
if ((p.startsWith(":is(") || p.startsWith(":where(")) && !p.includes(",")) {
|
|
165
|
+
const inner = p.slice(p.indexOf("(") + 1, -1);
|
|
166
|
+
const ch = inner[0];
|
|
167
|
+
if ((ch === ":" || ch === "." || ch === "[" || ch === "#") && !/\s/.test(inner)) return inner;
|
|
168
|
+
}
|
|
169
|
+
return p;
|
|
152
170
|
}
|
|
153
171
|
/**
|
|
154
172
|
* Convert media condition to parsed structure(s)
|
|
@@ -247,40 +265,50 @@ function collectSelectorConditions(variant) {
|
|
|
247
265
|
return [...variant.modifierConditions, ...variant.pseudoConditions];
|
|
248
266
|
}
|
|
249
267
|
/**
|
|
250
|
-
* Convert an inner condition tree into
|
|
251
|
-
*
|
|
268
|
+
* Convert an inner condition tree into a single SelectorVariant with
|
|
269
|
+
* one SelectorGroup whose branches represent the inner OR alternatives.
|
|
252
270
|
* Shared by @root() and @own().
|
|
271
|
+
*
|
|
272
|
+
* Both positive and negated cases produce one variant with one group.
|
|
273
|
+
* Negation simply sets the `negated` flag, which swaps :is() for :not()
|
|
274
|
+
* in the final CSS output — no De Morgan transformation is needed.
|
|
275
|
+
*
|
|
276
|
+
* This mirrors parentConditionToVariants: OR branches are kept inside
|
|
277
|
+
* a single group and rendered as comma-separated arguments in
|
|
278
|
+
* :is()/:not(), e.g. :root:is([a], [b]) or [el]:not([a], [b]).
|
|
253
279
|
*/
|
|
254
280
|
function innerConditionToVariants(innerCondition, negated, target) {
|
|
255
|
-
const innerCSS = conditionToCSS(
|
|
281
|
+
const innerCSS = conditionToCSS(innerCondition);
|
|
256
282
|
if (innerCSS.isImpossible || innerCSS.variants.length === 0) return {
|
|
257
283
|
variants: [],
|
|
258
284
|
isImpossible: true
|
|
259
285
|
};
|
|
260
|
-
const
|
|
286
|
+
const branches = [];
|
|
261
287
|
for (const innerVariant of innerCSS.variants) {
|
|
262
288
|
const conditions = collectSelectorConditions(innerVariant);
|
|
263
|
-
if (conditions.length > 0)
|
|
264
|
-
const v = emptyVariant();
|
|
265
|
-
v[target].push(...conditions);
|
|
266
|
-
variants.push(v);
|
|
267
|
-
}
|
|
289
|
+
if (conditions.length > 0) branches.push(conditions);
|
|
268
290
|
}
|
|
269
|
-
if (
|
|
291
|
+
if (branches.length === 0) return {
|
|
270
292
|
variants: [emptyVariant()],
|
|
271
293
|
isImpossible: false
|
|
272
294
|
};
|
|
295
|
+
const v = emptyVariant();
|
|
296
|
+
v[target].push({
|
|
297
|
+
branches,
|
|
298
|
+
negated
|
|
299
|
+
});
|
|
273
300
|
return {
|
|
274
|
-
variants,
|
|
301
|
+
variants: [v],
|
|
275
302
|
isImpossible: false
|
|
276
303
|
};
|
|
277
304
|
}
|
|
278
305
|
/**
|
|
279
|
-
* Convert a @parent() inner condition into
|
|
306
|
+
* Convert a @parent() inner condition into a single SelectorVariant with
|
|
307
|
+
* one ParentGroup whose branches represent the inner OR alternatives.
|
|
280
308
|
*
|
|
281
|
-
*
|
|
282
|
-
*
|
|
283
|
-
*
|
|
309
|
+
* Both positive and negated cases produce one variant with one group.
|
|
310
|
+
* Negation simply sets the `negated` flag, which swaps :is() for :not()
|
|
311
|
+
* in the final CSS output — no structural transformation is needed.
|
|
284
312
|
*/
|
|
285
313
|
function parentConditionToVariants(innerCondition, negated, direct) {
|
|
286
314
|
const innerCSS = conditionToCSS(innerCondition);
|
|
@@ -288,68 +316,178 @@ function parentConditionToVariants(innerCondition, negated, direct) {
|
|
|
288
316
|
variants: [],
|
|
289
317
|
isImpossible: true
|
|
290
318
|
};
|
|
291
|
-
|
|
292
|
-
const v = emptyVariant();
|
|
293
|
-
for (const innerVariant of innerCSS.variants) {
|
|
294
|
-
const conditions = collectSelectorConditions(innerVariant);
|
|
295
|
-
if (conditions.length > 0) v.parentGroups.push({
|
|
296
|
-
conditions,
|
|
297
|
-
direct,
|
|
298
|
-
negated: true
|
|
299
|
-
});
|
|
300
|
-
}
|
|
301
|
-
if (v.parentGroups.length === 0) return {
|
|
302
|
-
variants: [emptyVariant()],
|
|
303
|
-
isImpossible: false
|
|
304
|
-
};
|
|
305
|
-
return {
|
|
306
|
-
variants: [v],
|
|
307
|
-
isImpossible: false
|
|
308
|
-
};
|
|
309
|
-
}
|
|
310
|
-
const variants = [];
|
|
319
|
+
const branches = [];
|
|
311
320
|
for (const innerVariant of innerCSS.variants) {
|
|
312
321
|
const conditions = collectSelectorConditions(innerVariant);
|
|
313
|
-
if (conditions.length > 0)
|
|
314
|
-
const v = emptyVariant();
|
|
315
|
-
v.parentGroups.push({
|
|
316
|
-
conditions,
|
|
317
|
-
direct,
|
|
318
|
-
negated: false
|
|
319
|
-
});
|
|
320
|
-
variants.push(v);
|
|
321
|
-
}
|
|
322
|
+
if (conditions.length > 0) branches.push(conditions);
|
|
322
323
|
}
|
|
323
|
-
if (
|
|
324
|
+
if (branches.length === 0) return {
|
|
324
325
|
variants: [emptyVariant()],
|
|
325
326
|
isImpossible: false
|
|
326
327
|
};
|
|
328
|
+
const v = emptyVariant();
|
|
329
|
+
v.parentGroups.push({
|
|
330
|
+
branches,
|
|
331
|
+
direct,
|
|
332
|
+
negated
|
|
333
|
+
});
|
|
327
334
|
return {
|
|
328
|
-
variants,
|
|
335
|
+
variants: [v],
|
|
329
336
|
isImpossible: false
|
|
330
337
|
};
|
|
331
338
|
}
|
|
332
339
|
/**
|
|
333
|
-
*
|
|
340
|
+
* Sort key for canonical condition output within selectors.
|
|
341
|
+
*
|
|
342
|
+
* Priority order:
|
|
343
|
+
* 0: Boolean attribute selectors ([data-hovered])
|
|
344
|
+
* 1: Value attribute selectors ([data-size="small"])
|
|
345
|
+
* 2: Negated boolean attributes (:not([data-disabled]))
|
|
346
|
+
* 3: Negated value attributes (:not([data-size="small"]))
|
|
347
|
+
* 4: Pseudo-classes (:hover, :focus)
|
|
348
|
+
* 5: Negated pseudo-classes (:not(:disabled))
|
|
349
|
+
*
|
|
350
|
+
* Secondary sort: alphabetical by attribute name / pseudo string.
|
|
351
|
+
*/
|
|
352
|
+
function conditionSortKey(cond) {
|
|
353
|
+
if ("attribute" in cond) {
|
|
354
|
+
const hasValue = cond.value !== void 0 ? 1 : 0;
|
|
355
|
+
return `${(cond.negated ? 2 : 0) + hasValue}|${cond.attribute}|${cond.value ?? ""}`;
|
|
356
|
+
}
|
|
357
|
+
return `${cond.negated ? 5 : 4}|${cond.pseudo}`;
|
|
358
|
+
}
|
|
359
|
+
function sortConditions(conditions) {
|
|
360
|
+
return conditions.toSorted((a, b) => conditionSortKey(a).localeCompare(conditionSortKey(b)));
|
|
361
|
+
}
|
|
362
|
+
function branchToCSS(branch) {
|
|
363
|
+
let parts = "";
|
|
364
|
+
for (const cond of sortConditions(branch)) parts += selectorConditionToCSS(cond);
|
|
365
|
+
return parts;
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Wrap serialized selector arguments in :is() or :not().
|
|
369
|
+
* Arguments are sorted for canonical output.
|
|
370
|
+
*/
|
|
371
|
+
function wrapInIsOrNot(args, negated) {
|
|
372
|
+
return `${negated ? ":not" : ":is"}(${args.sort().join(", ")})`;
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Convert a selector group to a CSS selector fragment.
|
|
376
|
+
*
|
|
377
|
+
* Single-branch groups are unwrapped (no :is() wrapper).
|
|
378
|
+
* Multi-branch groups use :is() or :not().
|
|
379
|
+
* Negation swaps :is() for :not().
|
|
380
|
+
*/
|
|
381
|
+
function selectorGroupToCSS(group) {
|
|
382
|
+
if (group.branches.length === 0) return "";
|
|
383
|
+
if (group.branches.length === 1) {
|
|
384
|
+
const parts = branchToCSS(group.branches[0]);
|
|
385
|
+
if (group.negated) return `:not(${parts})`;
|
|
386
|
+
return parts;
|
|
387
|
+
}
|
|
388
|
+
return wrapInIsOrNot(group.branches.map(branchToCSS), group.negated);
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* Collect facts about modifier conditions for subsumption analysis.
|
|
392
|
+
* Tracks negated boolean attrs (:not([attr])) and positive exact values ([attr="X"]).
|
|
393
|
+
*/
|
|
394
|
+
function collectSubsumptionFacts(modifiers) {
|
|
395
|
+
const negatedBooleanAttrs = /* @__PURE__ */ new Set();
|
|
396
|
+
const positiveExactValuesByAttr = /* @__PURE__ */ new Map();
|
|
397
|
+
for (const mod of modifiers) {
|
|
398
|
+
if (mod.negated && mod.value === void 0) negatedBooleanAttrs.add(mod.attribute);
|
|
399
|
+
if (!mod.negated && mod.value !== void 0 && (mod.operator ?? "=") === "=") {
|
|
400
|
+
let vals = positiveExactValuesByAttr.get(mod.attribute);
|
|
401
|
+
if (!vals) {
|
|
402
|
+
vals = /* @__PURE__ */ new Set();
|
|
403
|
+
positiveExactValuesByAttr.set(mod.attribute, vals);
|
|
404
|
+
}
|
|
405
|
+
vals.add(mod.value);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
return {
|
|
409
|
+
negatedBooleanAttrs,
|
|
410
|
+
positiveExactValuesByAttr
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
/**
|
|
414
|
+
* Check if a negated-value modifier is subsumed by stronger facts:
|
|
415
|
+
* - :not([attr]) subsumes :not([attr="val"])
|
|
416
|
+
* - [attr="X"] implies :not([attr="Y"]) is redundant (single exact value)
|
|
417
|
+
*
|
|
418
|
+
* Only applies to exact-match (=) operators; substring operators don't
|
|
419
|
+
* imply exclusivity between values.
|
|
420
|
+
*/
|
|
421
|
+
function isSubsumedNegatedModifier(mod, facts) {
|
|
422
|
+
if (!mod.negated || mod.value === void 0) return false;
|
|
423
|
+
if (facts.negatedBooleanAttrs.has(mod.attribute)) return true;
|
|
424
|
+
if ((mod.operator ?? "=") === "=") {
|
|
425
|
+
const posVals = facts.positiveExactValuesByAttr.get(mod.attribute);
|
|
426
|
+
if (posVals && posVals.size === 1 && !posVals.has(mod.value)) return true;
|
|
427
|
+
}
|
|
428
|
+
return false;
|
|
429
|
+
}
|
|
430
|
+
/**
|
|
431
|
+
* Remove redundant single-condition groups that are subsumed by stronger
|
|
432
|
+
* groups on the same attribute. O(n) — only inspects single-branch,
|
|
433
|
+
* single-condition groups.
|
|
434
|
+
*/
|
|
435
|
+
function optimizeGroups(groups) {
|
|
436
|
+
if (groups.length <= 1) return groups;
|
|
437
|
+
const seen = /* @__PURE__ */ new Set();
|
|
438
|
+
const result = [];
|
|
439
|
+
for (const g of groups) {
|
|
440
|
+
const key = getSelectorGroupKey(g);
|
|
441
|
+
if (!seen.has(key)) {
|
|
442
|
+
seen.add(key);
|
|
443
|
+
result.push(g);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
if (result.length <= 1) return result;
|
|
447
|
+
const effectiveModifiers = [];
|
|
448
|
+
for (const g of result) {
|
|
449
|
+
if (g.branches.length !== 1 || g.branches[0].length !== 1) continue;
|
|
450
|
+
const cond = g.branches[0][0];
|
|
451
|
+
if (!("attribute" in cond)) continue;
|
|
452
|
+
effectiveModifiers.push({
|
|
453
|
+
...cond,
|
|
454
|
+
negated: g.negated !== cond.negated
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
const facts = collectSubsumptionFacts(effectiveModifiers);
|
|
458
|
+
if (facts.negatedBooleanAttrs.size === 0 && facts.positiveExactValuesByAttr.size === 0) return result;
|
|
459
|
+
return result.filter((g) => {
|
|
460
|
+
if (g.branches.length !== 1 || g.branches[0].length !== 1) return true;
|
|
461
|
+
const cond = g.branches[0][0];
|
|
462
|
+
if (!("attribute" in cond) || !g.negated || cond.negated || cond.value === void 0) return true;
|
|
463
|
+
return !isSubsumedNegatedModifier({
|
|
464
|
+
...cond,
|
|
465
|
+
negated: true
|
|
466
|
+
}, facts);
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
/**
|
|
470
|
+
* Convert root groups to CSS selector prefix (for final output)
|
|
334
471
|
*/
|
|
335
|
-
function
|
|
336
|
-
if (
|
|
472
|
+
function rootGroupsToCSS(groups) {
|
|
473
|
+
if (groups.length === 0) return void 0;
|
|
474
|
+
const optimized = optimizeGroups(groups);
|
|
475
|
+
if (optimized.length === 0) return void 0;
|
|
337
476
|
let prefix = ":root";
|
|
338
|
-
for (const
|
|
477
|
+
for (const group of optimized) prefix += selectorGroupToCSS(group);
|
|
339
478
|
return prefix;
|
|
340
479
|
}
|
|
341
480
|
/**
|
|
342
481
|
* Convert parent groups to CSS selector fragments (for final output).
|
|
343
|
-
* Each group produces its own :is() wrapper
|
|
482
|
+
* Each group produces its own :is()/:not() wrapper with a combinator
|
|
483
|
+
* suffix (` *` or ` > *`) appended to each branch.
|
|
344
484
|
*/
|
|
345
485
|
function parentGroupsToCSS(groups) {
|
|
346
486
|
let result = "";
|
|
347
487
|
for (const group of groups) {
|
|
348
488
|
const combinator = group.direct ? " > *" : " *";
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
const wrapper = group.negated ? ":not" : ":is";
|
|
352
|
-
result += `${wrapper}(${parts}${combinator})`;
|
|
489
|
+
const args = group.branches.map((branch) => branchToCSS(branch) + combinator);
|
|
490
|
+
result += wrapInIsOrNot(args, group.negated);
|
|
353
491
|
}
|
|
354
492
|
return result;
|
|
355
493
|
}
|
|
@@ -385,7 +523,7 @@ function getSelectorConditionKey(cond) {
|
|
|
385
523
|
*/
|
|
386
524
|
function dedupeSelectorConditions(conditions) {
|
|
387
525
|
const seen = /* @__PURE__ */ new Set();
|
|
388
|
-
|
|
526
|
+
const result = [];
|
|
389
527
|
for (const c of conditions) {
|
|
390
528
|
const key = getSelectorConditionKey(c);
|
|
391
529
|
if (!seen.has(key)) {
|
|
@@ -393,30 +531,12 @@ function dedupeSelectorConditions(conditions) {
|
|
|
393
531
|
result.push(c);
|
|
394
532
|
}
|
|
395
533
|
}
|
|
396
|
-
const
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
if (!("attribute" in c))
|
|
400
|
-
|
|
401
|
-
const op = c.operator ?? "=";
|
|
402
|
-
if (!c.negated && c.value !== void 0 && op === "=") {
|
|
403
|
-
let values = positiveExactValuesByAttr.get(c.attribute);
|
|
404
|
-
if (!values) {
|
|
405
|
-
values = /* @__PURE__ */ new Set();
|
|
406
|
-
positiveExactValuesByAttr.set(c.attribute, values);
|
|
407
|
-
}
|
|
408
|
-
values.add(c.value);
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
result = result.filter((c) => {
|
|
412
|
-
if (!("attribute" in c) || !c.negated || c.value === void 0) return true;
|
|
413
|
-
if (negatedBooleanAttrs.has(c.attribute)) return false;
|
|
414
|
-
if ((c.operator ?? "=") !== "=") return true;
|
|
415
|
-
const positiveValues = positiveExactValuesByAttr.get(c.attribute);
|
|
416
|
-
if (positiveValues !== void 0 && positiveValues.size === 1 && !positiveValues.has(c.value)) return false;
|
|
417
|
-
return true;
|
|
534
|
+
const facts = collectSubsumptionFacts(result.filter((c) => "attribute" in c));
|
|
535
|
+
if (facts.negatedBooleanAttrs.size === 0 && facts.positiveExactValuesByAttr.size === 0) return result;
|
|
536
|
+
return result.filter((c) => {
|
|
537
|
+
if (!("attribute" in c)) return true;
|
|
538
|
+
return !isSubsumedNegatedModifier(c, facts);
|
|
418
539
|
});
|
|
419
|
-
return result;
|
|
420
540
|
}
|
|
421
541
|
/**
|
|
422
542
|
* Check for modifier contradiction: same attribute with opposite negation
|
|
@@ -459,10 +579,32 @@ function hasSelectorConditionContradiction(conditions) {
|
|
|
459
579
|
* with opposite negation. E.g. :not([data-hovered] *) and :is([data-hovered] *)
|
|
460
580
|
* in the same variant is impossible.
|
|
461
581
|
*/
|
|
582
|
+
function getBranchesKey(branches) {
|
|
583
|
+
if (branches.length === 1) {
|
|
584
|
+
const b = branches[0];
|
|
585
|
+
if (b.length === 1) return getSelectorConditionKey(b[0]);
|
|
586
|
+
return b.map(getSelectorConditionKey).sort().join("+");
|
|
587
|
+
}
|
|
588
|
+
return branches.map((b) => b.map(getSelectorConditionKey).sort().join("+")).sort().join(",");
|
|
589
|
+
}
|
|
462
590
|
function hasParentGroupContradiction(groups) {
|
|
463
591
|
const byBaseKey = /* @__PURE__ */ new Map();
|
|
464
592
|
for (const g of groups) {
|
|
465
|
-
const baseKey = `${g.direct ? ">" : ""}(${g.
|
|
593
|
+
const baseKey = `${g.direct ? ">" : ""}(${getBranchesKey(g.branches)})`;
|
|
594
|
+
const existing = byBaseKey.get(baseKey);
|
|
595
|
+
if (existing !== void 0 && existing !== !g.negated) return true;
|
|
596
|
+
byBaseKey.set(baseKey, !g.negated);
|
|
597
|
+
}
|
|
598
|
+
return false;
|
|
599
|
+
}
|
|
600
|
+
/**
|
|
601
|
+
* Check for selector group contradiction: same branches with opposite negation.
|
|
602
|
+
* E.g. :is([data-a]) and :not([data-a]) in the same variant is impossible.
|
|
603
|
+
*/
|
|
604
|
+
function hasSelectorGroupContradiction(groups) {
|
|
605
|
+
const byBaseKey = /* @__PURE__ */ new Map();
|
|
606
|
+
for (const g of groups) {
|
|
607
|
+
const baseKey = getBranchesKey(g.branches);
|
|
466
608
|
const existing = byBaseKey.get(baseKey);
|
|
467
609
|
if (existing !== void 0 && existing !== !g.negated) return true;
|
|
468
610
|
byBaseKey.set(baseKey, !g.negated);
|
|
@@ -476,15 +618,17 @@ function hasParentGroupContradiction(groups) {
|
|
|
476
618
|
function mergeVariants(a, b) {
|
|
477
619
|
const mergedMedia = dedupeMediaConditions([...a.mediaConditions, ...b.mediaConditions]);
|
|
478
620
|
if (hasMediaContradiction(mergedMedia)) return null;
|
|
479
|
-
const
|
|
480
|
-
if (
|
|
621
|
+
const mergedRootGroups = optimizeGroups([...a.rootGroups, ...b.rootGroups]);
|
|
622
|
+
if (hasSelectorGroupContradiction(mergedRootGroups)) return null;
|
|
481
623
|
const mergedModifiers = dedupeSelectorConditions([...a.modifierConditions, ...b.modifierConditions]);
|
|
482
624
|
const mergedPseudos = dedupeSelectorConditions([...a.pseudoConditions, ...b.pseudoConditions]);
|
|
483
625
|
if (hasSelectorConditionContradiction([...mergedModifiers, ...mergedPseudos])) return null;
|
|
626
|
+
const mergedSelectorGroups = optimizeGroups([...a.selectorGroups, ...b.selectorGroups]);
|
|
627
|
+
if (hasSelectorGroupContradiction(mergedSelectorGroups)) return null;
|
|
484
628
|
const mergedParentGroups = [...a.parentGroups, ...b.parentGroups];
|
|
485
629
|
if (hasParentGroupContradiction(mergedParentGroups)) return null;
|
|
486
|
-
const
|
|
487
|
-
if (
|
|
630
|
+
const mergedOwnGroups = optimizeGroups([...a.ownGroups, ...b.ownGroups]);
|
|
631
|
+
if (hasSelectorGroupContradiction(mergedOwnGroups)) return null;
|
|
488
632
|
const mergedContainers = dedupeContainerConditions([...a.containerConditions, ...b.containerConditions]);
|
|
489
633
|
if (hasContainerStyleContradiction(mergedContainers)) return null;
|
|
490
634
|
const mergedSupports = dedupeSupportsConditions([...a.supportsConditions, ...b.supportsConditions]);
|
|
@@ -492,11 +636,12 @@ function mergeVariants(a, b) {
|
|
|
492
636
|
return {
|
|
493
637
|
modifierConditions: mergedModifiers,
|
|
494
638
|
pseudoConditions: mergedPseudos,
|
|
495
|
-
|
|
639
|
+
selectorGroups: mergedSelectorGroups,
|
|
640
|
+
ownGroups: mergedOwnGroups,
|
|
496
641
|
mediaConditions: mergedMedia,
|
|
497
642
|
containerConditions: mergedContainers,
|
|
498
643
|
supportsConditions: mergedSupports,
|
|
499
|
-
|
|
644
|
+
rootGroups: mergedRootGroups,
|
|
500
645
|
parentGroups: mergedParentGroups,
|
|
501
646
|
startingStyle: a.startingStyle || b.startingStyle
|
|
502
647
|
};
|
|
@@ -627,28 +772,45 @@ const variantKeyCache = /* @__PURE__ */ new WeakMap();
|
|
|
627
772
|
* Cached via WeakMap since variants are compared multiple times during
|
|
628
773
|
* deduplication and sorting.
|
|
629
774
|
*/
|
|
630
|
-
function
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
ownKey,
|
|
775
|
+
function getSelectorGroupKey(g) {
|
|
776
|
+
return `${g.negated ? "!" : ""}(${getBranchesKey(g.branches)})`;
|
|
777
|
+
}
|
|
778
|
+
/**
|
|
779
|
+
* Get a context key for a variant — everything except flat modifier/pseudo
|
|
780
|
+
* conditions. Variants with the same context key can be merged into an
|
|
781
|
+
* :is() group. Also used by getVariantKey as the shared non-selector portion.
|
|
782
|
+
*/
|
|
783
|
+
function getVariantContextKey(v) {
|
|
784
|
+
return [
|
|
641
785
|
v.mediaConditions.map((c) => `${c.subtype}:${c.negated ? "!" : ""}${c.condition}`).sort().join("|"),
|
|
642
|
-
|
|
786
|
+
v.containerConditions.map((c) => `${c.name ?? ""}:${c.negated ? "!" : ""}${c.condition}`).sort().join("|"),
|
|
643
787
|
v.supportsConditions.map((c) => `${c.subtype}:${c.negated ? "!" : ""}${c.condition}`).sort().join("|"),
|
|
644
|
-
v.
|
|
788
|
+
v.rootGroups.map(getSelectorGroupKey).sort().join("|"),
|
|
645
789
|
v.parentGroups.map(getParentGroupKey).sort().join("|"),
|
|
790
|
+
v.ownGroups.map(getSelectorGroupKey).sort().join("|"),
|
|
791
|
+
v.selectorGroups.map(getSelectorGroupKey).sort().join("|"),
|
|
646
792
|
v.startingStyle ? "1" : "0"
|
|
647
793
|
].join("###");
|
|
794
|
+
}
|
|
795
|
+
function getVariantKey(v) {
|
|
796
|
+
const cached = variantKeyCache.get(v);
|
|
797
|
+
if (cached !== void 0) return cached;
|
|
798
|
+
const modifierKey = v.modifierConditions.map(getModifierKey).sort().join("|");
|
|
799
|
+
const pseudoKey = v.pseudoConditions.map(getPseudoKey).sort().join("|");
|
|
800
|
+
const key = modifierKey + "###" + pseudoKey + "###" + getVariantContextKey(v);
|
|
648
801
|
variantKeyCache.set(v, key);
|
|
649
802
|
return key;
|
|
650
803
|
}
|
|
651
804
|
/**
|
|
805
|
+
* Total number of leaf conditions in a variant (for superset / dedup comparisons).
|
|
806
|
+
*/
|
|
807
|
+
function groupConditionCount(groups) {
|
|
808
|
+
return groups.reduce((sum, g) => sum + g.branches.reduce((s, b) => s + b.length, 0), 0);
|
|
809
|
+
}
|
|
810
|
+
function variantConditionCount(v) {
|
|
811
|
+
return v.modifierConditions.length + v.pseudoConditions.length + groupConditionCount(v.selectorGroups) + groupConditionCount(v.ownGroups) + v.mediaConditions.length + v.containerConditions.length + v.supportsConditions.length + groupConditionCount(v.rootGroups) + groupConditionCount(v.parentGroups);
|
|
812
|
+
}
|
|
813
|
+
/**
|
|
652
814
|
* Check if variant A is a superset of variant B (A is more restrictive)
|
|
653
815
|
*
|
|
654
816
|
* If A has all of B's conditions plus more, then A is redundant
|
|
@@ -661,16 +823,16 @@ function getVariantKey(v) {
|
|
|
661
823
|
*/
|
|
662
824
|
function isVariantSuperset(a, b) {
|
|
663
825
|
if (a.startingStyle !== b.startingStyle) return false;
|
|
664
|
-
if (!
|
|
826
|
+
if (!isSelectorGroupsSuperset(a.rootGroups, b.rootGroups)) return false;
|
|
665
827
|
if (!isMediaConditionsSuperset(a.mediaConditions, b.mediaConditions)) return false;
|
|
666
828
|
if (!isContainerConditionsSuperset(a.containerConditions, b.containerConditions)) return false;
|
|
667
829
|
if (!isSupportsConditionsSuperset(a.supportsConditions, b.supportsConditions)) return false;
|
|
668
830
|
if (!isModifierConditionsSuperset(a.modifierConditions, b.modifierConditions)) return false;
|
|
669
831
|
if (!isPseudoConditionsSuperset(a.pseudoConditions, b.pseudoConditions)) return false;
|
|
670
|
-
if (!
|
|
832
|
+
if (!isSelectorGroupsSuperset(a.selectorGroups, b.selectorGroups)) return false;
|
|
833
|
+
if (!isSelectorGroupsSuperset(a.ownGroups, b.ownGroups)) return false;
|
|
671
834
|
if (!isParentGroupsSuperset(a.parentGroups, b.parentGroups)) return false;
|
|
672
|
-
|
|
673
|
-
return a.mediaConditions.length + a.containerConditions.length + a.supportsConditions.length + a.modifierConditions.length + a.pseudoConditions.length + a.rootConditions.length + parentConditionCount(a.parentGroups) + a.ownConditions.length > b.mediaConditions.length + b.containerConditions.length + b.supportsConditions.length + b.modifierConditions.length + b.pseudoConditions.length + b.rootConditions.length + parentConditionCount(b.parentGroups) + b.ownConditions.length;
|
|
835
|
+
return variantConditionCount(a) > variantConditionCount(b);
|
|
674
836
|
}
|
|
675
837
|
/**
|
|
676
838
|
* Generic superset check: true if every item in B has a matching key in A.
|
|
@@ -694,8 +856,9 @@ function isModifierConditionsSuperset(a, b) {
|
|
|
694
856
|
function isPseudoConditionsSuperset(a, b) {
|
|
695
857
|
return isConditionsSuperset(a, b, getPseudoKey);
|
|
696
858
|
}
|
|
697
|
-
function
|
|
698
|
-
|
|
859
|
+
function isSelectorGroupsSuperset(a, b) {
|
|
860
|
+
if (a.length < b.length) return false;
|
|
861
|
+
return isConditionsSuperset(a, b, getSelectorGroupKey);
|
|
699
862
|
}
|
|
700
863
|
/**
|
|
701
864
|
* Check if parent groups A is a superset of B.
|
|
@@ -706,7 +869,7 @@ function isParentGroupsSuperset(a, b) {
|
|
|
706
869
|
return isConditionsSuperset(a, b, getParentGroupKey);
|
|
707
870
|
}
|
|
708
871
|
function getParentGroupKey(g) {
|
|
709
|
-
return `${g.negated ? "!" : ""}${g.direct ? ">" : ""}(${g.
|
|
872
|
+
return `${g.negated ? "!" : ""}${g.direct ? ">" : ""}(${getBranchesKey(g.branches)})`;
|
|
710
873
|
}
|
|
711
874
|
/**
|
|
712
875
|
* Deduplicate variants
|
|
@@ -716,6 +879,7 @@ function getParentGroupKey(g) {
|
|
|
716
879
|
* 2. Superset variants (more restrictive selectors that are redundant)
|
|
717
880
|
*/
|
|
718
881
|
function dedupeVariants(variants) {
|
|
882
|
+
if (variants.length <= 1) return variants;
|
|
719
883
|
const seen = /* @__PURE__ */ new Set();
|
|
720
884
|
const result = [];
|
|
721
885
|
for (const v of variants) {
|
|
@@ -725,7 +889,7 @@ function dedupeVariants(variants) {
|
|
|
725
889
|
result.push(v);
|
|
726
890
|
}
|
|
727
891
|
}
|
|
728
|
-
|
|
892
|
+
if (result.length <= 1) return result;
|
|
729
893
|
result.sort((a, b) => variantConditionCount(a) - variantConditionCount(b));
|
|
730
894
|
const filtered = [];
|
|
731
895
|
for (const candidate of result) {
|
|
@@ -775,8 +939,8 @@ function andToCSS(children) {
|
|
|
775
939
|
* Combine OR conditions into CSS
|
|
776
940
|
*
|
|
777
941
|
* OR in CSS means multiple selector variants (DNF).
|
|
778
|
-
*
|
|
779
|
-
*
|
|
942
|
+
* After deduplication, variants that differ only in their base
|
|
943
|
+
* modifier/pseudo conditions are merged into :is() groups.
|
|
780
944
|
*
|
|
781
945
|
* Note: OR exclusivity is handled at the pipeline level (expandOrConditions),
|
|
782
946
|
* so here we just collect all variants. Any remaining ORs in the condition
|
|
@@ -799,6 +963,103 @@ function orToCSS(children) {
|
|
|
799
963
|
};
|
|
800
964
|
}
|
|
801
965
|
/**
|
|
966
|
+
* Find keys present in ALL condition arrays.
|
|
967
|
+
*/
|
|
968
|
+
function findCommonKeys(conditionSets, getKey) {
|
|
969
|
+
if (conditionSets.length === 0) return /* @__PURE__ */ new Set();
|
|
970
|
+
const common = new Set(conditionSets[0].map(getKey));
|
|
971
|
+
for (let i = 1; i < conditionSets.length; i++) {
|
|
972
|
+
const keys = new Set(conditionSets[i].map(getKey));
|
|
973
|
+
for (const key of common) if (!keys.has(key)) common.delete(key);
|
|
974
|
+
}
|
|
975
|
+
return common;
|
|
976
|
+
}
|
|
977
|
+
/**
|
|
978
|
+
* Merge OR variants that share the same "context" (at-rules, root, parent,
|
|
979
|
+
* own, starting) into a single variant with a SelectorGroup.
|
|
980
|
+
*
|
|
981
|
+
* Variants with no modifier/pseudo conditions are kept separate (they match
|
|
982
|
+
* unconditionally and can't be expressed inside :is()).
|
|
983
|
+
*/
|
|
984
|
+
function mergeVariantsIntoSelectorGroups(variants) {
|
|
985
|
+
if (variants.length <= 1) return variants;
|
|
986
|
+
const groups = /* @__PURE__ */ new Map();
|
|
987
|
+
for (const v of variants) {
|
|
988
|
+
const key = getVariantContextKey(v);
|
|
989
|
+
const group = groups.get(key);
|
|
990
|
+
if (group) group.push(v);
|
|
991
|
+
else groups.set(key, [v]);
|
|
992
|
+
}
|
|
993
|
+
const result = [];
|
|
994
|
+
for (const group of groups.values()) {
|
|
995
|
+
if (group.length === 1) {
|
|
996
|
+
result.push(group[0]);
|
|
997
|
+
continue;
|
|
998
|
+
}
|
|
999
|
+
const withSelectors = [];
|
|
1000
|
+
const withoutSelectors = [];
|
|
1001
|
+
for (const v of group) if (v.modifierConditions.length === 0 && v.pseudoConditions.length === 0) withoutSelectors.push(v);
|
|
1002
|
+
else withSelectors.push(v);
|
|
1003
|
+
result.push(...withoutSelectors);
|
|
1004
|
+
if (withSelectors.length <= 1) {
|
|
1005
|
+
result.push(...withSelectors);
|
|
1006
|
+
continue;
|
|
1007
|
+
}
|
|
1008
|
+
result.push(factorAndGroup(withSelectors));
|
|
1009
|
+
}
|
|
1010
|
+
return result;
|
|
1011
|
+
}
|
|
1012
|
+
/**
|
|
1013
|
+
* Factor common modifier/pseudo conditions out of variants and create
|
|
1014
|
+
* a single variant with a SelectorGroup for the remaining (differing)
|
|
1015
|
+
* conditions.
|
|
1016
|
+
*
|
|
1017
|
+
* Precondition: all variants must share the same context key (identical
|
|
1018
|
+
* at-rules, root/parent/own/selector groups, startingStyle).
|
|
1019
|
+
*/
|
|
1020
|
+
function factorAndGroup(variants) {
|
|
1021
|
+
{
|
|
1022
|
+
const key0 = getVariantContextKey(variants[0]);
|
|
1023
|
+
for (let i = 1; i < variants.length; i++) {
|
|
1024
|
+
const keyI = getVariantContextKey(variants[i]);
|
|
1025
|
+
if (keyI !== key0) throw new Error(`factorAndGroup: context key mismatch at index ${i}.\n expected: ${key0}\n got: ${keyI}`);
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
const commonModKeys = findCommonKeys(variants.map((v) => v.modifierConditions), getModifierKey);
|
|
1029
|
+
const commonPseudoKeys = findCommonKeys(variants.map((v) => v.pseudoConditions), getPseudoKey);
|
|
1030
|
+
const commonModifiers = variants[0].modifierConditions.filter((m) => commonModKeys.has(getModifierKey(m)));
|
|
1031
|
+
const commonPseudos = variants[0].pseudoConditions.filter((p) => commonPseudoKeys.has(getPseudoKey(p)));
|
|
1032
|
+
const branches = [];
|
|
1033
|
+
let hasEmptyBranch = false;
|
|
1034
|
+
for (const v of variants) {
|
|
1035
|
+
const branch = [];
|
|
1036
|
+
for (const mod of v.modifierConditions) if (!commonModKeys.has(getModifierKey(mod))) branch.push(mod);
|
|
1037
|
+
for (const pseudo of v.pseudoConditions) if (!commonPseudoKeys.has(getPseudoKey(pseudo))) branch.push(pseudo);
|
|
1038
|
+
if (branch.length > 0) branches.push(branch);
|
|
1039
|
+
else hasEmptyBranch = true;
|
|
1040
|
+
}
|
|
1041
|
+
if (hasEmptyBranch) return {
|
|
1042
|
+
...variants[0],
|
|
1043
|
+
modifierConditions: commonModifiers,
|
|
1044
|
+
pseudoConditions: commonPseudos
|
|
1045
|
+
};
|
|
1046
|
+
return {
|
|
1047
|
+
modifierConditions: commonModifiers,
|
|
1048
|
+
pseudoConditions: commonPseudos,
|
|
1049
|
+
selectorGroups: [...variants[0].selectorGroups, {
|
|
1050
|
+
branches,
|
|
1051
|
+
negated: false
|
|
1052
|
+
}],
|
|
1053
|
+
ownGroups: [...variants[0].ownGroups],
|
|
1054
|
+
mediaConditions: [...variants[0].mediaConditions],
|
|
1055
|
+
containerConditions: [...variants[0].containerConditions],
|
|
1056
|
+
supportsConditions: [...variants[0].supportsConditions],
|
|
1057
|
+
rootGroups: [...variants[0].rootGroups],
|
|
1058
|
+
parentGroups: [...variants[0].parentGroups],
|
|
1059
|
+
startingStyle: variants[0].startingStyle
|
|
1060
|
+
};
|
|
1061
|
+
}
|
|
1062
|
+
/**
|
|
802
1063
|
* Build at-rules array from a variant
|
|
803
1064
|
*/
|
|
804
1065
|
function buildAtRulesFromVariant(variant) {
|
|
@@ -840,5 +1101,5 @@ function buildAtRulesFromVariant(variant) {
|
|
|
840
1101
|
}
|
|
841
1102
|
|
|
842
1103
|
//#endregion
|
|
843
|
-
export { buildAtRulesFromVariant, conditionToCSS,
|
|
1104
|
+
export { branchToCSS, buildAtRulesFromVariant, conditionToCSS, mergeVariantsIntoSelectorGroups, optimizeGroups, parentGroupsToCSS, rootGroupsToCSS, selectorGroupToCSS };
|
|
844
1105
|
//# sourceMappingURL=materialize.js.map
|