Skip to content

Commit 89d13f0

Browse files
Merge branch 'main' into fix-checking-null-elements-annotability
2 parents 39271c7 + d9d3819 commit 89d13f0

File tree

18 files changed

+644
-45651
lines changed

18 files changed

+644
-45651
lines changed

package-lock.json

Lines changed: 518 additions & 696 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@recogito/text-annotator-monorepo",
3-
"version": "3.0.0-rc.49",
3+
"version": "3.0.0-rc.50",
44
"description": "Recogito Text Annotator monorepo",
55
"author": "Rainer Simon",
66
"repository": {

packages/extension-tei/package.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@recogito/text-annotator-tei",
3-
"version": "3.0.0-rc.49",
3+
"version": "3.0.0-rc.50",
44
"description": "Recogito Text Annotator TEI extension",
55
"author": "Rainer Simon",
66
"license": "BSD-3-Clause",
@@ -27,12 +27,12 @@
2727
},
2828
"devDependencies": {
2929
"CETEIcean": "^1.9.3",
30-
"typescript": "5.6.2",
31-
"vite": "^5.4.8",
32-
"vite-plugin-dts": "^4.2.3"
30+
"typescript": "5.6.3",
31+
"vite": "^5.4.10",
32+
"vite-plugin-dts": "^4.3.0"
3333
},
3434
"peerDependencies": {
35-
"@annotorious/core": "^3.0.9",
36-
"@recogito/text-annotator": "3.0.0-rc.49"
35+
"@annotorious/core": "^3.0.11",
36+
"@recogito/text-annotator": "3.0.0-rc.50"
3737
}
3838
}

packages/extension-tei/src/crosswalk/forward.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import { rangeToSelector, reviveTarget as reviveTextOffsetTarget } from '@recogito/text-annotator';
2+
import type { TEIAnnotation, TEIAnnotationTarget, TEIRangeSelector } from '../TEIAnnotation';
3+
import { reanchor } from './utils';
24
import type {
35
TextAnnotation,
46
TextAnnotationTarget,
57
TextSelector
68
} from '@recogito/text-annotator';
7-
import type { TEIAnnotation, TEIAnnotationTarget, TEIRangeSelector } from '../TEIAnnotation';
89

910
/**
1011
* Helper: Returns the given XPath for a DOM node, in the form of
@@ -145,8 +146,21 @@ export const reviveTarget = (t: TextAnnotationTarget, container: HTMLElement) =>
145146
const [endNode, endOffset] = evaluateSelector(endExpression);
146147

147148
const range = document.createRange();
148-
range.setStart(startNode.firstChild, startOffset);
149-
range.setEnd(endNode.firstChild, endOffset);
149+
150+
// Helper
151+
const reanchorIfNeeded = (parent: Node, offset: number) => {
152+
if (parent.firstChild.toString().length >= offset) {
153+
return { node: parent.firstChild, offset };
154+
} else {
155+
return reanchor(parent.firstChild, parent, offset);
156+
}
157+
}
158+
159+
const reanchoredStart = reanchorIfNeeded(startNode, startOffset);
160+
const reanchoredEnd = reanchorIfNeeded(endNode, endOffset);
161+
162+
range.setStart(reanchoredStart.node, reanchoredStart.offset);
163+
range.setEnd(reanchoredEnd.node, reanchoredEnd.offset);
150164

151165
const textSelector = rangeToSelector(range, container);
152166

packages/extension-tei/src/crosswalk/reverse.ts

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { TextAnnotation, TextAnnotationTarget } from '@recogito/text-annotator';
22
import type { TEIAnnotation, TEIAnnotationTarget, TEIRangeSelector } from '../TEIAnnotation';
3+
import { reanchor } from './utils';
34

45
/**
56
* Helper: converts the given XPath string and DOM container element
@@ -24,35 +25,8 @@ const xpathToDOMPosition = (path: string, container: Element) => {
2425

2526
const offset = parseInt(path.substring(offsetIdx + 2));
2627

27-
const reanchor = (originalNode: Node, originalOffset: number) => {
28-
let node = originalNode;
29-
30-
let offset = originalOffset;
31-
32-
const it = document.createNodeIterator(parentNode, NodeFilter.SHOW_TEXT);
33-
34-
let currentNode = it.nextNode();
35-
36-
let run = true;
37-
38-
do {
39-
if (currentNode instanceof Text) {
40-
if (currentNode.length < offset) {
41-
offset -= currentNode.length;
42-
} else {
43-
node = currentNode;
44-
run = false;
45-
}
46-
}
47-
48-
currentNode = it.nextNode();
49-
} while (currentNode && run);
50-
51-
return { node, offset };
52-
};
53-
5428
if (!(node instanceof Text) || offset > node.length) {
55-
return reanchor(node, offset);
29+
return reanchor(node, parentNode, offset);
5630
} else {
5731
return { node, offset };
5832
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './reanchor';
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
export const reanchor = (originalNode: Node, parentNode: Node, originalOffset: number) => {
2+
let node = originalNode;
3+
4+
let offset = originalOffset;
5+
6+
const it = document.createNodeIterator(parentNode, NodeFilter.SHOW_TEXT);
7+
8+
let currentNode = it.nextNode();
9+
10+
let run = true;
11+
12+
do {
13+
if (currentNode instanceof Text) {
14+
if (currentNode.length < offset) {
15+
offset -= currentNode.length;
16+
} else {
17+
node = currentNode;
18+
run = false;
19+
}
20+
}
21+
22+
currentNode = it.nextNode();
23+
} while (currentNode && run);
24+
25+
return { node, offset };
26+
};
Lines changed: 35 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,40 @@
11
[{
2-
"id": "5430edac-706b-4943-9b87-fd6e8f281b39",
3-
"bodies": [],
2+
"id": "uid-5be9c1d9-a92f-47b9-aa95-acdc05cd6268",
3+
"layer_id": "tei_standoff",
44
"target": {
5-
"annotation": "5430edac-706b-4943-9b87-fd6e8f281b39",
6-
"selector": [{
7-
"startSelector": {
8-
"type": "XPathSelector",
9-
"value": "//castItem[@xml:id='WITCHES_Mac']::13"
5+
"annotation": "uid-5be9c1d9-a92f-47b9-aa95-acdc05cd6268",
6+
"creator": {
7+
"id": "uid-af5d65e0-a46f-4eb9-80f6-11ba5e907485",
8+
"name": "\n Professor\n "
109
},
11-
"endSelector": {
12-
"type": "XPathSelector",
13-
"value": "//castItem[@xml:id='Ross_Mac']/role[1]/name[1]::4"
14-
}
15-
}],
16-
"creator": {
17-
"isGuest": true,
18-
"id": "DwQPXeG3uLHfsSLnvTV8"
19-
},
20-
"created": "2023-09-21T05:47:51.594Z"
21-
}
22-
}, {
23-
"id": "fa049492-020b-4eaf-ba93-3d595e9d624f",
24-
"bodies": [],
25-
"target": {
26-
"annotation": "fa049492-020b-4eaf-ba93-3d595e9d624f",
27-
"selector": [{
28-
"start": 6464,
29-
"startSelector": {
30-
"type": "XPathSelector",
31-
"value": "//w[@xml:id='fs-mac-0000010']::0"
10+
"created": "2024-10-30T17:48:12.149Z",
11+
"updatedBy": {
12+
"id": "uid-af5d65e0-a46f-4eb9-80f6-11ba5e907485",
13+
"name": "\n Professor\n "
3214
},
33-
"end": 6828,
34-
"endSelector": {
35-
"type": "XPathSelector",
36-
"value": "//pc[@xml:id='fs-mac-0000190']::1"
37-
},
38-
"quote": "ACT 1 Scene 1 Thunder and Lightning . Enter three Witches .",
39-
"range": {}
40-
}],
41-
"creator": {
42-
"isGuest": true,
43-
"id": "jzgy0s50ZDZBGakEHfTU"
44-
},
45-
"created": "2023-09-21T05:29:04.847Z"
46-
}
47-
},{
48-
"id": "091078e1-4073-4efc-a82a-bee79774dbf0",
49-
"bodies": [],
50-
"target": {
51-
"annotation": "091078e1-4073-4efc-a82a-bee79774dbf0",
52-
"selector": [{
53-
"start": 3671,
54-
"startSelector": {
55-
"type": "XPathSelector",
56-
"value": "//castItem[@xml:id='Malcolm_Mac']/role[1]/name[1]::4"
57-
},
58-
"end": 4578,
59-
"endSelector": {
60-
"type": "XPathSelector",
61-
"value": "//castItem[@xml:id='Banquo_Mac']/roleDesc[1]::39"
62-
},
63-
"quote": "olm his elder son Donalbain Duncan’s younger son Macbeth thane of Glamis Lady Macbeth Seyton attendant to Macbeth Three Murderers in Macbeth’s service both attending upon Lady Macbeth A Doctor A Gentlewoman A Porter Banquo commander, with Macbeth, of Duncan’s ar",
64-
"range": {}
65-
}],
66-
"creator": {
67-
"isGuest": true,
68-
"id": "2G7YULxo_qVPC2wCYxfW"
69-
},
70-
"created": "2023-09-21T05:47:24.687Z"
71-
}
15+
"updated": "2024-10-30T17:48:08.235Z",
16+
"selector": [
17+
{
18+
"startSelector": {
19+
"type": "XPathSelector",
20+
"value": "//text[@xml:id='text-1']/body[1]/div[1]/p[4]/hi[1]::0"
21+
},
22+
"endSelector": {
23+
"type": "XPathSelector",
24+
"value": "//text[@xml:id='text-1']/body[1]/div[1]/p[4]::383"
25+
}
26+
}
27+
]
28+
},
29+
"bodies": [
30+
{
31+
"id": "479229dc-fc78-4a6d-8179-0ab58ffe89be",
32+
"annotation": "uid-5be9c1d9-a92f-47b9-aa95-acdc05cd6268",
33+
"value": "Very cool comment",
34+
"creator": {
35+
"id": "uid-af5d65e0-a46f-4eb9-80f6-11ba5e907485",
36+
"name": "\n Professor\n "
37+
}
38+
}
39+
]
7240
}]

packages/extension-tei/test/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
window.onload = async function () {
6363
var CETEIcean = new CETEI();
6464

65-
CETEIcean.getHTML5('macbeth.xml', data => {
65+
CETEIcean.getHTML5('paradise-lost.xml', data => {
6666
document.getElementById('content').appendChild(data);
6767

6868
var anno = TEIPlugin(createTextAnnotator(document.getElementById('content')));

0 commit comments

Comments
 (0)