Skip to content

Fixes how empty XHTML and SVG elements are serialized #305

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

PolariTOON
Copy link

The DOM Parsing and Serialization spec defines that only some empty elements should be autoclosed when serializing XHTML: https://w3c.github.io/DOM-Parsing/#ref-for-dfn-html-namespace-3 . This PR aligns with this spec.

It also tells that among empty elements, only those ones get a space before the slash (<link /> instead of <link/>). As such, SVG elements should not have a space for example (<rect/> instead of <rect />). This implements such change. Ideally it should also be applied on other XML documents, but i wanted to keep things simple and not too invasive for the codebase.

XHTML is case-sensitive so this matches only lowercase tags.
For consistency with XMLSerializer, only void XHTML elements should have a space.
Ideally such change should also be applied on other XML documents, but trying here to keep things simple.
@PolariTOON PolariTOON force-pushed the xhtml-and-svg-void-elements branch from 979886d to 8ab487b Compare May 29, 2025 16:31
@WebReflection
Copy link
Owner

What issue is this trying to solve?

@PolariTOON
Copy link
Author

PolariTOON commented May 30, 2025

Issues happen if you feed the HTML parser (of a browser) with XHTML content generated by LinkeDOM, resulting in the wrong DOM, because the HTML parser treats self-closing tags of non void elements as opening tags.

People should likely not do that, but realistically that can happen if, for example:

This PR prevents LinkedDOM to generate such not roundtripping code when serializing an XHTML document. I can add the examples above as testcases if you want.

@@ -26,6 +26,6 @@ export const Mime = {
'application/xhtml+xml': {
docType: '<?xml version="1.0" encoding="utf-8"?>',
ignoreCase: false,
voidElements
voidElements: /^(?:area|base|br|col|embed|hr|img|input|keygen|link|menuitem|meta|param|source|track|wbr)$/
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it misses a i I suppose but I don't understand why this is needed

@@ -461,7 +461,7 @@ export class Element extends ParentNode {
const start = next[START];
if (isOpened) {
if ('ownerSVGElement' in start)
out.push(' />');
out.push('/>');
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a breaking change for people generating JSX-like output for files to serve + it might play badly with non-quoted attributes as in <el test=123/> ... this is a bad idea and it doesn't solve any issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants