ShadowSelection
A Selection view over the composed ranges of a set of shadow roots. Read accessors are resolved live from the composed ranges on each access, so the view stays in sync with the underlying document selection; selection mutations are delegated to it. Only the subset of the Selection interface consumed by the editor is implemented, so getSelection() returns it alongside the native Selection.
Properties
anchorNode: Node | nullreadonlymodule:utils/dom/getselection~ShadowSelection#anchorNodeanchorOffset: numberreadonlymodule:utils/dom/getselection~ShadowSelection#anchorOffsetdirection: 'none' | 'forward' | 'backward'readonlymodule:utils/dom/getselection~ShadowSelection#directionThe direction of the selection, resolved against the tree the first composed range lives in. It is already computed to orient the anchor and focus endpoints, so exposing it lets consumers read the orientation directly instead of re-deriving it from the endpoints.
focusNode: Node | nullreadonlymodule:utils/dom/getselection~ShadowSelection#focusNodefocusOffset: numberreadonlymodule:utils/dom/getselection~ShadowSelection#focusOffsetisCollapsed: booleanreadonlymodule:utils/dom/getselection~ShadowSelection#isCollapsedrangeCount: numberreadonlymodule:utils/dom/getselection~ShadowSelection#rangeCount_domSelection: ComposedSelectionprivatereadonlymodule:utils/dom/getselection~ShadowSelection#_domSelectionThe underlying document-level selection that mutations are delegated to and composed ranges read from.
_shadowRoots: Array<ShadowRoot>privatereadonlymodule:utils/dom/getselection~ShadowSelection#_shadowRootsThe shadow roots the composed ranges are resolved against.
Static properties
_useLegacyComposedRanges: booleanprivatestaticmodule:utils/dom/getselection~ShadowSelection._useLegacyComposedRangesWhether the engine only accepts the legacy rest-parameter form of
getComposedRanges(). This is a fixed property of the engine, so it is detected once (the first call throws on the dictionary form) and cached for all instances, keeping the exception off the selection-read hot path.
Methods
constructor( domSelection, shadowRoots )internalmodule:utils/dom/getselection~ShadowSelection#constructoraddRange( range ) → voidmodule:utils/dom/getselection~ShadowSelection#addRangecollapse( node, offset? ) → voidmodule:utils/dom/getselection~ShadowSelection#collapseextend( node, offset? ) → voidmodule:utils/dom/getselection~ShadowSelection#extendgetRangeAt( index ) → Rangemodule:utils/dom/getselection~ShadowSelection#getRangeAtremoveAllRanges() → voidmodule:utils/dom/getselection~ShadowSelection#removeAllRangessetBaseAndExtent( anchorNode, anchorOffset, focusNode, focusOffset ) → voidmodule:utils/dom/getselection~ShadowSelection#setBaseAndExtentParameters
anchorNode: NodeanchorOffset: numberfocusNode: NodefocusOffset: number
Returns
void
_getComposedRanges() → Array<StaticRange>privatemodule:utils/dom/getselection~ShadowSelection#_getComposedRangesThe raw composed ranges reported for the shadow roots by the underlying selection.
Returns
Array<StaticRange>
_getDirection( rootNode ) → stringprivatemodule:utils/dom/getselection~ShadowSelection#_getDirectionThe direction of the underlying selection, preferring the one reported by Blink's shadow-scoped selection, which stays meaningful for a mouse selection made inside a shadow root.
Parameters
rootNode: Node
Returns
string
_getEndpoint( endpoint ) → objectprivatemodule:utils/dom/getselection~ShadowSelection#_getEndpointThe anchor or focus endpoint of the first composed range.
getComposedRanges()returns ranges in document order (start before end); the anchor/focus orientation therefore has to come fromSelection#direction. Known limitation: WebKit and Blink reportdirectionas'none'for a selection made with the mouse inside a shadow root (a keyboard selection reports it correctly). Blink's shadow-scoped selection still knows the direction in that case, so it is consulted first; it is of no use for the ranges themselves, as it covers a single tree only. Safari has no such API, so its mouse selections fall back to forward.Parameters
endpoint: 'anchor' | 'focus'
Returns
object
_getRanges() → Array<StaticRange>privatemodule:utils/dom/getselection~ShadowSelection#_getRangesThe composed ranges fully contained in one of the trees on the path from the given nodes to the document, in document order (start before end).
Only ranges whose both endpoints resolve into the same tree can be represented as a live, single-tree
Range. A range crossing a shadow boundary is therefore dropped, and so is one resolving into an unrelated tree, rather than surfacing foreign nodes. The document itself is one of those trees: it is where every node ends up when walking out of its shadow roots, and it is where a selection made in a sibling light-DOM editable lives, so such a selection is kept rather than dropped.A range with an endpoint outside its container is dropped as well, see
isOffsetInNode()below.Returns
Array<StaticRange>