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 15aec219ed6e489a8e6d405dcf1b524ef6cb523f
Author: Gerben <[email protected]>
AuthorDate: Mon Nov 16 23:00:13 2020 +0100

    Make ChunkSeeker interface, drop BoundaryPointer/DomSeeker
---
 packages/dom/src/chunker.ts           |  2 +-
 packages/dom/src/code-point-seeker.ts | 67 +++++++++++++++++++++++++++--------
 packages/dom/src/seek.ts              | 33 +++++------------
 3 files changed, 62 insertions(+), 40 deletions(-)

diff --git a/packages/dom/src/chunker.ts b/packages/dom/src/chunker.ts
index e636509..78b8646 100644
--- a/packages/dom/src/chunker.ts
+++ b/packages/dom/src/chunker.ts
@@ -24,7 +24,7 @@ import { ownerDocument } from "./owner-document";
 // A Chunk represents a fragment (typically a string) of some document.
 // Subclasses can add further attributes to map the chunk to its position in 
the
 // data structure it came from (e.g. a DOM node).
-export interface Chunk<TData extends any> {
+export interface Chunk<TData> {
   readonly data: TData;
   equals?(otherChunk: this): boolean;
 }
diff --git a/packages/dom/src/code-point-seeker.ts 
b/packages/dom/src/code-point-seeker.ts
index 9adc89c..b0a95cd 100644
--- a/packages/dom/src/code-point-seeker.ts
+++ b/packages/dom/src/code-point-seeker.ts
@@ -18,12 +18,13 @@
  * under the License.
  */
 
-import { Seeker, BoundaryPointer } from "./seek";
+import { ChunkSeeker } from "./seek";
+import { Chunk } from "./chunker";
 
-class _CodePointSeeker implements Seeker<string[]> {
+export class CodePointSeeker<TChunk extends Chunk<string>> implements 
ChunkSeeker<TChunk, string[]> {
   position = 0;
 
-  constructor(public readonly raw: Seeker<string>) {}
+  constructor(public readonly raw: ChunkSeeker<TChunk>) {}
 
   seekBy(length: number) {
     this.seekTo(this.position + length);
@@ -41,6 +42,54 @@ class _CodePointSeeker implements Seeker<string[]> {
     return this._readOrSeekTo(true, target, roundUp);
   }
 
+  get currentChunk() {
+    return this.raw.currentChunk;
+  }
+
+  get offsetInChunk() {
+    return this.raw.offsetInChunk;
+  }
+
+  seekToChunk(target: TChunk, offset: number = 0) {
+    this._readOrSeekToChunk(false, target, offset);
+  }
+
+  readToChunk(target: TChunk, offset: number = 0) {
+    return this._readOrSeekToChunk(true, target, offset);
+  }
+
+  private _readOrSeekToChunk(read: true, target: TChunk, offset?: number): 
string[]
+  private _readOrSeekToChunk(read: false, target: TChunk, offset?: number): 
void
+  private _readOrSeekToChunk(read: boolean, target: TChunk, offset: number = 
0) {
+    const oldPosition = this.position;
+    const oldRawPosition = this.raw.position;
+
+    let result = [...this.raw.readToChunk(target, 0)];
+    this.position = this.raw.position >= oldRawPosition
+      ? this.position + result.length
+      : this.position - result.length;
+
+    const targetPosition = this.position + offset;
+    if (!read) {
+      this.seekTo(targetPosition);
+    } else {
+      if (targetPosition >= this.position) {
+        // Read further until the target.
+        result = result.concat(this.readTo(targetPosition));
+      }
+      else if (targetPosition >= oldPosition) {
+        // We passed by our target position: step back.
+        this.seekTo(targetPosition);
+        result = result.slice(0, targetPosition - oldPosition);
+      } else {
+        // The target precedes our starting position: read backwards from 
there.
+        this.seekTo(oldPosition);
+        result = this.readTo(targetPosition);
+      }
+    }
+    return result;
+  }
+
   private _readOrSeekTo(read: true, target: number, roundUp?: boolean): 
string[];
   private _readOrSeekTo(read: false, target: number, roundUp?: boolean): void;
   private _readOrSeekTo(read: boolean, target: number, roundUp: boolean = 
false): string[] | void {
@@ -96,18 +145,6 @@ class _CodePointSeeker implements Seeker<string[]> {
   }
 }
 
-export class CodePointSeeker extends _CodePointSeeker implements 
Seeker<string[]>, BoundaryPointer<string[]> {
-  constructor(public readonly raw: Seeker<string> & BoundaryPointer<Text>) {
-    super(raw);
-  }
-
-  get referenceNode() { return [...this.raw.referenceNode.data] };
-  get offsetInReferenceNode() {
-    const substring = this.raw.referenceNode.data.substring(0, 
this.raw.offsetInReferenceNode);
-    return [...substring].length;
-  };
-}
-
 function endsWithinCharacter(s: string) {
   const codeUnit = s.charCodeAt(s.length - 1);
   return (0xD800 <= codeUnit && codeUnit <= 0xDBFF)
diff --git a/packages/dom/src/seek.ts b/packages/dom/src/seek.ts
index 00feaee..3832b07 100644
--- a/packages/dom/src/seek.ts
+++ b/packages/dom/src/seek.ts
@@ -18,7 +18,7 @@
  * under the License.
  */
 
-import { Chunk, Chunker, TextNodeChunker, PartialTextNode, chunkEquals } from 
"./chunker";
+import { Chunk, Chunker, chunkEquals } from "./chunker";
 
 const E_END = 'Iterator exhausted before seek ended.';
 
@@ -26,11 +26,6 @@ export interface NonEmptyChunker<TChunk extends Chunk<any>> 
extends Chunker<TChu
   readonly currentChunk: TChunk;
 }
 
-export interface BoundaryPointer<T extends any> {
-  readonly referenceNode: T;
-  readonly offsetInReferenceNode: number;
-}
-
 export interface Seeker<T extends Iterable<any> = string> {
   readonly position: number;
   read(length?: number, roundUp?: boolean): T;
@@ -39,7 +34,14 @@ export interface Seeker<T extends Iterable<any> = string> {
   seekTo(target: number): void;
 }
 
-export class TextSeeker<TChunk extends Chunk<string>> implements 
Seeker<string> {
+export interface ChunkSeeker<TChunk extends Chunk<any>, T extends 
Iterable<any> = string> extends Seeker<T> {
+  readonly currentChunk: TChunk;
+  readonly offsetInChunk: number;
+  seekToChunk(chunk: TChunk, offset?: number): void;
+  readToChunk(chunk: TChunk, offset?: number): T;
+}
+
+export class TextSeeker<TChunk extends Chunk<string>> implements 
ChunkSeeker<TChunk> {
   // The chunk containing our current text position.
   get currentChunk() {
     return this.chunker.currentChunk;
@@ -210,20 +212,3 @@ export class TextSeeker<TChunk extends Chunk<string>> 
implements Seeker<string>
     return [data, previousChunk];
   }
 }
-
-export class DomSeeker extends TextSeeker<PartialTextNode> implements 
BoundaryPointer<Text> {
-  constructor(scope: Range) {
-    const chunker = new TextNodeChunker(scope);
-    if (chunker.currentChunk === null)
-      throw new RangeError('Range does not contain any Text nodes.');
-    super(chunker as NonEmptyChunker<PartialTextNode>);
-  }
-
-  get referenceNode() {
-    return this.currentChunk.node;
-  }
-
-  get offsetInReferenceNode() {
-    return this.offsetInChunk + this.currentChunk.startOffset;
-  }
-}

Reply via email to