feat: add Firefox support via cross-browser build (Phase 8.2) - #123
Merged
Conversation
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
force-pushed
the
feat/firefox-support
branch
from
July 25, 2026 22:21
cc2bc3f to
529f811
Compare
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 sourcemanifest.json:dist/chrome/- MV3background.service_worker(unchanged)dist/firefox/- event-pagebackground.scripts+ the mandatorybrowser_specific_settings.gecko.idbackground.js,core/classifier.js,popup/popup.js): a one-lineglobalThis.browser = globalThis.browser || globalThis.chromealias, thenchrome.*→browser.*. On Chromiumbrowseraliases MV3's promise-basedchrome; on Firefoxbrowser.*is natively promise-based. Both keep the existingonMessagereturn true/sendResponsepattern, so no listener refactor.dist/gitignored.Why the alias over
webextension-polyfillThe roadmap floated the polyfill, but it is 40KB vendored and routes
onMessagethrough a wrapper that expects promise-returning listeners - which would force abackground.jsrefactor. The one-line alias is lighter, adds no dependency, and preserves the workingreturn true/sendResponsepattern (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.htmlloadspopup.jsexternally, so the default MV3 CSP needs nocontent_security_policyoverride.Testing
cd extension && npm test- 81/81 Jest tests pass, unchanged (the alias resolves to the mockedchromein jsdom)npm run buildproduces completedist/chromeanddist/firefoxbundles with correct manifestsdist/firefoxviaabout:debugging, check Twitter/X + YouTube + Reddit classify and render) - human taskNotes
content.jsis unreferenced legacy (not in the manifest); left untouched and excluded from the build - flagging rather than removing.intentkeeper@olawoyin007.github.io) is a stable placeholder; change before AMO submission if you prefer a different namespace.