Compare commits

..

No commits in common. "429ec419cff309b1e61a98aee494b600dfe10fed" and "59d52ce5daddb1d176e65b58dae39fd8c3f9f4d1" have entirely different histories.

2 changed files with 8 additions and 19 deletions

View File

@ -16,7 +16,6 @@ class BackupPage {
this.taskManager = (typeof TaskManager !== 'undefined') ? new TaskManager() : null;
this.eventBound = false;
this._taskRefreshTimer = null;
this._ac = new AbortController(); // dispose() aborts this to remove the document listeners on unmount
}
async init() {
@ -295,13 +294,13 @@ class BackupPage {
this.saveSection(saveBtn.dataset.backupSave);
return;
}
}, { signal: this._ac.signal });
});
document.addEventListener('input', (e) => {
if (e.target.id === 'backup-snapshot-filter' || e.target.id === 'backup-snapshot-repo') {
this.renderSnapshots();
}
}, { signal: this._ac.signal });
});
// Type select changes refresh the visible connection fields inline.
// Retention preset changes are handled by applyRetentionPreset, which
@ -324,17 +323,7 @@ class BackupPage {
if (presetSel) {
this.applyRetentionPreset(presetSel);
}
}, { signal: this._ac.signal });
}
/* Release everything this page attached to document/window so navigating
away (kernel unmount) can't leave stale listeners firing on the live DOM
the cause of the backup sidebar "content stacks on revisit" bug. Called by
the feature module's unmount(). */
dispose() {
try { this._ac && this._ac.abort(); } catch (_) {}
try { window.taskRefresh && window.taskRefresh.unregister('backups'); } catch (_) {}
if (this._taskRefreshTimer) { clearTimeout(this._taskRefreshTimer); this._taskRefreshTimer = null; }
});
}

View File

@ -46,11 +46,11 @@ LP.features.register({
},
async unmount(ctx) {
// Release the page's document listeners + task-refresh registration so a
// navigation away doesn't leave stale BackupPage listeners firing on the
// live DOM — the backup sidebar "content stacks on revisit" bug. dispose()
// aborts the click/input/change listeners and drops the coordinator reg.
try { window.backupPage && window.backupPage.dispose(); } catch (_) {}
// Best-effort teardown. BackupPage self-guards stale work via
// (window.backupPage === this), so nulling the global neutralises any
// pending task-refresh repaint; we also drop its coordinator registration.
// A proper dispose() (removing the leaked document listeners) lands with
// the Phase 5 backup decomposition.
try { ctx.services.tasks.refresh && ctx.services.tasks.refresh.unregister('backups'); } catch (_) {}
window.backupPage = null;
},