Skip to content

Commit

Permalink
Create a MVP version of uBOLite for Firefox
Browse files Browse the repository at this point in the history
What does not work at the time of commit:

Cosmetic filtering does not work:

The content scripts responsible for cosmetic filtering fail when
trying to inject the stylesheets through document.adoptedStyleSheets,
with the following error message:

  XrayWrapper denied access to property Symbol.iterator
  (reason: object is not safely Xrayable).
  See https://developer.mozilla.org/en-US/docs/Xray_vision for more
  information. ... css-declarative.js:106:8

A possible solution is to inject those content scripts in the
MAIN world. However Firefox scripting API does not support MAIN
world injection at the moment.

Scriptlet-filtering does not work:

Because scriptlet code needs to be injected in the MAIN world,
and this is currently not supported by Firefox's scripting API,
see https://bugzilla.mozilla.org/show_bug.cgi?id=1736575

There is no count badge on the toolbar icon in Firefox, as it
currently does not support the `DNR.setExtensionActionOptions`
method.

Other than the above issues, it does appear uBO is blocking
properly with no error reported in the dev console.

The adoptedStyleSheets issue though is worrisome, as the
cosmetic filtering content scripts were designed with ISOLATED
world injection in mind. Being forced to inject in MAIN world
(when available) make things a bit more complicated as uBO
has to ensure it's global variables do not leak into the page.
  • Loading branch information
gorhill committed Apr 7, 2023
1 parent 8b5774a commit cbfd2ad
Show file tree
Hide file tree
Showing 12 changed files with 124 additions and 17 deletions.
9 changes: 6 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ run_options := $(filter-out $@,$(MAKECMDGOALS))
compare maxcost medcost mincost modifiers record wasm

sources := $(wildcard assets/* assets/*/* dist/version src/* src/*/* src/*/*/* src/*/*/*/*)
platform := $(wildcard platform/* platform/*/* platform/*/*/* platform/*/*/*/*)
platform := $(wildcard platform/* platform/*/* platform/*/*/* platform/*/*/*/* platform/*/*/*/*/*)
assets := dist/build/uAssets

all: chromium firefox npm
Expand Down Expand Up @@ -55,8 +55,11 @@ dig: dist/build/uBlock0.dig
dig-snfe: dig
cd dist/build/uBlock0.dig && npm run snfe $(run_options)

mv3: tools/make-mv3.sh $(sources) $(platform)
tools/make-mv3.sh
mv3-chromium: tools/make-mv3.sh $(sources) $(platform)
tools/make-mv3.sh chromium

mv3-firefox: tools/make-mv3.sh $(sources) $(platform)
tools/make-mv3.sh firefox

mv3-quick: tools/make-mv3.sh $(sources) $(platform)
tools/make-mv3.sh quick
Expand Down
File renamed without changes.
10 changes: 8 additions & 2 deletions platform/mv3/extension/js/background.js
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,9 @@ async function onPermissionsRemoved() {

function onMessage(request, sender, callback) {

if ( sender.origin !== UBOL_ORIGIN ) { return; }
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/MessageSender
// Firefox API does not set `sender.origin`
if ( sender.origin !== undefined && sender.origin !== UBOL_ORIGIN ) { return; }

switch ( request.what ) {

Expand Down Expand Up @@ -304,7 +306,11 @@ async function start() {
console.log(`Available static rule count: ${count}`);
});

dnr.setExtensionActionOptions({ displayActionCountAsBadgeText: true });
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/declarativeNetRequest
// Firefox API does not support `dnr.setExtensionActionOptions`
if ( dnr.setExtensionActionOptions ) {
dnr.setExtensionActionOptions({ displayActionCountAsBadgeText: true });
}
}

(async ( ) => {
Expand Down
8 changes: 8 additions & 0 deletions platform/mv3/extension/js/scripting-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,10 @@ function registerDeclarative(context, declarativeDetails) {
/******************************************************************************/

function registerScriptlet(context, scriptletDetails) {
// https://bugzilla.mozilla.org/show_bug.cgi?id=1736575
// `MAIN` world not yet supported in Firefox
if ( navigator && navigator.product === 'Gecko' ) { return; }

const { before, filteringModeDetails, rulesetsDetails } = context;

const hasBroadHostPermission =
Expand Down Expand Up @@ -427,6 +431,10 @@ function registerScriptlet(context, scriptletDetails) {
/******************************************************************************/

function registerScriptletEntity(context) {
// https://bugzilla.mozilla.org/show_bug.cgi?id=1736575
// `MAIN` world not yet supported in Firefox
if ( navigator && navigator.product === 'Gecko' ) { return; }

const { before, filteringModeDetails, rulesetsDetails } = context;

const js = [];
Expand Down
1 change: 1 addition & 0 deletions platform/mv3/extension/js/scripting/css-declarative.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
/******************************************************************************/

const declarativeImports = self.declarativeImports || [];
delete self.declarativeImports;

const lookupSelectors = (hn, out) => {
for ( const { argsList, hostnamesMap } of declarativeImports ) {
Expand Down
4 changes: 2 additions & 2 deletions platform/mv3/extension/js/scripting/css-generic.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@
(function uBOL_cssGeneric() {

const genericSelectorMap = self.genericSelectorMap || new Map();
if ( genericSelectorMap.size === 0 ) { return; }
delete self.genericSelectorMap;

self.genericSelectorMap = undefined;
if ( genericSelectorMap.size === 0 ) { return; }

/******************************************************************************/

Expand Down
1 change: 1 addition & 0 deletions platform/mv3/extension/js/scripting/css-procedural.js
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,7 @@ class ProceduralFilterer {
/******************************************************************************/

const proceduralImports = self.proceduralImports || [];
delete self.proceduralImports;

const lookupSelectors = (hn, out) => {
for ( const { argsList, hostnamesMap } of proceduralImports ) {
Expand Down
3 changes: 1 addition & 2 deletions platform/mv3/extension/js/scripting/css-specific.entity.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
// $rulesetId$

const specificEntityImports = self.specificEntityImports || [];
delete self.specificEntityImports;

/******************************************************************************/

Expand Down Expand Up @@ -65,8 +66,6 @@ for ( let i = 0; i < hnpartslen; i++ ) {
}
}

self.specificEntityImports = undefined;

if ( selectors.length === 0 ) { return; }

try {
Expand Down
10 changes: 10 additions & 0 deletions platform/mv3/firefox/background.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>uBlock Origin Background Page</title>
</head>
<body>
<script src="js/background.js" type="module"></script>
</body>
</html>
48 changes: 48 additions & 0 deletions platform/mv3/firefox/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"action": {
"default_icon": {
"16": "img/icon_16.png",
"32": "img/icon_32.png",
"64": "img/icon_64.png"
},
"default_popup": "popup.html"
},
"author": "Raymond Hill",
"background": {
"page": "background.html"
},
"browser_specific_settings": {
"gecko": {
"id": "uBOLite@raymondhill.net",
"strict_min_version": "113a1"
}
},
"declarative_net_request": {
"rule_resources": [
]
},
"default_locale": "en",
"description": "__MSG_extShortDesc__",
"icons": {
"16": "img/icon_16.png",
"32": "img/icon_32.png",
"64": "img/icon_64.png",
"128": "img/icon_128.png"
},
"manifest_version": 3,
"name": "__MSG_extName__",
"options_ui": {
"page": "dashboard.html"
},
"optional_permissions": [
"<all_urls>"
],
"permissions": [
"activeTab",
"declarativeNetRequest",
"scripting"
],
"short_name": "uBO Lite",
"version": "0.1",
"web_accessible_resources": []
}
10 changes: 7 additions & 3 deletions platform/mv3/make-rulesets.js
Original file line number Diff line number Diff line change
Expand Up @@ -1418,11 +1418,15 @@ async function main() {
// Patch declarative_net_request key
manifest.declarative_net_request = { rule_resources: ruleResources };
// Patch web_accessible_resources key
manifest.web_accessible_resources = [{
const web_accessible_resources = {
resources: Array.from(requiredRedirectResources).map(path => `/${path}`),
matches: [ '<all_urls>' ],
use_dynamic_url: true,
}];
};
if ( commandLineArgs.get('platform') === 'chromium' ) {
web_accessible_resources.use_dynamic_url = true;
}
manifest.web_accessible_resources = [ web_accessible_resources ];

// Patch version key
const now = new Date();
const yearPart = now.getUTCFullYear() - 2000;
Expand Down
37 changes: 32 additions & 5 deletions tools/make-mv3.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,32 @@ set -e

echo "*** uBOLite.mv3: Creating extension"

DES="dist/build/uBOLite.mv3"
PLATFORM="chromium"

if [ "$1" != "quick" ]; then
for i in "$@"; do
case $i in
quick)
QUICK="yes"
shift # past argument=value
;;
firefox)
PLATFORM="firefox"
shift # past argument=value
;;
chromium)
PLATFORM="chromium"
shift # past argument=value
;;
esac
done

DES="dist/build/uBOLite.$PLATFORM"

if [ "$QUICK" != "yes" ]; then
rm -rf $DES
fi


mkdir -p $DES
cd $DES
DES=$(pwd)
Expand All @@ -35,17 +55,24 @@ cp src/js/i18n.js $DES/js/
cp LICENSE.txt $DES/

echo "*** uBOLite.mv3: Copying mv3-specific files"
if [ "$PLATFORM" = "firefox" ]; then
cp platform/mv3/firefox/background.html $DES/
fi
cp platform/mv3/extension/*.html $DES/
cp platform/mv3/extension/css/* $DES/css/
cp -R platform/mv3/extension/js/* $DES/js/
cp platform/mv3/extension/img/* $DES/img/
cp -R platform/mv3/extension/_locales $DES/

if [ "$1" != "quick" ]; then
if [ "$QUICK" != "yes" ]; then
echo "*** uBOLite.mv3: Generating rulesets"
TMPDIR=$(mktemp -d)
mkdir -p $TMPDIR
cp platform/mv3/extension/manifest.json $DES/
if [ "$PLATFORM" = "chromium" ]; then
cp platform/mv3/chromium/manifest.json $DES/
elif [ "$PLATFORM" = "firefox" ]; then
cp platform/mv3/firefox/manifest.json $DES/
fi
./tools/make-nodejs.sh $TMPDIR
cp platform/mv3/package.json $TMPDIR/
cp platform/mv3/*.js $TMPDIR/
Expand All @@ -55,7 +82,7 @@ if [ "$1" != "quick" ]; then
mkdir -p $TMPDIR/web_accessible_resources
cp src/web_accessible_resources/* $TMPDIR/web_accessible_resources/
cd $TMPDIR
node --no-warnings make-rulesets.js output=$DES
node --no-warnings make-rulesets.js output=$DES platform="$PLATFORM"
cd - > /dev/null
rm -rf $TMPDIR
fi
Expand Down

0 comments on commit cbfd2ad

Please sign in to comment.