Bug 1395871 - Open customWidget menus on mousedown, rather than oncommand.
MozReview-Commit-ID: 2K4uYSu7Nai
--- a/browser/components/customizableui/CustomizableUI.jsm
+++ b/browser/components/customizableui/CustomizableUI.jsm
@@ -1218,16 +1218,17 @@ var CustomizableUIInternal = {
this.notifyListeners("onWidgetBeforeDOMChange", aNode, aNextNode, aContainer);
this.setLocationAttributes(aNode, aArea);
aContainer.insertBefore(aNode, aNextNode);
this.notifyListeners("onWidgetAfterDOMChange", aNode, aNextNode, aContainer);
},
handleEvent(aEvent) {
switch (aEvent.type) {
+ case "mousedown":
case "command":
if (!this._originalEventInPanel(aEvent)) {
break;
}
aEvent = aEvent.sourceEvent;
// Fall through
case "click":
case "keypress":
@@ -1400,17 +1401,21 @@ var CustomizableUIInternal = {
let tooltip = this.getLocalizedProperty(aWidget, "tooltiptext", additionalTooltipArguments);
if (tooltip) {
node.setAttribute("tooltiptext", tooltip);
}
node.setAttribute("class", "toolbarbutton-1 chromeclass-toolbar-additional");
let commandHandler = this.handleWidgetCommand.bind(this, aWidget, node);
- node.addEventListener("command", commandHandler);
+ if (aWidget.type === "view") {
+ node.addEventListener("mousedown", commandHandler);
+ } else {
+ node.addEventListener("command", commandHandler);
+ }
let clickHandler = this.handleWidgetClick.bind(this, aWidget, node);
node.addEventListener("click", clickHandler);
// If the widget has a view, and has view showing / hiding listeners,
// hook those up to this widget.
if (aWidget.type == "view") {
log.debug("Widget " + aWidget.id + " has a view. Auto-registering event handlers.");
let viewNode = aDocument.getElementById(aWidget.viewId);
@@ -1716,17 +1721,17 @@ var CustomizableUIInternal = {
if (aEvent.keyCode != aEvent.DOM_VK_RETURN) {
return;
}
// If the user hit enter/return, we don't check preventDefault - it makes sense
// that this was prevented, but we probably still want to close the panel.
// If consumers don't want this to happen, they should specify the closemenu
// attribute.
- } else if (aEvent.type != "command") { // mouse events:
+ } else if (aEvent.type != "command" || aEvent.type != "mousedown") { // mouse events:
if (aEvent.defaultPrevented || aEvent.button != 0) {
return;
}
let isInteractive = this._isOnInteractiveElement(aEvent);
log.debug("maybeAutoHidePanel: interactive ? " + isInteractive);
if (isInteractive) {
return;
}
--- a/browser/components/extensions/ext-browserAction.js
+++ b/browser/components/extensions/ext-browserAction.js
@@ -168,17 +168,16 @@ this.browserAction = class extends Exten
}
},
onCreated: node => {
node.classList.add("badged-button");
node.classList.add("webextension-browser-action");
node.setAttribute("constrain-size", "true");
- node.onmousedown = event => this.handleEvent(event);
node.onmouseover = event => this.handleEvent(event);
node.onmouseout = event => this.handleEvent(event);
this.updateButton(node, this.defaults, true);
},
onViewShowing: async event => {
TelemetryStopwatch.start(POPUP_OPEN_MS_HISTOGRAM, this);
@@ -259,54 +258,30 @@ this.browserAction = class extends Exten
// Popups are shown only if a popup URL is defined; otherwise
// a "click" event is dispatched. This is done for compatibility with the
// Google Chrome onClicked extension API.
if (this.getProperty(tab, "popup")) {
if (this.widget.areaType == CustomizableUI.TYPE_MENU_PANEL) {
await window.document.getElementById("nav-bar").overflowable.show();
}
- let event = new window.CustomEvent("command", {bubbles: true, cancelable: true});
+ const activationEvent = widget.type ? "mousedown" : "command";
+ let event = new window.CustomEvent(activationEvent, {bubbles: true, cancelable: true});
widget.node.dispatchEvent(event);
} else {
this.tabManager.addActiveTabPermission(tab);
this.emit("click");
}
}
handleEvent(event) {
let button = event.target;
let window = button.ownerGlobal;
switch (event.type) {
- case "mousedown":
- if (event.button == 0) {
- // Begin pre-loading the browser for the popup, so it's more likely to
- // be ready by the time we get a complete click.
- let tab = window.gBrowser.selectedTab;
- let popupURL = this.getProperty(tab, "popup");
- let enabled = this.getProperty(tab, "enabled");
-
- if (popupURL && enabled && (this.pendingPopup || !ViewPopup.for(this.extension, window))) {
- this.eventQueue.push("Mousedown");
- // Add permission for the active tab so it will exist for the popup.
- // Store the tab to revoke the permission during clearPopup.
- if (!this.tabManager.hasActiveTabPermission(tab)) {
- this.tabManager.addActiveTabPermission(tab);
- this.tabToRevokeDuringClearPopup = tab;
- }
-
- this.pendingPopup = this.getPopup(window, popupURL);
- window.addEventListener("mouseup", this, true);
- } else {
- this.clearPopup();
- }
- }
- break;
-
case "mouseup":
if (event.button == 0) {
this.clearPopupTimeout();
// If we have a pending pre-loaded popup, cancel it after we've waited
// long enough that we can be relatively certain it won't be opening.
if (this.pendingPopup) {
let node = window.gBrowser && this.widget.forWindow(window).node;
if (isAncestorOrSelf(node, event.originalTarget)) {