Bug 1352075 - Implement new animation for opening/closing the arrow panels. r=dao,mossop
authorSam Foster <sfoster@mozilla.com>
Thu, 27 Jul 2017 11:07:23 -0700
changeset 372990 cd62bc7fffe4a0e01621872eee968fe656d04224
parent 372989 9e8f2f0c7730a682427b8c11d44a166de43a2225
child 372991 693f52e6fb26721453819c012a8134e694ade503
push id32287
push userarchaeopteryx@coole-files.de
push dateSat, 05 Aug 2017 09:53:03 +0000
treeherdermozilla-central@a9182f92641b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdao, mossop
bugs1352075
milestone57.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 1352075 - Implement new animation for opening/closing the arrow panels. r=dao,mossop * 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
@@ -1129,26 +1129,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;
 }
 
@@ -1215,16 +1271,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
@@ -600,17 +600,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;