Bug 1384953 - Run the library and pocket animations outside of the navigation-toolbar to workaround z-index issues with the selected tab. r?gijs draft
authorJared Wein <jwein@mozilla.com>
Wed, 09 Aug 2017 20:36:17 -0400
changeset 652381 e913de42023468d213ab160a048721ddf8919638
parent 652380 0df56be60d07b4da1b7a387b3d69aac133df928a
child 728073 f10885e42faed01126e403014bfb8a999f4e3c7f
push id76039
push userbmo:jaws@mozilla.com
push dateThu, 24 Aug 2017 18:50:02 +0000
reviewersgijs
bugs1384953
milestone57.0a1
Bug 1384953 - Run the library and pocket animations outside of the navigation-toolbar to workaround z-index issues with the selected tab. r?gijs MozReview-Commit-ID: dXVThUXdXi
browser/base/content/browser-places.js
browser/base/content/browser.xul
browser/extensions/pocket/bootstrap.js
browser/extensions/pocket/skin/shared/pocket.css
browser/themes/shared/browser.inc.css
browser/themes/shared/compacttheme.inc.css
browser/themes/shared/toolbarbutton-icons.inc.css
--- a/browser/base/content/browser-places.js
+++ b/browser/base/content/browser-places.js
@@ -74,23 +74,27 @@ var StarUI = {
       elt.removeAttribute("wasDisabled");
     });
   },
 
   // nsIDOMEventListener
   handleEvent(aEvent) {
     switch (aEvent.type) {
       case "animationend": {
-        let libraryButton = document.getElementById("library-button");
+        let animatableBox = document.getElementById("library-animatable-box");
         if (aEvent.animationName.startsWith("library-bookmark-animation")) {
-          libraryButton.setAttribute("fade", "true");
+          animatableBox.setAttribute("fade", "true");
         } else if (aEvent.animationName == "library-bookmark-fade") {
-          libraryButton.removeEventListener("animationend", this);
+          animatableBox.removeEventListener("animationend", this);
+          animatableBox.removeAttribute("animate");
+          animatableBox.removeAttribute("fade");
+          let libraryButton = document.getElementById("library-button");
+          // Put the 'fill' back in the normal icon.
           libraryButton.removeAttribute("animate");
-          libraryButton.removeAttribute("fade");
+          gNavToolbox.removeAttribute("animate");
         }
         break;
       }
       case "mousemove":
         clearTimeout(this._autoCloseTimer);
         // The autoclose timer is not disabled on generic mouseout
         // because the user may not have actually interacted with the popup.
         break;
@@ -141,20 +145,36 @@ var StarUI = {
             PlacesTransactions.Remove(guidsForRemoval)
                               .transact().catch(Cu.reportError);
           } else if (this._isNewBookmark &&
                      Services.prefs.getBoolPref("toolkit.cosmeticAnimations.enabled") &&
                      (libraryButton = document.getElementById("library-button")) &&
                      libraryButton.getAttribute("cui-areatype") != "menu-panel" &&
                      libraryButton.getAttribute("overflowedItem") != "true" &&
                      libraryButton.closest("#nav-bar")) {
-            BrowserUtils.setToolbarButtonHeightProperty(libraryButton);
-            libraryButton.removeAttribute("fade");
+            let animatableBox = document.getElementById("library-animatable-box");
+            let navBar = document.getElementById("nav-bar");
+            let libraryIcon = document.getAnonymousElementByAttribute(libraryButton, "class", "toolbarbutton-icon");
+            let dwu = window.getInterface(Ci.nsIDOMWindowUtils);
+            let iconBounds = dwu.getBoundsWithoutFlushing(libraryIcon);
+            let libraryBounds = dwu.getBoundsWithoutFlushing(libraryButton);
+
+            animatableBox.style.setProperty("--library-button-y", libraryBounds.y + "px");
+            animatableBox.style.setProperty("--library-button-height", libraryBounds.height + "px");
+            animatableBox.style.setProperty("--library-icon-x", iconBounds.x + "px");
+            if (navBar.hasAttribute("brighttext")) {
+              animatableBox.setAttribute("brighttext", "true");
+            } else {
+              animatableBox.removeAttribute("brighttext");
+            }
+            animatableBox.removeAttribute("fade");
+            gNavToolbox.setAttribute("animate", "bookmark");
             libraryButton.setAttribute("animate", "bookmark");
-            libraryButton.addEventListener("animationend", this);
+            animatableBox.setAttribute("animate", "bookmark");
+            animatableBox.addEventListener("animationend", this);
           }
         }
         break;
       }
       case "keypress":
         clearTimeout(this._autoCloseTimer);
         this._autoCloseTimerEnabled = false;
 
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -919,21 +919,17 @@
                        tooltip="dynamic-shortcut-tooltip"/>
 
         <toolbarbutton id="library-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
                        removable="true"
                        oncommand="PanelUI.showSubView('appMenu-libraryView', this, null, event);"
                        closemenu="none"
                        cui-areatype="toolbar"
                        tooltiptext="&libraryButton.tooltip;"
-                       label="&places.library.title;">
-          <box class="toolbarbutton-animatable-box">
-            <image class="toolbarbutton-animatable-image"/>
-          </box>
-        </toolbarbutton>
+                       label="&places.library.title;"/>
 
       </hbox>
 
       <toolbarbutton id="nav-bar-overflow-button"
                      class="toolbarbutton-1 chromeclass-toolbar-additional overflow-button"
                      skipintoolbarset="true"
                      tooltiptext="&navbarOverflow.label;">
         <box class="toolbarbutton-animatable-box">
@@ -1147,16 +1143,19 @@
           <menuitem id="BMB_bookmarksShowAll"
                     class="subviewbutton panel-subview-footer"
                     label="&showAllBookmarks2.label;"
                     command="Browser:ShowAllBookmarks"
                     key="manBookmarkKb"/>
         </menupopup>
       </toolbarbutton>
     </toolbarpalette>
+    <box id="library-animatable-box" class="toolbarbutton-animatable-box">
+      <image class="toolbarbutton-animatable-image"/>
+    </box>
   </toolbox>
 
   <hbox id="fullscr-toggler" hidden="true"/>
 
   <deck id="content-deck" flex="1">
     <hbox flex="1" id="browser">
       <vbox id="browser-border-start" hidden="true" layer="true"/>
       <vbox id="sidebar-box" hidden="true" class="chromeclass-extrachrome">
--- a/browser/extensions/pocket/bootstrap.js
+++ b/browser/extensions/pocket/bootstrap.js
@@ -187,38 +187,60 @@ var PocketPageAction = {
       }
     }
 
     this.pageAction.remove();
     this.pageAction = null;
   },
 
   startLibraryAnimation(doc) {
-    var libraryButton = doc.getElementById("library-button");
+    let libraryButton = doc.getElementById("library-button");
     if (!Services.prefs.getBoolPref("toolkit.cosmeticAnimations.enabled") ||
         !libraryButton ||
         libraryButton.getAttribute("cui-areatype") == "menu-panel" ||
         libraryButton.getAttribute("overflowedItem") == "true" ||
         !libraryButton.closest("#nav-bar")) {
       return;
     }
-    libraryButton.removeAttribute("fade");
+
+    let animatableBox = doc.getElementById("library-animatable-box");
+    let navBar = doc.getElementById("nav-bar");
+    let libraryIcon = doc.getAnonymousElementByAttribute(libraryButton, "class", "toolbarbutton-icon");
+    let dwu = doc.defaultView.getInterface(Ci.nsIDOMWindowUtils);
+    let iconBounds = dwu.getBoundsWithoutFlushing(libraryIcon);
+    let libraryBounds = dwu.getBoundsWithoutFlushing(libraryButton);
+
+    animatableBox.style.setProperty("--library-button-y", libraryBounds.y + "px");
+    animatableBox.style.setProperty("--library-button-height", libraryBounds.height + "px");
+    animatableBox.style.setProperty("--library-icon-x", iconBounds.x + "px");
+    if (navBar.hasAttribute("brighttext")) {
+      animatableBox.setAttribute("brighttext", "true");
+    } else {
+      animatableBox.removeAttribute("brighttext");
+    }
+    animatableBox.removeAttribute("fade");
+    doc.defaultView.gNavToolbox.setAttribute("animate", "pocket");
     libraryButton.setAttribute("animate", "pocket");
-    libraryButton.addEventListener("animationend", PocketPageAction.onLibraryButtonAnimationEnd);
+    animatableBox.setAttribute("animate", "pocket");
+    animatableBox.addEventListener("animationend", PocketPageAction.onLibraryButtonAnimationEnd);
   },
 
   onLibraryButtonAnimationEnd(event) {
     let doc = event.target.ownerDocument;
     let libraryButton = doc.getElementById("library-button");
+    let animatableBox = doc.getElementById("library-animatable-box");
     if (event.animationName.startsWith("library-pocket-animation")) {
-      libraryButton.setAttribute("fade", "true");
+      animatableBox.setAttribute("fade", "true");
     } else if (event.animationName == "library-pocket-fade") {
-      libraryButton.removeEventListener("animationend", PocketPageAction.onLibraryButtonAnimationEnd);
+      animatableBox.removeEventListener("animationend", PocketPageAction.onLibraryButtonAnimationEnd);
+      // Put the 'fill' back in the normal icon.
       libraryButton.removeAttribute("animate");
-      libraryButton.removeAttribute("fade");
+      animatableBox.removeAttribute("animate");
+      animatableBox.removeAttribute("fade");
+      event.target.ownerGlobal.gNavToolbox.removeAttribute("animate");
     }
   },
 };
 
 // PocketContextMenu
 // When the context menu is opened check if we need to build and enable pocket UI.
 var PocketContextMenu = {
   init() {
--- a/browser/extensions/pocket/skin/shared/pocket.css
+++ b/browser/extensions/pocket/skin/shared/pocket.css
@@ -133,81 +133,73 @@
     fill: #ef4056;
   }
   to {
     transform: scaleX(-1) translateX(-1056px);
     fill: #ef4056;
   }
 }
 
-/* The animations for the pocket-button and library-button are disabled
-   outside of the nav-bar due to bug 1382894. */
-:-moz-any(#pocket-button, #library-button) > .toolbarbutton-animatable-box {
-  display: none;
-}
-#nav-bar :-moz-any(#pocket-button, #library-button) > .toolbarbutton-animatable-box {
-  display: -moz-box;
-}
-
 /* We need to use an animation here instead of a transition
    to guarantee that the animation succeeds. With transitions
    if the starting value is already equal to the end value
    then no transition will occur and thus no transitionend event. */
 @keyframes library-pocket-fade {
   from {
     fill: #ef4056;
   }
   to {
     fill: inherit;
   }
 }
 
-#library-button[animate="pocket"] {
-  position: relative;
-}
-
-#library-button[animate="pocket"] > .toolbarbutton-animatable-box {
+.toolbarbutton-animatable-box[animate="pocket"] {
   position: absolute;
   overflow: hidden;
-  top: calc(50% - 27px); /* 27px is half the height of the sprite */
+  /* Position the sprite at the y-position of the library-button, then adjust
+     based on the size difference between half of the button height and half
+     of the sprite height. */
+  top: calc(var(--library-button-y) + var(--library-button-height) / 2 - 27px);
   /* Since .toolbarbutton-icon uses a different width than the animatable box,
-     we need to set a padding relative to the difference in widths. */
-  margin-inline-start: calc((16px + 2 * var(--toolbarbutton-inner-padding) - 22px) / 2);
+     we need to set a margin relative to the difference in widths.
+     margin-left is used here even in RTL because the item is positioned using `left` */
+  left: calc(var(--library-icon-x) + (16px + 2 * var(--toolbarbutton-inner-padding) - 22px) / 2);
   /* Set the min- and max- width and height of the box equal to that
      of each frame of the SVG sprite. Setting the width and height via
      the `width` and `height` CSS properties causes an assertion for
      `inline-size less than zero: 'aContainingBlockISize >= 0'` (bug 1379332). */
   min-width: 22px;
   max-width: 22px;
   /* Height of each frame within the SVG sprite. The sprite must have equal amount
      of space above and below the icon to allow it to vertically center with the
      sprite's icon on top of the toolbar icon when using position:absolute;. */
   min-height: 54px;
   max-height: 54px;
+  z-index: 2;
 }
 
-#library-button[animate="pocket"] > .toolbarbutton-animatable-box > .toolbarbutton-animatable-image {
+.toolbarbutton-animatable-box[animate="pocket"] > .toolbarbutton-animatable-image {
   height: var(--toolbarbutton-height); /* Height must be equal to height of toolbarbutton padding-box */
   min-height: 54px; /* Minimum height must be equal to the height of the SVG sprite */
 }
 
-#library-button[animate="pocket"] > .toolbarbutton-animatable-box > .toolbarbutton-animatable-image {
+.toolbarbutton-animatable-box[animate="pocket"] > .toolbarbutton-animatable-image {
   background-image: url("chrome://pocket-shared/skin/library-pocket-animation.svg");
   width: 1078px;
   animation-name: library-pocket-animation;
   animation-duration: 800ms;
   animation-timing-function: steps(48);
 }
 
-#library-button[animate="pocket"]:-moz-locale-dir(rtl) > .toolbarbutton-animatable-box > .toolbarbutton-animatable-image {
+.toolbarbutton-animatable-box[animate="pocket"]:-moz-locale-dir(rtl) > .toolbarbutton-animatable-image {
   animation-name: library-pocket-animation-rtl;
   transform: scaleX(-1);
 }
 
-#library-button[animate="pocket"][fade] > .toolbarbutton-animatable-box > .toolbarbutton-animatable-image {
+.toolbarbutton-animatable-box[animate="pocket"][fade] > .toolbarbutton-animatable-image {
   animation-name: library-pocket-fade;
   animation-duration: 2s;
   animation-timing-function: ease-out;
 }
 
 #pocket-button[cui-areatype="toolbar"][open] {
   fill: #ef4056;
 }
--- a/browser/themes/shared/browser.inc.css
+++ b/browser/themes/shared/browser.inc.css
@@ -50,8 +50,22 @@
   outline-offset: -3px;
   -moz-outline-radius: 2px;
   /* Avoid the toolbar having no height when there's no items in it */
   min-height: 22px;
   /* There's no border in customize mode, so we don't need extra padding. */
   padding-bottom: 0;
 }
 
+/* Library animation */
+
+#navigator-toolbox[animate] {
+  position: relative;
+}
+
+#library-animatable-box {
+  display: none;
+}
+
+#library-animatable-box[animate] {
+  display: -moz-box;
+}
+
--- a/browser/themes/shared/compacttheme.inc.css
+++ b/browser/themes/shared/compacttheme.inc.css
@@ -45,16 +45,17 @@
   --chrome-nav-bar-separator-color: #B6B6B8;
   --chrome-nav-buttons-background: #ffffff; /* --theme-body-background */
   --chrome-nav-buttons-hover-background: #DADBDB;
   --chrome-nav-bar-controls-border-color: #ccc;
   --chrome-selection-color: #f5f7fa;
   --chrome-selection-background-color: #4c9ed9;
 }
 
+.toolbarbutton-animatable-box[brighttext],
 toolbar[brighttext] .toolbarbutton-1 {
   fill: rgba(249, 249, 250, .7);
 }
 
 #urlbar ::-moz-selection,
 #navigator-toolbox .searchbar-textbox ::-moz-selection,
 .browserContainer > findbar ::-moz-selection {
   background-color: var(--chrome-selection-background-color);
--- a/browser/themes/shared/toolbarbutton-icons.inc.css
+++ b/browser/themes/shared/toolbarbutton-icons.inc.css
@@ -1,21 +1,23 @@
 :root {
   --toolbarbutton-icon-fill-attention: #0a84ff;
 }
 
 toolbar[brighttext] {
   --toolbarbutton-icon-fill-attention: #45a1ff;
 }
 
+.toolbarbutton-animatable-box,
 .toolbarbutton-1 {
   -moz-context-properties: fill;
   fill: #4c4c4c;
 }
 
+.toolbarbutton-animatable-box[brighttext],
 toolbar[brighttext] .toolbarbutton-1 {
   fill: #fff;
 }
 
 #back-button:-moz-locale-dir(rtl) > .toolbarbutton-icon,
 #forward-button:-moz-locale-dir(rtl) > .toolbarbutton-icon,
 #reload-button:-moz-locale-dir(rtl) > .toolbarbutton-icon,
 #library-button:-moz-locale-dir(rtl) > .toolbarbutton-icon,
@@ -451,53 +453,54 @@ toolbar[brighttext] .toolbarbutton-1 {
   from {
     fill: var(--toolbarbutton-icon-fill-attention);
   }
   to {
     fill: inherit;
   }
 }
 
-#library-button[animate="bookmark"] {
-  position: relative;
-}
-
 #library-button[animate="bookmark"] > .toolbarbutton-icon {
   fill: transparent;
 }
 
-#library-button[animate="bookmark"] > .toolbarbutton-animatable-box {
+.toolbarbutton-animatable-box[animate="bookmark"] {
   position: absolute;
   overflow: hidden;
-  top: calc(50% - 27px); /* 27px is half the height of the sprite */
+  /* Position the sprite at the y-position of the library-button, then adjust
+     based on the size difference between half of the button height and half
+     of the sprite height. */
+  top: calc(var(--library-button-y) + var(--library-button-height) / 2 - 27px);
   /* Set a margin relative to the difference in widths of the .toolbarbutton-icon
-     and the .toolbar-animatable-box */
-  margin-inline-start: calc((16px + 2 * var(--toolbarbutton-inner-padding) - 22px) / 2);
+     and the .toolbar-animatable-box. This is correct even in RTL because the item
+     is positioned using `left`. */
+  left: calc(var(--library-icon-x) + (16px + 2 * var(--toolbarbutton-inner-padding) - 22px) / 2);
   /* Set the min- and max- width and height of the box equal to that
      of each frame of the SVG sprite (must use min- and max- due to bug 1379332). */
   min-width: 22px;
   max-width: 22px;
   min-height: 54px;
   max-height: 54px;
+  z-index: 2;
 }
 
-#library-button[animate="bookmark"] > .toolbarbutton-animatable-box > .toolbarbutton-animatable-image {
+.toolbarbutton-animatable-box[animate="bookmark"] > .toolbarbutton-animatable-image {
   height: var(--toolbarbutton-height);
   min-height: 54px; /* Minimum height must be equal to the height of the SVG sprite */
   background-image: url("chrome://browser/skin/library-bookmark-animation.svg");
   width: 1078px;
   animation-name: library-bookmark-animation;
   animation-duration: 800ms;
   animation-timing-function: steps(48);
   -moz-context-properties: fill, stroke;
   stroke: var(--toolbarbutton-icon-fill-attention);
 }
 
-#library-button[animate="bookmark"]:-moz-locale-dir(rtl) > .toolbarbutton-animatable-box > .toolbarbutton-animatable-image {
+.toolbarbutton-animatable-box[animate="bookmark"]:-moz-locale-dir(rtl) > .toolbarbutton-animatable-image {
   animation-name: library-bookmark-animation-rtl;
   transform: scaleX(-1);
 }
 
-#library-button[animate="bookmark"][fade] > .toolbarbutton-animatable-box > .toolbarbutton-animatable-image {
+.toolbarbutton-animatable-box[animate="bookmark"][fade] > .toolbarbutton-animatable-image {
   animation-name: library-bookmark-fade;
   animation-duration: 2s;
   animation-timing-function: ease-out;
 }