Skip to content
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

Bug 1943050 - new userScripts API content #38073

Merged
merged 26 commits into from
Feb 25, 2025
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
8485776
Move legacy userScripts API documentation
rebloor Feb 5, 2025
02602fb
Deleted content
rebloor Feb 5, 2025
6882c17
Missing slug updates
rebloor Feb 5, 2025
a55a6d9
remove dup
rebloor Feb 5, 2025
13926ce
Updated userScripts main article and type and method stubs
rebloor Feb 10, 2025
2c4ed84
Correct ScriptSource stub
rebloor Feb 10, 2025
e076b22
Type details
rebloor Feb 10, 2025
fbae885
userScript method details
rebloor Feb 11, 2025
1cc58fa
Adds permissions details
rebloor Feb 12, 2025
de94fad
runtime API additions
rebloor Feb 12, 2025
9820157
Release note
rebloor Feb 13, 2025
df5cd85
Merge branch 'main' into Bug-1943050-userScripts-API-new-content
rebloor Feb 18, 2025
f5f897a
Apply suggestions from review
rebloor Feb 18, 2025
b000936
Removed based on chromium notes
rebloor Feb 18, 2025
5675d22
Eval space fix?
rebloor Feb 18, 2025
23d1d2e
Runtime event permission requirements
rebloor Feb 18, 2025
e26c543
Additional information about configurations
rebloor Feb 19, 2025
ef4ae42
Final feedback updates
rebloor Feb 19, 2025
0350cdb
Apply suggestions from review
rebloor Feb 20, 2025
800c1f2
Corrections to suggested changes
rebloor Feb 20, 2025
5750c8b
Further feedback updates
rebloor Feb 20, 2025
10d4a80
Apply suggestions from review
rebloor Feb 20, 2025
fed7682
Apply suggestions from review
rebloor Feb 22, 2025
c8c17db
Remove unnecessary space
rebloor Feb 22, 2025
8bbd328
Update files/en-us/mozilla/add-ons/webextensions/api/userscripts/regi…
Rob--W Feb 23, 2025
b8ed93a
Final review tweaks
rebloor Feb 24, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion files/en-us/_redirects.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6123,7 +6123,11 @@
/en-US/docs/Mozilla/Add-ons/WebExtensions/API/proxy/registerProxyScript /en-US/docs/Mozilla/Add-ons/WebExtensions/API/proxy
/en-US/docs/Mozilla/Add-ons/WebExtensions/API/proxy/unregister /en-US/docs/Mozilla/Add-ons/WebExtensions/API/proxy
/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/moveInSuccession() /en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/moveInSuccession
/en-US/docs/Mozilla/Add-ons/WebExtensions/API/userScripts/RegisteredUserScript/RegisteredUserScript.unregister() /en-US/docs/Mozilla/Add-ons/WebExtensions/API/userScripts/RegisteredUserScript/unregister
/en-US/docs/Mozilla/Add-ons/WebExtensions/API/userScripts/RegisteredUserScript/RegisteredUserScript.unregister() /en-US/docs/Mozilla/Add-ons/WebExtensions/API/userScripts_legacy/RegisteredUserScript/unregister
/en-US/docs/Mozilla/Add-ons/WebExtensions/API/userScripts/RegisteredUserScript/unregister /en-US/docs/Mozilla/Add-ons/WebExtensions/API/userScripts_legacy/RegisteredUserScript/unregister
/en-US/docs/Mozilla/Add-ons/WebExtensions/API/userScripts/UserScriptOptions /en-US/docs/Mozilla/Add-ons/WebExtensions/API/userScripts_legacy/UserScriptOptions
/en-US/docs/Mozilla/Add-ons/WebExtensions/API/userScripts/Working_with_userScripts /en-US/docs/Mozilla/Add-ons/WebExtensions/API/userScripts_legacy/Working_with_userScripts
/en-US/docs/Mozilla/Add-ons/WebExtensions/API/userScripts/onBeforeScript /en-US/docs/Mozilla/Add-ons/WebExtensions/API/userScripts_legacy/onBeforeScript
/en-US/docs/Mozilla/Add-ons/WebExtensions/API/windows/update() /en-US/docs/Mozilla/Add-ons/WebExtensions/API/windows/update
/en-US/docs/Mozilla/Add-ons/WebExtensions/Accessible_guidelines https://extensionworkshop.com/documentation/develop/build-an-accessible-extension/
/en-US/docs/Mozilla/Add-ons/WebExtensions/Add-on_ID https://extensionworkshop.com/documentation/develop/extensions-and-the-add-on-id/
Expand Down
32 changes: 16 additions & 16 deletions files/en-us/_wikihistory.json
Original file line number Diff line number Diff line change
Expand Up @@ -14426,22 +14426,6 @@
"modified": "2020-10-15T22:20:45.849Z",
"contributors": ["rebloor", "irenesmith", "bershanskiy", "pesar81"]
},
"Mozilla/Add-ons/WebExtensions/API/userScripts/RegisteredUserScript/unregister": {
"modified": "2020-10-15T22:22:39.367Z",
"contributors": ["rebloor", "hellosct1", "bershanskiy"]
},
"Mozilla/Add-ons/WebExtensions/API/userScripts/UserScriptOptions": {
"modified": "2020-06-22T16:28:43.349Z",
"contributors": ["hellosct1", "MelchiorIm3Tal", "irenesmith"]
},
"Mozilla/Add-ons/WebExtensions/API/userScripts/Working_with_userScripts": {
"modified": "2020-06-22T16:28:43.959Z",
"contributors": ["irenesmith", "hellosct1"]
},
"Mozilla/Add-ons/WebExtensions/API/userScripts/onBeforeScript": {
"modified": "2020-10-15T22:23:14.808Z",
"contributors": ["chrisdavidmills", "rebloor", "bershanskiy"]
},
"Mozilla/Add-ons/WebExtensions/API/userScripts/register": {
"modified": "2020-10-15T22:21:40.204Z",
"contributors": [
Expand All @@ -14454,6 +14438,22 @@
"stoyanster"
]
},
"Mozilla/Add-ons/WebExtensions/API/userScripts_legacy/RegisteredUserScript/unregister": {
"modified": "2020-10-15T22:22:39.367Z",
"contributors": ["rebloor", "hellosct1", "bershanskiy"]
},
"Mozilla/Add-ons/WebExtensions/API/userScripts_legacy/UserScriptOptions": {
"modified": "2020-06-22T16:28:43.349Z",
"contributors": ["hellosct1", "MelchiorIm3Tal", "irenesmith"]
},
"Mozilla/Add-ons/WebExtensions/API/userScripts_legacy/Working_with_userScripts": {
"modified": "2020-06-22T16:28:43.959Z",
"contributors": ["irenesmith", "hellosct1"]
},
"Mozilla/Add-ons/WebExtensions/API/userScripts_legacy/onBeforeScript": {
"modified": "2020-10-15T22:23:14.808Z",
"contributors": ["chrisdavidmills", "rebloor", "bershanskiy"]
},
"Mozilla/Add-ons/WebExtensions/API/webNavigation": {
"modified": "2020-10-15T21:38:48.088Z",
"contributors": ["fscholz", "wbamberg", "abbycar"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@ It also provides messaging APIs enabling you to:
- {{WebExtAPIRef("runtime.connectNative()")}}
- : Connects the extension to a native application on the user's computer.
- {{WebExtAPIRef("runtime.sendMessage()")}}
- : Sends a single message to event listeners within your extension or a different extension. Similar to {{WebExtAPIRef('runtime.connect')}} but only sends a single message, with an optional response.
- : Sends a message to event listeners within your extension or a different extension. Similar to {{WebExtAPIRef('runtime.connect')}} but only sends a single message, with an optional response.
- {{WebExtAPIRef("runtime.sendNativeMessage()")}}
- : Sends a single message from an extension to a native application.
- : Sends a message from an extension to a native application.
- {{WebExtAPIRef("runtime.getPlatformInfo()")}}
- : Returns information about the current platform.
- {{WebExtAPIRef("runtime.getBrowserInfo()")}}
Expand All @@ -98,10 +98,14 @@ It also provides messaging APIs enabling you to:
- : Fired when a connection is made with either an extension process or a content script.
- {{WebExtAPIRef("runtime.onConnectExternal")}}
- : Fired when a connection is made with another extension.
- {{WebExtAPIRef("runtime.onserScriptConnect")}}
- : Fired when a connection is made with a user script registered by the extension.
- {{WebExtAPIRef("runtime.onMessage")}}
- : Fired when a message is sent from either an extension process or a content script.
- {{WebExtAPIRef("runtime.onMessageExternal")}}
- : Fired when a message is sent from another extension. Cannot be used in a content script.
- {{WebExtAPIRef("runtime.onUserScriptMessage")}}
- : Fired when a message is sent from a user script registered by the extension.
- {{WebExtAPIRef("runtime.onPerformanceWarning")}}
- : Fired when a runtime performance issue is detected for the extension.
- {{WebExtAPIRef("runtime.onRestartRequired")}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ Values of this type are objects. They contain the following properties:

If the sender is a script running in a web page (including content and normal page scripts), then `url` is the web page URL. If the script is running in an iframe, `url` is the iframe's URL.

- `userScriptWorldId` {{optional_inline}}
- : `string`. The `worldId` of the `USER_SCRIPT` world that sent the message. Only present in {{WebExtAPIRef("runtime.onUserScriptMessage")}} and in {{WebExtAPIRef("port.sender")}} for {{WebExtAPIRef("runtime.onUserScriptConnect")}}.

{{WebExtExamples}}

## Browser compatibility
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
---
title: runtime.onUserScriptConnect
slug: Mozilla/Add-ons/WebExtensions/API/runtime/onUserScriptConnect
page-type: webextension-api-event
browser-compat: webextensions.api.runtime.onUserScriptConnect
---

{{AddonSidebar}}

Fired when a connection is made with a user script from one of the extension's [`USER_SCRIPT` worlds](/en-US/docs/Mozilla/Add-ons/WebExtensions/API/userScripts/ExecutionWorld).

A user script can only connect and then sent messages from a `USER_SCRIPT` world that is configured by {{WebExtAPIRef('userScripts.configureWorld()')}} with `messaging` set to `true`.

## Syntax

```js-nolint
browser.runtime.onUserScriptConnect.addListener(listener)
browser.runtime.onUserScriptConnect.removeListener(listener)
browser.runtime.onUserScriptConnect.hasListener(listener)
```

Events have three functions:

- `addListener(listener)`
- : Adds a listener to this event.
- `removeListener(listener)`
- : Stop listening to this event. The `listener` argument is the listener to remove.
- `hasListener(listener)`
- : Checks whether a `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

## addListener syntax

### Parameters

- `function`

- : The function called when this event occurs. The function is passed this argument:

- `port`
- : {{WebExtAPIRef('runtime.Port')}}. An object connecting the current script to the other context.

## Examples
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's delete this full example. It is inaccurate and incomplete, and I'd like to get the primary doc completed without being blocked on the example.

  • Missing userScripts.configureWorld() call.
  • Uses browserAction (which is MV2-only) instead of action API (which is MV3 only).
  • Example shows bad practice of storing the port in a global variable with the expectation of the variable sticking around; this is not guaranteed in event pages/service workers (because these may suspend).


This user script:

- Connects to the background script and stores `Port` in a variable `myPort`.
- Listens for messages on `myPort` and logs them.
- Sends messages to the background script using `myPort` when the user clicks the document.

```js
// user-script.js

let myPort = browser.runtime.connect({ name: "port-from-us" });
myPort.postMessage({ greeting: "hello from user script" });

myPort.onMessage.addListener((m) => {
console.log("In the user script, received message from background script: ");
console.log(m.greeting);
});

document.body.addEventListener("click", () => {
myPort.postMessage({ greeting: "they clicked the page!" });
});
```

The corresponding background script:

- Listens for connection attempts from the user script, and when it receives a connection attempt:

- Stores the port in a variable named `portFromUS`.
- Sends the content script a message using the port.
- Starts listening to messages received on the port and logs them.

- Sends messages to the content script using `portFromUS` when the user clicks the extension's browser action.

```js
// background-script.js

let portFromCS;

function connected(p) {
portFromUS = p;
portFromUS.postMessage({ greeting: "hi there user script!" });
portFromUS.onMessage.addListener((m) => {
console.log("In background script, received message from user script");
console.log(m.greeting);
});
}

browser.runtime.onUserScriptConnect.addListener(connected);

browser.browserAction.onClicked.addListener(() => {
portFromUS.postMessage({ greeting: "they clicked the button!" });
});
```

{{WebExtExamples}}

## Browser compatibility

{{Compat}}

> [!NOTE]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's delete all of this copyright etc stuff (in every article related to userScripts).

The userScripts API is designed together with me in the WECG; we don't need to call out Chromium's source and license header here.

> This API is based on Chromium's [`chrome.runtime`](https://developer.chrome.com/docs/extensions/reference/api/runtime#event-onUserScriptConnect) API. This documentation is derived from [`runtime.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/runtime.json) in the Chromium code.

<!--
// Copyright 2015 The Chromium Authors. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
---
title: runtime.onUserScriptMessage
slug: Mozilla/Add-ons/WebExtensions/API/runtime/onUserScriptMessage
page-type: webextension-api-event
browser-compat: webextensions.api.runtime.onUserScriptMessage
---

{{AddonSidebar}}

Use this event to listen for messages sent from one of the extension's [`USER_SCRIPT` worlds](/en-US/docs/Mozilla/Add-ons/WebExtensions/API/userScripts/ExecutionWorld).

A user script can only send messages using {{WebExtAPIRef('runtime.sendMessage')}} from a `USER_SCRIPT` world that is configured by {{WebExtAPIRef('userScripts.configureWorld()')}} with `messaging` set to `true`.

Along with the message, the listener is passed:

- a `sender` object with details about the message sender.
- a `sendResponse` function the listener can use to send a response back to the sender.

## Syntax

```js-nolint
browser.runtime.onUserScriptMessage.addListener()
browser.runtime.onUserScriptMessage.removeListener(listener)
browser.runtime.onUserScriptMessage.hasListener(listener)
```

Events have three functions:

- `addListener(listener)`
- : Adds a listener to this event.
- `removeListener(listener)`
- : Stop listening to this event. The `listener` argument is the listener to remove.
- `hasListener(listener)`
- : Checks whether a `listener` is registered for this event. Returns `true` if it is listening, `false` otherwise.

## addListener syntax

### Parameters

- `listener`

- : The function called when this event occurs. The function is passed these arguments:

- `message`
- : `object`. The message. This is a JSON-ifiable object.
- `sender`
- : A {{WebExtAPIRef('runtime.MessageSender')}} object representing the sender of the message.
- `sendResponse`

- : A function to call, at most once, to send a response to the message. The function takes one argument, which is any JSON-ifiable object. This argument is passed back to the message sender.

If you have more than one `onUserScriptMessage` listener in the same document, then only one can send a response.

To send a response synchronously, call `sendResponse` before the listener function returns. To send a response asynchronously, do one of these:

- keep a reference to the `sendResponse` argument and return `true` from the listener function. You can then call `sendResponse` after the listener function has returned.
- return a [`Promise`](/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) from the listener function and resolve the promise when the response is ready.

## Examples

In this example, a user script in a `USER_SCRIPT` world with the ID `myScriptWorld` sends a message to the extension that registered it:

```js
// The user script
// Send a message to the extension that registered the user script
browser.runtime.sendMessage("my message");
```

```js
// The extension that registered the user script

function handleMessage(message, sender) {
// check that the message originated from "myScriptWorld" world
if (sender.userScriptWorldI === "myScriptWorld") {
// process message
}
}

browser.runtime.onUserScriptMessage.addListener(handleMessage);
```

{{WebExtExamples}}

## Browser compatibility

{{Compat}}

> [!NOTE]
> This API is based on Chromium's [`chrome.runtime`](https://developer.chrome.com/docs/extensions/reference/api/runtime#event-onUserScriptMessage) API. This documentation is derived from [`runtime.json`](https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/runtime.json) in the Chromium code.

<!--
// Copyright 2015 The Chromium Authors. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ Values of this type are objects. They contain the following properties:
- `postMessage`
- : `function`. Send a message to the other end. This takes one argument, which is a serializable value (see [Data cloning algorithm](/en-US/docs/Mozilla/Add-ons/WebExtensions/Chrome_incompatibilities#data_cloning_algorithm)) representing the message to send. It will be delivered to any script listening to the port's `onMessage` event, or to the native application if this port is connected to a native application.
- `sender` {{optional_inline}}
- : {{WebExtAPIRef('runtime.MessageSender')}}. Contains information about the sender of the message. This property will only be present on ports passed to `onConnect`/`onConnectExternal` listeners.
- : {{WebExtAPIRef('runtime.MessageSender')}}. Contains information about the sender of the message. Only present on ports passed to the {{WebExtAPIRef('runtime.onConnect')}}, {{WebExtAPIRef('runtime.onConnectExternal')}}, or {{WebExtAPIRef("runtime.onUserScriptConnect")}} listeners.

## Lifecycle

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
title: userScripts.configureWorld()
slug: Mozilla/Add-ons/WebExtensions/API/userScripts/configureWorld
page-type: webextension-api-function
browser-compat: webextensions.api.userScripts.configureWorld
---

{{AddonSidebar}}

Configures a `USER_SCRIPT` execution environment for the extension.

This is an asynchronous method that returns a {{JSxRef("Promise")}}.

## Syntax

```js-nolint
const configuredWorld = await browser.userScripts.configureWorld(
properties // object
);
```

### Parameters

- `properties`
- : {{WebExtAPIRef("userScripts.WorldProperties")}}. Details of the configuration for a `USER_SCRIPT` world.

### Return value

A {{JSxRef("Promise")}} fulfilled with no arguments if the request is successful. If the request fails, the promise is rejected with an error message.

{{WebExtExamples("h2")}}

## Browser compatibility

{{Compat}}
Loading