mirror of
https://github.com/Kpa-clawbot/meshcore-analyzer.git
synced 2026-10-23 14:32:36 +00:00
fix(live): replace fragile DPR listener self-rebind with race-free pattern (#1514 M1)
The previous DPR change handler removed and re-added itself inside a
try/finally block. Two problems:
1. A throw inside updateAnimCanvas() would still trigger the re-bind, but
leave the canvas in a half-resized state.
2. The remove → matchMedia() → add sequence is not atomic; a synchronous
DPR change between remove and add would be silently dropped.
Switch to addEventListener with {once: true}: the runtime drops the
listener atomically before our handler runs, so re-binding is race-free
and a thrown updateAnimCanvas() doesn't double-bind.
Refs #1514
This commit is contained in:
1 parent
976ccf6db5
commit
0d32f06300
1 file changed
+20
-12
+20
-12
@@ -1258,19 +1258,27 @@
|
|||||||
map.on('moveend zoomend resize', updateAnimCanvas);
|
map.on('moveend zoomend resize', updateAnimCanvas);
|
||||||
updateAnimCanvas();
|
updateAnimCanvas();
|
||||||
|
|
||||||
_dprChangeHandler = () => {
|
// #1514 M1+S10 — DPR change handling.
|
||||||
try {
|
//
|
||||||
updateAnimCanvas();
|
// matchMedia(`(resolution: ${dpr}dppx)`) is a STRICT-MATCH query: it only
|
||||||
} finally {
|
// fires when the current DPR stops matching. After it fires, we must rebind
|
||||||
if (_dprMedia) {
|
// a new MQL keyed to the new DPR. Older code did remove → re-add inside a
|
||||||
_dprMedia.removeEventListener('change', _dprChangeHandler);
|
// try/finally which was fragile (a throw in updateAnimCanvas would still
|
||||||
}
|
// re-bind, and a synchronous re-entry between remove and add could lose
|
||||||
_dprMedia = window.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`);
|
// the handler). The {once: true} pattern below removes the listener
|
||||||
_dprMedia.addEventListener('change', _dprChangeHandler);
|
// atomically before our handler runs, so re-binding is race-free.
|
||||||
|
function _rebindDPRListener() {
|
||||||
|
if (_dprMedia && _dprChangeHandler) {
|
||||||
|
try { _dprMedia.removeEventListener('change', _dprChangeHandler); } catch (_) {}
|
||||||
}
|
}
|
||||||
};
|
_dprMedia = window.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`);
|
||||||
_dprMedia = window.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`);
|
_dprChangeHandler = () => {
|
||||||
_dprMedia.addEventListener('change', _dprChangeHandler);
|
updateAnimCanvas();
|
||||||
|
_rebindDPRListener();
|
||||||
|
};
|
||||||
|
_dprMedia.addEventListener('change', _dprChangeHandler, { once: true });
|
||||||
|
}
|
||||||
|
_rebindDPRListener();
|
||||||
|
|
||||||
const isDark = document.documentElement.getAttribute('data-theme') === 'dark' ||
|
const isDark = document.documentElement.getAttribute('data-theme') === 'dark' ||
|
||||||
(document.documentElement.getAttribute('data-theme') !== 'light' && window.matchMedia('(prefers-color-scheme: dark)').matches);
|
(document.documentElement.getAttribute('data-theme') !== 'light' && window.matchMedia('(prefers-color-scheme: dark)').matches);
|
||||||
|
|||||||
Reference in new issue
Block a user