mirror of
https://github.com/Kpa-clawbot/meshcore-analyzer.git
synced 2026-06-10 09:21:38 +00:00
refactor(live): dedupe _liveTestSeams and consolidate destroy() (#1514 S4+S8)
S4 — window._liveTestSeams was defined in two places. The earlier block (near the test-seam exposure for #1207) wires wake -> wakeCanvasEngine which respects the pause/empty-queue guards. The trailing block at the bottom of the IIFE installed a separate wake that bypassed those guards, so a test could wake an empty engine and burn rAF cycles on nothing. Delete the trailing block; single source of truth at the earlier site. S8 — destroy() had two cleanup blocks: one at the top (animation flags + stopReplay) and a duplicate at the bottom (canvas DOM + DPR MQL). Functionally harmless but confusing. Consolidate into one ordered teardown: drain animations -> stop loops -> cancel timers/WS -> tear down canvas+DPR before nulling map -> reset module state. Documented inline why the canvas teardown must precede map.remove(). Refs #1514
This commit is contained in:
+22
-24
@@ -4043,6 +4043,23 @@
|
||||
regionFilterChangeHandler = null;
|
||||
}
|
||||
if (map) { map.remove(); map = null; }
|
||||
// #1514 S8 — canvas teardown moved up here from a duplicate trailing block.
|
||||
// Order matters: clear+detach the canvas BEFORE we null out the map (which
|
||||
// already removed our pane) so we don't call clearRect on a context whose
|
||||
// backing pane is gone. Also drop the DPR MQL listener so a late
|
||||
// resolution change after destroy() can't fire updateAnimCanvas() against
|
||||
// a null map.
|
||||
if (animCtx && animCanvas) {
|
||||
try { animCtx.clearRect(0, 0, animCanvas.clientWidth, animCanvas.clientHeight); } catch (_) {}
|
||||
animCanvas.remove();
|
||||
animCanvas = null;
|
||||
animCtx = null;
|
||||
}
|
||||
if (_dprMedia && _dprChangeHandler) {
|
||||
try { _dprMedia.removeEventListener('change', _dprChangeHandler); } catch (_) {}
|
||||
_dprMedia = null;
|
||||
_dprChangeHandler = null;
|
||||
}
|
||||
if (_onResize) {
|
||||
window.removeEventListener('resize', _onResize);
|
||||
window.removeEventListener('orientationchange', _onResize);
|
||||
@@ -4076,23 +4093,6 @@
|
||||
nodeActivity = {}; pktTimestamps = [];
|
||||
feedDedup.clear();
|
||||
VCR.buffer = []; VCR.playhead = -1; VCR.mode = 'LIVE'; VCR.missedCount = 0; VCR.speed = _initialSpeed; VCR.replayGen = 0;
|
||||
|
||||
// CLEANUP: Kill the canvas loop, dump the queue, and clear the screen
|
||||
activeAnimations.length = 0;
|
||||
activeFades.length = 0;
|
||||
isAnimating = false;
|
||||
isFading = false;
|
||||
if (animCtx && animCanvas) {
|
||||
animCtx.clearRect(0, 0, animCanvas.clientWidth, animCanvas.clientHeight);
|
||||
animCanvas.remove();
|
||||
animCanvas = null;
|
||||
animCtx = null;
|
||||
}
|
||||
if (_dprMedia && _dprChangeHandler) {
|
||||
_dprMedia.removeEventListener('change', _dprChangeHandler);
|
||||
_dprMedia = null;
|
||||
_dprChangeHandler = null;
|
||||
}
|
||||
}
|
||||
|
||||
let _themeRefreshHandler = null;
|
||||
@@ -4104,13 +4104,11 @@
|
||||
// across re-mounts. window.__liveMQLBindCount is a debug seam consumed by
|
||||
// test-live-mql-leak-1180-e2e.js and otherwise unused.
|
||||
var _liveNarrowMqlBound = false;
|
||||
window._liveTestSeams = window._liveTestSeams || {};
|
||||
window._liveTestSeams.wake = function() {
|
||||
if (!isAnimating) {
|
||||
isAnimating = true;
|
||||
requestAnimationFrame(renderAnimations);
|
||||
}
|
||||
};
|
||||
// #1514 S4 — single source of truth for window._liveTestSeams is at the
|
||||
// earlier exposure block (search for `window._liveTestSeams = {`). The
|
||||
// duplicate definition that lived here previously added a `_liveTestSeams.wake`
|
||||
// that bypassed pause/empty-queue guards; tests must use the production
|
||||
// `wakeCanvasEngine` exposed there.
|
||||
|
||||
registerPage('live', {
|
||||
init: function(app, routeParam) {
|
||||
|
||||
Reference in New Issue
Block a user