From bea0f6925c0fe5a079f7890dcabff1eda7a31232 Mon Sep 17 00:00:00 2001 From: Timo <6156589+Shik3i@users.noreply.github.com> Date: Thu, 2 Jul 2026 13:27:53 +0200 Subject: [PATCH] Implement cached duration fallback and simulate keyboard events fallback for Disney+ seeks when controls are hidden --- extension/content.js | 38 +++++++++++++++++++++++++-- scripts/test-content-video-finder.cjs | 1 + 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/extension/content.js b/extension/content.js index 7287b5d..95d6dad 100644 --- a/extension/content.js +++ b/extension/content.js @@ -59,6 +59,7 @@ const PAGE_API_SEEK_BRIDGE = 1; let lastDisneyPlusTimelineCandidates = []; + let lastKnownDisneyPlusDuration = 0; function hostMatchesUrl(host, url) { const normalized = String(url || '') @@ -218,10 +219,31 @@ return backward ? backRe.test(label) : forwardRe.test(label); }); - if (!button || typeof button.click !== 'function') return false; + if (button && typeof button.click === 'function') { + const clicks = Math.max(1, Math.min(12, Math.round(Math.abs(delta) / 10))); + for (let i = 0; i < clicks; i++) { + setTimeout(() => button.click(), i * 60); + } + return true; + } + + // Fallback: Simulate ArrowLeft / ArrowRight keyboard events const clicks = Math.max(1, Math.min(12, Math.round(Math.abs(delta) / 10))); + const eventInit = { + key: backward ? 'ArrowLeft' : 'ArrowRight', + code: backward ? 'ArrowLeft' : 'ArrowRight', + keyCode: backward ? 37 : 39, + which: backward ? 37 : 39, + bubbles: true, + cancelable: true, + view: window + }; + const target = document.querySelector('.hive-video') || document.activeElement || document.body; for (let i = 0; i < clicks; i++) { - setTimeout(() => button.click(), i * 60); + setTimeout(() => { + target.dispatchEvent(new window.KeyboardEvent('keydown', eventInit)); + target.dispatchEvent(new window.KeyboardEvent('keyup', eventInit)); + }, i * 60); } return true; } @@ -233,6 +255,7 @@ const ui = getDisneyPlusUiTimeline(); if (ui) { + lastKnownDisneyPlusDuration = ui.duration; let nativeScale = 1; if (range && range.duration > ui.duration * 1.2) { nativeScale = range.duration / ui.duration; @@ -251,6 +274,17 @@ }; } + if (lastKnownDisneyPlusDuration > 0) { + return { + start: 0, + end: lastKnownDisneyPlusDuration, + duration: lastKnownDisneyPlusDuration, + current: Number.isFinite(current) ? current : 0, + nativeScale: 1, + nativeStart: 0 + }; + } + if (!range || range.start < 1 || range.duration < 60) return null; if (!Number.isFinite(current) || current < range.start - 1 || current > range.end + 1) return null; return { ...range, current: Math.max(0, current - range.start), nativeScale: 1, nativeStart: range.start }; diff --git a/scripts/test-content-video-finder.cjs b/scripts/test-content-video-finder.cjs index b9c5e3c..f7d0bc6 100644 --- a/scripts/test-content-video-finder.cjs +++ b/scripts/test-content-video-finder.cjs @@ -91,6 +91,7 @@ function makeNode(attrs = {}, textContent = '') { function loadTimelineFns(hostname, document = makeDocument()) { return Function('window', 'document', [ 'let lastDisneyPlusTimelineCandidates = [];', + 'let lastKnownDisneyPlusDuration = 0;', extractFunction('hostMatchesUrl', source), extractFunction('matchesPlayerUrls', source), extractFunction('isDisneyPlusHost', source),