dom-seek v5.1.1
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
TextNodewithin a text?Which
TextNodewithin a text contains the given offset?
Installation
Using npm:
npm install dom-seekUsage
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);
}