Fix table headers rendering at bottom (foster-parenting)#5
Fix table headers rendering at bottom (foster-parenting)#5melvincarvalho wants to merge 1 commit into
Conversation
Replace zero-width text markers with HTML comment markers. The browser's HTML parser foster-parents text nodes out of <table>, but comments survive — fixing header ordering for all tables. Fixes linkedobjects#4
There was a problem hiding this comment.
Pull request overview
This PR updates LOSOS’s html tagged-template rendering to avoid the browser’s HTML parser “foster-parenting” placeholder markers out of <table>, which caused dynamic insertions to shift and table headers to appear at the bottom.
Changes:
- Replace the zero-width text HOLE marker with an HTML comment marker (
<!--losos-->) to keep placeholders stable inside tables. - Update
findPartsto detect HOLE markers via comment nodes (nodeType === 8) and convert them into text-node insertion anchors.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| function findParts(node, parts) { | ||
| if (node.nodeType === 3) { | ||
| // Text node — split on HOLE markers | ||
| var text = node.textContent | ||
| if (text.indexOf(HOLE) === -1) return | ||
| var pieces = text.split(HOLE) | ||
| if (node.nodeType === 8 && node.textContent === 'losos') { | ||
| // Comment marker — replace with empty text node for content insertion | ||
| var parent = node.parentNode | ||
| for (var i = 0; i < pieces.length; i++) { | ||
| if (pieces[i]) parent.insertBefore(document.createTextNode(pieces[i]), node) | ||
| if (i < pieces.length - 1) { | ||
| var marker = document.createTextNode('') | ||
| parent.insertBefore(marker, node) | ||
| parts.push({ type: 'text', node: marker }) | ||
| } | ||
| } | ||
| var marker = document.createTextNode('') |
There was a problem hiding this comment.
findParts now only recognizes HOLE markers when they parse as comment nodes. In HTML RCDATA/RAWTEXT elements like <textarea> (and also <script>/<style>), the literal string <!--losos--> is parsed as plain text, so no parts are collected and interpolations inside these elements stop rendering (e.g. panes/schema-pane.js uses ${value || ''} inside a <textarea>). Consider keeping the previous text-node split logic as a fallback when a text node contains HOLE, in addition to the new comment-node handling.
Summary
\u200B\u200C\u200B) with HTML comment markers (<!--losos-->) inhtml.jsfindPartsto find comment nodes (nodeType === 8) instead of splitting text nodesWhy
The browser's HTML parser foster-parents text nodes out of
<table>, causing dynamic content markers to be displaced. Comments survive inside tables without being moved.Test plan
<tr><th>headers + dynamic${items.map(...)}rows render headers at topFixes #4