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
+3 -6
View File
@@ -1,6 +1,6 @@
import type { HyperframeLintFinding, HyperframeLintResult, HyperframeLinterOptions } from "./types";
import { buildLintContext } from "./context";
import { readAttr, truncateSnippet } from "./utils";
import { parseHtmlStructure, readAttr, truncateSnippet } from "./utils";
import { coreRules } from "./rules/core";
import { mediaRules } from "./rules/media";
import { gsapRules } from "./rules/gsap";
@@ -73,11 +73,8 @@ function extractMediaUrls(html: string): Array<{
elementId?: string;
snippet: string;
}> = [];
const tagRe = /<(video|audio|img|source)\b[^>]*>/gi;
let match: RegExpExecArray | null;
while ((match = tagRe.exec(html)) !== null) {
const tagName = (match[1] ?? "").toLowerCase();
const raw = match[0];
for (const { name: tagName, raw } of parseHtmlStructure(html).tags) {
if (!/^(?:video|audio|img|source)$/.test(tagName)) continue;
const src = readAttr(raw, "src");
if (!src) continue;
if (/^https?:\/\//i.test(src)) {