demo · v137

Composed Ranges

Select text below — including across the shadow-DOM boundary — then click read selection. The old getRangeAt(0) stops at the shadow boundary; getComposedRanges() crosses it and selection.direction tells you which end is the anchor.

probing…

Light DOM paragraph. Try selecting from here…

…through to here to span the shadow root.

no selection yet

the code

const sel = getSelection();
const composed = sel.getComposedRanges?.({ shadowRoots: [...] }) || [];
console.log("direction:", sel.direction);          // "forward" | "backward" | "none"
console.log("legacy range:", sel.getRangeAt(0).toString());
console.log("composed:", composed.map((r) => r.startContainer));

see also