Skip to content

feat: add Firefox support via cross-browser build (Phase 8.2) - #123

Merged
Olawoyin007 merged 1 commit into
mainfrom
feat/firefox-support
Jul 25, 2026
Merged

feat: add Firefox support via cross-browser build (Phase 8.2)#123
Olawoyin007 merged 1 commit into
mainfrom
feat/firefox-support

Conversation

@Olawoyin007

Copy link
Copy Markdown
Owner

Summary

Phase 8.2: ports the extension to Firefox MV3 without a runtime browser sniff or a vendored polyfill. The same source runs on Chromium and Firefox; a small build step emits the per-browser manifests.

Changes

  • extension/build.js (npm run build) - emits two bundles from the single source manifest.json:
    • dist/chrome/ - MV3 background.service_worker (unchanged)
    • dist/firefox/ - event-page background.scripts + the mandatory browser_specific_settings.gecko.id
  • Cross-browser API shim in the three files that call extension APIs (background.js, core/classifier.js, popup/popup.js): a one-line globalThis.browser = globalThis.browser || globalThis.chrome alias, then chrome.*browser.*. On Chromium browser aliases MV3's promise-based chrome; on Firefox browser.* is natively promise-based. Both keep the existing onMessage return true / sendResponse pattern, so no listener refactor.
  • Docs: ROADMAP 8.2 code items checked off; CHANGELOG entry. dist/ gitignored.

Why the alias over webextension-polyfill

The roadmap floated the polyfill, but it is 40KB vendored and routes onMessage through a wrapper that expects promise-returning listeners - which would force a background.js refactor. The one-line alias is lighter, adds no dependency, and preserves the working return true/sendResponse pattern (native on both engines). Fits the project's minimal-surface ethos.

Firefox CSP

Verified there are no inline scripts, inline event handlers, or eval; popup.html loads popup.js externally, so the default MV3 CSP needs no content_security_policy override.

Testing

  • cd extension && npm test - 81/81 Jest tests pass, unchanged (the alias resolves to the mocked chrome in jsdom)
  • npm run build produces complete dist/chrome and dist/firefox bundles with correct manifests
  • Manual smoke on Firefox Developer Edition (load dist/firefox via about:debugging, check Twitter/X + YouTube + Reddit classify and render) - human task
  • No-regression check on one Chromium browser - human task

Notes

  • content.js is unreferenced legacy (not in the manifest); left untouched and excluded from the build - flagging rather than removing.
  • The Firefox add-on id (intentkeeper@olawoyin007.github.io) is a stable placeholder; change before AMO submission if you prefer a different namespace.

Port the extension to Firefox MV3 without a runtime browser sniff or a
vendored polyfill:

- extension/build.js (npm run build) emits dist/chrome (MV3 service worker,
  unchanged) and dist/firefox (event-page background.scripts + the mandatory
  browser_specific_settings.gecko.id) from the single source manifest.json.
- The three API-calling files (background.js, core/classifier.js,
  popup/popup.js) gain a one-line alias
  'globalThis.browser = globalThis.browser || globalThis.chrome' and switch
  chrome.* -> browser.*. On Chromium, browser aliases MV3's promise-based
  chrome; on Firefox, browser.* is natively promise-based. Both keep the
  existing onMessage return-true/sendResponse pattern, so no listener refactor.
- Chose the alias over webextension-polyfill: lighter, no 40KB vendored file,
  no onMessage wrapper that would force a background refactor.
- CSP: verified no inline scripts/handlers/eval; popup.html loads popup.js
  externally, so the default MV3 CSP needs no override.

All 81 Jest tests pass unchanged. Manual Firefox Developer Edition smoke test
(load dist/firefox via about:debugging) and AMO submission remain as human
tasks.
@Olawoyin007
Olawoyin007 force-pushed the feat/firefox-support branch from cc2bc3f to 529f811 Compare July 25, 2026 22:21
@Olawoyin007
Olawoyin007 merged commit 9aa4957 into main Jul 25, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant