To see how tabs.query()
and tabs.Tab
are used, let's walk through how the tabs-tabs-tabs example adds the list of "switch to tabs" to its toolbar button popup.

-
manifest.json
-
Here is the manifest.json
:
{
"browser_action": {
"browser_style": true,
"default_title": "Tabs, tabs, tabs",
"default_popup": "tabs.html"
},
"description": "A list of methods you can perform on a tab.",
"homepage_url": "https://github.com/mdn/webextensions-examples/tree/master/tabs-tabs-tabs",
"manifest_version": 2,
"name": "Tabs, tabs, tabs",
"permissions": [
"tabs"
],
"version": "1.0"
}
Note:
tabs.html
is defined as the default_popup
in browser_action
. It is displayed whenever the user clicks the extension's toolbar icon.
- Permissions includes tabs. This is needed to support the tab list feature, as the extension reads the title of the tabs for display in the popup.
-
tabs.html
-
tabs.html
defines the content of the extension's popup:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="tabs.css" />
</head>
<body>
<div class="panel">
<div class="panel-section panel-section-header">
<div class="text-section-header">Tabs-tabs-tabs</div>
</div>
<a href="#" id="tabs-move-beginning">
Move active tab to the beginning of the window
</a>
<br />
<div class="switch-tabs">
<p>Switch to tab</p>
<div id="tabs-list"></div>
</div>
</div>
<script src="tabs.js"></script>
</body>
</html>
This does the following:
- The menu items are declared.
- An empty
div
with the ID tabs-list
is declared to contain the list of tabs.
tabs.js
is called.
-
tabs.js
-
In tabs.js
, we'll see how the list of tabs is built and added to the popup.
First, an event handler is added to execute listTabs()
when tabs.html
is loaded:
document.addEventListener("DOMContentLoaded", listTabs);
The first thing that listTabs()
does is to call getCurrentWindowTabs()
. This is where tabs.query()
is used to get a tabs.Tab
object for the tabs in the current window:
function getCurrentWindowTabs() {
return browser.tabs.query({ currentWindow: true });
}
Now, listTabs()
is ready to create the content for the popup.
To start with:
- Grab the
<div id="tabs-list">
element.
- Create a document fragment (into which the list will be built).
- Set counters.
- Clear the content of the
<div id="tabs-list">
element.
function listTabs() {
getCurrentWindowTabs().then((tabs) => {
const tabsList = document.getElementById('tabs-list');
const currentTabs = document.createDocumentFragment();
const limit = 5;
let counter = 0;
tabsList.textContent = '';
Next, we'll create the links for each tab:
- Loops through the first 5 items from the
tabs.Tab
object.
- For each item, add a hyperlink to the document fragment.
- The link's label—that is, its text—is set using the tab's
title
(or the id
, if it has no title
).
- The link's address is set using the tab's
id
.
for (const tab of tabs) {
if (!tab.active && counter <= limit) {
const tabLink = document.createElement("a");
tabLink.textContent = tab.title || tab.id;
tabLink.setAttribute("href", tab.id);
tabLink.classList.add("switch-tabs");
currentTabs.appendChild(tabLink);
}
counter += 1;
}
Finally, the document fragment is written to the <div id="tabs-list">
element:
tabsList.appendChild(currentTabs);
});
}
Working with the active tab
Another related example feature is the "Alert active tab" info option that dumps all the tabs.Tab
object properties for the active tab into an alert:
else if (e.target.id === "tabs-alertinfo") {
callOnActiveTab((tab) => {
let props = "";
for (const item in tab) {
props += `${ item } = ${ tab[item] } \n`;
}
alert(props);
});
}
Where callOnActiveTab()
finds the active tab object by looping through the tabs.Tab
objects looking for the item with active set:
document.addEventListener("click", (e) => {
function callOnActiveTab(callback) {
getCurrentWindowTabs().then((tabs) => {
for (const tab of tabs) {
if (tab.active) {
callback(tab, tabs);
}
}
});
}
}