From 783a85fe5e790890b73b5630cc5c9c6186ae47a1 Mon Sep 17 00:00:00 2001 From: Sai Asish Y Date: Mon, 20 Jul 2026 14:20:41 -0700 Subject: [PATCH] fix(ui): remove blocks holder listeners and detach it on destroy Signed-off-by: Sai Asish Y --- packages/ui/src/Blocks/Blocks.ts | 20 ++++++++++++++++++-- packages/ui/src/index.ts | 2 +- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/packages/ui/src/Blocks/Blocks.ts b/packages/ui/src/Blocks/Blocks.ts index 7e6313ea..b70a2cdb 100644 --- a/packages/ui/src/Blocks/Blocks.ts +++ b/packages/ui/src/Blocks/Blocks.ts @@ -47,6 +47,12 @@ export class BlocksUI implements EditorjsPlugin { */ #api: EditorAPI; + /** + * Controls the lifetime of the DOM listeners attached to the blocks holder + * so they can all be removed at once on destroy() + */ + #listenersController = new AbortController(); + /** * EditorUI constructor method * @param params - Plugin parameters @@ -114,7 +120,7 @@ export class BlocksUI implements EditorjsPlugin { targetRanges: e.getTargetRanges(), isCrossInputSelection, })); - }); + }, { signal: this.#listenersController.signal }); blocksHolder.addEventListener('keydown', (e) => { if (e.code !== 'KeyZ') { @@ -136,7 +142,7 @@ export class BlocksUI implements EditorjsPlugin { this.#api.document.undo(); e.preventDefault(); - }); + }, { signal: this.#listenersController.signal }); return blocksHolder; } @@ -223,5 +229,15 @@ export class BlocksUI implements EditorjsPlugin { public destroy(): void { this.#blocks.forEach(block => block.remove()); this.#blocks = []; + + /** + * Removes the beforeinput/keydown listeners attached to the blocks holder + */ + this.#listenersController.abort(); + + /** + * Detach the blocks holder itself so it doesn't linger in the DOM + */ + this.#blocksHolder.remove(); } } diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts index bc13c213..ee62801e 100644 --- a/packages/ui/src/index.ts +++ b/packages/ui/src/index.ts @@ -72,7 +72,7 @@ export class EditorjsUI implements EditorjsPlugin { * Method to destroy the plugin */ public destroy(): void { - // Cleanup if needed + this.#editorWrapper.remove(); } /**