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 <[email protected]> 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; -}
