From 8417eee0c191b64b89db4b1105aabd3db182e507 Mon Sep 17 00:00:00 2001 From: Calixte Denizet Date: Wed, 27 Sep 2023 22:10:32 +0200 Subject: [PATCH] [Editor] Clear the different timeouts when destroying --- src/display/editor/annotation_editor_layer.js | 19 +++++++++-------- src/display/editor/ink.js | 13 +++++++++++- src/display/editor/stamp.js | 4 ++++ src/display/editor/tools.js | 21 +++++++++++++++++++ 4 files changed, 47 insertions(+), 10 deletions(-) diff --git a/src/display/editor/annotation_editor_layer.js b/src/display/editor/annotation_editor_layer.js index ef2cb1ecd..aa3acc4bf 100644 --- a/src/display/editor/annotation_editor_layer.js +++ b/src/display/editor/annotation_editor_layer.js @@ -61,6 +61,8 @@ class AnnotationEditorLayer { #boundPointerdown = this.pointerdown.bind(this); + #editorFocusTimeoutId = null; + #editors = new Map(); #hadPointerDown = false; @@ -329,13 +331,6 @@ class AnnotationEditorLayer { this.detach(editor); this.#uiManager.removeEditor(editor); - if (editor.div.contains(document.activeElement)) { - setTimeout(() => { - // When the div is removed from DOM the focus can move on the - // document.body, so we need to move it back to the main container. - this.#uiManager.focusMainContainer(); - }, 0); - } editor.div.remove(); editor.isAttachedToDOM = false; @@ -396,13 +391,14 @@ class AnnotationEditorLayer { } const { activeElement } = document; - if (editor.div.contains(activeElement)) { + if (editor.div.contains(activeElement) && !this.#editorFocusTimeoutId) { // When the div is moved in the DOM the focus can move somewhere else, // so we want to be sure that the focus will stay on the editor but we // don't want to call any focus callbacks, hence we disable them and only // re-enable them when the editor has the focus. editor._focusEventsAllowed = false; - setTimeout(() => { + this.#editorFocusTimeoutId = setTimeout(() => { + this.#editorFocusTimeoutId = null; if (!editor.div.contains(document.activeElement)) { editor.div.addEventListener( "focusin", @@ -683,6 +679,11 @@ class AnnotationEditorLayer { this.#uiManager.setActiveEditor(null); } + if (this.#editorFocusTimeoutId) { + clearTimeout(this.#editorFocusTimeoutId); + this.#editorFocusTimeoutId = null; + } + for (const editor of this.#editors.values()) { this.#accessibilityManager?.removePointerInTextLayer(editor.contentDiv); editor.setParent(null); diff --git a/src/display/editor/ink.js b/src/display/editor/ink.js index 9194a9564..0e3c43821 100644 --- a/src/display/editor/ink.js +++ b/src/display/editor/ink.js @@ -39,6 +39,8 @@ class InkEditor extends AnnotationEditor { #boundCanvasPointerdown = this.canvasPointerdown.bind(this); + #canvasContextMenuTimeoutId = null; + #currentPath2D = new Path2D(); #disableEditing = false; @@ -259,6 +261,11 @@ class InkEditor extends AnnotationEditor { this.canvas.remove(); this.canvas = null; + if (this.#canvasContextMenuTimeoutId) { + clearTimeout(this.#canvasContextMenuTimeoutId); + this.#canvasContextMenuTimeoutId = null; + } + this.#observer.disconnect(); this.#observer = null; @@ -706,7 +713,11 @@ class InkEditor extends AnnotationEditor { // Slight delay to avoid the context menu to appear (it can happen on a long // tap with a pen). - setTimeout(() => { + if (this.#canvasContextMenuTimeoutId) { + clearTimeout(this.#canvasContextMenuTimeoutId); + } + this.#canvasContextMenuTimeoutId = setTimeout(() => { + this.#canvasContextMenuTimeoutId = null; this.canvas.removeEventListener("contextmenu", noContextMenu); }, 10); diff --git a/src/display/editor/stamp.js b/src/display/editor/stamp.js index 94f15136d..9974527f9 100644 --- a/src/display/editor/stamp.js +++ b/src/display/editor/stamp.js @@ -190,6 +190,10 @@ class StampEditor extends AnnotationEditor { this.#canvas = null; this.#observer?.disconnect(); this.#observer = null; + if (this.#resizeTimeoutId) { + clearTimeout(this.#resizeTimeoutId); + this.#resizeTimeoutId = null; + } } super.remove(); } diff --git a/src/display/editor/tools.js b/src/display/editor/tools.js index ed8b2e0bd..b631e9798 100644 --- a/src/display/editor/tools.js +++ b/src/display/editor/tools.js @@ -543,6 +543,8 @@ class AnnotationEditorUIManager { #filterFactory = null; + #focusMainContainerTimeoutId = null; + #idManager = new IdManager(); #isEnabled = false; @@ -735,6 +737,14 @@ class AnnotationEditorUIManager { this.#selectedEditors.clear(); this.#commandManager.destroy(); this.#altTextManager.destroy(); + if (this.#focusMainContainerTimeoutId) { + clearTimeout(this.#focusMainContainerTimeoutId); + this.#focusMainContainerTimeoutId = null; + } + if (this.#translationTimeoutId) { + clearTimeout(this.#translationTimeoutId); + this.#translationTimeoutId = null; + } } get hcmFilter() { @@ -1281,6 +1291,17 @@ class AnnotationEditorUIManager { * @param {AnnotationEditor} editor */ removeEditor(editor) { + if (editor.div.contains(document.activeElement)) { + if (this.#focusMainContainerTimeoutId) { + clearTimeout(this.#focusMainContainerTimeoutId); + } + this.#focusMainContainerTimeoutId = setTimeout(() => { + // When the div is removed from DOM the focus can move on the + // document.body, so we need to move it back to the main container. + this.focusMainContainer(); + this.#focusMainContainerTimeoutId = null; + }, 0); + } this.#allEditors.delete(editor.id); this.unselect(editor); if (