mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-11-11 19:09:20 +00:00
`readAttr` matched only quoted attribute values. Unquoted values are valid HTML5 and the runtime honours them, so on a root written `data-composition-id=main data-start=0 data-width=1920 data-height=1080` the linter reported two errors for attributes that are present, while a file with genuinely overlapping unquoted clips and no `class="clip"` linted clean. The same rule set printed the composition id in its own message, because `readDecodedAttr` — the htmlparser2-backed reader twenty lines below — parsed that tag correctly, which isolated the defect to the regex. Widening the regex with an unquoted alternative is worse, not better: it has no notion of attribute-list position, so it captures `name=value` pairs out of other attributes' quoted values. Measured on that version, two `<video>` elements with distinct real ids sharing a `?id=9` source both read as id "9" — `duplicate_media_id` fired on an id that does not exist and swallowed two genuine `video_missing_muted` findings — and a video with no id at all but `?id=7` in its URL had `media_missing_id` masked, hiding a frozen-video render bug. A Google-Drive-style `?export=view&id=…` asset URL is enough to trigger it. Delegating to the parser fixes the blind spot without that class of mis-read, and drops the `=`-truncation and undecoded-entity divergences as well. `|| null` keeps the existing "empty value means absent" contract. Behaviour change worth surfacing in release notes: attributes that were invisible are now linted, so a project written with unquoted attributes AND a real violation will newly fail `lint` and `render --strict`. Correct unquoted-attribute projects lint clean. The repo's own 13 examples and all registry blocks produce byte-identical findings. `readJsonAttr` is left alone; the parser makes it redundant, but removing it is its own change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>