Skip to content

Commit

Permalink
Merge branch 'main' into recogito#127-annotating-enabled-reactive
Browse files Browse the repository at this point in the history
# Conflicts:
#	packages/text-annotator-react/src/TextAnnotator.tsx
#	packages/text-annotator/src/SelectionHandler.ts
  • Loading branch information
oleksandr-danylchenko committed Aug 30, 2024
2 parents 5baebe7 + 183ebb5 commit 6b19a83
Show file tree
Hide file tree
Showing 13 changed files with 1,038 additions and 568 deletions.
1,462 changes: 947 additions & 515 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@recogito/text-annotator-monorepo",
"version": "3.0.0-rc.39",
"version": "3.0.0-rc.41",
"description": "Recogito Text Annotator monorepo",
"author": "Rainer Simon",
"repository": {
Expand Down
12 changes: 6 additions & 6 deletions packages/extension-tei/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@recogito/text-annotator-tei",
"version": "3.0.0-rc.39",
"version": "3.0.0-rc.41",
"description": "Recogito Text Annotator TEI extension",
"author": "Rainer Simon",
"license": "BSD-3-Clause",
Expand All @@ -27,12 +27,12 @@
},
"devDependencies": {
"CETEIcean": "^1.9.3",
"typescript": "5.5.3",
"vite": "^5.3.5",
"vite-plugin-dts": "^3.9.1"
"typescript": "5.5.4",
"vite": "^5.4.2",
"vite-plugin-dts": "^4.0.3"
},
"peerDependencies": {
"@annotorious/core": "^3.0.0-rc.31",
"@recogito/text-annotator": "3.0.0-rc.39"
"@annotorious/core": "^3.0.0",
"@recogito/text-annotator": "3.0.0-rc.41"
}
}
21 changes: 10 additions & 11 deletions packages/text-annotator-react/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@recogito/react-text-annotator",
"version": "3.0.0-rc.39",
"version": "3.0.0-rc.41",
"description": "Recogito Text Annotator React bindings",
"author": "Rainer Simon",
"license": "BSD-3-Clause",
Expand All @@ -26,13 +26,12 @@
"devDependencies": {
"@types/react-dom": "^18.3.0",
"@vitejs/plugin-react": "^4.3.1",
"openseadragon": "4.1.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"typescript": "5.5.3",
"vite": "^5.3.5",
"vite-plugin-dts": "^3.9.1",
"vite-tsconfig-paths": "^4.3.2"
"typescript": "5.5.4",
"vite": "^5.4.2",
"vite-plugin-dts": "^4.0.3",
"vite-tsconfig-paths": "^5.0.1"
},
"peerDependencies": {
"openseadragon": "^3.0.0 || ^4.0.0",
Expand All @@ -45,11 +44,11 @@
}
},
"dependencies": {
"@annotorious/core": "^3.0.0-rc.31",
"@annotorious/react": "^3.0.0-rc.31",
"@floating-ui/react": "^0.26.20",
"@recogito/text-annotator": "3.0.0-rc.39",
"@recogito/text-annotator-tei": "3.0.0-rc.39",
"@annotorious/core": "^3.0.0",
"@annotorious/react": "^3.0.0",
"@floating-ui/react": "^0.26.23",
"@recogito/text-annotator": "3.0.0-rc.41",
"@recogito/text-annotator-tei": "3.0.0-rc.41",
"CETEIcean": "^1.9.3"
}
}
14 changes: 9 additions & 5 deletions packages/text-annotator-react/src/TextAnnotator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ import { createTextAnnotator } from '@recogito/text-annotator';
import '@recogito/text-annotator/dist/text-annotator.css';


export interface TextAnnotatorProps<E extends unknown> extends Omit<TextAnnotatorOptions<E>, 'adapter'> {
export interface TextAnnotatorProps<E extends unknown> extends Omit<TextAnnotatorOptions<E>, 'adapter'> {

children?: ReactNode | JSX.Element;

adapter?: FormatAdapter<TextAnnotation, E> | ((container: HTMLElement) => FormatAdapter<TextAnnotation, E>) | null;

filter?: Filter;

style?: HighlightStyleExpression
style?: HighlightStyleExpression;

className?: string;

Expand All @@ -27,6 +27,8 @@ export const TextAnnotator = <E extends unknown>(props: TextAnnotatorProps<E>) =

const { className, children, ...opts } = props;

const { style, filter, user, annotatingEnabled } = opts;

const { anno, setAnno } = useContext(AnnotoriousContext);

useEffect(() => {
Expand All @@ -40,11 +42,13 @@ export const TextAnnotator = <E extends unknown>(props: TextAnnotatorProps<E>) =
return () => anno.destroy();
}, [setAnno]);

useEffect(() => anno?.setStyle(props.style), [anno, props.style]);
useEffect(() => anno?.setStyle(style), [anno, style]);

useEffect(() => anno?.setFilter(filter), [anno, filter]);

useEffect(() => anno?.setFilter(props.filter), [anno, props.filter]);
useEffect(() => anno?.setUser(user), [anno, user]);

useEffect(() => anno?.setAnnotatingEnabled(props.annotatingEnabled), [anno, props.annotatingEnabled]);
useEffect(() => anno?.setAnnotatingEnabled(annotatingEnabled), [anno, annotatingEnabled]);

return (
<div ref={el} className={className}>
Expand Down
20 changes: 10 additions & 10 deletions packages/text-annotator/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@recogito/text-annotator",
"version": "3.0.0-rc.39",
"version": "3.0.0-rc.41",
"description": "A JavaScript text annotation library",
"author": "Rainer Simon",
"license": "BSD-3-Clause",
Expand All @@ -27,21 +27,21 @@
},
"devDependencies": {
"@types/jsdom": "^21.1.7",
"@types/rbush": "^3.0.3",
"@types/rbush": "^3.0.4",
"@types/uuid": "^10.0.0",
"jsdom": "^24.1.1",
"svelte": "^4.2.18",
"typescript": "5.5.3",
"vite": "^5.3.5",
"vite-plugin-dts": "^3.9.1",
"vitest": "^2.0.4"
"jsdom": "^25.0.0",
"svelte": "^4.2.19",
"typescript": "5.5.4",
"vite": "^5.4.2",
"vite-plugin-dts": "^4.0.3",
"vitest": "^2.0.5"
},
"dependencies": {
"@annotorious/core": "^3.0.0-rc.31",
"@annotorious/core": "^3.0.0",
"colord": "^2.9.3",
"debounce": "^2.1.0",
"dequal": "^2.0.3",
"rbush": "^4.0.0",
"rbush": "^4.0.1",
"uuid": "^10.0.0"
}
}
21 changes: 15 additions & 6 deletions packages/text-annotator/src/SelectionHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
splitAnnotatableRanges,
rangeToSelector,
isWhitespaceOrEmpty,
trimRangeToContainer,
NOT_ANNOTATABLE_SELECTOR
} from './utils';

Expand Down Expand Up @@ -84,15 +85,19 @@ export const createSelectionHandler = (
}

// Chrome/iOS does not reliably fire the 'selectstart' event!
if (evt.timeStamp - (lastPointerDown?.timeStamp || evt.timeStamp) < 1000 && !currentTarget)
const timeDifference = evt.timeStamp - (lastPointerDown?.timeStamp || evt.timeStamp);
if (timeDifference < 1000 && !currentTarget)
onSelectStart(lastPointerDown);

if (sel.isCollapsed || !isLeftClick || !currentTarget) return;

const selectionRange = sel.getRangeAt(0);
if (isWhitespaceOrEmpty(selectionRange)) return;

const annotatableRanges = splitAnnotatableRanges(selectionRange.cloneRange());
// The selection should be captured only within the annotatable container
const containedRange = trimRangeToContainer(selectionRange, container);
if (isWhitespaceOrEmpty(containedRange)) return;

const annotatableRanges = splitAnnotatableRanges(containedRange.cloneRange());

const hasChanged =
annotatableRanges.length !== currentTarget.selector.length ||
Expand Down Expand Up @@ -138,7 +143,7 @@ export const createSelectionHandler = (
isLeftClick = evt.button === 0;
}

container.addEventListener('pointerdown', onPointerDown);
document.addEventListener('pointerdown', onPointerDown);

const onPointerUp = (evt: PointerEvent) => {
const annotatable = !(evt.target as Node).parentElement?.closest(NOT_ANNOTATABLE_SELECTOR);
Expand All @@ -149,7 +154,11 @@ export const createSelectionHandler = (
const clickSelect = () => {
const { x, y } = container.getBoundingClientRect();

const hovered = store.getAt(evt.clientX - x, evt.clientY - y, currentFilter);
const hovered =
evt.target instanceof Node &&
container.contains(evt.target) &&
store.getAt(evt.clientX - x, evt.clientY - y, currentFilter);

if (hovered) {
const { selected } = selection;

Expand Down Expand Up @@ -182,7 +191,7 @@ export const createSelectionHandler = (
container.removeEventListener('selectstart', onSelectStart);
document.removeEventListener('selectionchange', onSelectionChange);

container.removeEventListener('pointerdown', onPointerDown);
document.removeEventListener('pointerdown', onPointerDown);
document.removeEventListener('pointerup', onPointerUp);
}

Expand Down
7 changes: 4 additions & 3 deletions packages/text-annotator/src/TextAnnotator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,11 @@ export const createTextAnnotator = <E extends unknown = TextAnnotation>(
cancelSingleClickEvents(container);

const opts = fillDefaults<E>(options, {
annotatingEnabled: true
annotatingEnabled: true,
user: createAnonymousGuest()
});

const state: TextAnnotatorState = createTextAnnotatorState(container, opts.userAction);
const state: TextAnnotatorState = createTextAnnotatorState(container, opts.userSelectAction);

const { selection, viewport } = state;

Expand All @@ -60,7 +61,7 @@ export const createTextAnnotator = <E extends unknown = TextAnnotation>(

const lifecycle = createLifecycleObserver<TextAnnotation, E>(state, undoStack, opts.adapter);

let currentUser: User = createAnonymousGuest();
let currentUser: User = opts.user;

// Use selected renderer, or fall back to default. If CSS_HIGHLIGHT is
// requested, check if CSS Custom Highlights are supported, and fall
Expand Down
11 changes: 7 additions & 4 deletions packages/text-annotator/src/TextAnnotatorOptions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { FormatAdapter, UserSelectActionExpression } from '@annotorious/core';
import type { FormatAdapter, UserSelectActionExpression, User } from '@annotorious/core';
import type { PresencePainterOptions } from './presence';
import type { TextAnnotation } from './model';
import type { HighlightStyleExpression } from './highlight';
Expand All @@ -13,24 +13,27 @@ export interface TextAnnotatorOptions<T extends unknown = TextAnnotation> {

offsetReferenceSelector?: string;

userAction?: UserSelectActionExpression<TextAnnotation>,
userSelectAction?: UserSelectActionExpression<TextAnnotation>,

presence?: PresencePainterOptions;

style?: HighlightStyleExpression;

user?: User;

}

export type RendererType = 'SPANS' | 'CANVAS' | 'CSS_HIGHLIGHTS';

export const fillDefaults = <T extends unknown = TextAnnotation> (
export const fillDefaults = <T extends unknown = TextAnnotation>(
opts: TextAnnotatorOptions<T>,
defaults: TextAnnotatorOptions<T>
): TextAnnotatorOptions<T> => {

return {
...opts,
annotatingEnabled: opts.annotatingEnabled ?? defaults.annotatingEnabled
annotatingEnabled: opts.annotatingEnabled ?? defaults.annotatingEnabled,
user: opts.user || defaults.user
};

};
9 changes: 5 additions & 4 deletions packages/text-annotator/src/highlight/span/spansRenderer.css
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
.r6o-annotatable .r6o-span-highlight-layer {
height: 100%;
left: 0;
mix-blend-mode: multiply;
pointer-events: none;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
mix-blend-mode: multiply;
pointer-events: none;
z-index: 1;
}

.r6o-annotatable .r6o-span-highlight-layer.hidden {
Expand Down
8 changes: 5 additions & 3 deletions packages/text-annotator/src/state/TextAnnotatorState.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Filter, UserSelectAction, Store, ViewportState, UserSelectActionExpression } from '@annotorious/core';
import type { Filter, Store, ViewportState, UserSelectActionExpression } from '@annotorious/core';
import {
createHoverState,
createSelectionState,
Expand Down Expand Up @@ -28,14 +28,16 @@ export interface TextAnnotatorState extends AnnotatorState<TextAnnotation> {

export const createTextAnnotatorState = (
container: HTMLElement,
defaultUserAction?: UserSelectActionExpression<TextAnnotation>
defaultUserSelectAction?: UserSelectActionExpression<TextAnnotation>
): TextAnnotatorState => {

const store: Store<TextAnnotation> = createStore<TextAnnotation>();

const tree = createSpatialTree(store, container);

const selection = createSelectionState<TextAnnotation>(store, defaultUserAction);
// Temporary
const selection = createSelectionState<TextAnnotation>(store)
selection.setUserSelectAction(defaultUserSelectAction);

const hover = createHoverState(store);

Expand Down
1 change: 1 addition & 0 deletions packages/text-annotator/src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ export * from './reviveAnnotation';
export * from './reviveSelector';
export * from './reviveTarget';
export * from './splitAnnotatableRanges';
export * from './trimRangeToContainer';

18 changes: 18 additions & 0 deletions packages/text-annotator/src/utils/trimRangeToContainer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export const trimRangeToContainer = (
range: Range,
container: HTMLElement
): Range => {
const trimmedRange = range.cloneRange();

// If the start is outside the container - set it to the start of the container
if (!container.contains(trimmedRange.startContainer)) {
trimmedRange.setStart(container, 0);
}

// If the end is outside the container - set it to the end of the container
if (!container.contains(trimmedRange.endContainer)) {
trimmedRange.setEnd(container, container.childNodes.length);
}

return trimmedRange;
};

0 comments on commit 6b19a83

Please sign in to comment.