const E_SHOW = 'Argument 1 of seek must use filter NodeFilter.SHOW_TEXT.';
const E_SEEK = 'Argument 2 of seek is neither a number nor Text Node.';


export default function seek(iter, where) {

  if (iter.whatToShow !== NodeFilter.SHOW_TEXT) {
    throw new Error(E_SHOW);
  }

  let count = 0;
  let node = null;
  let predicates = null;

  if (isNumber(where)) {
    predicates = {
      forward: () => count <= where,
      backward: () => count > where
    };
  } else if (isText(where)) {
    predicates = {
      forward: () => node === where || before(node, where),
      backward: () => after(node, where)
    };
  } else {
    throw new Error(E_SEEK);
  }

  if (iter.pointerBeforeReferenceNode) {
    node = iter.referenceNode;
  } else {
    node = iter.previousNode();
  }

  do {
    node = iter.nextNode();
    if (node === null) break;
    count += node.textContent.length;
  } while(predicates.forward());

  do {
    node = iter.previousNode();
    if (node === null) break;
    count -= node.textContent.length;
  } while(predicates.backward());

  return count;
}


function isNumber(n) {
  return !isNaN(parseInt(n)) && isFinite(n);
}


function isText(node) {
  return node.nodeType === Node.TEXT_NODE;
}


function before(referenceNode, node) {
  return referenceNode.compareDocumentPosition(node) &
    (Node.DOCUMENT_POSITION_FOLLOWING | Node.DOCUMENT_CONTAINED_BY);
}


function after(referenceNode, node) {
  return referenceNode.compareDocumentPosition(node) &
    (Node.DOCUMENT_POSITION_PRECEDING | Node.DOCUMENT_CONTAINS);
}

@@ -1,16 +1,77 @@
+const E_ITER = 'Argument 1 of seek must be a NodeIterator.';%0A
 const E_SHOW = '
@@ -137,20 +137,21 @@
 const E_
-SEEK
+WHERE
  = 'Argu
@@ -169,18 +169,15 @@
 eek 
-is neither
+must be
  a n
@@ -186,12 +186,13 @@
 ber 
-n
 or 
+a 
 Text
@@ -245,16 +245,90 @@
 where) %7B
+%0A  if (!(iter instanceof NodeIterator)) %7B%0A    throw new Error(E_ITER);%0A  %7D
 %0A%0A  if (
@@ -785,12 +785,13 @@
 r(E_
-SEEK
+WHERE
 );%0A 

Tweak some error constants