Text traversal for HTML documents.


Keywords
dom, text, seek
License
MIT
Install
npm install dom-seek@5.1.1

Documentation

DOM Seek

License NPM Package Build Status Coverage Status

POSIX has lseek(2). Now the browser has dom-seek.

This library can answer two questions:

  • What is the offset of a given TextNode within a text?

  • Which TextNode within a text contains the given offset?

Installation

Using npm:

npm install dom-seek

Usage

seek(iter, where)

Adjust the position of a NodeIterator by an offset measured in text code units or to the position immediately before a target node.

If the whatToShow attribute of iter is any value other than NodeFilter.SHOW_TEXT, throw an InvalidStateError DOMException.

If where is a positive integer, seek the iterator forward until the sum of the text code unit lengths of all nodes that the iterator traverses is as close as possible to where without exceeding it.

If where is a negative integer, seek the iterator backward until the sum of the text code unit lengths of all nodes that the iterator traverses is as close as possible to the positive value of where without exceeding it.

If where is a node, seek the iterator forward or backward until its pointer is positioned immediately before the target node.

If where is any other value, throw a TypeError exception.

Return the number of text code units between the initial and final iterator positions. This number will be negative when the traversal causes the iterator to traverse backward in document order.

If the where argument specifies a target beyond the bounds of the root attribute of the iterator, throw a RangError exception.

After this function returns, the pointerBeforeReferencNode property of the iterator should be true. The function may return a value less than where if returning where exactly would result in the iterator pointing after the last text node that its root node contains.

Browser Support

Use the dom-node-iterator module for a portable NodeIterator polyfill if targeting browsers that lack a full implementation that includes the referenceNode and pointerBeforeReferenceNode properties.

Example

Often, when searching for text strings in HTML documents, authors will traverse a document and look at the text of the leaf Elements. However, when the search pattern is split across element boundaries, the problem is harder.

Below is an example of using seek to highlight a string in a document, even if that string is split across element boundaries.

var text = 'ipsum';

// Find the text.
var offset = document.body.textContent.indexOf(text);
var length = text.length;

// Create a NodeIterator.
var iter = document.createNodeIterator(document.body, NodeFilter.SHOW_TEXT);

// Seek the iterator forward by some amount, splitting the text node that
// contains the destination if it does not fall exactly at a text node boundary.
function split(where) {
  var count = seek(iter, where);
  var remainder = where - count;

  if (remainder) {
    // Split the text at the offset
    iter.referenceNode.splitText(remainder);

    // Seek to the exact offset
    seek(iter, remainder);
  }

  return iter.referenceNode;
}

// Find split points
var start = split(offset);
var end = split(length);

// Walk backwards, collecting all the nodes
var nodes = [end];
while (iter.referenceNode !== start) {
  nodes.unshift(iter.previousNode());
}

// Highlight all the nodes.
for (var i = 0 ; i < nodes.length ; i++) {
  var node = nodes[i];

  // Create a highlight
  var highlight = document.createElement('mark');

  // Wrap it around the text node
  node.parentNode.replaceChild(highlight, node);
  highlight.appendChild(node);
}