Bug 1332447 Part 2 - Implementation of the per-browser tabstrip hiding API; r?bwinton
MozReview-Commit-ID: 86GKiqCYUvS
--- a/browser/components/extensions/ext-browser.js
+++ b/browser/components/extensions/ext-browser.js
@@ -719,17 +719,79 @@ class Tab extends TabBase {
result.favIconUrl = tabData.image;
}
}
return result;
}
}
+
+class TabVisibilityManager {
+ constructor(win) {
+ this.window = win;
+ this.tabHidingContexts = new Set();
+ }
+
+ get tabsVisibility() {
+ return this.tabHidingContexts.size == 0;
+ }
+
+ set tabsVisibility(isVisible) {
+ this._updateTabsVisibility(isVisible);
+ let id = windowTracker.getId(this.window.window);
+ }
+
+
+ _updateTabsVisibility(isVisible) {
+ let toolbar = this.window.window.document.getElementById("TabsToolbar");
+ if (isVisible) {
+ toolbar.classList.remove("webext-collapsed");
+ } else {
+ toolbar.classList.add("webext-collapsed");
+ }
+ }
+
+ // Do not call directly. Called by contexts when they shut down.
+ close(context) {
+ this.tabHidingContexts.delete(context);
+ if (this.tabHidingContexts.size == 0) {
+ this.tabsVisibility = true;
+ }
+ }
+
+ setTabsVisibility(context, visible) {
+ if (!visible) {
+ if (this.tabHidingContexts.has(context)) {
+ return;
+ }
+ let wasVisible = this.tabsVisibility;
+ this.tabHidingContexts.add(context);
+ context.callOnClose(this);
+ // First context asking the tabstrip to be hidden.
+ if (wasVisible) {
+ this.tabsVisibility = false;
+ }
+ } else {
+ // Visible true always takes priority: clear everyone.
+ for (let context of this.tabHidingContexts) {
+ context.forgetOnClose(this);
+ }
+ this.tabHidingContexts.clear();
+ this.tabsVisibility = true;
+ }
+ }
+};
+
class Window extends WindowBase {
+ constructor(extension, window, id) {
+ super(extension, window, id);
+ this.tabVisibilityManager = new TabVisibilityManager(this);
+ }
+
/**
* Update the geometry of the browser window.
*
* @param {Object} options
* An object containing new values for the window's geometry.
* @param {integer} [options.left]
* The new pixel distance of the left side of the browser window from
* the left of the screen.
--- a/browser/components/extensions/ext-tabs.js
+++ b/browser/components/extensions/ext-tabs.js
@@ -932,14 +932,14 @@ this.tabs = class extends ExtensionAPI {
async toggleReaderMode(tabId) {
let tab = await promiseTabWhenReady(tabId);
if (!tab.isInReaderMode && !tab.isArticle) {
throw new ExtensionError("The specified tab cannot be placed into reader mode.");
}
tab = getTabOrActive(tabId);
tab.linkedBrowser.messageManager.sendAsyncMessage("Reader:ToggleReaderMode");
- },
+ }
},
};
return self;
}
};
--- a/browser/components/extensions/ext-windows.js
+++ b/browser/components/extensions/ext-windows.js
@@ -235,12 +235,22 @@ this.windows = class extends ExtensionAP
return new Promise(resolve => {
let listener = () => {
windowTracker.removeListener("domwindowclosed", listener);
resolve();
};
windowTracker.addListener("domwindowclosed", listener);
});
},
+
+ getTabsVisibility(windowId) {
+ let win = windowManager.get(windowId, context);
+ return Promise.resolve(win.tabVisibilityManager.tabsVisibility);
+ },
+
+ setTabsVisibility(windowId, visible) {
+ let win = windowManager.get(windowId, context);
+ win.tabVisibilityManager.setTabsVisibility(context, visible);
+ },
},
};
}
};
--- a/browser/components/extensions/schemas/tabs.json
+++ b/browser/components/extensions/schemas/tabs.json
@@ -7,17 +7,18 @@
"namespace": "manifest",
"types": [
{
"$extend": "OptionalPermission",
"choices": [{
"type": "string",
"enum": [
"activeTab",
- "tabs"
+ "tabs",
+ "tabsVisibility"
]
}]
}
]
},
{
"namespace": "tabs",
"description": "Use the <code>browser.tabs</code> API to interact with the browser's tab system. You can use this API to create, modify, and rearrange tabs in the browser.",
--- a/browser/components/extensions/schemas/windows.json
+++ b/browser/components/extensions/schemas/windows.json
@@ -448,16 +448,56 @@
},
{
"type": "function",
"name": "callback",
"optional": true,
"parameters": []
}
]
+ },
+ {
+ "name": "getTabsVisibility",
+ "type": "function",
+ "async": "callback",
+ "permissions": ["tabsVisibility"],
+ "description": "Query the visibility of the tabstrip.",
+ "parameters": [
+ {
+ "type": "integer",
+ "name": "windowId",
+ "minimum": 0
+ },
+ {
+ "type": "function",
+ "name": "callback",
+ "description": "Called with the window's current tab visibility state when fetched",
+ "parameters": [
+ {
+ "type": "boolean",
+ "name": "hidden",
+ "description": "Whether or not the tab strip is currently hidden"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "setTabsVisibility",
+ "type": "function",
+ "permissions": ["tabsVisibility"],
+ "description": "Sets the visibility of the tabstrip.",
+ "parameters": [{
+ "type": "integer",
+ "name": "windowId",
+ "minimum": 0
+ },
+ {
+ "type": "boolean"
+ }]
}
],
"events": [
{
"name": "onCreated",
"type": "function",
"description": "Fired when a window is created.",
"filters": [
@@ -512,12 +552,12 @@
"parameters": [
{
"type": "integer",
"name": "windowId",
"minimum": -1,
"description": "ID of the newly focused window."
}
]
- }
+ }
]
}
]
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -114,16 +114,17 @@ webextPerms.description.notifications=Di
webextPerms.description.pkcs11=Provide cryptographic authentication services
webextPerms.description.privacy=Read and modify privacy settings
webextPerms.description.proxy=Control browser proxy settings
webextPerms.description.sessions=Access recently closed tabs
webextPerms.description.tabs=Access browser tabs
webextPerms.description.topSites=Access browsing history
webextPerms.description.unlimitedStorage=Store unlimited amount of client-side data
webextPerms.description.webNavigation=Access browser activity during navigation
+webextPerms.description.tabsVisibility=Changes the visibility of the tab strip
webextPerms.hostDescription.allUrls=Access your data for all websites
# LOCALIZATION NOTE (webextPerms.hostDescription.wildcard)
# %S will be replaced by the DNS domain for which a webextension
# is requesting access (e.g., mozilla.org)
webextPerms.hostDescription.wildcard=Access your data for sites in the %S domain
--- a/browser/themes/linux/browser.css
+++ b/browser/themes/linux/browser.css
@@ -67,16 +67,20 @@
#TabsToolbar:not([collapsed="true"]) + #nav-bar {
border-top: 1px solid var(--tabs-border) !important;
background-clip: padding-box;
/* Position the toolbar above the bottom of background tabs */
position: relative;
z-index: 1;
}
+#TabsToolbar.webext-collapsed > * {
+ visibility: collapse;
+}
+
#nav-bar {
padding-top: 2px;
padding-bottom: 2px;
}
#browser-bottombox {
/* opaque for layers optimization */
background-color: -moz-Dialog;
--- a/browser/themes/osx/browser.css
+++ b/browser/themes/osx/browser.css
@@ -154,16 +154,24 @@
}
#TabsToolbar:not([collapsed="true"]) + #nav-bar {
/* The toolbar buttons that animate are only visible when the #TabsToolbar is not collapsed.
The animations use position:absolute and require a positioned #nav-bar. */
position: relative;
}
+#TabsToolbar.webext-collapsed {
+ min-height: 27px;
+}
+
+#TabsToolbar.webext-collapsed > * {
+ visibility: collapse;
+}
+
#PersonalToolbar:not(:-moz-lwtheme):-moz-window-inactive,
#nav-bar:not(:-moz-lwtheme):-moz-window-inactive {
background-color: -moz-mac-chrome-inactive;
}
/* ----- BOOKMARK TOOLBAR ----- */
#nav-bar-customization-target > #wrapper-personal-bookmarks > #personal-bookmarks {
--- a/browser/themes/windows/browser.css
+++ b/browser/themes/windows/browser.css
@@ -253,16 +253,46 @@
}
#TabsToolbar:not([collapsed="true"]) + #nav-bar {
/* Position the toolbar above the bottom of background tabs */
position: relative;
z-index: 1;
}
+#TabsToolbar.webext-collapsed > * {
+ visibility: collapse;
+}
+
+#TabsToolbar.webext-collapsed {
+ min-height: 31.5px;
+}
+
+@media (-moz-os-version: windows-win7) {
+ #TabsToolbar.webext-collapsed {
+ min-height: 20px;
+ }
+}
+
+@media (-moz-os-version: windows-win8) {
+ #TabsToolbar.webext-collapsed {
+ min-height: 22px;
+ }
+}
+
+@media (-moz-windows-classic) {
+ #TabsToolbar.webext-collapsed {
+ min-height: 16px;
+ }
+}
+
+#toolbar-menubar:not([inactive]) + #TabsToolbar {
+ min-height: 0 !important;
+}
+
#nav-bar {
border-top: 1px solid var(--tabs-border) !important;
}
@media (-moz-windows-compositor: 0) {
#TabsToolbar[collapsed="true"] + #nav-bar {
border-top-style: none !important;
}
}