Bug 1166365 - Pluralize dropdown logic. r=Gijs,Margaret
authorEitan Isaacson <eitan@monotonous.org>
Thu, 21 Jan 2016 11:25:48 -0800
changeset 323321 51459032ccce51c73fe3b44243ebfef874213065
parent 323317 b6acf4d4fc20431a8ae14bf32cdc6e43a9c0f9ad
child 323322 e3447f8edd06bc0f13e2e201357151e5b92a02a5
push id5913
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 16:57:49 +0000
treeherdermozilla-beta@dcaf0a6fa115 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersGijs, Margaret
bugs1166365
milestone47.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1166365 - Pluralize dropdown logic. r=Gijs,Margaret MozReview-Commit-ID: KCayCX4r8xQ
toolkit/components/reader/AboutReader.jsm
toolkit/themes/shared/aboutReaderControls.css
--- a/toolkit/components/reader/AboutReader.jsm
+++ b/toolkit/components/reader/AboutReader.jsm
@@ -163,17 +163,17 @@ AboutReader.prototype = {
     return _viewId;
   },
 
   receiveMessage: function (message) {
     switch (message.name) {
       // Triggered by Android user pressing BACK while the banner font-dropdown is open.
       case "Reader:CloseDropdown": {
         // Just close it.
-        this._closeDropdown();
+        this._closeDropdowns();
         break;
       }
 
       case "Reader:AddButton": {
         if (message.data.id && message.data.image &&
             !this._doc.getElementById(message.data.id)) {
           let btn = this._doc.createElement("button");
           btn.setAttribute("class", "button");
@@ -204,42 +204,50 @@ AboutReader.prototype = {
 
   handleEvent: function(aEvent) {
     if (!aEvent.isTrusted)
       return;
 
     switch (aEvent.type) {
       case "click":
         let target = aEvent.target;
-        while (target && target.id != "reader-popup")
-          target = target.parentNode;
-        if (!target)
-          this._closeDropdown();
+        if (target.classList.contains('dropdown-toggle')) {
+          this._toggleDropdownClicked(aEvent);
+        } else if (!target.closest('.dropdown-popup')) {
+          this._closeDropdowns();
+        }
         break;
       case "scroll":
-        this._closeDropdown();
+        this._closeDropdowns();
         let isScrollingUp = this._scrollOffset > aEvent.pageY;
         this._setSystemUIVisibility(isScrollingUp);
         this._scrollOffset = aEvent.pageY;
         break;
       case "resize":
         this._updateImageMargins();
+        if (this._isToolbarVertical) {
+          this._win.setTimeout(() => {
+            for (let dropdown of this._doc.querySelectorAll('.dropdown.open')) {
+              this._updatePopupPosition(dropdown);
+            }
+          }, 0);
+        }
         break;
 
       case "devicelight":
         this._handleDeviceLight(aEvent.value);
         break;
 
       case "visibilitychange":
         this._handleVisibilityChange();
         break;
 
       case "unload":
         // Close the Banners Font-dropdown, cleanup Android BackPressListener.
-        this._closeDropdown();
+        this._closeDropdowns();
 
         this._mm.removeMessageListener("Reader:CloseDropdown", this);
         this._mm.removeMessageListener("Reader:AddButton", this);
         this._mm.removeMessageListener("Reader:RemoveButton", this);
         this._windowUnloaded = true;
         break;
     }
   },
@@ -713,80 +721,71 @@ AboutReader.prototype = {
    * @param   Localizable string providing UI element usage tip.
    */
   _setButtonTip: function(id, titleEntity) {
     let button = this._doc.getElementById(id);
     button.setAttribute("title", gStrings.GetStringFromName(titleEntity));
   },
 
   _setupStyleDropdown: function() {
-    let doc = this._doc;
-    let win = this._win;
+    let dropdownToggle = this._doc.querySelector("#style-dropdown .dropdown-toggle");
+    dropdownToggle.setAttribute("title", gStrings.GetStringFromName("aboutReader.toolbar.typeControls"));
+  },
 
-    let dropdown = doc.getElementById("style-dropdown");
+  _updatePopupPosition: function(dropdown) {
     let dropdownToggle = dropdown.querySelector(".dropdown-toggle");
     let dropdownPopup = dropdown.querySelector(".dropdown-popup");
 
-    // Helper function used to position the popup on desktop,
-    // where there is a vertical toolbar.
-    function updatePopupPosition() {
-      let toggleHeight = dropdownToggle.offsetHeight;
-      let toggleTop = dropdownToggle.offsetTop;
-      let popupTop = toggleTop - toggleHeight / 2;
-      dropdownPopup.style.top = popupTop + "px";
-    }
+    let toggleHeight = dropdownToggle.offsetHeight;
+    let toggleTop = dropdownToggle.offsetTop;
+    let popupTop = toggleTop - toggleHeight / 2;
+
+    dropdownPopup.style.top = popupTop + "px";
+  },
+
+  _toggleDropdownClicked: function(event) {
+    let dropdown = event.target.closest('.dropdown');
 
-    if (this._isToolbarVertical) {
-      win.addEventListener("resize", event => {
-        if (!event.isTrusted)
-          return;
+    if (!dropdown)
+      return;
+
+    event.stopPropagation();
 
-        // Wait for reflow before calculating the new position of the popup.
-        win.setTimeout(updatePopupPosition, 0);
-      }, true);
+    if (dropdown.classList.contains("open")) {
+      this._closeDropdowns();
+    } else {
+      this._openDropdown(dropdown);
+      if (this._isToolbarVertical) {
+        this._updatePopupPosition(dropdown);
+      }
     }
-
-    dropdownToggle.setAttribute("title", gStrings.GetStringFromName("aboutReader.toolbar.typeControls"));
-    dropdownToggle.addEventListener("click", event => {
-      if (!event.isTrusted)
-        return;
-
-      event.stopPropagation();
-
-      if (dropdown.classList.contains("open")) {
-        this._closeDropdown();
-      } else {
-        this._openDropdown();
-        if (this._isToolbarVertical) {
-          updatePopupPosition();
-        }
-      }
-    }, true);
   },
 
   /*
    * If the ReaderView banner font-dropdown is closed, open it.
    */
-  _openDropdown: function() {
-    let dropdown = this._doc.getElementById("style-dropdown");
+  _openDropdown: function(dropdown) {
     if (dropdown.classList.contains("open")) {
       return;
     }
 
+    this._closeDropdowns();
+
     // Trigger BackPressListener initialization in Android.
     dropdown.classList.add("open");
     this._mm.sendAsyncMessage("Reader:DropdownOpened", this.viewId);
   },
 
   /*
-   * If the ReaderView banner font-dropdown is opened, close it.
+   * If the ReaderView has open dropdowns, close them.
    */
-  _closeDropdown: function() {
-    let dropdown = this._doc.getElementById("style-dropdown");
-    if (!dropdown.classList.contains("open")) {
-      return;
+  _closeDropdowns: function() {
+    let openDropdowns = this._doc.querySelectorAll(".dropdown.open:not(.keep-open)");
+    for (let dropdown of openDropdowns) {
+      dropdown.classList.remove("open");
     }
 
     // Trigger BackPressListener cleanup in Android.
-    dropdown.classList.remove("open");
-    this._mm.sendAsyncMessage("Reader:DropdownClosed", this.viewId);
-  },
+    if (openDropdowns.length) {
+      this._mm.sendAsyncMessage("Reader:DropdownClosed", this.viewId);
+    }
+  }
 };
--- a/toolkit/themes/shared/aboutReaderControls.css
+++ b/toolkit/themes/shared/aboutReaderControls.css
@@ -115,32 +115,36 @@
   padding: 0;
 }
 
 .dropdown li {
   margin: 0;
   padding: 0;
 }
 
-/*======= Font style popup =======*/
+/*======= Popup =======*/
 
 .dropdown-popup {
   min-width: 300px;
   text-align: start;
   position: absolute;
   left: 48px; /* offset to account for toolbar width */
   z-index: 1000;
   background-color: #fbfbfb;
   visibility: hidden;
   border-radius: 4px;
   border: 1px solid #b5b5b5;
   border-bottom-width: 0;
   box-shadow: 0 1px 12px #666;
 }
 
+.keep-open .dropdown-popup {
+  z-index: initial;
+}
+
 .dropdown-popup > hr {
   display: none;
 }
 
 .open > .dropdown-popup {
   visibility: visible;
 }
 
@@ -149,16 +153,18 @@
   top: 30px; /* offset arrow from top of popup */
   left: -16px;
   width: 24px;
   height: 24px;
   background-image: url("chrome://global/skin/reader/RM-Type-Controls-Arrow.svg");
   display: block;
 }
 
+/*======= Font style popup =======*/
+
 #font-type-buttons,
 #font-size-buttons,
 #color-scheme-buttons {
   display: flex;
   flex-direction: row;
 }
 
 #font-type-buttons > button:first-child {