BoundaryRange

Similar to builtin Range or StaticRange interfaces, but encodes the start/end of the range using Boundary. The anchors are not specified as an offset into a parent's children, so the range is robust to modifications of the DOM. In particular, you can use this to encode bounds for mutations, as DOM changes within the range will not corrupt the range. Conveniently, many comparisons and range operations can be performed on the individual start/end anchors via the Boundary class.

Constructor

new BoundaryRange(…args)

Create a new range; takes up to two arguments:

Parameters:
NameTypeAttributesDescription
argsRange | StaticRange | BoundaryRange | Array.<Boundary><repeatable>

One of these formats:

  • empty: uninitialized range; you should set start/end manually before using the range
  • Range or StaticRange: converts from a Range, defaulting to an "exclusive" range, see normalize
  • BoundaryRange: equivalent to cloneRange
  • [Boundary, Boundary]: set the start/end anchors to be a copy of these boundaries

For more control over initialization, leave args empty and use setStart and setEnd instead. You may also directly manipulate or assign start or end if desired.

Members

collapsed :boolean

Check if the range is collapsed in the current DOM. The start/end boundaries must be equal, or start/end must be adjacent to eachother (see Boundary#isEqual and Boundary#isAdjacent). If the start/end anchors are disconnected or out-of-order, it returns false.

Type:
  • boolean

end :Boundary

Ending anchor of the range. You can access or assign this directly as needed

start :Boundary

Starting anchor of the range. You can access or assign this directly as needed

Methods

cloneRange() → {BoundaryRange}

Make a copy of this range object

Returns:

cloned range

Type: 
BoundaryRange

collapse(toStartopt) → {BoundaryRange}

Collapse the range to one of the boundary points. After calling this method, the start anchor will equal the end: this.start.isEqual(this.end) (see Boundary#isEqual). If you would like to instead collapse with the start/end anchors adjacent (see Boundary#isAdjacent), then follow with a call to normalize.

Parameters:
NameTypeAttributesDefaultDescription
toStartboolean<optional>
false

If true, collapses to the start; otherwise collapses to end

Returns:

modified this

Type: 
BoundaryRange

contains(other, inclusiveopt) → {boolean}

Check if this range fully contains other

Parameters:
NameTypeAttributesDefaultDescription
otherBoundaryRange

the range to compare with

inclusiveboolean<optional>
true

whether to consider the range fully contained if one of its start/end anchors equals that of this

Returns:

true if other is contained

Type: 
boolean

extend(other) → {BoundaryRange}

Extend this range to include the bounds of another BoundaryRange. If the start/end has not been set yet, it will simply copy from other. Example:

<div id='a'></div> <div id='b'></div>
const ra = (new BoundaryRange()).selectNode(a);
const rb = (new BoundaryRange()).selectNodeContents(b)
ra.extend(rb);
// ra.start == (a, BEFORE_OPEN)
// ra.end == (b, BEFORE_CLOSE)
Parameters:
NameTypeDescription
otherBoundaryRange

extend bounds to enclose this range

Returns:

modified this

Type: 
BoundaryRange

intersects(other, inclusiveopt) → {boolean}

Check if this range intersects with another

Parameters:
NameTypeAttributesDefaultDescription
otherBoundaryRange

the range to compare with

inclusiveboolean<optional>
false

whether to consider the ranges intersecting if just one of their start/end anchors are equal

Returns:

true if the ranges intersect

Type: 
boolean

isEqual(other)

Check if range exactly matches another

Parameters:
NameTypeDescription
otherBoundaryRange

range to compare with

isNull() → {boolean}

Check if the range has been fully set, e.g. neither boundary is null

Returns:

true if range is not set, or is only partially set

Type: 
boolean

normalize(exclusiveopt) → {BoundaryRange}

Every boundary has one adjacent boundary at the same position. On one side you have the AFTER_OPEN/AFTER_CLOSE bounds, and following it will be a BEFORE_OPEN/BEFORE_CLOSE bounds. See Boundary#isAdjacent. The start/end anchors can use either boundary and the range positions will be equivalent; the main difference is the behavior when the DOM is mutated, as the reference nodes will be different. There are two normalization modes:

  1. exclusive: start/end anchor boundaries are outside the range; e.g. start boundary is AFTER and end boundary is BEFORE type
  2. inclusive: start/end anchor boundaries are inside the range; e.g. start boundary is BEFORE and end boundary is AFTER type

For example, if you are encoding a range of mutations, you might want to normalize the range to be exclusive; that way, the mutated nodes inside the range will not affect the boundaries.

Parameters:
NameTypeAttributesDefaultDescription
exclusiveboolean<optional>
true

true for exclusive bounds, or false for inclusive

Returns:

modified this

Type: 
BoundaryRange

selectNode(node, exclusiveopt) → {BoundaryRange}

Set range to surround a single node

Parameters:
NameTypeAttributesDefaultDescription
nodeNode

the node to surround

exclusiveboolean<optional>
true

see normalize

Returns:

modified this

Type: 
BoundaryRange

selectNodeContents(node, exclusiveopt) → {BoundaryRange}

Set range to surround the contents of a node. Warning, for CharacterData nodes, you probably want to use selectNode instead, since these nodes cannot have children

Parameters:
NameTypeAttributesDefaultDescription
nodeNode

node whose contents to enclose

exclusiveboolean<optional>
true

see normalize

Returns:

modified this

Type: 
BoundaryRange

setEnd(…args) → {BoundaryRange}

Update end anchor; equivalent to this.end.set()

Parameters:
NameTypeAttributesDescription
args<repeatable>

forwarded to Boundary#set

See
Returns:

modified this

Type: 
BoundaryRange

setStart(…args) → {BoundaryRange}

Update start anchor; equivalent to this.start.set()

Parameters:
NameTypeAttributesDescription
args<repeatable>

forwarded to Boundary#set

See
Returns:

modified this

Type: 
BoundaryRange

toRange() → {Range}

Convert to Range interface. Range's end is set last, so if the resulting range's anchors would be out of order, it would get collapsed to the end anchor. Boundaries inside a CharacterData node are treated as outside for conversion purposes. If the current BoundaryRange isNull, an uninitialized Range will be returned.

Returns:
Type: 
Range

toStaticRange() → {StaticRange}

Convert to StaticRange interface. Boundaries inside a CharacterData node are treated as outside for conversion purposes. If the current BoundaryRange isNull, an error will be thrown since a StaticRange cannot be created uninitialized.

Returns:
Type: 
StaticRange