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/11/18 18:58:59 UTC
[incubator-annotator] branch import-dom-seek updated (645eb77 ->
2ec7100)
This is an automated email from the ASF dual-hosted git repository.
gerben pushed a change to branch import-dom-seek
in repository https://gitbox.apache.org/repos/asf/incubator-annotator.git.
from 645eb77 Factor out chunkRangeToRange
new 84ae601 Handle half-characters in CodePointSeeker.seekToChunk
new d6a0be0 Make CodePointSeeker.seekToChunk count units, not points
new ec53350 Create basic tests for describe text position
new 2ec7100 Export describeTextPosition & use it in demo
The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
packages/dom/src/code-point-seeker.ts | 38 +++++++---------
packages/dom/src/index.ts | 1 +
packages/dom/test/text-position/describe.test.ts | 55 ++++++++++++++++++++++++
web/demo/index.html | 9 ++++
web/demo/index.js | 14 ++++--
5 files changed, 92 insertions(+), 25 deletions(-)
create mode 100644 packages/dom/test/text-position/describe.test.ts
[incubator-annotator] 02/04: Make CodePointSeeker.seekToChunk count
units, not points
Posted by ge...@apache.org.
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 d6a0be00eee0901b9e423dace49341a94afd7098
Author: Gerben <ge...@treora.com>
AuthorDate: Wed Nov 18 18:57:38 2020 +0100
Make CodePointSeeker.seekToChunk count units, not points
We don’t actually ever want to count chunk offsets as code points. Note
its (unused) offsetInChunk method also returns the number in code units.
Ideally the caller would invoke the TextSeeker’s (= codeUnitSeeker’s)
seekToChunk method. But, currently, doing so would not update the
codePointSeeker’s position.
---
packages/dom/src/code-point-seeker.ts | 23 ++---------------------
1 file changed, 2 insertions(+), 21 deletions(-)
diff --git a/packages/dom/src/code-point-seeker.ts b/packages/dom/src/code-point-seeker.ts
index 10cb1b1..b97089e 100644
--- a/packages/dom/src/code-point-seeker.ts
+++ b/packages/dom/src/code-point-seeker.ts
@@ -61,10 +61,9 @@ export class CodePointSeeker<TChunk extends Chunk<string>> implements ChunkSeeke
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 s = this.raw.readToChunk(target, 0);
+ let s = this.raw.readToChunk(target, offset);
const movedForward = this.raw.position >= oldRawPosition;
@@ -82,25 +81,7 @@ export class CodePointSeeker<TChunk extends Chunk<string>> implements ChunkSeeke
? 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;
- }
+ if (read) return result;
}
private _readOrSeekTo(read: true, target: number, roundUp?: boolean): string[];
[incubator-annotator] 03/04: Create basic tests for describe text
position
Posted by ge...@apache.org.
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 ec53350d56e55dbd67981d43ed2204d90080d40c
Author: Gerben <ge...@treora.com>
AuthorDate: Wed Nov 18 19:40:18 2020 +0100
Create basic tests for describe text position
---
packages/dom/test/text-position/describe.test.ts | 55 ++++++++++++++++++++++++
1 file changed, 55 insertions(+)
diff --git a/packages/dom/test/text-position/describe.test.ts b/packages/dom/test/text-position/describe.test.ts
new file mode 100644
index 0000000..2eefd38
--- /dev/null
+++ b/packages/dom/test/text-position/describe.test.ts
@@ -0,0 +1,55 @@
+/**
+ * @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.
+ */
+
+import { assert } from 'chai';
+import { describeTextPosition } from '../../src/text-position/describe';
+import { hydrateRange } from '../utils';
+import { testCases } from './match-cases';
+
+const domParser = new window.DOMParser();
+
+describe('createTextPositionSelectorMatcher', () => {
+ describe('inverts test cases of text position matcher', () => {
+ for (const [name, { html, selector, expected }] of Object.entries(
+ testCases,
+ )) {
+ const range = expected[0];
+ it(`case: '${name}'`, async () => {
+ const doc = domParser.parseFromString(html, 'text/html');
+ const scope = doc.createRange();
+ scope.selectNodeContents(doc);
+ const result = await describeTextPosition(hydrateRange(range, doc), scope);
+ assert.deepEqual(result, selector);
+ });
+ }
+ });
+
+ it('works with a scope', () => {
+ // TODO
+ });
+
+ it('works with split text nodes', () => {
+ // TODO
+ });
+
+ it('works with code points split across text nodes', () => {
+ // TODO
+ });
+});
[incubator-annotator] 01/04: Handle half-characters in
CodePointSeeker.seekToChunk
Posted by ge...@apache.org.
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 84ae601a32ef278dc4660da6be5a91586950389b
Author: Gerben <ge...@treora.com>
AuthorDate: Wed Nov 18 18:55:18 2020 +0100
Handle half-characters in CodePointSeeker.seekToChunk
---
packages/dom/src/code-point-seeker.ts | 19 ++++++++++++++++---
1 file changed, 16 insertions(+), 3 deletions(-)
diff --git a/packages/dom/src/code-point-seeker.ts b/packages/dom/src/code-point-seeker.ts
index b0a95cd..10cb1b1 100644
--- a/packages/dom/src/code-point-seeker.ts
+++ b/packages/dom/src/code-point-seeker.ts
@@ -64,8 +64,21 @@ export class CodePointSeeker<TChunk extends Chunk<string>> implements ChunkSeeke
const oldPosition = this.position;
const oldRawPosition = this.raw.position;
- let result = [...this.raw.readToChunk(target, 0)];
- this.position = this.raw.position >= oldRawPosition
+ let s = this.raw.readToChunk(target, 0);
+
+ const movedForward = this.raw.position >= oldRawPosition;
+
+ if (movedForward && endsWithinCharacter(s)) {
+ this.raw.seekBy(-1);
+ s = s.slice(0, -1);
+ } else if (!movedForward && startsWithinCharacter(s)) {
+ this.raw.seekBy(1);
+ s = s.slice(1);
+ }
+
+ let result = [...s];
+
+ this.position = movedForward
? this.position + result.length
: this.position - result.length;
@@ -86,8 +99,8 @@ export class CodePointSeeker<TChunk extends Chunk<string>> implements ChunkSeeke
this.seekTo(oldPosition);
result = this.readTo(targetPosition);
}
+ return result;
}
- return result;
}
private _readOrSeekTo(read: true, target: number, roundUp?: boolean): string[];
[incubator-annotator] 04/04: Export describeTextPosition & use it
in demo
Posted by ge...@apache.org.
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 2ec7100003fdef3fbfb18ed25852535f8959f3d6
Author: Gerben <ge...@treora.com>
AuthorDate: Wed Nov 18 19:46:19 2020 +0100
Export describeTextPosition & use it in demo
---
packages/dom/src/index.ts | 1 +
web/demo/index.html | 9 +++++++++
web/demo/index.js | 14 +++++++++++---
3 files changed, 21 insertions(+), 3 deletions(-)
diff --git a/packages/dom/src/index.ts b/packages/dom/src/index.ts
index 3d7ca58..cd7d2ea 100644
--- a/packages/dom/src/index.ts
+++ b/packages/dom/src/index.ts
@@ -21,4 +21,5 @@
export * from './css';
export * from './range';
export * from './text-quote';
+export * from './text-position';
export * from './highlight-range';
diff --git a/web/demo/index.html b/web/demo/index.html
index ad2d0a2..3ed0961 100644
--- a/web/demo/index.html
+++ b/web/demo/index.html
@@ -72,6 +72,15 @@ under the License.
Upon a change of selection, a
<a rel="external" href="https://www.w3.org/TR/2017/REC-annotation-model-20170223/#text-quote-selector" target="_blank">TextQuoteSelector</a>
will be created, that describes what was selected.</p>
+ <form id="form">
+ The selector can work either
+ <br/>
+ <input type="radio" name="describeMode" value="TextQuote" id="describeModeTextQuote" checked>
+ <label for="describeModeTextQuote">by quoting the selected text</label>; or
+ </br>
+ <input type="radio" name="describeMode" value="TextPosition" id="describeModeTextPosition">
+ <label for="describeModeTextPosition">by counting the selected characters’ position in the text</label>.
+ </form>
</div>
<div class="column">
<h2>Text is found here</h2>
diff --git a/web/demo/index.js b/web/demo/index.js
index cb96a40..842e074 100644
--- a/web/demo/index.js
+++ b/web/demo/index.js
@@ -18,12 +18,14 @@
* under the License.
*/
-/* global info, module, source, target */
+/* global info, module, source, target, form */
import {
makeCreateRangeSelectorMatcher,
createTextQuoteSelectorMatcher,
describeTextQuote,
+ createTextPositionSelectorMatcher,
+ describeTextPosition,
highlightRange,
} from '@annotator/dom';
import { makeRefinable } from '@annotator/selector';
@@ -88,13 +90,14 @@ function cleanup() {
while ((removeHighlight = cleanupFunctions.shift())) {
removeHighlight();
}
- target.normalize();
+ // target.normalize();
info.innerText = '';
}
const createMatcher = makeRefinable((selector) => {
const innerCreateMatcher = {
TextQuoteSelector: createTextQuoteSelectorMatcher,
+ TextPositionSelector: createTextPositionSelectorMatcher,
RangeSelector: makeCreateRangeSelectorMatcher(createMatcher),
}[selector.type];
@@ -126,12 +129,16 @@ async function anchor(selector) {
async function onSelectionChange() {
cleanup();
+ const describeMode = form.describeMode.value;
const scope = document.createRange();
scope.selectNodeContents(source);
const selection = document.getSelection();
for (let i = 0; i < selection.rangeCount; i++) {
const range = selection.getRangeAt(i);
- const selector = await describeTextQuote(range, scope);
+ const selector =
+ describeMode === 'TextPosition'
+ ? await describeTextPosition(range, scope)
+ : await describeTextQuote(range, scope);
await anchor(selector);
}
}
@@ -146,6 +153,7 @@ function onSelectorExampleClick(event) {
}
document.addEventListener('selectionchange', onSelectionChange);
+form.addEventListener('change', onSelectionChange);
document.addEventListener('click', onSelectorExampleClick);
if (module.hot) {