Bug 1396414 - Only animate cancelled popups, using a temporary result attribute.
* Add temp. result attribute when hiding a popup, to communicate when a popup is being cancelled (no action taken) vs. not.
* Refactor arrowpanel transition properties to be clearer about what animates, when.
* Add some debug logging
MozReview-Commit-ID: A9zqyC1z3VW
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -1180,63 +1180,65 @@ toolbarpaletteitem[place="palette"] > #d
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;
+ transition-property: none;
}
#BMB_bookmarksPopup[side="bottom"]:not([animate="false"]) {
-moz-window-transform: translateY(70px);
}
#BMB_bookmarksPopup[side][animate="open"] {
-moz-window-opacity: 1.0;
+ -moz-window-transform: none;
+ transition-property: -moz-window-transform, -moz-window-opacity;
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;
+ transition-property: -moz-window-opacity;
+ transition-duration: 0.18s;
+ transition-timing-function: ease-out;
}
%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;
+ transition-property: none;
}
#BMB_bookmarksPopup[side="bottom"]:not([animate="false"]) {
transform: translateY(70px);
}
#BMB_bookmarksPopup[side][animate="open"] {
opacity: 1.0;
+ transform: none;
+ transition-property: transform, opacity;
transition-duration: 0.18s, 0.18s;
- transform: none;
transition-timing-function:
var(--animation-easing-function), ease-in-out;
}
#BMB_bookmarksPopup[animate="cancel"] {
transform: none;
+ transition-property: opacity;
+ transition-duration: 0.18s;
+ transition-timing-function: ease-out;
}
%endif
/* Customize mode */
#PanelUI-contents > .panel-customization-placeholder > .panel-customization-placeholder-child {
list-style-image: none;
}
--- a/layout/xul/nsXULPopupManager.cpp
+++ b/layout/xul/nsXULPopupManager.cpp
@@ -1425,16 +1425,20 @@ nsXULPopupManager::ExecuteMenu(nsIConten
void
nsXULPopupManager::FirePopupShowingEvent(nsIContent* aPopup,
bool aIsContextMenu,
bool aSelectFirstItem,
nsIDOMEvent* aTriggerEvent)
{
nsCOMPtr<nsIContent> popup = aPopup; // keep a strong reference to the popup
+ if (aPopup->HasAttr(kNameSpaceID_None, nsGkAtoms::result)) {
+ aPopup->UnsetAttr(kNameSpaceID_None, nsGkAtoms::result, false);
+ }
+
nsMenuPopupFrame* popupFrame = do_QueryFrame(aPopup->GetPrimaryFrame());
if (!popupFrame)
return;
nsPresContext *presContext = popupFrame->PresContext();
nsCOMPtr<nsIPresShell> presShell = presContext->PresShell();
nsPopupType popupType = popupFrame->PopupType();
@@ -1553,16 +1557,22 @@ nsXULPopupManager::FirePopupHidingEvent(
nsPresContext *aPresContext,
nsPopupType aPopupType,
bool aDeselectMenu,
bool aIsCancel)
{
nsCOMPtr<nsIPresShell> presShell = aPresContext->PresShell();
mozilla::Unused << presShell; // This presShell may be keeping things alive on non GTK platforms
+ // set a "result" attribute so the front-end can know if this popup is being
+ // cancelled (no action taken) or dismissed (action taken)
+ aPopup->SetAttr(kNameSpaceID_None, nsGkAtoms::result,
+ aIsCancel ? NS_LITERAL_STRING("cancel") : NS_LITERAL_STRING("true"),
+ false);
+
nsEventStatus status = nsEventStatus_eIgnore;
WidgetMouseEvent event(true, eXULPopupHiding, nullptr,
WidgetMouseEvent::eReal);
EventDispatcher::Dispatch(aPopup, aPresContext, &event, nullptr, &status);
// when a panel is closed, blur whatever has focus inside the popup
if (aPopupType == ePopupTypePanel &&
!aPopup->AttrValueIs(kNameSpaceID_None, nsGkAtoms::noautofocus,
--- a/toolkit/content/widgets/popup.xml
+++ b/toolkit/content/widgets/popup.xml
@@ -511,26 +511,41 @@
} else {
return;
}
this._fadeTimer = setTimeout(() => this.hidePopup(true), fadeDelay, this);
]]>
</handler>
<handler event="popuphiding" phase="target">
- let animate = (this.getAttribute("animate") != "false");
-
+ <![CDATA[
+ let animate = this.getAttribute("animate");
+ let preventAnimate = (animate == "false");
+ let cancelling = this.getAttribute("result") == "cancel";
+ console.log(this.getAttribute("id") + ": popuphiding, animate: ", animate);
+ console.log(this.getAttribute("id") + ": popuphiding, cancelling: ", cancelling);
if (this._fadeTimer) {
clearTimeout(this._fadeTimer);
- if (animate) {
+ if (!preventAnimate && animate) {
this.setAttribute("animate", "fade");
}
- } else if (animate) {
- this.setAttribute("animate", "cancel");
+ } else if (!preventAnimate) {
+ if (cancelling) {
+ this.setAttribute("animate", "cancel");
+ } else {
+ // panel is being dismissed
+ this.setAttribute("animate", "dismiss");
+ }
}
+ console.log(this.getAttribute("id") + ": /popuphiding, animate: ", this.getAttribute("animate"));
+
+ let cs = getComputedStyle(this);
+ console.log(this.getAttribute("id") + ": /popuphiding, transition-property:", cs.getPropertyValue("transition-property"));
+ console.log(this.getAttribute("id") + ": /popuphiding, -moz-window-transform:", cs.getPropertyValue("-moz-window-transform"));
+ ]]>
</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") {
--- a/toolkit/content/xul.css
+++ b/toolkit/content/xul.css
@@ -449,63 +449,70 @@ panel[type="arrow"] {
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"][side]: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;
+ transition-property: none;
}
panel[type="arrow"][side="bottom"]:not([animate="false"]) {
-moz-window-transform: translateY(70px);
}
panel[type="arrow"][side][animate="open"] {
-moz-window-opacity: 1.0;
+ -moz-window-transform: none;
+ transition-property: -moz-window-transform, -moz-window-opacity;
transition-duration: 0.18s, 0.18s;
- -moz-window-transform: none;
transition-timing-function:
var(--animation-easing-function), ease-in-out;
}
panel[type="arrow"][side][animate="cancel"] {
-moz-window-transform: none;
+ transition-property: -moz-window-opacity;
+ transition-duration: 0.18s;
+ transition-timing-function: ease-out;
+}
+
+panel[type="arrow"][side][animate="dismiss"] {
+ /* wait until the popup is hidden before adjusting the transform */
+ -moz-window-transform: none;
}
%elifndef MOZ_WIDGET_GTK
panel[type="arrow"][side]: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;
+ transition-property: none;
}
panel[type="arrow"][side="bottom"]:not([animate="false"]) {
transform: translateY(70px);
}
panel[type="arrow"][side][animate="open"] {
opacity: 1.0;
+ transform: none;
+ transition-property: transform, opacity;
transition-duration: 0.18s, 0.18s;
- transform: none;
transition-timing-function:
var(--animation-easing-function), ease-in-out;
}
panel[type="arrow"][side][animate="cancel"] {
transform: none;
+ transition-property: opacity;
+ transition-duration: 0.18s;
+ transition-timing-function: ease-out;
}
%endif
panel[type="arrow"][animating] {
pointer-events: none;
}
%ifdef XP_MACOSX