@hyperframes/lint 0.8.13 → 0.8.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.js +14 -25
- package/dist/browser.js.map +1 -1
- package/dist/index.js +16 -32
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -96,13 +96,7 @@ function readDecodedAttr(tagSource, attr) {
|
|
|
96
96
|
return value;
|
|
97
97
|
}
|
|
98
98
|
function readJsonAttr(tagSource, attr) {
|
|
99
|
-
|
|
100
|
-
const escaped = attr.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
101
|
-
const match = tagSource.match(
|
|
102
|
-
new RegExp(`(?<![\\w-])${escaped}\\s*=\\s*(?:"([^"]*)"|'([^']*)')`, "i")
|
|
103
|
-
);
|
|
104
|
-
if (!match) return null;
|
|
105
|
-
return match[1] ?? match[2] ?? null;
|
|
99
|
+
return readDecodedAttr(tagSource, attr);
|
|
106
100
|
}
|
|
107
101
|
function collectCompositionIds(tags) {
|
|
108
102
|
const ids = /* @__PURE__ */ new Set();
|
|
@@ -531,7 +525,7 @@ var coreRules = [
|
|
|
531
525
|
}
|
|
532
526
|
];
|
|
533
527
|
},
|
|
534
|
-
// missing_timeline_registry
|
|
528
|
+
// missing_timeline_registry
|
|
535
529
|
// fallow-ignore-next-line complexity
|
|
536
530
|
({ source, rawSource, rootTag, options }) => {
|
|
537
531
|
if (options.isSubComposition || rawSource.trimStart().toLowerCase().startsWith("<template")) {
|
|
@@ -547,14 +541,6 @@ var coreRules = [
|
|
|
547
541
|
fixHint: "Register each composition timeline on `window.__timelines[compositionId]`."
|
|
548
542
|
});
|
|
549
543
|
}
|
|
550
|
-
if (TIMELINE_REGISTRY_ASSIGN_PATTERN.test(source) && !TIMELINE_REGISTRY_INIT_PATTERN.test(source)) {
|
|
551
|
-
findings.push({
|
|
552
|
-
code: "timeline_registry_missing_init",
|
|
553
|
-
severity: "error",
|
|
554
|
-
message: "`window.__timelines[\u2026] = \u2026` is used without initializing `window.__timelines` first.",
|
|
555
|
-
fixHint: "Add `window.__timelines = window.__timelines || {};` before any timeline assignment."
|
|
556
|
-
});
|
|
557
|
-
}
|
|
558
544
|
return findings;
|
|
559
545
|
},
|
|
560
546
|
// timeline_id_mismatch
|
|
@@ -1108,9 +1094,9 @@ var mediaRules = [
|
|
|
1108
1094
|
findings.push({
|
|
1109
1095
|
code: "video_nested_in_timed_element",
|
|
1110
1096
|
severity: "error",
|
|
1111
|
-
message: `<video> with data-start is nested inside <${parent.name}${parent.id ? ` id="${parent.id}"` : ""}> which also has data-start. The
|
|
1097
|
+
message: `<video> with data-start is nested inside <${parent.name}${parent.id ? ` id="${parent.id}"` : ""}> which also has data-start. The frame extractor resolves the video's start from its own data-start without the wrapper's offset, while visibility uses the wrapper's window, so the two disagree: the clip shows the wrong source frames and then disappears partway through its slot.`,
|
|
1112
1098
|
elementId: readAttr(tag.raw, "id") || void 0,
|
|
1113
|
-
fixHint: "
|
|
1099
|
+
fixHint: "Time the wrapper OR the video, never both: remove data-start from the wrapper (use it as a non-timed visual container), or move the <video> up to be a direct child of the stage.",
|
|
1114
1100
|
snippet: truncateSnippet(tag.raw)
|
|
1115
1101
|
});
|
|
1116
1102
|
break;
|
|
@@ -3638,7 +3624,7 @@ var compositionRules = [
|
|
|
3638
3624
|
severity: "error",
|
|
3639
3625
|
message: `<${tag.name}${elementId ? ` id="${elementId}"` : ""}> uses data-layer instead of data-track-index.`,
|
|
3640
3626
|
elementId,
|
|
3641
|
-
fixHint: "Replace data-layer with data-track-index.
|
|
3627
|
+
fixHint: "Replace data-layer with data-track-index, which is the canonical name Studio and the linter read. Neither name is read by the render.",
|
|
3642
3628
|
snippet: truncateSnippet(tag.raw)
|
|
3643
3629
|
});
|
|
3644
3630
|
}
|
|
@@ -4036,10 +4022,13 @@ var compositionRules = [
|
|
|
4036
4022
|
// can't leak styles into each other. A rule whose LEFTMOST selector is the ROOT
|
|
4037
4023
|
// element's own class (e.g. `.frame { ... }` on the same element that carries
|
|
4038
4024
|
// data-composition-id) therefore becomes a DESCENDANT selector that can never
|
|
4039
|
-
// match the
|
|
4040
|
-
//
|
|
4041
|
-
//
|
|
4042
|
-
//
|
|
4025
|
+
// match the SCOPED element itself. NOTE on the symptom: since #1886 the producer
|
|
4026
|
+
// preserves the authored root as a `data-hf-inner-root` wrapper INSIDE the scoped
|
|
4027
|
+
// element (regression fixture packages/producer/tests/sub-comp-class-selector),
|
|
4028
|
+
// so the class still matches as a descendant and the scene no longer renders
|
|
4029
|
+
// unstyled. This rule is now a consistency constraint, not a render-bug guard:
|
|
4030
|
+
// `#root` is the shape the registry blocks model and the one the scoper
|
|
4031
|
+
// special-cases. Style the root via `#root`
|
|
4043
4032
|
// (the scoper special-cases the root id) and descendants via plain selectors,
|
|
4044
4033
|
// like the registry blocks — the runtime already scopes each scene by id, so a
|
|
4045
4034
|
// class namespace on the root is redundant.
|
|
@@ -4056,9 +4045,9 @@ var compositionRules = [
|
|
|
4056
4045
|
{
|
|
4057
4046
|
code: "subcomposition_root_styled_by_class",
|
|
4058
4047
|
severity: "error",
|
|
4059
|
-
message: `Root element has class="${rootClasses.join(" ")}" and is styled by ${offenders.length} rule(s) keyed off that class (e.g. ${example}). At render, every sub-composition rule is scoped to [data-composition-id="${rootCompositionId}"] <selector>, so a selector whose leftmost part is the ROOT's own class becomes a descendant selector that cannot match the
|
|
4048
|
+
message: `Root element has class="${rootClasses.join(" ")}" and is styled by ${offenders.length} rule(s) keyed off that class (e.g. ${example}). At render, every sub-composition rule is scoped to [data-composition-id="${rootCompositionId}"] <selector>, so a selector whose leftmost part is the ROOT's own class becomes a descendant selector that cannot match the scoped element itself. Since #1886 the producer preserves the authored root as an inner wrapper, so this no longer renders the scene unstyled, but #root is the shape the scoper special-cases and the registry blocks model. Use it so preview, render, and Studio agree.`,
|
|
4060
4049
|
selector: example,
|
|
4061
|
-
fixHint: `Give the root id="root" and style it with \`#root { ... }\` plus plain descendant selectors (\`.kicker\`, \`#hero\`) \u2014 the runtime already scopes each sub-composition by data-composition-id, so a class namespace on the root is redundant
|
|
4050
|
+
fixHint: `Give the root id="root" and style it with \`#root { ... }\` plus plain descendant selectors (\`.kicker\`, \`#hero\`) \u2014 the runtime already scopes each sub-composition by data-composition-id, so a class namespace on the root is redundant.`,
|
|
4062
4051
|
snippet: truncateSnippet(rootTag.raw)
|
|
4063
4052
|
}
|
|
4064
4053
|
];
|
|
@@ -4804,6 +4793,7 @@ import { checkSubCompositionUsability } from "@hyperframes/parsers/sub-compositi
|
|
|
4804
4793
|
import { parseHTML } from "linkedom";
|
|
4805
4794
|
import {
|
|
4806
4795
|
cleanAssetUrl as cleanAssetUrl2,
|
|
4796
|
+
collectSubCompositionSrcs,
|
|
4807
4797
|
isRemoteOrInlineUrl as isRemoteOrInlineUrl2,
|
|
4808
4798
|
isUnresolvedAssetPlaceholder as isUnresolvedAssetPlaceholder2,
|
|
4809
4799
|
isWithinProjectRoot,
|
|
@@ -5306,13 +5296,7 @@ function lintMissingOrEmptySubComposition(projectDir, rootHtml) {
|
|
|
5306
5296
|
const checked = /* @__PURE__ */ new Map();
|
|
5307
5297
|
const visited = /* @__PURE__ */ new Set();
|
|
5308
5298
|
const walk = (html) => {
|
|
5309
|
-
const
|
|
5310
|
-
const scannable = maskNonScannableRanges2(html);
|
|
5311
|
-
let match;
|
|
5312
|
-
while ((match = compositionSrcRe.exec(scannable)) !== null) {
|
|
5313
|
-
const srcPath = (match[1] ?? "").trim();
|
|
5314
|
-
if (!srcPath) continue;
|
|
5315
|
-
if (isUnresolvedAssetPlaceholder2(srcPath)) continue;
|
|
5299
|
+
for (const srcPath of collectSubCompositionSrcs(html)) {
|
|
5316
5300
|
const filePath = resolve(projectDir, srcPath);
|
|
5317
5301
|
if (visited.has(filePath)) continue;
|
|
5318
5302
|
visited.add(filePath);
|