Disney+'s <video> is blob-relative (unusable as an absolute clock) and its scrubber aria-value freezes during playback, so DOM scraping lagged and the +/-10s button seek could neither reach far targets nor land precisely. The real player hangs off the <disney-web-player> custom element as `.mediaPlayer`, exposing seek(ms) and timeline.info (playhead/duration ms). Since the isolated content world can't read that page object, route it through the existing MAIN-world page-API bridge (as Netflix already does): - page-api-seek-overrides.js: register a 'disney' provider. - background.js installPageApiSeekBridge: seek Disney via mediaPlayer.seek(), and post the exact playhead/duration (seconds) to the content world every 250ms. Both are gated on provider === 'disney'; Netflix path unchanged. - content.js: cache the pushed playhead, prefer it in getDisneyPlusTimeline (DOM scraping stays as fallback), and check the page-API seek first in seekVideo. Outcome is identical for Netflix and generic sites. Verified live on Disney+: reported time matches the player exactly and seek lands within ~1s of the target. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Development Scripts
This directory contains utility scripts for the KoalaSync development workflow.
build-extension.cjs
The primary build tool for KoalaSync. This Node.js script automates two critical tasks:
- Protocol Synchronization: Copies the "Single Source of Truth" constants (
shared/constants.js) and the domain blacklist (shared/blacklist.js) from the root/shareddirectory into theextension/shared/directory. - Content Script Injection: Injects protocol constants directly into
content.jsusing marker-based replacement. This is necessary becausecontent.jsexecutes synchronously and cannot use ES module imports. - Artifact Generation: Compiles the extension into browser-specific bundles for Chrome and Firefox, located in the
dist/directory.
Usage
From the repository root, run:
node scripts/build-extension.cjs
Why this script exists
KoalaSync uses Vanilla JS in the extension to maintain zero runtime dependencies and maximum privacy. Since we don't use a bundler (like Webpack or Vite) inside the extension, this script serves as our lightweight "pre-build" step to ensure that the protocol constants remain synchronized between the extension and the relay server.
Content Injection Markers
The build script uses marker comments in content.js to locate and replace constant blocks:
| Marker Pair | Injected Value | Source |
|---|---|---|
SHARED_EVENTS_INJECT_START / END |
The full EVENTS object |
shared/constants.js |
SHARED_HEARTBEAT_INJECT_START / END |
HEARTBEAT_INTERVAL value |
shared/constants.js |
⚠️ Do NOT remove or modify these marker comments in
content.js. They are required for the build script to function. If the markers are missing, the build will fail with a clear error message.