Boundary

Encodes a node boundary. Every node has an opening and closing boundary; for HTML, this corresponds to the opening/closing tag. There is also an inner and outer half to each boundary, denoting the bounds for a node's children and siblings respectively. For example:

A<span>B C</span>D

Each of the letters illustrates a different boundary in reference to the <span> node. When defining a Boundary, you specify a reference node, and one of four sides:

These are bit flags, so can use bitmasks for filtering. The flags are ordered numerically by their DOM position, so you can do comparisons, e.g. BEFORE_OPEN < AFTER_OPEN.

Constructor

new Boundary(…args)

Create a new boundary; takes up to three arguments:

Parameters:
NameTypeAttributesDescription
args<repeatable>

One of three formats:

  1. Pass a Boundary to copy
  2. Pass a Node and one of BEFORE_OPEN, AFTER_OPEN, BEFORE_CLOSE, or AFTER_CLOSE flag
  3. In the manner of the builtin Range interface, pass an anchor Node, an offset into that anchor, and one of POSITION_BEFORE or POSITION_AFTER flag, indicating which side of the anchor you wish to get the boundary for. Since the Range interface uses text offsets for CharacterData nodes, if the first arg is CharacterData the offset will be ignored, instead setting the boundary to be outside. If you want to place the boundary inside a CharacterData node, set so directly using syntax #2.

Members

node :Node

node whose boundary we reference

Type:
  • Node

side :Number

bit flag giving which side of the node our boundary is for; this is one of BoundaryFlags

Type:
  • Number

Methods

clone() → {Boundary}

Copy this Boundary object

Returns:

cloned boundary

Type: 
Boundary

compare(other) → (nullable) {number}

Compare relative position of two boundaries

Parameters:
NameTypeDescription
otherBoundary

boundary to compare with

Returns:

One of the following:

  • null if the boundaries are from different DOM trees or the relative position can't be determined
  • 0 if they are equal (see also isEqual for a faster equality check)
  • 1 if this boundary is after other
  • -1 if this boundary is before other

Note, two boundaries that are adjacent, but have differing nodes/boundaries are not considered "equal". They have an implicit side to them. Use isAdjacent to check for this case instead.

Type: 
number

compareNode(node) → (nullable) {number}

See where the boundary sits relative to a Node. This just tells if the boundary is inside, before, or after the node. For more detailed comparisons, create a Boundary for node to compare with instead (see compare).

Parameters:
NameTypeDescription
nodeNode

node to compare with

Returns:

One of the following:

  • null if the boundary is null, in a different DOM tree than node, or the relative postiion can't be determined
  • POSITION_BEFORE if the boundary comes before node in DOM order
  • POSITION_INSIDE if the boundary is inside node
  • POSITION_AFTER if the boundary comes after node in DOM order
Type: 
number

insert(…nodes)

Insert nodes into the DOM at this boundary position

Parameters:
NameTypeAttributesDescription
nodesNode<repeatable>

the nodes to insert

inside() → {Boundary}

Traverses to the nearest boundary point inside the node. For example:

A<span>B C</span>D

A would become B and D would become C.

Returns:

modified this

Type: 
Boundary

isAdjacent(other) → {boolean}

Check if this boundary directly precedes another, and is the same DOM insertion point. For example, given the following DOM with letters representing boundaries:

<main>A B<article>C D<span>E F</span>G H</article>I J</main>

The pairs (A,B), (C,D), (E,F), (G,H), and (I,J) are considered "adjacent". While they represent the same DOM position, they differ in whether they are in reference to the preceding or following node. The preceding boundary will always have an "AFTER" side, with the adjacent following boundary having a "BEFORE" side (see BoundaryFlags).

Parameters:
NameTypeDescription
otherBoundary

boundary to compare with

Returns:

true if other is adjacent and following this

Type: 
boolean

isEqual(other) → {boolean}

Check if boundary equals another

Parameters:
NameTypeDescription
otherBoundary

boundary to compare with

Returns:

true if the boundaries are identical

Type: 
boolean

isNull() → {boolean}

Check if the boundary node is not set (e.g. null). A null reference node is allowed, and can be used to signal the end of DOM traversal or an unset Boundary.

Returns:

true if boundary is not set

Type: 
boolean

next() → {Boundary}

Traverses to the next boundary point in the DOM tree. For example:

A<span>B C</span>D

Given a boundary starting at A, traversal would proceed to B, C, D, and finally null to signal an end to traversal.

Returns:

modified this

Type: 
Boundary

(generator) nextNodes(include_startopt)

Generator that yields a Boundary for each unique node when traversing in the "next" direction. Unlike next this method tracks which nodes have been visited, and only emits their first boundary encountered. This method is meant to mimic the single node traversal of TreeWalker, but it yields a node when any of its boundaries is crossed. (Essentially doing a preorder traversal regardless of direction, except when traversing an unseen parentNode, which will be postorder). For example:

A <main>B C<article>D E</article>F G</main>H

Given a boundary starting with...

  • C: yield C, G, null
  • D: yield E, G, null

Note that the yielded side will always be BEFORE_OPEN or BEFORE_CLOSE. If the current Boundary is one of these types, it will be yielded first by default.

Parameters:
NameTypeAttributesDefaultDescription
include_startboolean<optional>
true

whether to yield the starting Boundary if it is of type "BEFORE"

Yields:
Modified `this`; traversal continues until there is neither sibling or parent node. If you need a copy for each iteration, clone the emitted Boundary.
Type: 
Boundary

outside() → {Boundary}

Traverses to the nearest boundary point outside the node. Performs the inverse of inside

See
Returns:

modified this

Type: 
Boundary

previous() → {Boundary}

Traverses to the previous boundary point. Performs the inverse of next

See
  • next for additional details
Returns:

modified this

Type: 
Boundary

(generator) previousNodes(include_startopt)

Performs the inverse of nextNodes. Note that when traversing in the previous direction, the side will always be one of AFTER_OPEN or AFTER_CLOSE

Parameters:
NameTypeAttributesDefaultDescription
include_startboolean<optional>
true

whether to yield the starting Boundary if it is of type "AFTER"

See
Yields:
modified `this`
Type: 
Boundary

set()

Update boundary values. Same arguments as the constructor

toAnchor(textopt) → {Object}

Convert to an anchor, in the manner of the builtin Range/StaticRange interface.

const {node, offset} = boundary.toAnchor();
const range = new Range();
range.setStart(node, offset);
Parameters:
NameTypeAttributesDefaultDescription
textboolean<optional>
true

The Range interface switches to encoding text offsets for CharacterData nodes, instead of encoding a child offset like other node types. We allow a boundary inside a CharacterData node though, so these boundaries can't be represented with Range.

Set this parameter to true to use nearest outside boundary for CharacterData nodes, which is what makes more sense for use with Range. Set this to false to do no conversion, which can be useful if you are not using the anchor with Range.

Returns:

An object with the following members:

  • node (Node): a reference parent node
  • offset (number): offset inside the node's childNodes list
Type: 
Object