Skip to content

Commit 7872dfe

Browse files
committed
Minor bugfix
1 parent a90587b commit 7872dfe

File tree

1 file changed

+26
-6
lines changed

1 file changed

+26
-6
lines changed

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

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,33 @@ const getXPath = (node: Node, path: string[] = []) => {
4747
* For the given path sgement lists, this function returns the the
4848
* start & end XPath expression pair.
4949
*/
50-
const toTEIXPaths = (startPath: string[], endPath: string[], selectedRange: Range) => {
50+
const toTEIXPaths = (container: HTMLElement, startPath: string[], endPath: string[], selectedRange: Range) => {
51+
52+
const findFirstTEIChild = (node: Node): Element | null => {
53+
const iterator = document.createNodeIterator(
54+
node,
55+
NodeFilter.SHOW_ELEMENT,
56+
(node) => {
57+
return (node as Element).nodeName.toLowerCase().startsWith('tei-')
58+
? NodeFilter.FILTER_ACCEPT
59+
: NodeFilter.FILTER_SKIP;
60+
}
61+
);
62+
63+
return iterator.nextNode() as Element | null;
64+
}
65+
5166
// For a given node, returns the closest parent that is a TEI element
5267
const getClosestTEINode = (node: Node | null) => {
5368
if (!node) return null;
5469

55-
return (node.nodeName.toLowerCase().indexOf('tei-') === 0) ?
56-
node : getClosestTEINode(node.parentNode);
70+
// Edge case: node is the container itself
71+
if (node === container) {
72+
return findFirstTEIChild(node);
73+
} else {
74+
return (node.nodeName.toLowerCase().indexOf('tei-') === 0) ?
75+
node : getClosestTEINode(node.parentNode);
76+
}
5777
};
5878

5979
// Helper to compute char offsets between end of XPath and a given reference node
@@ -85,15 +105,15 @@ const toTEIXPaths = (startPath: string[], endPath: string[], selectedRange: Rang
85105
* Using the DOM Range from a (revived!) TextSelector, this function computes
86106
* the TEIRangeSelector corresponding to that range.
87107
*/
88-
export const textToTEISelector = (selector: TextSelector): TEIRangeSelector => {
108+
export const textToTEISelector = (container: HTMLElement) => (selector: TextSelector): TEIRangeSelector => {
89109
const { range } = selector;
90110

91111
// XPath segments for Range start and end nodes as a list
92112
const startPathSegments: string[] = getXPath(range.startContainer);
93113
const endPathSegments: string[] = getXPath(range.endContainer);
94114

95115
// TEI XPath expressions
96-
const { start, end } = toTEIXPaths(startPathSegments, endPathSegments, range);
116+
const { start, end } = toTEIXPaths(container, startPathSegments, endPathSegments, range);
97117

98118
return {
99119
start: selector.start,
@@ -179,7 +199,7 @@ export const textToTEITarget = (container: HTMLElement) => (t: TextAnnotationTa
179199
const target = reviveTarget(t, container);
180200
return {
181201
...t,
182-
selector: target.selector.map(textToTEISelector)
202+
selector: target.selector.map(textToTEISelector(container))
183203
}
184204
}
185205

0 commit comments

Comments
 (0)