From c755d8914bc21a77634e4aa67ebaea1828bdc11a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemek=20Wi=C4=99ch?= Date: Wed, 10 Jun 2026 17:31:26 +0200 Subject: [PATCH] Clean up event listener in EmbeddedDataSource --- src/datasource/embedded.ts | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/datasource/embedded.ts b/src/datasource/embedded.ts index c93f2db..406d231 100644 --- a/src/datasource/embedded.ts +++ b/src/datasource/embedded.ts @@ -33,6 +33,8 @@ export interface EmbeddedSourceSpec { /** GEDCOM file received from outside of the iframe. */ export class EmbeddedDataSource implements DataSource { + private activeListener?: (event: MessageEvent) => void; + isNewData( _newSource: SourceSelection, _oldSource: SourceSelection, @@ -76,20 +78,32 @@ export class EmbeddedDataSource implements DataSource { _source: SourceSelection, onProgress?: (status: string) => void, ): Promise { + if (this.activeListener) { + window.removeEventListener('message', this.activeListener); + this.activeListener = undefined; + } + // Notify the parent window that we are ready. return new Promise((resolve, reject) => { // Remove the listener once the GEDCOM arrives (resolve) or an error // occurs (reject) to prevent it from accumulating across loadData calls. const wrappedResolve = (value: TopolaData) => { - window.removeEventListener('message', listener); + if (this.activeListener === listener) { + window.removeEventListener('message', listener); + this.activeListener = undefined; + } resolve(value); }; const wrappedReject = (reason: unknown) => { - window.removeEventListener('message', listener); + if (this.activeListener === listener) { + window.removeEventListener('message', listener); + this.activeListener = undefined; + } reject(reason); }; const listener = (event: MessageEvent) => this.onMessage(event.data, wrappedResolve, wrappedReject, onProgress); + this.activeListener = listener; window.parent.postMessage({message: EmbeddedMessageType.READY}, '*'); window.addEventListener('message', listener); });