diff --git a/platform/common/vapi-common.js b/platform/common/vapi-common.js index 65e0c93c5c048..eafb02c425198 100644 --- a/platform/common/vapi-common.js +++ b/platform/common/vapi-common.js @@ -197,6 +197,18 @@ vAPI.webextFlavor = { .add('user_stylesheet'); } flavor.major = match && parseInt(match[1], 10) || 120; + // Brave can't be told apart through the user agent string, which is + // identical to Chrome's. Both tests below are synchronous, whereas + // navigator.brave.isBrave() is promise-based -- the flavor must be + // settled before filter lists are compiled and cached. Either test + // alone would do, the second one is a fallback for the first. + // https://github.com/brave/brave-browser/wiki/Detecting-Brave-(for-Websites) + if ( + navigator.brave instanceof Object || + navigator.userAgentData?.brands?.some(a => a.brand === 'Brave') + ) { + soup.add('brave'); + } } // Don't starve potential listeners diff --git a/src/js/static-filtering-parser.js b/src/js/static-filtering-parser.js index 5429d423d5f8d..d2a1af2f96363 100644 --- a/src/js/static-filtering-parser.js +++ b/src/js/static-filtering-parser.js @@ -604,6 +604,7 @@ export const preparserIfTokens = new Set([ 'ext_ublock', 'ext_ubol', 'ext_devbuild', + 'env_brave', 'env_chromium', 'env_edge', 'env_firefox', @@ -4230,6 +4231,7 @@ export const utils = (( ) => { [ 'ext_ublock', 'ublock' ], [ 'ext_ubol', 'ubol' ], [ 'ext_devbuild', 'devbuild' ], + [ 'env_brave', 'brave' ], [ 'env_chromium', 'chromium' ], [ 'env_edge', 'edge' ], [ 'env_firefox', 'firefox' ],