Bug 1327155 - Can't open urlbar Blocked Popups menu with a single click if it's already open from the notification bar. r=Felipe a=gchang
authorMarco Bonardo <mbonardo@mozilla.com>
Fri, 27 Jan 2017 01:11:09 +0100
changeset 378170 8c15bbe4488de496caa453426882214f4d703ba5
parent 378169 ed726703c08c7a0398d349efaded8bdea25c46ff
child 378171 a2ed1e8da84e31071c331412f352a42e6586fca2
push id1419
push userjlund@mozilla.com
push dateMon, 10 Apr 2017 20:44:07 +0000
treeherdermozilla-release@5e6801b73ef6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersFelipe, gchang
bugs1327155
milestone53.0a2
Bug 1327155 - Can't open urlbar Blocked Popups menu with a single click if it's already open from the notification bar. r=Felipe a=gchang 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;
     }
   },