Skip to content

Commit

Permalink
Fix duplicate injected script error in MV3 (#2298)
Browse files Browse the repository at this point in the history
  • Loading branch information
sammacbeth committed Oct 24, 2023
1 parent 033cef9 commit 6f812ff
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 39 deletions.
7 changes: 6 additions & 1 deletion shared/js/background/background.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import { onStartup } from './startup'
import FireButton from './components/fire-button'
import TabTracker from './components/tab-tracking'
import MV3ContentScriptInjection from './components/mv3-content-script-injection'
import initDebugBuild from './devbuild'
import initReloader from './devbuild-reloader'
import tabManager from './tab-manager'
Expand All @@ -27,7 +28,6 @@ require('./events')
const settings = require('./settings')
if (BUILD_TARGET === 'chrome-mv3') {
require('./dnr-config-rulesets')
require('./script-injection')
}

settings.ready().then(() => {
Expand All @@ -43,9 +43,14 @@ const components = {
tabTracking: new TabTracker({ tabManager })
}

// Chrome-only components
if (BUILD_TARGET === 'chrome' || BUILD_TARGET === 'chrome-mv3') {
components.fireButton = new FireButton({ settings, tabManager })
}
// MV3-only components
if (BUILD_TARGET === 'chrome-mv3') {
components.scriptInjection = new MV3ContentScriptInjection()
}
console.log('Loaded components:', components)
// @ts-ignore
self.components = components
Expand Down
48 changes: 48 additions & 0 deletions shared/js/background/components/mv3-content-script-injection.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// With Manifest V2 the content scripts are run directly from the manifest and
// they inject into the main world of websites by adding a <script> element to
// the DOM. With Manifest V3 however the chrome.scripting API must be used to
// inject scripts into the main world.
// Note: It's important that the isolated world script runs first. The order the
// scripts are added by registerContentScripts is based on the script ID,
// but note that's an implementation detail (from use of std::set for new
// script IDs[1]) and could change in the future.
// 1 - https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/extensions/api/scripting/scripting_api.cc;l=929

export default class MV3ContentScriptInjection {
constructor () {
this.ready = this.registerScripts()
}

async registerScripts () {
// check if scripts were already registered - in scripts will remain registered under
// some startup conditions, and in that case registering the scripts will throw an error.
const scripts = await chrome.scripting.getRegisteredContentScripts()
const ids = scripts.map(s => s.id)
if (ids.length > 0) {
await chrome.scripting.unregisterContentScripts({ ids })
}
await chrome.scripting.registerContentScripts([{
id: '1-script-injection-isolated-world',
allFrames: true,
js: ['public/js/content-scripts/content-scope-messaging.js'],
runAt: 'document_start',
world: 'ISOLATED',
matches: ['<all_urls>'],
excludeMatches: [
'*://localhost/*',
'*://*.localhost/'
]
}, {
id: '2-script-injection-main-world',
allFrames: true,
js: ['public/js/inject.js'],
runAt: 'document_start',
world: 'MAIN',
matches: ['<all_urls>'],
excludeMatches: [
'*://localhost/*',
'*://*.localhost/'
]
}])
}
}
38 changes: 0 additions & 38 deletions shared/js/background/script-injection.js

This file was deleted.

0 comments on commit 6f812ff

Please sign in to comment.