Skip to content

Commit

Permalink
Merge branch 'main' into recogito#71-fix-losing-styleClass
Browse files Browse the repository at this point in the history
# Conflicts:
#	packages/text-annotator/src/highlight/canvas/highlightRenderer.ts
  • Loading branch information
oleksandr-danylchenko committed Apr 4, 2024
2 parents 7f80bb3 + 1dbda37 commit 3647e9e
Show file tree
Hide file tree
Showing 33 changed files with 1,316 additions and 915 deletions.
739 changes: 408 additions & 331 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.18",
"version": "3.0.0-rc.21",
"description": "Recogito Text Annotator monorepo",
"author": "Rainer Simon",
"repository": {
Expand Down
15 changes: 8 additions & 7 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.18",
"version": "3.0.0-rc.21",
"description": "Recogito Text Annotator TEI extension",
"author": "Rainer Simon",
"license": "BSD-3-Clause",
Expand All @@ -27,11 +27,12 @@
},
"devDependencies": {
"CETEIcean": "^1.9.2",
"typescript": "^5.3.3",
"vite": "^5.2.6",
"vite-plugin-dts": "^3.7.3"
"typescript": "^5.4.3",
"vite": "^5.2.7",
"vite-plugin-dts": "^3.8.1"
},
"dependencies": {
"@annotorious/core": "^3.0.0-rc.21"
"peerDependencies": {
"@annotorious/core": "^3.0.0-rc.22",
"@recogito/text-annotator": "3.0.0-rc.21"
}
}
}
17 changes: 10 additions & 7 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.18",
"version": "3.0.0-rc.21",
"description": "Recogito Text Annotator React bindings",
"author": "Rainer Simon",
"license": "BSD-3-Clause",
Expand All @@ -24,23 +24,26 @@
"module": "./dist/react-text-annotator.es.js",
"types": "./dist/index.d.ts",
"devDependencies": {
"@types/react-dom": "^18.2.22",
"@types/react-dom": "^18.2.23",
"@vitejs/plugin-react": "^4.2.1",
"openseadragon": "4.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"typescript": "^5.3.3",
"vite": "^5.2.6",
"vite-plugin-dts": "^3.7.3",
"typescript": "^5.4.3",
"vite": "^5.2.7",
"vite-plugin-dts": "^3.8.1",
"vite-tsconfig-paths": "^4.3.2"
},
"peerDependencies": {
"@annotorious/react": "^3.0.0-rc.21",
"react": "16.8.0 || >=17.x || >=18.x",
"react-dom": "16.8.0 || >=17.x || >=18.x"
},
"dependencies": {
"@annotorious/core": "^3.0.0-rc.22",
"@annotorious/react": "^3.0.0-rc.22",
"@recogito/text-annotator": "3.0.0-rc.21",
"@recogito/text-annotator-tei": "3.0.0-rc.21",
"@neodrag/react": "^2.0.3",
"CETEIcean": "^1.9.2"
}
}
}
7 changes: 4 additions & 3 deletions packages/text-annotator-react/src/TextAnnotator.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { ReactNode, useContext, useEffect, useRef } from 'react';
import { AnnotoriousContext, DrawingStyle, Filter } from '@annotorious/react';
import { AnnotoriousContext, Filter } from '@annotorious/react';
import type { FormatAdapter } from '@annotorious/core';
import type { TextAnnotation, TextAnnotatorOptions } from '@recogito/text-annotator';
import type { HighlightStyleExpression, TextAnnotation, TextAnnotatorOptions } from '@recogito/text-annotator';
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'> {

children?: ReactNode | JSX.Element;
Expand All @@ -14,7 +15,7 @@ export interface TextAnnotatorProps<E extends unknown> extends Omit<TextAnnotato

filter?: Filter;

style?: DrawingStyle | ((annotation: TextAnnotation) => DrawingStyle);
style?: HighlightStyleExpression

className?: string;

Expand Down
10 changes: 5 additions & 5 deletions packages/text-annotator-react/src/tei/TEIAnnotator.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Children, ReactElement, ReactNode, cloneElement, useContext, useEffect } from 'react';
import { AnnotoriousContext, DrawingStyle, Filter } from '@annotorious/react';
import { AnnotoriousContext, Filter } from '@annotorious/react';
import { TEIPlugin } from '@recogito/text-annotator-tei';
import { createTextAnnotator } from '@recogito/text-annotator';
import type { TextAnnotatorOptions, TextAnnotation } from '@recogito/text-annotator';
import { createTextAnnotator, HighlightStyleExpression } from '@recogito/text-annotator';
import type { TextAnnotatorOptions } from '@recogito/text-annotator';

import '@recogito/text-annotator/dist/text-annotator.css';

Expand All @@ -12,7 +12,7 @@ export type TEIAnnotatorProps = TextAnnotatorOptions & {

filter?: Filter;

style?: DrawingStyle | ((annotation: TextAnnotation) => DrawingStyle);
style?: HighlightStyleExpression

}

Expand Down Expand Up @@ -48,4 +48,4 @@ export const TEIAnnotator = (props: TEIAnnotatorProps) => {
</>
) : null;

}
}
15 changes: 7 additions & 8 deletions packages/text-annotator-react/vite.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export default defineConfig(({ command, mode }) => ({
open: '/test/index.html'
},
build: {
minify: false,
lib: {
entry: './src/index.ts',
name: 'ReactTextAnnotator',
Expand All @@ -26,17 +27,15 @@ export default defineConfig(({ command, mode }) => ({
},
rollupOptions: {
external: [
...Object.keys(packageJson.peerDependencies)
...Object.keys(packageJson.peerDependencies),
"@annotorious/core",
"@annotorious/react",
"@recogito/text-annotator",
"@recogito/text-annotator-tei"
],
output: {
preserveModules: true,
assetFileNames: 'react-text-annotator.[ext]',
globals: {
'@annotorious/react': 'AnnotoriousReact',
'openseadragon': 'OpenSeadragon',
'react': 'React',
'react-dom': 'ReactDOM'
}
assetFileNames: 'react-text-annotator.[ext]'
}
},
sourcemap: true
Expand Down
13 changes: 7 additions & 6 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.18",
"version": "3.0.0-rc.21",
"description": "A JavaScript text annotation library",
"author": "Rainer Simon",
"license": "BSD-3-Clause",
Expand Down Expand Up @@ -31,15 +31,16 @@
"@types/uuid": "^9.0.8",
"jsdom": "^24.0.0",
"svelte": "^4.2.12",
"typescript": "^5.3.3",
"vite": "^5.2.6",
"vite-plugin-dts": "^3.7.3",
"typescript": "^5.4.3",
"vite": "^5.2.7",
"vite-plugin-dts": "^3.8.1",
"vitest": "^1.4.0"
},
"dependencies": {
"@annotorious/core": "^3.0.0-rc.21",
"@annotorious/core": "^3.0.0-rc.22",
"colord": "^2.9.3",
"dequal": "^2.0.3",
"rbush": "^3.0.1",
"uuid": "^9.0.1"
}
}
}
47 changes: 31 additions & 16 deletions packages/text-annotator/src/TextAnnotator.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
import { createAnonymousGuest, createLifecyleObserver, createBaseAnnotator, DrawingStyle, Filter, createUndoStack } from '@annotorious/core';
import { createAnonymousGuest, createLifecyleObserver, createBaseAnnotator, Filter, createUndoStack } from '@annotorious/core';
import type { Annotator, User, PresenceProvider } from '@annotorious/core';
import { createCanvasHighlightRenderer, createCSSHighlightRenderer } from './highlight';
import { createCanvasRenderer, createHighlightsRenderer, createSpansRenderer, type HighlightStyleExpression } from './highlight';
import { createPresencePainter } from './presence';
import { scrollIntoView } from './api';
import { TextAnnotationStore, TextAnnotatorState, createTextAnnotatorState } from './state';
import type { TextAnnotation } from './model';
import type { TextAnnotatorOptions } from './TextAnnotatorOptions';
import type { RendererType, TextAnnotatorOptions } from './TextAnnotatorOptions';
import { SelectionHandler } from './SelectionHandler';

import './TextAnnotator.css';


const USE_DEFAULT_RENDERER: RendererType = 'SPANS';

export interface TextAnnotator<E extends unknown = TextAnnotation> extends Annotator<TextAnnotation, E> {

element: HTMLElement;

setStyle(style: HighlightStyleExpression | undefined): void;

// Returns true if successful (or false if the annotation is not currently rendered)
scrollIntoView(annotation: TextAnnotation): boolean;

Expand Down Expand Up @@ -42,20 +47,26 @@ export const createTextAnnotator = <E extends unknown = TextAnnotation>(

let currentUser: User = createAnonymousGuest();

// Switch on CSS Custom Highlight rendering, if requested in the init
// opts and API is available in this browser
// @ts-ignore
const useExperimentalCSSRenderer = opts.experimentalCSSRenderer && Boolean(CSS.highlights);
// Use selected renderer, or fall back to default. If CSS_HIGHLIGHT is
// requested, check if CSS Custom Highlights are supported, and fall
// back to default renderer if not.
const useRenderer: RendererType =
opts.renderer === 'CSS_HIGHLIGHTS'
? Boolean(CSS.highlights) ? 'CSS_HIGHLIGHTS' : USE_DEFAULT_RENDERER
: opts.renderer || USE_DEFAULT_RENDERER;

if (useExperimentalCSSRenderer)
console.log('Using experimental CSS Custom Highlight API renderer');
const highlightRenderer =
useRenderer === 'SPANS' ? createSpansRenderer(container, state, viewport) :
useRenderer === 'CSS_HIGHLIGHTS' ? createHighlightsRenderer(container, state, viewport) :
useRenderer === 'CANVAS' ? createCanvasRenderer(container, state, viewport) : undefined;

const highlightRenderer = useExperimentalCSSRenderer
? createCSSHighlightRenderer(container, state, viewport)
: createCanvasHighlightRenderer(container, state, viewport);
if (!highlightRenderer)
throw `Unknown renderer implementation: ${useRenderer}`;

console.debug(`Using ${useRenderer} renderer`);

if (opts.style)
highlightRenderer.setDrawingStyle(opts.style);
highlightRenderer.setStyle(opts.style);

const selectionHandler = SelectionHandler(container, state, opts.offsetReferenceSelector);

Expand All @@ -73,8 +84,8 @@ export const createTextAnnotator = <E extends unknown = TextAnnotation>(
const setFilter = (filter?: Filter) =>
highlightRenderer.setFilter(filter);

const setStyle = (drawingStyle: DrawingStyle | ((annotation: TextAnnotation) => DrawingStyle) | undefined) =>
highlightRenderer.setDrawingStyle(drawingStyle);
const setStyle = (style: HighlightStyleExpression | undefined) =>
highlightRenderer.setStyle(style);

const setUser = (user: User) => {
currentUser = user;
Expand All @@ -84,7 +95,7 @@ export const createTextAnnotator = <E extends unknown = TextAnnotation>(
const setPresenceProvider = (provider: PresenceProvider) => {
if (provider) {
highlightRenderer.setPainter(createPresencePainter(container, provider, opts.presence));
provider.on('selectionChange', () => highlightRenderer.refresh());
provider.on('selectionChange', () => highlightRenderer.redraw());
}
}

Expand All @@ -96,6 +107,9 @@ export const createTextAnnotator = <E extends unknown = TextAnnotation>(
}
}

const setVisible = (visible: boolean) =>
highlightRenderer.setVisible(visible);

const destroy = () => {
highlightRenderer.destroy();
selectionHandler.destroy();
Expand All @@ -114,6 +128,7 @@ export const createTextAnnotator = <E extends unknown = TextAnnotation>(
setUser,
setSelected,
setPresenceProvider,
setVisible,
on: lifecycle.on,
off: lifecycle.off,
scrollIntoView: scrollIntoView(container, store),
Expand Down
9 changes: 6 additions & 3 deletions packages/text-annotator/src/TextAnnotatorOptions.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
import type { DrawingStyle, FormatAdapter, PointerSelectAction } from '@annotorious/core';
import type { FormatAdapter, PointerSelectAction } from '@annotorious/core';
import type { PresencePainterOptions } from './presence';
import type { TextAnnotation } from './model';
import type { HighlightStyleExpression } from './highlight';

export interface TextAnnotatorOptions<T extends unknown = TextAnnotation> {

adapter?: FormatAdapter<TextAnnotation, T> | null;

experimentalCSSRenderer?: boolean;
renderer?: RendererType;

offsetReferenceSelector?: string;

pointerAction?: PointerSelectAction | ((annotation: TextAnnotation) => PointerSelectAction);

presence?: PresencePainterOptions;

style?: DrawingStyle | ((annotation: TextAnnotation) => DrawingStyle);
style?: HighlightStyleExpression;

}

export type RendererType = 'SPANS' | 'CANVAS' | 'CSS_HIGHLIGHTS';
8 changes: 8 additions & 0 deletions packages/text-annotator/src/highlight/Highlight.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import type { AnnotationState } from '@annotorious/core';
import type { AnnotationRects } from '../state';

export interface Highlight extends AnnotationRects {

state: AnnotationState;

}
32 changes: 25 additions & 7 deletions packages/text-annotator/src/highlight/HighlightPainter.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import type { AnnotationRects } from '../state';
import type { HighlightStyle } from './HighlightStyle';

import type { Highlight } from './Highlight';
import { DEFAULT_SELECTED_STYLE, DEFAULT_STYLE } from './HighlightStyle';
import type { HighlightStyle, HighlightStyleExpression } from './HighlightStyle';
import type { ViewportBounds } from './viewport';

export interface HighlightPainter {
Expand All @@ -8,12 +10,28 @@ export interface HighlightPainter {

destroy(): void;

paint(
annotation: AnnotationRects,
viewportBounds: ViewportBounds,
isSelected?: boolean
): HighlightStyle;
paint(highlight: Highlight, viewportBounds: ViewportBounds): HighlightStyle;

reset(): void;

}

/** Helper **/
export const paint = (
highlight: Highlight,
viewportBounds: ViewportBounds,
style?: HighlightStyleExpression,
painter?: HighlightPainter,
zIndex?: number
) => {
const base: HighlightStyle = style
? typeof style === 'function'
? style(highlight.annotation, highlight.state, zIndex)
: style
: highlight.state?.selected
? DEFAULT_SELECTED_STYLE
: DEFAULT_STYLE;

// Trigger the custom painter (if any) as a side-effect
return painter ? painter.paint(highlight, viewportBounds) || base : base;
}
Loading

0 comments on commit 3647e9e

Please sign in to comment.