-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add example using MV3 userScripts API #576
base: main
Are you sure you want to change the base?
Conversation
"browser_specific_settings": { | ||
"gecko": { | ||
"id": "[email protected]", | ||
"strict_min_version": "134.0a1" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: I put strict_min_version
134 because this is the first version of Firefox where the API landed, behind the extensions.userScripts.mv3.enabled
preference. I may update it to 135 or 136 once we ship it by default on release.
Note: |
This is a demo extension, not a full-fledged user script manager. For it to be a complete user script manager, it would have to define the full |
I understand.. the intension was to demonstrate that the MV3 userScripts API supports |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this review I mostly identified small tweaks. The core functionality looks quite solid. Nice work, @Rob--W!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Rob--W, if you want to publish this example before the 135, I think we should add some installation instructions to the README that mention that you need to enable extensions.userScripts.mv3.enabled
in about:config
.
A user script manager, demonstrating the userScripts API, the permissions API, | ||
`optional_permissions`, and Manifest Version 3 (MV3). | ||
The extension is an example of a | ||
[user script manager](https://en.wikipedia.org/wiki/Userscript_manager). | ||
|
||
This covers the following aspects to extension development: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reword to fix a grammar issue and for clarity. Currently the intro sentence is incomplete.
A user script manager, demonstrating the userScripts API, the permissions API, | |
`optional_permissions`, and Manifest Version 3 (MV3). | |
The extension is an example of a | |
[user script manager](https://en.wikipedia.org/wiki/Userscript_manager). | |
This covers the following aspects to extension development: | |
The extension is an example of a | |
[user script manager](https://en.wikipedia.org/wiki/Userscript_manager). It | |
demonstrates the userScripts API, the permissions API, `optional_permissions`, | |
and Manifest Version 3 (MV3). | |
This demo covers the following aspects to extension development: |
- Minimizing the overhead of background script startup, which is especially | ||
relevant because event pages . |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reword to make this comment more applicable to other browsers. It also addresses the fact that other browsers may also support service workers in the future.
- Minimizing the overhead of background script startup, which is especially | |
relevant because event pages . | |
- Minimizing the overhead of background script startup. This is relevant because | |
Manifest Version 3 extensions uses an event-based background context. |
NOTE: If you accept this suggestion, you should also update this line with a similar change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correcting grammar in suggestion
- Minimizing the overhead of background script startup, which is especially | |
relevant because event pages . | |
- Minimizing the overhead of background script startup. This is relevant because | |
Manifest Version 3 extensions use an event-based background context. |
- Monitoring an optional (userScripts) permission, and dynamically registering | ||
events and scripts based on its availability. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reword for clarity. The parenthetical should appear after the entire phrase that it applies to.
I tend to prefer to include the quotation marks when referring to a permission. That said, I don't know if we have an established pattern one way or the other.
- Monitoring an optional (userScripts) permission, and dynamically registering | |
events and scripts based on its availability. | |
- Monitoring grants for an optional permission (`"userScripts"`), and | |
dynamically registering events and scripts based on its availability. |
- Monitoring an optional (userScripts) permission, and dynamically registering | ||
events and scripts based on its availability. | ||
|
||
- Using the `userScripts` API to register, update and unregister code. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Optional: clarify that the extension is specifically operating on user scripts rather than arbitrary code.
- Using the `userScripts` API to register, update and unregister code. | |
- Using the `userScripts` API to register, update and unregister user script | |
code. |
|
||
## What it does | ||
|
||
This extension is an example of a [user script manager](https://en.wikipedia.org/wiki/Userscript_manager) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: end the sentence with a period.
This extension is an example of a [user script manager](https://en.wikipedia.org/wiki/Userscript_manager) | |
This extension is an example of a [user script manager](https://en.wikipedia.org/wiki/Userscript_manager). |
userScriptsAvailableAtStartup = false; | ||
|
||
// Clear cached state, so that ensureUserScriptsRegistered() will refresh | ||
// the registered user scripts if the permissions is granted again. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// the registered user scripts if the permissions is granted again. | |
// the registered user scripts if the permission is granted again. |
let worldIds = scriptsToRemove.map(s => s.id); | ||
await browser.userScripts.unregister({ worldIds }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Line 145 currently throws the following error:
Uncaught (in promise) Error: Type error for parameter filter (Unexpected property "worldIds") for userScripts.unregister.
Channel: Nightly
Version: 135.0a1 (2024-12-30) (aarch64)
OS: macOS 15.1 (24B83)
I looked through the current version of toolkit/components/extensions/schemas/user_scripts.json
and the current version of UserScriptFilter
only has a ids
property.
It looks like this may be the result of some refactoring that occured during development. The script appears to work as expected if we change the body of the if clause as follows:
let worldIds = scriptsToRemove.map(s => s.id); | |
await browser.userScripts.unregister({ worldIds }); | |
await browser.userScripts.unregister({ ids: scriptsToRemove }); |
} | ||
} | ||
|
||
button.onclick = async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had to double check that re-assigning an onevent handler like this would remove the previous event handler, but it checks out! (mdn, whatwg spec)
"javascript_apis": [ | ||
"userScripts.register", | ||
"runtime.onMessage", | ||
"runtime.sendMessage" | ||
], | ||
"name": "user-script-register" | ||
}, | ||
{ | ||
"description": "A user script manager, demonstrating the userScripts API, permissions API, optional_permissions and Manifest Version 3 (MV3).", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"description": "A user script manager, demonstrating the userScripts API, permissions API, optional_permissions and Manifest Version 3 (MV3).", | |
"description": "A user script manager demonstrating the userScripts API, permissions API, optional_permissions, and Manifest Version 3 (MV3).", |
A user script manager, demonstrating the userScripts API, the permissions API, | ||
`optional_permissions`, and Manifest Version 3 (MV3). | ||
The extension is an example of a | ||
[user script manager](https://en.wikipedia.org/wiki/Userscript_manager). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A user script manager, demonstrating the userScripts API, the permissions API, | |
`optional_permissions`, and Manifest Version 3 (MV3). | |
The extension is an example of a | |
[user script manager](https://en.wikipedia.org/wiki/Userscript_manager). | |
This is an example [user script manager](https://en.wikipedia.org/wiki/Userscript_manager) that demonstrates the userScripts API, the permissions API,`optional_permissions`, and Manifest Version 3 (MV3). |
The extension is an example of a | ||
[user script manager](https://en.wikipedia.org/wiki/Userscript_manager). | ||
|
||
This covers the following aspects to extension development: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This covers the following aspects to extension development: | |
This example illustrates these aspects of extension development: |
|
||
This covers the following aspects to extension development: | ||
|
||
- Showing onboarding UI after installation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Showing onboarding UI after installation. | |
- Showing an onboarding UI after installation. |
|
||
- Showing onboarding UI after installation. | ||
|
||
- Designing background scripts that can restart repeatedly with minimal |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Rob--W as we seem to make the assumption that this is going to be rendered as a markdown document (e.g. use of hyperlink in the introductory paragraph) is there any need to impose line breaks?
|
||
// Now we have computed the changed scripts, apply the changes in this order: | ||
// 1. Unregister obsolete scripts. | ||
// 2. Reset / configure worlds. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// 2. Reset / configure worlds. | |
// 2. Reset or configure worlds. |
// Now we have computed the changed scripts, apply the changes in this order: | ||
// 1. Unregister obsolete scripts. | ||
// 2. Reset / configure worlds. | ||
// 3. Update / register new scripts. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// 3. Update / register new scripts. | |
// 3. Update or register new scripts. |
// 3. Update / register new scripts. | ||
// This order is significant: scripts rely on world configurations, and while | ||
// running this asynchronous script updating logic, the browser may try to | ||
// execute any of the registered scripts when a website loaded in a tab or |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// execute any of the registered scripts when a website loaded in a tab or | |
// execute any of the registered scripts when a website loads in a tab or |
await browser.userScripts.unregister({ worldIds }); | ||
} | ||
|
||
// 2. Reset / configure worlds. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// 2. Reset / configure worlds. | |
// 2. Reset or configure worlds. |
|
||
// 2. Reset / configure worlds. | ||
if (scripts.some(s => s.worldId)) { | ||
// When a userscripts need privileged functionality, we run them in a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// When a userscripts need privileged functionality, we run them in a | |
// When a userscripts need privileged functionality, run them in a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn’t that be "When a userscript needs" or "When userscripts need"?
- Minimizing the overhead of background script startup, which is especially | ||
relevant because event pages . |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correcting grammar in suggestion
- Minimizing the overhead of background script startup, which is especially | |
relevant because event pages . | |
- Minimizing the overhead of background script startup. This is relevant because | |
Manifest Version 3 extensions use an event-based background context. |
} | ||
|
||
/** | ||
* Shows the form where the user can edit or create a new user script. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* Shows the form where the user can edit or create a new user script. | |
* Shows the form where the user can edit or create a user script. |
Description
Add example using MV3 userScripts API. And many other aspects of MV3 development, useful for #496.
Motivation
This example is part of the documentation of the userScripts API.
Additional details
Related issues and pull requests