The shared spaces API provides a standard way for addons to add their own custom UI elements to areas (“spaces”) inside Scratch.
For example, both the “mouse position” and “clone counter” addons add their own HTML elements to the project player stage header, after the stop button.
parentElement.appendChild(ownElement)
. Instead, addons should use shared spaces by calling this method.See below for more information, and a list of existing shared spaces.
Example
As an example, this is how the “pause button” addon could be adding an element to the afterGreenFlag
space:
// Creating an element and listening to events works like usually
const pauseButton = document.createElement("img");
pauseButton.src = addon.self.dir + "/play.svg";
pauseButton.addEventListener("click", changePauseState);
// Wait until the stage header exists before adding the pause button, like usually
await addon.tab.waitForElement("[class^='green-flag']");
// This number was reserved for the pause button.
// No other addon should use this order number in the `afterGreenFlag` space.
const PAUSE_BUTTON_ORDER_NUMBER = 0;
// appendToSharedSpace is used below, instead of typical element.appendChild()
addon.tab.appendToSharedSpace({
space: "afterGreenFlag",
element: pauseButton,
order: PAUSE_BUTTON_ORDER_NUMBER
});
Description
Order numbers prevent adding new UI elements from being a racy operation, where users would observe that the order of UI elements added by third-party browser extensions varies unpredictably on each page session.
Regarding order numbers
- Each shared space has its own order number set, independent from all other shared spaces.
- Order numbers are typically positive integers, but negative and decimal numbers are also supported.
- The element with the lowest number will always become the first child of the corresponding HTML element.
- Any addon can theoretically call this method with any order number, and no error will be thrown. Order numbers aren’t logically reserved. Developers are in charge of making sure each addon is calling this method with a suitable order number.
- Multiple order numbers may be reserved for a single addon within a shared space.
- In some cases, 2 or more addons may use the same order number within the same shared space, as long as only one of the elements can be visible at once.
addon.tab.waitForElement
method is still necessary in most situations.
Defining shared spaces
The list of existing shared spaces is hardcoded inside the code definition of the method (addon-api/content-script/Tab.js
).
Each shared space has a name, and is defined by these properties:
- Space parent element: the HTML element where addons would typically add their UI elements inside of. This will be the parent element of all elements added to the shared space.
- Space starting bound (optional): the sibling after which shared space items should always be added.
- Space ending bound (optional): the sibling before which shared space items should always be added.
- Accepts
scope
option: whether a space can exist multiple times per page. In those cases, addons should manually provide an HTML element that contains the wanted parent element.
As an example, the definition of the afterGreenFlag
shared space calls document.querySelector('div[class^="controls_controls-container"]')
to find the space parent element. Additionally, this space does not use the scope
option, because there can only be 1 project player per document.
In cases where only one addon is adding custom UI elements, it’s not necessary to create a space for it.
Method
Parameter | Type | Required | Description | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
options | Object |
Yes |
|
Return value | boolean |
Description | Whether the element was added. Typically ignored. |
List of shared spaces
Scratch editor spaces
stageHeader
Elements added to this space will be positioned next to the “small stage” and “big stage” buttons.
This is typically the right side of the stage header. This might not be true in RTL languages, or if the editor-buttons-reverse-order
addon is enabled.
This shared space may exist in 5 different situations:
- Project in
editor
mode, small stage disabled (default). - Project in
editor
mode, small stage enabled. Elements from this space are often hidden in this situation. - Project in
editor
mode,hide-stage
addon functionality triggered by the user. - Project in
projectpage
mode. - Project in
embed
mode.
This shared space will not exist while on fullscreen
mode. See fullscreenStageHeader.
Typical CSS properties: margin-right: 0.2rem
(LTR), margin-left: 0.2rem
(RTL)
Space parent element | div[class^="stage-header_stage-size-row"] |
Space starting bound | None |
Space ending bound | "Small stage" button or "full screen" button |
scope option used |
❌ |
Addon ID | Element | Order number | Visibility in small stage mode |
---|---|---|---|
debugger |
Debugger button | 0 | Hidden |
gamepad |
Gamepad button | 1 | Hidden |
fullscreenStageHeader
See stageHeader. Full screen can be triggered both from the project page and from inside the editor.
Typical CSS properties: margin-right: 0.2rem
(LTR), margin-left: 0.2rem
(RTL)
Space parent element | div[class^="stage-header_stage-menu-wrapper"] |
Space starting bound | None |
Space ending bound | "Full screen" button |
scope option used |
❌ |
Addon ID | Element | Order number |
---|---|---|
gamepad |
Gamepad button | 0 |
afterGreenFlag
Elements added to this space will be positioned between the green flag and the stop button.
This space will exist in all situations where a project player also exists.
Typical CSS properties: padding: 0.375rem
Space parent element | div[class^="controls_controls-container"] |
Space starting bound | Green flag button |
Space ending bound | Stop button |
scope option used |
❌ |
Addon ID | Element | Order number | Visibility in small stage mode |
---|---|---|---|
pause |
Pause button | 0 | Visible |
afterStopButton
Elements added to this space will be positioned after the project control buttons.
This space will exist in all situations where a project player also exists.
Typical CSS properties: padding-left: 0.25rem; padding-right: 0.25rem
Space parent element | div[class^="controls_controls-container"] |
Space starting bound | Stop button |
Space ending bound | None |
scope option used |
❌ |
Addon ID | Element | Order number | Visibility in small stage mode |
---|---|---|---|
mute-project |
Muted project indicator (only visible if vol-slider disabled) |
0 | Visible |
vol-slider |
Muted project indicator and volume slider | 0 | Hidden |
mouse-pos |
Mouse coordinates | 1 | Hidden |
clone-count |
Clone count | 2 | Hidden |
afterSoundTab
Elements added to this space will be positioned after the “sounds” tab.
Typical DOM classes for elements added to this space: addon.tab.scratchClass("react-tabs_react-tabs__tab", "gui_tab")
The order number typically matches the reserved value for redux.state.scratchGui.editorTab.activeTabIndex
.
Space parent element | div[class^="react-tabs_react-tabs__tab-list"] |
Space starting bound | "Sounds" tab |
Space ending bound | Search bar added by find-bar addon |
scope option used |
❌ |
Addon ID | Element | Order number |
---|---|---|
variable-manager |
"Variables" tab | 3 |
Scratch website spaces
afterCopyLinkButton
Elements added to this space will be positioned after the “copy link” button in project pages.
Typical DOM classes for elements added to this space: button
, action-button
Space parent element | .flex-row.action-buttons |
Space starting bound | "Copy link" button |
Space ending bound | None |
scope option used |
❌ |
Addon ID | Element | Order number |
---|---|---|
remix-tree-button |
"Remix tree" button | 0 |
beforeRemixButton
Elements added to this space will be positioned before the “remix” or “see inside” buttons in project pages.
Space parent element | div.project-buttons |
Space starting bound | None |
Space ending bound | "Remix" button or "see inside" button |
scope option used |
❌ |
Addon ID | Element | Order number |
---|---|---|
project-info |
Sprite and script count | 0 |
turbowarp-player |
TurboWarp button | 1 |
remix-button |
Remix button (only visible in own projects) | 9 |
Scratch forums spaces
forumsBeforePostReport
Elements added to this space will be positioned before the “report” button in a specific post.
If the “report” button does not exist (user is logged out), a visible placeholder dot will be added to the post automatically to act as a separator between the forumsBeforePostReport
and forumsAfterPostReport
spaces.
Addition of the |
separator is handled by the shared spaces API.
Space parent element | .postfootright > ul |
Space starting bound | None |
Space ending bound | "Report" button |
scope option used |
✔️ (usually a div.blockpost ) |
Addon ID | Element | Order number |
---|---|---|
my-ocular |
Reactions | 0 |
my-ocular |
Reaction menu | 1 |
my-ocular |
View in Ocular button | 2 |
hide-signatures |
"Show signature" button | 9 |
forum-id |
"Quote post number" button | 10 |
forumsAfterPostReport
Elements added to this space will be positioned after the “report” button in a specific post.
See forumsBeforePostReport for more information.
Space parent element | .postfootright > ul |
Space starting bound | "Report" button |
Space ending bound | None |
scope option used |
✔️ (usually a div.blockpost ) |
Addon ID | Element | Order number |
---|---|---|
show-bbcode |
Show BBCode button | 0 |
Comments
Make sure to follow the code of conduct. You can see this comment section on GitHub Discussions, as well as editing and removing your comment.