From c1724ebacc3fdfabb11c0b4320bb555a29847732 Mon Sep 17 00:00:00 2001 From: Sid Vishnoi <8426945+sidvishnoi@users.noreply.github.com> Date: Tue, 17 Sep 2024 14:14:22 +0530 Subject: [PATCH 1/2] fix: inject polyfill earlier when `world: MAIN` is supported --- esbuild/plugins.ts | 5 ----- src/background/services/background.ts | 25 +++++++++++++++++++++++++ src/content/polyfill.ts | 5 +++++ src/content/services/contentScript.ts | 3 ++- src/manifest.json | 4 ++-- 5 files changed, 34 insertions(+), 8 deletions(-) diff --git a/esbuild/plugins.ts b/esbuild/plugins.ts index b996be81..d65d2fc1 100644 --- a/esbuild/plugins.ts +++ b/esbuild/plugins.ts @@ -147,11 +147,6 @@ function processManifestPlugin({ json.background = { scripts: [json.background.service_worker], }; - json.content_scripts?.forEach((contentScript) => { - // TODO: Remove this when Firefox supports `world` - at least last 10 - // versions - contentScript.world = undefined; - }); delete json.minimum_chrome_version; } else { delete json['browser_specific_settings']; diff --git a/src/background/services/background.ts b/src/background/services/background.ts index f5b9fbad..55b151bc 100644 --- a/src/background/services/background.ts +++ b/src/background/services/background.ts @@ -51,6 +51,7 @@ export class Background { async start() { this.bindOnInstalled(); + await this.injectPolyfill(); await this.onStart(); this.heartbeat.start(); this.bindMessageHandler(); @@ -61,6 +62,30 @@ export class Background { this.sendToPopup.start(); } + async injectPolyfill() { + try { + // TODO: When Firefox 128 is old enough, inject directly via manifest. + // Also see: injectPolyfill in contentScript + await this.browser.scripting.registerContentScripts([ + { + world: 'MAIN', + id: 'polyfill', + allFrames: true, + js: ['polyfill/polyfill.js'], + matches: PERMISSION_HOSTS.origins, + runAt: 'document_start', + }, + ]); + } catch (error) { + // Firefox <128 will throw saying world: MAIN isn't supported. So, we'll + // inject via contentScript later. Injection via contentScript is slow, + // but apart from WM detection on page-load, everything else works fine. + if (!error.message.includes(`world`)) { + this.logger.error(error); + } + } + } + async onStart() { await this.storage.populate(); await this.checkPermissions(); diff --git a/src/content/polyfill.ts b/src/content/polyfill.ts index 062dae0d..14114aed 100644 --- a/src/content/polyfill.ts +++ b/src/content/polyfill.ts @@ -1,5 +1,10 @@ import type { MonetizationEventPayload } from '@/shared/messages'; (function () { + if (document.createElement('link').relList.supports('monetization')) { + // console.log('already patched'); + return; + } + const handlers = new WeakMap(); const attributes: PropertyDescriptor & ThisType = { enumerable: true, diff --git a/src/content/services/contentScript.ts b/src/content/services/contentScript.ts index 84a36d94..27a97be8 100644 --- a/src/content/services/contentScript.ts +++ b/src/content/services/contentScript.ts @@ -72,7 +72,8 @@ export class ContentScript { } // TODO: When Firefox has good support for `world: MAIN`, inject this directly - // via manifest.json https://bugzilla.mozilla.org/show_bug.cgi?id=1736575 + // via manifest.json https://bugzilla.mozilla.org/show_bug.cgi?id=1736575 and + // remove this, along with injectPolyfill from background async injectPolyfill() { const document = this.window.document; const script = document.createElement('script'); diff --git a/src/manifest.json b/src/manifest.json index d8b29928..6680fd44 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -22,14 +22,14 @@ "background": { "service_worker": "background/background.js" }, - "permissions": ["tabs", "storage", "alarms"], + "permissions": ["tabs", "storage", "alarms", "scripting"], "action": { "default_title": "Web Monetization", "default_popup": "popup/index.html" }, "web_accessible_resources": [ { - "resources": ["assets/*", "polyfill/*"], + "resources": ["polyfill/*"], "matches": [""] } ], From 391efd22efc82f20472a720b893c4633efea42b3 Mon Sep 17 00:00:00 2001 From: Sid Vishnoi <8426945+sidvishnoi@users.noreply.github.com> Date: Tue, 17 Sep 2024 19:12:16 +0530 Subject: [PATCH 2/2] address feedback --- src/background/services/background.ts | 11 ++++++++--- src/content/polyfill.ts | 2 +- src/content/services/contentScript.ts | 1 + 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/background/services/background.ts b/src/background/services/background.ts index 55b151bc..a1e34db3 100644 --- a/src/background/services/background.ts +++ b/src/background/services/background.ts @@ -62,10 +62,11 @@ export class Background { this.sendToPopup.start(); } + // TODO: When Firefox 128 is old enough, inject directly via manifest. + // Also see: injectPolyfill in contentScript + // See: https://github.com/interledger/web-monetization-extension/issues/607 async injectPolyfill() { try { - // TODO: When Firefox 128 is old enough, inject directly via manifest. - // Also see: injectPolyfill in contentScript await this.browser.scripting.registerContentScripts([ { world: 'MAIN', @@ -81,7 +82,11 @@ export class Background { // inject via contentScript later. Injection via contentScript is slow, // but apart from WM detection on page-load, everything else works fine. if (!error.message.includes(`world`)) { - this.logger.error(error); + this.logger.error( + `Content script execution world \`MAIN\` not supported by your browser.\n` + + `Check https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/scripting/ExecutionWorld#browser_compatibility for browser compatibility.`, + error, + ); } } } diff --git a/src/content/polyfill.ts b/src/content/polyfill.ts index 14114aed..ec12fd5c 100644 --- a/src/content/polyfill.ts +++ b/src/content/polyfill.ts @@ -1,7 +1,7 @@ import type { MonetizationEventPayload } from '@/shared/messages'; (function () { if (document.createElement('link').relList.supports('monetization')) { - // console.log('already patched'); + // already patched return; } diff --git a/src/content/services/contentScript.ts b/src/content/services/contentScript.ts index 27a97be8..2cbef244 100644 --- a/src/content/services/contentScript.ts +++ b/src/content/services/contentScript.ts @@ -74,6 +74,7 @@ export class ContentScript { // TODO: When Firefox has good support for `world: MAIN`, inject this directly // via manifest.json https://bugzilla.mozilla.org/show_bug.cgi?id=1736575 and // remove this, along with injectPolyfill from background + // See: https://github.com/interledger/web-monetization-extension/issues/607 async injectPolyfill() { const document = this.window.document; const script = document.createElement('script');