-
Notifications
You must be signed in to change notification settings - Fork 240
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix detection of popup UI close for Chrome MV3 (#1485)
The extension's popup UI allows the user to do several things, including disabling/enabling protections for the current website. When the user disables protections for a website, the website is added to the allowlist. After a delay (or when the user clicks away) the popup UI is closed and the website is reloaded automatically. Until now, that worked by listening for the window.unload event, and then using the chrome.extension.getBackgroundPage() API to fetch the background page before triggering the unload function in the background. With Chrome Manifest v3, the getBackgroundPage() API is no longer available and so a different approach must be used. We're now opening a messaging connection to the background, sending through user actions as they happen, then finally having the background detect when the connection is closed (popup is closed) to trigger any corresponding actions like reloading the active website. 1 - https://developer.chrome.com/docs/extensions/mv3/mv3-migration-checklist/#api-background-context
- Loading branch information
Showing
6 changed files
with
69 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,41 @@ | ||
const browserUIWrapper = require('./../../base/ui-wrapper.es6.js') | ||
import browser from 'webextension-polyfill' | ||
|
||
module.exports = { | ||
/** | ||
* Collect any 'user-action' messages and pass them along | ||
* when we call `browserUIWrapper.popupUnloaded` - this allows the background script | ||
* to make a decision about whether to reload the current page. | ||
* Passes any 'user-action' messages through a messaging connection to the | ||
* extension's background, so that they can be used at the point this window | ||
* is closed. This allows the background script to make a decision about | ||
* whether to reload the current page. | ||
* | ||
* For example: If a user has manually disabled protections in the popup, | ||
* we don't immediately reload the page behind - but instead we want to wait until the | ||
* popup is closed. | ||
* we don't immediately reload the page behind - but instead we want to wait | ||
* until the popup is closed. | ||
* | ||
* @param store | ||
*/ | ||
registerUnloadListener: function (store) { | ||
/** @type {string[]} */ | ||
const userActions = [] | ||
let connection = null | ||
|
||
// Create a messaging connection to the background. If the connection is | ||
// broken by the background, the background ServiceWorker was restarted | ||
// and the connection must be recreated + any earlier user actions | ||
// resent. | ||
const reconnect = () => { | ||
connection = browser.runtime.connect({ name: 'popup' }) | ||
connection.onDisconnect.addListener(reconnect) | ||
for (const userAction of userActions) { | ||
connection.postMessage(userAction) | ||
} | ||
} | ||
reconnect() | ||
|
||
store.subscribe.on('action:site', (event) => { | ||
if (event.action === 'user-action') { | ||
userActions.push(event.data) | ||
connection.postMessage(event.data) | ||
} | ||
}) | ||
window.addEventListener('unload', function () { | ||
browserUIWrapper.popupUnloaded(userActions) | ||
}, false) | ||
} | ||
} |