From e6ef046e4150aeb8a49f3a1784bb81348d130bac Mon Sep 17 00:00:00 2001 From: Oleksandr Danylchenko Date: Wed, 28 Aug 2024 19:05:47 +0300 Subject: [PATCH] Added cleanable `debounce` function --- package-lock.json | 13 +++++++++++++ packages/text-annotator/package.json | 3 ++- packages/text-annotator/src/SelectionHandler.ts | 16 +++++++++++----- .../text-annotator/src/highlight/baseRenderer.ts | 4 +++- .../src/highlight/canvas/canvasRenderer.ts | 8 ++++---- packages/text-annotator/src/utils/debounce.ts | 8 -------- packages/text-annotator/src/utils/index.ts | 1 - 7 files changed, 33 insertions(+), 20 deletions(-) delete mode 100644 packages/text-annotator/src/utils/debounce.ts diff --git a/package-lock.json b/package-lock.json index 1530d74c..c07a4675 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2367,6 +2367,18 @@ "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==", "dev": true }, + "node_modules/debounce": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-2.1.0.tgz", + "integrity": "sha512-OkL3+0pPWCqoBc/nhO9u6TIQNTK44fnBnzuVtJAbp13Naxw9R6u21x+8tVTka87AhDZ3htqZ2pSSsZl9fqL2Wg==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/debug": { "version": "4.3.6", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", @@ -4370,6 +4382,7 @@ "dependencies": { "@annotorious/core": "^3.0.0-rc.31", "colord": "^2.9.3", + "debounce": "^2.1.0", "dequal": "^2.0.3", "rbush": "^4.0.0", "uuid": "^10.0.0" diff --git a/packages/text-annotator/package.json b/packages/text-annotator/package.json index 81cb5be9..bcb99787 100644 --- a/packages/text-annotator/package.json +++ b/packages/text-annotator/package.json @@ -39,8 +39,9 @@ "dependencies": { "@annotorious/core": "^3.0.0-rc.31", "colord": "^2.9.3", + "debounce": "^2.1.0", "dequal": "^2.0.3", "rbush": "^4.0.0", "uuid": "^10.0.0" } -} \ No newline at end of file +} diff --git a/packages/text-annotator/src/SelectionHandler.ts b/packages/text-annotator/src/SelectionHandler.ts index 429e0365..2027fc4d 100644 --- a/packages/text-annotator/src/SelectionHandler.ts +++ b/packages/text-annotator/src/SelectionHandler.ts @@ -1,9 +1,10 @@ import { Filter, Origin, type User } from '@annotorious/core'; import { v4 as uuidv4 } from 'uuid'; +import debounce from 'debounce'; + import type { TextAnnotatorState } from './state'; import type { TextAnnotationTarget } from './model'; import { - debounce, splitAnnotatableRanges, rangeToSelector, isWhitespaceOrEmpty, @@ -82,13 +83,13 @@ export const createSelectionHandler = ( const selectionRange = sel.getRangeAt(0); if (isWhitespaceOrEmpty(selectionRange)) return; - + const annotatableRanges = splitAnnotatableRanges(selectionRange.cloneRange()); const hasChanged = annotatableRanges.length !== currentTarget.selector.length || annotatableRanges.some((r, i) => r.toString() !== currentTarget.selector[i]?.quote); - + if (!hasChanged) return; currentTarget = { @@ -102,7 +103,7 @@ export const createSelectionHandler = ( } else { // Proper lifecycle management: clear selection first... selection.clear(); - + // ...then add annotation to store... store.addAnnotation({ id: currentTarget.annotation, @@ -165,9 +166,14 @@ export const createSelectionHandler = ( document.addEventListener('pointerup', onPointerUp); const destroy = () => { + currentTarget = undefined; + lastPointerDown = undefined; + + onSelectionChange.clear(); + container.removeEventListener('selectstart', onSelectStart); document.removeEventListener('selectionchange', onSelectionChange); - + container.removeEventListener('pointerdown', onPointerDown); document.removeEventListener('pointerup', onPointerUp); } diff --git a/packages/text-annotator/src/highlight/baseRenderer.ts b/packages/text-annotator/src/highlight/baseRenderer.ts index 3698c4dd..d4fde630 100644 --- a/packages/text-annotator/src/highlight/baseRenderer.ts +++ b/packages/text-annotator/src/highlight/baseRenderer.ts @@ -1,6 +1,7 @@ +import debounce from 'debounce'; import type { Filter, ViewportState } from '@annotorious/core'; + import type { TextAnnotatorState } from '../state'; -import { debounce } from '../utils'; import { ViewportBounds, getViewportBounds, trackViewport } from './viewport'; import type { HighlightPainter } from './HighlightPainter'; import type { Highlight } from './Highlight'; @@ -169,6 +170,7 @@ export const createBaseRenderer = ( document.removeEventListener('scroll', onScroll); + onResize.clear(); window.removeEventListener('resize', onResize); resizeObserver.disconnect(); diff --git a/packages/text-annotator/src/highlight/canvas/canvasRenderer.ts b/packages/text-annotator/src/highlight/canvas/canvasRenderer.ts index 76237351..3927200b 100644 --- a/packages/text-annotator/src/highlight/canvas/canvasRenderer.ts +++ b/packages/text-annotator/src/highlight/canvas/canvasRenderer.ts @@ -1,6 +1,7 @@ +import debounce from 'debounce'; import type { ViewportState } from '@annotorious/core'; + import type { TextAnnotatorState } from '../../state'; -import { debounce } from '../../utils'; import type { ViewportBounds } from '../viewport'; import type { HighlightStyle } from '../HighlightStyle'; import { DEFAULT_SELECTED_STYLE, DEFAULT_STYLE, HighlightStyleExpression } from '../HighlightStyle'; @@ -116,9 +117,7 @@ const createRenderer = (container: HTMLElement): RendererImplementation => { }); }); - const onResize = debounce(() => { - resetCanvas(canvas); - }); + const onResize = debounce(() => resetCanvas(canvas)); window.addEventListener('resize', onResize); @@ -129,6 +128,7 @@ const createRenderer = (container: HTMLElement): RendererImplementation => { const destroy = () => { canvas.remove(); + onResize.clear(); window.removeEventListener('resize', onResize); } diff --git a/packages/text-annotator/src/utils/debounce.ts b/packages/text-annotator/src/utils/debounce.ts deleted file mode 100644 index c20a566c..00000000 --- a/packages/text-annotator/src/utils/debounce.ts +++ /dev/null @@ -1,8 +0,0 @@ -export const debounce = void>(func: T, delay = 10): T => { - let timeoutId: ReturnType; - - return ((...args: any[]) => { - clearTimeout(timeoutId); - timeoutId = setTimeout(() => func.apply(this, args), delay); - }) as T; -} diff --git a/packages/text-annotator/src/utils/index.ts b/packages/text-annotator/src/utils/index.ts index e8b379d8..77d41b8d 100644 --- a/packages/text-annotator/src/utils/index.ts +++ b/packages/text-annotator/src/utils/index.ts @@ -1,5 +1,4 @@ export * from './cancelSingleClickEvents'; -export * from './debounce'; export * from './getAnnotatableFragment'; export * from './getClientRectsPonyfill'; export * from './getQuoteContext';