@drskillissue/ganko 0.1.23 → 0.1.24
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 +1 -1
- package/dist/{chunk-V6U7TQCD.js → chunk-64TMAKYI.js} +870 -729
- package/dist/chunk-64TMAKYI.js.map +1 -0
- package/dist/{chunk-4PJEULOI.js → chunk-KVZ56NZ5.js} +6 -6
- package/dist/chunk-KVZ56NZ5.js.map +1 -0
- package/dist/eslint-plugin.cjs +796 -655
- package/dist/eslint-plugin.cjs.map +1 -1
- package/dist/eslint-plugin.js +1 -1
- package/dist/index.cjs +801 -660
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +112 -55
- package/dist/index.d.ts +112 -55
- package/dist/index.js +2 -2
- package/dist/rules-manifest.cjs +5 -5
- package/dist/rules-manifest.cjs.map +1 -1
- package/dist/rules-manifest.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-4PJEULOI.js.map +0 -1
- package/dist/chunk-V6U7TQCD.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -8919,7 +8919,7 @@ function resolveMessage(template, data) {
|
|
|
8919
8919
|
}
|
|
8920
8920
|
return result;
|
|
8921
8921
|
}
|
|
8922
|
-
function createDiagnosticFromLoc(file, loc, rule, messageId, message, severity, fix) {
|
|
8922
|
+
function createDiagnosticFromLoc(file, loc, rule, messageId, message, severity, fix, suggest) {
|
|
8923
8923
|
const result = {
|
|
8924
8924
|
file,
|
|
8925
8925
|
rule,
|
|
@@ -8929,13 +8929,14 @@ function createDiagnosticFromLoc(file, loc, rule, messageId, message, severity,
|
|
|
8929
8929
|
loc: firstLine(loc)
|
|
8930
8930
|
};
|
|
8931
8931
|
if (fix !== void 0) result.fix = fix;
|
|
8932
|
+
if (suggest !== void 0 && suggest.length > 0) result.suggest = suggest;
|
|
8932
8933
|
return result;
|
|
8933
8934
|
}
|
|
8934
|
-
function createDiagnosticFromComment(file, comment, rule, messageId, message, severity, fix) {
|
|
8935
|
-
return createDiagnosticFromLoc(file, comment.loc, rule, messageId, message, severity, fix);
|
|
8935
|
+
function createDiagnosticFromComment(file, comment, rule, messageId, message, severity, fix, suggest) {
|
|
8936
|
+
return createDiagnosticFromLoc(file, comment.loc, rule, messageId, message, severity, fix, suggest);
|
|
8936
8937
|
}
|
|
8937
|
-
function createDiagnostic(file, node, rule, messageId, message, severity, fix) {
|
|
8938
|
-
return createDiagnosticFromLoc(file, node.loc, rule, messageId, message, severity, fix);
|
|
8938
|
+
function createDiagnostic(file, node, rule, messageId, message, severity, fix, suggest) {
|
|
8939
|
+
return createDiagnosticFromLoc(file, node.loc, rule, messageId, message, severity, fix, suggest);
|
|
8939
8940
|
}
|
|
8940
8941
|
|
|
8941
8942
|
// src/solid/rule.ts
|
|
@@ -12091,9 +12092,9 @@ var CONDITIONAL_MOUNT_TAGS = /* @__PURE__ */ new Set([
|
|
|
12091
12092
|
"TabPanel"
|
|
12092
12093
|
]);
|
|
12093
12094
|
var messages16 = {
|
|
12094
|
-
loadingMismatch: "createResource '{{name}}' has no initialValue but uses
|
|
12095
|
-
conditionalSuspense: "createResource '{{name}}' is
|
|
12096
|
-
missingErrorBoundary: "createResource '{{name}}' has no <ErrorBoundary> between its component and the nearest <Suspense>. When the fetcher throws (network error, 401/403/503, timeout), the error propagates to Suspense which
|
|
12095
|
+
loadingMismatch: "createResource '{{name}}' has no initialValue but uses {{name}}.loading for manual loading UI. Suspense intercepts before your loading UI renders \u2014 the component is unmounted before the <Show>/<Switch> evaluates. Replace createResource with onMount + createSignal to decouple from Suspense entirely.",
|
|
12096
|
+
conditionalSuspense: "createResource '{{name}}' is inside a conditional mount point ({{mountTag}}) with a distant Suspense boundary. The SuspenseContext increment fires when the fetcher's Promise is pending and unmounts the entire page subtree \u2014 initialValue does NOT prevent this. Replace createResource with onMount + createSignal to avoid Suspense interaction.",
|
|
12097
|
+
missingErrorBoundary: "createResource '{{name}}' has no <ErrorBoundary> between its component and the nearest <Suspense>. When the fetcher throws (network error, 401/403/503, timeout), the error propagates to Suspense which has no error handling \u2014 the boundary breaks permanently. Wrap the component in <ErrorBoundary> or replace createResource with onMount + createSignal and catch errors in the fetcher."
|
|
12097
12098
|
};
|
|
12098
12099
|
var options16 = {};
|
|
12099
12100
|
function hasInitialValue(call) {
|
|
@@ -12179,7 +12180,8 @@ function analyzeComponentBoundaries(graph, componentName) {
|
|
|
12179
12180
|
const result = {
|
|
12180
12181
|
conditionalMountTag: null,
|
|
12181
12182
|
suspenseDistance: 0,
|
|
12182
|
-
lacksErrorBoundary: false
|
|
12183
|
+
lacksErrorBoundary: false,
|
|
12184
|
+
usagesLackingErrorBoundary: []
|
|
12183
12185
|
};
|
|
12184
12186
|
const usages = graph.jsxByTag.get(componentName) ?? [];
|
|
12185
12187
|
if (usages.length === 0) return result;
|
|
@@ -12201,6 +12203,7 @@ function analyzeComponentBoundaries(graph, componentName) {
|
|
|
12201
12203
|
foundSuspense = true;
|
|
12202
12204
|
if (!foundErrorBoundary) {
|
|
12203
12205
|
result.lacksErrorBoundary = true;
|
|
12206
|
+
result.usagesLackingErrorBoundary.push(usage);
|
|
12204
12207
|
}
|
|
12205
12208
|
if (conditionalTag !== null && componentLevels > 1) {
|
|
12206
12209
|
result.conditionalMountTag = conditionalTag;
|
|
@@ -12215,6 +12218,7 @@ function analyzeComponentBoundaries(graph, componentName) {
|
|
|
12215
12218
|
}
|
|
12216
12219
|
if (!foundSuspense && !foundErrorBoundary) {
|
|
12217
12220
|
result.lacksErrorBoundary = true;
|
|
12221
|
+
result.usagesLackingErrorBoundary.push(usage);
|
|
12218
12222
|
if (conditionalTag !== null) {
|
|
12219
12223
|
result.conditionalMountTag = conditionalTag;
|
|
12220
12224
|
result.suspenseDistance = componentLevels;
|
|
@@ -12238,13 +12242,28 @@ function findResourceVariable(graph, name) {
|
|
|
12238
12242
|
}
|
|
12239
12243
|
return null;
|
|
12240
12244
|
}
|
|
12245
|
+
function buildErrorBoundaryFix(usages, graph) {
|
|
12246
|
+
if (usages.length === 0) return null;
|
|
12247
|
+
const usage = usages[0];
|
|
12248
|
+
if (!usage) return null;
|
|
12249
|
+
const jsxNode = usage.node;
|
|
12250
|
+
const startPos = jsxNode.range[0];
|
|
12251
|
+
const endPos = jsxNode.range[1];
|
|
12252
|
+
const ops = [
|
|
12253
|
+
{ range: [startPos, startPos], text: "<ErrorBoundary fallback={<div>Error</div>}>" },
|
|
12254
|
+
{ range: [endPos, endPos], text: "</ErrorBoundary>" }
|
|
12255
|
+
];
|
|
12256
|
+
const importFix = buildSolidImportFix(graph, "ErrorBoundary");
|
|
12257
|
+
if (importFix) ops.unshift(importFix);
|
|
12258
|
+
return ops;
|
|
12259
|
+
}
|
|
12241
12260
|
var resourceImplicitSuspense = defineSolidRule({
|
|
12242
12261
|
id: "resource-implicit-suspense",
|
|
12243
12262
|
severity: "warn",
|
|
12244
12263
|
messages: messages16,
|
|
12245
12264
|
meta: {
|
|
12246
12265
|
description: "Detect createResource that implicitly triggers or permanently breaks Suspense boundaries.",
|
|
12247
|
-
fixable:
|
|
12266
|
+
fixable: true,
|
|
12248
12267
|
category: "reactivity"
|
|
12249
12268
|
},
|
|
12250
12269
|
options: options16,
|
|
@@ -12299,6 +12318,10 @@ var resourceImplicitSuspense = defineSolidRule({
|
|
|
12299
12318
|
if (analysis.lacksErrorBoundary) {
|
|
12300
12319
|
const fetcherFn = resolveFetcherFunction(graph, call);
|
|
12301
12320
|
if (fetcherFn && fetcherCanThrow(graph, fetcherFn, throwVisited)) {
|
|
12321
|
+
const errorBoundaryFix = buildErrorBoundaryFix(
|
|
12322
|
+
analysis.usagesLackingErrorBoundary,
|
|
12323
|
+
graph
|
|
12324
|
+
);
|
|
12302
12325
|
emit(
|
|
12303
12326
|
createDiagnostic(
|
|
12304
12327
|
graph.file,
|
|
@@ -12306,7 +12329,8 @@ var resourceImplicitSuspense = defineSolidRule({
|
|
|
12306
12329
|
"resource-implicit-suspense",
|
|
12307
12330
|
"missingErrorBoundary",
|
|
12308
12331
|
resolveMessage(messages16.missingErrorBoundary, { name: resourceName }),
|
|
12309
|
-
"error"
|
|
12332
|
+
"error",
|
|
12333
|
+
errorBoundaryFix ?? void 0
|
|
12310
12334
|
)
|
|
12311
12335
|
);
|
|
12312
12336
|
}
|
|
@@ -30243,6 +30267,11 @@ function toLayoutElementKey(solidFile, elementId) {
|
|
|
30243
30267
|
return `${solidFile}::${elementId}`;
|
|
30244
30268
|
}
|
|
30245
30269
|
|
|
30270
|
+
// src/cross-file/layout/context-model.ts
|
|
30271
|
+
function deriveAlignmentContext(base, overrides) {
|
|
30272
|
+
return { ...base, ...overrides };
|
|
30273
|
+
}
|
|
30274
|
+
|
|
30246
30275
|
// src/cross-file/layout/signal-model.ts
|
|
30247
30276
|
var layoutSignalNames = [
|
|
30248
30277
|
"line-height",
|
|
@@ -30271,6 +30300,8 @@ var layoutSignalNames = [
|
|
|
30271
30300
|
"justify-items",
|
|
30272
30301
|
"place-items",
|
|
30273
30302
|
"place-self",
|
|
30303
|
+
"flex-direction",
|
|
30304
|
+
"grid-auto-flow",
|
|
30274
30305
|
"appearance",
|
|
30275
30306
|
"box-sizing",
|
|
30276
30307
|
"padding-top",
|
|
@@ -30389,13 +30420,44 @@ function expandShorthand(property, value2) {
|
|
|
30389
30420
|
{ name: blockTarget[1], value: parsed.end }
|
|
30390
30421
|
];
|
|
30391
30422
|
}
|
|
30423
|
+
if (property === "flex-flow") {
|
|
30424
|
+
return expandFlexFlow(value2);
|
|
30425
|
+
}
|
|
30392
30426
|
return void 0;
|
|
30393
30427
|
}
|
|
30428
|
+
var FLEX_DIRECTION_VALUES = /* @__PURE__ */ new Set(["row", "row-reverse", "column", "column-reverse"]);
|
|
30429
|
+
function expandFlexFlow(value2) {
|
|
30430
|
+
const tokens = splitWhitespaceTokens(value2.trim().toLowerCase());
|
|
30431
|
+
if (tokens.length === 0) return null;
|
|
30432
|
+
if (tokens.length > 2) return null;
|
|
30433
|
+
let direction = null;
|
|
30434
|
+
let wrap = null;
|
|
30435
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
30436
|
+
const token = tokens[i];
|
|
30437
|
+
if (!token) continue;
|
|
30438
|
+
if (FLEX_DIRECTION_VALUES.has(token)) {
|
|
30439
|
+
if (direction !== null) return null;
|
|
30440
|
+
direction = token;
|
|
30441
|
+
} else {
|
|
30442
|
+
if (wrap !== null) return null;
|
|
30443
|
+
wrap = token;
|
|
30444
|
+
}
|
|
30445
|
+
}
|
|
30446
|
+
const out = [];
|
|
30447
|
+
if (direction !== null) {
|
|
30448
|
+
out.push({ name: "flex-direction", value: direction });
|
|
30449
|
+
}
|
|
30450
|
+
if (wrap !== null) {
|
|
30451
|
+
out.push({ name: "flex-wrap", value: wrap });
|
|
30452
|
+
}
|
|
30453
|
+
return out.length > 0 ? out : null;
|
|
30454
|
+
}
|
|
30394
30455
|
function getShorthandLonghandNames(property) {
|
|
30395
30456
|
const quad = QUAD_EXPANSIONS.get(property);
|
|
30396
30457
|
if (quad !== void 0) return [...quad];
|
|
30397
30458
|
const block = BLOCK_EXPANSIONS.get(property);
|
|
30398
30459
|
if (block !== void 0) return [...block];
|
|
30460
|
+
if (property === "flex-flow") return ["flex-direction", "flex-wrap"];
|
|
30399
30461
|
return null;
|
|
30400
30462
|
}
|
|
30401
30463
|
|
|
@@ -30406,27 +30468,90 @@ var CONTROL_ELEMENT_TAGS = /* @__PURE__ */ new Set([
|
|
|
30406
30468
|
"textarea",
|
|
30407
30469
|
"button"
|
|
30408
30470
|
]);
|
|
30471
|
+
var INTRINSIC_REPLACED_TAGS = /* @__PURE__ */ new Set([
|
|
30472
|
+
"img",
|
|
30473
|
+
"svg",
|
|
30474
|
+
"video",
|
|
30475
|
+
"canvas",
|
|
30476
|
+
"iframe",
|
|
30477
|
+
"object",
|
|
30478
|
+
"embed"
|
|
30479
|
+
]);
|
|
30480
|
+
var WHITESPACE_RE3 = /\s+/;
|
|
30409
30481
|
function clamp(value2, min, max) {
|
|
30410
30482
|
if (value2 < min) return min;
|
|
30411
30483
|
if (value2 > max) return max;
|
|
30412
30484
|
return value2;
|
|
30413
30485
|
}
|
|
30414
|
-
function kindRank(kind) {
|
|
30415
|
-
if (kind === "exact") return 0;
|
|
30416
|
-
if (kind === "interval") return 1;
|
|
30417
|
-
if (kind === "conditional") return 2;
|
|
30418
|
-
return 3;
|
|
30419
|
-
}
|
|
30420
30486
|
function mergeEvidenceKind(left, right) {
|
|
30421
|
-
|
|
30422
|
-
|
|
30487
|
+
return left > right ? left : right;
|
|
30488
|
+
}
|
|
30489
|
+
function selectKth(values, targetIndex) {
|
|
30490
|
+
let left = 0;
|
|
30491
|
+
let right = values.length - 1;
|
|
30492
|
+
while (left <= right) {
|
|
30493
|
+
if (left === right) {
|
|
30494
|
+
const result = values[left];
|
|
30495
|
+
if (result === void 0) return 0;
|
|
30496
|
+
return result;
|
|
30497
|
+
}
|
|
30498
|
+
const pivotIndex = choosePivotIndex(values, left, right);
|
|
30499
|
+
const partitionIndex = partitionAroundPivot(values, left, right, pivotIndex);
|
|
30500
|
+
if (partitionIndex === targetIndex) {
|
|
30501
|
+
const result = values[partitionIndex];
|
|
30502
|
+
if (result === void 0) return 0;
|
|
30503
|
+
return result;
|
|
30504
|
+
}
|
|
30505
|
+
if (partitionIndex < targetIndex) {
|
|
30506
|
+
left = partitionIndex + 1;
|
|
30507
|
+
continue;
|
|
30508
|
+
}
|
|
30509
|
+
right = partitionIndex - 1;
|
|
30510
|
+
}
|
|
30511
|
+
const fallback = values[targetIndex];
|
|
30512
|
+
if (fallback === void 0) return 0;
|
|
30513
|
+
return fallback;
|
|
30514
|
+
}
|
|
30515
|
+
function choosePivotIndex(values, left, right) {
|
|
30516
|
+
const middle = Math.floor((left + right) / 2);
|
|
30517
|
+
const leftValue = values[left] ?? 0;
|
|
30518
|
+
const middleValue = values[middle] ?? 0;
|
|
30519
|
+
const rightValue = values[right] ?? 0;
|
|
30520
|
+
if (leftValue < middleValue) {
|
|
30521
|
+
if (middleValue < rightValue) return middle;
|
|
30522
|
+
if (leftValue < rightValue) return right;
|
|
30523
|
+
return left;
|
|
30524
|
+
}
|
|
30525
|
+
if (leftValue < rightValue) return left;
|
|
30526
|
+
if (middleValue < rightValue) return right;
|
|
30527
|
+
return middle;
|
|
30528
|
+
}
|
|
30529
|
+
function partitionAroundPivot(values, left, right, pivotIndex) {
|
|
30530
|
+
const pivotValue = values[pivotIndex] ?? 0;
|
|
30531
|
+
swap(values, pivotIndex, right);
|
|
30532
|
+
let storeIndex = left;
|
|
30533
|
+
for (let i = left; i < right; i++) {
|
|
30534
|
+
const current = values[i];
|
|
30535
|
+
if (current === void 0 || current > pivotValue) continue;
|
|
30536
|
+
swap(values, storeIndex, i);
|
|
30537
|
+
storeIndex++;
|
|
30538
|
+
}
|
|
30539
|
+
swap(values, storeIndex, right);
|
|
30540
|
+
return storeIndex;
|
|
30541
|
+
}
|
|
30542
|
+
function swap(values, left, right) {
|
|
30543
|
+
if (left === right) return;
|
|
30544
|
+
const leftValue = values[left] ?? 0;
|
|
30545
|
+
const rightValue = values[right] ?? 0;
|
|
30546
|
+
values[left] = rightValue;
|
|
30547
|
+
values[right] = leftValue;
|
|
30423
30548
|
}
|
|
30424
30549
|
function toComparableExactValue(value2) {
|
|
30425
30550
|
if (value2.value !== null) {
|
|
30426
|
-
if (value2.kind !==
|
|
30551
|
+
if (value2.kind !== 0 /* Exact */) return null;
|
|
30427
30552
|
return value2.value;
|
|
30428
30553
|
}
|
|
30429
|
-
if (value2.kind ===
|
|
30554
|
+
if (value2.kind === 0 /* Exact */) return 0;
|
|
30430
30555
|
return null;
|
|
30431
30556
|
}
|
|
30432
30557
|
|
|
@@ -30440,7 +30565,8 @@ var MONITORED_SHORTHAND_SET = /* @__PURE__ */ new Set([
|
|
|
30440
30565
|
"border-width",
|
|
30441
30566
|
"margin-block",
|
|
30442
30567
|
"padding-block",
|
|
30443
|
-
"inset-block"
|
|
30568
|
+
"inset-block",
|
|
30569
|
+
"flex-flow"
|
|
30444
30570
|
]);
|
|
30445
30571
|
var LENGTH_SIGNAL_SET = /* @__PURE__ */ new Set([
|
|
30446
30572
|
"font-size",
|
|
@@ -30482,13 +30608,22 @@ var KEYWORD_SIGNAL_SET = /* @__PURE__ */ new Set([
|
|
|
30482
30608
|
"justify-items",
|
|
30483
30609
|
"place-items",
|
|
30484
30610
|
"place-self",
|
|
30611
|
+
"flex-direction",
|
|
30612
|
+
"grid-auto-flow",
|
|
30485
30613
|
"appearance",
|
|
30486
30614
|
"box-sizing",
|
|
30487
30615
|
"position",
|
|
30488
30616
|
"writing-mode",
|
|
30489
30617
|
"direction"
|
|
30490
30618
|
]);
|
|
30491
|
-
var
|
|
30619
|
+
var REPLACED_ELEMENT_TAGS = /* @__PURE__ */ new Set([
|
|
30620
|
+
...CONTROL_ELEMENT_TAGS,
|
|
30621
|
+
"img",
|
|
30622
|
+
"video",
|
|
30623
|
+
"canvas",
|
|
30624
|
+
"svg",
|
|
30625
|
+
"iframe"
|
|
30626
|
+
]);
|
|
30492
30627
|
function isMonitoredSignal(property) {
|
|
30493
30628
|
if (MONITORED_SIGNAL_SET.has(property)) return true;
|
|
30494
30629
|
return MONITORED_SHORTHAND_SET.has(property);
|
|
@@ -30499,7 +30634,7 @@ function isControlTag(tag) {
|
|
|
30499
30634
|
}
|
|
30500
30635
|
function isReplacedTag(tag) {
|
|
30501
30636
|
if (tag === null) return false;
|
|
30502
|
-
return
|
|
30637
|
+
return REPLACED_ELEMENT_TAGS.has(tag.toLowerCase());
|
|
30503
30638
|
}
|
|
30504
30639
|
function normalizeSignalMapWithCounts(values) {
|
|
30505
30640
|
const out = /* @__PURE__ */ new Map();
|
|
@@ -30510,12 +30645,11 @@ function normalizeSignalMapWithCounts(values) {
|
|
|
30510
30645
|
"font-size",
|
|
30511
30646
|
fontSizeEntry.value,
|
|
30512
30647
|
fontSizeEntry.source,
|
|
30513
|
-
fontSizeEntry.guard,
|
|
30514
30648
|
fontSizeEntry.guardProvenance,
|
|
30515
30649
|
null
|
|
30516
30650
|
);
|
|
30517
30651
|
out.set("font-size", parsedFontSize);
|
|
30518
|
-
if (parsedFontSize.kind === "known" && parsedFontSize.guard ===
|
|
30652
|
+
if (parsedFontSize.kind === "known" && parsedFontSize.guard.kind === 0 /* Unconditional */) {
|
|
30519
30653
|
fontSizePx = parsedFontSize.px;
|
|
30520
30654
|
}
|
|
30521
30655
|
}
|
|
@@ -30531,7 +30665,6 @@ function normalizeSignalMapWithCounts(values) {
|
|
|
30531
30665
|
name,
|
|
30532
30666
|
declaration.value,
|
|
30533
30667
|
declaration.source,
|
|
30534
|
-
declaration.guard,
|
|
30535
30668
|
declaration.guardProvenance,
|
|
30536
30669
|
fontSizePx
|
|
30537
30670
|
);
|
|
@@ -30541,7 +30674,7 @@ function normalizeSignalMapWithCounts(values) {
|
|
|
30541
30674
|
let unknownSignalCount = 0;
|
|
30542
30675
|
let conditionalSignalCount = 0;
|
|
30543
30676
|
for (const value2 of out.values()) {
|
|
30544
|
-
if (value2.guard ===
|
|
30677
|
+
if (value2.guard.kind === 1 /* Conditional */) {
|
|
30545
30678
|
conditionalSignalCount++;
|
|
30546
30679
|
continue;
|
|
30547
30680
|
}
|
|
@@ -30569,7 +30702,7 @@ function applyExpandedShorthand(out, property, declaration, fontSizePx) {
|
|
|
30569
30702
|
if (!longhand) continue;
|
|
30570
30703
|
const name = MONITORED_SIGNAL_NAME_MAP.get(longhand);
|
|
30571
30704
|
if (name === void 0) continue;
|
|
30572
|
-
out.set(name, createUnknown(name, declaration.
|
|
30705
|
+
out.set(name, createUnknown(name, declaration.source, declaration.guardProvenance, reason));
|
|
30573
30706
|
}
|
|
30574
30707
|
return;
|
|
30575
30708
|
}
|
|
@@ -30579,127 +30712,139 @@ function applyExpandedShorthand(out, property, declaration, fontSizePx) {
|
|
|
30579
30712
|
if (!entry) continue;
|
|
30580
30713
|
const name = MONITORED_SIGNAL_NAME_MAP.get(entry.name);
|
|
30581
30714
|
if (name === void 0) continue;
|
|
30582
|
-
out.set(name, normalizeSignal(name, entry.value, declaration.source, declaration.
|
|
30715
|
+
out.set(name, normalizeSignal(name, entry.value, declaration.source, declaration.guardProvenance, fontSizePx));
|
|
30583
30716
|
}
|
|
30584
30717
|
}
|
|
30585
30718
|
function toMonitoredSignalName(property) {
|
|
30586
30719
|
return MONITORED_SIGNAL_NAME_MAP.get(property) ?? null;
|
|
30587
30720
|
}
|
|
30588
|
-
function normalizeSignal(name, raw, source, guard,
|
|
30721
|
+
function normalizeSignal(name, raw, source, guard, fontSizePx) {
|
|
30589
30722
|
switch (name) {
|
|
30590
30723
|
case "line-height":
|
|
30591
|
-
return parseLineHeight(name, raw, source, guard,
|
|
30724
|
+
return parseLineHeight(name, raw, source, guard, fontSizePx);
|
|
30592
30725
|
case "aspect-ratio":
|
|
30593
|
-
return parseAspectRatio(name, raw, source, guard
|
|
30726
|
+
return parseAspectRatio(name, raw, source, guard);
|
|
30594
30727
|
case "contain-intrinsic-size":
|
|
30595
|
-
return parseContainIntrinsicSize(name, raw, source, guard
|
|
30728
|
+
return parseContainIntrinsicSize(name, raw, source, guard);
|
|
30596
30729
|
case "transform":
|
|
30597
|
-
return parseTransform(name, raw, source, guard
|
|
30730
|
+
return parseTransform(name, raw, source, guard);
|
|
30598
30731
|
case "translate":
|
|
30599
|
-
return parseTranslateProperty(name, raw, source, guard
|
|
30732
|
+
return parseTranslateProperty(name, raw, source, guard);
|
|
30600
30733
|
default:
|
|
30601
30734
|
break;
|
|
30602
30735
|
}
|
|
30603
|
-
if (LENGTH_SIGNAL_SET.has(name)) return parseLength(name, raw, source, guard
|
|
30604
|
-
if (KEYWORD_SIGNAL_SET.has(name)) return parseKeyword(name, raw, source, guard
|
|
30605
|
-
return createUnknown(name,
|
|
30736
|
+
if (LENGTH_SIGNAL_SET.has(name)) return parseLength(name, raw, source, guard);
|
|
30737
|
+
if (KEYWORD_SIGNAL_SET.has(name)) return parseKeyword(name, raw, source, guard);
|
|
30738
|
+
return createUnknown(name, source, guard, "unsupported signal");
|
|
30606
30739
|
}
|
|
30607
|
-
function parseAspectRatio(name, raw, source, guard
|
|
30740
|
+
function parseAspectRatio(name, raw, source, guard) {
|
|
30608
30741
|
const trimmed = raw.trim().toLowerCase();
|
|
30609
30742
|
if (trimmed.length === 0) {
|
|
30610
|
-
return createUnknown(name,
|
|
30743
|
+
return createUnknown(name, source, guard, "aspect-ratio value is empty");
|
|
30611
30744
|
}
|
|
30612
30745
|
if (hasDynamicExpression(trimmed)) {
|
|
30613
|
-
return createUnknown(name,
|
|
30746
|
+
return createUnknown(name, source, guard, "aspect-ratio uses runtime-dependent function");
|
|
30614
30747
|
}
|
|
30615
30748
|
if (trimmed === "auto") {
|
|
30616
|
-
return createUnknown(name,
|
|
30749
|
+
return createUnknown(name, source, guard, "aspect-ratio auto does not reserve ratio");
|
|
30617
30750
|
}
|
|
30618
30751
|
const slash = trimmed.indexOf("/");
|
|
30619
30752
|
if (slash !== -1) {
|
|
30620
30753
|
const left = Number(trimmed.slice(0, slash).trim());
|
|
30621
30754
|
const right = Number(trimmed.slice(slash + 1).trim());
|
|
30622
30755
|
if (!Number.isFinite(left) || !Number.isFinite(right) || left <= 0 || right <= 0) {
|
|
30623
|
-
return createUnknown(name,
|
|
30756
|
+
return createUnknown(name, source, guard, "aspect-ratio ratio is invalid");
|
|
30624
30757
|
}
|
|
30625
|
-
return createKnown(name, raw, source, guard,
|
|
30758
|
+
return createKnown(name, raw, source, guard, null, 1 /* Unitless */, "exact");
|
|
30626
30759
|
}
|
|
30627
30760
|
const ratio = Number(trimmed);
|
|
30628
30761
|
if (!Number.isFinite(ratio) || ratio <= 0) {
|
|
30629
|
-
return createUnknown(name,
|
|
30762
|
+
return createUnknown(name, source, guard, "aspect-ratio is not statically parseable");
|
|
30630
30763
|
}
|
|
30631
|
-
return createKnown(name, raw, source, guard,
|
|
30764
|
+
return createKnown(name, raw, source, guard, null, 1 /* Unitless */, "exact");
|
|
30632
30765
|
}
|
|
30633
|
-
function parseContainIntrinsicSize(name, raw, source, guard
|
|
30766
|
+
function parseContainIntrinsicSize(name, raw, source, guard) {
|
|
30634
30767
|
const trimmed = raw.trim().toLowerCase();
|
|
30635
30768
|
if (trimmed.length === 0) {
|
|
30636
|
-
return createUnknown(name,
|
|
30769
|
+
return createUnknown(name, source, guard, "contain-intrinsic-size value is empty");
|
|
30637
30770
|
}
|
|
30638
30771
|
if (hasDynamicExpression(trimmed)) {
|
|
30639
|
-
return createUnknown(name,
|
|
30772
|
+
return createUnknown(name, source, guard, "contain-intrinsic-size uses runtime-dependent function");
|
|
30640
30773
|
}
|
|
30641
30774
|
if (trimmed === "none" || trimmed === "auto") {
|
|
30642
|
-
return createUnknown(name,
|
|
30775
|
+
return createUnknown(name, source, guard, "contain-intrinsic-size does not reserve space");
|
|
30643
30776
|
}
|
|
30644
30777
|
const parts = splitWhitespaceTokens(trimmed);
|
|
30645
30778
|
for (let i = 0; i < parts.length; i++) {
|
|
30646
30779
|
const part = parts[i];
|
|
30647
30780
|
if (!part) continue;
|
|
30648
30781
|
const px = parseSignedPxValue(part);
|
|
30649
|
-
if (px !== null) return createKnown(name, raw, source, guard,
|
|
30782
|
+
if (px !== null) return createKnown(name, raw, source, guard, px, 0 /* Px */, "exact");
|
|
30650
30783
|
}
|
|
30651
|
-
return createUnknown(name,
|
|
30784
|
+
return createUnknown(name, source, guard, "contain-intrinsic-size is not statically parseable in px");
|
|
30652
30785
|
}
|
|
30653
|
-
function parseLineHeight(name, raw, source, guard,
|
|
30786
|
+
function parseLineHeight(name, raw, source, guard, fontSizePx) {
|
|
30654
30787
|
const unitless = parseUnitlessValue(raw);
|
|
30655
30788
|
if (unitless !== null) {
|
|
30656
30789
|
const base = fontSizePx === null ? 16 : fontSizePx;
|
|
30657
|
-
return createKnown(name, raw, source, guard,
|
|
30790
|
+
return createKnown(name, raw, source, guard, unitless * base, 1 /* Unitless */, "estimated");
|
|
30658
30791
|
}
|
|
30659
30792
|
const px = parseSignedPxValue(raw);
|
|
30660
|
-
if (px !== null) return createKnown(name, raw, source, guard,
|
|
30661
|
-
return createUnknown(name,
|
|
30793
|
+
if (px !== null) return createKnown(name, raw, source, guard, px, 0 /* Px */, "exact");
|
|
30794
|
+
return createUnknown(name, source, guard, "line-height is not statically parseable");
|
|
30662
30795
|
}
|
|
30663
|
-
|
|
30796
|
+
var DIMENSION_KEYWORD_SET = /* @__PURE__ */ new Set([
|
|
30797
|
+
"auto",
|
|
30798
|
+
"none",
|
|
30799
|
+
"fit-content",
|
|
30800
|
+
"min-content",
|
|
30801
|
+
"max-content",
|
|
30802
|
+
"stretch"
|
|
30803
|
+
]);
|
|
30804
|
+
function parseLength(name, raw, source, guard) {
|
|
30664
30805
|
const px = parseSignedPxValue(raw);
|
|
30665
|
-
if (px
|
|
30666
|
-
return
|
|
30806
|
+
if (px !== null) {
|
|
30807
|
+
return createKnown(name, raw, source, guard, px, 0 /* Px */, "exact");
|
|
30667
30808
|
}
|
|
30668
|
-
|
|
30809
|
+
const normalized = raw.trim().toLowerCase();
|
|
30810
|
+
if (DIMENSION_KEYWORD_SET.has(normalized) || normalized.startsWith("fit-content(")) {
|
|
30811
|
+
return createKnown(name, raw, source, guard, null, 2 /* Keyword */, "exact");
|
|
30812
|
+
}
|
|
30813
|
+
return createUnknown(name, source, guard, "length is not statically parseable in px");
|
|
30669
30814
|
}
|
|
30670
|
-
function parseKeyword(name, raw, source, guard
|
|
30815
|
+
function parseKeyword(name, raw, source, guard) {
|
|
30671
30816
|
const normalized = raw.trim().toLowerCase();
|
|
30672
30817
|
if (normalized.length === 0) {
|
|
30673
|
-
return createUnknown(name,
|
|
30818
|
+
return createUnknown(name, source, guard, "keyword value is empty");
|
|
30674
30819
|
}
|
|
30675
30820
|
if (hasDynamicExpression(normalized)) {
|
|
30676
|
-
return createUnknown(name,
|
|
30821
|
+
return createUnknown(name, source, guard, "keyword uses runtime-dependent function");
|
|
30677
30822
|
}
|
|
30678
|
-
return createKnown(name, raw, source, guard,
|
|
30823
|
+
return createKnown(name, raw, source, guard, null, 2 /* Keyword */, "exact");
|
|
30679
30824
|
}
|
|
30680
|
-
function parseTransform(name, raw, source, guard
|
|
30825
|
+
function parseTransform(name, raw, source, guard) {
|
|
30681
30826
|
const normalized = raw.trim().toLowerCase();
|
|
30682
30827
|
if (normalized.length === 0) {
|
|
30683
|
-
return createUnknown(name,
|
|
30828
|
+
return createUnknown(name, source, guard, "transform value is empty");
|
|
30684
30829
|
}
|
|
30685
30830
|
if (hasDynamicExpression(normalized)) {
|
|
30686
|
-
return createUnknown(name,
|
|
30831
|
+
return createUnknown(name, source, guard, "transform uses runtime-dependent function");
|
|
30687
30832
|
}
|
|
30688
30833
|
const y = extractTransformYPx(normalized);
|
|
30689
|
-
if (y !== null) return createKnown(name, raw, source, guard,
|
|
30690
|
-
return createUnknown(name,
|
|
30834
|
+
if (y !== null) return createKnown(name, raw, source, guard, y, 0 /* Px */, "exact");
|
|
30835
|
+
return createUnknown(name, source, guard, "transform has non-translational or non-px functions");
|
|
30691
30836
|
}
|
|
30692
|
-
function parseTranslateProperty(name, raw, source, guard
|
|
30837
|
+
function parseTranslateProperty(name, raw, source, guard) {
|
|
30693
30838
|
const trimmed = raw.trim().toLowerCase();
|
|
30694
30839
|
if (trimmed.length === 0) {
|
|
30695
|
-
return createUnknown(name,
|
|
30840
|
+
return createUnknown(name, source, guard, "translate value is empty");
|
|
30696
30841
|
}
|
|
30697
30842
|
if (hasDynamicExpression(trimmed)) {
|
|
30698
|
-
return createUnknown(name,
|
|
30843
|
+
return createUnknown(name, source, guard, "translate uses runtime-dependent function");
|
|
30699
30844
|
}
|
|
30700
30845
|
const y = extractTranslatePropertyYPx(trimmed);
|
|
30701
|
-
if (y !== null) return createKnown(name, raw, source, guard,
|
|
30702
|
-
return createUnknown(name,
|
|
30846
|
+
if (y !== null) return createKnown(name, raw, source, guard, y, 0 /* Px */, "exact");
|
|
30847
|
+
return createUnknown(name, source, guard, "translate property vertical component is not px");
|
|
30703
30848
|
}
|
|
30704
30849
|
function hasDynamicExpression(raw) {
|
|
30705
30850
|
if (raw.includes("var(")) return true;
|
|
@@ -30711,28 +30856,24 @@ function hasDynamicExpression(raw) {
|
|
|
30711
30856
|
if (raw.includes("clamp(")) return true;
|
|
30712
30857
|
return false;
|
|
30713
30858
|
}
|
|
30714
|
-
function createKnown(name, raw, source, guard,
|
|
30859
|
+
function createKnown(name, raw, source, guard, px, unit, quality) {
|
|
30715
30860
|
return {
|
|
30716
30861
|
kind: "known",
|
|
30717
30862
|
name,
|
|
30718
|
-
raw,
|
|
30719
30863
|
normalized: raw.trim().toLowerCase(),
|
|
30720
30864
|
source,
|
|
30721
30865
|
guard,
|
|
30722
|
-
guardProvenance,
|
|
30723
30866
|
unit,
|
|
30724
30867
|
px,
|
|
30725
30868
|
quality
|
|
30726
30869
|
};
|
|
30727
30870
|
}
|
|
30728
|
-
function createUnknown(name,
|
|
30871
|
+
function createUnknown(name, source, guard, reason) {
|
|
30729
30872
|
return {
|
|
30730
30873
|
kind: "unknown",
|
|
30731
30874
|
name,
|
|
30732
|
-
raw,
|
|
30733
30875
|
source,
|
|
30734
30876
|
guard,
|
|
30735
|
-
guardProvenance,
|
|
30736
30877
|
reason
|
|
30737
30878
|
};
|
|
30738
30879
|
}
|
|
@@ -30779,13 +30920,7 @@ function buildSnapshotForNode(node, cascadeByElementNode, snapshotByElementNode,
|
|
|
30779
30920
|
const unknownSignalCount = normalized.unknownSignalCount + inherited.unknownDelta;
|
|
30780
30921
|
const conditionalSignalCount = normalized.conditionalSignalCount + inherited.conditionalDelta;
|
|
30781
30922
|
const snapshot = {
|
|
30782
|
-
|
|
30783
|
-
elementId: node.elementId,
|
|
30784
|
-
elementKey: node.key,
|
|
30785
|
-
tag: node.tag,
|
|
30786
|
-
textualContent: node.textualContent,
|
|
30787
|
-
isControl: node.isControl,
|
|
30788
|
-
isReplaced: node.isReplaced,
|
|
30923
|
+
node,
|
|
30789
30924
|
signals: inherited.signals,
|
|
30790
30925
|
knownSignalCount,
|
|
30791
30926
|
unknownSignalCount,
|
|
@@ -30816,7 +30951,7 @@ function inheritSignalsFromParent(parentSnapshot, local) {
|
|
|
30816
30951
|
if (!inheritedValue) continue;
|
|
30817
30952
|
if (out === null) out = new Map(local);
|
|
30818
30953
|
out.set(signal, inheritedValue);
|
|
30819
|
-
if (inheritedValue.guard ===
|
|
30954
|
+
if (inheritedValue.guard.kind === 1 /* Conditional */) {
|
|
30820
30955
|
conditionalDelta++;
|
|
30821
30956
|
continue;
|
|
30822
30957
|
}
|
|
@@ -30860,7 +30995,7 @@ var EMPTY_LAYOUT_RESERVED_SPACE_FACT = Object.freeze({
|
|
|
30860
30995
|
});
|
|
30861
30996
|
var EMPTY_LAYOUT_SCROLL_CONTAINER_FACT = Object.freeze({
|
|
30862
30997
|
isScrollContainer: false,
|
|
30863
|
-
axis:
|
|
30998
|
+
axis: 0 /* None */,
|
|
30864
30999
|
overflow: null,
|
|
30865
31000
|
overflowY: null,
|
|
30866
31001
|
hasConditionalScroll: false,
|
|
@@ -30893,53 +31028,28 @@ function readKnownSignalWithGuard(snapshot, name) {
|
|
|
30893
31028
|
return value2;
|
|
30894
31029
|
}
|
|
30895
31030
|
function toEvidenceKind(value2) {
|
|
30896
|
-
if (value2.guard ===
|
|
30897
|
-
if (value2.quality === "estimated") return
|
|
30898
|
-
return
|
|
30899
|
-
}
|
|
30900
|
-
function readNumericSignalEvidence(snapshot, name) {
|
|
30901
|
-
const value2 = snapshot.signals.get(name);
|
|
30902
|
-
if (!value2) {
|
|
30903
|
-
return {
|
|
30904
|
-
value: null,
|
|
30905
|
-
kind: "unknown"
|
|
30906
|
-
};
|
|
30907
|
-
}
|
|
30908
|
-
if (value2.kind !== "known") {
|
|
30909
|
-
if (value2.guard === "conditional") {
|
|
30910
|
-
return {
|
|
30911
|
-
value: null,
|
|
30912
|
-
kind: "conditional"
|
|
30913
|
-
};
|
|
30914
|
-
}
|
|
30915
|
-
return {
|
|
30916
|
-
value: null,
|
|
30917
|
-
kind: "unknown"
|
|
30918
|
-
};
|
|
30919
|
-
}
|
|
30920
|
-
return {
|
|
30921
|
-
value: value2.px,
|
|
30922
|
-
kind: toEvidenceKind(value2)
|
|
30923
|
-
};
|
|
31031
|
+
if (value2.guard.kind === 1 /* Conditional */) return 2 /* Conditional */;
|
|
31032
|
+
if (value2.quality === "estimated") return 1 /* Interval */;
|
|
31033
|
+
return 0 /* Exact */;
|
|
30924
31034
|
}
|
|
30925
31035
|
function readNormalizedSignalEvidence(snapshot, name) {
|
|
30926
31036
|
const value2 = snapshot.signals.get(name);
|
|
30927
31037
|
if (!value2) {
|
|
30928
31038
|
return {
|
|
30929
31039
|
value: null,
|
|
30930
|
-
kind:
|
|
31040
|
+
kind: 3 /* Unknown */
|
|
30931
31041
|
};
|
|
30932
31042
|
}
|
|
30933
31043
|
if (value2.kind !== "known") {
|
|
30934
|
-
if (value2.guard ===
|
|
31044
|
+
if (value2.guard.kind === 1 /* Conditional */) {
|
|
30935
31045
|
return {
|
|
30936
31046
|
value: null,
|
|
30937
|
-
kind:
|
|
31047
|
+
kind: 2 /* Conditional */
|
|
30938
31048
|
};
|
|
30939
31049
|
}
|
|
30940
31050
|
return {
|
|
30941
31051
|
value: null,
|
|
30942
|
-
kind:
|
|
31052
|
+
kind: 3 /* Unknown */
|
|
30943
31053
|
};
|
|
30944
31054
|
}
|
|
30945
31055
|
return {
|
|
@@ -30950,7 +31060,7 @@ function readNormalizedSignalEvidence(snapshot, name) {
|
|
|
30950
31060
|
function readKnownSignal(snapshot, name) {
|
|
30951
31061
|
const value2 = readKnownSignalWithGuard(snapshot, name);
|
|
30952
31062
|
if (!value2) return null;
|
|
30953
|
-
if (value2.guard !==
|
|
31063
|
+
if (value2.guard.kind !== 0 /* Unconditional */) return null;
|
|
30954
31064
|
return value2;
|
|
30955
31065
|
}
|
|
30956
31066
|
function readKnownPx(snapshot, name) {
|
|
@@ -30984,19 +31094,19 @@ function hasEffectivePosition(snapshot) {
|
|
|
30984
31094
|
return position !== "static";
|
|
30985
31095
|
}
|
|
30986
31096
|
function readReservedSpaceFact(graph, node) {
|
|
30987
|
-
return graph.
|
|
31097
|
+
return graph.reservedSpaceFactsByNode.get(node) ?? EMPTY_LAYOUT_RESERVED_SPACE_FACT;
|
|
30988
31098
|
}
|
|
30989
31099
|
function readScrollContainerFact(graph, node) {
|
|
30990
|
-
return graph.
|
|
31100
|
+
return graph.scrollContainerFactsByNode.get(node) ?? EMPTY_LAYOUT_SCROLL_CONTAINER_FACT;
|
|
30991
31101
|
}
|
|
30992
31102
|
function readFlowParticipationFact(graph, node) {
|
|
30993
|
-
return graph.
|
|
31103
|
+
return graph.flowParticipationFactsByNode.get(node) ?? EMPTY_LAYOUT_FLOW_PARTICIPATION_FACT;
|
|
30994
31104
|
}
|
|
30995
31105
|
function readContainingBlockFact(graph, node) {
|
|
30996
|
-
return graph.
|
|
31106
|
+
return graph.containingBlockFactsByNode.get(node) ?? EMPTY_LAYOUT_CONTAINING_BLOCK_FACT;
|
|
30997
31107
|
}
|
|
30998
31108
|
function readConditionalSignalDeltaFact(graph, node, name) {
|
|
30999
|
-
const byProperty = graph.
|
|
31109
|
+
const byProperty = graph.conditionalSignalDeltaFactsByNode.get(node);
|
|
31000
31110
|
if (!byProperty) return EMPTY_LAYOUT_CONDITIONAL_DELTA_FACT;
|
|
31001
31111
|
return byProperty.get(name) ?? EMPTY_LAYOUT_CONDITIONAL_DELTA_FACT;
|
|
31002
31112
|
}
|
|
@@ -31024,7 +31134,7 @@ function readScrollContainerElements(graph) {
|
|
|
31024
31134
|
return graph.scrollContainerElements;
|
|
31025
31135
|
}
|
|
31026
31136
|
function readBaselineOffsetFacts(graph, node) {
|
|
31027
|
-
return graph.
|
|
31137
|
+
return graph.baselineOffsetFactsByNode.get(node) ?? EMPTY_BASELINE_FACTS;
|
|
31028
31138
|
}
|
|
31029
31139
|
function readElementRef(graph, node) {
|
|
31030
31140
|
return readElementRefById(graph, node.solidFile, node.elementId);
|
|
@@ -31046,7 +31156,6 @@ function readStatefulBaseValueIndex(graph) {
|
|
|
31046
31156
|
}
|
|
31047
31157
|
|
|
31048
31158
|
// src/cross-file/layout/context-classification.ts
|
|
31049
|
-
var WHITESPACE_RE3 = /\s+/;
|
|
31050
31159
|
var TABLE_SEMANTIC_TAGS = /* @__PURE__ */ new Set(["table", "thead", "tbody", "tfoot", "tr", "td", "th"]);
|
|
31051
31160
|
var TABLE_DISPLAY_VALUES = /* @__PURE__ */ new Set([
|
|
31052
31161
|
"table",
|
|
@@ -31063,7 +31172,6 @@ var TABLE_DISPLAY_VALUES = /* @__PURE__ */ new Set([
|
|
|
31063
31172
|
var FLEX_DISPLAY_VALUES = /* @__PURE__ */ new Set(["flex", "inline-flex"]);
|
|
31064
31173
|
var GRID_DISPLAY_VALUES = /* @__PURE__ */ new Set(["grid", "inline-grid"]);
|
|
31065
31174
|
var INLINE_DISPLAY_VALUES = /* @__PURE__ */ new Set(["inline", "inline-block", "inline-list-item"]);
|
|
31066
|
-
var DISPLAY_TOKEN_SPLIT_RE = /\s+/;
|
|
31067
31175
|
function createAlignmentContextForParent(parent, snapshot) {
|
|
31068
31176
|
const axis = resolveAxis(snapshot);
|
|
31069
31177
|
const inlineDirection = resolveInlineDirection(snapshot);
|
|
@@ -31086,6 +31194,7 @@ function createAlignmentContextForParent(parent, snapshot) {
|
|
|
31086
31194
|
const contextCertainty = combineCertainty(classified.certainty, axis.certainty);
|
|
31087
31195
|
const certainty = combineCertainty(contextCertainty, inlineDirection.certainty);
|
|
31088
31196
|
const baselineRelevance = computeBaselineRelevance(classified.kind, parentAlignItems, parentPlaceItems);
|
|
31197
|
+
const crossAxisInfo = resolveCrossAxisIsBlockAxis(classified.kind, snapshot, axis.value);
|
|
31089
31198
|
const out = {
|
|
31090
31199
|
kind: classified.kind,
|
|
31091
31200
|
certainty,
|
|
@@ -31101,6 +31210,8 @@ function createAlignmentContextForParent(parent, snapshot) {
|
|
|
31101
31210
|
parentAlignItems,
|
|
31102
31211
|
parentPlaceItems,
|
|
31103
31212
|
hasPositionedOffset: positionedOffset.hasPositionedOffset,
|
|
31213
|
+
crossAxisIsBlockAxis: crossAxisInfo.value,
|
|
31214
|
+
crossAxisIsBlockAxisCertainty: crossAxisInfo.certainty,
|
|
31104
31215
|
baselineRelevance,
|
|
31105
31216
|
evidence
|
|
31106
31217
|
};
|
|
@@ -31110,7 +31221,7 @@ function classifyKind(evidence) {
|
|
|
31110
31221
|
if (evidence.hasTableSemantics) {
|
|
31111
31222
|
return {
|
|
31112
31223
|
kind: "table-cell",
|
|
31113
|
-
certainty:
|
|
31224
|
+
certainty: 0 /* Resolved */
|
|
31114
31225
|
};
|
|
31115
31226
|
}
|
|
31116
31227
|
if (evidence.containerKind === "table") {
|
|
@@ -31197,7 +31308,7 @@ function resolveContainerKind(parentDisplay, certainty) {
|
|
|
31197
31308
|
certainty
|
|
31198
31309
|
};
|
|
31199
31310
|
}
|
|
31200
|
-
const tokens = display.split(
|
|
31311
|
+
const tokens = display.split(WHITESPACE_RE3);
|
|
31201
31312
|
if (tokens.length === 2) {
|
|
31202
31313
|
const outside = tokens[0];
|
|
31203
31314
|
const inside = tokens[1];
|
|
@@ -31247,7 +31358,7 @@ function resolveAxis(snapshot) {
|
|
|
31247
31358
|
if (!snapshot.signals.has("writing-mode")) {
|
|
31248
31359
|
return {
|
|
31249
31360
|
value: "horizontal-tb",
|
|
31250
|
-
certainty:
|
|
31361
|
+
certainty: 0 /* Resolved */
|
|
31251
31362
|
};
|
|
31252
31363
|
}
|
|
31253
31364
|
const writingMode = readNormalizedSignalEvidence(snapshot, "writing-mode");
|
|
@@ -31272,7 +31383,7 @@ function resolveInlineDirection(snapshot) {
|
|
|
31272
31383
|
if (!snapshot.signals.has("direction")) {
|
|
31273
31384
|
return {
|
|
31274
31385
|
value: "ltr",
|
|
31275
|
-
certainty:
|
|
31386
|
+
certainty: 0 /* Resolved */
|
|
31276
31387
|
};
|
|
31277
31388
|
}
|
|
31278
31389
|
const direction = readNormalizedSignalEvidence(snapshot, "direction");
|
|
@@ -31288,16 +31399,16 @@ function resolveInlineDirection(snapshot) {
|
|
|
31288
31399
|
};
|
|
31289
31400
|
}
|
|
31290
31401
|
function toContextCertainty(kind) {
|
|
31291
|
-
if (kind ===
|
|
31292
|
-
if (kind ===
|
|
31293
|
-
return
|
|
31402
|
+
if (kind === 0 /* Exact */) return 0 /* Resolved */;
|
|
31403
|
+
if (kind === 1 /* Interval */ || kind === 2 /* Conditional */) return 1 /* Conditional */;
|
|
31404
|
+
return 2 /* Unknown */;
|
|
31294
31405
|
}
|
|
31295
31406
|
function resolvePositionedOffset(snapshot) {
|
|
31296
31407
|
const position = readKnownSignalWithGuard(snapshot, "position");
|
|
31297
31408
|
if (!position) {
|
|
31298
31409
|
return {
|
|
31299
31410
|
hasPositionedOffset: false,
|
|
31300
|
-
certainty:
|
|
31411
|
+
certainty: 2 /* Unknown */
|
|
31301
31412
|
};
|
|
31302
31413
|
}
|
|
31303
31414
|
const certainty = resolveSignalCertainty(position);
|
|
@@ -31312,15 +31423,33 @@ function resolvePositionedOffset(snapshot) {
|
|
|
31312
31423
|
certainty
|
|
31313
31424
|
};
|
|
31314
31425
|
}
|
|
31426
|
+
var FLEX_ROW_VALUES = /* @__PURE__ */ new Set(["row", "row-reverse"]);
|
|
31427
|
+
function resolveCrossAxisIsBlockAxis(kind, snapshot, _axis) {
|
|
31428
|
+
if (kind !== "flex-cross-axis" && kind !== "grid-cross-axis") {
|
|
31429
|
+
return { value: true, certainty: 0 /* Resolved */ };
|
|
31430
|
+
}
|
|
31431
|
+
if (kind === "flex-cross-axis") {
|
|
31432
|
+
const signal2 = readKnownSignalWithGuard(snapshot, "flex-direction");
|
|
31433
|
+
if (!signal2) {
|
|
31434
|
+
return { value: true, certainty: 0 /* Resolved */ };
|
|
31435
|
+
}
|
|
31436
|
+
const certainty2 = resolveSignalCertainty(signal2);
|
|
31437
|
+
return { value: FLEX_ROW_VALUES.has(signal2.normalized), certainty: certainty2 };
|
|
31438
|
+
}
|
|
31439
|
+
const signal = readKnownSignalWithGuard(snapshot, "grid-auto-flow");
|
|
31440
|
+
if (!signal) {
|
|
31441
|
+
return { value: true, certainty: 0 /* Resolved */ };
|
|
31442
|
+
}
|
|
31443
|
+
const certainty = resolveSignalCertainty(signal);
|
|
31444
|
+
return { value: !signal.normalized.startsWith("column"), certainty };
|
|
31445
|
+
}
|
|
31315
31446
|
function resolveSignalCertainty(value2) {
|
|
31316
|
-
if (!value2) return
|
|
31317
|
-
if (value2.guard ===
|
|
31318
|
-
return
|
|
31447
|
+
if (!value2) return 2 /* Unknown */;
|
|
31448
|
+
if (value2.guard.kind === 1 /* Conditional */) return 1 /* Conditional */;
|
|
31449
|
+
return 0 /* Resolved */;
|
|
31319
31450
|
}
|
|
31320
31451
|
function combineCertainty(left, right) {
|
|
31321
|
-
|
|
31322
|
-
if (left === "conditional" || right === "conditional") return "conditional";
|
|
31323
|
-
return "resolved";
|
|
31452
|
+
return left > right ? left : right;
|
|
31324
31453
|
}
|
|
31325
31454
|
var FLEX_GRID_GEOMETRIC_ALIGN_ITEMS = /* @__PURE__ */ new Set([
|
|
31326
31455
|
"center",
|
|
@@ -31359,24 +31488,7 @@ function finalizeTableCellBaselineRelevance(contextByParentNode, cohortVerticalA
|
|
|
31359
31488
|
if (context.kind !== "table-cell") continue;
|
|
31360
31489
|
if (consensusValue === null) continue;
|
|
31361
31490
|
if (!TABLE_CELL_GEOMETRIC_VERTICAL_ALIGN.has(consensusValue)) continue;
|
|
31362
|
-
contextByParentNode.set(parent, {
|
|
31363
|
-
kind: context.kind,
|
|
31364
|
-
certainty: context.certainty,
|
|
31365
|
-
parentSolidFile: context.parentSolidFile,
|
|
31366
|
-
parentElementId: context.parentElementId,
|
|
31367
|
-
parentElementKey: context.parentElementKey,
|
|
31368
|
-
parentTag: context.parentTag,
|
|
31369
|
-
axis: context.axis,
|
|
31370
|
-
axisCertainty: context.axisCertainty,
|
|
31371
|
-
inlineDirection: context.inlineDirection,
|
|
31372
|
-
inlineDirectionCertainty: context.inlineDirectionCertainty,
|
|
31373
|
-
parentDisplay: context.parentDisplay,
|
|
31374
|
-
parentAlignItems: context.parentAlignItems,
|
|
31375
|
-
parentPlaceItems: context.parentPlaceItems,
|
|
31376
|
-
hasPositionedOffset: context.hasPositionedOffset,
|
|
31377
|
-
baselineRelevance: "irrelevant",
|
|
31378
|
-
evidence: context.evidence
|
|
31379
|
-
});
|
|
31491
|
+
contextByParentNode.set(parent, deriveAlignmentContext(context, { baselineRelevance: "irrelevant" }));
|
|
31380
31492
|
}
|
|
31381
31493
|
}
|
|
31382
31494
|
|
|
@@ -31923,6 +32035,20 @@ function collectTransitiveCSSScope(entryPath, resolver, cssFilesByNormalizedPath
|
|
|
31923
32035
|
}
|
|
31924
32036
|
|
|
31925
32037
|
// src/cross-file/layout/perf.ts
|
|
32038
|
+
function createReservoir(capacity) {
|
|
32039
|
+
return { buffer: [], count: 0, capacity };
|
|
32040
|
+
}
|
|
32041
|
+
function reservoirPush(r, value2) {
|
|
32042
|
+
r.count++;
|
|
32043
|
+
if (r.buffer.length < r.capacity) {
|
|
32044
|
+
r.buffer.push(value2);
|
|
32045
|
+
return;
|
|
32046
|
+
}
|
|
32047
|
+
const j = Math.floor(Math.random() * r.count);
|
|
32048
|
+
if (j < r.capacity) {
|
|
32049
|
+
r.buffer[j] = value2;
|
|
32050
|
+
}
|
|
32051
|
+
}
|
|
31926
32052
|
var EMPTY_STATS = {
|
|
31927
32053
|
elementsScanned: 0,
|
|
31928
32054
|
selectorCandidatesChecked: 0,
|
|
@@ -31979,7 +32105,7 @@ function createLayoutPerfStats() {
|
|
|
31979
32105
|
cohortUnimodalFalse: 0,
|
|
31980
32106
|
factorCoverageSum: 0,
|
|
31981
32107
|
factorCoverageCount: 0,
|
|
31982
|
-
posteriorWidths:
|
|
32108
|
+
posteriorWidths: createReservoir(200),
|
|
31983
32109
|
uncertaintyEscalations: 0,
|
|
31984
32110
|
signalSnapshotsBuilt: 0,
|
|
31985
32111
|
signalSnapshotCacheHits: 0,
|
|
@@ -32044,14 +32170,12 @@ function maybeLogLayoutPerf(stats, log) {
|
|
|
32044
32170
|
`[layout] elements=${view.elementsScanned} candidates=${view.selectorCandidatesChecked} compiledSelectors=${view.compiledSelectorCount} unsupportedSelectors=${view.selectorsRejectedUnsupported} conditionalSelectors=${view.selectorsGuardedConditional} ancestryChecks=${view.ancestryChecks} edges=${view.matchEdgesCreated} collected=${view.casesCollected} cases=${view.casesScored} rejectLowEvidence=${view.casesRejectedLowEvidence} rejectThreshold=${view.casesRejectedThreshold} rejectUndecidable=${view.casesRejectedUndecidable} rejectIdentifiability=${view.casesRejectedIdentifiability} undecidableInterval=${view.undecidableInterval} conditionalSignalRatio=${Math.round(view.conditionalSignalRatio * 1e3) / 1e3} conditionalSignals=${view.conditionalSignals} totalSignals=${view.totalSignals} cohortUnimodalFalse=${view.cohortUnimodalFalse} factorCoverageMean=${Math.round(view.factorCoverageMean * 1e3) / 1e3} posteriorWidthP95=${Math.round(view.posteriorWidthP95 * 1e3) / 1e3} uncertaintyEscalations=${view.uncertaintyEscalations} snapshots=${view.signalSnapshotsBuilt} snapshotHits=${view.signalSnapshotCacheHits} measurementIndexHits=${view.measurementIndexHits} contexts=${view.contextsClassified} diagnostics=${view.diagnosticsEmitted} selectorIndexMs=${Math.round(view.selectorIndexMs * 100) / 100} selectorMatchMs=${Math.round(view.selectorMatchMs * 100) / 100} cascadeBuildMs=${Math.round(view.cascadeBuildMs * 100) / 100} caseBuildMs=${Math.round(view.caseBuildMs * 100) / 100} scoringMs=${Math.round(view.scoringMs * 100) / 100} elapsedMs=${Math.round(view.elapsedMs * 100) / 100}`
|
|
32045
32171
|
);
|
|
32046
32172
|
}
|
|
32047
|
-
function computeP95(
|
|
32048
|
-
if (
|
|
32049
|
-
const
|
|
32050
|
-
|
|
32051
|
-
const
|
|
32052
|
-
|
|
32053
|
-
if (index >= sorted.length) return sorted[sorted.length - 1] ?? 0;
|
|
32054
|
-
return sorted[index] ?? 0;
|
|
32173
|
+
function computeP95(sampler) {
|
|
32174
|
+
if (sampler.buffer.length === 0) return 0;
|
|
32175
|
+
const scratch = [...sampler.buffer];
|
|
32176
|
+
const index = Math.ceil(scratch.length * 0.95) - 1;
|
|
32177
|
+
const clamped = index <= 0 ? 0 : index >= scratch.length ? scratch.length - 1 : index;
|
|
32178
|
+
return selectKth(scratch, clamped);
|
|
32055
32179
|
}
|
|
32056
32180
|
|
|
32057
32181
|
// src/cross-file/layout/component-host.ts
|
|
@@ -34021,16 +34145,16 @@ function includesAttributeWord(value2, word) {
|
|
|
34021
34145
|
|
|
34022
34146
|
// src/cross-file/layout/guard-model.ts
|
|
34023
34147
|
var UNCONDITIONAL_GUARD = {
|
|
34024
|
-
kind:
|
|
34148
|
+
kind: 0 /* Unconditional */,
|
|
34025
34149
|
conditions: [],
|
|
34026
34150
|
key: "always"
|
|
34027
34151
|
};
|
|
34028
|
-
var
|
|
34152
|
+
var WHITESPACE_RE_GLOBAL = /\s+/g;
|
|
34029
34153
|
function resolveRuleGuard(rule) {
|
|
34030
34154
|
const conditions = collectRuleConditions(rule);
|
|
34031
34155
|
if (conditions.length === 0) return UNCONDITIONAL_GUARD;
|
|
34032
34156
|
return {
|
|
34033
|
-
kind:
|
|
34157
|
+
kind: 1 /* Conditional */,
|
|
34034
34158
|
conditions,
|
|
34035
34159
|
key: conditions.map((condition) => condition.key).join("&")
|
|
34036
34160
|
};
|
|
@@ -34084,7 +34208,7 @@ function buildCondition(kind, query) {
|
|
|
34084
34208
|
}
|
|
34085
34209
|
function normalizeQuery(query) {
|
|
34086
34210
|
if (query === null) return null;
|
|
34087
|
-
const normalized = query.trim().toLowerCase().replace(
|
|
34211
|
+
const normalized = query.trim().toLowerCase().replace(WHITESPACE_RE_GLOBAL, " ");
|
|
34088
34212
|
if (normalized.length === 0) return null;
|
|
34089
34213
|
return normalized;
|
|
34090
34214
|
}
|
|
@@ -34154,7 +34278,7 @@ function summarizeSignalFacts(snapshots) {
|
|
|
34154
34278
|
}
|
|
34155
34279
|
function accumulateSnapshotFacts(snapshot, sink) {
|
|
34156
34280
|
for (const value2 of snapshot.signals.values()) {
|
|
34157
|
-
if (value2.guard ===
|
|
34281
|
+
if (value2.guard.kind === 1 /* Conditional */) {
|
|
34158
34282
|
sink.addConditional();
|
|
34159
34283
|
continue;
|
|
34160
34284
|
}
|
|
@@ -34348,15 +34472,6 @@ function assertUnitInterval(name, value2) {
|
|
|
34348
34472
|
}
|
|
34349
34473
|
|
|
34350
34474
|
// src/cross-file/layout/content-composition.ts
|
|
34351
|
-
var INTRINSIC_REPLACED_TAGS = /* @__PURE__ */ new Set([
|
|
34352
|
-
"img",
|
|
34353
|
-
"svg",
|
|
34354
|
-
"video",
|
|
34355
|
-
"canvas",
|
|
34356
|
-
"iframe",
|
|
34357
|
-
"object",
|
|
34358
|
-
"embed"
|
|
34359
|
-
]);
|
|
34360
34475
|
var BLOCK_FORMATTING_CONTEXT_DISPLAYS = /* @__PURE__ */ new Set([
|
|
34361
34476
|
"block",
|
|
34362
34477
|
"flex",
|
|
@@ -34390,7 +34505,7 @@ var VERTICAL_ALIGN_MITIGATIONS = /* @__PURE__ */ new Set([
|
|
|
34390
34505
|
"text-top",
|
|
34391
34506
|
"text-bottom"
|
|
34392
34507
|
]);
|
|
34393
|
-
function computeContentCompositionFingerprint(elementNode, childrenByParentNode, snapshotByElementNode,
|
|
34508
|
+
function computeContentCompositionFingerprint(elementNode, childrenByParentNode, snapshotByElementNode, snapshotHotSignalsByNode) {
|
|
34394
34509
|
const state = {
|
|
34395
34510
|
hasTextContent: false,
|
|
34396
34511
|
hasInlineReplaced: false,
|
|
@@ -34404,10 +34519,10 @@ function computeContentCompositionFingerprint(elementNode, childrenByParentNode,
|
|
|
34404
34519
|
blockChildCount: 0,
|
|
34405
34520
|
inlineChildCount: 0
|
|
34406
34521
|
};
|
|
34407
|
-
if (elementNode.textualContent ===
|
|
34522
|
+
if (elementNode.textualContent === 0 /* Yes */ || elementNode.textualContent === 3 /* DynamicText */) {
|
|
34408
34523
|
state.hasTextContent = true;
|
|
34409
34524
|
}
|
|
34410
|
-
const elementHotSignals =
|
|
34525
|
+
const elementHotSignals = snapshotHotSignalsByNode.get(elementNode);
|
|
34411
34526
|
const elementDisplay = elementHotSignals?.display.value ?? null;
|
|
34412
34527
|
if (elementDisplay !== null && establishesFormattingContext(elementDisplay)) {
|
|
34413
34528
|
return {
|
|
@@ -34418,7 +34533,7 @@ function computeContentCompositionFingerprint(elementNode, childrenByParentNode,
|
|
|
34418
34533
|
wrappingContextMitigates: false,
|
|
34419
34534
|
hasVerticalAlignMitigation: false,
|
|
34420
34535
|
mixedContentDepth: 0,
|
|
34421
|
-
classification:
|
|
34536
|
+
classification: 4 /* BlockSegmented */,
|
|
34422
34537
|
analyzableChildCount: 0,
|
|
34423
34538
|
totalChildCount: 0,
|
|
34424
34539
|
hasOnlyBlockChildren: false
|
|
@@ -34428,7 +34543,7 @@ function computeContentCompositionFingerprint(elementNode, childrenByParentNode,
|
|
|
34428
34543
|
elementNode,
|
|
34429
34544
|
childrenByParentNode,
|
|
34430
34545
|
snapshotByElementNode,
|
|
34431
|
-
|
|
34546
|
+
snapshotHotSignalsByNode,
|
|
34432
34547
|
state,
|
|
34433
34548
|
0
|
|
34434
34549
|
);
|
|
@@ -34448,7 +34563,7 @@ function computeContentCompositionFingerprint(elementNode, childrenByParentNode,
|
|
|
34448
34563
|
hasOnlyBlockChildren
|
|
34449
34564
|
};
|
|
34450
34565
|
}
|
|
34451
|
-
function walkInlineDescendants(node, childrenByParentNode, snapshotByElementNode,
|
|
34566
|
+
function walkInlineDescendants(node, childrenByParentNode, snapshotByElementNode, snapshotHotSignalsByNode, state, depth) {
|
|
34452
34567
|
const children = childrenByParentNode.get(node);
|
|
34453
34568
|
if (!children) return;
|
|
34454
34569
|
for (let i = 0; i < children.length; i++) {
|
|
@@ -34459,7 +34574,7 @@ function walkInlineDescendants(node, childrenByParentNode, snapshotByElementNode
|
|
|
34459
34574
|
if (!snapshot) continue;
|
|
34460
34575
|
if (depth === 0) state.analyzableChildCount++;
|
|
34461
34576
|
const childTag = child.tagName?.toLowerCase() ?? null;
|
|
34462
|
-
const hotSignals =
|
|
34577
|
+
const hotSignals = snapshotHotSignalsByNode.get(child);
|
|
34463
34578
|
const childDisplay = hotSignals?.display.value ?? null;
|
|
34464
34579
|
if (childTag !== null && (isIntrinsicReplacedTag(childTag) || isControlReplacedTag(childTag))) {
|
|
34465
34580
|
state.hasInlineReplaced = true;
|
|
@@ -34481,16 +34596,16 @@ function walkInlineDescendants(node, childrenByParentNode, snapshotByElementNode
|
|
|
34481
34596
|
checkVerticalAlignMitigation(snapshot, state);
|
|
34482
34597
|
updateMixedContentDepth(state, depth);
|
|
34483
34598
|
if (depth === 0) state.inlineChildCount++;
|
|
34484
|
-
const parentHotSignals =
|
|
34599
|
+
const parentHotSignals = snapshotHotSignalsByNode.get(node);
|
|
34485
34600
|
const parentDisplay = parentHotSignals?.display.value ?? null;
|
|
34486
34601
|
if (parentDisplay !== null && isAlignmentContextWithNonBaselineAlignment(parentDisplay, parentHotSignals)) {
|
|
34487
34602
|
state.wrappingContextMitigates = true;
|
|
34488
|
-
} else if (isAlignmentContextWithNonBaselineAlignment(childDisplay, hotSignals) && containsMixedContent(child, childrenByParentNode, snapshotByElementNode,
|
|
34603
|
+
} else if (isAlignmentContextWithNonBaselineAlignment(childDisplay, hotSignals) && containsMixedContent(child, childrenByParentNode, snapshotByElementNode, snapshotHotSignalsByNode)) {
|
|
34489
34604
|
state.wrappingContextMitigates = true;
|
|
34490
34605
|
}
|
|
34491
34606
|
continue;
|
|
34492
34607
|
}
|
|
34493
|
-
if (child.textualContent ===
|
|
34608
|
+
if (child.textualContent === 0 /* Yes */ || child.textualContent === 3 /* DynamicText */) {
|
|
34494
34609
|
state.hasTextContent = true;
|
|
34495
34610
|
}
|
|
34496
34611
|
checkHeightContributions(snapshot, state);
|
|
@@ -34500,7 +34615,7 @@ function walkInlineDescendants(node, childrenByParentNode, snapshotByElementNode
|
|
|
34500
34615
|
child,
|
|
34501
34616
|
childrenByParentNode,
|
|
34502
34617
|
snapshotByElementNode,
|
|
34503
|
-
|
|
34618
|
+
snapshotHotSignalsByNode,
|
|
34504
34619
|
state,
|
|
34505
34620
|
depth + 1
|
|
34506
34621
|
);
|
|
@@ -34535,19 +34650,19 @@ function isAlignmentContextWithNonBaselineAlignment(display, hotSignals) {
|
|
|
34535
34650
|
if (alignItems === null) return false;
|
|
34536
34651
|
return alignItems !== "baseline";
|
|
34537
34652
|
}
|
|
34538
|
-
function containsMixedContent(node, childrenByParentNode, snapshotByElementNode,
|
|
34539
|
-
const hasText = node.textualContent ===
|
|
34653
|
+
function containsMixedContent(node, childrenByParentNode, snapshotByElementNode, snapshotHotSignalsByNode) {
|
|
34654
|
+
const hasText = node.textualContent === 0 /* Yes */ || node.textualContent === 3 /* DynamicText */;
|
|
34540
34655
|
const hasReplaced = false;
|
|
34541
|
-
return scanMixedContent(node, childrenByParentNode, snapshotByElementNode,
|
|
34656
|
+
return scanMixedContent(node, childrenByParentNode, snapshotByElementNode, snapshotHotSignalsByNode, { hasText, hasReplaced });
|
|
34542
34657
|
}
|
|
34543
|
-
function scanMixedContent(node, childrenByParentNode, snapshotByElementNode,
|
|
34658
|
+
function scanMixedContent(node, childrenByParentNode, snapshotByElementNode, snapshotHotSignalsByNode, found) {
|
|
34544
34659
|
const children = childrenByParentNode.get(node);
|
|
34545
34660
|
if (!children) return false;
|
|
34546
34661
|
for (let i = 0; i < children.length; i++) {
|
|
34547
34662
|
const child = children[i];
|
|
34548
34663
|
if (!child) continue;
|
|
34549
34664
|
const childTag = child.tagName?.toLowerCase() ?? null;
|
|
34550
|
-
const hotSignals =
|
|
34665
|
+
const hotSignals = snapshotHotSignalsByNode.get(child);
|
|
34551
34666
|
const childDisplay = hotSignals?.display.value ?? null;
|
|
34552
34667
|
if (childTag !== null && (isIntrinsicReplacedTag(childTag) || isControlReplacedTag(childTag))) {
|
|
34553
34668
|
found.hasReplaced = true;
|
|
@@ -34562,12 +34677,12 @@ function scanMixedContent(node, childrenByParentNode, snapshotByElementNode, sna
|
|
|
34562
34677
|
if (found.hasText) return true;
|
|
34563
34678
|
continue;
|
|
34564
34679
|
}
|
|
34565
|
-
if (child.textualContent ===
|
|
34680
|
+
if (child.textualContent === 0 /* Yes */ || child.textualContent === 3 /* DynamicText */) {
|
|
34566
34681
|
found.hasText = true;
|
|
34567
34682
|
if (found.hasReplaced) return true;
|
|
34568
34683
|
}
|
|
34569
34684
|
if (childDisplay === null || isInlineContinuationDisplay(childDisplay)) {
|
|
34570
|
-
if (scanMixedContent(child, childrenByParentNode, snapshotByElementNode,
|
|
34685
|
+
if (scanMixedContent(child, childrenByParentNode, snapshotByElementNode, snapshotHotSignalsByNode, found)) {
|
|
34571
34686
|
return true;
|
|
34572
34687
|
}
|
|
34573
34688
|
}
|
|
@@ -34590,30 +34705,30 @@ function updateMixedContentDepth(state, depth) {
|
|
|
34590
34705
|
}
|
|
34591
34706
|
function classifyFromState(state, elementNode, hasOnlyBlockChildren) {
|
|
34592
34707
|
if (hasOnlyBlockChildren) {
|
|
34593
|
-
return
|
|
34708
|
+
return 4 /* BlockSegmented */;
|
|
34594
34709
|
}
|
|
34595
34710
|
if (state.totalChildCount === 0 && !state.hasTextContent) {
|
|
34596
|
-
if (elementNode.textualContent ===
|
|
34597
|
-
if (elementNode.textualContent ===
|
|
34598
|
-
return
|
|
34711
|
+
if (elementNode.textualContent === 2 /* Unknown */) return 5 /* Unknown */;
|
|
34712
|
+
if (elementNode.textualContent === 0 /* Yes */ || elementNode.textualContent === 3 /* DynamicText */) {
|
|
34713
|
+
return 0 /* TextOnly */;
|
|
34599
34714
|
}
|
|
34600
|
-
return
|
|
34715
|
+
return 5 /* Unknown */;
|
|
34601
34716
|
}
|
|
34602
34717
|
if (state.analyzableChildCount === 0 && state.totalChildCount > 0) {
|
|
34603
|
-
return
|
|
34718
|
+
return 5 /* Unknown */;
|
|
34604
34719
|
}
|
|
34605
34720
|
if (state.hasTextContent && state.hasInlineReplaced) {
|
|
34606
|
-
if (state.wrappingContextMitigates) return
|
|
34607
|
-
if (state.hasVerticalAlignMitigation) return
|
|
34608
|
-
return
|
|
34721
|
+
if (state.wrappingContextMitigates) return 3 /* MixedMitigated */;
|
|
34722
|
+
if (state.hasVerticalAlignMitigation) return 3 /* MixedMitigated */;
|
|
34723
|
+
return 2 /* MixedUnmitigated */;
|
|
34609
34724
|
}
|
|
34610
34725
|
if (!state.hasTextContent && state.hasInlineReplaced) {
|
|
34611
|
-
return
|
|
34726
|
+
return 1 /* ReplacedOnly */;
|
|
34612
34727
|
}
|
|
34613
34728
|
if (state.hasTextContent && !state.hasInlineReplaced) {
|
|
34614
|
-
return
|
|
34729
|
+
return 0 /* TextOnly */;
|
|
34615
34730
|
}
|
|
34616
|
-
return
|
|
34731
|
+
return 5 /* Unknown */;
|
|
34617
34732
|
}
|
|
34618
34733
|
function isIntrinsicReplacedTag(tag) {
|
|
34619
34734
|
return INTRINSIC_REPLACED_TAGS.has(tag);
|
|
@@ -34633,10 +34748,14 @@ function isInlineReplacedDisplay(display) {
|
|
|
34633
34748
|
function isInlineContinuationDisplay(display) {
|
|
34634
34749
|
return INLINE_CONTINUATION_DISPLAYS.has(display);
|
|
34635
34750
|
}
|
|
34636
|
-
|
|
34637
|
-
|
|
34751
|
+
var NO_DIVERGENCE = Object.freeze({
|
|
34752
|
+
strength: 0,
|
|
34753
|
+
majorityClassification: 5 /* Unknown */
|
|
34754
|
+
});
|
|
34755
|
+
function resolveCompositionDivergence(subjectFingerprint, allFingerprints, parentContext) {
|
|
34756
|
+
if (allFingerprints.length < 2) return NO_DIVERGENCE;
|
|
34638
34757
|
if (parentContext !== null && !hasSharedBaselineAlignment(parentContext)) {
|
|
34639
|
-
return
|
|
34758
|
+
return NO_DIVERGENCE;
|
|
34640
34759
|
}
|
|
34641
34760
|
const countByClassification = /* @__PURE__ */ new Map();
|
|
34642
34761
|
for (let i = 0; i < allFingerprints.length; i++) {
|
|
@@ -34648,10 +34767,7 @@ function resolveCompositionDivergenceStrength(subjectFingerprint, allFingerprint
|
|
|
34648
34767
|
}
|
|
34649
34768
|
const subjectNormalized = normalizeClassificationForComparison(subjectFingerprint.classification);
|
|
34650
34769
|
const subjectCount = countByClassification.get(subjectNormalized) ?? 0;
|
|
34651
|
-
|
|
34652
|
-
return resolveInlineReplacedKindDivergence(subjectFingerprint, allFingerprints);
|
|
34653
|
-
}
|
|
34654
|
-
let majorityClassification = "unknown";
|
|
34770
|
+
let majorityClassification = 5 /* Unknown */;
|
|
34655
34771
|
let majorityCount = 0;
|
|
34656
34772
|
for (const [classification, count] of countByClassification) {
|
|
34657
34773
|
if (count > majorityCount) {
|
|
@@ -34659,35 +34775,38 @@ function resolveCompositionDivergenceStrength(subjectFingerprint, allFingerprint
|
|
|
34659
34775
|
majorityClassification = classification;
|
|
34660
34776
|
}
|
|
34661
34777
|
}
|
|
34778
|
+
if (subjectCount === allFingerprints.length) {
|
|
34779
|
+
return { strength: resolveInlineReplacedKindDivergence(subjectFingerprint, allFingerprints), majorityClassification };
|
|
34780
|
+
}
|
|
34662
34781
|
if (subjectNormalized === majorityClassification) {
|
|
34663
|
-
return resolveInlineReplacedKindDivergence(subjectFingerprint, allFingerprints);
|
|
34782
|
+
return { strength: resolveInlineReplacedKindDivergence(subjectFingerprint, allFingerprints), majorityClassification };
|
|
34664
34783
|
}
|
|
34665
|
-
if (subjectNormalized ===
|
|
34666
|
-
return 0;
|
|
34784
|
+
if (subjectNormalized === 5 /* Unknown */) {
|
|
34785
|
+
return { strength: 0, majorityClassification };
|
|
34667
34786
|
}
|
|
34668
34787
|
const cal = alignmentStrengthCalibration;
|
|
34669
|
-
if (majorityClassification ===
|
|
34670
|
-
return cal.compositionMixedUnmitigatedOutlierStrength;
|
|
34788
|
+
if (majorityClassification === 0 /* TextOnly */ && subjectNormalized === 2 /* MixedUnmitigated */) {
|
|
34789
|
+
return { strength: cal.compositionMixedUnmitigatedOutlierStrength, majorityClassification };
|
|
34671
34790
|
}
|
|
34672
|
-
if (majorityClassification ===
|
|
34673
|
-
return cal.compositionMixedOutlierAmongReplacedStrength;
|
|
34791
|
+
if (majorityClassification === 1 /* ReplacedOnly */ && subjectNormalized === 2 /* MixedUnmitigated */) {
|
|
34792
|
+
return { strength: cal.compositionMixedOutlierAmongReplacedStrength, majorityClassification };
|
|
34674
34793
|
}
|
|
34675
|
-
if (majorityClassification ===
|
|
34676
|
-
return cal.compositionTextOutlierAmongMixedStrength;
|
|
34794
|
+
if (majorityClassification === 2 /* MixedUnmitigated */ && subjectNormalized === 0 /* TextOnly */) {
|
|
34795
|
+
return { strength: cal.compositionTextOutlierAmongMixedStrength, majorityClassification };
|
|
34677
34796
|
}
|
|
34678
|
-
if (majorityClassification ===
|
|
34679
|
-
return cal.compositionTextOutlierAmongMixedStrength;
|
|
34797
|
+
if (majorityClassification === 2 /* MixedUnmitigated */ && subjectNormalized === 1 /* ReplacedOnly */) {
|
|
34798
|
+
return { strength: cal.compositionTextOutlierAmongMixedStrength, majorityClassification };
|
|
34680
34799
|
}
|
|
34681
|
-
if (majorityClassification ===
|
|
34682
|
-
return cal.compositionMixedOutlierAmongReplacedStrength;
|
|
34800
|
+
if (majorityClassification === 0 /* TextOnly */ && subjectNormalized === 1 /* ReplacedOnly */) {
|
|
34801
|
+
return { strength: cal.compositionMixedOutlierAmongReplacedStrength, majorityClassification };
|
|
34683
34802
|
}
|
|
34684
|
-
if (majorityClassification ===
|
|
34685
|
-
return cal.compositionTextOutlierAmongMixedStrength;
|
|
34803
|
+
if (majorityClassification === 1 /* ReplacedOnly */ && subjectNormalized === 0 /* TextOnly */) {
|
|
34804
|
+
return { strength: cal.compositionTextOutlierAmongMixedStrength, majorityClassification };
|
|
34686
34805
|
}
|
|
34687
|
-
if (majorityClassification ===
|
|
34688
|
-
return 0;
|
|
34806
|
+
if (majorityClassification === 5 /* Unknown */) {
|
|
34807
|
+
return { strength: 0, majorityClassification };
|
|
34689
34808
|
}
|
|
34690
|
-
return cal.compositionUnknownPenalty;
|
|
34809
|
+
return { strength: cal.compositionUnknownPenalty, majorityClassification };
|
|
34691
34810
|
}
|
|
34692
34811
|
function resolveInlineReplacedKindDivergence(subjectFingerprint, allFingerprints) {
|
|
34693
34812
|
if (subjectFingerprint.inlineReplacedKind === null) return 0;
|
|
@@ -34708,28 +34827,9 @@ function resolveInlineReplacedKindDivergence(subjectFingerprint, allFingerprints
|
|
|
34708
34827
|
function hasSharedBaselineAlignment(context) {
|
|
34709
34828
|
return context.baselineRelevance === "relevant";
|
|
34710
34829
|
}
|
|
34711
|
-
function resolveMajorityClassification(allFingerprints) {
|
|
34712
|
-
const countByClassification = /* @__PURE__ */ new Map();
|
|
34713
|
-
for (let i = 0; i < allFingerprints.length; i++) {
|
|
34714
|
-
const fp = allFingerprints[i];
|
|
34715
|
-
if (!fp) continue;
|
|
34716
|
-
const normalized = normalizeClassificationForComparison(fp.classification);
|
|
34717
|
-
const existing = countByClassification.get(normalized) ?? 0;
|
|
34718
|
-
countByClassification.set(normalized, existing + 1);
|
|
34719
|
-
}
|
|
34720
|
-
let majorityClassification = "unknown";
|
|
34721
|
-
let majorityCount = 0;
|
|
34722
|
-
for (const [classification, count] of countByClassification) {
|
|
34723
|
-
if (count > majorityCount) {
|
|
34724
|
-
majorityCount = count;
|
|
34725
|
-
majorityClassification = classification;
|
|
34726
|
-
}
|
|
34727
|
-
}
|
|
34728
|
-
return majorityClassification;
|
|
34729
|
-
}
|
|
34730
34830
|
function normalizeClassificationForComparison(classification) {
|
|
34731
|
-
if (classification ===
|
|
34732
|
-
if (classification ===
|
|
34831
|
+
if (classification === 3 /* MixedMitigated */) return 0 /* TextOnly */;
|
|
34832
|
+
if (classification === 4 /* BlockSegmented */) return 0 /* TextOnly */;
|
|
34733
34833
|
return classification;
|
|
34734
34834
|
}
|
|
34735
34835
|
function resolveCompositionCoverage(subjectFingerprint, allFingerprints) {
|
|
@@ -34737,12 +34837,12 @@ function resolveCompositionCoverage(subjectFingerprint, allFingerprints) {
|
|
|
34737
34837
|
let analyzableCount = 0;
|
|
34738
34838
|
for (let i = 0; i < allFingerprints.length; i++) {
|
|
34739
34839
|
const fp = allFingerprints[i];
|
|
34740
|
-
if (fp && fp.classification !==
|
|
34840
|
+
if (fp && fp.classification !== 5 /* Unknown */) {
|
|
34741
34841
|
analyzableCount++;
|
|
34742
34842
|
}
|
|
34743
34843
|
}
|
|
34744
34844
|
const analyzableShare = analyzableCount / allFingerprints.length;
|
|
34745
|
-
if (subjectFingerprint.classification ===
|
|
34845
|
+
if (subjectFingerprint.classification === 5 /* Unknown */) {
|
|
34746
34846
|
return analyzableShare * 0.3;
|
|
34747
34847
|
}
|
|
34748
34848
|
if (subjectFingerprint.totalChildCount > 0 && subjectFingerprint.analyzableChildCount === 0) {
|
|
@@ -34750,24 +34850,19 @@ function resolveCompositionCoverage(subjectFingerprint, allFingerprints) {
|
|
|
34750
34850
|
}
|
|
34751
34851
|
return analyzableShare;
|
|
34752
34852
|
}
|
|
34853
|
+
var COMPOSITION_LABELS = {
|
|
34854
|
+
[0 /* TextOnly */]: "text-only",
|
|
34855
|
+
[1 /* ReplacedOnly */]: "inline-replaced-only",
|
|
34856
|
+
[2 /* MixedUnmitigated */]: "mixed text + inline-replaced",
|
|
34857
|
+
[3 /* MixedMitigated */]: "mixed (alignment mitigated)",
|
|
34858
|
+
[4 /* BlockSegmented */]: "block-segmented",
|
|
34859
|
+
[5 /* Unknown */]: "unknown"
|
|
34860
|
+
};
|
|
34753
34861
|
function formatCompositionClassification(classification) {
|
|
34754
|
-
|
|
34755
|
-
case "text-only":
|
|
34756
|
-
return "text-only";
|
|
34757
|
-
case "replaced-only":
|
|
34758
|
-
return "inline-replaced-only";
|
|
34759
|
-
case "mixed-unmitigated":
|
|
34760
|
-
return "mixed text + inline-replaced";
|
|
34761
|
-
case "mixed-mitigated":
|
|
34762
|
-
return "mixed (alignment mitigated)";
|
|
34763
|
-
case "block-segmented":
|
|
34764
|
-
return "block-segmented";
|
|
34765
|
-
case "unknown":
|
|
34766
|
-
return "unknown";
|
|
34767
|
-
}
|
|
34862
|
+
return COMPOSITION_LABELS[classification];
|
|
34768
34863
|
}
|
|
34769
34864
|
function formatCompositionFixSuggestion(subjectFingerprint) {
|
|
34770
|
-
if (subjectFingerprint.classification ===
|
|
34865
|
+
if (subjectFingerprint.classification === 2 /* MixedUnmitigated */) {
|
|
34771
34866
|
if (subjectFingerprint.hasVerticalAlignMitigation) {
|
|
34772
34867
|
return "verify vertical-align resolves the baseline shift";
|
|
34773
34868
|
}
|
|
@@ -34802,12 +34897,12 @@ function estimateBlockOffsetWithDeclaredFromHotSignals(hot, axis) {
|
|
|
34802
34897
|
function estimateBlockOffsetWithDeclaredFromSources(axis, position, readNumeric) {
|
|
34803
34898
|
let declaredTotal = 0;
|
|
34804
34899
|
let declaredCount = 0;
|
|
34805
|
-
let declaredKind =
|
|
34806
|
-
let declaredMissingKind =
|
|
34900
|
+
let declaredKind = 0 /* Exact */;
|
|
34901
|
+
let declaredMissingKind = 0 /* Exact */;
|
|
34807
34902
|
let effectiveTotal = 0;
|
|
34808
34903
|
let effectiveCount = 0;
|
|
34809
|
-
let effectiveKind =
|
|
34810
|
-
let effectiveMissingKind =
|
|
34904
|
+
let effectiveKind = 0 /* Exact */;
|
|
34905
|
+
let effectiveMissingKind = 0 /* Exact */;
|
|
34811
34906
|
const positioned = position.value !== null && position.value !== "static";
|
|
34812
34907
|
const add = (name, sign, requiresPositioning) => {
|
|
34813
34908
|
const v = readNumeric(name);
|
|
@@ -34878,7 +34973,7 @@ function buildCohortIndex(input) {
|
|
|
34878
34973
|
axisCertainty: context.axisCertainty,
|
|
34879
34974
|
measurementNodeByRootKey: input.measurementNodeByRootKey,
|
|
34880
34975
|
snapshotByElementNode: input.snapshotByElementNode,
|
|
34881
|
-
|
|
34976
|
+
snapshotHotSignalsByNode: input.snapshotHotSignalsByNode
|
|
34882
34977
|
});
|
|
34883
34978
|
measurementIndexHits += cohortMetricsResult.measurementHits;
|
|
34884
34979
|
const metrics = cohortMetricsResult.metrics;
|
|
@@ -34912,7 +35007,7 @@ function buildCohortIndex(input) {
|
|
|
34912
35007
|
subjectMetrics.rootNode,
|
|
34913
35008
|
input.childrenByParentNode,
|
|
34914
35009
|
input.snapshotByElementNode,
|
|
34915
|
-
input.
|
|
35010
|
+
input.snapshotHotSignalsByNode
|
|
34916
35011
|
);
|
|
34917
35012
|
subjectsByElementKey.set(subjectMetrics.key, {
|
|
34918
35013
|
element: subjectMetrics.element,
|
|
@@ -34978,7 +35073,7 @@ function collectCohortMetrics(input) {
|
|
|
34978
35073
|
if (!snapshot) {
|
|
34979
35074
|
throw new Error(`missing snapshot for measurement node ${measurementNode.key}`);
|
|
34980
35075
|
}
|
|
34981
|
-
const hotSignals = input.
|
|
35076
|
+
const hotSignals = input.snapshotHotSignalsByNode.get(measurementNode);
|
|
34982
35077
|
if (!hotSignals) {
|
|
34983
35078
|
throw new Error(`missing hot signals for measurement node ${measurementNode.key}`);
|
|
34984
35079
|
}
|
|
@@ -35303,9 +35398,9 @@ function buildCohortSignalIndex(metrics) {
|
|
|
35303
35398
|
const verticalAlignCounts = /* @__PURE__ */ new Map();
|
|
35304
35399
|
const alignSelfCounts = /* @__PURE__ */ new Map();
|
|
35305
35400
|
const placeSelfCounts = /* @__PURE__ */ new Map();
|
|
35306
|
-
let verticalAlignMergedKind =
|
|
35307
|
-
let alignSelfMergedKind =
|
|
35308
|
-
let placeSelfMergedKind =
|
|
35401
|
+
let verticalAlignMergedKind = 0 /* Exact */;
|
|
35402
|
+
let alignSelfMergedKind = 0 /* Exact */;
|
|
35403
|
+
let placeSelfMergedKind = 0 /* Exact */;
|
|
35309
35404
|
let verticalAlignComparableCount = 0;
|
|
35310
35405
|
let alignSelfComparableCount = 0;
|
|
35311
35406
|
let placeSelfComparableCount = 0;
|
|
@@ -35319,12 +35414,12 @@ function buildCohortSignalIndex(metrics) {
|
|
|
35319
35414
|
const snapshot = metric.element.snapshot;
|
|
35320
35415
|
const alignSelf = metric.hotSignals.alignSelf;
|
|
35321
35416
|
const placeSelf = metric.hotSignals.placeSelf;
|
|
35322
|
-
const isControlOrReplaced = snapshot.isControl || snapshot.isReplaced;
|
|
35417
|
+
const isControlOrReplaced = snapshot.node.isControl || snapshot.node.isReplaced;
|
|
35323
35418
|
const verticalAlign = resolveComparableVerticalAlign(metric.hotSignals.verticalAlign, isControlOrReplaced);
|
|
35324
35419
|
if (isControlOrReplaced) controlOrReplacedCount++;
|
|
35325
|
-
if (snapshot.textualContent ===
|
|
35326
|
-
if (snapshot.textualContent ===
|
|
35327
|
-
if (snapshot.textualContent ===
|
|
35420
|
+
if (snapshot.node.textualContent === 0 /* Yes */ || snapshot.node.textualContent === 3 /* DynamicText */) textYesCount++;
|
|
35421
|
+
if (snapshot.node.textualContent === 1 /* No */) textNoCount++;
|
|
35422
|
+
if (snapshot.node.textualContent === 2 /* Unknown */) textUnknownCount++;
|
|
35328
35423
|
if (verticalAlign.value !== null) {
|
|
35329
35424
|
verticalAlignMergedKind = mergeEvidenceKind(verticalAlignMergedKind, verticalAlign.kind);
|
|
35330
35425
|
verticalAlignComparableCount++;
|
|
@@ -35344,24 +35439,24 @@ function buildCohortSignalIndex(metrics) {
|
|
|
35344
35439
|
verticalAlign,
|
|
35345
35440
|
alignSelf,
|
|
35346
35441
|
placeSelf,
|
|
35347
|
-
textualContent: snapshot.textualContent,
|
|
35442
|
+
textualContent: snapshot.node.textualContent,
|
|
35348
35443
|
isControlOrReplaced
|
|
35349
35444
|
});
|
|
35350
35445
|
}
|
|
35351
35446
|
return {
|
|
35352
35447
|
byKey,
|
|
35353
35448
|
verticalAlign: {
|
|
35354
|
-
mergedKind: verticalAlignComparableCount === 0 ?
|
|
35449
|
+
mergedKind: verticalAlignComparableCount === 0 ? 3 /* Unknown */ : verticalAlignMergedKind,
|
|
35355
35450
|
comparableCount: verticalAlignComparableCount,
|
|
35356
35451
|
countsByValue: verticalAlignCounts
|
|
35357
35452
|
},
|
|
35358
35453
|
alignSelf: {
|
|
35359
|
-
mergedKind: alignSelfComparableCount === 0 ?
|
|
35454
|
+
mergedKind: alignSelfComparableCount === 0 ? 3 /* Unknown */ : alignSelfMergedKind,
|
|
35360
35455
|
comparableCount: alignSelfComparableCount,
|
|
35361
35456
|
countsByValue: alignSelfCounts
|
|
35362
35457
|
},
|
|
35363
35458
|
placeSelf: {
|
|
35364
|
-
mergedKind: placeSelfComparableCount === 0 ?
|
|
35459
|
+
mergedKind: placeSelfComparableCount === 0 ? 3 /* Unknown */ : placeSelfMergedKind,
|
|
35365
35460
|
comparableCount: placeSelfComparableCount,
|
|
35366
35461
|
countsByValue: placeSelfCounts
|
|
35367
35462
|
},
|
|
@@ -35398,9 +35493,9 @@ function collectSubjectCohortSignals(index, subjectMetrics, context) {
|
|
|
35398
35493
|
sawComparableVerticalAlign,
|
|
35399
35494
|
sawVerticalAlignConflict
|
|
35400
35495
|
);
|
|
35401
|
-
const tableCellControlFallback = context.kind === "table-cell" && subject.isControlOrReplaced && verticalAlign.value ===
|
|
35496
|
+
const tableCellControlFallback = context.kind === "table-cell" && subject.isControlOrReplaced && verticalAlign.value === 2 /* Unknown */ && index.byKey.size > index.controlOrReplacedCount;
|
|
35402
35497
|
const normalizedVerticalAlign = tableCellControlFallback ? {
|
|
35403
|
-
value:
|
|
35498
|
+
value: 0 /* Conflict */,
|
|
35404
35499
|
kind: verticalAlignKind
|
|
35405
35500
|
} : verticalAlign;
|
|
35406
35501
|
const textContrastWithPeers = resolveIndexedTextContrastWithPeers(
|
|
@@ -35433,7 +35528,7 @@ function resolveComparableVerticalAlign(verticalAlign, isControlOrReplaced) {
|
|
|
35433
35528
|
return {
|
|
35434
35529
|
present: verticalAlign.present,
|
|
35435
35530
|
value: "baseline",
|
|
35436
|
-
kind:
|
|
35531
|
+
kind: 0 /* Exact */
|
|
35437
35532
|
};
|
|
35438
35533
|
}
|
|
35439
35534
|
function hasComparablePeer(aggregate, subjectValue) {
|
|
@@ -35450,37 +35545,37 @@ function hasConflictPeer(aggregate, subjectValue) {
|
|
|
35450
35545
|
function finalizeConflictEvidence(subjectValue, kind, sawComparablePeer, sawConflict) {
|
|
35451
35546
|
if (subjectValue === null) {
|
|
35452
35547
|
return {
|
|
35453
|
-
value:
|
|
35548
|
+
value: 2 /* Unknown */,
|
|
35454
35549
|
kind
|
|
35455
35550
|
};
|
|
35456
35551
|
}
|
|
35457
35552
|
if (!sawComparablePeer) {
|
|
35458
35553
|
return {
|
|
35459
|
-
value:
|
|
35554
|
+
value: 2 /* Unknown */,
|
|
35460
35555
|
kind
|
|
35461
35556
|
};
|
|
35462
35557
|
}
|
|
35463
35558
|
return {
|
|
35464
|
-
value: sawConflict ?
|
|
35559
|
+
value: sawConflict ? 0 /* Conflict */ : 1 /* Aligned */,
|
|
35465
35560
|
kind
|
|
35466
35561
|
};
|
|
35467
35562
|
}
|
|
35468
35563
|
function resolveIndexedTextContrastWithPeers(index, subjectTextualContent, subjectIsControlOrReplaced, tableCellControlFallback) {
|
|
35469
|
-
if (subjectTextualContent ===
|
|
35564
|
+
if (subjectTextualContent === 2 /* Unknown */) return 2 /* Unknown */;
|
|
35470
35565
|
const unknownPeers = index.textUnknownCount;
|
|
35471
35566
|
const cohortSize = index.byKey.size;
|
|
35472
|
-
if (subjectTextualContent ===
|
|
35473
|
-
if (index.textNoCount > 0) return
|
|
35474
|
-
if (unknownPeers > 0) return
|
|
35475
|
-
return
|
|
35567
|
+
if (subjectTextualContent === 0 /* Yes */ || subjectTextualContent === 3 /* DynamicText */) {
|
|
35568
|
+
if (index.textNoCount > 0) return 0 /* Different */;
|
|
35569
|
+
if (unknownPeers > 0) return 2 /* Unknown */;
|
|
35570
|
+
return 1 /* Same */;
|
|
35476
35571
|
}
|
|
35477
|
-
if (index.textYesCount > 0) return
|
|
35478
|
-
if (tableCellControlFallback) return
|
|
35572
|
+
if (index.textYesCount > 0) return 0 /* Different */;
|
|
35573
|
+
if (tableCellControlFallback) return 0 /* Different */;
|
|
35479
35574
|
if (subjectIsControlOrReplaced && index.controlOrReplacedCount === 1 && cohortSize >= 3 && unknownPeers > 0) {
|
|
35480
|
-
return
|
|
35575
|
+
return 0 /* Different */;
|
|
35481
35576
|
}
|
|
35482
|
-
if (unknownPeers > 0) return
|
|
35483
|
-
return
|
|
35577
|
+
if (unknownPeers > 0) return 2 /* Unknown */;
|
|
35578
|
+
return 1 /* Same */;
|
|
35484
35579
|
}
|
|
35485
35580
|
function resolveSubjectIdentifiability(subjectMetrics, profile, subjectBaselineProfile, clusterSummary, signalIndex, cohortKind, cohortSize) {
|
|
35486
35581
|
const subjectClusterKey = toComparableClusterKey(subjectMetrics);
|
|
@@ -35496,7 +35591,7 @@ function resolveSubjectIdentifiability(subjectMetrics, profile, subjectBaselineP
|
|
|
35496
35591
|
return {
|
|
35497
35592
|
dominantShare: profile.dominantClusterShare,
|
|
35498
35593
|
subjectExcludedDominantShare: subjectBaselineProfile.dominantClusterShare,
|
|
35499
|
-
subjectMembership:
|
|
35594
|
+
subjectMembership: 3 /* Insufficient */,
|
|
35500
35595
|
ambiguous: true,
|
|
35501
35596
|
kind
|
|
35502
35597
|
};
|
|
@@ -35505,7 +35600,7 @@ function resolveSubjectIdentifiability(subjectMetrics, profile, subjectBaselineP
|
|
|
35505
35600
|
return {
|
|
35506
35601
|
dominantShare: profile.dominantClusterShare,
|
|
35507
35602
|
subjectExcludedDominantShare: subjectBaselineProfile.dominantClusterShare,
|
|
35508
|
-
subjectMembership:
|
|
35603
|
+
subjectMembership: 0 /* Dominant */,
|
|
35509
35604
|
ambiguous: false,
|
|
35510
35605
|
kind
|
|
35511
35606
|
};
|
|
@@ -35514,7 +35609,7 @@ function resolveSubjectIdentifiability(subjectMetrics, profile, subjectBaselineP
|
|
|
35514
35609
|
return {
|
|
35515
35610
|
dominantShare: profile.dominantClusterShare,
|
|
35516
35611
|
subjectExcludedDominantShare: subjectBaselineProfile.dominantClusterShare,
|
|
35517
|
-
subjectMembership:
|
|
35612
|
+
subjectMembership: 3 /* Insufficient */,
|
|
35518
35613
|
ambiguous: true,
|
|
35519
35614
|
kind
|
|
35520
35615
|
};
|
|
@@ -35524,7 +35619,7 @@ function resolveSubjectIdentifiability(subjectMetrics, profile, subjectBaselineP
|
|
|
35524
35619
|
return {
|
|
35525
35620
|
dominantShare: profile.dominantClusterShare,
|
|
35526
35621
|
subjectExcludedDominantShare: subjectBaselineProfile.dominantClusterShare,
|
|
35527
|
-
subjectMembership:
|
|
35622
|
+
subjectMembership: 3 /* Insufficient */,
|
|
35528
35623
|
ambiguous: true,
|
|
35529
35624
|
kind
|
|
35530
35625
|
};
|
|
@@ -35534,7 +35629,7 @@ function resolveSubjectIdentifiability(subjectMetrics, profile, subjectBaselineP
|
|
|
35534
35629
|
return {
|
|
35535
35630
|
dominantShare: profile.dominantClusterShare,
|
|
35536
35631
|
subjectExcludedDominantShare: subjectBaselineProfile.dominantClusterShare,
|
|
35537
|
-
subjectMembership:
|
|
35632
|
+
subjectMembership: 2 /* Ambiguous */,
|
|
35538
35633
|
ambiguous: true,
|
|
35539
35634
|
kind
|
|
35540
35635
|
};
|
|
@@ -35543,7 +35638,7 @@ function resolveSubjectIdentifiability(subjectMetrics, profile, subjectBaselineP
|
|
|
35543
35638
|
return {
|
|
35544
35639
|
dominantShare: profile.dominantClusterShare,
|
|
35545
35640
|
subjectExcludedDominantShare: subjectBaselineProfile.dominantClusterShare,
|
|
35546
|
-
subjectMembership:
|
|
35641
|
+
subjectMembership: 0 /* Dominant */,
|
|
35547
35642
|
ambiguous: false,
|
|
35548
35643
|
kind
|
|
35549
35644
|
};
|
|
@@ -35551,13 +35646,13 @@ function resolveSubjectIdentifiability(subjectMetrics, profile, subjectBaselineP
|
|
|
35551
35646
|
return {
|
|
35552
35647
|
dominantShare: profile.dominantClusterShare,
|
|
35553
35648
|
subjectExcludedDominantShare: subjectBaselineProfile.dominantClusterShare,
|
|
35554
|
-
subjectMembership:
|
|
35649
|
+
subjectMembership: 1 /* Nondominant */,
|
|
35555
35650
|
ambiguous: false,
|
|
35556
35651
|
kind
|
|
35557
35652
|
};
|
|
35558
35653
|
}
|
|
35559
35654
|
function resolveControlRoleIdentifiability(subjectMetrics, signalIndex, kind, cohortSize) {
|
|
35560
|
-
const subjectIsControlOrReplaced = subjectMetrics.element.snapshot.isControl || subjectMetrics.element.snapshot.isReplaced;
|
|
35655
|
+
const subjectIsControlOrReplaced = subjectMetrics.element.snapshot.node.isControl || subjectMetrics.element.snapshot.node.isReplaced;
|
|
35561
35656
|
const controlCount = signalIndex.controlOrReplacedCount;
|
|
35562
35657
|
const nonControlCount = cohortSize - controlCount;
|
|
35563
35658
|
if (controlCount <= 0 || nonControlCount <= 0) return null;
|
|
@@ -35572,12 +35667,12 @@ function resolveControlRoleIdentifiability(subjectMetrics, signalIndex, kind, co
|
|
|
35572
35667
|
return {
|
|
35573
35668
|
dominantShare,
|
|
35574
35669
|
subjectExcludedDominantShare: excludedDominantShare,
|
|
35575
|
-
subjectMembership: subjectMembership ===
|
|
35670
|
+
subjectMembership: subjectMembership === 2 /* Ambiguous */ ? 0 /* Dominant */ : subjectMembership,
|
|
35576
35671
|
ambiguous: false,
|
|
35577
35672
|
kind
|
|
35578
35673
|
};
|
|
35579
35674
|
}
|
|
35580
|
-
if (subjectMembership ===
|
|
35675
|
+
if (subjectMembership === 2 /* Ambiguous */) {
|
|
35581
35676
|
return {
|
|
35582
35677
|
dominantShare,
|
|
35583
35678
|
subjectExcludedDominantShare: excludedDominantShare,
|
|
@@ -35595,9 +35690,9 @@ function resolveControlRoleIdentifiability(subjectMetrics, signalIndex, kind, co
|
|
|
35595
35690
|
};
|
|
35596
35691
|
}
|
|
35597
35692
|
function resolveRoleMembership(controlCount, nonControlCount, subjectIsControlOrReplaced) {
|
|
35598
|
-
if (controlCount === nonControlCount) return
|
|
35693
|
+
if (controlCount === nonControlCount) return 2 /* Ambiguous */;
|
|
35599
35694
|
const dominantRoleIsControl = controlCount > nonControlCount;
|
|
35600
|
-
return dominantRoleIsControl === subjectIsControlOrReplaced ?
|
|
35695
|
+
return dominantRoleIsControl === subjectIsControlOrReplaced ? 0 /* Dominant */ : 1 /* Nondominant */;
|
|
35601
35696
|
}
|
|
35602
35697
|
function resolveExcludedRoleDominantShare(controlCount, nonControlCount, subjectIsControlOrReplaced) {
|
|
35603
35698
|
const controlAfterExclusion = controlCount - (subjectIsControlOrReplaced ? 1 : 0);
|
|
@@ -35635,8 +35730,8 @@ function collectCohortProvenanceFromSnapshots(snapshots) {
|
|
|
35635
35730
|
const snapshot = snapshots[i];
|
|
35636
35731
|
if (!snapshot) continue;
|
|
35637
35732
|
for (const signal of snapshot.signals.values()) {
|
|
35638
|
-
for (let j = 0; j < signal.
|
|
35639
|
-
const guard = signal.
|
|
35733
|
+
for (let j = 0; j < signal.guard.conditions.length; j++) {
|
|
35734
|
+
const guard = signal.guard.conditions[j];
|
|
35640
35735
|
if (!guard) continue;
|
|
35641
35736
|
if (!byKey.has(guard.key)) byKey.set(guard.key, guard);
|
|
35642
35737
|
}
|
|
@@ -35666,7 +35761,7 @@ function buildGuardKey(guards) {
|
|
|
35666
35761
|
return keys.join("&");
|
|
35667
35762
|
}
|
|
35668
35763
|
function resolveCohortEvidenceKind(metrics) {
|
|
35669
|
-
let kind =
|
|
35764
|
+
let kind = 0 /* Exact */;
|
|
35670
35765
|
for (let i = 0; i < metrics.length; i++) {
|
|
35671
35766
|
const metric = metrics[i];
|
|
35672
35767
|
if (!metric) continue;
|
|
@@ -35683,9 +35778,9 @@ function incrementCount(counts, key) {
|
|
|
35683
35778
|
counts.set(key, existing + 1);
|
|
35684
35779
|
}
|
|
35685
35780
|
function toEvidenceKind2(certainty) {
|
|
35686
|
-
if (certainty ===
|
|
35687
|
-
if (certainty ===
|
|
35688
|
-
return
|
|
35781
|
+
if (certainty === 0 /* Resolved */) return 0 /* Exact */;
|
|
35782
|
+
if (certainty === 1 /* Conditional */) return 2 /* Conditional */;
|
|
35783
|
+
return 3 /* Unknown */;
|
|
35689
35784
|
}
|
|
35690
35785
|
function computeMedian(values) {
|
|
35691
35786
|
if (values.length === 0) return null;
|
|
@@ -35705,66 +35800,6 @@ function computeMedianAbsoluteDeviation(values, median, scratch) {
|
|
|
35705
35800
|
}
|
|
35706
35801
|
return computeMedian(scratch);
|
|
35707
35802
|
}
|
|
35708
|
-
function selectKth(values, targetIndex) {
|
|
35709
|
-
let left = 0;
|
|
35710
|
-
let right = values.length - 1;
|
|
35711
|
-
while (left <= right) {
|
|
35712
|
-
if (left === right) {
|
|
35713
|
-
const result = values[left];
|
|
35714
|
-
if (result === void 0) return 0;
|
|
35715
|
-
return result;
|
|
35716
|
-
}
|
|
35717
|
-
const pivotIndex = choosePivotIndex(values, left, right);
|
|
35718
|
-
const partitionIndex = partitionAroundPivot(values, left, right, pivotIndex);
|
|
35719
|
-
if (partitionIndex === targetIndex) {
|
|
35720
|
-
const result = values[partitionIndex];
|
|
35721
|
-
if (result === void 0) return 0;
|
|
35722
|
-
return result;
|
|
35723
|
-
}
|
|
35724
|
-
if (partitionIndex < targetIndex) {
|
|
35725
|
-
left = partitionIndex + 1;
|
|
35726
|
-
continue;
|
|
35727
|
-
}
|
|
35728
|
-
right = partitionIndex - 1;
|
|
35729
|
-
}
|
|
35730
|
-
const fallback = values[targetIndex];
|
|
35731
|
-
if (fallback === void 0) return 0;
|
|
35732
|
-
return fallback;
|
|
35733
|
-
}
|
|
35734
|
-
function choosePivotIndex(values, left, right) {
|
|
35735
|
-
const middle = Math.floor((left + right) / 2);
|
|
35736
|
-
const leftValue = values[left] ?? 0;
|
|
35737
|
-
const middleValue = values[middle] ?? 0;
|
|
35738
|
-
const rightValue = values[right] ?? 0;
|
|
35739
|
-
if (leftValue < middleValue) {
|
|
35740
|
-
if (middleValue < rightValue) return middle;
|
|
35741
|
-
if (leftValue < rightValue) return right;
|
|
35742
|
-
return left;
|
|
35743
|
-
}
|
|
35744
|
-
if (leftValue < rightValue) return left;
|
|
35745
|
-
if (middleValue < rightValue) return right;
|
|
35746
|
-
return middle;
|
|
35747
|
-
}
|
|
35748
|
-
function partitionAroundPivot(values, left, right, pivotIndex) {
|
|
35749
|
-
const pivotValue = values[pivotIndex] ?? 0;
|
|
35750
|
-
swap(values, pivotIndex, right);
|
|
35751
|
-
let storeIndex = left;
|
|
35752
|
-
for (let i = left; i < right; i++) {
|
|
35753
|
-
const current = values[i];
|
|
35754
|
-
if (current === void 0 || current > pivotValue) continue;
|
|
35755
|
-
swap(values, storeIndex, i);
|
|
35756
|
-
storeIndex++;
|
|
35757
|
-
}
|
|
35758
|
-
swap(values, storeIndex, right);
|
|
35759
|
-
return storeIndex;
|
|
35760
|
-
}
|
|
35761
|
-
function swap(values, left, right) {
|
|
35762
|
-
if (left === right) return;
|
|
35763
|
-
const leftValue = values[left] ?? 0;
|
|
35764
|
-
const rightValue = values[right] ?? 0;
|
|
35765
|
-
values[left] = rightValue;
|
|
35766
|
-
values[right] = leftValue;
|
|
35767
|
-
}
|
|
35768
35803
|
function resolveVerticalAlignConsensus(aggregate) {
|
|
35769
35804
|
if (aggregate.comparableCount === 0) return null;
|
|
35770
35805
|
if (aggregate.countsByValue.size !== 1) return null;
|
|
@@ -35863,7 +35898,7 @@ function resolveMeasurementCandidates(root, childrenByParentNode, snapshotByElem
|
|
|
35863
35898
|
if (firstControlOrReplacedDescendant === null && (child.isControl || child.isReplaced)) {
|
|
35864
35899
|
firstControlOrReplacedDescendant = child;
|
|
35865
35900
|
}
|
|
35866
|
-
if (firstTextualDescendant === null && child.textualContent ===
|
|
35901
|
+
if (firstTextualDescendant === null && child.textualContent === 0 /* Yes */) {
|
|
35867
35902
|
firstTextualDescendant = child;
|
|
35868
35903
|
}
|
|
35869
35904
|
if (firstControlOrReplacedDescendant !== null && firstTextualDescendant !== null) break;
|
|
@@ -35889,7 +35924,7 @@ function resolveMeasurementNode(root, candidates) {
|
|
|
35889
35924
|
if (candidates.firstControlOrReplacedDescendant !== null) return candidates.firstControlOrReplacedDescendant;
|
|
35890
35925
|
if (root.isControl || root.isReplaced) return root;
|
|
35891
35926
|
if (candidates.firstTextualDescendant !== null) return candidates.firstTextualDescendant;
|
|
35892
|
-
if (root.textualContent ===
|
|
35927
|
+
if (root.textualContent === 0 /* Yes */) return root;
|
|
35893
35928
|
return root;
|
|
35894
35929
|
}
|
|
35895
35930
|
|
|
@@ -35936,7 +35971,7 @@ function buildScopedSelectorIndexBySolidFile(cssScopeBySolidFile, css, selectorM
|
|
|
35936
35971
|
seenSelectorIds.add(selector.id);
|
|
35937
35972
|
const metadata = selectorMetadataById.get(selector.id);
|
|
35938
35973
|
if (!metadata) continue;
|
|
35939
|
-
if (metadata.guard.kind ===
|
|
35974
|
+
if (metadata.guard.kind === 1 /* Conditional */) {
|
|
35940
35975
|
if (!conditionalSelectorIds.has(selector.id)) {
|
|
35941
35976
|
conditionalSelectorIds.add(selector.id);
|
|
35942
35977
|
perf.selectorsGuardedConditional++;
|
|
@@ -35978,7 +36013,7 @@ function buildScopedSelectorIndexBySolidFile(cssScopeBySolidFile, css, selectorM
|
|
|
35978
36013
|
}
|
|
35979
36014
|
return out;
|
|
35980
36015
|
}
|
|
35981
|
-
function
|
|
36016
|
+
function buildSelectorCandidatesByNode(elements, scopedSelectorsBySolidFile, perf) {
|
|
35982
36017
|
const out = /* @__PURE__ */ new Map();
|
|
35983
36018
|
for (let i = 0; i < elements.length; i++) {
|
|
35984
36019
|
const node = elements[i];
|
|
@@ -35988,7 +36023,7 @@ function buildSelectorCandidatesByElementKey(elements, scopedSelectorsBySolidFil
|
|
|
35988
36023
|
const byTag = node.tagName !== null ? collectSelectorCandidates(scoped.bySubjectTag.get(node.tagName), node.selectorDispatchKeys) : EMPTY_SELECTOR_LIST;
|
|
35989
36024
|
const withoutTag = collectSelectorCandidates(scoped.withoutSubjectTag, node.selectorDispatchKeys);
|
|
35990
36025
|
const merged = mergeSelectorCandidateIds(byTag, withoutTag);
|
|
35991
|
-
out.set(node
|
|
36026
|
+
out.set(node, merged);
|
|
35992
36027
|
perf.elementsScanned++;
|
|
35993
36028
|
perf.selectorCandidatesChecked += merged.length;
|
|
35994
36029
|
}
|
|
@@ -36447,12 +36482,6 @@ var EMPTY_EXPANSION_RESULT = [];
|
|
|
36447
36482
|
function collectMonitoredDeclarations(selector, layerOrder, guard) {
|
|
36448
36483
|
const out = [];
|
|
36449
36484
|
const declarations = selector.rule.declarations;
|
|
36450
|
-
const signalGuard = guard.kind === "conditional" ? "conditional" : "unconditional";
|
|
36451
|
-
const guardProvenance = {
|
|
36452
|
-
kind: signalGuard,
|
|
36453
|
-
conditions: guard.conditions,
|
|
36454
|
-
key: guard.key
|
|
36455
|
-
};
|
|
36456
36485
|
for (let i = 0; i < declarations.length; i++) {
|
|
36457
36486
|
const declaration = declarations[i];
|
|
36458
36487
|
if (!declaration) continue;
|
|
@@ -36463,8 +36492,7 @@ function collectMonitoredDeclarations(selector, layerOrder, guard) {
|
|
|
36463
36492
|
out.push({
|
|
36464
36493
|
property: monitored,
|
|
36465
36494
|
value: declaration.value,
|
|
36466
|
-
|
|
36467
|
-
guardProvenance,
|
|
36495
|
+
guardProvenance: guard,
|
|
36468
36496
|
position: {
|
|
36469
36497
|
layer: declaration.cascadePosition.layer,
|
|
36470
36498
|
layerOrder,
|
|
@@ -36486,6 +36514,7 @@ function toMonitoredSignalKey(property) {
|
|
|
36486
36514
|
case "margin-block":
|
|
36487
36515
|
case "padding-block":
|
|
36488
36516
|
case "inset-block":
|
|
36517
|
+
case "flex-flow":
|
|
36489
36518
|
return property;
|
|
36490
36519
|
default:
|
|
36491
36520
|
return null;
|
|
@@ -36509,30 +36538,27 @@ function expandMonitoredDeclarationForDelta(declaration) {
|
|
|
36509
36538
|
if (signalName === void 0) return EMPTY_EXPANSION_RESULT;
|
|
36510
36539
|
return [{ name: signalName, value: value2 }];
|
|
36511
36540
|
}
|
|
36512
|
-
function appendMatchingEdgesFromSelectorIds(selectorIds, node,
|
|
36513
|
-
const fileRoots = rootElementsByFile.get(node.solidFile) ?? null;
|
|
36541
|
+
function appendMatchingEdgesFromSelectorIds(ctx, selectorIds, node, applies, appliesByElementNodeMutable) {
|
|
36542
|
+
const fileRoots = ctx.rootElementsByFile.get(node.solidFile) ?? null;
|
|
36514
36543
|
for (let i = 0; i < selectorIds.length; i++) {
|
|
36515
36544
|
const selectorId = selectorIds[i];
|
|
36516
36545
|
if (selectorId === void 0) continue;
|
|
36517
|
-
const metadata = selectorMetadataById.get(selectorId);
|
|
36546
|
+
const metadata = ctx.selectorMetadataById.get(selectorId);
|
|
36518
36547
|
if (!metadata || !metadata.matcher) {
|
|
36519
36548
|
throw new Error(`missing compiled selector matcher for selector ${selectorId}`);
|
|
36520
36549
|
}
|
|
36521
|
-
const selector = selectorsById.get(selectorId);
|
|
36550
|
+
const selector = ctx.selectorsById.get(selectorId);
|
|
36522
36551
|
if (!selector) {
|
|
36523
36552
|
throw new Error(`missing selector ${selectorId}`);
|
|
36524
36553
|
}
|
|
36525
|
-
if (!selectorMatchesLayoutElement(metadata.matcher, node, perf, fileRoots, logger)) continue;
|
|
36554
|
+
if (!selectorMatchesLayoutElement(metadata.matcher, node, ctx.perf, fileRoots, ctx.logger)) continue;
|
|
36526
36555
|
const edge = {
|
|
36527
|
-
solidFile: node.solidFile,
|
|
36528
|
-
elementId: node.elementId,
|
|
36529
|
-
elementKey: node.key,
|
|
36530
36556
|
selectorId: selector.id,
|
|
36531
36557
|
specificityScore: selector.specificityScore,
|
|
36532
36558
|
sourceOrder: selector.rule.sourceOrder
|
|
36533
36559
|
};
|
|
36534
36560
|
applies.push(edge);
|
|
36535
|
-
perf.matchEdgesCreated++;
|
|
36561
|
+
ctx.perf.matchEdgesCreated++;
|
|
36536
36562
|
const existing = appliesByElementNodeMutable.get(node);
|
|
36537
36563
|
if (existing) {
|
|
36538
36564
|
existing.push(edge);
|
|
@@ -36558,7 +36584,7 @@ function augmentCascadeWithTailwind(cascade, node, tailwind) {
|
|
|
36558
36584
|
const classTokens = node.classTokens;
|
|
36559
36585
|
if (classTokens.length === 0) return;
|
|
36560
36586
|
const guardProvenance = {
|
|
36561
|
-
kind:
|
|
36587
|
+
kind: 0 /* Unconditional */,
|
|
36562
36588
|
conditions: [],
|
|
36563
36589
|
key: "always"
|
|
36564
36590
|
};
|
|
@@ -36575,8 +36601,7 @@ function augmentCascadeWithTailwind(cascade, node, tailwind) {
|
|
|
36575
36601
|
if (cascade.has(property)) continue;
|
|
36576
36602
|
cascade.set(property, {
|
|
36577
36603
|
value: value2,
|
|
36578
|
-
source:
|
|
36579
|
-
guard: "unconditional",
|
|
36604
|
+
source: 0 /* Selector */,
|
|
36580
36605
|
guardProvenance
|
|
36581
36606
|
});
|
|
36582
36607
|
}
|
|
@@ -36596,8 +36621,7 @@ function buildCascadeMapForElement(node, edges, monitoredDeclarationsBySelectorI
|
|
|
36596
36621
|
const property = declaration.property;
|
|
36597
36622
|
const newDeclaration = {
|
|
36598
36623
|
value: declaration.value,
|
|
36599
|
-
source:
|
|
36600
|
-
guard: declaration.guard,
|
|
36624
|
+
source: 0 /* Selector */,
|
|
36601
36625
|
guardProvenance: declaration.guardProvenance
|
|
36602
36626
|
};
|
|
36603
36627
|
const existingPosition = positions.get(property);
|
|
@@ -36616,33 +36640,26 @@ function buildCascadeMapForElement(node, edges, monitoredDeclarationsBySelectorI
|
|
|
36616
36640
|
positions.set(property, declaration.position);
|
|
36617
36641
|
}
|
|
36618
36642
|
}
|
|
36619
|
-
const inlinePosition = createInlineCascadePosition();
|
|
36620
|
-
const inlineGuardProvenance = {
|
|
36621
|
-
kind: "unconditional",
|
|
36622
|
-
conditions: [],
|
|
36623
|
-
key: "always"
|
|
36624
|
-
};
|
|
36625
36643
|
for (const [property, value2] of node.inlineStyleValues) {
|
|
36626
36644
|
const newDeclaration = {
|
|
36627
36645
|
value: value2,
|
|
36628
|
-
source:
|
|
36629
|
-
|
|
36630
|
-
guardProvenance: inlineGuardProvenance
|
|
36646
|
+
source: 1 /* InlineStyle */,
|
|
36647
|
+
guardProvenance: INLINE_GUARD_PROVENANCE
|
|
36631
36648
|
};
|
|
36632
36649
|
const existingPosition = positions.get(property);
|
|
36633
36650
|
if (existingPosition === void 0) {
|
|
36634
36651
|
out.set(property, newDeclaration);
|
|
36635
|
-
positions.set(property,
|
|
36652
|
+
positions.set(property, INLINE_CASCADE_POSITION);
|
|
36636
36653
|
continue;
|
|
36637
36654
|
}
|
|
36638
36655
|
const existingDeclaration = out.get(property);
|
|
36639
36656
|
if (existingDeclaration === void 0) continue;
|
|
36640
36657
|
if (!doesCandidateOverride(
|
|
36641
36658
|
{ declaration: existingDeclaration, position: existingPosition },
|
|
36642
|
-
{ declaration: newDeclaration, position:
|
|
36659
|
+
{ declaration: newDeclaration, position: INLINE_CASCADE_POSITION }
|
|
36643
36660
|
)) continue;
|
|
36644
36661
|
out.set(property, newDeclaration);
|
|
36645
|
-
positions.set(property,
|
|
36662
|
+
positions.set(property, INLINE_CASCADE_POSITION);
|
|
36646
36663
|
}
|
|
36647
36664
|
if (tailwind !== null) {
|
|
36648
36665
|
augmentCascadeWithTailwind(out, node, tailwind);
|
|
@@ -36659,7 +36676,7 @@ function doesCandidateOverride(existing, incoming) {
|
|
|
36659
36676
|
const existingSource = existing.declaration.source;
|
|
36660
36677
|
const incomingSource = incoming.declaration.source;
|
|
36661
36678
|
if (existingSource !== incomingSource) {
|
|
36662
|
-
if (incomingSource ===
|
|
36679
|
+
if (incomingSource === 1 /* InlineStyle */) {
|
|
36663
36680
|
if (existing.position.isImportant && !incoming.position.isImportant) return false;
|
|
36664
36681
|
return true;
|
|
36665
36682
|
}
|
|
@@ -36667,16 +36684,19 @@ function doesCandidateOverride(existing, incoming) {
|
|
|
36667
36684
|
}
|
|
36668
36685
|
return compareCascadePositions(incoming.position, existing.position) > 0;
|
|
36669
36686
|
}
|
|
36670
|
-
|
|
36671
|
-
|
|
36672
|
-
|
|
36673
|
-
|
|
36674
|
-
|
|
36675
|
-
|
|
36676
|
-
|
|
36677
|
-
|
|
36678
|
-
|
|
36679
|
-
|
|
36687
|
+
var INLINE_CASCADE_POSITION = Object.freeze({
|
|
36688
|
+
layer: null,
|
|
36689
|
+
layerOrder: Number.MAX_SAFE_INTEGER,
|
|
36690
|
+
sourceOrder: Number.MAX_SAFE_INTEGER,
|
|
36691
|
+
specificity: [1, 0, 0, 0],
|
|
36692
|
+
specificityScore: Number.MAX_SAFE_INTEGER,
|
|
36693
|
+
isImportant: false
|
|
36694
|
+
});
|
|
36695
|
+
var INLINE_GUARD_PROVENANCE = Object.freeze({
|
|
36696
|
+
kind: 0 /* Unconditional */,
|
|
36697
|
+
conditions: [],
|
|
36698
|
+
key: "always"
|
|
36699
|
+
});
|
|
36680
36700
|
function resolveRuleLayerOrder(rule, css) {
|
|
36681
36701
|
const layer = rule.containingLayer;
|
|
36682
36702
|
if (!layer) return 0;
|
|
@@ -36684,14 +36704,14 @@ function resolveRuleLayerOrder(rule, css) {
|
|
|
36684
36704
|
if (!name) return 0;
|
|
36685
36705
|
return css.layerOrder.get(name) ?? 0;
|
|
36686
36706
|
}
|
|
36687
|
-
function buildConditionalDeltaIndex(elements,
|
|
36688
|
-
const
|
|
36707
|
+
function buildConditionalDeltaIndex(elements, appliesByNode, monitoredDeclarationsBySelectorId) {
|
|
36708
|
+
const conditionalSignalDeltaFactsByNode = /* @__PURE__ */ new Map();
|
|
36689
36709
|
const elementsWithConditionalDeltaBySignal = /* @__PURE__ */ new Map();
|
|
36690
|
-
const
|
|
36710
|
+
const baselineOffsetFactsByNode = /* @__PURE__ */ new Map();
|
|
36691
36711
|
for (let i = 0; i < elements.length; i++) {
|
|
36692
36712
|
const node = elements[i];
|
|
36693
36713
|
if (!node) continue;
|
|
36694
|
-
const edges =
|
|
36714
|
+
const edges = appliesByNode.get(node);
|
|
36695
36715
|
let factByProperty = null;
|
|
36696
36716
|
if (edges !== void 0 && edges.length > 0) {
|
|
36697
36717
|
const byProperty = /* @__PURE__ */ new Map();
|
|
@@ -36716,7 +36736,7 @@ function buildConditionalDeltaIndex(elements, appliesByElementKey, monitoredDecl
|
|
|
36716
36736
|
};
|
|
36717
36737
|
byProperty.set(property, bucket);
|
|
36718
36738
|
}
|
|
36719
|
-
if (declaration.
|
|
36739
|
+
if (declaration.guardProvenance.kind === 1 /* Conditional */) {
|
|
36720
36740
|
bucket.conditional.add(expandedEntry.value);
|
|
36721
36741
|
continue;
|
|
36722
36742
|
}
|
|
@@ -36756,7 +36776,7 @@ function buildConditionalDeltaIndex(elements, appliesByElementKey, monitoredDecl
|
|
|
36756
36776
|
}
|
|
36757
36777
|
if (facts.size > 0) {
|
|
36758
36778
|
factByProperty = facts;
|
|
36759
|
-
|
|
36779
|
+
conditionalSignalDeltaFactsByNode.set(node, facts);
|
|
36760
36780
|
for (const [signal, fact] of facts) {
|
|
36761
36781
|
if (!fact.hasConditional) continue;
|
|
36762
36782
|
const existing = elementsWithConditionalDeltaBySignal.get(signal);
|
|
@@ -36793,13 +36813,13 @@ function buildConditionalDeltaIndex(elements, appliesByElementKey, monitoredDecl
|
|
|
36793
36813
|
baselineBySignal.set(signal, [...values]);
|
|
36794
36814
|
}
|
|
36795
36815
|
if (baselineBySignal.size > 0) {
|
|
36796
|
-
|
|
36816
|
+
baselineOffsetFactsByNode.set(node, baselineBySignal);
|
|
36797
36817
|
}
|
|
36798
36818
|
}
|
|
36799
36819
|
return {
|
|
36800
|
-
|
|
36820
|
+
conditionalSignalDeltaFactsByNode,
|
|
36801
36821
|
elementsWithConditionalDeltaBySignal,
|
|
36802
|
-
|
|
36822
|
+
baselineOffsetFactsByNode
|
|
36803
36823
|
};
|
|
36804
36824
|
}
|
|
36805
36825
|
var EMPTY_NODE_LIST2 = [];
|
|
@@ -36926,8 +36946,8 @@ function getTextualContentState(element, memo, compositionMetaByElementId, logge
|
|
|
36926
36946
|
if (child.kind === "expression") {
|
|
36927
36947
|
if (isStructuralExpression(child.node)) {
|
|
36928
36948
|
if (logger.enabled) logger.trace(`[textual-content] element=${element.tagName ?? element.tag}#${element.id} \u2192 unknown (structural expression child)`);
|
|
36929
|
-
memo.set(element.id,
|
|
36930
|
-
return
|
|
36949
|
+
memo.set(element.id, 2 /* Unknown */);
|
|
36950
|
+
return 2 /* Unknown */;
|
|
36931
36951
|
}
|
|
36932
36952
|
hasTextOnlyExpression = true;
|
|
36933
36953
|
continue;
|
|
@@ -36935,8 +36955,8 @@ function getTextualContentState(element, memo, compositionMetaByElementId, logge
|
|
|
36935
36955
|
if (child.kind !== "text") continue;
|
|
36936
36956
|
if (child.node.type !== "JSXText") continue;
|
|
36937
36957
|
if (isBlank(child.node.value)) continue;
|
|
36938
|
-
memo.set(element.id,
|
|
36939
|
-
return
|
|
36958
|
+
memo.set(element.id, 0 /* Yes */);
|
|
36959
|
+
return 0 /* Yes */;
|
|
36940
36960
|
}
|
|
36941
36961
|
let childHasUnknown = false;
|
|
36942
36962
|
let childHasDynamicText = false;
|
|
@@ -36950,31 +36970,31 @@ function getTextualContentState(element, memo, compositionMetaByElementId, logge
|
|
|
36950
36970
|
if (logger.enabled) logger.trace(`[textual-content] element=${element.tagName ?? element.tag}#${element.id}: non-DOM child ${child.tag}#${child.id} resolves to control tag=${childMeta.tagName}, skipping`);
|
|
36951
36971
|
continue;
|
|
36952
36972
|
}
|
|
36953
|
-
if (childState !==
|
|
36973
|
+
if (childState !== 1 /* No */) {
|
|
36954
36974
|
if (logger.enabled) logger.trace(`[textual-content] element=${element.tagName ?? element.tag}#${element.id}: non-DOM child ${child.tag ?? child.id}#${child.id} has state=${childState} \u2192 childHasUnknown`);
|
|
36955
36975
|
childHasUnknown = true;
|
|
36956
36976
|
}
|
|
36957
36977
|
continue;
|
|
36958
36978
|
}
|
|
36959
|
-
if (childState ===
|
|
36960
|
-
memo.set(element.id,
|
|
36961
|
-
return
|
|
36979
|
+
if (childState === 0 /* Yes */) {
|
|
36980
|
+
memo.set(element.id, 0 /* Yes */);
|
|
36981
|
+
return 0 /* Yes */;
|
|
36962
36982
|
}
|
|
36963
|
-
if (childState ===
|
|
36964
|
-
if (childState ===
|
|
36983
|
+
if (childState === 2 /* Unknown */) childHasUnknown = true;
|
|
36984
|
+
if (childState === 3 /* DynamicText */) childHasDynamicText = true;
|
|
36965
36985
|
}
|
|
36966
36986
|
if (childHasUnknown) {
|
|
36967
36987
|
if (logger.enabled) logger.trace(`[textual-content] element=${element.tagName ?? element.tag}#${element.id} \u2192 unknown (child has unknown)`);
|
|
36968
|
-
memo.set(element.id,
|
|
36969
|
-
return
|
|
36988
|
+
memo.set(element.id, 2 /* Unknown */);
|
|
36989
|
+
return 2 /* Unknown */;
|
|
36970
36990
|
}
|
|
36971
36991
|
if (hasTextOnlyExpression || childHasDynamicText) {
|
|
36972
36992
|
if (logger.enabled) logger.trace(`[textual-content] element=${element.tagName ?? element.tag}#${element.id} \u2192 dynamic-text`);
|
|
36973
|
-
memo.set(element.id,
|
|
36974
|
-
return
|
|
36993
|
+
memo.set(element.id, 3 /* DynamicText */);
|
|
36994
|
+
return 3 /* DynamicText */;
|
|
36975
36995
|
}
|
|
36976
|
-
memo.set(element.id,
|
|
36977
|
-
return
|
|
36996
|
+
memo.set(element.id, 1 /* No */);
|
|
36997
|
+
return 1 /* No */;
|
|
36978
36998
|
}
|
|
36979
36999
|
function isStructuralExpression(node) {
|
|
36980
37000
|
if (node.type !== "JSXExpressionContainer") return false;
|
|
@@ -37273,8 +37293,6 @@ function buildLayoutGraph(solids, css, logger = noopLogger) {
|
|
|
37273
37293
|
classTokens: record.classTokens,
|
|
37274
37294
|
classTokenSet: record.classTokenSet,
|
|
37275
37295
|
inlineStyleKeys: record.inlineStyleKeys,
|
|
37276
|
-
parentElementId,
|
|
37277
|
-
parentElementKey: parentNode ? parentNode.key : parentElementId === null ? null : toLayoutElementKey(solid.file, parentElementId),
|
|
37278
37296
|
parentElementNode: parentNode,
|
|
37279
37297
|
previousSiblingNode,
|
|
37280
37298
|
siblingIndex,
|
|
@@ -37315,22 +37333,25 @@ function buildLayoutGraph(solids, css, logger = noopLogger) {
|
|
|
37315
37333
|
logger.debug(`[build] rootElementsByFile file=${file} count=${roots.length}: ${descs.join(", ")}`);
|
|
37316
37334
|
}
|
|
37317
37335
|
}
|
|
37318
|
-
const
|
|
37336
|
+
const selectorCandidatesByNode = buildSelectorCandidatesByNode(elements, scopedSelectorsBySolidFile, perf);
|
|
37337
|
+
const selectorMatchCtx = {
|
|
37338
|
+
selectorMetadataById,
|
|
37339
|
+
selectorsById,
|
|
37340
|
+
rootElementsByFile,
|
|
37341
|
+
perf,
|
|
37342
|
+
logger
|
|
37343
|
+
};
|
|
37319
37344
|
for (let i = 0; i < elements.length; i++) {
|
|
37320
37345
|
const node = elements[i];
|
|
37321
37346
|
if (!node) continue;
|
|
37322
|
-
const selectorIds =
|
|
37347
|
+
const selectorIds = selectorCandidatesByNode.get(node) ?? EMPTY_NUMBER_LIST2;
|
|
37323
37348
|
if (selectorIds.length === 0) continue;
|
|
37324
37349
|
appendMatchingEdgesFromSelectorIds(
|
|
37350
|
+
selectorMatchCtx,
|
|
37325
37351
|
selectorIds,
|
|
37326
37352
|
node,
|
|
37327
|
-
selectorMetadataById,
|
|
37328
|
-
selectorsById,
|
|
37329
37353
|
applies,
|
|
37330
|
-
appliesByElementNodeMutable
|
|
37331
|
-
perf,
|
|
37332
|
-
rootElementsByFile,
|
|
37333
|
-
logger
|
|
37354
|
+
appliesByElementNodeMutable
|
|
37334
37355
|
);
|
|
37335
37356
|
}
|
|
37336
37357
|
perf.selectorMatchMs = performance.now() - selectorMatchStartedAt;
|
|
@@ -37338,7 +37359,7 @@ function buildLayoutGraph(solids, css, logger = noopLogger) {
|
|
|
37338
37359
|
for (const edges of appliesByElementNodeMutable.values()) {
|
|
37339
37360
|
edges.sort(compareLayoutEdge);
|
|
37340
37361
|
}
|
|
37341
|
-
const
|
|
37362
|
+
const appliesByNode = /* @__PURE__ */ new Map();
|
|
37342
37363
|
const tailwind = css.tailwind;
|
|
37343
37364
|
for (let i = 0; i < elements.length; i++) {
|
|
37344
37365
|
const node = elements[i];
|
|
@@ -37346,7 +37367,7 @@ function buildLayoutGraph(solids, css, logger = noopLogger) {
|
|
|
37346
37367
|
const edges = appliesByElementNodeMutable.get(node) ?? [];
|
|
37347
37368
|
const cascade = buildCascadeMapForElement(node, edges, monitoredDeclarationsBySelectorId, tailwind);
|
|
37348
37369
|
cascadeByElementNode.set(node, cascade);
|
|
37349
|
-
|
|
37370
|
+
appliesByNode.set(node, edges);
|
|
37350
37371
|
}
|
|
37351
37372
|
perf.cascadeBuildMs = performance.now() - cascadeStartedAt;
|
|
37352
37373
|
const snapshotByElementNode = buildSignalSnapshotIndex(elements, cascadeByElementNode, perf);
|
|
@@ -37354,7 +37375,7 @@ function buildLayoutGraph(solids, css, logger = noopLogger) {
|
|
|
37354
37375
|
const factIndex = buildElementFactIndex(elements, snapshotByElementNode);
|
|
37355
37376
|
const conditionalDeltaIndex = buildConditionalDeltaIndex(
|
|
37356
37377
|
elements,
|
|
37357
|
-
|
|
37378
|
+
appliesByNode,
|
|
37358
37379
|
monitoredDeclarationsBySelectorId
|
|
37359
37380
|
);
|
|
37360
37381
|
const elementsWithConditionalOverflowDelta = buildConditionalDeltaSignalGroupElements(
|
|
@@ -37372,7 +37393,7 @@ function buildLayoutGraph(solids, css, logger = noopLogger) {
|
|
|
37372
37393
|
contextByParentNode,
|
|
37373
37394
|
measurementNodeByRootKey,
|
|
37374
37395
|
snapshotByElementNode,
|
|
37375
|
-
|
|
37396
|
+
snapshotHotSignalsByNode: factIndex.snapshotHotSignalsByNode
|
|
37376
37397
|
});
|
|
37377
37398
|
finalizeTableCellBaselineRelevance(contextByParentNode, cohortIndex.verticalAlignConsensusByParent);
|
|
37378
37399
|
perf.conditionalSignals = cohortIndex.conditionalSignals;
|
|
@@ -37388,11 +37409,11 @@ function buildLayoutGraph(solids, css, logger = noopLogger) {
|
|
|
37388
37409
|
childrenByParentNode: childrenByParentNodeMutable,
|
|
37389
37410
|
elementBySolidFileAndId: elementBySolidFileAndIdMutable,
|
|
37390
37411
|
elementRefsBySolidFileAndId: elementRefsBySolidFileAndIdMutable,
|
|
37391
|
-
|
|
37392
|
-
|
|
37412
|
+
appliesByNode,
|
|
37413
|
+
selectorCandidatesByNode,
|
|
37393
37414
|
selectorsById,
|
|
37394
37415
|
measurementNodeByRootKey,
|
|
37395
|
-
|
|
37416
|
+
snapshotHotSignalsByNode: factIndex.snapshotHotSignalsByNode,
|
|
37396
37417
|
elementsByTagName: factIndex.elementsByTagName,
|
|
37397
37418
|
elementsWithConditionalDeltaBySignal: conditionalDeltaIndex.elementsWithConditionalDeltaBySignal,
|
|
37398
37419
|
elementsWithConditionalOverflowDelta,
|
|
@@ -37400,12 +37421,12 @@ function buildLayoutGraph(solids, css, logger = noopLogger) {
|
|
|
37400
37421
|
elementsByKnownSignalValue: factIndex.elementsByKnownSignalValue,
|
|
37401
37422
|
dynamicSlotCandidateElements: factIndex.dynamicSlotCandidateElements,
|
|
37402
37423
|
scrollContainerElements: factIndex.scrollContainerElements,
|
|
37403
|
-
|
|
37404
|
-
|
|
37405
|
-
|
|
37406
|
-
|
|
37407
|
-
|
|
37408
|
-
|
|
37424
|
+
reservedSpaceFactsByNode: factIndex.reservedSpaceFactsByNode,
|
|
37425
|
+
scrollContainerFactsByNode: factIndex.scrollContainerFactsByNode,
|
|
37426
|
+
flowParticipationFactsByNode: factIndex.flowParticipationFactsByNode,
|
|
37427
|
+
containingBlockFactsByNode: factIndex.containingBlockFactsByNode,
|
|
37428
|
+
conditionalSignalDeltaFactsByNode: conditionalDeltaIndex.conditionalSignalDeltaFactsByNode,
|
|
37429
|
+
baselineOffsetFactsByNode: conditionalDeltaIndex.baselineOffsetFactsByNode,
|
|
37409
37430
|
statefulSelectorEntriesByRuleId: statefulRuleIndexes.selectorEntriesByRuleId,
|
|
37410
37431
|
statefulNormalizedDeclarationsByRuleId: statefulRuleIndexes.normalizedDeclarationsByRuleId,
|
|
37411
37432
|
statefulBaseValueIndex: statefulRuleIndexes.baseValueIndex,
|
|
@@ -37417,11 +37438,11 @@ function buildLayoutGraph(solids, css, logger = noopLogger) {
|
|
|
37417
37438
|
};
|
|
37418
37439
|
}
|
|
37419
37440
|
function buildElementFactIndex(elements, snapshotByElementNode) {
|
|
37420
|
-
const
|
|
37421
|
-
const
|
|
37422
|
-
const
|
|
37423
|
-
const
|
|
37424
|
-
const
|
|
37441
|
+
const reservedSpaceFactsByNode = /* @__PURE__ */ new Map();
|
|
37442
|
+
const scrollContainerFactsByNode = /* @__PURE__ */ new Map();
|
|
37443
|
+
const flowParticipationFactsByNode = /* @__PURE__ */ new Map();
|
|
37444
|
+
const containingBlockFactsByNode = /* @__PURE__ */ new Map();
|
|
37445
|
+
const snapshotHotSignalsByNode = /* @__PURE__ */ new Map();
|
|
37425
37446
|
const elementsByTagName = /* @__PURE__ */ new Map();
|
|
37426
37447
|
const elementsByKnownSignalValue = /* @__PURE__ */ new Map();
|
|
37427
37448
|
const dynamicSlotCandidateElements = [];
|
|
@@ -37431,7 +37452,7 @@ function buildElementFactIndex(elements, snapshotByElementNode) {
|
|
|
37431
37452
|
const node = elements[i];
|
|
37432
37453
|
if (!node) continue;
|
|
37433
37454
|
const snapshot = snapshotByElementNode.get(node);
|
|
37434
|
-
if (node.textualContent ===
|
|
37455
|
+
if (node.textualContent === 2 /* Unknown */ && node.siblingCount >= 2) {
|
|
37435
37456
|
dynamicSlotCandidateElements.push(node);
|
|
37436
37457
|
}
|
|
37437
37458
|
if (node.tagName) {
|
|
@@ -37452,18 +37473,18 @@ function buildElementFactIndex(elements, snapshotByElementNode) {
|
|
|
37452
37473
|
nearestPositionedAncestorHasReservedSpace = parentPositioned.hasReservedSpace;
|
|
37453
37474
|
}
|
|
37454
37475
|
}
|
|
37455
|
-
|
|
37476
|
+
containingBlockFactsByNode.set(node, {
|
|
37456
37477
|
nearestPositionedAncestorKey,
|
|
37457
37478
|
nearestPositionedAncestorHasReservedSpace
|
|
37458
37479
|
});
|
|
37459
37480
|
if (!snapshot) continue;
|
|
37460
37481
|
const reservedSpaceFact = computeReservedSpaceFact(snapshot);
|
|
37461
|
-
|
|
37482
|
+
reservedSpaceFactsByNode.set(node, reservedSpaceFact);
|
|
37462
37483
|
const scrollFact = computeScrollContainerFact(snapshot);
|
|
37463
|
-
|
|
37484
|
+
scrollContainerFactsByNode.set(node, scrollFact);
|
|
37464
37485
|
if (scrollFact.isScrollContainer) scrollContainerElements.push(node);
|
|
37465
|
-
|
|
37466
|
-
|
|
37486
|
+
flowParticipationFactsByNode.set(node, computeFlowParticipationFact(snapshot));
|
|
37487
|
+
snapshotHotSignalsByNode.set(node, computeHotSignals(snapshot));
|
|
37467
37488
|
const positionSignal = snapshot.signals.get("position");
|
|
37468
37489
|
const isPositioned = positionSignal !== void 0 && positionSignal.kind === "known" && positionSignal.normalized !== "static";
|
|
37469
37490
|
if (isPositioned) {
|
|
@@ -37494,49 +37515,163 @@ function buildElementFactIndex(elements, snapshotByElementNode) {
|
|
|
37494
37515
|
}
|
|
37495
37516
|
}
|
|
37496
37517
|
return {
|
|
37497
|
-
|
|
37498
|
-
|
|
37518
|
+
reservedSpaceFactsByNode,
|
|
37519
|
+
scrollContainerFactsByNode,
|
|
37499
37520
|
scrollContainerElements,
|
|
37500
|
-
|
|
37501
|
-
|
|
37502
|
-
|
|
37521
|
+
flowParticipationFactsByNode,
|
|
37522
|
+
containingBlockFactsByNode,
|
|
37523
|
+
snapshotHotSignalsByNode,
|
|
37503
37524
|
elementsByTagName,
|
|
37504
37525
|
elementsByKnownSignalValue,
|
|
37505
37526
|
dynamicSlotCandidateElements
|
|
37506
37527
|
};
|
|
37507
37528
|
}
|
|
37508
|
-
|
|
37529
|
+
var ABSENT_NUMERIC = Object.freeze({
|
|
37530
|
+
present: false,
|
|
37531
|
+
value: null,
|
|
37532
|
+
kind: 3 /* Unknown */
|
|
37533
|
+
});
|
|
37534
|
+
var ABSENT_NORMALIZED = Object.freeze({
|
|
37535
|
+
present: false,
|
|
37536
|
+
value: null,
|
|
37537
|
+
kind: 3 /* Unknown */
|
|
37538
|
+
});
|
|
37539
|
+
function toHotNumeric(signal) {
|
|
37540
|
+
if (signal.kind !== "known") {
|
|
37541
|
+
return {
|
|
37542
|
+
present: true,
|
|
37543
|
+
value: null,
|
|
37544
|
+
kind: signal.guard.kind === 1 /* Conditional */ ? 2 /* Conditional */ : 3 /* Unknown */
|
|
37545
|
+
};
|
|
37546
|
+
}
|
|
37509
37547
|
return {
|
|
37510
|
-
|
|
37511
|
-
|
|
37512
|
-
|
|
37513
|
-
placeSelf: computeHotNormalized(snapshot, "place-self"),
|
|
37514
|
-
writingMode: computeHotNormalized(snapshot, "writing-mode"),
|
|
37515
|
-
direction: computeHotNormalized(snapshot, "direction"),
|
|
37516
|
-
display: computeHotNormalized(snapshot, "display"),
|
|
37517
|
-
alignItems: computeHotNormalized(snapshot, "align-items"),
|
|
37518
|
-
placeItems: computeHotNormalized(snapshot, "place-items"),
|
|
37519
|
-
position: computeHotNormalized(snapshot, "position"),
|
|
37520
|
-
insetBlockStart: computeHotNumeric(snapshot, "inset-block-start"),
|
|
37521
|
-
insetBlockEnd: computeHotNumeric(snapshot, "inset-block-end"),
|
|
37522
|
-
transform: computeHotNumeric(snapshot, "transform"),
|
|
37523
|
-
translate: computeHotNumeric(snapshot, "translate"),
|
|
37524
|
-
top: computeHotNumeric(snapshot, "top"),
|
|
37525
|
-
bottom: computeHotNumeric(snapshot, "bottom"),
|
|
37526
|
-
marginTop: computeHotNumeric(snapshot, "margin-top"),
|
|
37527
|
-
marginBottom: computeHotNumeric(snapshot, "margin-bottom")
|
|
37548
|
+
present: true,
|
|
37549
|
+
value: signal.px,
|
|
37550
|
+
kind: signal.guard.kind === 1 /* Conditional */ ? 2 /* Conditional */ : signal.quality === "estimated" ? 1 /* Interval */ : 0 /* Exact */
|
|
37528
37551
|
};
|
|
37529
37552
|
}
|
|
37530
|
-
function
|
|
37553
|
+
function toHotNormalized(signal) {
|
|
37554
|
+
if (signal.kind !== "known") {
|
|
37555
|
+
return {
|
|
37556
|
+
present: true,
|
|
37557
|
+
value: null,
|
|
37558
|
+
kind: signal.guard.kind === 1 /* Conditional */ ? 2 /* Conditional */ : 3 /* Unknown */
|
|
37559
|
+
};
|
|
37560
|
+
}
|
|
37531
37561
|
return {
|
|
37532
|
-
present:
|
|
37533
|
-
|
|
37562
|
+
present: true,
|
|
37563
|
+
value: signal.normalized,
|
|
37564
|
+
kind: signal.guard.kind === 1 /* Conditional */ ? 2 /* Conditional */ : signal.quality === "estimated" ? 1 /* Interval */ : 0 /* Exact */
|
|
37534
37565
|
};
|
|
37535
37566
|
}
|
|
37536
|
-
function
|
|
37567
|
+
function computeHotSignals(snapshot) {
|
|
37568
|
+
let lineHeight = ABSENT_NUMERIC;
|
|
37569
|
+
let verticalAlign = ABSENT_NORMALIZED;
|
|
37570
|
+
let alignSelf = ABSENT_NORMALIZED;
|
|
37571
|
+
let placeSelf = ABSENT_NORMALIZED;
|
|
37572
|
+
let flexDirection = ABSENT_NORMALIZED;
|
|
37573
|
+
let gridAutoFlow = ABSENT_NORMALIZED;
|
|
37574
|
+
let writingMode = ABSENT_NORMALIZED;
|
|
37575
|
+
let direction = ABSENT_NORMALIZED;
|
|
37576
|
+
let display = ABSENT_NORMALIZED;
|
|
37577
|
+
let alignItems = ABSENT_NORMALIZED;
|
|
37578
|
+
let placeItems = ABSENT_NORMALIZED;
|
|
37579
|
+
let position = ABSENT_NORMALIZED;
|
|
37580
|
+
let insetBlockStart = ABSENT_NUMERIC;
|
|
37581
|
+
let insetBlockEnd = ABSENT_NUMERIC;
|
|
37582
|
+
let transform = ABSENT_NUMERIC;
|
|
37583
|
+
let translate = ABSENT_NUMERIC;
|
|
37584
|
+
let top = ABSENT_NUMERIC;
|
|
37585
|
+
let bottom = ABSENT_NUMERIC;
|
|
37586
|
+
let marginTop = ABSENT_NUMERIC;
|
|
37587
|
+
let marginBottom = ABSENT_NUMERIC;
|
|
37588
|
+
for (const [name, value2] of snapshot.signals) {
|
|
37589
|
+
switch (name) {
|
|
37590
|
+
case "line-height":
|
|
37591
|
+
lineHeight = toHotNumeric(value2);
|
|
37592
|
+
break;
|
|
37593
|
+
case "vertical-align":
|
|
37594
|
+
verticalAlign = toHotNormalized(value2);
|
|
37595
|
+
break;
|
|
37596
|
+
case "align-self":
|
|
37597
|
+
alignSelf = toHotNormalized(value2);
|
|
37598
|
+
break;
|
|
37599
|
+
case "place-self":
|
|
37600
|
+
placeSelf = toHotNormalized(value2);
|
|
37601
|
+
break;
|
|
37602
|
+
case "flex-direction":
|
|
37603
|
+
flexDirection = toHotNormalized(value2);
|
|
37604
|
+
break;
|
|
37605
|
+
case "grid-auto-flow":
|
|
37606
|
+
gridAutoFlow = toHotNormalized(value2);
|
|
37607
|
+
break;
|
|
37608
|
+
case "writing-mode":
|
|
37609
|
+
writingMode = toHotNormalized(value2);
|
|
37610
|
+
break;
|
|
37611
|
+
case "direction":
|
|
37612
|
+
direction = toHotNormalized(value2);
|
|
37613
|
+
break;
|
|
37614
|
+
case "display":
|
|
37615
|
+
display = toHotNormalized(value2);
|
|
37616
|
+
break;
|
|
37617
|
+
case "align-items":
|
|
37618
|
+
alignItems = toHotNormalized(value2);
|
|
37619
|
+
break;
|
|
37620
|
+
case "place-items":
|
|
37621
|
+
placeItems = toHotNormalized(value2);
|
|
37622
|
+
break;
|
|
37623
|
+
case "position":
|
|
37624
|
+
position = toHotNormalized(value2);
|
|
37625
|
+
break;
|
|
37626
|
+
case "inset-block-start":
|
|
37627
|
+
insetBlockStart = toHotNumeric(value2);
|
|
37628
|
+
break;
|
|
37629
|
+
case "inset-block-end":
|
|
37630
|
+
insetBlockEnd = toHotNumeric(value2);
|
|
37631
|
+
break;
|
|
37632
|
+
case "transform":
|
|
37633
|
+
transform = toHotNumeric(value2);
|
|
37634
|
+
break;
|
|
37635
|
+
case "translate":
|
|
37636
|
+
translate = toHotNumeric(value2);
|
|
37637
|
+
break;
|
|
37638
|
+
case "top":
|
|
37639
|
+
top = toHotNumeric(value2);
|
|
37640
|
+
break;
|
|
37641
|
+
case "bottom":
|
|
37642
|
+
bottom = toHotNumeric(value2);
|
|
37643
|
+
break;
|
|
37644
|
+
case "margin-top":
|
|
37645
|
+
marginTop = toHotNumeric(value2);
|
|
37646
|
+
break;
|
|
37647
|
+
case "margin-bottom":
|
|
37648
|
+
marginBottom = toHotNumeric(value2);
|
|
37649
|
+
break;
|
|
37650
|
+
default:
|
|
37651
|
+
break;
|
|
37652
|
+
}
|
|
37653
|
+
}
|
|
37537
37654
|
return {
|
|
37538
|
-
|
|
37539
|
-
|
|
37655
|
+
lineHeight,
|
|
37656
|
+
verticalAlign,
|
|
37657
|
+
alignSelf,
|
|
37658
|
+
placeSelf,
|
|
37659
|
+
flexDirection,
|
|
37660
|
+
gridAutoFlow,
|
|
37661
|
+
writingMode,
|
|
37662
|
+
direction,
|
|
37663
|
+
display,
|
|
37664
|
+
alignItems,
|
|
37665
|
+
placeItems,
|
|
37666
|
+
position,
|
|
37667
|
+
insetBlockStart,
|
|
37668
|
+
insetBlockEnd,
|
|
37669
|
+
transform,
|
|
37670
|
+
translate,
|
|
37671
|
+
top,
|
|
37672
|
+
bottom,
|
|
37673
|
+
marginTop,
|
|
37674
|
+
marginBottom
|
|
37540
37675
|
};
|
|
37541
37676
|
}
|
|
37542
37677
|
function computeReservedSpaceFact(snapshot) {
|
|
@@ -37571,15 +37706,14 @@ function computeReservedSpaceFact(snapshot) {
|
|
|
37571
37706
|
function hasPositiveOrDeclaredDimension(snapshot, property) {
|
|
37572
37707
|
const signal = snapshot.signals.get(property);
|
|
37573
37708
|
if (!signal) return false;
|
|
37574
|
-
if (signal.guard !==
|
|
37709
|
+
if (signal.guard.kind !== 0 /* Unconditional */) return false;
|
|
37575
37710
|
let normalized = "";
|
|
37576
37711
|
if (signal.kind === "known") {
|
|
37577
37712
|
if (signal.px !== null) return signal.px > 0;
|
|
37578
37713
|
normalized = signal.normalized.trim().toLowerCase();
|
|
37579
37714
|
}
|
|
37580
37715
|
if (signal.kind === "unknown") {
|
|
37581
|
-
|
|
37582
|
-
normalized = signal.raw.trim().toLowerCase();
|
|
37716
|
+
return signal.source !== null;
|
|
37583
37717
|
}
|
|
37584
37718
|
if (normalized.length === 0) return false;
|
|
37585
37719
|
if (isNonReservingDimension(normalized)) return false;
|
|
@@ -37588,15 +37722,14 @@ function hasPositiveOrDeclaredDimension(snapshot, property) {
|
|
|
37588
37722
|
function hasUsableAspectRatio(snapshot) {
|
|
37589
37723
|
const signal = snapshot.signals.get("aspect-ratio");
|
|
37590
37724
|
if (!signal) return false;
|
|
37591
|
-
if (signal.guard !==
|
|
37725
|
+
if (signal.guard.kind !== 0 /* Unconditional */) return false;
|
|
37726
|
+
if (signal.kind === "unknown") {
|
|
37727
|
+
return false;
|
|
37728
|
+
}
|
|
37592
37729
|
let normalized = "";
|
|
37593
37730
|
if (signal.kind === "known") {
|
|
37594
37731
|
normalized = signal.normalized.trim().toLowerCase();
|
|
37595
37732
|
}
|
|
37596
|
-
if (signal.kind === "unknown") {
|
|
37597
|
-
if (signal.raw === null) return false;
|
|
37598
|
-
normalized = signal.raw.trim().toLowerCase();
|
|
37599
|
-
}
|
|
37600
37733
|
if (normalized.length === 0) return false;
|
|
37601
37734
|
return normalized !== "auto";
|
|
37602
37735
|
}
|
|
@@ -37614,8 +37747,8 @@ function computeScrollContainerFact(snapshot) {
|
|
|
37614
37747
|
const yFromLonghand = parseSingleAxisScroll(overflowY);
|
|
37615
37748
|
const xScroll = shorthandAxis.x;
|
|
37616
37749
|
const yScroll = yFromLonghand === null ? shorthandAxis.y : yFromLonghand;
|
|
37617
|
-
const hasConditionalScroll = overflowSignal?.guard ===
|
|
37618
|
-
const hasUnconditionalScroll = overflowSignal?.guard ===
|
|
37750
|
+
const hasConditionalScroll = overflowSignal?.guard.kind === 1 /* Conditional */ && (shorthandAxis.x || shorthandAxis.y) || overflowYSignal?.guard.kind === 1 /* Conditional */ && yFromLonghand === true;
|
|
37751
|
+
const hasUnconditionalScroll = overflowSignal?.guard.kind === 0 /* Unconditional */ && (shorthandAxis.x || shorthandAxis.y) || overflowYSignal?.guard.kind === 0 /* Unconditional */ && yFromLonghand === true;
|
|
37619
37752
|
return {
|
|
37620
37753
|
isScrollContainer: xScroll || yScroll,
|
|
37621
37754
|
axis: toScrollAxis(xScroll, yScroll),
|
|
@@ -37625,18 +37758,18 @@ function computeScrollContainerFact(snapshot) {
|
|
|
37625
37758
|
hasUnconditionalScroll
|
|
37626
37759
|
};
|
|
37627
37760
|
}
|
|
37761
|
+
var NO_SCROLL = Object.freeze({ x: false, y: false });
|
|
37762
|
+
var BOTH_SCROLL = Object.freeze({ x: true, y: true });
|
|
37628
37763
|
function parseOverflowShorthandAxis(value2) {
|
|
37629
|
-
if (value2 === null) return
|
|
37630
|
-
const
|
|
37631
|
-
|
|
37632
|
-
|
|
37633
|
-
|
|
37634
|
-
|
|
37635
|
-
|
|
37636
|
-
|
|
37637
|
-
|
|
37638
|
-
const second = tokens[1];
|
|
37639
|
-
if (!second) return { x: SCROLLABLE_VALUES.has(first), y: false };
|
|
37764
|
+
if (value2 === null) return NO_SCROLL;
|
|
37765
|
+
const trimmed = value2.trim();
|
|
37766
|
+
const spaceIdx = trimmed.indexOf(" ");
|
|
37767
|
+
if (spaceIdx === -1) {
|
|
37768
|
+
const scroll = SCROLLABLE_VALUES.has(trimmed);
|
|
37769
|
+
return scroll ? BOTH_SCROLL : NO_SCROLL;
|
|
37770
|
+
}
|
|
37771
|
+
const first = trimmed.slice(0, spaceIdx);
|
|
37772
|
+
const second = trimmed.slice(spaceIdx + 1).trimStart();
|
|
37640
37773
|
return {
|
|
37641
37774
|
x: SCROLLABLE_VALUES.has(first),
|
|
37642
37775
|
y: SCROLLABLE_VALUES.has(second)
|
|
@@ -37644,16 +37777,16 @@ function parseOverflowShorthandAxis(value2) {
|
|
|
37644
37777
|
}
|
|
37645
37778
|
function parseSingleAxisScroll(value2) {
|
|
37646
37779
|
if (value2 === null) return null;
|
|
37647
|
-
const
|
|
37648
|
-
const
|
|
37649
|
-
|
|
37780
|
+
const trimmed = value2.trim();
|
|
37781
|
+
const spaceIdx = trimmed.indexOf(" ");
|
|
37782
|
+
const first = spaceIdx === -1 ? trimmed : trimmed.slice(0, spaceIdx);
|
|
37650
37783
|
return SCROLLABLE_VALUES.has(first);
|
|
37651
37784
|
}
|
|
37652
37785
|
function toScrollAxis(x, y) {
|
|
37653
|
-
if (x && y) return
|
|
37654
|
-
if (x) return
|
|
37655
|
-
if (y) return
|
|
37656
|
-
return
|
|
37786
|
+
if (x && y) return 3 /* Both */;
|
|
37787
|
+
if (x) return 1 /* X */;
|
|
37788
|
+
if (y) return 2 /* Y */;
|
|
37789
|
+
return 0 /* None */;
|
|
37657
37790
|
}
|
|
37658
37791
|
function computeFlowParticipationFact(snapshot) {
|
|
37659
37792
|
const signal = snapshot.signals.get("position");
|
|
@@ -37670,8 +37803,8 @@ function computeFlowParticipationFact(snapshot) {
|
|
|
37670
37803
|
return {
|
|
37671
37804
|
inFlow: !outOfFlow,
|
|
37672
37805
|
position,
|
|
37673
|
-
hasConditionalOutOfFlow: signal.guard ===
|
|
37674
|
-
hasUnconditionalOutOfFlow: signal.guard ===
|
|
37806
|
+
hasConditionalOutOfFlow: signal.guard.kind === 1 /* Conditional */ && outOfFlow,
|
|
37807
|
+
hasUnconditionalOutOfFlow: signal.guard.kind === 0 /* Unconditional */ && outOfFlow
|
|
37675
37808
|
};
|
|
37676
37809
|
}
|
|
37677
37810
|
function buildContextIndex(childrenByParentNode, snapshotByElementNode, perf) {
|
|
@@ -37746,7 +37879,7 @@ function collectAlignmentCases(context) {
|
|
|
37746
37879
|
subjectDeclaredOffsetDeviation,
|
|
37747
37880
|
subjectEffectiveOffsetDeviation,
|
|
37748
37881
|
subjectLineHeightDeviation,
|
|
37749
|
-
subjectStats.element.snapshot.textualContent,
|
|
37882
|
+
subjectStats.element.snapshot.node.textualContent,
|
|
37750
37883
|
subjectStats.element,
|
|
37751
37884
|
subjectStats.contentComposition,
|
|
37752
37885
|
cohortContentCompositions
|
|
@@ -37839,26 +37972,26 @@ function coverageFromNumeric(value2) {
|
|
|
37839
37972
|
}
|
|
37840
37973
|
function coverageFromConflict(value2) {
|
|
37841
37974
|
const certainty = coverageFromKind(value2.kind);
|
|
37842
|
-
if (value2.value ===
|
|
37975
|
+
if (value2.value === 2 /* Unknown */) return certainty * 0.4;
|
|
37843
37976
|
return certainty;
|
|
37844
37977
|
}
|
|
37845
37978
|
function coverageFromTextContrast(value2) {
|
|
37846
|
-
if (value2 ===
|
|
37979
|
+
if (value2 === 2 /* Unknown */) return 0.35;
|
|
37847
37980
|
return 1;
|
|
37848
37981
|
}
|
|
37849
37982
|
function coverageFromSubjectText(subjectTextualContent) {
|
|
37850
|
-
if (subjectTextualContent ===
|
|
37983
|
+
if (subjectTextualContent === 2 /* Unknown */) return 0.35;
|
|
37851
37984
|
return 1;
|
|
37852
37985
|
}
|
|
37853
37986
|
function coverageFromContextCertainty(certainty) {
|
|
37854
|
-
if (certainty ===
|
|
37855
|
-
if (certainty ===
|
|
37987
|
+
if (certainty === 0 /* Resolved */) return 1;
|
|
37988
|
+
if (certainty === 1 /* Conditional */) return 0.55;
|
|
37856
37989
|
return 0.25;
|
|
37857
37990
|
}
|
|
37858
37991
|
function coverageFromKind(kind) {
|
|
37859
|
-
if (kind ===
|
|
37860
|
-
if (kind ===
|
|
37861
|
-
if (kind ===
|
|
37992
|
+
if (kind === 0 /* Exact */) return 1;
|
|
37993
|
+
if (kind === 1 /* Interval */) return 0.78;
|
|
37994
|
+
if (kind === 2 /* Conditional */) return 0.5;
|
|
37862
37995
|
return 0.2;
|
|
37863
37996
|
}
|
|
37864
37997
|
function averageCoverage(...values) {
|
|
@@ -37891,24 +38024,7 @@ function resolveEffectiveAlignmentContext(parentContext, child, measurementNode,
|
|
|
37891
38024
|
const childContext = contextByParentNode.get(child);
|
|
37892
38025
|
if (!childContext) return parentContext;
|
|
37893
38026
|
if (childContext.baselineRelevance !== "irrelevant") return parentContext;
|
|
37894
|
-
return {
|
|
37895
|
-
kind: parentContext.kind,
|
|
37896
|
-
certainty: parentContext.certainty,
|
|
37897
|
-
parentSolidFile: parentContext.parentSolidFile,
|
|
37898
|
-
parentElementId: parentContext.parentElementId,
|
|
37899
|
-
parentElementKey: parentContext.parentElementKey,
|
|
37900
|
-
parentTag: parentContext.parentTag,
|
|
37901
|
-
axis: parentContext.axis,
|
|
37902
|
-
axisCertainty: parentContext.axisCertainty,
|
|
37903
|
-
inlineDirection: parentContext.inlineDirection,
|
|
37904
|
-
inlineDirectionCertainty: parentContext.inlineDirectionCertainty,
|
|
37905
|
-
parentDisplay: parentContext.parentDisplay,
|
|
37906
|
-
parentAlignItems: parentContext.parentAlignItems,
|
|
37907
|
-
parentPlaceItems: parentContext.parentPlaceItems,
|
|
37908
|
-
hasPositionedOffset: parentContext.hasPositionedOffset,
|
|
37909
|
-
baselineRelevance: "irrelevant",
|
|
37910
|
-
evidence: parentContext.evidence
|
|
37911
|
-
};
|
|
38027
|
+
return deriveAlignmentContext(parentContext, { baselineRelevance: "irrelevant" });
|
|
37912
38028
|
}
|
|
37913
38029
|
function compareAlignmentCaseOrder(left, right) {
|
|
37914
38030
|
if (left.subject.solidFile < right.subject.solidFile) return -1;
|
|
@@ -37927,12 +38043,12 @@ function buildConsistencyEvidence(input) {
|
|
|
37927
38043
|
input.cohortProfile.medianLineHeightPx,
|
|
37928
38044
|
input.cohortProfile.medianDeclaredOffsetPx
|
|
37929
38045
|
);
|
|
37930
|
-
const
|
|
38046
|
+
const offsetRaw = normalizeDeviation(
|
|
37931
38047
|
input.subjectEffectiveOffsetDeviation,
|
|
37932
38048
|
input.cohortProfile.effectiveOffsetDispersionPx,
|
|
37933
38049
|
effectiveOffsetScaleReference
|
|
37934
38050
|
);
|
|
37935
|
-
const
|
|
38051
|
+
const declaredOffsetRaw = normalizeDeviation(
|
|
37936
38052
|
input.subjectDeclaredOffsetDeviation,
|
|
37937
38053
|
input.cohortProfile.declaredOffsetDispersionPx,
|
|
37938
38054
|
declaredOffsetScaleReference
|
|
@@ -37943,10 +38059,15 @@ function buildConsistencyEvidence(input) {
|
|
|
37943
38059
|
input.cohortProfile.medianLineHeightPx
|
|
37944
38060
|
);
|
|
37945
38061
|
const baselinesIrrelevant = input.context.baselineRelevance === "irrelevant";
|
|
37946
|
-
const
|
|
37947
|
-
const
|
|
37948
|
-
const
|
|
37949
|
-
const
|
|
38062
|
+
const blockAxisIsMainAxis = !input.context.crossAxisIsBlockAxis;
|
|
38063
|
+
const suppressAll = blockAxisIsMainAxis;
|
|
38064
|
+
const offset = suppressAll ? ZERO_STRENGTH : offsetRaw;
|
|
38065
|
+
const declaredOffset = suppressAll ? ZERO_STRENGTH : declaredOffsetRaw;
|
|
38066
|
+
const baselineStrength = baselinesIrrelevant || suppressAll ? ZERO_STRENGTH : resolveBaselineStrength(input, lineHeight);
|
|
38067
|
+
const contextStrength = baselinesIrrelevant || suppressAll ? ZERO_STRENGTH : resolveContextStrength(input, lineHeight);
|
|
38068
|
+
const replacedStrength = baselinesIrrelevant || suppressAll ? ZERO_STRENGTH : resolveReplacedControlStrength(input, lineHeight);
|
|
38069
|
+
const compositionResult = baselinesIrrelevant || suppressAll ? null : resolveContentCompositionStrength(input);
|
|
38070
|
+
const compositionStrength = compositionResult ? compositionResult.evidence : ZERO_STRENGTH;
|
|
37950
38071
|
const contextCertaintyPenalty = resolveContextCertaintyPenalty(input);
|
|
37951
38072
|
const provenance = input.cohortProvenance;
|
|
37952
38073
|
const atoms = buildEvidenceAtoms(
|
|
@@ -37967,6 +38088,7 @@ function buildConsistencyEvidence(input) {
|
|
|
37967
38088
|
contextStrength: contextStrength.strength,
|
|
37968
38089
|
replacedStrength: replacedStrength.strength,
|
|
37969
38090
|
compositionStrength: compositionStrength.strength,
|
|
38091
|
+
majorityClassification: compositionResult ? compositionResult.divergence.majorityClassification : 5 /* Unknown */,
|
|
37970
38092
|
identifiability: input.subjectIdentifiability,
|
|
37971
38093
|
factSummary,
|
|
37972
38094
|
atoms
|
|
@@ -38002,7 +38124,7 @@ function resolveOffsetScaleReference(medianLineHeightPx, fallbackMedianOffsetPx)
|
|
|
38002
38124
|
}
|
|
38003
38125
|
function resolveBaselineStrength(input, lineHeight) {
|
|
38004
38126
|
const verticalAlign = input.cohortSignals.verticalAlign;
|
|
38005
|
-
const hasConflict = verticalAlign.value ===
|
|
38127
|
+
const hasConflict = verticalAlign.value === 0 /* Conflict */;
|
|
38006
38128
|
const conflict = hasConflict ? alignmentStrengthCalibration.baselineConflictBoost : 0;
|
|
38007
38129
|
const kind = resolveBaselineEvidenceKind(lineHeight.kind, verticalAlign.kind, hasConflict);
|
|
38008
38130
|
return {
|
|
@@ -38012,7 +38134,7 @@ function resolveBaselineStrength(input, lineHeight) {
|
|
|
38012
38134
|
}
|
|
38013
38135
|
function resolveBaselineEvidenceKind(lineHeightKind, verticalAlignKind, hasConflict) {
|
|
38014
38136
|
if (!hasConflict) return mergeEvidenceKind(lineHeightKind, verticalAlignKind);
|
|
38015
|
-
if (lineHeightKind ===
|
|
38137
|
+
if (lineHeightKind === 3 /* Unknown */) return verticalAlignKind;
|
|
38016
38138
|
return mergeEvidenceKind(lineHeightKind, verticalAlignKind);
|
|
38017
38139
|
}
|
|
38018
38140
|
function resolveContextStrength(input, lineHeight) {
|
|
@@ -38040,7 +38162,7 @@ function resolveContextConflictEvidence(input) {
|
|
|
38040
38162
|
const alignSelf = input.cohortSignals.alignSelf;
|
|
38041
38163
|
const placeSelf = input.cohortSignals.placeSelf;
|
|
38042
38164
|
const kind = mergeEvidenceKind(alignSelf.kind, placeSelf.kind);
|
|
38043
|
-
const hasConflict = alignSelf.value ===
|
|
38165
|
+
const hasConflict = alignSelf.value === 0 /* Conflict */ || placeSelf.value === 0 /* Conflict */;
|
|
38044
38166
|
if (!hasConflict) {
|
|
38045
38167
|
return {
|
|
38046
38168
|
strength: 0,
|
|
@@ -38054,23 +38176,23 @@ function resolveContextConflictEvidence(input) {
|
|
|
38054
38176
|
}
|
|
38055
38177
|
function resolveReplacedControlStrength(input, lineHeight) {
|
|
38056
38178
|
const subject = input.subject.snapshot;
|
|
38057
|
-
const hasReplacedPair = subject.isControl || subject.isReplaced || input.cohortSignals.hasControlOrReplacedPeer;
|
|
38179
|
+
const hasReplacedPair = subject.node.isControl || subject.node.isReplaced || input.cohortSignals.hasControlOrReplacedPeer;
|
|
38058
38180
|
if (!hasReplacedPair) {
|
|
38059
38181
|
return {
|
|
38060
38182
|
strength: 0,
|
|
38061
38183
|
kind: lineHeight.kind
|
|
38062
38184
|
};
|
|
38063
38185
|
}
|
|
38064
|
-
if (input.cohortSignals.textContrastWithPeers ===
|
|
38186
|
+
if (input.cohortSignals.textContrastWithPeers === 0 /* Different */) {
|
|
38065
38187
|
return {
|
|
38066
38188
|
strength: alignmentStrengthCalibration.replacedDifferentTextBoost,
|
|
38067
|
-
kind:
|
|
38189
|
+
kind: 0 /* Exact */
|
|
38068
38190
|
};
|
|
38069
38191
|
}
|
|
38070
|
-
if (input.cohortSignals.textContrastWithPeers ===
|
|
38192
|
+
if (input.cohortSignals.textContrastWithPeers === 2 /* Unknown */) {
|
|
38071
38193
|
return {
|
|
38072
38194
|
strength: alignmentStrengthCalibration.replacedUnknownTextBoost,
|
|
38073
|
-
kind:
|
|
38195
|
+
kind: 2 /* Conditional */
|
|
38074
38196
|
};
|
|
38075
38197
|
}
|
|
38076
38198
|
return {
|
|
@@ -38079,22 +38201,28 @@ function resolveReplacedControlStrength(input, lineHeight) {
|
|
|
38079
38201
|
};
|
|
38080
38202
|
}
|
|
38081
38203
|
function resolveContentCompositionStrength(input) {
|
|
38082
|
-
const
|
|
38204
|
+
const divergence = resolveCompositionDivergence(
|
|
38083
38205
|
input.subjectContentComposition,
|
|
38084
38206
|
input.cohortContentCompositions,
|
|
38085
38207
|
input.context
|
|
38086
38208
|
);
|
|
38087
|
-
if (
|
|
38209
|
+
if (divergence.strength <= 0) {
|
|
38088
38210
|
return {
|
|
38089
|
-
|
|
38090
|
-
|
|
38211
|
+
evidence: {
|
|
38212
|
+
strength: 0,
|
|
38213
|
+
kind: 0 /* Exact */
|
|
38214
|
+
},
|
|
38215
|
+
divergence
|
|
38091
38216
|
};
|
|
38092
38217
|
}
|
|
38093
38218
|
const subjectClassification = input.subjectContentComposition.classification;
|
|
38094
|
-
const kind = subjectClassification ===
|
|
38219
|
+
const kind = subjectClassification === 5 /* Unknown */ ? 2 /* Conditional */ : 0 /* Exact */;
|
|
38095
38220
|
return {
|
|
38096
|
-
|
|
38097
|
-
|
|
38221
|
+
evidence: {
|
|
38222
|
+
strength: clamp(divergence.strength, 0, 1),
|
|
38223
|
+
kind
|
|
38224
|
+
},
|
|
38225
|
+
divergence
|
|
38098
38226
|
};
|
|
38099
38227
|
}
|
|
38100
38228
|
function resolveContextCertaintyPenalty(input) {
|
|
@@ -38166,9 +38294,9 @@ function buildEvidenceAtoms(input, offset, declaredOffset, baselineStrength, con
|
|
|
38166
38294
|
return out;
|
|
38167
38295
|
}
|
|
38168
38296
|
function mapContextCertaintyToEvidenceKind(certainty) {
|
|
38169
|
-
if (certainty ===
|
|
38170
|
-
if (certainty ===
|
|
38171
|
-
return
|
|
38297
|
+
if (certainty === 0 /* Resolved */) return 0 /* Exact */;
|
|
38298
|
+
if (certainty === 1 /* Conditional */) return 2 /* Conditional */;
|
|
38299
|
+
return 3 /* Unknown */;
|
|
38172
38300
|
}
|
|
38173
38301
|
function pushSupportAtom(out, factorId, valueKind, strength, coverage, provenance) {
|
|
38174
38302
|
pushAtom(out, factorId, valueKind, strength, coverage, provenance, "support");
|
|
@@ -38194,19 +38322,19 @@ function pushAtom(out, factorId, valueKind, strength, coverage, provenance, expe
|
|
|
38194
38322
|
}
|
|
38195
38323
|
function toPositiveContribution(strength, maxWeight, valueKind) {
|
|
38196
38324
|
const contribution = clamp(strength, 0, 2) * maxWeight;
|
|
38197
|
-
if (valueKind ===
|
|
38325
|
+
if (valueKind === 0 /* Exact */) {
|
|
38198
38326
|
return {
|
|
38199
38327
|
min: contribution,
|
|
38200
38328
|
max: contribution
|
|
38201
38329
|
};
|
|
38202
38330
|
}
|
|
38203
|
-
if (valueKind ===
|
|
38331
|
+
if (valueKind === 1 /* Interval */) {
|
|
38204
38332
|
return {
|
|
38205
38333
|
min: contribution * evidenceContributionCalibration.supportIntervalLowerScale,
|
|
38206
38334
|
max: contribution
|
|
38207
38335
|
};
|
|
38208
38336
|
}
|
|
38209
|
-
if (valueKind ===
|
|
38337
|
+
if (valueKind === 2 /* Conditional */) {
|
|
38210
38338
|
return {
|
|
38211
38339
|
min: 0,
|
|
38212
38340
|
max: contribution * evidenceContributionCalibration.supportConditionalUpperScale
|
|
@@ -38219,19 +38347,19 @@ function toPositiveContribution(strength, maxWeight, valueKind) {
|
|
|
38219
38347
|
}
|
|
38220
38348
|
function toNegativeContribution(strength, maxPenalty, valueKind) {
|
|
38221
38349
|
const penalty = clamp(strength, 0, 1) * maxPenalty;
|
|
38222
|
-
if (valueKind ===
|
|
38350
|
+
if (valueKind === 0 /* Exact */) {
|
|
38223
38351
|
return {
|
|
38224
38352
|
min: -penalty,
|
|
38225
38353
|
max: -penalty
|
|
38226
38354
|
};
|
|
38227
38355
|
}
|
|
38228
|
-
if (valueKind ===
|
|
38356
|
+
if (valueKind === 1 /* Interval */) {
|
|
38229
38357
|
return {
|
|
38230
38358
|
min: -penalty,
|
|
38231
38359
|
max: -penalty * evidenceContributionCalibration.penaltyIntervalUpperScale
|
|
38232
38360
|
};
|
|
38233
38361
|
}
|
|
38234
|
-
if (valueKind ===
|
|
38362
|
+
if (valueKind === 2 /* Conditional */) {
|
|
38235
38363
|
return {
|
|
38236
38364
|
min: -penalty,
|
|
38237
38365
|
max: 0
|
|
@@ -38242,7 +38370,7 @@ function toNegativeContribution(strength, maxPenalty, valueKind) {
|
|
|
38242
38370
|
max: 0
|
|
38243
38371
|
};
|
|
38244
38372
|
}
|
|
38245
|
-
var ZERO_STRENGTH = { strength: 0, kind:
|
|
38373
|
+
var ZERO_STRENGTH = { strength: 0, kind: 0 /* Exact */ };
|
|
38246
38374
|
|
|
38247
38375
|
// src/cross-file/layout/consistency-policy.ts
|
|
38248
38376
|
function applyConsistencyPolicy(input) {
|
|
@@ -38326,23 +38454,38 @@ function resolveConfidence(posterior, evidenceMass) {
|
|
|
38326
38454
|
const confidence = posterior.lower * weightedMass * (1 - intervalWidth * alignmentPolicyCalibration.confidenceIntervalPenalty);
|
|
38327
38455
|
return clamp(confidence, 0, 1);
|
|
38328
38456
|
}
|
|
38457
|
+
var EMPTY_FACTOR_LIST = Object.freeze([]);
|
|
38329
38458
|
function selectTopFactors(evidence) {
|
|
38330
|
-
const
|
|
38331
|
-
|
|
38332
|
-
|
|
38333
|
-
|
|
38334
|
-
|
|
38335
|
-
if (
|
|
38336
|
-
|
|
38459
|
+
const atoms = evidence.atoms;
|
|
38460
|
+
if (atoms.length === 0) return EMPTY_FACTOR_LIST;
|
|
38461
|
+
const top = [];
|
|
38462
|
+
for (let i = 0; i < atoms.length; i++) {
|
|
38463
|
+
const atom = atoms[i];
|
|
38464
|
+
if (!atom) continue;
|
|
38465
|
+
const mag = Math.abs((atom.contribution.min + atom.contribution.max) / 2);
|
|
38466
|
+
if (mag <= 0) continue;
|
|
38467
|
+
if (top.length < 4) {
|
|
38468
|
+
top.push({ id: atom.factorId, mag });
|
|
38469
|
+
continue;
|
|
38470
|
+
}
|
|
38471
|
+
let minIdx = 0;
|
|
38472
|
+
for (let j = 1; j < top.length; j++) {
|
|
38473
|
+
const curr = top[j];
|
|
38474
|
+
const best = top[minIdx];
|
|
38475
|
+
if (curr && best && curr.mag < best.mag) minIdx = j;
|
|
38476
|
+
}
|
|
38477
|
+
const minEntry = top[minIdx];
|
|
38478
|
+
if (minEntry && mag > minEntry.mag) {
|
|
38479
|
+
top[minIdx] = { id: atom.factorId, mag };
|
|
38480
|
+
}
|
|
38481
|
+
}
|
|
38482
|
+
top.sort((a, b) => {
|
|
38483
|
+
if (a.mag !== b.mag) return b.mag - a.mag;
|
|
38484
|
+
if (a.id < b.id) return -1;
|
|
38485
|
+
if (a.id > b.id) return 1;
|
|
38337
38486
|
return 0;
|
|
38338
38487
|
});
|
|
38339
|
-
|
|
38340
|
-
for (let i = 0; i < sorted.length && i < 4; i++) {
|
|
38341
|
-
const item = sorted[i];
|
|
38342
|
-
if (!item) continue;
|
|
38343
|
-
out.push(item.factorId);
|
|
38344
|
-
}
|
|
38345
|
-
return out;
|
|
38488
|
+
return top.map((t) => t.id);
|
|
38346
38489
|
}
|
|
38347
38490
|
function logistic(value2) {
|
|
38348
38491
|
if (value2 > 30) return 1;
|
|
@@ -38363,7 +38506,7 @@ function evaluateAlignmentCase(input) {
|
|
|
38363
38506
|
evidenceMass: policy.evidenceMass
|
|
38364
38507
|
};
|
|
38365
38508
|
}
|
|
38366
|
-
const signalFindings = buildFindingsFromAtoms(evidence.atoms, input);
|
|
38509
|
+
const signalFindings = buildFindingsFromAtoms(evidence.atoms, input, evidence);
|
|
38367
38510
|
return {
|
|
38368
38511
|
kind: "accept",
|
|
38369
38512
|
evaluation: {
|
|
@@ -38383,12 +38526,12 @@ function evaluateAlignmentCase(input) {
|
|
|
38383
38526
|
}
|
|
38384
38527
|
};
|
|
38385
38528
|
}
|
|
38386
|
-
function buildFindingsFromAtoms(atoms, input) {
|
|
38529
|
+
function buildFindingsFromAtoms(atoms, input, evidence) {
|
|
38387
38530
|
const byKind = /* @__PURE__ */ new Map();
|
|
38388
38531
|
for (let i = 0; i < atoms.length; i++) {
|
|
38389
38532
|
const atom = atoms[i];
|
|
38390
38533
|
if (!atom) continue;
|
|
38391
|
-
const factor = toFindingFactor(atom.factorId, input);
|
|
38534
|
+
const factor = toFindingFactor(atom.factorId, input, evidence);
|
|
38392
38535
|
if (factor === null) continue;
|
|
38393
38536
|
const meanContribution = (atom.contribution.min + atom.contribution.max) / 2;
|
|
38394
38537
|
if (meanContribution <= 0) continue;
|
|
@@ -38409,7 +38552,7 @@ function buildFindingsFromAtoms(atoms, input) {
|
|
|
38409
38552
|
}
|
|
38410
38553
|
return [...byKind.values()];
|
|
38411
38554
|
}
|
|
38412
|
-
function toFindingFactor(factorId, input) {
|
|
38555
|
+
function toFindingFactor(factorId, input, evidence) {
|
|
38413
38556
|
switch (factorId) {
|
|
38414
38557
|
case "offset-delta":
|
|
38415
38558
|
return {
|
|
@@ -38439,17 +38582,15 @@ function toFindingFactor(factorId, input) {
|
|
|
38439
38582
|
case "content-composition-conflict":
|
|
38440
38583
|
return {
|
|
38441
38584
|
kind: "content-composition-conflict",
|
|
38442
|
-
message: formatContentCompositionFinding(input)
|
|
38585
|
+
message: formatContentCompositionFinding(input, evidence)
|
|
38443
38586
|
};
|
|
38444
38587
|
default:
|
|
38445
38588
|
return null;
|
|
38446
38589
|
}
|
|
38447
38590
|
}
|
|
38448
|
-
function formatContentCompositionFinding(input) {
|
|
38591
|
+
function formatContentCompositionFinding(input, evidence) {
|
|
38449
38592
|
const subjectClassification = formatCompositionClassification(input.subjectContentComposition.classification);
|
|
38450
|
-
const majorityClassification = formatCompositionClassification(
|
|
38451
|
-
resolveMajorityClassification(input.cohortContentCompositions)
|
|
38452
|
-
);
|
|
38593
|
+
const majorityClassification = formatCompositionClassification(evidence.majorityClassification);
|
|
38453
38594
|
const fixSuggestion = formatCompositionFixSuggestion(input.subjectContentComposition);
|
|
38454
38595
|
return `siblings have identical CSS but different content composition (subject: ${subjectClassification}, majority: ${majorityClassification}; fix: ${fixSuggestion})`;
|
|
38455
38596
|
}
|
|
@@ -38508,7 +38649,7 @@ function recordPolicyMetrics(context, evidenceMass, posteriorLower, posteriorUpp
|
|
|
38508
38649
|
context.layout.perf.factorCoverageSum += clamp(evidenceMass, 0, 1);
|
|
38509
38650
|
context.layout.perf.factorCoverageCount++;
|
|
38510
38651
|
const width = clamp(posteriorUpper - posteriorLower, 0, 1);
|
|
38511
|
-
context.layout.perf.posteriorWidths
|
|
38652
|
+
reservoirPush(context.layout.perf.posteriorWidths, width);
|
|
38512
38653
|
if (width > 1e-3) context.layout.perf.uncertaintyEscalations++;
|
|
38513
38654
|
}
|
|
38514
38655
|
|
|
@@ -38527,16 +38668,16 @@ function readNodeRefById(layout, solidFile, elementId) {
|
|
|
38527
38668
|
}
|
|
38528
38669
|
function isFlowRelevantBySiblingsOrText(node, textualContent) {
|
|
38529
38670
|
if (node.siblingCount >= 2) return true;
|
|
38530
|
-
return textualContent ===
|
|
38671
|
+
return textualContent === 0 /* Yes */ || textualContent === 2 /* Unknown */ || textualContent === 3 /* DynamicText */;
|
|
38531
38672
|
}
|
|
38532
38673
|
function isDeferredContainerLike(node, textualContent) {
|
|
38533
38674
|
if (node.siblingCount >= 2) return true;
|
|
38534
|
-
if (textualContent ===
|
|
38675
|
+
if (textualContent === 2 /* Unknown */) return true;
|
|
38535
38676
|
if (node.tagName !== null && SECTIONING_CONTAINER_TAGS.has(node.tagName)) return true;
|
|
38536
38677
|
return false;
|
|
38537
38678
|
}
|
|
38538
38679
|
function isDynamicContainerLike(node) {
|
|
38539
|
-
return node.textualContent ===
|
|
38680
|
+
return node.textualContent === 2 /* Unknown */ && node.siblingCount >= 2;
|
|
38540
38681
|
}
|
|
38541
38682
|
function isLikelyViewportAffectingContainer(node) {
|
|
38542
38683
|
if (node.siblingCount >= 2) return true;
|
|
@@ -39776,7 +39917,7 @@ var cssLayoutScrollbarGutterInstability = defineCrossRule({
|
|
|
39776
39917
|
const snapshot = collectSignalSnapshot(context, node);
|
|
39777
39918
|
const scroll = readScrollContainerFact(context.layout, node);
|
|
39778
39919
|
if (!scroll.isScrollContainer) continue;
|
|
39779
|
-
if (scroll.axis !==
|
|
39920
|
+
if (scroll.axis !== 2 /* Y */ && scroll.axis !== 3 /* Both */) continue;
|
|
39780
39921
|
const scrollbarWidth = readKnownNormalized(snapshot, "scrollbar-width");
|
|
39781
39922
|
if (scrollbarWidth === "none") continue;
|
|
39782
39923
|
const gutter = readKnownNormalized(snapshot, "scrollbar-gutter");
|
|
@@ -39906,10 +40047,10 @@ var cssLayoutConditionalDisplayCollapse = defineCrossRule({
|
|
|
39906
40047
|
const display = readKnownNormalizedWithGuard(snapshot, "display");
|
|
39907
40048
|
if (!display || !COLLAPSING_DISPLAYS.has(display)) continue;
|
|
39908
40049
|
const displaySignal = snapshot.signals.get("display");
|
|
39909
|
-
if (!displaySignal || displaySignal.guard !==
|
|
40050
|
+
if (!displaySignal || displaySignal.guard.kind !== 1 /* Conditional */) continue;
|
|
39910
40051
|
const flow = readFlowParticipationFact(context.layout, node);
|
|
39911
40052
|
if (!flow.inFlow) continue;
|
|
39912
|
-
if (!isFlowRelevantBySiblingsOrText(node, snapshot.textualContent)) continue;
|
|
40053
|
+
if (!isFlowRelevantBySiblingsOrText(node, snapshot.node.textualContent)) continue;
|
|
39913
40054
|
const reservedSpace = readReservedSpaceFact(context.layout, node);
|
|
39914
40055
|
if (reservedSpace.hasReservedSpace) continue;
|
|
39915
40056
|
if (!emitLayoutDiagnostic(context.layout, node, emit, cssLayoutConditionalDisplayCollapse.id, "conditionalDisplayCollapse", messages152.conditionalDisplayCollapse, cssLayoutConditionalDisplayCollapse.severity, { display })) continue;
|
|
@@ -39945,10 +40086,10 @@ var cssLayoutConditionalWhiteSpaceWrapShift = defineCrossRule({
|
|
|
39945
40086
|
if (!hasWrapShiftDelta(whiteSpaceDelta)) continue;
|
|
39946
40087
|
if (!whiteSpace) continue;
|
|
39947
40088
|
const whiteSpaceSignal = snapshot.signals.get("white-space");
|
|
39948
|
-
if (!whiteSpaceSignal || whiteSpaceSignal.guard !==
|
|
40089
|
+
if (!whiteSpaceSignal || whiteSpaceSignal.guard.kind !== 1 /* Conditional */) continue;
|
|
39949
40090
|
const flow = readFlowParticipationFact(context.layout, node);
|
|
39950
40091
|
if (!flow.inFlow) continue;
|
|
39951
|
-
if (!isFlowRelevantBySiblingsOrText(node, snapshot.textualContent)) continue;
|
|
40092
|
+
if (!isFlowRelevantBySiblingsOrText(node, snapshot.node.textualContent)) continue;
|
|
39952
40093
|
if (hasStableTextShell(snapshot)) continue;
|
|
39953
40094
|
if (!emitLayoutDiagnostic(context.layout, node, emit, cssLayoutConditionalWhiteSpaceWrapShift.id, "conditionalWhiteSpaceShift", messages153.conditionalWhiteSpaceShift, cssLayoutConditionalWhiteSpaceWrapShift.severity, { whiteSpace })) continue;
|
|
39954
40095
|
}
|
|
@@ -40085,7 +40226,7 @@ var cssLayoutContentVisibilityNoIntrinsicSize = defineCrossRule({
|
|
|
40085
40226
|
const node = candidates[i];
|
|
40086
40227
|
if (!node) continue;
|
|
40087
40228
|
const snapshot = collectSignalSnapshot(context, node);
|
|
40088
|
-
if (!isDeferredContainerLike(node, snapshot.textualContent)) continue;
|
|
40229
|
+
if (!isDeferredContainerLike(node, snapshot.node.textualContent)) continue;
|
|
40089
40230
|
const reservedSpace = readReservedSpaceFact(context.layout, node);
|
|
40090
40231
|
if (reservedSpace.hasReservedSpace) continue;
|
|
40091
40232
|
if (!emitLayoutDiagnostic(context.layout, node, emit, cssLayoutContentVisibilityNoIntrinsicSize.id, "missingIntrinsicSize", messages156.missingIntrinsicSize, cssLayoutContentVisibilityNoIntrinsicSize.severity)) continue;
|
|
@@ -40144,11 +40285,11 @@ function collectConditionalOffsets(layout, node, snapshot) {
|
|
|
40144
40285
|
if (!delta.hasConditional || !delta.hasDelta) continue;
|
|
40145
40286
|
const signal = snapshot.signals.get(name);
|
|
40146
40287
|
if (!signal) continue;
|
|
40147
|
-
if (signal.guard !==
|
|
40288
|
+
if (signal.guard.kind !== 1 /* Conditional */) continue;
|
|
40148
40289
|
if (signal.kind !== "known") continue;
|
|
40149
40290
|
if (signal.px === null) continue;
|
|
40150
40291
|
if (Math.abs(signal.px) <= 0.25) continue;
|
|
40151
|
-
out.push({ property: name, value: signal.px, guardKey: signal.
|
|
40292
|
+
out.push({ property: name, value: signal.px, guardKey: signal.guard.key });
|
|
40152
40293
|
}
|
|
40153
40294
|
return out;
|
|
40154
40295
|
}
|
|
@@ -40169,8 +40310,8 @@ function hasEffectivePositionForConditionalOffset(snapshot, guardKey) {
|
|
|
40169
40310
|
const position = snapshot.signals.get("position");
|
|
40170
40311
|
if (!position) return false;
|
|
40171
40312
|
if (position.kind !== "known") return false;
|
|
40172
|
-
if (position.guard !==
|
|
40173
|
-
if (position.
|
|
40313
|
+
if (position.guard.kind !== 1 /* Conditional */) return false;
|
|
40314
|
+
if (position.guard.key !== guardKey) return false;
|
|
40174
40315
|
return position.normalized !== "static";
|
|
40175
40316
|
}
|
|
40176
40317
|
function hasStableBaseline(baselineBySignal, property, expectedPx) {
|
|
@@ -42385,13 +42526,13 @@ var RULES = [
|
|
|
42385
42526
|
"id": "resource-implicit-suspense",
|
|
42386
42527
|
"severity": "warn",
|
|
42387
42528
|
"description": "Detect createResource that implicitly triggers or permanently breaks Suspense boundaries.",
|
|
42388
|
-
"fixable":
|
|
42529
|
+
"fixable": true,
|
|
42389
42530
|
"category": "reactivity",
|
|
42390
42531
|
"plugin": "solid",
|
|
42391
42532
|
"messages": {
|
|
42392
|
-
"loadingMismatch": "createResource '{{name}}' has no initialValue but uses
|
|
42393
|
-
"conditionalSuspense": "createResource '{{name}}' is
|
|
42394
|
-
"missingErrorBoundary": "createResource '{{name}}' has no <ErrorBoundary> between its component and the nearest <Suspense>. When the fetcher throws (network error, 401/403/503, timeout), the error propagates to Suspense which
|
|
42533
|
+
"loadingMismatch": "createResource '{{name}}' has no initialValue but uses {{name}}.loading for manual loading UI. Suspense intercepts before your loading UI renders \u2014 the component is unmounted before the <Show>/<Switch> evaluates. Replace createResource with onMount + createSignal to decouple from Suspense entirely.",
|
|
42534
|
+
"conditionalSuspense": "createResource '{{name}}' is inside a conditional mount point ({{mountTag}}) with a distant Suspense boundary. The SuspenseContext increment fires when the fetcher's Promise is pending and unmounts the entire page subtree \u2014 initialValue does NOT prevent this. Replace createResource with onMount + createSignal to avoid Suspense interaction.",
|
|
42535
|
+
"missingErrorBoundary": "createResource '{{name}}' has no <ErrorBoundary> between its component and the nearest <Suspense>. When the fetcher throws (network error, 401/403/503, timeout), the error propagates to Suspense which has no error handling \u2014 the boundary breaks permanently. Wrap the component in <ErrorBoundary> or replace createResource with onMount + createSignal and catch errors in the fetcher."
|
|
42395
42536
|
}
|
|
42396
42537
|
},
|
|
42397
42538
|
{
|
|
@@ -42594,7 +42735,7 @@ var RULES_BY_CATEGORY = {
|
|
|
42594
42735
|
"css-structure": [{ "id": "css-no-empty-rule", "severity": "warn", "description": "Disallow empty CSS rules.", "fixable": false, "category": "css-structure", "plugin": "css", "messages": { "emptyRule": "Empty rule `{{selector}}` should be removed." } }, { "id": "css-no-unknown-container-name", "severity": "error", "description": "Disallow unknown named containers in @container queries.", "fixable": false, "category": "css-structure", "plugin": "css", "messages": { "unknownContainer": "Unknown container name `{{name}}` in @container query." } }, { "id": "css-no-unused-container-name", "severity": "warn", "description": "Disallow unused named containers.", "fixable": false, "category": "css-structure", "plugin": "css", "messages": { "unusedContainer": "Container name `{{name}}` is declared but never queried." } }, { "id": "layer-requirement-for-component-rules", "severity": "warn", "description": "Require style rules to be inside @layer when the file defines layers.", "fixable": false, "category": "css-structure", "plugin": "css", "messages": { "missingLayer": "Rule `{{selector}}` is not inside any @layer block while this file uses @layer. Place component rules inside an explicit layer." } }],
|
|
42595
42736
|
"jsx": [{ "id": "components-return-once", "severity": "error", "description": "Disallow early returns in components. Solid components only run once, and so conditionals should be inside JSX.", "fixable": true, "category": "jsx", "plugin": "solid", "messages": { "noEarlyReturn": "Early returns in Solid components break reactivity because the component function only runs once. Use <Show> or <Switch>/<Match> inside the JSX to conditionally render content instead of returning early from the function.", "noConditionalReturn": "Conditional expressions in return statements break reactivity because Solid components only run once. Wrap the condition in <Show when={...}> for a single condition, or <Switch>/<Match> for multiple conditions." } }, { "id": "jsx-no-duplicate-props", "severity": "error", "description": "Disallow passing the same prop twice in JSX.", "fixable": true, "category": "jsx", "plugin": "solid", "messages": { "noDuplicateProps": "Duplicate prop detected. Each prop should only be specified once; the second value will override the first.", "noDuplicateClass": "Duplicate `class` prop detected. While this might appear to work, it can break unexpectedly because only one class binding is applied. Use `classList` to conditionally apply multiple classes.", "noDuplicateChildren": "Conflicting children: {{used}}. Only one method of setting children is allowed at a time." } }, { "id": "jsx-no-script-url", "severity": "error", "description": "Disallow javascript: URLs.", "fixable": true, "category": "jsx", "plugin": "solid", "messages": { "noJSURL": "Using javascript: URLs is a security risk because it can enable cross-site scripting (XSS) attacks. Use an event handler like onClick instead, or navigate programmatically with useNavigate()." } }, { "id": "jsx-no-undef", "severity": "error", "description": "Disallow references to undefined variables in JSX. Handles custom directives.", "fixable": false, "category": "jsx", "plugin": "solid", "messages": { "customDirectiveUndefined": "Custom directive '{{identifier}}' is not defined. Directives must be imported or declared in scope before use (e.g., `const {{identifier}} = (el, accessor) => { ... }`)." } }, { "id": "jsx-uses-vars", "severity": "warn", "description": "Detect imported components and directives that are never used in JSX.", "fixable": false, "category": "jsx", "plugin": "solid", "messages": { "unusedComponent": "Component '{{name}}' is imported but never used in JSX.", "unusedDirective": "Directive '{{name}}' is imported but never used in JSX." } }, { "id": "no-innerhtml", "severity": "error", "description": "Disallow usage of the innerHTML attribute, which can lead to security vulnerabilities.", "fixable": true, "category": "jsx", "plugin": "solid", "messages": { "dangerous": "Using innerHTML with dynamic content is a security risk. Unsanitized user input can lead to cross-site scripting (XSS) attacks. Use a sanitization library or render content safely.", "conflict": "The innerHTML prop will overwrite all child elements. Remove the children or use innerHTML on an empty element.", "notHtml": "The innerHTML value doesn't appear to be HTML. If you're setting text content, use innerText instead for clarity and safety.", "dangerouslySetInnerHTML": "The dangerouslySetInnerHTML is a React prop that Solid doesn't support. Use innerHTML instead." } }, { "id": "no-unknown-namespaces", "severity": "error", "description": "Enforce using only Solid-specific namespaced attribute names (i.e. `'on:'` in `<div on:click={...} />`).", "fixable": false, "category": "jsx", "plugin": "solid", "messages": { "unknownNamespace": "'{{namespace}}:' is not a recognized Solid namespace. Valid namespaces are: {{validNamespaces}}.", "styleNamespace": "The 'style:' namespace works but is discouraged. Use the style prop with an object instead: style={{ {{property}}: value }}.", "classNamespace": `The 'class:' namespace works but is discouraged. Use the classList prop instead: classList={{ "{{className}}": condition }}.`, "componentNamespace": "Namespaced attributes like '{{namespace}}:' only work on DOM elements, not components. The '{{fullName}}' attribute will be passed as a regular prop named '{{fullName}}'." } }, { "id": "show-truthy-conversion", "severity": "error", "description": "Detect <Show when={expr}> where expr is not explicitly boolean, which may have unexpected truthy/falsy behavior.", "fixable": true, "category": "jsx", "plugin": "solid", "messages": { "showNonBoolean": "<Show when={{{{expr}}}}> uses truthy/falsy conversion. Value '0' or empty string '' will hide content. Use explicit boolean: when={Boolean({{expr}})} or when={{{expr}}} != null}" } }, { "id": "suspense-boundary-missing", "severity": "error", "description": "Detect missing fallback props on Suspense/ErrorBoundary, and lazy components without Suspense wrapper.", "fixable": false, "category": "jsx", "plugin": "solid", "messages": { "suspenseNoFallback": "<Suspense> should have a fallback prop to show while children are loading. Add: fallback={<Loading />}", "errorBoundaryNoFallback": "<ErrorBoundary> should have a fallback prop to show when an error occurs. Add: fallback={(err) => <Error error={err} />}", "lazyNoSuspense": "Lazy component '{{name}}' must be wrapped in a <Suspense> boundary. Add a <Suspense fallback={...}> ancestor." } }, { "id": "validate-jsx-nesting", "severity": "error", "description": "Validates that HTML elements are nested according to the HTML5 specification.", "fixable": false, "category": "jsx", "plugin": "solid", "messages": { "invalidNesting": "Invalid HTML nesting: <{{child}}> cannot be a child of <{{parent}}>. {{reason}}.", "voidElementWithChildren": "<{{parent}}> is a void element and cannot have children. Found <{{child}}> as a child.", "invalidListChild": "<{{child}}> is not a valid direct child of <{{parent}}>. Only <li> elements can be direct children of <ul> and <ol>.", "invalidSelectChild": "<{{child}}> is not a valid direct child of <select>. Only <option> and <optgroup> elements are allowed.", "invalidTableChild": "<{{child}}> is not a valid direct child of <{{parent}}>. Expected: {{expected}}.", "invalidDlChild": "<{{child}}> is not a valid direct child of <dl>. Only <dt>, <dd>, and <div> elements are allowed." } }],
|
|
42596
42737
|
"performance": [{ "id": "avoid-arguments-object", "severity": "warn", "description": "Disallow arguments object (use rest parameters instead).", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "avoidArguments": "arguments object can prevent V8 optimization. Use rest parameters (...args) instead." } }, { "id": "avoid-chained-array-methods", "severity": "warn", "description": "Flags chained array methods creating 3+ intermediate arrays, or filter().map() pattern.", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "avoidChainedArrayMethods": "Chain creates {{count}} intermediate array(s). Consider reduce() or a loop. Chain: {{chain}}", "mapJoinHotPath": "map().join() inside loops allocates intermediate arrays on a hot path. Prefer single-pass string construction." } }, { "id": "avoid-defensive-copy-for-scalar-stat", "severity": "warn", "description": "Disallow defensive array copies passed into scalar statistic calls.", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "defensiveCopy": "Defensive copy before scalar statistic '{{stat}}' allocates unnecessarily. Prefer readonly/non-mutating scalar computation." } }, { "id": "avoid-delete-operator", "severity": "warn", "description": "Disallow delete operator on objects (causes V8 deoptimization).", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "avoidDelete": "delete operator transitions object to slow mode. Use `obj.prop = undefined` or destructuring instead." } }, { "id": "avoid-function-allocation-in-hot-loop", "severity": "warn", "description": "Disallow creating closures inside loops.", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "closureInLoop": "Function created inside loop allocates new closure per iteration. Consider hoisting or using event delegation." } }, { "id": "avoid-hidden-class-transition", "severity": "warn", "description": "Suggest consistent object shapes to avoid V8 hidden class transitions.", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "hiddenClassTransition": "Property '{{property}}' added conditionally to '{{object}}' creates inconsistent object shapes. Initialize '{{property}}' in the object literal." } }, { "id": "avoid-intermediate-map-copy", "severity": "warn", "description": "Disallow temporary Map allocations that are copied key-for-key into another Map.", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "intermediateMapCopy": "Intermediate Map '{{tempName}}' is copied into '{{outName}}' key-for-key. Build output directly to avoid extra allocation." } }, { "id": "avoid-megamorphic-property-access", "severity": "warn", "description": "Avoid property access on `any` or wide union types to prevent V8 deoptimization.", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "megamorphicAccess": "Property access on `any` or wide union type causes V8 deoptimization. Consider narrowing the type." } }, { "id": "avoid-quadratic-pair-comparison", "severity": "warn", "description": "Disallow nested for-loops over the same collection creating O(n\xB2) pair comparison.", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "quadraticPair": "Nested loops over `{{collection}}` create O(n\xB2) pair comparison. Group by a key property first." } }, { "id": "avoid-quadratic-spread", "severity": "error", "description": "Disallow spreading accumulator in reduce callbacks (O(n\xB2) complexity).", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "quadraticSpread": "Spreading accumulator in reduce creates O(n\xB2) complexity. Use push() instead." } }, { "id": "avoid-repeated-indexof-check", "severity": "warn", "description": "Disallow 3+ .indexOf() calls on the same array variable in one function.", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "repeatedIndexOf": "{{count}} .indexOf() calls on `{{name}}` in the same function. Use a Set, regex, or single-pass scan instead." } }, { "id": "avoid-slice-sort-pattern", "severity": "warn", "description": "Disallow .slice().sort() and .slice().reverse() chains. Use .toSorted()/.toReversed().", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "sliceSort": ".slice().sort() creates an intermediate array. Use .toSorted() instead.", "sliceReverse": ".slice().reverse() creates an intermediate array. Use .toReversed() instead.", "spreadSort": "[...array].sort() creates an intermediate array. Use .toSorted() instead.", "spreadReverse": "[...array].reverse() creates an intermediate array. Use .toReversed() instead." } }, { "id": "avoid-sparse-arrays", "severity": "warn", "description": "Disallow new Array(n) without fill (creates holey array).", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "sparseArray": "new Array(n) creates a holey array. Use Array.from() or .fill() instead." } }, { "id": "avoid-spread-sort-map-join-pipeline", "severity": "warn", "description": "Disallow [...iterable].sort().map().join() pipelines on hot paths.", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "spreadSortMapJoin": "Spread+sort+map+join pipeline allocates multiple intermediates. Prefer single-pass string construction on hot paths." } }, { "id": "bounded-worklist-traversal", "severity": "warn", "description": "Detect queue/worklist traversals with unbounded growth and no guard.", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "boundedWorklist": "Worklist '{{name}}' grows via push() without visited set or explicit size bound. Add traversal guard to prevent pathological growth." } }, { "id": "closure-captured-scope", "severity": "warn", "description": "Detect closures returned from scopes containing large allocations that may be retained.", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "capturedScope": "Returned closure shares scope with large allocation '{{name}}'. V8 may retain the allocation via scope capture even though the closure doesn't reference it. Move the allocation to an inner scope." } }, { "id": "closure-dom-circular", "severity": "warn", "description": "Detect event handler property assignments that create closure-DOM circular references.", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "circularRef": "Event handler on '{{param}}' creates a closure that captures '{{param}}', forming a closure-DOM circular reference. Use addEventListener with a named handler for easier cleanup." } }, { "id": "create-root-dispose", "severity": "warn", "description": "Detect createRoot with unused dispose parameter.", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "unusedDispose": "createRoot() dispose parameter is never used. The reactive tree will never be cleaned up. Call dispose(), return it, or pass it to onCleanup()." } }, { "id": "detached-dom-reference", "severity": "warn", "description": "Detect DOM query results stored in module-scoped variables that may hold detached nodes.", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "detachedRef": "DOM query result from '{{method}}' stored in module-scoped variable '{{name}}'. If the DOM node is removed, this reference prevents garbage collection. Use a local variable or WeakRef instead." } }, { "id": "effect-outside-root", "severity": "error", "description": "Detect reactive computations created outside a reactive root (no Owner).", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "orphanedEffect": "{{primitive}}() called outside a reactive root. Without an Owner, this computation is never disposed and leaks memory. Wrap in a component, createRoot, or runWithOwner." } }, { "id": "finalization-registry-leak", "severity": "error", "description": "Detect FinalizationRegistry.register() where heldValue references the target.", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "selfReference": "FinalizationRegistry.register() heldValue references the target '{{name}}'. This strong reference prevents the target from being garbage collected, defeating the purpose of the registry." } }, { "id": "no-char-array-materialization", "severity": "warn", "description": 'Disallow split(""), Array.from(str), or [...str] in parsing loops.', "fixable": false, "category": "performance", "plugin": "solid", "messages": { "charArrayMaterialization": "Character array materialization via {{pattern}} in parsing loops allocates O(n) extra memory. Prefer index-based scanning." } }, { "id": "no-double-pass-delimiter-count", "severity": "warn", "description": "Disallow split-based delimiter counting followed by additional split passes.", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "doublePassDelimiterCount": "Delimiter counting via `split(...).length` plus another `split(...)` repeats full-string passes. Prefer one indexed scan." } }, { "id": "no-full-split-in-hot-parse", "severity": "warn", "description": "Disallow full split() materialization inside hot string parsing loops.", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "fullSplitInHotParse": "`split()` inside parsing loops materializes full token arrays each iteration. Prefer cursor/index scanning." } }, { "id": "no-heavy-parser-constructor-in-loop", "severity": "warn", "description": "Disallow constructing heavy parsing helpers inside loops.", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "heavyParserConstructor": "`new {{ctor}}(...)` inside parsing loops repeatedly allocates heavy parser helpers. Hoist and reuse instances." } }, { "id": "no-leaked-abort-controller", "severity": "warn", "description": "Detect AbortController in effects without abort() in onCleanup.", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "leakedAbort": "new AbortController() inside a reactive effect without onCleanup. Add onCleanup(() => controller.abort())." } }, { "id": "no-leaked-animation-frame", "severity": "warn", "description": "Detect requestAnimationFrame in effects without cancelAnimationFrame in onCleanup.", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "leakedRaf": "requestAnimationFrame() inside a reactive effect without onCleanup. Add onCleanup(() => cancelAnimationFrame(id))." } }, { "id": "no-leaked-event-listener", "severity": "warn", "description": "Detect addEventListener in effects without removeEventListener in onCleanup.", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "leakedListener": "addEventListener() inside a reactive effect without onCleanup. Each re-run leaks a listener. Add onCleanup(() => removeEventListener(...))." } }, { "id": "no-leaked-observer", "severity": "warn", "description": "Detect Observer APIs in effects without disconnect() in onCleanup.", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "leakedObserver": "new {{type}}() inside a reactive effect without onCleanup. Add onCleanup(() => observer.disconnect())." } }, { "id": "no-leaked-subscription", "severity": "warn", "description": "Detect WebSocket/EventSource/BroadcastChannel in effects without close() in onCleanup.", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "leakedSubscription": "new {{type}}() inside a reactive effect without onCleanup. Add onCleanup(() => instance.close())." } }, { "id": "no-leaked-timer", "severity": "warn", "description": "Detect setInterval/setTimeout in effects without onCleanup to clear them.", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "leakedTimer": "{{setter}}() inside a reactive effect without onCleanup. Each re-run leaks a timer. Add onCleanup(() => {{clearer}}(id))." } }, { "id": "no-loop-string-plus-equals", "severity": "warn", "description": "Disallow repeated string += accumulation in parsing loops.", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "loopStringPlusEquals": "Repeated string `+=` in parsing loops creates avoidable allocations. Buffer chunks and join once." } }, { "id": "no-multipass-split-pipeline", "severity": "warn", "description": "Disallow multipass split/map/filter pipelines in parsing code.", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "multipassSplit": "`split()` followed by multiple array passes allocates heavily on parsing paths. Prefer single-pass parsing." } }, { "id": "no-per-char-substring-scan", "severity": "warn", "description": "Disallow per-character substring/charAt scanning patterns in loops.", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "perCharSubstring": "Per-character `{{method}}()` scanning in loops allocates extra strings. Prefer index + charCodeAt scanning." } }, { "id": "no-repeated-token-normalization", "severity": "warn", "description": "Disallow repeated trim/lower/upper normalization chains on the same token in one function.", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "repeatedTokenNormalization": "Repeated token normalization `{{chain}}` on `{{name}}` in one function. Compute once and reuse." } }, { "id": "no-rescan-indexof-loop", "severity": "warn", "description": "Disallow repeated indexOf/includes scans from start in parsing loops.", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "rescanIndexOf": "Repeated `{{method}}()` from string start inside loops rescans prior text. Pass a cursor start index." } }, { "id": "no-rest-slice-loop", "severity": "warn", "description": "Disallow repeated self-slice reassignment loops in string parsing code.", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "restSliceLoop": "Repeated `{{name}} = {{name}}.{{method}}(...)` in loops creates string churn. Track cursor indexes instead." } }, { "id": "no-shift-splice-head-consume", "severity": "warn", "description": "Disallow shift/splice(0,1) head-consume patterns in loops.", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "headConsume": "Head-consuming `{{method}}()` inside loops causes array reindexing costs. Use index cursor iteration instead." } }, { "id": "no-write-only-index", "severity": "warn", "description": "Detect index structures that are written but never queried by key.", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "writeOnlyIndex": "Index '{{name}}' is built via writes but never queried by key. Remove it or use direct collection flow." } }, { "id": "prefer-charcode-over-regex-test", "severity": "warn", "description": "Prefer charCodeAt() range checks over regex .test() for single-character classification.", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "regexTest": "Regex `{{pattern}}`.test() on a single character. Use charCodeAt() range checks instead." } }, { "id": "prefer-index-scan-over-string-iterator", "severity": "warn", "description": "Prefer index-based string scanning over for-of iteration in ASCII parser code.", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "preferIndexScan": "ASCII parsing loops should avoid `for...of` string iteration. Prefer indexed scanning with charCodeAt for lower overhead." } }, { "id": "prefer-lazy-property-access", "severity": "warn", "description": "Suggests moving property access after early returns when not used immediately.", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "preferLazyPropertyAccess": "Property '{{propertyName}}' assigned to '{{variableName}}' before early return but not used there. Move assignment after early returns." } }, { "id": "prefer-map-lookup-over-linear-scan", "severity": "warn", "description": "Disallow repeated linear scans over fixed literal collections in hot paths.", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "preferMapLookup": "Linear scan over fixed collection '{{name}}' in '{{fnName}}'. Precompute Map/Set lookup for O(1) access." } }, { "id": "prefer-map-over-object-dictionary", "severity": "warn", "description": "Suggest Map for dictionary-like objects with dynamic keys.", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "preferMap": "Dynamic key assignment on dictionary object causes hidden class transitions. Consider using Map." } }, { "id": "prefer-precompiled-regex", "severity": "warn", "description": "Prefer hoisting regex literals to module-level constants to avoid repeated compilation.", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "inlineRegex": "Regex `{{pattern}}` is compiled on every call. Hoist to a module-level constant." } }, { "id": "prefer-set-has-over-equality-chain", "severity": "warn", "description": "Disallow 4+ guard-style equality checks against string literals on the same variable. Use a Set.", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "equalityChain": "{{count}} equality checks against `{{name}}`. Extract literals to a Set and use .has() instead." } }, { "id": "prefer-set-lookup-in-loop", "severity": "warn", "description": "Disallow linear search methods (.includes/.indexOf) on arrays inside loops.", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "preferSet": "`.{{method}}()` on `{{name}}` called inside a loop. Convert to a Set for O(1) lookups." } }, { "id": "recursive-timer", "severity": "warn", "description": "Detect setTimeout that recursively calls its enclosing function.", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "recursiveTimer": "setTimeout() recursively calls '{{name}}', creating an unbreakable polling loop. Add a termination condition or use setInterval with cleanup." } }, { "id": "self-referencing-store", "severity": "error", "description": "Detect setStore() where the value argument references the store itself.", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "selfReference": "setStore() value references the store variable '{{name}}', creating a circular proxy reference. This prevents garbage collection and can cause infinite loops." } }, { "id": "unbounded-collection", "severity": "warn", "description": "Detect module-scoped Map/Set/Array that only grow without removal.", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "unboundedCollection": "Module-scoped {{type}} '{{name}}' only uses additive methods ({{methods}}). Without removal or clearing, this grows unbounded. Consider WeakMap, LRU eviction, or periodic clear()." } }, { "id": "unbounded-signal-accumulation", "severity": "warn", "description": "Detect signal setters that accumulate data without truncation via spread+append pattern.", "fixable": false, "category": "performance", "plugin": "solid", "messages": { "unbounded": "Signal setter '{{name}}' accumulates data without bounds. The array grows monotonically via spread+append. Add truncation (e.g. prev.slice(-limit)) to prevent unbounded growth." } }],
|
|
42597
|
-
"reactivity": [{ "id": "async-tracked", "severity": "error", "description": "Disallow async functions in tracked scopes (createEffect, createMemo, etc.)", "fixable": false, "category": "reactivity", "plugin": "solid", "messages": { "asyncCreateEffect": "Async function{{fnName}} in createEffect loses tracking after await. Read all signals before the first await, or use createResource for async data fetching.", "asyncCreateMemo": "Async function{{fnName}} in createMemo won't work correctly. createMemo must be synchronous. For async derived data, use createResource instead.", "asyncCreateComputed": "Async function{{fnName}} in createComputed won't track properly. createComputed must be synchronous\u2014signal reads after await won't trigger re-computation.", "asyncCreateRenderEffect": "Async function{{fnName}} in createRenderEffect breaks DOM update timing. createRenderEffect must be synchronous. Move async work to onMount or createResource.", "asyncTrackedGeneric": "Async function{{fnName}} in {{source}} won't track reactivity after await. Solid's tracking only works synchronously\u2014signal reads after await are ignored." } }, { "id": "children-helper-misuse", "severity": "error", "description": "Detect misuse of the children() helper that causes unnecessary re-computation or breaks reactivity", "fixable": false, "category": "reactivity", "plugin": "solid", "messages": { "multipleChildrenCalls": "The children() helper should only be called once per component. Each call re-resolves children, causing unnecessary computation. Store the result and reuse the accessor.", "directChildrenAccess": "Access props.children through the children() helper in reactive contexts. Direct access won't properly resolve or track children. Use: const resolved = children(() => props.children);" } }, { "id": "cleanup-scope", "severity": "error", "description": "Detect onCleanup called outside of a valid reactive scope", "fixable": false, "category": "reactivity", "plugin": "solid", "messages": { "cleanupOutsideScope": "onCleanup() called outside a reactive scope ({{location}}). The cleanup function will never execute unless this code runs within a component, effect, createRoot, or runWithOwner." } }, { "id": "derived-signal", "severity": "error", "description": "Detect functions that capture reactive values but are called in untracked contexts", "fixable": false, "category": "reactivity", "plugin": "solid", "messages": { "moduleScopeInit": "Assigning '{{fnName}}()' to '{{varName}}' at module scope runs once at startup. It captures {{vars}} which won't trigger updates.", "moduleScopeCall": "'{{fnName}}()' at module scope executes once when the module loads. It captures {{vars}}\u2014changes won't cause this to re-run.", "componentTopLevelInit": "'{{fnName}}()' assigned to '{{varName}}' in '{{componentName}}' captures a one-time snapshot of {{vars}}. Changes won't update '{{varName}}'. Call in JSX or use createMemo().", "componentTopLevelCall": "'{{fnName}}()' at top-level of '{{componentName}}' runs once and captures a snapshot of {{vars}}. Changes won't re-run this. Move inside JSX: {{{fnName}}()} or wrap with createMemo().", "utilityFnCall": "'{{fnName}}()' inside '{{utilityName}}' won't be reactive. Call '{{utilityName}}' from a tracked scope (createEffect, JSX), or pass {{vars}} as parameters.", "syncCallbackCall": "'{{fnName}}()' inside {{methodName}}() callback runs outside a tracking scope. The result captures a snapshot of {{vars}} that won't update.", "untrackedCall": "'{{fnName}}()' called in an untracked context. It captures {{vars}} which won't trigger updates here. Move to JSX or a tracked scope." } }, { "id": "effect-as-memo", "severity": "error", "description": "Detect createEffect that only sets a derived signal value, which should be createMemo instead", "fixable": true, "category": "reactivity", "plugin": "solid", "messages": { "effectAsMemo": "This createEffect only computes a derived value. Use createMemo() instead: const {{signalName}} = createMemo(() => {{expression}});" } }, { "id": "effect-as-mount", "severity": "error", "description": "Detect createEffect/createRenderEffect with no reactive dependencies that should be onMount instead", "fixable": true, "category": "reactivity", "plugin": "solid", "messages": { "effectAsMount": "This {{primitive}} has no reactive dependencies and runs only once. Use onMount() for initialization logic that doesn't need to re-run." } }, { "id": "inline-component", "severity": "error", "description": "Detect component functions defined inside other components, which causes remount on every parent update", "fixable": false, "category": "reactivity", "plugin": "solid", "messages": { "inlineComponent": "Component '{{name}}' is defined inside another component. This creates a new component type on every render, causing unmount/remount. Move the component definition outside." } }, { "id": "no-top-level-signal-call", "severity": "error", "description": "Disallow calling signals at component top-level (captures stale snapshots)", "fixable": false, "category": "reactivity", "plugin": "solid", "messages": { "assignedToVar": "'{{name}}()' assigned to '{{varName}}' in {{componentName}} captures a one-time snapshot. '{{varName}}' won't update when {{name}} changes. Use createMemo(): `const {{varName}} = createMemo(() => {{name}}());`", "computedValue": "'{{name}}()' in computation at top-level of {{componentName}} captures a stale snapshot. Wrap with createMemo(): `const {{varName}} = createMemo(() => /* computation using {{name}}() */);`", "templateLiteral": "'{{name}}()' in template literal at top-level of {{componentName}} captures a stale snapshot. Use createMemo() or compute directly in JSX: `{`Hello, ${{{name}}()}!`}`", "destructuring": "Destructuring '{{name}}()' at top-level of {{componentName}} captures a stale snapshot. Access properties in JSX or createMemo(): `{{{name}}().propertyName}`", "objectLiteral": "'{{name}}()' in object literal at top-level of {{componentName}} captures a stale snapshot. Use createMemo() for the object, or spread in JSX.", "arrayCreation": "'{{name}}()' in array creation at top-level of {{componentName}} captures a stale snapshot. Wrap with createMemo(): `const items = createMemo(() => Array.from(...));`", "earlyReturn": "'{{name}}()' in early return at top-level of {{componentName}} captures a stale snapshot. Use <Show when={{{name}}()}> for conditional rendering instead.", "conditionalAssign": "'{{name}}()' in ternary at top-level of {{componentName}} captures a stale snapshot. Use createMemo() or compute in JSX: `{{{name}}() ? 'Yes' : 'No'}`", "functionArgument": "'{{name}}()' passed as argument at top-level of {{componentName}} captures a stale snapshot. Move to createEffect() or compute in JSX.", "syncCallback": "'{{name}}()' inside {{methodName}}() at top-level of {{componentName}} captures a stale snapshot. Wrap the entire computation in createMemo(): `const result = createMemo(() => items.{{methodName}}(...));`", "topLevelCall": "'{{name}}()' at top-level of {{componentName}} captures a one-time snapshot. Changes to {{name}} won't update the result. Call directly in JSX or wrap in createMemo()." } }, { "id": "ref-early-access", "severity": "error", "description": "Detect accessing refs before they are assigned (before mount)", "fixable": false, "category": "reactivity", "plugin": "solid", "messages": { "refBeforeMount": "Ref '{{name}}' is accessed before component mounts. Refs are undefined until after mount. Access in onMount(), createEffect(), or event handlers." } }, { "id": "resource-access-unchecked", "severity": "error", "description": "Detect accessing resource data without checking loading/error state.", "fixable": false, "category": "reactivity", "plugin": "solid", "messages": { "resourceUnchecked": "Accessing resource '{{name}}' without checking loading/error state may return undefined. Wrap in <Show when={!{{name}}.loading}> or <Suspense>." } }, { "id": "resource-implicit-suspense", "severity": "warn", "description": "Detect createResource that implicitly triggers or permanently breaks Suspense boundaries.", "fixable": false, "category": "reactivity", "plugin": "solid", "messages": { "loadingMismatch": "createResource '{{name}}' has no initialValue but uses manual loading checks ({{name}}.loading). Without initialValue, Suspense intercepts before your loading UI renders. Add initialValue to the options: createResource(fetcher, { initialValue: ... })", "conditionalSuspense": "createResource '{{name}}' is rendered inside a conditional mount point ({{mountTag}}) with a distant Suspense boundary. When the fetcher's Promise is pending, the SuspenseContext increment fires and unmounts the entire subtree. initialValue does NOT prevent this \u2014 it only prevents the accessor from returning undefined.", "missingErrorBoundary": "createResource '{{name}}' has no <ErrorBoundary> between its component and the nearest <Suspense>. When the fetcher throws (network error, 401/403/503, timeout), the error propagates to Suspense which absorbs it and stays in its fallback state permanently. Wrap the component in <ErrorBoundary fallback={...}> or catch errors inside the fetcher." } }, { "id": "resource-refetch-loop", "severity": "error", "description": "Detect refetch() calls inside createEffect which can cause infinite loops", "fixable": false, "category": "reactivity", "plugin": "solid", "messages": { "refetchInEffect": "Calling {{name}}.refetch() inside createEffect may cause infinite loops. The resource tracks its own dependencies. Move refetch to an event handler or use on() to control dependencies." } }, { "id": "signal-call", "severity": "error", "description": "Require signals to be called as functions when used in tracked contexts", "fixable": true, "category": "reactivity", "plugin": "solid", "messages": { "signalInJsxText": "Signal '{{name}}' in JSX text should be called: {{{name}}()}. Without (), you're rendering the function, not its value.", "signalInJsxAttribute": "Signal '{{name}}' in JSX attribute should be called: {{attr}}={{{name}}()}. Without (), the attribute won't update reactively.", "signalInTernary": "Signal '{{name}}' in ternary should be called: {{name}}() ? ... : .... The condition won't react to changes without ().", "signalInLogical": "Signal '{{name}}' in logical expression should be called: {{name}}() && .... Without (), this always evaluates to truthy (functions are truthy).", "signalInComparison": "Signal '{{name}}' in comparison should be called: {{name}}() === .... Comparing functions always returns false.", "signalInArithmetic": "Signal '{{name}}' in arithmetic should be called: {{name}}() + .... Math on functions produces NaN.", "signalInTemplate": "Signal '{{name}}' in template literal should be called: `...${{{name}}()}...`. Without (), you're embedding '[Function]'.", "signalInTrackedScope": "Signal '{{name}}' in {{where}} should be called: {{name}}(). Without (), reactivity is lost.", "badSignal": "The reactive variable '{{name}}' should be called as a function when used in {{where}}." } }, { "id": "signal-in-loop", "severity": "error", "description": "Detect problematic signal usage inside For/Index loop callbacks", "fixable": false, "category": "reactivity", "plugin": "solid", "messages": { "signalInLoop": "Creating signals inside <{{component}}> callback creates new signals on each render. Use a store at the parent level, or derive state from the index.", "signalCallInvariant": "Signal '{{name}}' called inside <{{component}}> produces the same value for every item. Extract to a variable or memoize with createMemo() before the loop.", "derivedCallInvariant": "'{{name}}()' inside <{{component}}> captures {{captures}} but doesn't use the loop item. Extract the call before the loop or pass the item as a parameter." } }, { "id": "store-reactive-break", "severity": "error", "description": "Detect patterns that break store reactivity: spreading stores, top-level property extraction, or destructuring", "fixable": false, "category": "reactivity", "plugin": "solid", "messages": { "storeSpread": "Spreading a store ({...store}) creates a static snapshot that won't update. Access store properties directly in JSX or tracked contexts.", "storeTopLevelAccess": "Accessing store property '{{property}}' at component top-level captures the value once. Access store.{{property}} directly in JSX or wrap in createMemo().", "storeDestructure": "Destructuring a store breaks reactivity. Access properties via store.{{property}} instead of destructuring." } }, { "id": "transition-pending-unchecked", "severity": "error", "description": "Detect useTransition usage without handling the isPending state", "fixable": false, "category": "reactivity", "plugin": "solid", "messages": { "pendingUnchecked": "useTransition returns [isPending, startTransition]. The isPending state should be used to show loading UI during transitions." } }],
|
|
42738
|
+
"reactivity": [{ "id": "async-tracked", "severity": "error", "description": "Disallow async functions in tracked scopes (createEffect, createMemo, etc.)", "fixable": false, "category": "reactivity", "plugin": "solid", "messages": { "asyncCreateEffect": "Async function{{fnName}} in createEffect loses tracking after await. Read all signals before the first await, or use createResource for async data fetching.", "asyncCreateMemo": "Async function{{fnName}} in createMemo won't work correctly. createMemo must be synchronous. For async derived data, use createResource instead.", "asyncCreateComputed": "Async function{{fnName}} in createComputed won't track properly. createComputed must be synchronous\u2014signal reads after await won't trigger re-computation.", "asyncCreateRenderEffect": "Async function{{fnName}} in createRenderEffect breaks DOM update timing. createRenderEffect must be synchronous. Move async work to onMount or createResource.", "asyncTrackedGeneric": "Async function{{fnName}} in {{source}} won't track reactivity after await. Solid's tracking only works synchronously\u2014signal reads after await are ignored." } }, { "id": "children-helper-misuse", "severity": "error", "description": "Detect misuse of the children() helper that causes unnecessary re-computation or breaks reactivity", "fixable": false, "category": "reactivity", "plugin": "solid", "messages": { "multipleChildrenCalls": "The children() helper should only be called once per component. Each call re-resolves children, causing unnecessary computation. Store the result and reuse the accessor.", "directChildrenAccess": "Access props.children through the children() helper in reactive contexts. Direct access won't properly resolve or track children. Use: const resolved = children(() => props.children);" } }, { "id": "cleanup-scope", "severity": "error", "description": "Detect onCleanup called outside of a valid reactive scope", "fixable": false, "category": "reactivity", "plugin": "solid", "messages": { "cleanupOutsideScope": "onCleanup() called outside a reactive scope ({{location}}). The cleanup function will never execute unless this code runs within a component, effect, createRoot, or runWithOwner." } }, { "id": "derived-signal", "severity": "error", "description": "Detect functions that capture reactive values but are called in untracked contexts", "fixable": false, "category": "reactivity", "plugin": "solid", "messages": { "moduleScopeInit": "Assigning '{{fnName}}()' to '{{varName}}' at module scope runs once at startup. It captures {{vars}} which won't trigger updates.", "moduleScopeCall": "'{{fnName}}()' at module scope executes once when the module loads. It captures {{vars}}\u2014changes won't cause this to re-run.", "componentTopLevelInit": "'{{fnName}}()' assigned to '{{varName}}' in '{{componentName}}' captures a one-time snapshot of {{vars}}. Changes won't update '{{varName}}'. Call in JSX or use createMemo().", "componentTopLevelCall": "'{{fnName}}()' at top-level of '{{componentName}}' runs once and captures a snapshot of {{vars}}. Changes won't re-run this. Move inside JSX: {{{fnName}}()} or wrap with createMemo().", "utilityFnCall": "'{{fnName}}()' inside '{{utilityName}}' won't be reactive. Call '{{utilityName}}' from a tracked scope (createEffect, JSX), or pass {{vars}} as parameters.", "syncCallbackCall": "'{{fnName}}()' inside {{methodName}}() callback runs outside a tracking scope. The result captures a snapshot of {{vars}} that won't update.", "untrackedCall": "'{{fnName}}()' called in an untracked context. It captures {{vars}} which won't trigger updates here. Move to JSX or a tracked scope." } }, { "id": "effect-as-memo", "severity": "error", "description": "Detect createEffect that only sets a derived signal value, which should be createMemo instead", "fixable": true, "category": "reactivity", "plugin": "solid", "messages": { "effectAsMemo": "This createEffect only computes a derived value. Use createMemo() instead: const {{signalName}} = createMemo(() => {{expression}});" } }, { "id": "effect-as-mount", "severity": "error", "description": "Detect createEffect/createRenderEffect with no reactive dependencies that should be onMount instead", "fixable": true, "category": "reactivity", "plugin": "solid", "messages": { "effectAsMount": "This {{primitive}} has no reactive dependencies and runs only once. Use onMount() for initialization logic that doesn't need to re-run." } }, { "id": "inline-component", "severity": "error", "description": "Detect component functions defined inside other components, which causes remount on every parent update", "fixable": false, "category": "reactivity", "plugin": "solid", "messages": { "inlineComponent": "Component '{{name}}' is defined inside another component. This creates a new component type on every render, causing unmount/remount. Move the component definition outside." } }, { "id": "no-top-level-signal-call", "severity": "error", "description": "Disallow calling signals at component top-level (captures stale snapshots)", "fixable": false, "category": "reactivity", "plugin": "solid", "messages": { "assignedToVar": "'{{name}}()' assigned to '{{varName}}' in {{componentName}} captures a one-time snapshot. '{{varName}}' won't update when {{name}} changes. Use createMemo(): `const {{varName}} = createMemo(() => {{name}}());`", "computedValue": "'{{name}}()' in computation at top-level of {{componentName}} captures a stale snapshot. Wrap with createMemo(): `const {{varName}} = createMemo(() => /* computation using {{name}}() */);`", "templateLiteral": "'{{name}}()' in template literal at top-level of {{componentName}} captures a stale snapshot. Use createMemo() or compute directly in JSX: `{`Hello, ${{{name}}()}!`}`", "destructuring": "Destructuring '{{name}}()' at top-level of {{componentName}} captures a stale snapshot. Access properties in JSX or createMemo(): `{{{name}}().propertyName}`", "objectLiteral": "'{{name}}()' in object literal at top-level of {{componentName}} captures a stale snapshot. Use createMemo() for the object, or spread in JSX.", "arrayCreation": "'{{name}}()' in array creation at top-level of {{componentName}} captures a stale snapshot. Wrap with createMemo(): `const items = createMemo(() => Array.from(...));`", "earlyReturn": "'{{name}}()' in early return at top-level of {{componentName}} captures a stale snapshot. Use <Show when={{{name}}()}> for conditional rendering instead.", "conditionalAssign": "'{{name}}()' in ternary at top-level of {{componentName}} captures a stale snapshot. Use createMemo() or compute in JSX: `{{{name}}() ? 'Yes' : 'No'}`", "functionArgument": "'{{name}}()' passed as argument at top-level of {{componentName}} captures a stale snapshot. Move to createEffect() or compute in JSX.", "syncCallback": "'{{name}}()' inside {{methodName}}() at top-level of {{componentName}} captures a stale snapshot. Wrap the entire computation in createMemo(): `const result = createMemo(() => items.{{methodName}}(...));`", "topLevelCall": "'{{name}}()' at top-level of {{componentName}} captures a one-time snapshot. Changes to {{name}} won't update the result. Call directly in JSX or wrap in createMemo()." } }, { "id": "ref-early-access", "severity": "error", "description": "Detect accessing refs before they are assigned (before mount)", "fixable": false, "category": "reactivity", "plugin": "solid", "messages": { "refBeforeMount": "Ref '{{name}}' is accessed before component mounts. Refs are undefined until after mount. Access in onMount(), createEffect(), or event handlers." } }, { "id": "resource-access-unchecked", "severity": "error", "description": "Detect accessing resource data without checking loading/error state.", "fixable": false, "category": "reactivity", "plugin": "solid", "messages": { "resourceUnchecked": "Accessing resource '{{name}}' without checking loading/error state may return undefined. Wrap in <Show when={!{{name}}.loading}> or <Suspense>." } }, { "id": "resource-implicit-suspense", "severity": "warn", "description": "Detect createResource that implicitly triggers or permanently breaks Suspense boundaries.", "fixable": true, "category": "reactivity", "plugin": "solid", "messages": { "loadingMismatch": "createResource '{{name}}' has no initialValue but uses {{name}}.loading for manual loading UI. Suspense intercepts before your loading UI renders \u2014 the component is unmounted before the <Show>/<Switch> evaluates. Replace createResource with onMount + createSignal to decouple from Suspense entirely.", "conditionalSuspense": "createResource '{{name}}' is inside a conditional mount point ({{mountTag}}) with a distant Suspense boundary. The SuspenseContext increment fires when the fetcher's Promise is pending and unmounts the entire page subtree \u2014 initialValue does NOT prevent this. Replace createResource with onMount + createSignal to avoid Suspense interaction.", "missingErrorBoundary": "createResource '{{name}}' has no <ErrorBoundary> between its component and the nearest <Suspense>. When the fetcher throws (network error, 401/403/503, timeout), the error propagates to Suspense which has no error handling \u2014 the boundary breaks permanently. Wrap the component in <ErrorBoundary> or replace createResource with onMount + createSignal and catch errors in the fetcher." } }, { "id": "resource-refetch-loop", "severity": "error", "description": "Detect refetch() calls inside createEffect which can cause infinite loops", "fixable": false, "category": "reactivity", "plugin": "solid", "messages": { "refetchInEffect": "Calling {{name}}.refetch() inside createEffect may cause infinite loops. The resource tracks its own dependencies. Move refetch to an event handler or use on() to control dependencies." } }, { "id": "signal-call", "severity": "error", "description": "Require signals to be called as functions when used in tracked contexts", "fixable": true, "category": "reactivity", "plugin": "solid", "messages": { "signalInJsxText": "Signal '{{name}}' in JSX text should be called: {{{name}}()}. Without (), you're rendering the function, not its value.", "signalInJsxAttribute": "Signal '{{name}}' in JSX attribute should be called: {{attr}}={{{name}}()}. Without (), the attribute won't update reactively.", "signalInTernary": "Signal '{{name}}' in ternary should be called: {{name}}() ? ... : .... The condition won't react to changes without ().", "signalInLogical": "Signal '{{name}}' in logical expression should be called: {{name}}() && .... Without (), this always evaluates to truthy (functions are truthy).", "signalInComparison": "Signal '{{name}}' in comparison should be called: {{name}}() === .... Comparing functions always returns false.", "signalInArithmetic": "Signal '{{name}}' in arithmetic should be called: {{name}}() + .... Math on functions produces NaN.", "signalInTemplate": "Signal '{{name}}' in template literal should be called: `...${{{name}}()}...`. Without (), you're embedding '[Function]'.", "signalInTrackedScope": "Signal '{{name}}' in {{where}} should be called: {{name}}(). Without (), reactivity is lost.", "badSignal": "The reactive variable '{{name}}' should be called as a function when used in {{where}}." } }, { "id": "signal-in-loop", "severity": "error", "description": "Detect problematic signal usage inside For/Index loop callbacks", "fixable": false, "category": "reactivity", "plugin": "solid", "messages": { "signalInLoop": "Creating signals inside <{{component}}> callback creates new signals on each render. Use a store at the parent level, or derive state from the index.", "signalCallInvariant": "Signal '{{name}}' called inside <{{component}}> produces the same value for every item. Extract to a variable or memoize with createMemo() before the loop.", "derivedCallInvariant": "'{{name}}()' inside <{{component}}> captures {{captures}} but doesn't use the loop item. Extract the call before the loop or pass the item as a parameter." } }, { "id": "store-reactive-break", "severity": "error", "description": "Detect patterns that break store reactivity: spreading stores, top-level property extraction, or destructuring", "fixable": false, "category": "reactivity", "plugin": "solid", "messages": { "storeSpread": "Spreading a store ({...store}) creates a static snapshot that won't update. Access store properties directly in JSX or tracked contexts.", "storeTopLevelAccess": "Accessing store property '{{property}}' at component top-level captures the value once. Access store.{{property}} directly in JSX or wrap in createMemo().", "storeDestructure": "Destructuring a store breaks reactivity. Access properties via store.{{property}} instead of destructuring." } }, { "id": "transition-pending-unchecked", "severity": "error", "description": "Detect useTransition usage without handling the isPending state", "fixable": false, "category": "reactivity", "plugin": "solid", "messages": { "pendingUnchecked": "useTransition returns [isPending, startTransition]. The isPending state should be used to show loading UI during transitions." } }],
|
|
42598
42739
|
"solid": [{ "id": "batch-optimization", "severity": "warn", "description": "Suggest using batch() when multiple signal setters are called in the same synchronous scope", "fixable": true, "category": "solid", "plugin": "solid", "messages": { "multipleSetters": "Multiple signal updates in the same scope cause multiple re-renders. Wrap in batch() for a single update: batch(() => { {{setters}} });" } }, { "id": "imports", "severity": "error", "description": 'Enforce consistent imports from "solid-js", "solid-js/web", and "solid-js/store".', "fixable": false, "category": "solid", "plugin": "solid", "messages": { "preferSource": 'Prefer importing {{name}} from "{{source}}".' } }, { "id": "index-vs-for", "severity": "warn", "description": "Suggest <For> for object arrays and <Index> for primitive arrays.", "fixable": true, "category": "solid", "plugin": "solid", "messages": { "indexWithObjects": "<Index> with object arrays causes the item accessor to change on any array mutation. Use <For> for objects to maintain reference stability.", "forWithPrimitives": "<For> with primitive arrays (strings, numbers) keys by value, which may cause unexpected re-renders. Consider <Index> if index stability is preferred." } }, { "id": "no-react-deps", "severity": "error", "description": "Disallow usage of dependency arrays in `createEffect`, `createMemo`, and `createRenderEffect`.", "fixable": true, "category": "solid", "plugin": "solid", "messages": { "noUselessDep": "In Solid, `{{name}}` doesn't accept a dependency array because it automatically tracks its dependencies. If you really need to override the list of dependencies, use `on`." } }, { "id": "no-react-specific-props", "severity": "error", "description": "Disallow usage of React-specific `className`/`htmlFor` props, which were deprecated in v1.4.0.", "fixable": true, "category": "solid", "plugin": "solid", "messages": { "prefer": "Prefer the `{{to}}` prop over the deprecated `{{from}}` prop.", "noUselessKey": "Elements in a <For> or <Index> list do not need a key prop." } }, { "id": "prefer-for", "severity": "warn", "description": "Enforce using Solid's `<For />` component for mapping an array to JSX elements.", "fixable": true, "category": "solid", "plugin": "solid", "messages": { "preferFor": "Prefer Solid's `<For each={...}>` component for rendering lists of objects. Array#map recreates all DOM elements on every update, while <For> updates only changed items by keying on reference.", "preferIndex": "Prefer Solid's `<Index each={...}>` component for rendering lists of primitives. Array#map recreates all DOM elements on every update, while <Index> updates only changed items by keying on index position.", "preferForOrIndex": "Prefer Solid's `<For />` or `<Index />` component for rendering lists. Use <For> when items are objects (keys by reference), or <Index> when items are primitives like strings/numbers (keys by index). Array#map recreates all DOM elements on every update." } }, { "id": "prefer-memo-complex-styles", "severity": "warn", "description": "Enforce extracting complex style computations to createMemo for better approach. Complex inline style objects are rebuilt on every render, which can impact approach.", "fixable": false, "category": "solid", "plugin": "solid", "messages": { "preferMemoComplexStyle": "Complex style computation should be extracted to createMemo() for better approach. This style object contains {{complexity}} conditional expressions that are recalculated on every render.", "preferMemoConditionalSpread": "Conditional spread operators in style objects should be extracted to createMemo(). Pattern like `...(condition ? {...} : {})` creates new objects on every render." } }, { "id": "prefer-show", "severity": "warn", "description": "Enforce using Solid's `<Show />` component for conditionally showing content. Solid's compiler covers this case, so it's a stylistic rule only.", "fixable": true, "category": "solid", "plugin": "solid", "messages": { "preferShowAnd": "Prefer Solid's `<Show when={...}>` component for conditional rendering. While Solid's compiler handles `&&` expressions, <Show> is more explicit and provides better readability for conditional content.", "preferShowTernary": "Prefer Solid's `<Show when={...} fallback={...}>` component for conditional rendering with a fallback. This provides clearer intent and better readability than ternary expressions." } }, { "id": "self-closing-comp", "severity": "warn", "description": "Disallow extra closing tags for components without children.", "fixable": true, "category": "solid", "plugin": "solid", "messages": { "selfClose": "Empty elements should be self-closing. Use `<{{name}} />` instead of `<{{name}}></{{name}}>` for cleaner, more concise JSX.", "dontSelfClose": "This element should not be self-closing based on your configuration. Use `<{{name}}></{{name}}>` instead of `<{{name}} />` for explicit opening and closing tags." } }, { "id": "style-prop", "severity": "warn", "description": "Require CSS properties in the `style` prop to be valid and kebab-cased (ex. 'font-size'), not camel-cased (ex. 'fontSize') like in React, and that property values with dimensions are strings, not numbers with implicit 'px' units.", "fixable": true, "category": "solid", "plugin": "solid", "messages": { "kebabStyleProp": "Solid uses kebab-case for CSS property names, not camelCase like React. Use '{{kebabName}}' instead of '{{name}}'.", "invalidStyleProp": "'{{name}}' is not a valid CSS property. Check for typos, or if this is a custom property, prefix it with '--' (e.g., '--{{name}}').", "numericStyleValue": "Numeric values for dimensional properties need explicit units in Solid. Unlike React, Solid does not auto-append 'px'. Use '{{value}}px' or another appropriate unit.", "stringStyle": "Use an object for the style prop instead of a string for better approach and type safety. Example: style={{ '{{prop}}': '{{value}}' }}." } }]
|
|
42599
42740
|
};
|
|
42600
42741
|
function getRule2(id) {
|