From ddd3901c9fb67e3f7efb878c1f04720e8a0c636e Mon Sep 17 00:00:00 2001 From: Dylan Piercey Date: Wed, 23 Sep 2026 12:17:38 -0700 Subject: [PATCH] fix: report comments before a comma-continued concise attr line At a newline in a concise open tag, the parser looks ahead past whitespace and comments for a `,` that continues the tag on the next line, and jumped past everything it skipped, so the comments on those lines reached no handler and consumers dropped them. It now steps past only the newline and parses the rest as part of the open tag, which reports each comment through `onOpenTagComment`. Co-Authored-By: Claude Opus 5.5 (1M context) --- .changeset/concise-attr-line-comments.md | 5 +++++ ...026-09-23-bench-compare-installs-with-npm.md | 12 ++++++++++++ .../attr-comma-multiline-comments.expected.txt | 8 ++++++-- .../open-tag-comments-concise.expected.txt | 17 +++++++++++++++-- .../open-tag-comments-concise/input.marko | 4 ++++ src/states/OPEN_TAG.ts | 6 +++--- 6 files changed, 45 insertions(+), 7 deletions(-) create mode 100644 .changeset/concise-attr-line-comments.md create mode 100644 agent-feedback/items/2026-09-23-bench-compare-installs-with-npm.md diff --git a/.changeset/concise-attr-line-comments.md b/.changeset/concise-attr-line-comments.md new file mode 100644 index 00000000..0494e4a4 --- /dev/null +++ b/.changeset/concise-attr-line-comments.md @@ -0,0 +1,5 @@ +--- +"htmljs-parser": patch +--- + +Report the comments on the lines before a comma-continued concise attr line through `onOpenTagComment`. They were skipped without an event, so consumers dropped them. diff --git a/agent-feedback/items/2026-09-23-bench-compare-installs-with-npm.md b/agent-feedback/items/2026-09-23-bench-compare-installs-with-npm.md new file mode 100644 index 00000000..f2abdfc1 --- /dev/null +++ b/agent-feedback/items/2026-09-23-bench-compare-installs-with-npm.md @@ -0,0 +1,12 @@ +--- +type: dx +impact: low +effort: low +site: bench.ts +--- + +# Install the COMPARE build with pnpm in the bench + +`COMPARE= pnpm run bench` clones the ref and runs `npm ci && npm run --if-present build` in it, but the repo only has a `pnpm-lock.yaml`, so `npm ci` exits with `EUSAGE` and the comparison never runs. Run `pnpm install --frozen-lockfile && pnpm run build` instead. Because the clone's directory is created before the install, a failed run also leaves it behind, and the next run sees it and skips the install, then fails to import the unbuilt `dist`. Only treat the clone as ready once its build has finished. + +Check: `rm -rf "$TMPDIR/htmljs-bench-main" /tmp/htmljs-bench-main; COMPARE=main GREP=attr-comma pnpm run bench` fails with `The npm ci command can only install with an existing package-lock.json`. diff --git a/src/__tests__/fixtures/attr-comma-multiline-comments/__snapshots__/attr-comma-multiline-comments.expected.txt b/src/__tests__/fixtures/attr-comma-multiline-comments/__snapshots__/attr-comma-multiline-comments.expected.txt index 7b8ad8a2..42d69a5d 100644 --- a/src/__tests__/fixtures/attr-comma-multiline-comments/__snapshots__/attr-comma-multiline-comments.expected.txt +++ b/src/__tests__/fixtures/attr-comma-multiline-comments/__snapshots__/attr-comma-multiline-comments.expected.txt @@ -4,12 +4,16 @@ │ │ │╰─ attrValue.value "bar" │ │ ╰─ attrValue "=bar" ╰─ ╰─ attrName "foo" -3├─ // comment +3╭─ // comment + │ │ ╰─ openTagComment.value " comment" + ╰─ ╰─ openTagComment "// comment" 4╭─ ,bar=baz │ │ │╰─ attrValue.value "baz" │ │ ╰─ attrValue "=baz" ╰─ ╰─ attrName "bar" -5├─ /* block */ +5╭─ /* block */ + │ │ ╰─ openTagComment.value " block " + ╰─ ╰─ openTagComment "/* block */" 6╭─ ,qux=qux │ │ │╰─ attrValue.value "qux" │ │ ╰─ attrValue "=qux" diff --git a/src/__tests__/fixtures/open-tag-comments-concise/__snapshots__/open-tag-comments-concise.expected.txt b/src/__tests__/fixtures/open-tag-comments-concise/__snapshots__/open-tag-comments-concise.expected.txt index a1ccfacb..22b4ae82 100644 --- a/src/__tests__/fixtures/open-tag-comments-concise/__snapshots__/open-tag-comments-concise.expected.txt +++ b/src/__tests__/fixtures/open-tag-comments-concise/__snapshots__/open-tag-comments-concise.expected.txt @@ -11,6 +11,19 @@ │ ├─ closeTagEnd(div) │ ├─ openTagEnd ╰─ ╰─ tagName "span" -3╭─ +3╭─ input + │ ├─ closeTagEnd(span) │ ├─ openTagEnd - ╰─ ╰─ closeTagEnd(span) \ No newline at end of file + ╰─ ╰─ tagName "input" +4╭─ // e + │ │ ╰─ openTagComment.value " e" + ╰─ ╰─ openTagComment "// e" +5╭─ /* f */ + │ │ ╰─ openTagComment.value " f " + ╰─ ╰─ openTagComment "/* f */" +6╭─ ,type="text" + │ │ │╰─ attrValue.value "\"text\"" + │ │ ╰─ attrValue "=\"text\"" + ╰─ ╰─ attrName "type" +7╭─ + ╰─ ╰─ openTagEnd \ No newline at end of file diff --git a/src/__tests__/fixtures/open-tag-comments-concise/input.marko b/src/__tests__/fixtures/open-tag-comments-concise/input.marko index d943a877..82e6c9f5 100644 --- a/src/__tests__/fixtures/open-tag-comments-concise/input.marko +++ b/src/__tests__/fixtures/open-tag-comments-concise/input.marko @@ -1,2 +1,6 @@ div /* c */ a=1 span // d +input + // e + /* f */ + ,type="text" diff --git a/src/states/OPEN_TAG.ts b/src/states/OPEN_TAG.ts index cae5edec..4723966e 100644 --- a/src/states/OPEN_TAG.ts +++ b/src/states/OPEN_TAG.ts @@ -131,10 +131,10 @@ export const OPEN_TAG: StateDefinition = { } } - // comma continues the open tag with another line attribute + // comma continues the open tag with another line attribute, so + // the comments before it are parsed as part of the open tag if (data.charCodeAt(cur) === CODE.COMMA) { - this.pos = cur + 1; - this.consumeWhitespace(); + this.pos += len; continue; }