SVG / MathML streaming with <template for>
Streaming SVG or MathML children with
<template for> fails: the insert is HTML-namespaced,
so nothing paints. Stream the whole <svg> or
<math> instead — or parse that tree in a
<div hidden> and swap it in with JS, like React/Sold/Preact SSR.
DPU completion inside <svg>
<template for> inserts an HTML-namespaced
<circle> into an existing <svg>.
It is not an SVGElement, so it never paints. React-style JS
replaces a placeholder with a complete <svg>
parsed in a hidden div, so it does.
Limit: the DPU frame stays empty. The streamed circle is HTML, not SVG. The React column paints.
<svg> <?start name="svg-slot"> <text>Loading…</text> <?end> </svg> <template for="svg-slot"> <circle cx="80" cy="55" r="24" fill="tomato"/> </template>
<div id="B">Loading…</div>
<div hidden id="S">
<svg>
<circle cx="80" cy="55" r="24" fill="tomato"/>
</svg>
</div>
<script>
B.replaceWith(...S.childNodes);
S.remove();
</script>
Stream the whole <svg>
Replace the pending range with a complete <svg>
tree. The HTML parser puts it in the SVG namespace, so the circle
paints. React-style JS does the same swap from a hidden div.
Expected: DPU, JS replacement, and the static result all paint a tomato circle.
<?start name="svg-whole">
Loading…
<?end>
<template for="svg-whole">
<svg width="160" height="100" viewBox="0 0 160 100">
<circle cx="80" cy="55" r="24" fill="tomato"/>
</svg>
</template>
<div id="B">Loading…</div>
<div hidden id="S">
<svg>
<circle cx="80" cy="55" r="24" fill="tomato"/>
</svg>
</div>
<script>
B.replaceWith(...S.childNodes);
S.remove();
</script>
DPU completion inside <math>
Same limit as SVG: <template for> inserts
HTML-namespaced <mi> / <mo> /
<mn> into an existing <math>.
They are not MathML, so they typeset as plain text (or not at all).
React-style JS replaces a placeholder with a complete
<math> parsed in a hidden div, so it typesets.
Limit: the DPU frame has no italic variables or stacked exponents. The streamed tokens are HTML, not MathML. The React column typesets.
<math> <?start name="math-slot"> <mtext>Loading…</mtext> <?end> </math> <template for="math-slot"> <msup><mi>a</mi><mn>2</mn></msup> <mo>+</mo> <msup><mi>b</mi><mn>2</mn></msup> <mo>=</mo> <msup><mi>c</mi><mn>2</mn></msup> </template>
<div id="B">Loading…</div>
<div hidden id="S">
<math display="block">
<msup><mi>a</mi><mn>2</mn></msup>
<mo>+</mo>
<msup><mi>b</mi><mn>2</mn></msup>
<mo>=</mo>
<msup><mi>c</mi><mn>2</mn></msup>
</math>
</div>
<script>
B.replaceWith(...S.childNodes);
S.remove();
</script>
Stream the whole <math>
Replace the pending range with a complete <math>
tree. The HTML parser puts the tokens in the MathML namespace, so
they typeset. React-style JS does the same swap from a hidden div.
Expected: DPU, JS replacement, and the static result all typeset italic variables and stacked exponents.
<?start name="math-whole">
Loading…
<?end>
<template for="math-whole">
<math display="block">
<msup><mi>a</mi><mn>2</mn></msup>
<mo>+</mo>
<msup><mi>b</mi><mn>2</mn></msup>
<mo>=</mo>
<msup><mi>c</mi><mn>2</mn></msup>
</math>
</template>
<div id="B">Loading…</div>
<div hidden id="S">
<math display="block">
<msup><mi>a</mi><mn>2</mn></msup>
<mo>+</mo>
<msup><mi>b</mi><mn>2</mn></msup>
<mo>=</mo>
<msup><mi>c</mi><mn>2</mn></msup>
</math>
</div>
<script>
B.replaceWith(...S.childNodes);
S.remove();
</script>