From ed308ab1d56cf1556a97237ff48a65ba6453d63a Mon Sep 17 00:00:00 2001 From: fanxing11 Date: Sat, 27 Jun 2026 17:17:46 +0800 Subject: [PATCH] fix(detect): auto-detect Zen/Floorp via getBrowserInfo (fixes #232) detectBrowser() only checks navigator.userAgent, which is plain Firefox for Firefox forks (Zen, Floorp, LibreWolf, Waterfox, ...) since that's how they run Firefox extensions unchanged. As a result, Zen users got a bucket named aw-watcher-web-firefox_, but the aw-webui Browser view's firefox regex (firefox|librewolf|waterfox|nightly) does not match zen's window-watcher app name, so 'Top Browser Domains/URLs' came up empty even though Timeline showed the raw events. Refine the 'firefox' branch with browser.runtime.getBrowserInfo() (a Firefox-only API that forks override to report their own name) and map known forks that have a dedicated entry in aw-webui queries.ts (browser_appnames + browser_appname_regex) onto their bucket: zen, floorp. Forks without a dedicated entry stay on the firefox bucket. getBrowserInfo is absent on Chromium and on Firefox < 51, so we guard the lookup with a typeof check and a try/catch and fall back to 'firefox' on any failure. --- src/background/helpers.ts | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/background/helpers.ts b/src/background/helpers.ts index c6f46c2..279e191 100644 --- a/src/background/helpers.ts +++ b/src/background/helpers.ts @@ -2,6 +2,36 @@ import browser from 'webextension-polyfill' import { FetchError } from 'aw-client' import { getBrowserName, setBrowserName } from '../storage' +// Firefox forks share Firefox's userAgent (that's how they run Firefox +// extensions unchanged), so UA-based detection cannot distinguish them. +// browser.runtime.getBrowserInfo() is a Firefox-only API that returns +// {name, vendor, version, buildID} and is overridden by most forks to +// reflect their own brand. We use it to refine 'firefox' into a specific +// fork name when aw-webui's queries.ts has a dedicated entry for it +// (browser_appnames + browser_appname_regex). Forks not listed below +// (librewolf, waterfox, …) fall through and keep using the firefox bucket, +// which already covers them via the firefox regex. +const FIREFOX_FORK_BUCKETS: Record = { + zen: 'zen', + floorp: 'floorp', +} + +async function refineFirefoxFork(): Promise { + // getBrowserInfo is Firefox-only; missing on Chromium and on Firefox < 51. + const getBrowserInfo = (browser.runtime as any).getBrowserInfo + if (typeof getBrowserInfo !== 'function') return 'firefox' + try { + const info = await getBrowserInfo.call(browser.runtime) + const name = (info?.name || '').toLowerCase() + for (const key of Object.keys(FIREFOX_FORK_BUCKETS)) { + if (name.includes(key)) return FIREFOX_FORK_BUCKETS[key] + } + return 'firefox' + } catch { + return 'firefox' + } +} + export const getTab = (id: number) => browser.tabs.get(id) export const getTabs = (query: browser.Tabs.QueryQueryInfoType = {}) => browser.tabs.query(query) @@ -48,7 +78,11 @@ export const getBrowser = async (): Promise => { return storedName } - const browserName = detectBrowser() + let browserName = detectBrowser() + // Refine Firefox-family detection so forks like Zen get their own bucket. + if (browserName === 'firefox') { + browserName = await refineFirefoxFork() + } await setBrowserName(browserName) return browserName