fix(lint): parse HTML structure without regex (#2223)

* fix(lint): ignore scripts inside quoted attributes

* Address PR review feedback (#2223)

- replace repeated attribute scanner with quoted tag ranges
- remove the Fallow complexity finding

* refactor(lint): parse HTML structure with htmlparser2

* fix(lint): traverse template style sources

* test(lint): cover nested template style sources
This commit is contained in:
Miguel Ángel
2026-07-11 00:03:07 -04:00
committed by GitHub
parent 87618eef4c
commit 05c3b5503f
10 changed files with 252 additions and 144 deletions
+26
View File
@@ -209,3 +209,29 @@ describe("missing_or_empty_sub_composition", () => {
expect(finding?.message).toContain("compositions/does-not-exist.html");
});
});
describe("template shell style sources", () => {
it("collects links, style blocks, and inline styles from template content", async () => {
const project = makeProject(`<html><body>
<div id="scene" data-composition-id="main" data-width="1920" data-height="1080" data-start="0" data-duration="10"></div>
<template data-composition-id="shell">
<link rel="stylesheet" href="shell.css">
<style>[data-composition-id="main"] .title { opacity: 0; }</style>
<div style="mask-image: url(missing-inline-mask.png)"></div>
<template><style>[data-composition-id="main"] .nested { opacity: 0; }</style></template>
</template>
<script>window.__timelines = {};</script>
</body></html>`);
writeFileSync(
join(project, "shell.css"),
'[data-composition-id="main"] .from-link { opacity: 0; }',
);
const { results } = await lintProject(project);
const findings = results.flatMap((entry) => entry.result.findings);
expect(
findings.filter((finding) => finding.code === "composition_self_attribute_selector"),
).toHaveLength(3);
expect(findings.some((finding) => finding.code === "texture_mask_asset_not_found")).toBe(true);
});
});