You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@annotator.apache.org by ge...@apache.org on 2020/10/13 20:59:36 UTC

[incubator-annotator] 01/05: Move dom-seek dependency into this repo

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

gerben pushed a commit to branch import-dom-seek
in repository https://gitbox.apache.org/repos/asf/incubator-annotator.git

commit d604bf6ea38a8a164e5332de7d0b6f3a1c516549
Author: Gerben <ge...@treora.com>
AuthorDate: Fri Oct 9 14:28:19 2020 +0200

    Move dom-seek dependency into this repo
    
    Plain copy-paste; the only modification is adding its TypeScript signature.
---
 packages/dom/package.json               |  3 +-
 packages/dom/src/seek.ts                | 89 +++++++++++++++++++++++++++++++++
 packages/dom/src/text-position/match.ts |  2 +-
 packages/dom/src/text-quote/describe.ts |  2 +-
 packages/dom/src/text-quote/match.ts    |  2 +-
 packages/dom/src/types/dom-seek.d.ts    | 26 ----------
 6 files changed, 93 insertions(+), 31 deletions(-)

diff --git a/packages/dom/package.json b/packages/dom/package.json
index b623c60..5f4add9 100644
--- a/packages/dom/package.json
+++ b/packages/dom/package.json
@@ -18,8 +18,7 @@
   "module": "./lib/index.mjs",
   "types": "./lib/index.d.ts",
   "dependencies": {
-    "@babel/runtime-corejs3": "^7.8.7",
-    "dom-seek": "^5.1.0"
+    "@babel/runtime-corejs3": "^7.8.7"
   },
   "devDependencies": {
     "@annotator/selector": "^0.1.0"
diff --git a/packages/dom/src/seek.ts b/packages/dom/src/seek.ts
new file mode 100644
index 0000000..dc547da
--- /dev/null
+++ b/packages/dom/src/seek.ts
@@ -0,0 +1,89 @@
+const E_END = 'Iterator exhausted before seek ended.'
+const E_SHOW = 'Argument 1 of seek must use filter NodeFilter.SHOW_TEXT.'
+const E_WHERE = 'Argument 2 of seek must be an integer or a Text Node.'
+
+const DOCUMENT_POSITION_PRECEDING = 2
+const SHOW_TEXT = 4
+const TEXT_NODE = 3
+
+
+export default function seek(iter: NodeIterator, where: number | Text): number {
+  if (iter.whatToShow !== SHOW_TEXT) {
+    let error
+
+    // istanbul ignore next
+    try {
+      error = new DOMException(E_SHOW, 'InvalidStateError')
+    } catch {
+      error = new Error(E_SHOW);
+      error.code = 11
+      error.name = 'InvalidStateError'
+      error.toString = () => `InvalidStateError: ${E_SHOW}`
+    }
+
+    throw error
+  }
+
+  let count = 0
+  let node = iter.referenceNode
+  let predicates = null
+
+  if (isInteger(where)) {
+    predicates = {
+      forward: () => count < where,
+      backward: () => count > where || !iter.pointerBeforeReferenceNode,
+    }
+  } else if (isText(where)) {
+    let forward = before(node, where) ? () => false : () => node !== where
+    let backward = () => node !== where || !iter.pointerBeforeReferenceNode
+    predicates = {forward, backward}
+  } else {
+    throw new TypeError(E_WHERE)
+  }
+
+  while (predicates.forward()) {
+    node = iter.nextNode()
+
+    if (node === null) {
+      throw new RangeError(E_END)
+    }
+
+    count += node.nodeValue.length
+  }
+
+  if (iter.nextNode()) {
+    node = iter.previousNode()
+  }
+
+  while (predicates.backward()) {
+    node = iter.previousNode()
+
+    if (node === null) {
+      throw new RangeError(E_END)
+    }
+
+    count -= node.nodeValue.length
+  }
+
+  if (!isText(iter.referenceNode)) {
+    throw new RangeError(E_END);
+  }
+
+  return count
+}
+
+
+function isInteger(n) {
+  if (typeof n !== 'number') return false;
+  return isFinite(n) && Math.floor(n) === n;
+}
+
+
+function isText(node) {
+  return node.nodeType === TEXT_NODE
+}
+
+
+function before(ref, node) {
+  return ref.compareDocumentPosition(node) & DOCUMENT_POSITION_PRECEDING
+}
diff --git a/packages/dom/src/text-position/match.ts b/packages/dom/src/text-position/match.ts
index a579e94..00acd4c 100644
--- a/packages/dom/src/text-position/match.ts
+++ b/packages/dom/src/text-position/match.ts
@@ -18,9 +18,9 @@
  * under the License.
  */
 
-import seek from 'dom-seek';
 import type { Matcher, TextPositionSelector } from '@annotator/selector';
 import { ownerDocument } from '../owner-document';
+import seek from '../seek';
 
 export function createTextPositionSelectorMatcher(
   selector: TextPositionSelector,
diff --git a/packages/dom/src/text-quote/describe.ts b/packages/dom/src/text-quote/describe.ts
index 4e0e976..514208b 100644
--- a/packages/dom/src/text-quote/describe.ts
+++ b/packages/dom/src/text-quote/describe.ts
@@ -18,9 +18,9 @@
  * under the License.
  */
 
-import seek from 'dom-seek';
 import type { TextQuoteSelector } from '@annotator/selector';
 import { ownerDocument } from '../owner-document';
+import seek from '../seek';
 
 export async function describeTextQuote(
   range: Range,
diff --git a/packages/dom/src/text-quote/match.ts b/packages/dom/src/text-quote/match.ts
index d076f76..c6b769b 100644
--- a/packages/dom/src/text-quote/match.ts
+++ b/packages/dom/src/text-quote/match.ts
@@ -18,9 +18,9 @@
  * under the License.
  */
 
-import seek from 'dom-seek';
 import type { Matcher, TextQuoteSelector } from '@annotator/selector';
 import { ownerDocument } from '../owner-document';
+import seek from '../seek';
 
 export function createTextQuoteSelectorMatcher(
   selector: TextQuoteSelector,
diff --git a/packages/dom/src/types/dom-seek.d.ts b/packages/dom/src/types/dom-seek.d.ts
deleted file mode 100644
index bb379b3..0000000
--- a/packages/dom/src/types/dom-seek.d.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-/**
- * @license
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-declare module 'dom-seek' {
-  export default function seek(
-    iter: NodeIterator,
-    where: number | Text,
-  ): number;
-}