fix(tiles): a tile focus no longer leaves a glow listener on its tab

_selectTiledSession added a once animationend listener to the focused
tile's tab on every focus. On every skin but OG the glow is `animation:
none`, so animationend never fires: the listeners piled up on the tab (and
the class stayed). It now glows a tab only when it is not glowing already,
so a tab holds at most one; on OG the animation ends, the class goes and
the next focus glows again.

Measured (50 tile focus changes, daylight-blue): animationend listeners on
the tabs 0 -> 49 before, 0 -> 6 (one per tab) after. Over the leak run's
20 grid open/close cycles the page's listener count grew 1003 -> 1042;
this is the part CDP could attribute.

Live, this code: 50 tile focus changes leave 6 animationend listeners on
the tabs, one per tab.

The single view's copy of the same block (app.js selectSession) has the
same leak on every non-OG skin; it is a separate, pre-existing copy and is
left alone here.

Test: ten focus changes leave one listener; after animationend the next
focus glows again; mutation-checked.

Scope: PR 2 (tile-grid.js).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Codeman maintainer
2026-10-07 06:57:54 +02:00
parent 02387b5b16
commit d7f6047529
2 changed files with 29 additions and 1 deletions
+4 -1
View File
@@ -1535,7 +1535,10 @@ Object.assign(CodemanApp.prototype, {
this.closeSessionSidebarOnHandheld?.();
this.renderSessionTabs?.();
const activeTab = document.querySelector(`.session-tab.active[data-id="${sessionId}"]`);
if (activeTab) {
// Not while it still glows: on every skin but OG the glow is `animation:
// none`, so animationend never comes and each tile focus used to leave
// another listener behind on the tab (49 after 50 focus changes).
if (activeTab && !activeTab.classList.contains('tab-glow')) {
activeTab.classList.add('tab-glow');
activeTab.addEventListener('animationend', () => activeTab.classList.remove('tab-glow'), { once: true });
}