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
--- 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;