Bug 786125 - Alert showing/hiding animation is janky (nsIAlertsService). r=Unfocused
authorJared Wein <jwein@mozilla.com>
Wed, 03 Oct 2012 23:59:36 -0700
changeset 115514 d946b507ebc2a6fb46ff4c17f8ff533b43adea92
parent 115513 6134705b1a11fad73266562e0bbdc3cae743fe62
child 115515 53bf054fe0f1e33215347d468ccd9777e0c85803
push id1708
push userakeybl@mozilla.com
push dateMon, 19 Nov 2012 21:10:21 +0000
treeherdermozilla-beta@27b14fe50103 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersUnfocused
bugs786125
milestone18.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 786125 - Alert showing/hiding animation is janky (nsIAlertsService). r=Unfocused
browser/app/profile/firefox.js
modules/libpref/src/init/all.js
toolkit/components/alerts/jar.mn
toolkit/components/alerts/resources/content/alert.css
toolkit/components/alerts/resources/content/alert.js
toolkit/components/alerts/resources/content/alert.xul
toolkit/themes/winstripe/global/alerts/alert.css
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -527,21 +527,16 @@ pref("mousewheel.with_shift.action", 1);
 #else
 pref("mousewheel.with_alt.action", 1);
 pref("mousewheel.with_shift.action", 2);
 #endif
 pref("mousewheel.with_control.action",3);
 pref("mousewheel.with_meta.action", 1);  // command key on Mac
 pref("mousewheel.with_win.action", 1);
 
-// pref to control the alert notification 
-pref("alerts.slideIncrement", 1);
-pref("alerts.slideIncrementTime", 10);
-pref("alerts.totalOpenTime", 4000);
-
 pref("browser.xul.error_pages.enabled", true);
 pref("browser.xul.error_pages.expert_bad_cert", false);
 
 // Work Offline is best manually managed by the user.
 pref("network.manage-offline-status", false);
 
 // We want to make sure mail URLs are handled externally...
 pref("network.protocol-handler.external.mailto", true); // for mail
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -3668,20 +3668,17 @@ pref("extensions.alwaysUnpack", false);
 pref("extensions.minCompatiblePlatformVersion", "2.0");
 
 pref("network.buffer.cache.count", 24);
 pref("network.buffer.cache.size",  32768);
 
 // Desktop Notification
 pref("notification.feature.enabled", false);
 
-// Alert sliding effect
-pref("alerts.slideIncrement", 1);
-pref("alerts.slideIncrementTime", 10);
-pref("alerts.totalOpenTime", 4000);
+// Alert animation effect, name is disableSlidingEffect for backwards-compat.
 pref("alerts.disableSlidingEffect", false);
 
 // DOM full-screen API.
 pref("full-screen-api.enabled", false);
 pref("full-screen-api.allow-trusted-requests-only", true);
 pref("full-screen-api.exit-on-deactivate", true);
 pref("full-screen-api.pointer-lock.enabled", true);
 
--- a/toolkit/components/alerts/jar.mn
+++ b/toolkit/components/alerts/jar.mn
@@ -1,7 +1,8 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 toolkit.jar:
+  content/global/alerts/alert.css (resources/content/alert.css)
   content/global/alerts/alert.xul (resources/content/alert.xul)
   content/global/alerts/alert.js  (resources/content/alert.js)
new file mode 100644
--- /dev/null
+++ b/toolkit/components/alerts/resources/content/alert.css
@@ -0,0 +1,15 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#alertBox[animate] {
+  animation-duration: 4s;
+  animation-fill-mode: both;
+  animation-name: alert-animation;
+}
+
+@keyframes alert-animation {
+  to {
+    visibility: hidden;
+  }
+}
--- a/toolkit/components/alerts/resources/content/alert.js
+++ b/toolkit/components/alerts/resources/content/alert.js
@@ -6,42 +6,33 @@
 
 Components.utils.import("resource://gre/modules/Services.jsm");
 
 // Copied from nsILookAndFeel.h, see comments on eMetric_AlertNotificationOrigin
 const NS_ALERT_HORIZONTAL = 1;
 const NS_ALERT_LEFT = 2;
 const NS_ALERT_TOP = 4;
 
-var gFinalSize;
-var gCurrentSize = 1;
-
-var gSlideIncrement = 1;
-var gSlideTime = 10;
-var gOpenTime = 3000; // total time the alert should stay up once we are done animating.
-var gOrigin = 0; // Default value: alert from bottom right, sliding in vertically.
-var gDisableSlideEffect = false;
+var gOrigin = 0; // Default value: alert from bottom right.
  
 var gAlertListener = null;
 var gAlertTextClickable = false;
 var gAlertCookie = "";
 
-function prefillAlertInfo()
-{
+function prefillAlertInfo() {
   // unwrap all the args....
   // arguments[0] --> the image src url
   // arguments[1] --> the alert title
   // arguments[2] --> the alert text
-  // arguments[3] --> is the text clickable? 
+  // arguments[3] --> is the text clickable?
   // arguments[4] --> the alert cookie to be passed back to the listener
   // arguments[5] --> the alert origin reported by the look and feel
   // arguments[6] --> an optional callback listener (nsIObserver)
 
-  switch (window.arguments.length)
-  {
+  switch (window.arguments.length) {
     default:
     case 7:
       gAlertListener = window.arguments[6];
     case 6:
       gOrigin = window.arguments[5];
     case 5:
       gAlertCookie = window.arguments[4];
     case 4:
@@ -56,136 +47,66 @@ function prefillAlertInfo()
       document.getElementById('alertTitleLabel').setAttribute('value', window.arguments[1]);
     case 1:
       document.getElementById('alertImage').setAttribute('src', window.arguments[0]);
     case 0:
       break;
   }
 }
 
-function onAlertLoad()
-{
-  gSlideIncrement     = Services.prefs.getIntPref("alerts.slideIncrement");
-  gSlideTime          = Services.prefs.getIntPref("alerts.slideIncrementTime");
-  gOpenTime           = Services.prefs.getIntPref("alerts.totalOpenTime");
-  gDisableSlideEffect = Services.prefs.getBoolPref("alerts.disableSlidingEffect");
-
-  var alertBox = document.getElementById("alertBox");
+function onAlertLoad() {
   // Make sure that the contents are fixed at the window edge facing the
   // screen's center so that the window looks like "sliding in" and not
   // like "unfolding". The default packing of "start" only works for
   // vertical-bottom and horizontal-right positions, so we change it here.
-  if (gOrigin & NS_ALERT_HORIZONTAL)
-  {
-    if (gOrigin & NS_ALERT_LEFT) {
+  if (gOrigin & NS_ALERT_HORIZONTAL) {
+    if (gOrigin & NS_ALERT_LEFT)
       document.documentElement.pack = "end";
-      alertBox.setAttribute("origin", "left");
-    } else {
-      alertBox.setAttribute("origin", "right");
-    }
 
     // Additionally, change the orientation so the packing works as intended
     document.documentElement.orient = "horizontal";
-  }
-  else
-  {
-    if (gOrigin & NS_ALERT_TOP) {
+  } else {
+    if (gOrigin & NS_ALERT_TOP)
       document.documentElement.pack = "end";
-      alertBox.setAttribute("origin", "top");
-    } else {
-      alertBox.setAttribute("origin", "bottom");
-    }
   }
 
+  var alertBox = document.getElementById("alertBox");
   alertBox.orient = (gOrigin & NS_ALERT_HORIZONTAL) ? "vertical" : "horizontal";
 
   sizeToContent();
 
-  // Start with a 1px width/height, because 0 causes trouble with gtk1/2
-  gCurrentSize = 1;
-
-  // Determine final size
-  if (gOrigin & NS_ALERT_HORIZONTAL)
-  {
-    gFinalSize = window.outerWidth;
-    window.outerWidth = gCurrentSize;
-  }
-  else
-  {
-    gFinalSize = window.outerHeight;
-    window.outerHeight = gCurrentSize;
-  }
-
   // Determine position
   var x = gOrigin & NS_ALERT_LEFT ? screen.availLeft :
           screen.availLeft + screen.availWidth - window.outerWidth;
   var y = gOrigin & NS_ALERT_TOP ? screen.availTop :
           screen.availTop + screen.availHeight - window.outerHeight;
 
   // Offset the alert by 10 pixels from the edge of the screen
-  if (gOrigin & NS_ALERT_HORIZONTAL)
-    y += gOrigin & NS_ALERT_TOP ? 10 : -10;
-  else
-    x += gOrigin & NS_ALERT_LEFT ? 10 : -10;
+  y += gOrigin & NS_ALERT_TOP ? 10 : -10;
+  x += gOrigin & NS_ALERT_LEFT ? 10 : -10;
 
   window.moveTo(x, y);
 
-  setTimeout(animateAlert, gSlideTime);
-}
-
-function animate(step)
-{
-  gCurrentSize += step;
-
-  if (gFinalSize < gCurrentSize)
-    gCurrentSize = gFinalSize;
-
-  if (gOrigin & NS_ALERT_HORIZONTAL)
-  {
-    if (!(gOrigin & NS_ALERT_LEFT))
-      window.screenX -= step;
-    window.outerWidth = gCurrentSize;
+  if (Services.prefs.getBoolPref("alerts.disableSlidingEffect")) {
+    setTimeout(closeAlert, 4000);
+    return;
   }
-  else
-  {
-    if (!(gOrigin & NS_ALERT_TOP))
-      window.screenY -= step;
-    window.outerHeight = gCurrentSize;
-  }
-}
 
-function animateAlert()
-{
-  if (gCurrentSize < gFinalSize)
-  {
-    if (gDisableSlideEffect)
-      animate(gFinalSize); // We don't begin on zero.
-    else
-      animate(gSlideIncrement);
-    setTimeout(animateAlert, gSlideTime);
-  }
-  else
-    setTimeout(animateCloseAlert, gOpenTime);  
-}
-
-function animateCloseAlert()
-{
-  if (gCurrentSize > 1 && !gDisableSlideEffect)
-  {
-    animate(-gSlideIncrement);
-    setTimeout(animateCloseAlert, gSlideTime);
-  }
-  else
-    closeAlert();
+  alertBox.addEventListener("animationend", function hideAlert(event) {
+    if (event.animationName == "alert-animation") {
+      alertBox.removeEventListener("animationend", hideAlert, false);
+      closeAlert();
+    }
+  }, false);
+  alertBox.setAttribute("animate", true);
 }
 
 function closeAlert() {
   if (gAlertListener)
-    gAlertListener.observe(null, "alertfinished", gAlertCookie); 
-  window.close(); 
+    gAlertListener.observe(null, "alertfinished", gAlertCookie);
+  window.close();
 }
 
-function onAlertClick()
-{
+function onAlertClick() {
   if (gAlertListener && gAlertTextClickable)
     gAlertListener.observe(null, "alertclickcallback", gAlertCookie);
   closeAlert();
 }
--- a/toolkit/components/alerts/resources/content/alert.xul
+++ b/toolkit/components/alerts/resources/content/alert.xul
@@ -1,24 +1,25 @@
 <?xml version="1.0"?>
 <!-- This Source Code Form is subject to the terms of the Mozilla Public
    - License, v. 2.0. If a copy of the MPL was not distributed with this
    - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
 
+<?xml-stylesheet href="chrome://global/content/alerts/alert.css" type="text/css"?>
 <?xml-stylesheet href="chrome://global/skin/alerts/alert.css" type="text/css"?>
 
 <window id="alertNotification"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         windowtype="alert:alert"
         xmlns:xhtml="http://www.w3.org/1999/xhtml"
         xhtml:role="alert"
         pack="start"
         onload="onAlertLoad()"
         onclick="onAlertClick();">
-  
+
   <script type="application/javascript" src="chrome://global/content/alerts/alert.js"/>
 
   <box id="alertBox" class="alertBox">
     
     <hbox class="alertImageBox" align="center" pack="center">
       <image id="alertImage"/>
     </hbox>
 
--- a/toolkit/themes/winstripe/global/alerts/alert.css
+++ b/toolkit/themes/winstripe/global/alerts/alert.css
@@ -7,51 +7,28 @@
   ======================================================================= */
 
 @import url("chrome://global/skin/");
 
 @namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
 
 .alertBox {
   border: 1px solid threedshadow;
+  border-radius: 3px;
   background-color: -moz-Dialog;
   min-height: 50px;
   padding: 8px;
 }
 
 @media (-moz-windows-default-theme) {
   .alertBox {
     background-image: linear-gradient(to bottom, white 1px, rgba(255,255,255,0) 15px);
   }
 }
 
-.alertBox[origin="top"] {
-  border-top: none;
-  border-bottom-left-radius: 3px;
-  border-bottom-right-radius: 3px;
-}
-
-.alertBox[origin="right"] {
-  border-right: none;
-  border-bottom-left-radius: 3px;
-  border-top-left-radius: 3px;
-}
-
-.alertBox[origin="bottom"] {
-  border-bottom: none;
-  border-top-left-radius: 3px;
-  border-top-right-radius: 3px;
-}
-
-.alertBox[origin="left"] {
-  border-left: none;
-  border-bottom-right-radius: 3px;
-  border-top-right-radius: 3px;
-}
-
 .alertBox[orient="horizontal"] > .alertImageBox {
   -moz-margin-end: 8px;
 }
 
 .alertBox[orient="vertical"] > .alertImageBox {
   margin-bottom: 8px;
 }
 
@@ -83,8 +60,23 @@ label {
 
 .alertText[clickable="true"]:hover:active {
   color: #424F63;
 }
 
 .alertBox[orient="vertical"] > .alertTextBox {
   -moz-box-align: center;
 }
+
+@keyframes alert-animation {
+  from {
+    opacity: 0;
+  }
+  6.25% {
+    opacity: 1;
+  }
+  93.75% {
+    opacity: 1;
+  }
+  to {
+    opacity: 0;
+  }
+}