-
Notifications
You must be signed in to change notification settings - Fork 281
API for other addons
This describes about Tree Style Tab 2.x API for other WebExtensions-based addons. See also old documentation about Legacy TST 0.19.x (Japanese translation)
- Abstract
- Detecting version of TST itself
- Register and unregister your addon to TST
-
Manipulate tree of tabs
- Basics to specify tabs
- Open new tab bypassing TST's tab control behavior
- Open new child tab from a specific tab
- Indent (demote) tab
- Outdent (promote) tab
- Attach existing tab to another as a child
- Detach existing child tab from its parent
- Collapse expanded tree
- Expand collapsed tree
- Toggle collapsed state of tree
- Set "Locked as Collapsed" state of tree
- Control sticky state of tabs at tab bar edges
- Set custom tooltip text to tabs
- Move tree to different position
- Focus to the next/previous sibling tab
- Duplicate tab as child/sibling tab
- Move tabs to a new window (opening new window from tabs)
- Reopen tabs in a container
- Create new group from given tabs
- Close whole tree
- Scroll the tab bar
- Take a tree structure snapshot of tabs
- Apply a tree structure to tabs
- Get tree information
- Override reaction for mouse wheel rotation on the vertical tab bar
- APIs to set custom state for tabs
-
Notification messages from TST
- When the TST itself is initialized
- When the TST sidebar is shown/hidden
- When any context menu item is clicked
- When the context menu is opened and closed
- When the TST finishes its handling for a newly opened tab
- When one or more tabs are rendered/un-rendered
- When a tab is clicked
- When the new tab button is clicked
- When the non-tab area is clicked
- When the pointer is moved over tabs
- When the tab bar becomes scrollable or unscrollable
- When tree structure is modified
- When tree is collapsed or expanded
- When a tab is stuck or unstuck to/from tab bar edges
- When permissions for your addon are changed
- Suppress handling of new tabs by TST
- Suppress unintentional focus change by TST
- Suppress unintentional expansion of collapsed tree by TST
- Suppress unintentional collapsion of expanded tree by TST
- Suppress autofixing of tree structure for moved tabs
- Suppress auto-scrolling to activated tabs
- Suppress the "Are you sure you want to continue?" for closing multiple tabs
- Suppress auto-grouping of newly opened tabs
- Manipulate bookmarks
- Appendix: Index of message types
(generated by Table of Contents Generator for GitHub Wiki)
And there are more APIs for specific purposes.
Important Note: this document assumes that you have experienced to develop one ore mroe Firefox extensions. If you've never done it, I recommend you to see the basic document for extensions authors.
To communicate with TST, your addon can send messages to TST via browser.runtime.sendMessage()
.
You need to specify TST's internal ID treestyletab@piro.sakura.ne.jp
as the first argument of the method.
Any API message for TST is an object with a string property named type
, which indicates the type of the message.
For example:
const TST_ID = 'treestyletab@piro.sakura.ne.jp';
let success = await browser.runtime.sendMessage(TST_ID, {
type: 'register-self',
name: 'My Addon',
icons: browser.runtime.getManifest().icons,
listeningTypes: ['tab-mousedown', 'tab-mouseup'],
permissions: ['tabs']
});
You'll receive returned value from TST APIs as a promise.
On TST 4.0 and later, you can send multiple messages at once to reduce cross-addon messagings, like as:
const TST_ID = 'treestyletab@piro.sakura.ne.jp';
let responses = await browser.runtime.sendMessage(TST_ID, {
messages: [
{ type: 'get-tree',
tabId: 1 },
{ type: 'set-extra-contents',
tabId: 2,
place: 'tab-indent',
contents: ... },
{ type: 'set-extra-contents',
tabId: 3,
place: 'tab-behind',
contents: ... },
],
});
You'll get an array of responses for sent messages.
On TST 3.5.4 and later, browser.runtime.connect()
is also available to send messages if you don't need responses. For example:
const TSTConnection = browser.runtime.connect(TST_ID, { name: `connection from ${browser.runtime.id}` });
TSTConnection.postMessage({
type: 'scroll-lock'
});
This way will help you to send very large number of messages with better performance. And of couse you can send multiple messages at once with this method, like as the previous example, on TST 4.0 and later.
Here is a boilerplate to implement your custom helper addon for TST.
This page explains most APIs but some specific APIs are explained in sub pages:
TST 4.0 and later supports a message type get-version
.
Example usage:
let TSTVersion = await browser.runtime.sendMessage(TST_ID, { type: 'get-version' });
// TSTVersion = "4.0.1" or something string if responded, otherwise `null` will be got.
You'll get null
response if the version of TST is older than 4.0, so you can deactivate some features if it depends on lately versions of TST but not updated yet on the runtime environment.
You need to register your addon to TST, to receive notification messages from TST.
Send a message with the type register-self
to TST, like:
async function registerToTST() {
try {
let result = await browser.runtime.sendMessage(TST_ID, {
type: 'register-self',
// The name of your addon (string)
name: browser.i18n.getMessage('extensionName'),
// Icons (string, used for extra context menu items, works on TST 2.4.18 and later)
icons: browser.runtime.getManifest().icons, // { '16': '/path/to/icon.png', 24: '...', ... }
// The list of listening message types (array of strings)
listeningTypes: ['tab-mousedown', 'tab-mouseup'],
// Accept bulk messages from TST (boolean, works on TST 4.0 and later)
allowBulkMessaging: true,
// Receive notified messages with light tree (boolean, works on TST 4.0 and later)
lightTree: true,
// Extra style rules applied in the sidebar (string)
style: `
.tab.unread {
color: red;
}
`,
// Extra permissions to receive tab information via TST's API (array of strings, works on TST 3.0.12 and later)
permissions: ['tabs']
});
}
catch(e) {
// TST is not available
}
}
registerToTST();
On TST 3.0.12 and later, the returned promise will be filled with an object with following properties, when TST successfully process the message:
-
grantedPermissions
: An array of strings, currently granted permissions. -
privateWindowAllowed
: A boolean, indicating allowed (or not) to be notified messages from private windows.
On TST 3.0.11 and older, the promise is filled with just a boolean value true
.
Important note: please remind that options are sticky (on TST 4.0.25 or earlier treats some options sticky, TST 4.0.26 and later treats all sticky.) If you call the register-self
API again only with some options, other options will be inherited from the previous API call, including the case you reload the addon. Thus you need to specify blank or false values for options explicitly if you want those options should become default state. This behavior is designed mainly for cases that calling the API multiple times to update style
option with omitted other options frequently. (See also the discussion at the issue #3666.)
When you addon is loaded and initialized before TST is initialized, no one responds to the message and you'll fail to register your addon. Because TST cannot broadcast any message to unknown addons, your addon won't receive any message from TST until it is successfully registered. So the user need to reload your addon manually if he install TST after your addon.
TST caches IDs of known registered addons and sends a message ready
to them when TST is successfully initialized.
For secondary and after startup cases, you should listen the message to re-register your addon safely, like:
function onMessageExternal(message, sender) {
switch (sender.id) {
case TST_ID:
switch (message.type) {
...
case 'ready':
case 'permissions-changed':
registerToTST(); // passive registration for secondary (or after) startup
break;
...
}
break;
}
}
browser.runtime.onMessageExternal.addListener(onMessageExternal);
registerToTST(); // aggressive registration on initial installation
After your addon is successfully registered, it will receive messages from TST via the event listener registered to browser.runtime.onMessageExternal
. Note that you should keep listening the ready
message from TST even if you successfully registered your addon, because you need to re-register your addon again when TST is reloaded while your addon is working.
Note for Tree Style Tab 2.4.17 and later: You should list message types only your addon really requires, via the listeningTypes
parameter. Otherwise, TST may change some behaviors of itself to wait responses from external addons. For backward compatibility, all known type messages on TST 2.4.16 (ready
, shutdown
, tab-clicked
, tab-mousedown
, tab-mouseup
, tabbar-clicked
, tabbar-mousedown
, and tabbar-mouseup
) will be delivered to your addon if you omit this parameter.
On TST 4.0 and later, you can specify an option lightTree: true
to minimize messaging cost, like:
async function registerToTST() {
try {
let result = await browser.runtime.sendMessage(TST_ID, {
type: 'register-self',
...
listeningTypes: ['tabs-rendered'],
lightTree: true,
allowBulkMessaging: true, // Recommended to combine this option. See the next section also.
...
});
}
catch(e) {
// TST is not available
}
}
registerToTST();
tab
, tabs
and other tab-like properties in notification messages delivered to your addon will become light tree when you specify this option.
Huge number tabs (ex. 3000 or more) with full tree format may eat too much RAM while messagings and it may trigger GC too frequently.
Light tree format expects reducing such performance issues.
Important note: you need to specify listeningTypes: []
explicitly if your addon listened some events in past versions and you want all events are unlistened at a new version of your addon. TST memorize last state of the option listeningTypes
and it will be applied to future API calls automatically, even if you opmit the option.
For better performance, TST 4.0 and later may send multiple messages with some one-way notification types in bulk, if you registered your addon with the flag allowBulkMessaging: true
.
You'll receive a bulk messages as an object containing a property messages
, and messages
will be an array of regular notification messages.
Here is an example to handle bulk messages:
async function registerToTST() {
try {
let result = await browser.runtime.sendMessage(TST_ID, {
type: 'register-self',
name: browser.i18n.getMessage('extensionName'),
icons: browser.runtime.getManifest().icons,
...
allowBulkMessaging: true, // IMPORTANT!
...
});
}
catch(e) {
}
}
registerToTST();
function onMessageExternal(message, sender) {
switch (sender.id) {
case TST_ID:
if (message && message.messages) { // bulk message
for (const oneMessage of message.messages) {
onMessageExternal(oneMessage, sender);
}
}
switch (message.type) {
...
}
break;
}
}
browser.runtime.onMessageExternal.addListener(onMessageExternal);
Important note: you need to specify allowBulkMessaging: false
explicitly if your addon accepted bulk messages in past versions and you want all messages are given separately for a new version of your addon. TST memorize last state of the option allowBulkMessaging: true
and it will be applied to future API calls automatically, even if you opmit the option.
You can unregister your addon from TST, to stop listening of notification messages. This will also remove all of following:
- The extra style rules that you applied to TST's sidebar.
- The sub panel that was reigstered.
For unregisteration you need to send a unregister-self
message from your addon:
let success = await browser.runtime.sendMessage(TST_ID, {
type: 'unregister-self'
});
But actually you may not send such a message effectively, because beforeunload
, unload
and any other DOM event, or runtime.connect()
way is not available to detect unloading of your addon.
Therefore TST provides another way for unregisteration that detects when your extension is no longer available: a wait-for-shutdown
type notification, on Tree Style Tab 3.1.2 and later.
This method is similar to how the wait-for-shutdown
message that can be sent to TST works. Your extension needs to add the value wait-for-shutdown
to listeningTypes
of the 'register-self' message, and respond to the notification with a maybe never-resolved promise:
async function registerToTST() {
try {
let result = await browser.runtime.sendMessage(TST_ID, {
type: 'register-self',
name: browser.i18n.getMessage('extensionName'),
listeningTypes: ['wait-for-shutdown'] // IMPORTANT!
});
}
catch(e) {
// TST is not available
}
}
function onMessageExternal(message, sender) {
switch (sender.id) {
case TST_ID:
...
switch (message.type) {
...
case 'wait-for-shutdown': // IMPORTANT!
return new Promise(() => { // Yes, this may not be resolved never.
window.addEventListener('beforeunload', () => resolve(true)); // IMPORTANT!
});
...
}
break;
}
}
browser.runtime.onMessageExternal.addListener(onMessageExternal);
registerToTST();
For more details: the returned promise can be resolved or rejected manually if you needed.
- If the promise is resolved with a
true
value or rejected with an error, then TST will unregister your extension automatically. - If the promise is resolved with a
false
value, then TST will not unregister your extension, so this way will effective for reloading or other cases. - The promise is rejected by Firefox itself automatically, when your addon is unloaded. (The example above aspects this case.)
-
A completely blank promise like
new Promise(() => {})
won't work as you expected due to something "timeout" mechanism of FIrefox itself. If the returned promise doesn't do anything then there seems to be a timeout by Firefox, so it only works if tracked your extension is disabled within about 10 seconds after this promise is used as a response to a message. After that it will not throw an error for the waiting extension. Thus you should put something code to call the resolver function, even if the code may not be performed.
Here is a complex case example:
const promisedShutdown = new Promise((resolve, reject) => {
// If we use the following then the returned promise will be rejected when
// this extension is disabled even for longer times:
window.addEventListener('beforeunload', () => resolve(true));
});
function onMessageExternal(message, sender) {
switch (sender.id) {
case TST_ID:
...
switch (message.type) {
...
case 'wait-for-shutdown':
return promisedShutdown;
...
}
break;
}
}
browser.runtime.onMessageExternal.addListener(onMessageExternal);
Please note that any wait-for-shutdown
notification won't be sent on TST 3.1.1 and older.
On TST 3.0.12 and later, tree item information and notification messages in private windows won't be provided if any of following cases:
- TST itself is not granted to be activated on private windows.
- Notifying of messages from private windows is not allowed for the addon, on TST's options.
A permissions-changed
notification message will be delivered after the user grants (or deprives) accessing to information in private windows for your addon.
Some TST APIs return or notify information of related tree items. Due to security reasons, they are not same to tabs.Tab
on TST 3.0.12 and later, so you may need to use tabs.get()
or tabs.query()
parallelly to get full tab information on demand.
However, sometimes you may want to get event information and full tab information related to the event together, for example mouse events on tabs. For such special cases, TST provides its own permission system. You can add an optional parameter named permissions
for the register-self
type message. It should be an array of strings indicating requesting permissions. Possible values are:
-
activeTab
: exposestitle
,url
, andfavIconUrl
of the tab corresponding to the tree item, only for the active tab or the context tab for the fake context menu. -
tabs
: exposestitle
,url
, andfavIconUrl
for all tabs corresponding to tree items. -
cookies
: exposescookieStoreId
for all tabs corresponding to tree items.
A permissions-changed
notification message will be delivered after the user grants (or deprives) requested permissions for your addon. The user may not allow these permissions for your addon, so please remind that you should make your addon compatible for environments without permissions.
Important note: you need to specify permissions: []
explicitly if your addon requested some permissions in past versions and you want all permissions are revoked at a new version of your addon. TST memorize last state of the option permissions
and it will be applied to future API calls automatically, even if you opmit the option.
By limitations of WebExtensions APIs, TST cannot send something messages like "shutdown" to listeners when it is going to be disabled (and uninstalled). If your addon provides something special feature for TST, it won't work after TST is disabled dynamically. Thus you'll need something way to know that TST is still alive or not.
There are two APIs available for such a case:
-
wait-for-shutdown
type message -
ping
type message
This is available on TST 2.7.17 or later.
If you send a message with the type wait-for-shutdown
, TST simply returns a promised value it will be resolved after TST is disabled. However, please note that the promise is never been resolved. The promise will be rejected when TST becomes disabled or uninstalled. So you can do uninitialize your addon when the promise is rejected. For example:
browser.runtime.sendMessage(TST_ID, { type: 'wait-for-shutdown' })
.finally(uninitFeaturesForTST);
More rich example:
async function waitForTSTShutdown() {
try {
// This message should always throw an error:
await browser.runtime.sendMessage(TST_ID, { type: 'wait-for-shutdown' });
// Will happen if message is not supported (TST 2.7.16 and earlier):
return false;
} catch (error) {
// Extension was disabled before message was sent:
if (error.message.startsWith("Could not establish connection. Receiving end does not exist."))
return true;
// Extension was disabled while we waited:
if (error.message.startsWith("Message manager disconnected"))
return true;
// Probably an internal Tree Style Tab error:
throw error;
}
}
waitForTSTShutdown().then(uninitFeaturesForTST);
You'll see the reason why the API has such an odd style at the issue 2128.
This is available on TST 2.0.3 or later.
If you send a message with the type ping
, TST simply returns true
as the result. On the other hand, if TST is not available, browser.runtime.sendMessage()
will report an error. By these difference you can know TST's living status. For example:
function checkTSTAvailability() {
try {
await browser.runtime.sendMessage(TST_ID, {
type: 'ping'
});
}
catch(e) {
clearInterval(checkTSTAvailability.timer);
uninitFeaturesForTST();
}
}
checkTSTAvailability.timer = setInterval(checkTSTAvailability, 10000);
Most of TST's APIs accept tabs.Tab.id
or some alias names to specify target tabs like active
, next-of-10
, or more. Available aliases are:
-
current
/active
: the active tab in the last focused window. -
parent
: the parent tab of the active tab. (available at TST 3.8.5 and later)-
parent-of-<Integer:id>
: the parent tab of the specified tab. (available at TST 3.8.5 and later)
-
-
root
: the root level parent tab of the active tab. (available at TST 3.8.5 and later)-
root-of-<Integer:id>
: the root level parent tab of the specified tab. (available at TST 3.8.5 and later)
-
-
next
: the next tab of the active tab.-
next-of-<Integer:id>
: the next tab of the specified tab. -
nextCyclic
/nextCyclic-of-<Integer:id>
: same to thenext
but the first tab is returned when there is no next tab.
-
-
nextVisible
: the next visible (not collapsed) tab of the active tab.-
nextVisible-of-<Integer:id>
: the next visible (not collapsed) tab of the specified tab. -
nextVisibleCyclic
/nextVisibleCyclic-of-<Integer:id>
: same to thenextVisible
but the first visible tab is returned when there is no next visible tab.
-
-
nextSibling
: the next sibling tab of the active tab.-
nextSibling-of-<Integer:id>
: the next sibling tab of the specified tab. -
nextSiblingCyclic
/ nextSiblingCyclic-of-Integer:id: same to the
nextSibling` but the first sibling is returned when there is no next sibling.
-
-
previous
/prev
: the previous tab of the active tab.-
previous-of-<Integer:id>
/prev-of-<Integer:id>
: the previous tab of the specified tab. -
previousCyclic
/prevCyclic
/previousCyclic-of-<Integer:id>
/prevCyclic-of-<Integer:id>
: same to theprev
but the last tab is returned when there is no previous tab.
-
-
previousVisible
/prevVisible
: the previous visible (not collapsed) tab of the active tab.-
previousVisible-of-<Integer:id>
/prevVisible-of-<Integer:id>
: the previous visible (not collapsed) tab of the specified tab. -
previousVisibleCyclic
/prevVisibleCyclic
/previousVisibleCyclic-of-<Integer:id>
/prevVisibleCyclic-of-<Integer:id>
: same to thepreviousVisible
but the last visible tab is returned when there is no previous visible tab.
-
-
previousSibling
/prevSibling
: the previous sibling tab of the active tab.-
previousSibling-of-<Integer:id>
/prevSibling-of-<Integer:id>
: the previous sibling tab of the specified tab. -
previousSiblingCyclic
/prevSiblingCyclic
/previousSiblingCyclic-of-<Integer:id>
/prevSiblingCyclic-of-<Integer:id>
: same to thepreviousSibling
but the last sibling is returned when there is no previous sibling.
-
-
lastDescendant
(TST 3.7.0-): the last descendant (the last child recursively found) tab of the active tab.-
lastDescendant-of-<Integer:id>
: the last descendant tab of the specified tab.
-
-
senderTab
(TST 2.4.9-): the tab containing the content script which calls the API. -
highlighted
(TST 2.6.9-, with Firefox 63 or later) /multiselected
(TST 2.6.9-, with Firefox 63 or later): multiselected tabs in the specified or last focused window. -
allVisibles
(TST 4.0-): visible (not hidden, not under any collapsed tree) tabs in the specified or last focused window. -
normalVisibles
(TST 4.0-): visible (not hidden, not under any collapsed tree), and not pinned tabs in the specified or last focused window.
And you can specify more optional parameters states
and statesNot
to filter results based on tree items' states
property. (TST 4.0-)
-
states
: an array of state strings. For examplestates: ["collapsed"]
will return collapsed descendant tabs. -
statesNot
: an array of state strings. For examplestatesNot: ["collapsed"]
will return root, expanded descendants, and/or tree parent.
Note:
- All these aliases are available on TST 2.4.4 and later.
- All
Cyclic
suffixed aliases are available on TST 3.2.7 and later. - All
-of-<id>
suffixed aliases are available on TST 3.7.0 and later.
This is available on TST 3.7.4 or later.
TST is basically designed to work with tabs created by other addons and Firefox itself. However, TST has some options to control position of newly opened tabs from specific triggers and it may break behaviors of your addon. So TST provides an API create
: it provides ability for your addon to open a new tab bypassing TST's new tab control behavior. It is compatible to tabs.create()
, so it can be used like as:
const params = { url: 'https://example.com/', windowId: 1 };
let tab;
if (useTST)
tab = await browser.runtime.sendMessage(TST_ID, { type:'create', params });
else
tab = await browser.tabs.create(params);
Here is the list of available parameters:
-
params
: An object, compatible tocreateProperties
fortabs.create()
.
This API returns a tree item information. Please remind that you need to get an extra permission to get the returned tab object with some sensitive information, due to security restrictions.
And, please remind that this API completely bypasses TST's tab control including auto-fixup of tree structure, except it is explicitly opened as a child tab of an existing tab. New tabs can be opened at a middle of an existing tree without valid tree structure, so it can break tree management too easily.
To open new child tab from any existing tab, you just need to specify openerTabId
option (available at Firefox 57 and later) for browser.tabs.create()
. For example:
let [activeTab, ] = await browser.tabs.query({
active: true,
currentWindow: true
});
browser.tabs.create({
url: 'http://www.example.com/',
openerTabId: activeTab.id // optional, tabs.Tab.id
});
Of course you can use the create
API instead of tabs.create()
to open a new child tab.
This API is available on TST 2.4.4 or later.
indent
(and demote
) message attaches the specified tab to its previous sibling tab.
For example:
let success = await browser.runtime.sendMessage(TST_ID, {
type: 'indent', // or 'demote'
tab: 'current', // required, tabs.Tab.id or alias
followChildren: false // optional, boolean (default=false)
});
If you specify an option followChildren:true
, all of descendants are indented together.
Otherwise descendants are detached from the specified tab and only the tab is indented.
This API is available on TST 2.4.4 or later.
outdent
(and promote
) message attaches the specified tab to its grand-parent tab.
For example:
let success = await browser.runtime.sendMessage(TST_ID, {
type: 'outdent', // or 'promote'
tab: 'current', // required, tabs.Tab.id or alias
followChildren: false // optional, boolean (default=false)
});
If you specify an option followChildren:true
, all of descendants are outdented together.
Otherwise descendants are detached from the specified tab and only the tab is outdented.
attach
message attaches an existing tab to different tab as its child.
For example:
let success = await browser.runtime.sendMessage(TST_ID, {
type: 'attach',
parent: 6, // required, tabs.Tab.id or alias
child: 9, // required, tabs.Tab.id or alias
insertBefore: 8, // optional, tabs.Tab.id or alias
insertAfter: 7, // optional, tabs.Tab.id or alias
});
If the new child tab is already attached to different parent, then it is implicitly detached from its old parent.
You can give optional parameter insertBefore
and/or insertAfter
to control where the attached tab is placed at.
Otherwise the attached tab will be placed at top or bottom of existing children.
detach
message detaches a child tab from its parent.
For example:
let success = await browser.runtime.sendMessage(TST_ID, {
type: 'detach',
tab: 9 // required, tabs.Tab.id or alias
});
Note that detached tab (and its descendants) stays there. In other words, if you detach a child tab from a tree, you must move detached tab (and its descendants) to somewhere like after the last tab manually.
collapse-tree
message collapses an existing tree.
let success = await browser.runtime.sendMessage(TST_ID, {
type: 'collapse-tree',
tab: 2, // required, tabs.Tab.id or alias
recursively: false // optional, collapse tree recursively or not. false by default.
});
It always succeeds if the tab has no child or it is already collapsed.
The recursively
option is available on TST 3.4.6 and later.
expand-tree
message expands an existing tree.
let success = await browser.runtime.sendMessage(TST_ID, {
type: 'expand-tree',
tab: 2, // required, tabs.Tab.id or alias
recursively: false // optional, expand tree recursively or not. false by default.
});
It always succeeds if the tab has no child or it is already expanded.
The recursively
option is available on TST 3.4.6 and later.
This API is available on TST 3.2.7 or later.
toggle-tree-collapsed
message toggles collapsed state of an existing tree.
let success = await browser.runtime.sendMessage(TST_ID, {
type: 'toggle-tree-collapsed',
tab: 2 // required, tabs.Tab.id or alias
});
It always succeeds if the tab has no child.
This API is no longer supported on TST 3.3.7 and later, because the feature was removed and extracted as a helper addon.
This API is available on TST 3.2.7 or later.
You can set "Locked as Collapsed" state of a tree with lock-tree-collapsed
and unlock-tree-collapsed
message.
let success = await browser.runtime.sendMessage(TST_ID, {
type: 'lock-tree-collapsed',
tab: 2 // required, tabs.Tab.id or alias
});
let success = await browser.runtime.sendMessage(TST_ID, {
type: 'unlock-tree-collapsed',
tab: 2 // required, tabs.Tab.id or alias
});
toggle-lock-tree-collapsed
message toggles the "Locked as Collapsed" state of an existing tree.
let success = await browser.runtime.sendMessage(TST_ID, {
type: 'toggle-lock-tree-collapsed',
tab: 2 // required, tabs.Tab.id or alias
});
They always succeed if the tab has no child.
This API is available on TST 4.0 or later.
You can control sticky state of tabs via messages with types stick-tab
, unstick-tab
, and toggle-sticky-state
.
-
stick-tab
marks specified tab to be stuck to tab bar edges. -
unstick-tab
unmarks specified tab to be stuck. -
toggle-sticky-state
toggles sticky state of tabs based on the first specified tab.
For example:
let success = await browser.runtime.sendMessage(TST_ID, {
type: 'toggle-sticky-state',
tab: 2 // required, tabs.Tab.id or alias
});
Please note that this API just marks the tab as "to be stuck" or unmarks, so the tab won't be stuck to tab bar edges while it is in the viewport. The tab will be stuck when it is scrolled out, and unstuck when it moves into the viewport.
See also a notification type to know a tab is stuck or unstuck.
And, there are more message types register-auto-sticky-states
and unregister-auto-sticky-states
to make tabs with something states sticky automatically.
They accepts only one parameter:
-
state
(required): An array of strings or a string to be registered/unregistered as "auto sticky state".
Here is an example to make tabs sharing something sticky:
await browser.runtime.sendMessage(TST_ID, {
type: 'register-auto-sticky-states',
state: ['sharing-camera', 'sharing-microphone', 'sharing-screen'],
});
Please note that registered states are cleared when the sidebar panel is reloaded, so you need to register them again with sidebar-shown
notification.
This API is available on TST 4.0 or later.
You can set custom tooltip text to each tab by a message with the type set-tooltip-text
.
It accepts some parameters:
-
tab
(required): Atabs.Tab.id
or an alias of the tab to be changed its tooltip text. -
text
(required): A string which should be used as the tooltip text. Blank string means "disable tooltip text". -
force
(optional, default=false
): A boolean, indicating the tooltip text to be applied always (true
) or applied only when the title is short (false
).
For example:
let success = await browser.runtime.sendMessage(TST_ID, {
type: 'set-tooltip-text',
tab: 2, // required, tabs.Tab.id or alias
text: tab.url, // use the URL as the tooltip
});
Please note that blank text
means "show no tooltip text on the tab". Call clear-tooltip-text
instead, if you hope to restore the default tooltip text applied by TST.
let success = await browser.runtime.sendMessage(TST_ID, {
type: 'clear-tooltip-text',
tab: 2, // required, tabs.Tab.id or alias
});
The final caller will win if multiple addons call these APIs for a specific tab.
Basically you don't need to call any TST's API to move tabs. TST is designed compatible to the regular way browser.tabs.move()
.
- When a parent tab is moved in same window, all descendant tabs are also moved together automatically.
- When a parent tab is moved across windows, all descendant tabs are left in the source window. In this case, if you hope that a whole tree is moved to different window, then you need to move descendant tabs to the destination window and restructure tree manually.
But this compatibility mechanism is fragile. If an addon moves multiple tabs in a time, TST sometimes fails to fixup the tree structure of moved tabs. So, there are some APIs for safety: commands to move tabs with their structure, and a hook to cancel the autofixing.
Here is a list of command type APIs:
-
move-up
(available on TST 2.4.4 and later) moves a solo tab or a tree upward. This accepts some parameters:-
tab
(required): Atabs.Tab.id
or an alias of the tab to be moved. -
followChildren
(optional, default=false
): A boolean, indicating the move mode.true
means "move a tree",false
means "move a solo tab without its children".
For example:
// move a tree upward let success = await browser.runtime.sendMessage(TST_ID, { type: 'move-up', tab: 'current', followChildren: true });
-
-
move-down
(available on TST 2.4.4 and later) moves a solo tab or a tree downward. This accepts some parameters:-
tab
(required): Atabs.Tab.id
or an alias of the tab to be moved. -
followChildren
(optional, default=false
): A boolean, indicating the move mode.true
means "move a tree",false
means "move a solo tab without its children".
For example:
// move a tree downward let success = await browser.runtime.sendMessage(TST_ID, { type: 'move-down', tab: 'current', followChildren: true });
-
-
move-before
(available on TST 2.8.0 and later) moves a solo tab or a tree before a reference tab. This accepts some parameters:-
tab
(required): Atabs.Tab.id
or an alias of the tab to be moved. -
referenceTabId
(required): Atabs.Tab.id
of the reference tab which thetab
should be placed before. -
followChildren
(optional, default=false
): A boolean, indicating the move mode.true
means "move a tree",false
means "move a solo tab without its children".
For example:
// move a tree before the tab 8 let success = await browser.runtime.sendMessage(TST_ID, { type: 'move-before', tab: 'current', referenceTabId: 4, followChildren: true });
-
-
move-after
(available on TST 2.8.0 and later) moves a solo tab or a tree after a reference tab. This accepts some parameters:-
tab
(required): Atabs.Tab.id
or an alias of the tab to be moved. -
referenceTabId
(required): Atabs.Tab.id
of the reference tab which thetab
should be placed after. -
followChildren
(optional, default=false
): A boolean, indicating the move mode.true
means "move a tree",false
means "move a solo tab without its children".
For example:
// move a tree after the tab 8 let success = await browser.runtime.sendMessage(TST_ID, { type: 'move-after', tab: 'current', referenceTabId: 8, followChildren: true });
-
-
move-to-start
(available on TST 2.6.9 and later) This will help you to simulate the "Move Tabs" => "Move to Start" command of the tab context menu, safely with tree structure. This accepts some parameter:-
tab
(optional, aliastabId
): Atabs.Tab.id
or an alias of a tab or tabs to be moved. -
tabs
(optional, aliastabIds
): An array oftabs.Tab.id
or alias of tabs to be moved.
One of
tab
,tabId
,tabs
ortabIds
is required. For example:// move all highlighted tabs to the start let success = await browser.runtime.sendMessage(TST_ID, { type: 'move-to-start', tab: 'highlighted' });
-
-
move-to-end
(available on TST 2.6.9 and later) moves specified tabs to the end of the tab bar. This will help you to simulate the "Move Tabs" => "Move to End" command of the tab context menu, safely with tree structure. This accepts some parameter:-
tab
(optional, aliastabId
): Atabs.Tab.id
or an alias of a tab or tabs to be moved. -
tabs
(optional, aliastabIds
): An array oftabs.Tab.id
or alias of tabs to be moved.
One of
tab
,tabId
,tabs
ortabIds
is required. For example:// move all highlighted tabs to the end let success = await browser.runtime.sendMessage(TST_ID, { type: 'move-to-end', tab: 'highlighted' });
-
And you can also cancel TST's tree autofixing for moved tabs.
See the description of try-fixup-tree-on-tab-moved
also.
This API is available on TST 2.4.4 or later.
focus
message focuses to the specified tab.
For example:
let success = await browser.runtime.sendMessage(TST_ID, {
type: 'focus',
tab: 'nextSibling', // required, tabs.Tab.id or alias
silently: false // optional, boolean (default=false)
});
The tab
parameter accepts alias name of tabs, so nextSibling
will focus to the next sibling tab, previousSibling
will focus to the previous sibling tab.
If you specify an option silently:true
, children of focused tab will be kept collapsed.
Otherwise TST expands the tree of focused tab automatically. Combinations with tab aliases nextVisible
and previousVisible
should allow you to move focus only around visible (not collapsed) tabs, on TST 3.2.7 and later.
This API is available on TST 2.4.4 or later.
duplicate
message duplicates the specified tab at the specified position.
For example:
let success = await browser.runtime.sendMessage(TST_ID, {
type: 'duplicate',
tab: 'current', // required, tabs.Tab.id or alias
as: 'child' // optional, string
});
Here is the list of available value for the as
option:
-
sibling
: duplicated tab will be placed just next to the source tab. -
nextSibling
: duplicated tab will be placed as the next sibling of the source tab. -
first-child
(available on TST 3.9.20 or later): duplicated tab will be placed as the fist child of the source tab. -
last-child
(available on TST 3.9.20 or later): duplicated tab will be placed as the last child of the source tab. -
child
: duplicated tab will be placed as a child of the source tab. On TST 3.9.20 or later, this respects TST's configuration for duplicated tabs if it is configured as "first child" or "last child". -
orphan
(default on TST 2.6.8 or olders): duplicated tab will be placed at the end of the tab bar.
On TST 2.6.9 or later, the default behavior of the as
option respects TST's configuration for duplicated tabs.
This API is available on TST 2.6.9 or later.
open-in-new-window
type message moves specified tabs to a new window.
For example:
let windowId = await browser.runtime.sendMessage(TST_ID, {
type: 'open-in-new-window',
tab: 'highlighted', // required, tabs.Tab.id or alias
});
The result is the ID of the newly opened window. It will help you to simulate "Move Tabs" => "Move Tabs to New Window" command of the tab context menu, safely with tree structure.
This API is available on TST 2.6.9 or later.
reopen-in-container
type message reopens specified tabs with the container.
For example:
let reopenedTabs = await browser.runtime.sendMessage(TST_ID, {
type: 'reopen-in-container',
tab: 'highlighted', // required, tabs.Tab.id or alias
containerId: 'firefox-container-1' // optional, 'firefox-default' by default
});
The parameter containerId
is a valid ID of a contextual identity, appearing as tabs.Tab.cookieStoreId
.
The result is the new tabs reopened in the container. It will help you to simulate "Reopen in Container" command of the tab context menu, safely with tree structure.
This API is available on TST 2.4.4 or later.
group-tabs
message creates a new tree from specified tabs.
Tabs will be grouped under a dummy parent tab.
For example:
let parentTab = await browser.runtime.sendMessage(TST_ID, {
type: 'group-tabs',
title: 'New Group', // optional, title of the created group tab (available on TST 3.9.13 and later)
tabs: [1, 2, 3], // required, array of tabs.Tab.id or alias
});
TST 4.0.19 and later supports temporary
and temporaryAggressive
boolean options, to control checkboxes in the group tab.
// Close the group tab when there is no child tab
let parentTab = await browser.runtime.sendMessage(TST_ID, {
type: 'group-tabs',
title: 'New Group',
tabs: [1, 2, 3],
temporary: true,
});
// Close the group tab when there is only one child tab is left
let parentTab = await browser.runtime.sendMessage(TST_ID, {
type: 'group-tabs',
title: 'New Group',
tabs: [1, 2, 3],
temporaryAggressive: true,
});
// Never close the group tab even if there is no child tab
let parentTab = await browser.runtime.sendMessage(TST_ID, {
type: 'group-tabs',
title: 'New Group',
tabs: [1, 2, 3],
temporary: false,
temporaryAggressive: false,
});
There is no specific API to close all tabs in a tree by just one operation.
Please use browser.tabs.remove()
simply to close tree of tabs.
- When a closing parent tab has collapsed children, all descendants are also closed together automatically.
- When a closing parent tab has expanded children, the first child tab is promoted as the new parent. In this case, if you hope that a whole expanded tree is closed, then you need to collapse the tree at first or close all descendant tabs manually.
This API is available on TST 2.0.2 or later.
scroll
message scrolls the tab bar.
let success = await browser.runtime.sendMessage(TST_ID, {
type: 'scroll',
...
});
There are three forms of its usage:
-
Scrolling to a tab. In this form, you must specify an ID of a tab, like:
let success = await browser.runtime.sendMessage(TST_ID, { type: 'scroll', tab: 2 // integer, an ID of a tab });
Note that this does nothing if the specified tab is already visible.
-
Scrolling to absolute position. In this form, you must specify an ID of a window and absolute position, like:
let success = await browser.runtime.sendMessage(TST_ID, { type: 'scroll', window: 3, // integer, an ID of a window position: 250 // integer, an absolute scroll position in pixels / string, an CSS length (TST 3.7.5 and later) });
On TST 3.2.7 and later, a special ID string
active
is available to specify the active browser window, like:let success = await browser.runtime.sendMessage(TST_ID, { type: 'scroll', window: 'active', position: 250 });
-
Scrolling by relative delta. In this form, you must specify an ID of a window and delta, like:
let success = await browser.runtime.sendMessage(TST_ID, { type: 'scroll', window: 3, // integer, an ID of a window delta: -20 // integer, a relative scroll in pixels / string, an CSS length (TST 3.7.5 and later) });
On TST 3.2.7 and later, a special ID string
active
is available to specify the active browser window, like:let success = await browser.runtime.sendMessage(TST_ID, { type: 'scroll', window: 'active', delta: -20 });
-
Scrolling slowly (available on TST 3.7.5 and later). You can specify the scroll duration via the
duration
option, like:let success = await browser.runtime.sendMessage(TST_ID, { type: 'scroll', window: 3, delta: 3000, duration: 10 * 1000 // integer, in milliseconds. 1000 msec equals to 1 sec. });
In-progress scroll with large duration can be canceled with the
stop-scroll
API like as:let success = await browser.runtime.sendMessage(TST_ID, { type: 'stop-scroll', window: 3 });
On TST 3.7.5 and later position
and delta
accept any CSS length like 123px
, 4em
, 0px - var(--tab-size) * 3
, and others.
You can get structure information of given tabs with a message with the type get-tree-structure
. It returns an array object indicating tree structure of tabs specified with tab
/tabId
/tabs
/tabIds
and window
/windowId
parameters (compatible to get-tree
's parameters). For example:
// Get tree structure of entire tabs in the window 1.
const structure1 = await browser.runtime.sendMessage(TST_ID, {
type: 'get-tree-structure',
tabs: '*',
window: 1
});
// Get tree structure of only some tabs.
const structure2 = await browser.runtime.sendMessage(TST_ID, {
type: 'get-tree-structure',
tabs: [1,2,3,4]
});
The returned object is available for the structure
parameter of a message with the type set-tree-structure
.
It is an array of objects with following properties:
-
parent
: An integer, indicating the index of its parent tab. For more details see the description below. -
collapsed
: A boolean, indicating that its subtree is collapsed (true
) or expanded (false
). -
id
: The ID string internally used by TST. It is different fromTab.id
generally used in WebExtensions APIs. This is exposed for internal use, so you should ignore it.
It is little hard to describe what the value of parent
means.
For example assume that given tabs have a tree structure like this:
* Tab A \
* Tab A-1 | Tree X
* Tab A-1-1 |
* Tab A-2 /
* Tab B \
* Tab B-1 | Tree Y
* Tab B-2 /
* Tab C -- Tree Z
Then get-tree-structure
will return a result like:
[
{ parent: -1, collapsed: true, id: '...' }, // Tab A \
{ parent: 0, collapsed: true, id: '...' }, // Tab A-1 | Tree X
{ parent: 1, collapsed: true, id: '...' }, // Tab A-1-1 |
{ parent: 0, collapsed: true, id: '...' }, // Tab A-2 /
{ parent: -1, collapsed: true, id: '...' }, // Tab B \
{ parent: 0, collapsed: true, id: '...' }, // Tab B-1 | Tree Y
{ parent: 0, collapsed: true, id: '...' }, // Tab B-2 /
{ parent: -1, collapsed: true, id: '...' } // Tab C -- Tree Z
]
There are three root tabs [A, B, C] and corresponding three trees [X, Y, Z]. The value of parent
indicates the index of the tab in the tree belonging to, as:
- The tab A has no parent in the tree X so its
parent
is-1
. - The parent of the tab A-1 is A, the first tab in the tree X. So the
parent
of A-1 is0
. - The parent of the tab A-1-1 is A-1, the second tab in the tree X. So the
parent
of A-1-1 is1
. - The parent of the tab A-2 is A, so the
parent
of A-2 is0
. - The tab B has no parent in the tree Y so its
parent
is-1
. - The parent of the tab B-1 is B, the first tab in the tree Y. So the
parent
of B-1 is0
. - ...
You can set tree structure of given tabs with a message with the type set-tree-structure
with just one API call. The target tabs are specified with tab
/tabId
/tabs
/tabIds
and window
/windowId
parameters (compatible to get-tree
's parameters), and the structure of tabs is specified with the object respond by the get-tree-structure
API or a simplified version of it.
For example:
// Case 1: get tree structure of entire tabs in the window 1,
const structure1 = await browser.runtime.sendMessage(TST_ID, {
type: 'get-tree-structure',
tabs: '*',
window: 1
});
// and apply the structure to tabs in the window 2.
browser.runtime.sendMessage(TST_ID, {
type: 'set-tree-structure',
tabs: '*',
window: 2,
structure: structure1
});
// Case 2: create a structure like a group (one parent and other children).
// This is same to an array of `parent` extracted from the result of `get-tree-structure`
const structure2 = [-1, 0, 0, 0];
browser.runtime.sendMessage(TST_ID, {
type: 'set-tree-structure',
tabs: [1,2,3,4],
structure: structure2
});
Extra tabs or structure information are cut off if the number of tabs and the length of the structure information is not same.
TST API provides ability to get tree information. Each tree item is presented as an object with following properties:
-
id
: an integer, theid
of the tab. -
windowId
: an integer, thewindowId
of the tab. -
states
: an array of TST-specific states applied to the tab. Possible values are:-
collapsed
: The tab is in a collapsed subtree. The tab is invisible. -
subtree-collapsed
: The tab has any child, and its subtree is collapsed. All child tabs are invisible. -
locked-collapsed
: The subtree of the tab is locked as collapsed. (Available on TST 3.2.7 and later.) -
group-tab
: A special class on a dummy tab for grouping. -
creating
: The tab is in the creating process. (Available on TST 4.0 and later.) -
newtab-command-tab
: The tab is detected as a tab opened from any "New Tab" command. (Available on TST 4.0 and later.) -
duplicated
: The tab is detected as a tab duplicated from any other tab. (Available on TST 4.0 and later.) -
restored
: The tab is detected as a tab reopened from Ctrl-Shift-T or something other triggers. (Available on TST 4.0 and later.) -
from-external
: The tab is detected as a tab opened from any external application. (Available on TST 4.0 and later.) -
from-firefox-view
: The tab is detected as a tab opened from Firefox View. (Available on TST 4.0 and later.) -
opened-for-same-website
: The tab is detected as a tab opened with a URL which the domain is same to the active tab. (Available on TST 4.0 and later.) -
sticky
: The tab is marked to be stuck to tab bar edges. (Available on TST 4.0 and later.) -
stuck
: The tab is really stuck to one of tab bar edges. Note that this state is presented only when the information is given from the visible sidebar panel, e.g. a part of atry-scroll-to-activated-tab
notification. (Available on TST 4.0.23 and later.)
-
-
indent
: the indent level of the tab (integer). It is0
for top level tabs. (Note: this property is available on Tree Style Tab 2.4.8 and later.) -
children
: an array of child tabs with same format (extendedtabs.Tab
) recursively. -
ancestorTabIds
: an array of ancestor tabs'tabs.Tab.id
(integer). The first item is the direct parent of the tab, the last item is the root level parent. (Note: this property is available on Tree Style Tab 2.4.17 and later.) -
bundledTabId
: the bundled tab'stabs.Tab.id
(integer). If the tab has no bundled tab, this becomes-1
. (Note: this property is available on Tree Style Tab 3.2.6 and later.) What the bundled tab is:- For a pinned tab, the related group tab opened to group regular child tabs opened from the pinned tab.
- For a group tab, the related pinned tab which is the real parent tab of children tabs under the group tab itself.
On TST 4.0 and later, "Light tree", responses for get-light-tree
request or tab-like properties contained in notifications to an addon registered with an option lightTree:true
, will have only properties described above.
"Full tree", responses for get-tree
request or tab-like properties contained in notifications to an addon registered without lightTree:true
, will have more properties corresponding to ones of tabs.Tab
object except title
, url
, favIconUrl
, and cookieStoreId
.
For example:
browser.runtime.sendMessage(TST_ID, { type: 'get-light-tree', tabId: 2 });
=>
{ id: 2,
windowId: 1,
states: [],
indent: 0,
ancestorTabIds: [],
children: [
{ id: 3,
windowId: 1,
states: [],
indent: 1,
ancestorTabIds: [2],
children: [] },
{ id: 4,
windowId: 1,
states: ["subtree-collapsed"],
indent: 1,
ancestorTabIds: [2],
children: [
{ id: 5,
windowId: 1,
states: ["collapsed"],
indent: 2,
ancestorTabIds: [4, 2],
children: [] }
] }
] }
browser.runtime.sendMessage(TST_ID, { type: 'get-tree', tabId: 2 });
=>
{ id: 2,
windowId: 1,
pinned: false, // from tabs.Tab
attention: false, // from tabs.Tab
... // more other properties are available
states: [],
indent: 0,
ancestorTabIds: [],
children: [
{ id: 3,
windowId: 1,
pinned: false,
attention: false,
...
states: [],
indent: 1,
ancestorTabIds: [2],
children: [] },
...
] }
On TST 3.0.12 and later, you need to call tabs.get()
, tabs.query()
or other WebExtensions APIs to get full tab information of tree items. However, if your addon has special permissions, each tree item will have more properties inherited from the tabs.Tab
object corresponding to it.
(In other words, on TST 3.0.11 or older versions, each tree item always had properties inherited from tabs.Tab
object corresponding to it, and more information was exposed via its states
property. This spec violated WebExtensions's security model, so now they are hidden by default.)
Here is an example implementation to resolve tree items to tabs without special permissions:
async function resolveTreeItemToTab(treeItem, windowId) {
if (!treeItem)
return treeItem;
const tabs = await browser.tabs.query({ windowId });
const tabsById = new Map();
for (const tab of tabs) {
tabsById.set(tab.id, tab);
}
const resolve = (tab) => {
if (tab.children)
tab.children = tab.children.map(resolve);
return Object.assign(tabsById.get(tab.id), tab);
};
return resolve(treeItem);
}
There are APIs get-tree
and get-light-tree
, to collect tab information with their tree structure.
For descriptions, now we assume that there a set of tabs with tree structure:
- Window A (id:1)
- Tab A (id:1, pinned)
- Tab B (id:2, active)
- Tab B-a (id:3)
- Tab B-b (id:4, collapsed)
- Tab B-b-1 (id:5)
- Tab C (id:6, collapsed, out of the viewport)
- Tab C-a (id:7, out of the viewport)
You should give the ID of a tab via the tab
parameter, to get tree information of single tab.
For example:
let tab = await browser.runtime.sendMessage(TST_ID, {
type: 'get-light-tree',
tab: 2
});
/* tab =>
{ id: 2, ...
states: [],
indent: 0,
children: [
{ id: 3, ...
states: [],
indent: 1,
children: [],
ancestorTabIds: [2] },
{ id: 4, ...
states: ["subtree-collapsed"],
indent: 1,
children: [
{ id: 5, ...
states: ["collapsed"],
indent: 2,
children: [],
ancestorTabIds: [4, 2] }
],
ancestorTabIds: [2] }
],
ancestorTabIds: [] }
*/
You should give an array of IDs of tabs via the tabs
/tabIds
parameter, to get tree information of multiple tab at a time.
For example:
let tabs = await browser.runtime.sendMessage(TST_ID, {
type: 'get-light-tree',
tabs: [1, 2]
});
/* tabs =>
[
{ id: 1, ...
children: [] },
{ id: 2, ...
children: [...] }
]
*/
You should give an window ID via the window
parameter, to get clear tree information of a window at a time.
For example:
let tabs = await browser.runtime.sendMessage(TST_ID, {
type: 'get-light-tree',
window: 1
});
/* tabs =>
[
{ id: 1, ... },
{ id: 2, ...
children: [
{ id: 3, ... },
{ id: 4, ...
children: [
{ id: 5, ... }
] }
] },
{ id: 6, ...
children: [
{ id: 7, ... }
] }
]
*/
Note that only root tabs appear in the array (id=1, 2, 6).
As the result, you need to scan children
of each tab to retrieve all tabs.
If you hope to get a flat list of all tabs in the current window, see the next section.
You should give a string *
via tab
, tabId
, tabs
or tabIds
parameter, to get tree information of all tabs at a time as a flat array.
For example:
let tabs = await browser.runtime.sendMessage(TST_ID, {
type: 'get-light-tree',
window: 1,
tabs: '*'
});
/* tabs =>
[
{ id: 1, ... },
{ id: 2, ...
children: [
{ id: 3, ... },
{ id: 4, ...
children: [
{ id: 5, ... }
] }
] },
{ id: 3, ... },
{ id: 4, ...
children: [
{ id: 5, ... }
] },
{ id: 5, ... },
{ id: 6, ...
children: [
{ id: 7, ... }
] },
{ id: 7, ... }
]
*/
Note that some tabs appear multiple times (id=3, 4, 5, 7).
This is because the wildcard *
always collects tree information from all tabs.
If you don't need such duplicated information, see the previous section.
If you omit the window
parameter, tabs in the last focused window will be returned.
For better performance, only in-viewport tabs are actually rendered, and they are un-rendered when they go away from the viewport, on TST 4.0 and later.
You can get tree information for already rendered tabs with a boolean parameter rendered: true
, for example:
let tabs = await browser.runtime.sendMessage(TST_ID, {
type: 'get-light-tree',
window: 1,
tabs: '*',
rendered: true,
});
/* tabs =>
[
{ id: 1, ... }, // pinned tabs are always rendered
{ id: 2, ... },
{ id: 3, ... },
{ id: 4, ... },
// id=5 tab is not rendered because it is under a collapsed tree
// id=6 and id=7 are out of the viewport
]
*/
By default, mouse wheel simply scrolls the tab bar. If you hope to override the behavior, you need to lock the scroll and do something based on notified messages.
This API is available on TST 2.0.2 or later.
scroll-lock
message disables the default scrolling behavior.
let success = await browser.runtime.sendMessage(TST_ID, {
type: 'scroll-lock'
});
On the other hand, scroll-unlock
message enables the default scrolling behavior again.
let success = await browser.runtime.sendMessage(TST_ID, {
type: 'scroll-unlock'
});
Multiple addons can lock the scroll at a time, and TST never produce the default scrolling behavior while it is locked by any addon even if your addon already unlocks. In other words, you must not forget to unlock the scroll before your addon is completely unloaded (disabled or uninstalled).
This API is available on TST 2.0.2 or later.
While your addon locks the scrolling, TST notifies scrolled
message to your addon.
browser.runtime.onMessageExternal.addListener((message, sender) => {
switch (sender.id) {
case TST_ID:
switch (message.type) {
...
case 'scrolled':
// do something here. for example:
let tab = getNextFocusedTab(message.tabs);
browser.tabs.update(tab.id, { active: true });
return Promise.resolve(true); // you must return any non-undefined value.
...
}
break;
}
});
Here is a list of properties notified message have:
-
tab
: A tree item corresponding to the tab you rotated the mouse wheel on. -
tabs
: A flatten array of tree items corresponding to tabs in the window. This quite equals to the result ofget-tree
withtabs:'*'
. -
window
(aliaswindowId
): An integer, the owner window's ID. -
overflow
: A boolean, meaning the tab bar is scrollable or not. (available on TST 3.8.9 and later) -
deltaX
: A number, the value ofWheelEvent#deltaX
. (Available on TST 3.2.6 and later.) -
deltaY
: A number, the value ofWheelEvent#deltaY
. -
deltaZ
: A number, the value ofWheelEvent#deltaZ
. (Available on TST 3.2.6 and later.) -
deltaMode
: An integer, the value ofWheelEvent#deltaMode
. -
scrollTop
: An integer, the current scroll position of the tab bar. -
scrollTopMax
: An integer, the maximum scroll position of the tab bar. -
altKey
: A boolean, theAlt
modifier key is pressed or not. -
ctrlKey
: A boolean, theCtrl
(Control
) modifier key is pressed or not. -
metaKey
: A boolean, theMeta
(Command
on macOS) modifier key is pressed or not. -
shiftKey
: A boolean, theShift
modifier key is pressed or not. -
clientX
: An integer, the value ofMouseEvent#clientX
indicating the coordinate the event fired at. -
clientY
: An integer, the value ofMouseEvent#clientY
indicating the coordinate the event fired at.
Based on these information, you'll scroll the tab bar with custom algorithm or any other reactions.
You must return any non-undefined
value (including false
, 0
, and so on) from the listener.
Otherwise TST guesses the listener addon is already unloaded and unlocks the scroll for your addon automatically.
You can set custom state to tabs via messages with add-tab-state
and remove-tab-state
type.
Custom classes will appear as classes of tab elements like <li class="tab active myaddon-marked">
, so you can apply any style definitions to tabs.
Note that all built-in states and custom states are mixed into the same namespace, so you can break TST's functions easily if you modify TST's built-in states. For safety, prefixed names like myaddon-marked
instead of simple names like marked
are recommended.
And, please note that custom states won't be exposed via the states
property of any tree item for security reasons, on TST 3.0.12 or later. (On TST 3.0.11 or older versions all extra stats and built-in states were exposed, but now they are unavailable.)
A message with the type add-tab-state
adds given states to specified tabs as their classes. For example:
browser.runtime.sendMessage(TST_ID, {
type: 'add-tab-state',
tabs: [1, 2, 3], // required, an array of tabs.Tab.id or alias
state: 'my-selected' // required, a state string or an array of state strings
});
You can specify multiple states at a time:
browser.runtime.sendMessage(TST_ID, {
type: 'add-tab-state',
tabs: [1, 2, 3],
state: ['my-selected', 'my-another-custom-status']
});
A message with the type remove-tab-state
removes given states from specified tabs. For example:
browser.runtime.sendMessage(TST_ID, {
type: 'remove-tab-state',
tabs: [1, 2, 3], // required, an array of tabs.Tab.id or alias
state: 'my-selected' // required, a state string or an array of state strings
});
You can specify multiple states at a time:
browser.runtime.sendMessage(TST_ID, {
type: 'remove-tab-state',
tabs: [1, 2, 3],
state: ['my-selected', 'my-another-custom-status']
});
TST sends notification messages to registered addons. To receive these messages, you need to register your addon at first.
A message with the type ready
will be notified, when the TST itself is initialized.
For more details, see another section: how to register your addon.
This API is available on TST 2.4.23 or later.
There are two notification message types: sidebar-show
and sidebar-hide
.
- A message with the type
sidebar-show
will be notified when the TST sidebar is shown. - A message with the type
sidebar-hide
will be notified when the TST sidebar is hidden.
Here is a list of properties these type message objects commonly have:
-
window
(aliaswindowId
): An integer, the owner window's ID for the sidebar.
On TST 3.0.12 and later, this notification won't be delivered if it happens on a private window and your addon is not allowed for private windows.
When a context menu item added by your addon is clicked, your addon will receive a notification message with the type contextMenu-click
. For more details, see another section.
This message will be delivered to your addon even if you don't list this at the listeningTypes
parameter for the register-self
message.
On TST 3.0.12 and later, this notification won't be delivered if it happens on a private window and your addon is not allowed for private windows.
This API is available on TST 2.4.25 or later.
A message with the type contextMenu-shown
will be notified, when the context menu is going to be opened. It corresponds to the browser.menus.onShown
. See another section for more details.
And, another message with the type contextMenu-hidden
will be notified, when the context menu is closed. It corresponds to the browser.menus.onHidden
.
These type messages won't be delivered to your addon implicitly. You need to list them at the listeningTypes
parameter for the register-self
message.
On TST 3.0.12 and later, this notification won't be delivered if it happens on a private window and your addon is not allowed for private windows.
This API is available on TST 3.8.24 or later.
When a tab is opened by TST or others, TST handles it and attaches to existing tree based on its context or doesn't.
After all handling by TST is finished, a notification message with the type new-tab-processed
will be delivered to listeners.
Here is a list of properties the message object has:
-
tab
: A tree item corresponding to the tab newly opened. -
restored
: A boolean, indicating the tab is restored from session information (ex. Ctrl-Shift-T) or not. -
duplicated
: A boolean, indicating the tab is duplicated from another tab or not. -
originalTab
: A tree item corresponding to the original tab, if it is duplicated. -
fromExternal
: A boolean, indicating the tab is guessed as opened by another application. Please note that this is based on situational evidences and it can be misdetected.
This will help you to implement something helper addon working for new tabs opened at the root level: it can be detected like as notifiedMessage.tab.ancestorTabIds.length == 0
.
This notification won't be delivered if it happens on a private window and your addon is not allowed for private windows.
This API is available on TST 4.0 and later.
For better performance, only in-viewport tabs are actually rendered, and they are un-rendered when they go away from the viewport, on TST 4.0 and later.
Notification message with types tabs-rendered
or tabs-unrendered
will be delivered to listeners, when rendered status of one or more tabs are changed.
Here is a list of properties the message object has:
-
tabs
: An array of tree items corresponding to the tabs newly rendered or un-rendered.
Messages with tab-mousedown
, tab-mouseup
, tab-clicked
(and tab-dblclicked
) types will be delivered to listeners, when any tab is clicked (or double-clicked).
Here is a list of properties the message object has:
-
tab
: A tree item corresponding to the clicked tab. -
window
(aliaswindowId
): An integer, the owner window's ID. -
button
: An integer to indicate the clicked button.0
=left button,1
=middle button (2
won't be notified) -
ctrlKey
: A boolean, theCtrl
(Control
) modifier key is pressed or not. -
shiftKey
: A boolean, theShift
modifier key is pressed or not. -
altKey
: A boolean, theAlt
modifier key is pressed or not. -
metaKey
: A boolean, theMeta
(Command
on macOS) modifier key is pressed or not. -
closebox
: A boolean, the event happens on the closebox or not. -
sharingState
: A boolean, the event happens on the sharing state icon or not. (This property is available on TST 4.0 or later.) -
soundButton
: A boolean, the event happens on the mute/unmute button or not. (This property is available on TST 2.5.3 or later.) -
twisty
: A boolean, the event happens on the twisty or not. (This property is available on TST 2.7.8 or later.) -
(deprecated): A string, indicate the operated extra tab contents inserted via Extra Tab Contents API. (This property is available on TST 3.3.7 or later and deprecated at TST 3.9.0. Currently it is left for backward compatibility.)originalTarget
If any addon responds to the message with a boolean value true
, TST's default behavior (activating the tab) will be canceled.
(On TST 2.7.8 and later, returning true
for clicking on twisty, closebox, and sound button also cancels default behavior for each button.)
For example:
browser.runtime.onMessageExternal.addListener((message, sender) => {
switch (sender.id) {
case TST_ID:
switch (message.type) {
...
case 'tab-clicked':
let focusChanged = ...; // you'll do something here
return Promise.resolve(focusChanged);
...
}
break;
}
});
On TST 3.0.12 and later, this notification won't be delivered if it happens on a private window and your addon is not allowed for private windows.
This API is available on TST 3.8.2 or later.
Messages with new-tab-button-mousedown
, new-tab-button-mouseup
and new-tab-button-clicked
types will be notified, when the new tab button is clicked.
Here is a list of properties the message object has:
-
window
(aliaswindowId
): An integer, the owner window's ID. -
button
: An integer to indicate the clicked button.0
=left button,1
=middle button (2
won't be notified) -
ctrlKey
: A boolean, theCtrl
(Control
) modifier key is pressed or not. -
shiftKey
: A boolean, theShift
modifier key is pressed or not. -
altKey
: A boolean, theAlt
modifier key is pressed or not. -
metaKey
: A boolean, theMeta
(Command
on macOS) modifier key is pressed or not. -
(deprecated): A string, indicate the operated extra tab contents inserted via Extra Tab Contents API. (Deprecated at TST 3.9.0. Currently it is left for backward compatibility.)originalTarget
If any addon responds to the message with a boolean value true
, TST's default behavior (open new tab) will be canceled.
For example:
browser.runtime.onMessageExternal.addListener((message, sender) => {
switch (sender.id) {
case TST_ID:
switch (message.type) {
...
case 'new-tab-button-clicked':
let overrideActionDone = ...; // you'll do something here
return Promise.resolve(overrideActionDone);
...
}
break;
}
});
This notification won't be delivered if it happens on a private window and your addon is not allowed for private windows.
Messages with tabbar-mousedown
, tabbar-mouseup
and tabbar-clicked
types will be notified, when the non-tab area is clicked.
Here is a list of properties the message object has:
-
window
(aliaswindowId
): An integer, the owner window's ID. -
button
: An integer to indicate the clicked button.0
=left button,1
=middle button (2
won't be notified) -
isMiddleClick
: A boolean indicating if a middle click was performed. -
ctrlKey
: A boolean, theCtrl
(Control
) modifier key is pressed or not. -
shiftKey
: A boolean, theShift
modifier key is pressed or not. -
altKey
: A boolean, theAlt
modifier key is pressed or not. -
metaKey
: A boolean, theMeta
(Command
on macOS) modifier key is pressed or not.
If any addon responds to the message with a boolean value true
, TST's default behavior (add new tab) will be canceled. (TST 2.0.5 or later)
On TST 3.0.12 and later, this notification won't be delivered if it happens on a private window and your addon is not allowed for private windows.
This API is available on TST 2.4.19 or later.
Following type messages can be delivered to your addon by moving pointer over tabs:
-
tab-mousemove
corresponds tomousemove
event on tabs. -
tab-mouseover
corresponds tomouseover
event on tabs. This won't be delivered again and again for same tab. -
tab-mouseout
corresponds tomouseout
event on tabs. This won't be delivered again and again for same tab.
Here is a list of properties these type message objects commonly have:
-
window
(aliaswindowId
): An integer, the owner window's ID. -
tab
: A tree item corresponding to the clicked tab. -
ctrlKey
: A boolean, theCtrl
(Control
) modifier key is pressed or not. -
shiftKey
: A boolean, theShift
modifier key is pressed or not. -
altKey
: A boolean, theAlt
modifier key is pressed or not. -
metaKey
: A boolean, theMeta
(Command
on macOS) modifier key is pressed or not. -
dragging
: A boolean, a dragging operation (started by long-press) is in progress or not.
These type messages won't be delivered to your addon implicitly. You need to list them at the listeningTypes
parameter for the register-self
message.
On TST 3.0.12 and later, this notification won't be delivered if it happens on a private window and your addon is not allowed for private windows.
This API is available on TST 3.8.9 or later.
There are two notification message types tabbar-overflow
and tabbar-underflow
to know changes of the overflow state of the vertical tab bar.
- A message with the type
tabbar-overflow
will be notified when the tab bar becomes scrollable for too many tabs or too small window height. - A message with the type
tabbar-underflow
will be notified when the tab bar becomes unscrollable for less tabs or very large window height.
Here is a list of properties these type message objects commonly have:
-
windowId
: An integer, the owner window's ID.
This API is available on TST 3.0.12 or later.
There are two notification message types tree-attached
and tree-detached
to know changes around the tree structure.
- A message with the type
tree-attached
will be notified when a tab is attached to an existing another tab. - A message with the type
tree-detached
will be notified when a child tab is detached from a parent tab.
Here is a list of properties these type message objects commonly have:
-
tab
: A tree item corresponding to the "child" tab, attached or detached.
tree-attached
type messages specially have more properties:
-
parent
: A tree item corresponding to the "parent" tab, the child tab is attached to. Itschildren
may have thetab
itself.
On the other hand, tree-detached
type messages specially have more properties:
-
oldParent
: A tree item corresponding to the "parent" tab, the child tab is detached from.
On TST 3.0.12 and later, this notification won't be delivered if it happens on a private window and your addon is not allowed for private windows.
This API is available on TST 3.3.7 or later.
When a tree is collapsed or expanded, a notification message with the type tree-collapsed-state-changed
will be delivered to listeners. The message object will have properties:
-
tab
: A tree item corresponding to the tab, collapsed or expanded its subtree. -
collapsed
: A boolean, indicating the tree is collapsed (true
) or expanded (false
).
This notification won't be delivered if it happens on a private window and your addon is not allowed for private windows.
This API is available on TST 4.0 or later.
When a tab is marked to be stuck or unmarked, a notification message with the type tab-sticky-state-changed
will be delivered to listeners. The message object will have properties:
-
tab
: A tree item corresponding to the tab which is changed its sticky state. -
sticky
: A boolean, indicating the tab is marked to be stuck (true
) or not (false
).
Please note that this notification will be delivered when the user does something action to mark a tab to be stuck or unmarked, not when the tab is moved away from the viewport and really stuck to a tab bar edge.
This notification won't be delivered if it happens on a private window and your addon is not allowed for private windows.
See also message types to change tabs' sticky state.
This API is available on TST 3.0.12 or later.
A message with the type permissions-changed
will be notified, when the requested permissions are granted/deprived, or the user allowed/disalloed to access information in private windows.
Here is a list of properties the message object has:
-
grantedPermissions
: An array of strings, currently granted permissions. -
privateWindowAllowed
: A boolean, indicating allowed (or not) to be notified messages from private windows.
If your addon injects additional style rules to TST's sidebar, you may need to re-inject it when permissions are changed, like:
browser.runtime.onMessageExternal.addListener((message, sender) => {
switch (sender.id) {
case TST_ID:
switch (message.type) {
...
case 'ready': // for restart
case 'permissions-changed': // for permission changes
registerToTST();
break;
...
}
break;
}
});
This API is available on TST 3.9.6 or later.
TST handles new tabs based on their context to manage tree of tabs; e.g. attaching a tab as a child tab of the active tab when it is opened from a link in the active tab, keeping a tab independent when it is opened via the "new tab" button.
The result depends on user-configured options, but TST also provides ability to override it from helper addons via its API.
When TST is trying to handle a new tab, it notifies a message with the type try-handle-newtab
to listener addons.
Here is a list of properties the message object has:
-
tab
: A tree item corresponding to the newly opened tab. -
activeTab
: A tree item corresponding to the (old) active tab when a new tab is opened. -
openerTab
(optional); A tree item corresponding to theopenerTabId
of the new tab. -
context
: A string indicating the context which the tab is opened in. Please note that the value is just guessed by TST, not provided by Firefox - sometimes it maybe wrong. Possible values:-
newtab-command
: Opened by Ctrl-T, "new tab" button in Firefox's tab bar, etc. -
with-opener
: Opened from a link or script in the active tab, or opened withopenerTabId
attribute given by someone. -
duplicated
: Opened as a duplicated tab of an existing tab. -
from-pinned
: Opened from a pinned tab. -
from-external
: Opened by something other application, external of Firefox. -
website-same-to-active-tab
: Opened with a URL of the website same to the active tab, e.g. from a bookmark, the address bar, or something. -
from-about-addons
: AMO webpages opened from the addon manager. -
unknown
: All other cases.
-
If any addon responds to the message with a boolean value true
, TST's handling will be canceled.
For example:
browser.runtime.onMessageExternal.addListener((message, sender) => {
switch (sender.id) {
case TST_ID:
switch (message.type) {
...
case 'try-handle-newtab':
if (message.context == 'newtab-command') {
// something operation to handle new tab opened by Ctrl-T or something way.
return Promise.resolve(true);
}
return;
...
}
break;
}
});
This notification won't be delivered if it happens on a private window and your addon is not allowed for private windows.
Please note that you may also need to suppress autofixing of tree structure for moved tabs to prevent auto-attaching of the new tab by TST.
This API is available on TST 3.3.7 or later.
TST automatically moves focus to the most nearest visible ancestor tab by default, when you collapse a tree and the active tab is going to be invisible. This behavior can be canceled by another addon.
- A message with the type
try-move-focus-from-collapsing-tree
will be notified, when the current tab is going to be invisible by collapsing of a parent tree. - A message with the type
try-redirect-focus-from-collaped-tab
will be notified, when another tab is going to be focused for a redirection from unexpectedly focused collapsed tab. (available on TST 3.4.5 and later)- This will be notified next of the corresponding
try-expand-tree-from-focused-collapsed-tab
.
- This will be notified next of the corresponding
Here is a list of properties the message object has:
-
tab
: A tree item corresponding to the current tab going to be invisible. -
focusDirection
(available only fortry-redirect-focus-from-collaped-tab
, on TST 3.4.5 and later): A number indicating the guessed focus direciton.-1
means "focus from a following tab by Ctrl-Shift-Tab",1
means "focus from a preceding tab by Ctrl-Tab".
If any addon responds to the message with a boolean value true
, TST's default behavior (activating the nearest visible ancestor tab) will be canceled.
For example:
browser.runtime.onMessageExternal.addListener((message, sender) => {
switch (sender.id) {
case TST_ID:
switch (message.type) {
...
case 'try-move-focus-from-collapsing-tree':
return Promise.resolve(true);
...
}
break;
}
});
This notification won't be delivered if it happens on a private window and your addon is not allowed for private windows.
This API is available on TST 3.3.7 or later.
TST automatically expands existing collapsed trees by default on some situations. This behavior can be canceled by another addon.
- A message with the type
try-expand-tree-from-focused-parent
will be notified, when a parent tab with collapsed children gets focused. - A message with the type
try-expand-tree-from-focused-bundled-parent
will be notified, when a parent tab with collapsed children gets pseudo focus with corresponding focused pinned tab. - A message with the type
try-expand-tree-from-attached-child
will be notified, when a child tab is attached to a collapsed tree. - A message with the type
try-expand-tree-from-focused-collapsed-tab
will be notified, when an invisible descendant tab gets focused.- On TST 3.4.5 and later, a corresponding
try-redirect-focus-from-collaped-tab
notification will be sent after this notification.
- On TST 3.4.5 and later, a corresponding
- A message with the type
try-expand-tree-from-long-press-ctrl-key
will be notified, when the Ctrl (Control) key is pressed for a while when you are switching tabs with Ctrl-Tab/Ctrl-Shift-Tab. - A message with the type
try-expand-tree-from-end-tab-switch
will be notified, when the Ctrl (Control) key is released after tab switching with Ctrl-Tab/Ctrl-Shift-Tab. - A message with the type
try-expand-tree-from-expand-command
will be notified when "Expand this Tree recursively" context menu (or shortcut) command is invoked. (on TST 3.9.13 and later) - A message with the type
try-expand-tree-from-expand-all-command
will be notified when "Expand All" context menu (or shortcut) command is invoked. (on TST 3.9.13 and later)
Here is a list of properties the message object has:
-
tab
: A tree item corresponding to the tab trying to expand its tree. In other words, it is a parent tab. -
child
: A tree item (available only fortry-expand-tree-from-attached-child
, on TST 4.0 and later) corresponding to the tab attached to the parent. -
focusDirection
(available only fortry-expand-tree-from-focused-collapsed-tab
, on TST 3.4.5 and later): A number indicating the guessed focus direciton.-1
means "focus from a following tab by Ctrl-Shift-Tab",1
means "focus from a preceding tab by Ctrl-Tab". -
recursivelyExpanded
(available only fortry-expand-tree-from-expand-command
, on TST 3.9.13 and later): A boolean indicating that the notified tab is expanded recursively. In other words,false
means that the context menu (or shortcut) command "Expand this Tree recursively" is invoked on the notified tab.
If any addon responds to the message with a boolean value true
, TST's default behavior (expanding the tree) will be canceled.
For example:
browser.runtime.onMessageExternal.addListener((message, sender) => {
switch (sender.id) {
case TST_ID:
switch (message.type) {
...
case 'try-expand-tree-from-focused-parent':
case 'try-expand-tree-from-focused-collapsed-tab':
case 'try-expand-tree-from-long-press-ctrl-key':
case 'try-expand-tree-from-end-tab-switch':
return Promise.resolve(true);
...
}
break;
}
});
These notifications won't be delivered if they happen on a private window and your addon is not allowed for private windows.
This API is available on TST 3.8.22 or later.
TST automatically collapses existing expanded trees by default on some situations. This behavior can be canceled by another addon.
- A message with the type
try-collapse-tree-from-other-expansion
will be notified when a collapsed tree gets focused and it become expanded. - A message with the type
try-collapse-tree-from-collapse-command
will be notified when "Collapse this Tree recursively" context menu (or shortcut) command is invoked. (on TST 3.9.17 and later) - A message with the type
try-collapse-tree-from-collapse-all-command
will be notified when "Collapse All" context menu (or shortcut) command is invoked. (on TST 3.9.17 and later)
Here is a list of properties the message object has:
-
tab
: A tree item corresponding to the parent tab going to be collapsed. -
recursivelyExpanded
(available only fortry-collapse-tree-from-collapse-command
, on TST 3.9.15 and later): A boolean indicating that the notified tab is collapsed recursively. In other words,false
means that the context menu (or shortcut) command "Collapse this Tree recursively" is invoked on the notified tab.
If any addon responds to the message with a boolean value true
, TST's default behavior (collapsing the tree) will be canceled.
For example:
browser.runtime.onMessageExternal.addListener((message, sender) => {
switch (sender.id) {
case TST_ID:
switch (message.type) {
...
case 'try-collapse-tree-from-other-expansion':
return Promise.resolve(true);
...
}
break;
}
});
This notification won't be delivered if it happen on a private window and your addon is not allowed for private windows.
This API is available on TST 3.4.10 or later.
TST tries autofixing of tree structure when tabs are moved by other addons, but you can also deactivate the autofixing behavior fundamentally on some cases - for example your addon moves multiple tabs in a time.
A message with the type try-fixup-tree-on-tab-moved
will be notified after a listener of tabs.onMoved
is called, if TST tries autofixing for the moved tab.
Here is a list of properties the message object has:
-
tab
: A tree item corresponding to the moved tab. -
fromIndex
A number corresponding to thefromIndex
of thetabs.onMoved
notification. -
toIndex
A number corresponding to thetoIndex
of thetabs.onMoved
notification. -
action
A string indicating the autofixing action. One ofmove
,attach
,detach
, ormoveBack
(this means that TST detected the tab move as an invalid move conflicting to the current tree structure, and the tab is going to be moved back to its original position.) -
parent
: A tree item that the moved tab is going to be attached to. This will be provided whenaction
isattach
. -
insertBefore
: A tree item corresponding to a tab going to become the new next sibling tab of the moved tab. This will be provided whenaction
isattach
,detach
, ormove
. -
insertAfter
: A tree item corresponding to a tab going to become the new previous sibling tab of the moved tab. This will be provided whenaction
isattach
,detach
, ormove
.
If any addon responds to the message with a boolean value true
, TST's autofixing will be canceled.
For example:
browser.runtime.onMessageExternal.addListener((message, sender) => {
switch (sender.id) {
case TST_ID:
switch (message.type) {
...
case 'try-fixup-tree-on-tab-moved':
return Promise.resolve(true);
...
}
break;
}
});
This notifications won't be delivered if they happen on a private window and your addon is not allowed for private windows.
This API is available on TST 4.0.23 or later.
A message with the type try-scroll-to-activated-tab
will be notified before TST tris to scroll the sidebar contents to the tab when the tab gets focus.
Here is a list of properties the message object has:
-
tab
: A tree item corresponding to the moved tab.
If any addon responds to the message with a boolean value true
, TST won't scroll the sidebar to the tab.
For example:
browser.runtime.onMessageExternal.addListener((message, sender) => {
switch (sender.id) {
case TST_ID:
switch (message.type) {
...
case 'try-scroll-to-activated-tab':
// Don't scroll the sidebar when the activated tab is stuck.
if (message.type.states.includes('stuck'))
return Promise.resolve(true);
return;
...
}
break;
}
});
This notifications won't be delivered if they happen on a private window and your addon is not allowed for private windows.
This API is available on TST 2.7.3 or later.
TST shows a confirmation dialog when you close multiple tabs at a time by default. If your addon already provides similar dialog and you want to suppress TST's dialog, you can do that by a grant-to-remove-tabs
type message like:
browser.runtime.sendMessage(TST_ID, {
type: 'grant-to-remove-tabs',
tabs: [1, 2, 3] // required, an array of tabs.Tab.id or alias
});
After that TST won't show the confirmation dialog for specified tabs.
block-grouping
type message disables the auto-grouping behavior for newly opened tabs.
let success = await browser.runtime.sendMessage(TST_ID, {
type: 'block-grouping'
});
On the other hand, unblock-grouping
message re-enables the auto-grouping behavior again.
let success = await browser.runtime.sendMessage(TST_ID, {
type: 'unblock-grouping'
});
Multiple addons can block the auto-grouping behavior, so please remind that you don't forget to unblock the auto-grouping behavior before your addon is completely unloaded (disabled or uninstalled).
This API is available on TST 3.2.4 or later.
open-all-bookmarks-with-structure
type message opens all bookmarks in the specified folder with structure.
For example:
browser.runtime.sendMessage(TST_ID, {
type: 'open-all-bookmarks-with-structure',
id: '4Mgbi1Guv2wi', // required, an id of a folder or a regular bookmark
discarded: true, // optional, keep tabs pended or not (default: user's preference)
recursively: false, // optional, retrieve subfolders recursively or not (default: false)
});
Options discarded
and recursively
are available on TST 3.2.6 and later.
Please note that TST tries to open all bookmarks in its parent folder, if you specify an id of a regular bookmark.
add-tab-state
attach
block-grouping
clear-all-extra-tab-contents
clear-extra-contents
-
(deprecated at TST 3.9.0)clear-extra-tab-contents
-
(deprecated at TST 3.9.0)clear-extra-new-tab-button-contents
clear-tooltip-text
collapse-tree
contextMenu-create
contextMenu-update
contextMenu-remove
contextMenu-remove-all
create
demote
detach
duplicate
expand-tree
-
fake-contextMenu-create
(for backward compatibility) -
fake-contextMenu-update
(for backward compatibility) -
fake-contextMenu-remove
(for backward compatibility) -
fake-contextMenu-remove-all
(for backward compatibility) focus
indent
get-drag-data
get-light-tree
get-tree
get-tree-structure
grant-to-remove-tabs
group-tabs
lock-tree-collapsed
move-after
move-before
move-down
move-to-end
move-to-start
move-up
open-all-bookmarks-with-structure
open-in-new-window
outdent
override-context
ping
promote
-
register-self
(for unregistration) register-auto-sticky-states
remove-tab-state
reopen-in-container
set-tooltip-text
scroll
scroll-lock
scroll-unlock
set-extra-contents
-
(deprecated at TST 3.9.0)set-extra-tab-contents
-
(deprecated at TST 3.9.0)set-extra-new-tab-button-contents
set-tree-structure
stick-tab
stop-scroll
toggle-lock-tree-collapsed
toggle-sticky-state
toggle-tree-collapsed
unblock-grouping
unlock-tree-collapsed
unregister-auto-sticky-states
unregister-self
unstick-tab
wait-for-shutdown
contextMenu-shown
contextMenu-click
extra-contents-blur
extra-contents-change
extra-contents-clicked
extra-contents-compositionend
extra-contents-compositionstart
extra-contents-compositionupdate
extra-contents-dblclicked
extra-contents-focus
extra-contents-input
extra-contents-keydown
extra-contents-keyup
extra-contents-mousedown
extra-contents-mouseup
-
fake-contextMenu-shown
(for backward compatibility) -
fake-contextMenu-click
(for backward compatibility) get-version
new-tab-button-clicked
new-tab-button-mousedown
new-tab-button-mouseup
new-tab-processed
permissions-changed
ready
scrolled
sidebar-hide
sidebar-show
tabbar-clicked
tabbar-mousedown
tabbar-mouseup
tabbar-overflow
tabbar-underflow
tab-clicked
tab-dblclicked
tab-mousedown
tab-mousemove
tab-mouseout
tab-mouseover
tab-mouseup
tab-sticky-state-changed
tabs-rendered
tabs-unrendered
tree-attached
tree-collapsed-state-changed
tree-detached
try-collapse-tree-from-collapse-all-command
try-collapse-tree-from-collapse-command
try-collapse-tree-from-other-expansion
try-expand-tree-from-attached-child
try-expand-tree-from-end-tab-switch
try-expand-tree-from-expand-all-command
try-expand-tree-from-expand-command
try-expand-tree-from-focused-bundled-parent
try-expand-tree-from-focused-collapsed-tab
try-expand-tree-from-focused-parent
try-expand-tree-from-long-press-ctrl-key
try-fixup-tree-on-tab-moved
try-handle-newtab
try-redirect-focus-from-collaped-tab
try-scroll-to-activated-tab
try-move-focus-from-collapsing-tree