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 109325 d946b507ebc2a6fb46ff4c17f8ff533b43adea92
parent 109324 6134705b1a11fad73266562e0bbdc3cae743fe62
child 109326 53bf054fe0f1e33215347d468ccd9777e0c85803
push id82
push usershu@rfrn.org
push dateFri, 05 Oct 2012 13:20:22 +0000
reviewersUnfocused
bugs786125
milestone18.0a1
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;
+  }
+}