You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@annotator.apache.org by ra...@apache.org on 2019/06/22 23:27:36 UTC

[incubator-annotator] 05/06: Support crossing node boundaries in demo search

This is an automated email from the ASF dual-hosted git repository.

randall pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-annotator.git

commit 9b1e5f3e68261c51a1f120f51d0ebe89736fb57c
Author: Randall Leeds <ra...@apache.org>
AuthorDate: Sat Jun 22 16:18:48 2019 -0700

    Support crossing node boundaries in demo search
---
 demo/search.js | 40 +++++++++++++++++++---------------------
 package.json   |  2 ++
 yarn.lock      |  5 +++++
 3 files changed, 26 insertions(+), 21 deletions(-)

diff --git a/demo/search.js b/demo/search.js
index 1415af1..f66fb25 100644
--- a/demo/search.js
+++ b/demo/search.js
@@ -16,6 +16,8 @@
 import { makeRefinable } from '@annotator/selector';
 import { createRangeSelectorCreator } from '@annotator/range';
 import { createTextQuoteSelector } from '@annotator/dom';
+import createNodeIterator from 'dom-node-iterator';
+import seek from 'dom-seek';
 
 const createSelector = makeRefinable(selector => {
   const selectorCreator = {
@@ -37,30 +39,26 @@ const createSelector = makeRefinable(selector => {
  * @return {Range}
  */
 export async function* search(root, selector) {
-  for (const node of nodeIterator(root)) {
-    if (!node.nodeValue) continue;
+  const matches = createSelector(selector)(root);
 
-    const matches = createSelector(selector)(node.nodeValue);
+  for await (let match of matches) {
+    const matchIndex = match.index;
+    const matchLength = match[0].length;
 
-    for await (let match of matches) {
-      const startIndex = match.index;
-      const endIndex = startIndex + match[0].length;
-      const range = document.createRange();
-      range.setStart(node, startIndex);
-      range.setEnd(node, endIndex);
-      yield range;
-    }
-  }
-}
+    const iter = createNodeIterator(root, NodeFilter.SHOW_TEXT);
 
-/**
- * Iterate over the nodes of a sub-tree of the document.
- * @param {Node} node
- */
-function* nodeIterator(node) {
-  yield node;
+    const startIndex = seek(iter, matchIndex);
+    const startContainer = iter.referenceNode;
+    const startOffset = match.index - startIndex;
+
+    const endIndex = startIndex + seek(iter, startOffset + matchLength);
+    const endContainer = iter.referenceNode;
+    const endOffset = matchIndex + matchLength - endIndex;
+
+    const range = document.createRange();
+    range.setStart(startContainer, startOffset);
+    range.setEnd(endContainer, endOffset);
 
-  for (const child of node.childNodes) {
-    yield* nodeIterator(child);
+    yield range;
   }
 }
diff --git a/package.json b/package.json
index 514191f..c52bf48 100644
--- a/package.json
+++ b/package.json
@@ -49,6 +49,8 @@
     "core-js": "3",
     "cross-env": "^5.2.0",
     "dom-highlight-range": "^1.0.1",
+    "dom-node-iterator": "^3.5.3",
+    "dom-seek": "^4.0.3",
     "eslint": "^5.16.0",
     "eslint-config-prettier": "^4.1.0",
     "eslint-import-resolver-babel-module": "^5.0.1",
diff --git a/yarn.lock b/yarn.lock
index 28b30d3..f7f81c5 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4770,6 +4770,11 @@ index-of@^0.2.0:
   resolved "https://registry.yarnpkg.com/index-of/-/index-of-0.2.0.tgz#38c1e2367ea55dffad3b6eb592ec1cc3090d7d65"
   integrity sha1-OMHiNn6lXf+tO261kuwcwwkNfWU=
 
+index-of@^0.2.0:
+  version "0.2.0"
+  resolved "https://registry.yarnpkg.com/index-of/-/index-of-0.2.0.tgz#38c1e2367ea55dffad3b6eb592ec1cc3090d7d65"
+  integrity sha1-OMHiNn6lXf+tO261kuwcwwkNfWU=
+
 indexes-of@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607"