mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-09 08:59:40 +02:00
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:
@@ -19,7 +19,9 @@
|
||||
*/
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import {
|
||||
FakeEl,
|
||||
FakeTile,
|
||||
bySelector,
|
||||
idleCallbacks,
|
||||
localStore,
|
||||
makeGridApp,
|
||||
@@ -63,6 +65,29 @@ describe('selectSession with the grid open', () => {
|
||||
expect(app._focusedPane().sessionId).toBe('s-b');
|
||||
});
|
||||
|
||||
it('focus changes leave at most one glow listener on a tab, and the glow runs again once it ended', async () => {
|
||||
// On every skin but OG the glow is `animation: none`: animationend never
|
||||
// fires, and every focus used to add one more once-listener to the tab.
|
||||
const app = openGrid();
|
||||
const tab = new FakeEl();
|
||||
tab.className = 'session-tab active';
|
||||
bySelector.set('.session-tab.active[data-id="s-b"]', tab);
|
||||
for (let i = 0; i < 5; i++) {
|
||||
await app.selectSession('s-b');
|
||||
await app.selectSession('s-a');
|
||||
}
|
||||
expect(tab.classList.contains('tab-glow')).toBe(true);
|
||||
expect(tab.listeners.animationend).toHaveLength(1);
|
||||
|
||||
// OG: the animation ends, the class goes, and the next focus glows again.
|
||||
tab.dispatch('animationend');
|
||||
tab.listeners.animationend = [];
|
||||
expect(tab.classList.contains('tab-glow')).toBe(false);
|
||||
await app.selectSession('s-b');
|
||||
expect(tab.classList.contains('tab-glow')).toBe(true);
|
||||
expect(tab.listeners.animationend).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('a user-initiated focus acknowledges the idle alert; an `auto` one does not', async () => {
|
||||
const app = openGrid();
|
||||
await app.selectSession('s-b');
|
||||
|
||||
Reference in New Issue
Block a user