-
Notifications
You must be signed in to change notification settings - Fork 280
Tab Extra Contents API
(generated by Table of Contents Generator for GitHub Wiki)
TST provides ability to embed arbitrary contents inside tabs via its API. You can provide custom UI elements on TST's tabs - icons, buttons, thumbnails, and more.
This feature is available on TST 3.3.7 and later.
You can set extra contents for a tab with a message with the type set-extra-tab-contents
. For example:
const TST_ID = '[email protected]';
function insertContents(tabId) {
browser.runtime.sendMessage(TST_ID, {
type: 'set-extra-tab-contents',
id: tabId,
contents: `<button part="button">foo</button>`
});
}
Parameters are:
-
id
: Integer, ID of the tab. -
contents
(optional): String, HTML source of extra contents. Dangerous contents are automatically sanitized. If you specify null contents, previous contents will be cleared.- Only limited safe type elements are allowed, and all others (for example
<script>
) will be rejected. There is a list of allowed element types.
- Only limited safe type elements are allowed, and all others (for example
-
style
(optional): String, CSS style definitions for inserted contents. -
place
(optional): String,"front"
(default value) or"behind"
.
// For all existing tabs in currently shown sidebars
browser.tabs.query({}).then(tabs => {
for (const tab of tabs) {
insertContents(tab.id);
}
});
// For new tabs opened after initialized
browser.tabs.onCreated.addListener(tab => {
insertContents(tab.id);
});
// For existing tabs, after the sidebar is shown
async function registerToTST() {
try {
await browser.runtime.sendMessage(TST_ID, {
type: 'register-self',
name: browser.i18n.getMessage('extensionName'),
icons: browser.runtime.getManifest().icons,
listeningTypes: ['sidebar-show']
});
}
catch(e) {
// TST is not available
}
}
registerToTST();
browser.runtime.onMessageExternal.addListener((message, sender) => {
if (sender.id != TST_ID)
return;
switch (message.type) {
case 'sidebar-show':
browser.tabs.query({ windowId: message.windowId }).then(tabs => {
for (const tab of tabs) {
insertContents(tab.id);
}
});
break;
}
});
Notification messages with types tab-mousedown
, tab-mouseup
, tab-clicked
and tab-dblclicked
will have an extra property originalTarget
(string, the source of the element which the user operated on) when those actions happen on any extra tab contents.
async function registerToTST() {
try {
await browser.runtime.sendMessage(TST_ID, {
type: 'register-self',
name: browser.i18n.getMessage('extensionName'),
icons: browser.runtime.getManifest().icons,
listeningTypes: [..., 'tab-mousedown', 'tab-dblclicked']
});
}
catch(e) {
// TST is not available
}
}
registerToTST();
browser.runtime.onMessageExternal.addListener((message, sender) => {
if (sender.id != TST_ID)
return;
switch (message.type) {
...
case 'tab-mousedown':
case 'tab-dbclicked':
if (message.originalTarget) {
console.log(message.originalTarget); // => "<button>foo</button>"
return Promise.resolve(true); // cancel default event handling of TST
}
break;
}
});
Extra contents are inserted to tabs under a shadow root. The container element generated by TST always has a fixed part name container
, and TST appends a common part name extra-contents-for-(sanitized addon id)
to all inserted elements originally with their own part
attribute. For exmple, if you set <button part="button">foo</button>
as the contents, it will become:
<span part="extra-contents-for-(sanitized addon id) container">
<button part="container extra-contents-for-(sanitized addon id)">
foo
</button>
</span>
Such shadow DOM elements won't be styled with regular CSS applied to the document, thus there are two methods to style extra tab contents.
CSS Shadow Parts, available on Firefox 72 and later, is the recommended way. You can use ::part()
pseudo element to specify elements under shadow root, for example:
async function registerToTST() {
try {
await browser.runtime.sendMessage(TST_ID, {
type: 'register-self',
...
style: `
::part(%EXTRA_CONTENTS_PART% container) {
background: ThreeDFace;
border: 1px solid ThreeDDarkShadow;
color: ButtonText;
}
::part(%EXTRA_CONTENTS_PART% button) {
background: transparent;
border: none;
}
tab-item.active ::part(%EXTRA_CONTENTS_PART% button) {
background: InactiveCaption;
color: InactiveCaptionText;
}
tab-item.active ::part(%EXTRA_CONTENTS_PART% button):hover {
background: ActiveCaption;
color: CaptionText;
}
`
});
}
catch(e) {
}
}
A placeholder %EXTRA_CONTENTS_PART%
is available: it will be replaced to the common part name (extra-contents-for-(sanitized addon id)
) automatically.
On old versions of Firefox without CSS Shadow Parts support, you need to use a different way: style
parameter for each contents. For exmaple:
browser.runtime.sendMessage(TST_ID, {
type: 'set-extra-tab-contents',
...
style: `
[part~="%EXTRA_CONTENTS_PART%"][part~="container"] {
background: ThreeDFace;
border: 1px solid ThreeDDarkShadow;
color: ButtonText;
}
[part~="%EXTRA_CONTENTS_PART%"][part~="button"] {
background: transparent;
border: none;
}
`
});
It will generates custom <style>
element for each shadow root, so it may decrease system performance.
You can clear your extra contents from a tab at arbitrary timing, with a message with the type clear-extra-tab-contents
. For example:
function clearContents(tabId) {
browser.runtime.sendMessage(TST_ID, {
type: 'clear-extra-tab-contents',
id: tabId
});
}
Parameters are:
-
id
: Integer, ID of the tab.
This will clear both front and behind contents. If you need to clear only one of them, you need to call set-extra-tab-contents
with null contents.
You can clear all your extra contents from all tabs, with a message with the type clear-all-extra-tab-contents
. For example:
browser.runtime.sendMessage(TST_ID, {
type: 'clear-all-extra-tab-contents'
});