Bug 1352075 - Implement new animation for opening/closing the arrow panels. draft
authorSam Foster <sfoster@mozilla.com>
Thu, 27 Jul 2017 11:07:23 -0700
changeset 618691 e7e38e16aa1aee42fd9735ed0274b11b026272af
parent 618502 1be0c1da06076f85c69cd8a9d244e0164ec544d9
child 640151 06b8fae9f004ea2218dfe4e37d6399a47f962f15
push id71420
push userbmo:sfoster@mozilla.com
push dateMon, 31 Jul 2017 22:20:39 +0000
bugs1352075
milestone56.0a1
Bug 1352075 - Implement new animation for opening/closing the arrow panels. * Use new panel animation when opening arrow-panels (including bookmarks menu) to fade in and drop into position * Linux/GTK is (still) excluded * New animation is non-directional (i.e. LTR vs. RTL) This was landed then backed out due to test failures. New since last review: * Make opacity & transform transition durations equal - ensuring popup is not still moving when popupshown is fired * Fix missing comma in transition-duration values * Add animating attribute to the arrowpanel binding to disable pointer-events during the opening transition (via :jaws) * Wait for popupshown rather than transitionend in bookmark reparenting test * Fix specificity of CSS rules for panels/bookmarks-menu on edges other than the top (via :jaws) MozReview-Commit-ID: DTnvyMryf5Y
browser/base/content/browser.css
browser/components/customizableui/test/browser_984455_bookmarks_items_reparenting.js
browser/components/places/content/menu.xml
toolkit/content/widgets/popup.xml
toolkit/content/xul.css
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -1128,26 +1128,82 @@ toolbarpaletteitem[place="palette"] > #d
   -moz-appearance: none;
   -moz-binding: url("chrome://browser/content/places/menu.xml#places-popup-arrow");
   background: transparent;
   border: none;
   /* The popup inherits -moz-image-region from the button, must reset it */
   -moz-image-region: auto;
 }
 
+%ifdef MOZ_PHOTON_ANIMATIONS
 %ifdef MOZ_WIDGET_COCOA
 
 /* On Mac, use the properties "-moz-window-transform" and "-moz-window-opacity"
    instead of "transform" and "opacity" for these animations.
    The -moz-window* properties apply to the whole window including the window's
    shadow, and they don't affect the window's "shape", so the system doesn't
    have to recompute the shadow shape during the animation. This makes them a
    lot faster. In fact, Gecko no longer triggers shadow shape recomputations
    for repaints.
    These properties are not implemented on other platforms. */
+#BMB_bookmarksPopup:not([animate="false"]) {
+  -moz-window-opacity: 0;
+  -moz-window-transform: translateY(-70px);
+  transition-property: -moz-window-transform, -moz-window-opacity;
+  transition-duration: 0.18s, 0.18s;
+  transition-timing-function:
+    var(--animation-easing-function), ease-out;
+}
+
+#BMB_bookmarksPopup[side="bottom"]:not([animate="false"]) {
+  -moz-window-transform: translateY(70px);
+}
+
+#BMB_bookmarksPopup[side][animate="open"] {
+  -moz-window-opacity: 1.0;
+  transition-duration: 0.18s, 0.18s;
+  -moz-window-transform: none;
+  transition-timing-function:
+    var(--animation-easing-function), ease-in-out;
+}
+
+#BMB_bookmarksPopup[animate="cancel"] {
+  -moz-window-transform: none;
+}
+
+%elifndef MOZ_WIDGET_GTK
+
+#BMB_bookmarksPopup:not([animate="false"]) {
+  opacity: 0;
+  transform: translateY(-70px);
+  transition-property: transform, opacity;
+  transition-duration: 0.18s, 0.18s;
+  transition-timing-function:
+    var(--animation-easing-function), ease-out;
+}
+
+#BMB_bookmarksPopup[side="bottom"]:not([animate="false"]) {
+  transform: translateY(70px);
+}
+
+#BMB_bookmarksPopup[side][animate="open"] {
+  opacity: 1.0;
+  transition-duration: 0.18s, 0.18s;
+  transform: none;
+  transition-timing-function:
+    var(--animation-easing-function), ease-in-out;
+}
+
+#BMB_bookmarksPopup[animate="cancel"] {
+  transform: none;
+}
+%endif
+
+%else
+%ifdef MOZ_WIDGET_COCOA
 #BMB_bookmarksPopup {
   -moz-window-transform: scale(.4);
   -moz-window-opacity: 0;
   transition-property: -moz-window-transform, -moz-window-opacity;
   transition-duration: 0.15s;
   transition-timing-function: ease-out;
 }
 
@@ -1214,16 +1270,17 @@ toolbarpaletteitem[place="palette"] > #d
   transform-origin: 20px bottom;
 }
 
 #BMB_bookmarksPopup[arrowposition="before_end"]:-moz-locale-dir(ltr),
 #BMB_bookmarksPopup[arrowposition="before_start"]:-moz-locale-dir(rtl) {
   transform-origin: calc(100% - 20px) bottom;
 }
 %endif
+%endif
 
 /* Customize mode */
 %ifndef MOZ_PHOTON_THEME
 #navigator-toolbox,
 #browser-bottombox,
 #content-deck {
   transition-property: margin-left, margin-right;
   transition-duration: 200ms;
--- a/browser/components/customizableui/test/browser_984455_bookmarks_items_reparenting.js
+++ b/browser/components/customizableui/test/browser_984455_bookmarks_items_reparenting.js
@@ -14,23 +14,23 @@ const kSmallWidth = 400;
 
 /**
  * Helper function that opens the bookmarks menu, and returns a Promise that
  * resolves as soon as the menu is ready for interaction.
  */
 function bookmarksMenuPanelShown() {
   return new Promise(resolve => {
     let bookmarksMenuPopup = document.getElementById("BMB_bookmarksPopup");
-    let onTransitionEnd = (e) => {
+    let onPopupShown = (e) => {
       if (e.target == bookmarksMenuPopup) {
-        bookmarksMenuPopup.removeEventListener("transitionend", onTransitionEnd);
+        bookmarksMenuPopup.removeEventListener("popupshown", onPopupShown);
         resolve();
       }
     }
-    bookmarksMenuPopup.addEventListener("transitionend", onTransitionEnd);
+    bookmarksMenuPopup.addEventListener("popupshown", onPopupShown);
   });
 }
 
 /**
  * Checks that the placesContext menu is correctly attached to the
  * controller of some view. Returns a Promise that resolves as soon
  * as the context menu is closed.
  *
--- a/browser/components/places/content/menu.xml
+++ b/browser/components/places/content/menu.xml
@@ -597,17 +597,17 @@
           disablePointerEvents = this.getAttribute("disablepointereventsfortransition") == "true";
         }
         if (!disablePointerEvents) {
           this.style.removeProperty("pointer-events");
         }
       ]]></handler>
       <handler event="transitionend"><![CDATA[
         if (event.originalTarget.getAttribute("anonid") == "container" &&
-            event.propertyName == "transform") {
+            (event.propertyName == "transform" || event.propertyName == "-moz-window-transform")) {
           this.style.removeProperty("pointer-events");
         }
       ]]></handler>
       <handler event="popuphiding" phase="target"><![CDATA[
         this.setAttribute("animate", "cancel");
       ]]></handler>
       <handler event="popuphidden" phase="target"><![CDATA[
         this.removeAttribute("panelopen");
--- a/toolkit/content/widgets/popup.xml
+++ b/toolkit/content/widgets/popup.xml
@@ -491,16 +491,19 @@
         arrow.hidden = this.anchorNode == null;
         document.getAnonymousElementByAttribute(this, "anonid", "arrowbox")
                 .style.removeProperty("transform");
 
         this.adjustArrowPosition();
 
         if (this.getAttribute("animate") != "false") {
           this.setAttribute("animate", "open");
+          // the animating attribute prevents user interaction during transition
+          // it is removed when popupshown fires
+          this.setAttribute("animating", "true");
         }
 
         // set fading
         var fade = this.getAttribute("fade");
         var fadeDelay = 0;
         if (fade == "fast") {
           fadeDelay = 1;
         } else if (fade == "slow") {
@@ -520,16 +523,17 @@
           if (animate) {
             this.setAttribute("animate", "fade");
           }
         } else if (animate) {
           this.setAttribute("animate", "cancel");
         }
       </handler>
       <handler event="popupshown" phase="target">
+        this.removeAttribute("animating");
         this.setAttribute("panelopen", "true");
       </handler>
       <handler event="popuphidden" phase="target">
         this.removeAttribute("panelopen");
         if (this.getAttribute("animate") != "false") {
           this.removeAttribute("animate");
         }
       </handler>
--- a/toolkit/content/xul.css
+++ b/toolkit/content/xul.css
@@ -436,27 +436,88 @@ tooltip {
   white-space: pre-wrap;
   margin-top: 21px;
 }
 
 panel[type="arrow"] {
   -moz-binding: url("chrome://global/content/bindings/popup.xml#arrowpanel");
 }
 
+%ifdef MOZ_PHOTON_ANIMATIONS
 %ifdef MOZ_WIDGET_COCOA
 
 /* On Mac, use the properties "-moz-window-transform" and "-moz-window-opacity"
    instead of "transform" and "opacity" for these animations.
    The -moz-window* properties apply to the whole window including the window's
    shadow, and they don't affect the window's "shape", so the system doesn't
    have to recompute the shadow shape during the animation. This makes them a
    lot faster. In fact, Gecko no longer triggers shadow shape recomputations
    for repaints.
    These properties are not implemented on other platforms. */
 panel[type="arrow"]:not([animate="false"]) {
+  -moz-window-opacity: 0;
+  -moz-window-transform: translateY(-70px);
+  transition-property: -moz-window-transform, -moz-window-opacity;
+  transition-duration: 0.18s, 0.18s;
+  transition-timing-function:
+    var(--animation-easing-function), ease-out;
+}
+
+panel[type="arrow"][side="bottom"]:not([animate="false"]) {
+  -moz-window-transform: translateY(70px);
+}
+
+panel[type="arrow"][side][animate="open"] {
+  -moz-window-opacity: 1.0;
+  transition-duration: 0.18s, 0.18s;
+  -moz-window-transform: none;
+  transition-timing-function:
+    var(--animation-easing-function), ease-in-out;
+}
+
+panel[type="arrow"][animate="cancel"] {
+  -moz-window-transform: none;
+}
+
+%elifndef MOZ_WIDGET_GTK
+
+panel[type="arrow"]:not([animate="false"]) {
+  opacity: 0;
+  transform: translateY(-70px);
+  transition-property: transform, opacity;
+  transition-duration: 0.18s, 0.18s;
+  transition-timing-function:
+    var(--animation-easing-function), ease-out;
+}
+
+panel[type="arrow"][side="bottom"]:not([animate="false"]) {
+  transform: translateY(70px);
+}
+
+panel[type="arrow"][side][animate="open"] {
+  opacity: 1.0;
+  transition-duration: 0.18s, 0.18s;
+  transform: none;
+  transition-timing-function:
+    var(--animation-easing-function), ease-in-out;
+}
+
+panel[type="arrow"][animate="cancel"] {
+  transform: none;
+}
+
+%endif
+panel[type="arrow"][animating] {
+  pointer-events: none;
+}
+
+%else
+
+%ifdef MOZ_WIDGET_COCOA
+panel[type="arrow"]:not([animate="false"]) {
   -moz-window-transform: scale(.4);
   -moz-window-opacity: 0;
   transition-property: -moz-window-transform, -moz-window-opacity;
   transition-duration: 0.15s;
   transition-timing-function: ease-out;
 }
 
 panel[type="arrow"][animate="open"] {
@@ -563,16 +624,17 @@ panel[arrowposition="start_before"]:-moz
 }
 
 panel[arrowposition="end_after"]:-moz-locale-dir(ltr),
 panel[arrowposition="start_after"]:-moz-locale-dir(rtl) {
   transform-origin: left calc(100% - 20px);
 }
 
 %endif
+%endif
 
 %ifdef XP_MACOSX
 .statusbar-resizerpanel {
   display: none;
 }
 %else
 window[sizemode="maximized"] statusbarpanel.statusbar-resizerpanel {
   visibility: collapse;