You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@annotator.apache.org by df...@apache.org on 2021/06/28 13:34:37 UTC
[incubator-annotator] 03/07: Add failing test changing DOM (text
quote match)
This is an automated email from the ASF dual-hosted git repository.
dfoulks pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-annotator.git
commit 65b8c181e1703105538ea85e1f3ac0e9d8d56edb
Author: Gerben <ge...@treora.com>
AuthorDate: Fri Jun 25 17:15:12 2021 +0200
Add failing test changing DOM (text quote match)
See issue #112 <https://github.com/apache/incubator-annotator/issues/112>
---
packages/dom/test/text-quote/match.test.ts | 65 ++++++++++++++++++++----------
web/index.js | 2 +
2 files changed, 45 insertions(+), 22 deletions(-)
diff --git a/packages/dom/test/text-quote/match.test.ts b/packages/dom/test/text-quote/match.test.ts
index f023215..cfb0753 100644
--- a/packages/dom/test/text-quote/match.test.ts
+++ b/packages/dom/test/text-quote/match.test.ts
@@ -171,6 +171,20 @@ describe('createTextQuoteSelectorMatcher', () => {
scope.setEnd(evaluateXPath(doc, '//b/text()'), 32);
await testMatcher(doc, scope, selector, []);
});
+
+ it.skip('is resistant to splitting text nodes', async () => {
+ const { html, selector, expected } = testCases['two matches'];
+ const doc = domParser.parseFromString(html, 'text/html');
+
+ const matcher = createTextQuoteSelectorMatcher(selector);
+ let count = 0;
+ for await (const match of matcher(doc.body)) {
+ assertMatchIsCorrect(doc, match, expected[count++]);
+ const wrapperNode = doc.createElement('mark');
+ match.surroundContents(wrapperNode);
+ }
+ assert.equal(count, expected.length, 'Wrong number of matches.');
+ });
});
async function testMatcher(
@@ -184,31 +198,38 @@ async function testMatcher(
for await (const value of matcher(scope)) matches.push(value);
assert.equal(matches.length, expected.length, 'Wrong number of matches.');
matches.forEach((match, i) => {
- const expectedRange = expected[i];
- const expectedStartContainer = evaluateXPath(
- doc,
- expectedRange.startContainerXPath,
- );
- const expectedEndContainer = evaluateXPath(
- doc,
- expectedRange.endContainerXPath,
- );
- assert(
- match.startContainer === expectedStartContainer,
- `unexpected start container: ${prettyNodeName(match.startContainer)}; ` +
- `expected ${prettyNodeName(expectedStartContainer)}`,
- );
- assert.equal(match.startOffset, expectedRange.startOffset);
- assert(
- match.endContainer ===
- evaluateXPath(doc, expectedRange.endContainerXPath),
- `unexpected end container: ${prettyNodeName(match.endContainer)}; ` +
- `expected ${prettyNodeName(expectedEndContainer)}`,
- );
- assert.equal(match.endOffset, expectedRange.endOffset);
+ assertMatchIsCorrect(doc, match, expected[i]);
});
}
+function assertMatchIsCorrect(
+ doc: Document,
+ match: Range,
+ expected: RangeInfo,
+) {
+ const expectedStartContainer = evaluateXPath(
+ doc,
+ expected.startContainerXPath,
+ );
+ const expectedEndContainer = evaluateXPath(
+ doc,
+ expected.endContainerXPath,
+ );
+ assert(
+ match.startContainer === expectedStartContainer,
+ `unexpected start container: ${prettyNodeName(match.startContainer)}; ` +
+ `expected ${prettyNodeName(expectedStartContainer)}`,
+ );
+ assert.equal(match.startOffset, expected.startOffset);
+ assert(
+ match.endContainer ===
+ evaluateXPath(doc, expected.endContainerXPath),
+ `unexpected end container: ${prettyNodeName(match.endContainer)}; ` +
+ `expected ${prettyNodeName(expectedEndContainer)}`,
+ );
+ assert.equal(match.endOffset, expected.endOffset);
+}
+
function prettyNodeName(node: Node) {
switch (node.nodeType) {
case Node.TEXT_NODE: {
diff --git a/web/index.js b/web/index.js
index 5ca1445..d8275bd 100644
--- a/web/index.js
+++ b/web/index.js
@@ -114,6 +114,8 @@ async function anchor(selector) {
const matchAll = createMatcher(selector);
const ranges = [];
+ // First collect all matches, and only then highlight them; to avoid
+ // modifying the DOM while the matcher is running.
for await (const range of matchAll(target)) {
ranges.push(range);
}