dom-seek
v5.1.1
Published
Text traversal for HTML documents.
Downloads
9,479
Readme
DOM Seek
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);
}