diff --git a/browser/base/content/browser-menubar.inc b/browser/base/content/browser-menubar.inc
index a9e4ea3f43ce..f3e08cfedfa3 100644
--- a/browser/base/content/browser-menubar.inc
+++ b/browser/base/content/browser-menubar.inc
@@ -199,16 +199,19 @@
accesskey="&viewSidebarMenu.accesskey;">
diff --git a/browser/base/content/browser-sets.inc b/browser/base/content/browser-sets.inc
index b7520510c7b6..870e890c488d 100644
--- a/browser/base/content/browser-sets.inc
+++ b/browser/base/content/browser-sets.inc
@@ -122,14 +122,6 @@
#include ../../components/places/content/placesCommands.inc.xul
-
-
-
-
@@ -145,9 +137,6 @@
-
#endif
-
+
#ifdef XP_WIN
# Cmd+I is conventially mapped to Info on MacOS X, thus it should not be
# overridden for other purposes there.
-
+
#endif
@@ -306,7 +295,7 @@
#else
modifiers="accel"
#endif
- command="viewHistorySidebar"/>
+ oncommand="SidebarUI.toggle('viewHistorySidebar');"/>
diff --git a/browser/base/content/browser-sidebar.js b/browser/base/content/browser-sidebar.js
index ec7e213e60fc..833a3bc98193 100644
--- a/browser/base/content/browser-sidebar.js
+++ b/browser/base/content/browser-sidebar.js
@@ -15,16 +15,22 @@ var SidebarUI = {
title: document.getElementById("sidebar-switcher-bookmarks")
.getAttribute("label"),
url: "chrome://browser/content/places/bookmarksSidebar.xul",
+ menuId: "menu_bookmarksSidebar",
+ buttonId: "sidebar-switcher-bookmarks",
}],
["viewHistorySidebar", {
title: document.getElementById("sidebar-switcher-history")
.getAttribute("label"),
url: "chrome://browser/content/places/historySidebar.xul",
+ menuId: "menu_historySidebar",
+ buttonId: "sidebar-switcher-history",
}],
["viewTabsSidebar", {
title: document.getElementById("sidebar-switcher-tabs")
.getAttribute("label"),
url: "chrome://browser/content/syncedtabs/sidebar.xhtml",
+ menuId: "menu_tabsSidebar",
+ buttonId: "sidebar-switcher-tabs",
}],
]);
},
@@ -235,7 +241,7 @@ var SidebarUI = {
// dynamically generated sidebars will fail this check, but we still
// consider it adopted.
- if (!document.getElementById(commandID)) {
+ if (!this.sidebars.has(commandID)) {
return true;
}
@@ -275,7 +281,7 @@ var SidebarUI = {
}
let commandID = this._box.getAttribute("sidebarcommand");
- if (commandID && document.getElementById(commandID)) {
+ if (commandID && this.sidebars.has(commandID)) {
this.showInitially(commandID);
} else {
this._box.removeAttribute("checked");
@@ -323,7 +329,7 @@ var SidebarUI = {
},
/**
- * The ID of the current sidebar (ie, the ID of the broadcaster being used).
+ * The ID of the current sidebar.
*/
get currentID() {
return this.isOpen ? this._box.getAttribute("sidebarcommand") : "";
@@ -337,20 +343,12 @@ var SidebarUI = {
this._title.value = value;
},
- getBroadcasterById(id) {
- let sidebarBroadcaster = document.getElementById(id);
- if (sidebarBroadcaster && sidebarBroadcaster.localName == "broadcaster") {
- return sidebarBroadcaster;
- }
- return null;
- },
-
/**
* Toggle the visibility of the sidebar. If the sidebar is hidden or is open
* with a different commandID, then the sidebar will be opened using the
* specified commandID. Otherwise the sidebar will be hidden.
*
- * @param {string} commandID ID of the xul:broadcaster element to use.
+ * @param {string} commandID ID of the sidebar.
* @param {DOMNode} [triggerNode] Node, usually a button, that triggered the
* visibility toggling of the sidebar.
* @return {Promise}
@@ -363,7 +361,7 @@ var SidebarUI = {
if (!commandID) {
commandID = this._box.getAttribute("sidebarcommand");
}
- if (!commandID || !this.getBroadcasterById(commandID)) {
+ if (!commandID || !this.sidebars.has(commandID)) {
commandID = this.DEFAULT_SIDEBAR_ID;
}
@@ -374,28 +372,27 @@ var SidebarUI = {
return this.show(commandID, triggerNode);
},
- _loadSidebarExtension(sidebarBroadcaster) {
- let extensionId = sidebarBroadcaster.getAttribute("extensionId");
+ _loadSidebarExtension(commandID) {
+ let sidebar = this.sidebars.get(commandID);
+ let {extensionId} = sidebar;
if (extensionId) {
- let extensionUrl = sidebarBroadcaster.getAttribute("panel");
- let browserStyle = sidebarBroadcaster.getAttribute("browserStyle");
- SidebarUI.browser.contentWindow.loadPanel(extensionId, extensionUrl, browserStyle);
+ SidebarUI.browser.contentWindow.loadPanel(extensionId, sidebar.panel,
+ sidebar.browserStyle);
}
},
/**
- * Show the sidebar, using the parameters from the specified broadcaster.
- * @see SidebarUI note.
+ * Show the sidebar.
*
* This wraps the internal method, including a ping to telemetry.
*
- * @param {string} commandID ID of the xul:broadcaster element to use.
+ * @param {string} commandID ID of the sidebar to use.
* @param {DOMNode} [triggerNode] Node, usually a button, that triggered the
* showing of the sidebar.
*/
show(commandID, triggerNode) {
- return this._show(commandID).then((sidebarBroadcaster) => {
- this._loadSidebarExtension(sidebarBroadcaster);
+ return this._show(commandID).then(() => {
+ this._loadSidebarExtension(commandID);
if (triggerNode) {
updateToggleControlLabel(triggerNode);
@@ -410,11 +407,11 @@ var SidebarUI = {
* This is intended to be used when the sidebar is opened automatically
* when a window opens (not triggered by user interaction).
*
- * @param {string} commandID ID of the xul:broadcaster element to use.
+ * @param {string} commandID ID of the sidebar.
*/
showInitially(commandID) {
- return this._show(commandID).then((sidebarBroadcaster) => {
- this._loadSidebarExtension(sidebarBroadcaster);
+ return this._show(commandID).then(() => {
+ this._loadSidebarExtension(commandID);
});
},
@@ -422,24 +419,11 @@ var SidebarUI = {
* Implementation for show. Also used internally for sidebars that are shown
* when a window is opened and we don't want to ping telemetry.
*
- * @param {string} commandID ID of the xul:broadcaster element to use.
+ * @param {string} commandID ID of the sidebar.
*/
_show(commandID) {
- return new Promise((resolve, reject) => {
- let sidebarBroadcaster = this.getBroadcasterById(commandID);
- if (!sidebarBroadcaster) {
- reject(new Error("Invalid sidebar broadcaster specified: " + commandID));
- return;
- }
-
- let broadcasters = document.querySelectorAll("broadcaster[group=sidebar]");
- for (let broadcaster of broadcasters) {
- if (broadcaster != sidebarBroadcaster) {
- broadcaster.removeAttribute("checked");
- } else {
- sidebarBroadcaster.setAttribute("checked", "true");
- }
- }
+ return new Promise(resolve => {
+ this.selectMenuItem(commandID);
this._box.hidden = this._splitter.hidden = false;
this.setPosition();
@@ -447,8 +431,8 @@ var SidebarUI = {
this.hideSwitcherPanel();
this._box.setAttribute("checked", "true");
- this._box.setAttribute("sidebarcommand", sidebarBroadcaster.id);
- this.lastOpenedId = sidebarBroadcaster.id;
+ this._box.setAttribute("sidebarcommand", commandID);
+ this.lastOpenedId = commandID;
let {url, title} = this.sidebars.get(commandID);
this.title = title;
@@ -459,14 +443,14 @@ var SidebarUI = {
// We're handling the 'load' event before it bubbles up to the usual
// (non-capturing) event handlers. Let it bubble up before resolving.
setTimeout(() => {
- resolve(sidebarBroadcaster);
+ resolve();
// Now that the currentId is updated, fire a show event.
this._fireShowEvent();
}, 0);
}, {capture: true, once: true});
} else {
- resolve(sidebarBroadcaster);
+ resolve();
// Now that the currentId is updated, fire a show event.
this._fireShowEvent();
@@ -493,11 +477,7 @@ var SidebarUI = {
this.hideSwitcherPanel();
let commandID = this._box.getAttribute("sidebarcommand");
- let sidebarBroadcaster = document.getElementById(commandID);
-
- if (sidebarBroadcaster.getAttribute("checked") != "true") {
- return;
- }
+ this.selectMenuItem("");
// Replace the document currently displayed in the sidebar with about:blank
// so that we can free memory by unloading the page. We need to explicitly
@@ -507,7 +487,6 @@ var SidebarUI = {
this.browser.setAttribute("src", "about:blank");
this.browser.docShell.createAboutBlankContentViewer(null);
- sidebarBroadcaster.removeAttribute("checked");
this._box.removeAttribute("checked");
this._box.hidden = this._splitter.hidden = true;
@@ -520,6 +499,24 @@ var SidebarUI = {
updateToggleControlLabel(triggerNode);
}
},
+
+ /**
+ * Sets the checked state only on the menu items of the specified sidebar, or
+ * none if the argument is an empty string.
+ */
+ selectMenuItem(commandID) {
+ for (let [id, {menuId, buttonId}] of this.sidebars) {
+ let menu = document.getElementById(menuId);
+ let button = document.getElementById(buttonId);
+ if (id == commandID) {
+ menu.setAttribute("checked", "true");
+ button.setAttribute("checked", "true");
+ } else {
+ menu.removeAttribute("checked");
+ button.removeAttribute("checked");
+ }
+ }
+ },
};
// Add getters related to the position here, since we will want them
diff --git a/browser/base/content/browser.xul b/browser/base/content/browser.xul
index 7b8824b04eef..602d2f32deca 100644
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -321,28 +321,22 @@ xmlns="http://www.w3.org/1999/xhtml"
orient="vertical"
position="bottomcenter topleft">
+ oncommand="SidebarUI.show('viewBookmarksSidebar');"/>
+ oncommand="SidebarUI.show('viewHistorySidebar');"/>
+ oncommand="SidebarUI.show('viewTabsSidebar');"/>
diff --git a/browser/base/content/test/sidebar/browser.ini b/browser/base/content/test/sidebar/browser.ini
index e2d312835263..3e076fadd4ef 100644
--- a/browser/base/content/test/sidebar/browser.ini
+++ b/browser/base/content/test/sidebar/browser.ini
@@ -1,5 +1,6 @@
[DEFAULT]
[browser_sidebar_adopt.js]
+[browser_sidebar_keys.js]
[browser_sidebar_move.js]
[browser_sidebar_switcher.js]
diff --git a/browser/base/content/test/sidebar/browser_sidebar_keys.js b/browser/base/content/test/sidebar/browser_sidebar_keys.js
new file mode 100644
index 000000000000..c40672c98ca0
--- /dev/null
+++ b/browser/base/content/test/sidebar/browser_sidebar_keys.js
@@ -0,0 +1,24 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+async function testSidebarKeyToggle(key, options, expectedSidebarId) {
+ let promiseShown = BrowserTestUtils.waitForEvent(window, "SidebarShown");
+ EventUtils.synthesizeKey(key, options);
+ await promiseShown;
+ Assert.equal(document.getElementById("sidebar-box")
+ .getAttribute("sidebarcommand"), expectedSidebarId);
+ EventUtils.synthesizeKey(key, options);
+ Assert.ok(!SidebarUI.isOpen);
+}
+
+add_task(async function test_sidebar_keys() {
+ registerCleanupFunction(() => SidebarUI.hide());
+
+ await testSidebarKeyToggle("b", { accelKey: true }, "viewBookmarksSidebar");
+ if (AppConstants.platform == "win") {
+ await testSidebarKeyToggle("i", { accelKey: true }, "viewBookmarksSidebar");
+ }
+
+ let options = { accelKey: true, shiftKey: AppConstants.platform == "macosx" };
+ await testSidebarKeyToggle("h", options, "viewHistorySidebar");
+});
diff --git a/browser/components/customizableui/content/panelUI.inc.xul b/browser/components/customizableui/content/panelUI.inc.xul
index 0265cb3ba298..670e22da9f85 100644
--- a/browser/components/customizableui/content/panelUI.inc.xul
+++ b/browser/components/customizableui/content/panelUI.inc.xul
@@ -378,9 +378,7 @@
type="checkbox"
class="subviewbutton subviewbutton-iconic"
key="key_gotoHistory"
- oncommand="SidebarUI.toggle('viewHistorySidebar'); PanelUI.hide();">
-
-
+ oncommand="SidebarUI.toggle('viewHistorySidebar');"/>