Skip to content

Commit 39271c7

Browse files
Merge branch 'main' into fix-checking-null-elements-annotability
2 parents a462c66 + 69be7ea commit 39271c7

File tree

7 files changed

+30
-32
lines changed

7 files changed

+30
-32
lines changed

packages/text-annotator-react/src/TextAnnotatorPopup/TextAnnotatorPopup.tsx

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { PointerEvent, ReactNode, useCallback, useEffect, useMemo, useState } from 'react';
22
import { useAnnotator, useSelection } from '@annotorious/react';
3-
import type { TextAnnotation, TextAnnotator } from '@recogito/text-annotator';
3+
import { isRevived, TextAnnotation, TextAnnotator } from '@recogito/text-annotator';
44
import { isMobile } from './isMobile';
55
import {
66
autoUpdate,
@@ -71,15 +71,10 @@ export const TextAnnotatorPopup = (props: TextAnnotationPopupProps) => {
7171
const { getFloatingProps } = useInteractions([dismiss, role]);
7272

7373
useEffect(() => {
74-
setOpen(
75-
// Selected annotation exists and has a selector?
76-
annotation?.target.selector &&
77-
// Selector not empty? (Annotations from plugins, general defensive programming)
78-
annotation.target.selector.length > 0 &&
79-
// Range not collapsed? (E.g. lazy loading PDFs. Note that this will have to
80-
// change if we switch from ranges to pre-computed bounds!)
81-
!annotation.target.selector[0].range.collapsed
82-
);
74+
const annotationSelector = annotation?.target.selector;
75+
if (!annotationSelector) return;
76+
77+
setOpen(isRevived(annotationSelector));
8378
}, [annotation]);
8479

8580
useEffect(() => {
@@ -154,4 +149,4 @@ export const TextAnnotatorPopup = (props: TextAnnotationPopupProps) => {
154149
</FloatingPortal>
155150
) : null;
156151

157-
}
152+
}

packages/text-annotator/src/utils/cancelSingleClickEvents.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { NOT_ANNOTATABLE_SELECTOR } from './splitAnnotatableRanges';
1+
import { NOT_ANNOTATABLE_SELECTOR } from './isNotAnnotatable';
22

33
/**
44
* Calls .preventDefault() on click events in annotable areas, in order
Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
export * from './cancelSingleClickEvents';
2+
export * from './cloneEvents';
23
export * from './device';
34
export * from './programmaticallyFocusable';
45
export * from './debounce';
56
export * from './getQuoteContext';
6-
export * from './isWhitespaceOrEmpty';
7+
export * from './isNotAnnotatable';
78
export * from './isRevived';
9+
export * from './isWhitespaceOrEmpty';
810
export * from './mergeClientRects';
911
export * from './rangeToSelector';
1012
export * from './reviveAnnotation';
1113
export * from './reviveSelector';
1214
export * from './reviveTarget';
1315
export * from './splitAnnotatableRanges';
1416
export * from './trimRangeToContainer';
15-
export * from './cloneEvents';
17+
1618

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
export const NOT_ANNOTATABLE_CLASS = 'not-annotatable';
2+
3+
export const NOT_ANNOTATABLE_SELECTOR = `.${NOT_ANNOTATABLE_CLASS}`;
4+
5+
export const isNotAnnotatable = (node: Node): boolean => {
6+
const closestNotAnnotatable = node instanceof HTMLElement
7+
? node.closest(NOT_ANNOTATABLE_SELECTOR)
8+
: node.parentElement?.closest(NOT_ANNOTATABLE_SELECTOR);
9+
return Boolean(closestNotAnnotatable);
10+
}
11+
12+
export const isRangeAnnotatable = (range: Range): boolean => {
13+
const ancestor = range.commonAncestorContainer;
14+
return !isNotAnnotatable(ancestor);
15+
}

packages/text-annotator/src/utils/reviveSelector.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { TextSelector } from '../model';
2-
import { NOT_ANNOTATABLE_SELECTOR } from './splitAnnotatableRanges';
2+
import { NOT_ANNOTATABLE_SELECTOR } from './isNotAnnotatable';
33

44
/**
55
* Creates a new selector object with the revived DOM range from the given text annotation position

packages/text-annotator/src/utils/splitAnnotatableRanges.ts

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,4 @@
1-
export const NOT_ANNOTATABLE_CLASS = 'not-annotatable';
2-
3-
export const NOT_ANNOTATABLE_SELECTOR = `.${NOT_ANNOTATABLE_CLASS}`;
4-
5-
export const isNotAnnotatable = (node: Node): boolean => {
6-
const closestNotAnnotatable = node instanceof HTMLElement
7-
? node.closest(NOT_ANNOTATABLE_SELECTOR)
8-
: node.parentElement?.closest(NOT_ANNOTATABLE_SELECTOR);
9-
return Boolean(closestNotAnnotatable);
10-
}
11-
12-
export const isRangeAnnotatable = (range: Range): boolean => {
13-
const ancestor = range.commonAncestorContainer;
14-
return !isNotAnnotatable(ancestor);
15-
}
1+
import { isRangeAnnotatable, NOT_ANNOTATABLE_CLASS, NOT_ANNOTATABLE_SELECTOR } from './isNotAnnotatable';
162

173
const iterateNotAnnotatableElements = function*(range: Range): Generator<HTMLElement> {
184
const notAnnotatableIterator = document.createNodeIterator(

packages/text-annotator/test/model/w3c/fixtures.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ export const textAnnotation: W3CTextAnnotation = {
2828
},
2929
{
3030
type: 'TextPositionSelector',
31-
start: 986,
32-
end: 998
31+
start: 958,
32+
end: 970
3333
},
3434
]
3535
}

0 commit comments

Comments
 (0)