diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 849ddff..0000000 --- a/.eslintignore +++ /dev/null @@ -1 +0,0 @@ -dist/ diff --git a/eslint.config.js b/eslint.config.js index 4a2ae27..276ca04 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -3,7 +3,7 @@ import globals from 'globals'; export default [ { - ignores: ['dist/', 'node_modules/'], + ignores: ['dist/', 'node_modules/', '__tests__/'], }, { files: ['**/*.js', '**/*.mjs'], diff --git a/src/content/content.js b/src/content/content.js index fbfefc0..0c0d056 100644 --- a/src/content/content.js +++ b/src/content/content.js @@ -85,7 +85,7 @@ return url; } } - } catch(_e) {} + } catch {} } return null; } @@ -122,7 +122,7 @@ }); } } - } catch(_e) { /* ignore DOM access errors */ } + } catch { /* ignore DOM access errors */ } return { posterUrl: poster, diff --git a/src/inject/interceptors.js b/src/inject/interceptors.js index d544727..277093c 100644 --- a/src/inject/interceptors.js +++ b/src/inject/interceptors.js @@ -163,6 +163,6 @@ } }); observer.observe(document.head || document.documentElement, { childList: true, subtree: true }); - } catch(_e) { /* MutationObserver not available — polling still works */ } + } catch { /* MutationObserver not available — polling still works */ } } })(); diff --git a/src/viewer/index.js b/src/viewer/index.js index 2efd3f8..1f2650d 100644 --- a/src/viewer/index.js +++ b/src/viewer/index.js @@ -404,7 +404,6 @@ function dedupManifests(allManifests) { '__goon_plugin_data': 0, 'content-script-intercept': 0, 'video._goon_hls_manifest': 1, - 'Hls.cast': 1, 'inline-script': 99, }; unique.sort((a, b) => { diff --git a/src/viewer/viewer.js b/src/viewer/viewer.js index 740a349..1a6040e 100644 --- a/src/viewer/viewer.js +++ b/src/viewer/viewer.js @@ -320,7 +320,7 @@ function wireHlsEvents(hls, video, panel) { const HlsEvents = window.Hls.Events; // --- Manifest lifecycle --- - hls.on(HlsEvents.MANIFEST_LOADED, (_ev, data) => { + hls.on(HlsEvents.MANIFEST_LOADED, () => { state.phase = 'loading'; state.lastEvent = 'MANIFEST_LOADED'; state.lastActivity = Date.now(); @@ -524,35 +524,22 @@ function wireHlsEvents(hls, video, panel) { * These complement hls.js events by providing browser-level playback state. */ function wireVideoEvents(video) { - video.addEventListener('playing', () => { - const s = panelStates.get(video); - if (s) { - s.phase = 'playing'; - s.lastEvent = 'video.playing'; + // Helper: bind a video event that updates state and re-renders. + // Skips the handler if the panel state has already been cleaned up. + function onVideoEvent(eventName, updater) { + video.addEventListener(eventName, () => { + const s = panelStates.get(video); + if (!s) return; + updater(s); s.lastActivity = Date.now(); - renderPanelState(video, s._panel); - } - }); + if (s._panel) renderPanelState(video, s._panel); + }); + } - video.addEventListener('waiting', () => { - const s = panelStates.get(video); - if (s) { - s.phase = 'buffering'; - s.lastEvent = 'video.waiting'; - s.lastActivity = Date.now(); - renderPanelState(video, s._panel); - } - }); - - video.addEventListener('stalled', () => { - const s = panelStates.get(video); - if (s) { - s.phase = 'buffering'; - s.lastEvent = 'video.stalled'; - s.lastActivity = Date.now(); - renderPanelState(video, s._panel); - } - }); + // Track playback phase transitions. + onVideoEvent('playing', s => { s.phase = 'playing'; s.lastEvent = 'video.playing'; }); + onVideoEvent('waiting', s => { s.phase = 'buffering'; s.lastEvent = 'video.waiting'; }); + onVideoEvent('stalled', s => { s.phase = 'buffering'; s.lastEvent = 'video.stalled'; }); // Track actual playback position (fragments are delivered out of order but // the browser's timeupdate fires as they are played back sequentially). @@ -563,6 +550,7 @@ function wireVideoEvents(video) { s.duration = video.duration || 0; }); + // Seek events — update activity marker, re-render. video.addEventListener('seeking', () => { const s = panelStates.get(video); if (s) { @@ -571,14 +559,7 @@ function wireVideoEvents(video) { } }); - video.addEventListener('seeked', () => { - const s = panelStates.get(video); - if (s) { - s.lastEvent = 'video.seeked'; - s.lastActivity = Date.now(); - renderPanelState(video, s._panel); - } - }); + onVideoEvent('seeked', s => { s.lastEvent = 'video.seeked'; }); } /* ======================================================================== */