From bcdcca01a5dc2c2aaafd0d6c67ee28826ed8a460 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Thu, 14 May 2026 12:22:52 +0300 Subject: [PATCH] =?UTF-8?q?fix(graph):=20T1=20hardening=20=E2=80=94=20loca?= =?UTF-8?q?lStorage=20try/catch=20+=20rAF=20throttle=20on=20redraw?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit После T1 code-quality review: 2 Important issues из spec §9 mitigation list. (1) try/catch обернул read/write localStorage — в Edge InPrivate / quota-exceeded не падает, fallback на default 300. (2) network.redraw() rAF-throttled через redrawScheduled flag — устраняет potential jank при fast drag на медленном hardware (mousemove может fire'ить >60Hz). Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/automation-graph.html | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/docs/automation-graph.html b/docs/automation-graph.html index 05f1d23f..9b34bcbb 100644 --- a/docs/automation-graph.html +++ b/docs/automation-graph.html @@ -1200,16 +1200,26 @@ document.getElementById('btn-clear').addEventListener('click', () => { const LEGEND_STORAGE_KEY = 'liderra-map-legend-width'; const LEGEND_MIN_W = 300, LEGEND_MAX_W = 900; +let redrawScheduled = false; function applyLegendWidth(w) { const clamped = Math.max(LEGEND_MIN_W, Math.min(LEGEND_MAX_W, w)); const panel = document.getElementById('legend-panel'); panel.style.width = clamped + 'px'; panel.style.minWidth = clamped + 'px'; - if (typeof network !== 'undefined' && network) network.redraw(); + if (typeof network !== 'undefined' && network && !redrawScheduled) { + redrawScheduled = true; + requestAnimationFrame(() => { + redrawScheduled = false; + network.redraw(); + }); + } } function restoreLegendWidth() { - const saved = parseInt(localStorage.getItem(LEGEND_STORAGE_KEY) || '300', 10); + let saved = 300; + try { + saved = parseInt(localStorage.getItem(LEGEND_STORAGE_KEY) || '300', 10); + } catch (e) { /* private mode or quota — keep default */ } applyLegendWidth(saved); } @@ -1234,7 +1244,7 @@ function restoreLegendWidth() { handle.classList.remove('dragging'); document.body.style.userSelect = ''; const w = parseInt(document.getElementById('legend-panel').style.width, 10); - localStorage.setItem(LEGEND_STORAGE_KEY, String(w)); + try { localStorage.setItem(LEGEND_STORAGE_KEY, String(w)); } catch (e) { /* private mode or quota */ } }); })();