Bug 1312244 - Autocomplete popup does not close when anchor clicked a second time. r?Enn draft
authorMike Conley <mconley@mozilla.com>
Mon, 24 Oct 2016 11:32:10 -0400
changeset 428741 aec15addce71c2d503179943552d5de910534fe6
parent 427560 3f0aeafe59c40c5e92ba9636fa718cf26088e127
child 534827 48a36a67707b5457f4a142676cb8df003393c37f
push id33409
push usermconley@mozilla.com
push dateMon, 24 Oct 2016 15:42:20 +0000
bugs1312244, 1183037
Bug 1312244 - Autocomplete popup does not close when anchor clicked a second time. r?Enn The popuphiding / popuphidden events are fired synchronously when the popup manager decides we're doing a "rollup" (closing the popups due to "outside" events). In the case of this bug, the "outside" event is a click on the input element in content. Here's the kicker though: we handle that popuphidden event and queue a message to content _before_ the mouse event that caused the roll-up is dispatched to content. This means that browser-content.js hears that the popup closed due to popuphidden first, sets its internal state of popupClosed to true, and then the MouseDown on the input field is processed. The nsFormFillController then queries browser-content's AutoCompletePopup, sees its closed, and tells the parent to open it again. This patch adds the norolluponanchor attribute to the panel, which causes us to ignore the rollup event if it happens to be targeted within the anchor rect. This means that we need to trust content to tell us to close the autocomplete popup if the input is clicked when the popup is open (and this is what bug 1183037, which this bug depends on, does). MozReview-Commit-ID: 4A9qVfTYIUz
--- a/toolkit/components/satchel/AutoCompletePopup.jsm
+++ b/toolkit/components/satchel/AutoCompletePopup.jsm
@@ -164,16 +164,28 @@ this.AutoCompletePopup = {
     this.openedPopup.view = AutoCompleteResultView;
     this.openedPopup.selectedIndex = -1;
     if (results.length) {
       // Reset fields that were set from the last time the search popup was open
       this.openedPopup.mInput = AutoCompleteResultView;
       this.openedPopup.showCommentColumn = false;
       this.openedPopup.showImageColumn = false;
+      // norolluponanchor is so that if the user clicks within the rect
+      // that is the "anchor" for this popup, we don't hide the popup.
+      // This is because the mouse event that causes the popup to close will
+      // be dispatched to content _after_ the popup closes, which means
+      // that content will think that the popup is closed by the time
+      // that it processes that mouse event. That's normally fine, but if that
+      // mouse event occurs on the anchor, it will think that the popup is
+      // closed and might attempt to open the popup again.
+      //
+      // So if the user clicks on the anchor, the parent ignores the rollup, and
+      // we trust content to tell us to close the popup instead.
+      this.openedPopup.setAttribute("norolluponanchor", true);
       this.openedPopup.addEventListener("popuphidden", this);
       this.openedPopup.addEventListener("popupshowing", this);
       this.openedPopup.openPopupAtScreenRect("after_start", rect.left, rect.top,
                                              rect.width, rect.height, false,
     } else {