demo · v148
Range Marker Highlighter
Wrap text in <?start name="X">...<?end> processing-instruction markers. The page detects each matching pair after parsing and highlights the enclosed range in real time. Same pattern Declarative Partial Updates uses to denote streaming holes.
About this demo: The HTML on the left is parsed with
DOMParser. We walk the result, find each ProcessingInstruction whose target is start or end, pair them up, and wrap the nodes between each pair with a <span data-range-name="...">. The CSS rules for those spans (blue, rose, emerald, amber) make each named range visible without ever rendering the PIs themselves.
preset documents
input
bio
ad
status
note
rendered
Ranges detected: 0
what's happening
After parsing, we collect every ProcessingInstruction node whose target is start or end. start PIs carry a name="X" attribute; the next end closes the most recent open named range. We then traverse the DOM and wrap everything between each matched pair in a span tagged with the range name, which CSS uses to apply a coloured highlight.
const doc = new DOMParser().parseFromString(input, "text/html");
const stack = [];
const ranges = [];
const walker = doc.createTreeWalker(doc.body, NodeFilter.SHOW_ALL);
let node;
while ((node = walker.nextNode())) {
if (node.nodeType !== Node.PROCESSING_INSTRUCTION_NODE) continue;
if (node.target === "start") {
const m = node.data.match(/name="([^"]+)"/);
stack.push({ name: m?.[1] ?? "range", start: node });
} else if (node.target === "end" && stack.length) {
const open = stack.pop();
ranges.push({ name: open.name, start: open.start, end: node });
}
}
// Wrap each pair in a span — see the live demo for the exact walk.
see also
- Parse processing instructions in HTML — feature index
- PI Tree Inspector — sibling demo
- Out-of-order streaming demos — the streaming feature that uses this primitive
- WHATWG HTML PR #12118
implementation reference
Need the exact API surface, compatibility boundaries, errors, lifecycle, and source links? Read the matching gendn reference ↗