Repository navigation
Close a void element that set_tag_name renames to a non-void name (port of cloudflare/lol-html#337) - #4
Open
robobun wants to merge 1 commit into
Open
Close a void element that set_tag_name renames to a non-void name (port of cloudflare/lol-html#337)#4robobun wants to merge 1 commit into
robobun wants to merge 1 commit into
Conversation
robobun
added a commit
to oven-sh/bun
that referenced
this pull request
Sep 15, 2026
… name Pin oven-sh/lol-html at 5816ca4 (oven-sh/lol-html#4, the bun-branch port of cloudflare/lol-html#337). `el.tagName = "picture"` on `<img>` rewrote only the start tag, so the following siblings re-parsed as children of the unclosed `<picture>`. lol-html now writes `</picture>` right after the start tag unless the new name is void too. The pin also moves past ea6125b (descendant-selector matching linear in depth), which #41479 pins on its own.
`Element::set_tag_name` on an HTML void element (`<img>`, `<br>`, `<input>`, `<hr>`, ...) rewrote only the start tag. A void element has no end tag in the input, so nothing closed the new name: every sibling after `<img>` renamed to `picture` re-parsed as a child of `<picture>`, and after a rename to `textarea` or `style` the rest of the document became its text. The start tag now carries an `emit_end_tag` flag. `set_tag_name` sets it when the element cannot have content, is in the HTML namespace, and the new name is not itself a void element name. The serializer then writes `</name>` straight after the start tag, before any `after()` content, and drops a decorative `/>`. A rename to another void name, a rename of a self-closing element in foreign content (closed by its `/>` whatever the name), and `remove()`/`replace()` are unchanged. The element still reports `can_have_content() == false`, so `prepend`, `append` and `set_inner_content` stay no-ops and no end tag handlers run for the written tag. The void-name list moves from `selectors_vm::stack` to `Tag::is_void_html_element` so both callers share it. Nine existing tests used an `<img>` rename as a match marker and now expect the end tag too. Port of cloudflare#337 (8dba2f7) to the `bun` branch. The differences: the start tag is reached through `tag()`/`tag_mut()`, and `StartTag::take_owned` copies the flag so that it survives a handler suspension (new test `void_element_renamed_across_suspension`).
robobun
force-pushed
the
robobun/void-rename-end-tag
branch
from
September 22, 2026 12:17
5816ca4 to
55edbfd
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The
bun-branch port of cloudflare#337, for Bun'sHTMLRewriter. It is the same patch with two differences for handler suspension. The start tag is reached throughtag()/tag_mut().StartTag::take_ownedcopies the new flag, so the end tag survives a suspension (new testvoid_element_renamed_across_suspension).Element::set_tag_nameon an HTML void element (<img>,<br>,<input>,<hr>, ...) rewrote only the start tag, so nothing closed the new name:<img src=a.png><p>next</p>renamed topicturecame out as<picture src=a.png><p>next</p>, and both<p>re-parse as its children. With this change the serializer writes</picture>right after the start tag (before anyafter()content) unless the new name is itself void. Foreign-content/>elements,remove()andreplace()are unchanged, andcan_have_content()staysfalse.Not to be merged ahead of upstream review: if cloudflare#337 changes there, this branch is replaced by a cherry-pick of the merged commit, as with #2.
Rebased on 2026-09-22 onto the v3.0.1-based
bun(e1a306d). The earlier port for the v2.7.2 lineage is kept atrobobun/void-rename-end-tag-v2.7.2(5816ca4). oven-sh/bun#41968 (draft) pins that commit while Bun's main is on the v2.7.2 lineage, and moves to this branch after the v3.0.1 move lands in Bun.cargo test --features _integration_test: 210 + 3 + 38 + 2 pass.cargo clippy --all-targets: no new warnings.cargo fmt --check: clean. The red checks on this PR fail at "Set up job" before any command runs, as they do on thebunbranch itself.