Bug 1374048 - Show the sidebar extension icon in the header. r=Gijs, ui-r=shorlander.
MozReview-Commit-ID: 3FLYauvCs8E
--- a/browser/base/content/browser-sidebar.js
+++ b/browser/base/content/browser-sidebar.js
@@ -225,16 +225,25 @@ var SidebarUI = {
// Remove the |sidebarcommand| attribute, because the element it
// refers to no longer exists, so we should assume this sidebar
// panel has been uninstalled. (249883)
this._box.removeAttribute("sidebarcommand");
}
},
/**
+ * Fire a "SidebarShown" event on the sidebar to give any interested parties
+ * a chance to update the button or whatever.
+ */
+ _fireShowEvent() {
+ let event = new CustomEvent("SidebarShown", {bubbles: true});
+ this._switcherTarget.dispatchEvent(event);
+ },
+
+ /**
* Fire a "SidebarFocused" event on the sidebar's |window| to give the sidebar
* a chance to adjust focus as needed. An additional event is needed, because
* we don't want to focus the sidebar when it's opened on startup or in a new
* window, only when the user opens the sidebar.
*/
_fireFocusedEvent() {
let event = new CustomEvent("SidebarFocused", {bubbles: true});
this.browser.contentWindow.dispatchEvent(event);
@@ -367,21 +376,27 @@ var SidebarUI = {
// (non-capturing) event handlers. Let it bubble up before firing the
// SidebarFocused event.
setTimeout(() => this._fireFocusedEvent(), 0);
// Run the original function for backwards compatibility.
sidebarOnLoad(event);
resolve();
+
+ // Now that the currentId is updated, fire a show event.
+ this._fireShowEvent();
}, {capture: true, once: true});
} else {
// Older code handled this case, so we do it too.
this._fireFocusedEvent();
resolve();
+
+ // Now that the currentId is updated, fire a show event.
+ this._fireShowEvent();
}
let selBrowser = gBrowser.selectedBrowser;
selBrowser.messageManager.sendAsyncMessage("Sidebar:VisibilityChange",
{commandID, isOpen: true}
);
});
},
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -1382,9 +1382,24 @@ toolbarpaletteitem[place="palette"][hidd
}
/* Page action panel */
#pageAction-panel-sendToDevice-subview-body:not([state="notready"]) > #pageAction-panel-sendToDevice-notReady,
#pageAction-urlbar-sendToDevice-subview-body:not([state="notready"]) > #pageAction-urlbar-sendToDevice-notReady {
display: none;
}
+/* WebExtension Sidebars */
+#sidebar-box[sidebarcommand$="-sidebar-action"] > #sidebar-header > #sidebar-switcher-target > #sidebar-icon {
+ list-style-image: var(--webextension-menuitem-image, inherit);
+ -moz-context-properties: fill;
+ fill: currentColor;
+ width: 16px;
+ height: 16px;
+}
+
+@media (min-resolution: 1.1dppx) {
+ #sidebar-box[sidebarcommand$="-sidebar-action"] > #sidebar-header > #sidebar-switcher-target > #sidebar-icon {
+ list-style-image: var(--webextension-menuitem-image-2x, inherit);
+ }
+}
+
%include theme-vars.inc.css
--- a/browser/components/extensions/ext-sidebarAction.js
+++ b/browser/components/extensions/ext-sidebarAction.js
@@ -65,16 +65,33 @@ this.sidebarAction = class extends Exten
extension);
// We need to ensure our elements are available before session restore.
this.windowOpenListener = (window) => {
this.createMenuItem(window, this.defaults);
};
windowTracker.addOpenListener(this.windowOpenListener);
+ this.updateHeader = (event) => {
+ let window = event.target.ownerGlobal;
+ let details = this.tabContext.get(window.gBrowser.selectedTab);
+ let header = window.document.getElementById("sidebar-switcher-target");
+ if (window.SidebarUI.currentID === this.id) {
+ this.setMenuIcon(header, details);
+ }
+ };
+
+ this.windowCloseListener = (window) => {
+ let header = window.document.getElementById("sidebar-switcher-target");
+ if (header) {
+ header.removeEventListener("SidebarShown", this.updateHeader);
+ }
+ };
+ windowTracker.addCloseListener(this.windowCloseListener);
+
sidebarActionMap.set(extension, this);
}
onReady() {
this.build();
}
onShutdown(reason) {
@@ -100,18 +117,21 @@ this.sidebarAction = class extends Exten
let button = document.getElementById(this.buttonId);
if (button) {
button.remove();
}
let broadcaster = document.getElementById(this.id);
if (broadcaster) {
broadcaster.remove();
}
+ let header = document.getElementById("sidebar-switcher-target");
+ header.removeEventListener("SidebarShown", this.updateHeader);
}
windowTracker.removeOpenListener(this.windowOpenListener);
+ windowTracker.removeCloseListener(this.windowCloseListener);
}
build() {
this.tabContext.on("tab-select", // eslint-disable-line mozilla/balanced-listeners
(evt, tab) => { this.updateWindow(tab.ownerGlobal); });
let install = this.extension.startupReason === "ADDON_INSTALL";
let upgrade = ["ADDON_UPGRADE", "ADDON_DOWNGRADE"].includes(this.extension.startupReason);
@@ -160,16 +180,19 @@ this.sidebarAction = class extends Exten
broadcaster.setAttribute("group", "sidebar");
broadcaster.setAttribute("label", details.title);
broadcaster.setAttribute("sidebarurl", this.sidebarUrl(details.panel));
// oncommand gets attached to menuitem, so we use the observes attribute to
// get the command id we pass to SidebarUI.
broadcaster.setAttribute("oncommand", "SidebarUI.show(this.getAttribute('observes'))");
+ let header = document.getElementById("sidebar-switcher-target");
+ header.addEventListener("SidebarShown", this.updateHeader);
+
// Insert a menuitem for View->Show Sidebars.
let menuitem = document.createElementNS(XUL_NS, "menuitem");
menuitem.setAttribute("id", this.menuId);
menuitem.setAttribute("observes", this.id);
menuitem.setAttribute("class", "menuitem-iconic webextension-menuitem");
this.setMenuIcon(menuitem, details);
// Insert a toolbarbutton for the sidebar dropdown selector.
@@ -227,16 +250,18 @@ this.sidebarAction = class extends Exten
this.setMenuIcon(menu, tabData);
let button = document.getElementById(this.buttonId);
this.setMenuIcon(button, tabData);
// Update the sidebar if this extension is the current sidebar.
if (SidebarUI.currentID === this.id) {
SidebarUI.title = title;
+ let header = document.getElementById("sidebar-switcher-target");
+ this.setMenuIcon(header, tabData);
if (SidebarUI.isOpen && urlChanged) {
SidebarUI.show(this.id);
}
}
}
/**
* Update the broadcaster and menuitem for a given window.