Bug 1327155 - Can't open urlbar Blocked Popups menu with a single click if it's already open from the notification bar. r=felipe draft
authorMarco Bonardo <mbonardo@mozilla.com>
Fri, 27 Jan 2017 01:11:09 +0100
changeset 467188 a869c7c37a3d9f066373420b6fc263bca732ce4d
parent 464990 5a4412474c63e1d9e66036d603ac42e9cb2b9150
child 543630 93ce1d2ba824351c6dda311f17cb3ce797ca2384
push id43116
push usermak77@bonardo.net
push dateFri, 27 Jan 2017 08:58:51 +0000
reviewersfelipe
bugs1327155
milestone54.0a1
Bug 1327155 - Can't open urlbar Blocked Popups menu with a single click if it's already open from the notification bar. r=felipe MozReview-Commit-ID: Lo4fz9kVeEG
browser/base/content/browser.js
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -453,23 +453,33 @@ function findChildShell(aDocument, aDocS
   }
   return null;
 }
 
 var gPopupBlockerObserver = {
   _reportButton: null,
 
   onReportButtonMousedown(aEvent) {
-    // If this method is called on the same event tick as the popup gets
-    // hidden, do nothing to avoid re-opening the popup.
+    // The button is part of the textbox that is considered the popup's anchor,
+    // thus consumeoutsideclicks="false" is ignored. Moreover On OS X the popup
+    // is hidden well before mousedown gets dispatched.
+    // Thus, if the popup is open and the user clicks on the button, it gets
+    // hidden before mousedown, and may then be unexpectedly reopened by click.
+    // To avoid this, we check if mousedown is in the same tick as popupHidden,
+    // and, in such a case, we don't handle the click event.
+    // Note we can't just openPopup in mousedown, cause this popup is shared by
+    // multiple anchors, and we could end up opening it just before the other
+    // anchor tries to hide it.
     if (aEvent.button != 0 || aEvent.target != this._reportButton || this.isPopupHidingTick)
       return;
 
-    document.getElementById("blockedPopupOptions")
-            .openPopup(this._reportButton, "after_end", 0, 2, false, false, aEvent);
+    this._reportButton.addEventListener("click", event => {
+      document.getElementById("blockedPopupOptions")
+              .openPopup(event.target, "after_end", 0, 2, false, false, event);
+    }, { once: true });
   },
 
   handleEvent(aEvent) {
     if (aEvent.originalTarget != gBrowser.selectedBrowser)
       return;
 
     if (!this._reportButton)
       this._reportButton = document.getElementById("page-report-button");
@@ -644,21 +654,22 @@ var gPopupBlockerObserver = {
       // Show the separator if we added any
       // showable popup addresses to the menu.
       if (foundUsablePopupURI)
         blockedPopupsSeparator.removeAttribute("hidden");
     }, null);
   },
 
   onPopupHiding(aEvent) {
-    if (aEvent.target.anchorNode.id == "page-report-button")
+    if (aEvent.target.anchorNode.id == "page-report-button") {
       aEvent.target.anchorNode.removeAttribute("open");
 
-    this.isPopupHidingTick = true;
-    setTimeout(() => this.isPopupHidingTick = false, 0);
+      this.isPopupHidingTick = true;
+      setTimeout(() => this.isPopupHidingTick = false, 0);
+    }
 
     let item = aEvent.target.lastChild;
     while (item && item.getAttribute("observes") != "blockedPopupsSeparator") {
       let next = item.previousSibling;
       item.parentNode.removeChild(item);
       item = next;
     }
   },