From 389dca97a647fbba14c6ffe628417f89913c2268 Mon Sep 17 00:00:00 2001 From: "Grot (@grafanabot)" <43478413+grafanabot@users.noreply.github.com> Date: Thu, 18 Aug 2022 14:28:33 +0200 Subject: [PATCH] TimeSeries: Fix memory leak on viz re-init caused by KeyboardPlugin (#53891) (cherry picked from commit 329aab73952e9762d07b6fa46f5c51471c91b1d1) Co-authored-by: Leon Sorokin --- .../uPlot/plugins/KeyboardPlugin.tsx | 32 ++++++++++++++----- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/packages/grafana-ui/src/components/uPlot/plugins/KeyboardPlugin.tsx b/packages/grafana-ui/src/components/uPlot/plugins/KeyboardPlugin.tsx index 053e99e4b08..d8f0d11313e 100644 --- a/packages/grafana-ui/src/components/uPlot/plugins/KeyboardPlugin.tsx +++ b/packages/grafana-ui/src/components/uPlot/plugins/KeyboardPlugin.tsx @@ -87,7 +87,7 @@ const initHook = (u: uPlot) => { window.requestAnimationFrame(handlePressedKeys); }; - vizLayoutViz.addEventListener('keydown', (e) => { + const onKeyDown = (e: KeyboardEvent) => { if (e.key === 'Tab') { // Hide the cursor if the user tabs away u.setCursor({ left: -5, top: -5 }); @@ -112,9 +112,9 @@ const initHook = (u: uPlot) => { window.requestAnimationFrame(handlePressedKeys); } } - }); + }; - vizLayoutViz.addEventListener('keyup', (e) => { + const onKeyUp = (e: KeyboardEvent) => { if (!KNOWN_KEYS.has(e.key)) { return; } @@ -129,9 +129,9 @@ const initHook = (u: uPlot) => { u.setSelect(u.select); dragStartX = null; } - }); + }; - vizLayoutViz.addEventListener('focus', (e) => { + const onFocus = () => { // We only want to initialize the cursor if the user is using keyboard controls if (!vizLayoutViz?.matches(':focus-visible')) { return; @@ -141,14 +141,30 @@ const initHook = (u: uPlot) => { const drawWidth = parseFloat(u.over.style.width); const drawHeight = parseFloat(u.over.style.height); u.setCursor({ left: drawWidth / 2, top: drawHeight / 2 }); - }); + }; - vizLayoutViz.addEventListener('blur', (e) => { + const onBlur = () => { keysLastHandledAt = null; dragStartX = null; pressedKeys.clear(); u.setSelect({ left: 0, top: 0, width: 0, height: 0 }, false); - }); + }; + + vizLayoutViz.addEventListener('keydown', onKeyDown); + vizLayoutViz.addEventListener('keyup', onKeyUp); + vizLayoutViz.addEventListener('focus', onFocus); + vizLayoutViz.addEventListener('blur', onBlur); + + const onDestroy = () => { + vizLayoutViz?.removeEventListener('keydown', onKeyDown); + vizLayoutViz?.removeEventListener('keyup', onKeyUp); + vizLayoutViz?.removeEventListener('focus', onFocus); + vizLayoutViz?.removeEventListener('blur', onBlur); + + vizLayoutViz = null; + }; + + (u.hooks.destroy ??= []).push(onDestroy); }; /**