refactor: audit fixes — clean up bugs, dead code, and type mismatches
CI / test (pull_request) Successful in 23s
CI / test (pull_request) Successful in 23s
- viewer.js: remove undefined state.segmentsBuffered assignment in BUFFER_RESET
- viewer.js: add missing 'switching' and 'ended' phases to PHASE_ICONS
- index.js: remove redundant Strategy B3 (duplicated B1 video-element walk)
- index.js: filter standard <video> DOM attributes from custom-property scans
(m3u8DeepProbeFn B1 and scrapeFn Priority 3) to avoid iterating built-in
properties that can never contain HLS data
- background.js: remove unconditional return true (handlers are synchronous)
and remove dead error-response for unknown message types
- types.ts: align MediaType union ('direct' | 'hls') with actual runtime
value used in code ('video' | 'hls')
- package.json: remove hls.js from dependencies (loaded from CDN at runtime,
never imported as an npm module)
This commit is contained in:
1 parent
ae8608148d
commit
8e9f7f96f1
5 files changed
+36
-31
No files matched your search
+31
-20
@@ -171,8 +171,23 @@ function m3u8DeepProbeFn() {
|
||||
// NOT a reverse-lookup. It returns its input unchanged — Hls.cast(video) just
|
||||
// returns the <video> element with no .url property. Real players store the
|
||||
// HLS instance directly on the video element as a custom property.
|
||||
// Only check non-standard properties (skip built-in <video> attributes).
|
||||
const STANDARD_VIDEO_ATTRS = new Set([
|
||||
'src', 'srcObject', 'crossOrigin', 'preload', 'autoplay', 'muted',
|
||||
'defaultMuted', 'loop', 'controls', 'controlsList', 'disableRemotePlayback',
|
||||
'volume', 'playbackRate', 'defaultPlaybackRate', 'playbackState',
|
||||
'currentTime', 'startTime', 'duration', 'buffered', 'seekable',
|
||||
'played', 'seeking', 'ended', 'readyState', 'networkState',
|
||||
'videoWidth', 'videoHeight', 'error', 'textTracks', 'videoTracks',
|
||||
'audioTracks', 'loadingBeganAt', 'label', 'id', 'className',
|
||||
'classList', 'style', 'attributes', 'dataset', 'innerHTML', 'textContent',
|
||||
'outerHTML', 'outerText', 'slot', 'accessKey', 'draggable', 'hidden',
|
||||
'lang', 'spellcheck', 'tabIndex', 'title', 'translate',
|
||||
'width', 'height', 'poster', 'preload', 'referrerPolicy',
|
||||
]);
|
||||
for (const v of document.querySelectorAll('video')) {
|
||||
for (const key of Object.keys(v)) {
|
||||
if (STANDARD_VIDEO_ATTRS.has(key)) continue;
|
||||
const obj = v[key];
|
||||
if (!obj || typeof obj !== 'object') continue;
|
||||
// Check for common HLS instance patterns on video elements
|
||||
@@ -193,23 +208,6 @@ function m3u8DeepProbeFn() {
|
||||
}
|
||||
}
|
||||
|
||||
// B3: Fallback — walk video element keys looking for HLS-related objects
|
||||
for (const v of document.querySelectorAll('video')) {
|
||||
for (const key of Object.keys(v)) {
|
||||
if (key.toLowerCase().includes('hls') || key === 'player') {
|
||||
const hlsObj = v[key];
|
||||
if (hlsObj && typeof hlsObj === 'object') {
|
||||
for (const subKey of Object.keys(hlsObj)) {
|
||||
if (typeof hlsObj[subKey] === 'string' && hlsObj[subKey].includes('.m3u8')) {
|
||||
if (!seen.has(hlsObj[subKey])) { seen.add(hlsObj[subKey]); manifests.push({ url: hlsObj[subKey], player: `video.${key}.${subKey}` }); }
|
||||
}
|
||||
}
|
||||
walk(hlsObj, `video.${key}`, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Strategy C: Inline scripts
|
||||
for (const script of document.querySelectorAll('script:not([src])')) {
|
||||
const text = script.textContent || '';
|
||||
@@ -281,11 +279,24 @@ function scrapeFn(hlsManifests) {
|
||||
mediaType = 'hls';
|
||||
src = hlsManifest;
|
||||
}
|
||||
// Priority 3: Scan video element properties for HLS instance references.
|
||||
// Hls.cast() is a TypeScript identity cast in hls.js — NOT a reverse-lookup.
|
||||
// Real players store the HLS instance on the video element as custom properties.
|
||||
// Priority 3: Scan video element custom properties for HLS instance references.
|
||||
// Only check non-standard (custom) properties — skip built-in <video> attrs.
|
||||
if (!hlsManifest) {
|
||||
const stdAttrs = new Set([
|
||||
'src', 'srcObject', 'crossOrigin', 'preload', 'autoplay', 'muted',
|
||||
'defaultMuted', 'loop', 'controls', 'controlsList', 'disableRemotePlayback',
|
||||
'volume', 'playbackRate', 'defaultPlaybackRate', 'playbackState',
|
||||
'currentTime', 'startTime', 'duration', 'buffered', 'seekable',
|
||||
'played', 'seeking', 'ended', 'readyState', 'networkState',
|
||||
'videoWidth', 'videoHeight', 'error', 'textTracks', 'videoTracks',
|
||||
'audioTracks', 'loadingBeganAt', 'label', 'id', 'className',
|
||||
'classList', 'style', 'attributes', 'dataset', 'innerHTML', 'textContent',
|
||||
'outerHTML', 'outerText', 'slot', 'accessKey', 'draggable', 'hidden',
|
||||
'lang', 'spellcheck', 'tabIndex', 'title', 'translate',
|
||||
'width', 'height', 'poster', 'referrerPolicy',
|
||||
]);
|
||||
for (const key of Object.keys(v)) {
|
||||
if (stdAttrs.has(key)) continue;
|
||||
const obj = v[key];
|
||||
if (obj && typeof obj === 'object' && typeof obj.url === 'string') {
|
||||
const u = obj.url.toLowerCase();
|
||||
|
||||
@@ -170,7 +170,9 @@ const PHASE_ICONS = {
|
||||
loading: '\u2B07', // down arrow
|
||||
buffering: '\u27F7', // spinning
|
||||
playing: '\u25B6', // play
|
||||
switching: '\u21BB', // right arrow corner
|
||||
error: '\u2717', // X
|
||||
ended: '\u23F9', // stop
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -413,7 +415,6 @@ function wireHlsEvents(hls, video, panel) {
|
||||
state.lastActivity = Date.now();
|
||||
state.bufferedAhead = 0;
|
||||
state.segmentsLoaded = 0;
|
||||
state.segmentsBuffered = 0;
|
||||
renderPanelState(video, panel);
|
||||
});
|
||||
|
||||
|
||||
Reference in new issue
Block a user