Bug 831737 Re-write and simplify newmailalert.{js|xul|css} (Backport changes from SeaMonkey Bug 404580) ui-r=paenglab r=mkmelin.
authorPhilip Chee <philip.chee@gmail.com>
Fri, 01 Feb 2013 21:37:17 +0800
changeset 14771 a3767eefc68525478e7a3178fcdd51034f4029d0
parent 14770 45ffe028116902a163cdf5de7664e2b29a17edff
child 14772 49fedca3c4b6e0f0ac139eb904433679ab3f0cb2
push id867
push userbugzilla@standard8.plus.com
push dateMon, 01 Apr 2013 20:44:27 +0000
treeherdercomm-beta@797726b8d244 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspaenglab, mkmelin
bugs831737, 404580
Bug 831737 Re-write and simplify newmailalert.{js|xul|css} (Backport changes from SeaMonkey Bug 404580) ui-r=paenglab r=mkmelin.
mail/app/profile/all-thunderbird.js
mail/base/content/newmailalert.js
mail/base/content/newmailalert.xul
mail/base/jar.mn
mail/themes/gnomestripe/mail/newmailalert.css
mail/themes/qute/mail/newmailalert.css
mailnews/base/content/newmailalert.css
mailnews/base/content/newmailalert.js
mailnews/base/content/newmailalert.xul
mailnews/jar.mn
mailnews/mailnews.js
suite/browser/browser-prefs.js
suite/mailnews/jar.mn
suite/mailnews/newmailalert.css
suite/mailnews/newmailalert.js
suite/mailnews/newmailalert.xul
--- a/mail/app/profile/all-thunderbird.js
+++ b/mail/app/profile/all-thunderbird.js
@@ -211,21 +211,16 @@ pref("general.smoothScroll", true);
 pref("general.autoScroll", false);
 #else
 pref("general.autoScroll", true);
 #endif
 
 pref("mail.shell.checkDefaultClient", true);
 pref("mail.spellcheck.inline", true);
 
-pref("mail.biff.alert.show_preview", true);
-pref("mail.biff.alert.show_subject", true);
-pref("mail.biff.alert.show_sender",  true);
-pref("mail.biff.alert.preview_length", 40);
-
 pref("mail.folder.views.version", 0);
 
 // target folder URI used for the last move or copy
 pref("mail.last_msg_movecopy_target_uri", "");
 // last move or copy operation was a move
 pref("mail.last_msg_movecopy_was_move", true);
 
 #ifdef XP_WIN
@@ -399,17 +394,17 @@ pref("spellchecker.dictionaries.download
 
 // profile.force.migration can be used to bypass the migration wizard, forcing migration from a particular
 // mail application without any user intervention. Possible values are: 
 // seamonkey (mozilla suite), eudora, oexpress, outlook.
 pref("profile.force.migration", "");
 
 // prefs to control the mail alert notification
 pref("alerts.slideIncrementTime", 50);
-pref("alerts.totalOpenTime", 3000);
+pref("alerts.totalOpenTime", 10000);
 
 // analyze urls in mail messages for scams
 pref("mail.phishing.detection.enabled", true);
 // If phishing detection is enabled, allow fine grained control
 // of the local, static tests
 pref("mail.phishing.detection.ipaddresses", true); 
 pref("mail.phishing.detection.mismatched_hosts", true);
 
deleted file mode 100644
--- a/mail/base/content/newmailalert.js
+++ /dev/null
@@ -1,190 +0,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/. */
-
-Components.utils.import("resource://gre/modules/Services.jsm");
-
-const HORIZONTAL = 1;
-const LEFT = 2;
-const TOP = 4;
-
-var gSlideTime = 50;
-var gNumNewMsgsToShowInAlert = 4; // the more messages we show in the alert, the larger it will be
-var gOpenTime = 3000; // total time the alert should stay up once we are done animating.
-var gAlertListener = null;
-var gPendingPreviewFetchRequests = 0;
-var gUserInitiated = false;
-var gFadeIncrement = .05;
-var gOrigin = 0;
-
-function prefillAlertInfo()
-{
-  // unwrap all the args....
-  // arguments[0] --> array of folders with new mail
-  // arguments[1] --> the observer to call back with notifications about the alert
-  // arguments[2] --> user initiated boolean. true if the user initiated opening the alert 
-  //                 (which means skip the fade effect and don't auto close the alert)
-  // arguments[3] --> the alert origin returned by the look and feel
-  var foldersWithNewMail = window.arguments[0];  
-  gAlertListener = window.arguments[1];
-  gUserInitiated = window.arguments[2];
-  gOrigin = window.arguments[3];
-
-  // For now just grab the first folder which should be a root folder
-  // for the account that has new mail. If we can't find a folder, just
-  // return to avoid the exception and empty dialog in upper left-hand corner.
-  let rootFolder;
-  if (foldersWithNewMail && foldersWithNewMail.Count() > 0)
-     rootFolder = foldersWithNewMail.GetElementAt(0)
-                    .QueryInterface(Components.interfaces.nsIWeakReference)
-                    .QueryReferent(Components.interfaces.nsIMsgFolder);
-  else
-   return;
-
-  // generate an account label string based on the root folder
-  var label = document.getElementById('alertTitle');
-  var totalNumNewMessages = rootFolder.getNumNewMessages(true);
-  label.value = document.getElementById('bundle_messenger').getFormattedString(totalNumNewMessages == 1 ? "newMailNotification_message" : "newMailNotification_messages", 
-                                                                                     [rootFolder.prettiestName, totalNumNewMessages]);
-
-  // this is really the root folder and we have to walk through the list to find the real folder that has new mail in it...:(
-  var allFolders = Components.classes["@mozilla.org/supports-array;1"].createInstance(Components.interfaces.nsISupportsArray);
-  rootFolder.ListDescendents(allFolders);
-  var numFolders = allFolders.Count();
-  var folderSummaryInfoEl = document.getElementById('folderSummaryInfo');
-  folderSummaryInfoEl.mMaxMsgHdrsInPopup = gNumNewMsgsToShowInAlert;
-  for (var folderIndex = 0; folderIndex < numFolders; folderIndex++)
-  {
-    var folder = allFolders.GetElementAt(folderIndex).QueryInterface(Components.interfaces.nsIMsgFolder);
-    const nsMsgFolderFlags = Components.interfaces.nsMsgFolderFlags;
-    if (folder.hasNewMessages && !(folder.flags & nsMsgFolderFlags.Virtual))
-    {
-      var asyncFetch = {};
-      folderSummaryInfoEl.parseFolder(folder, new urlListener(folder), asyncFetch);
-      if (asyncFetch.value)
-        gPendingPreviewFetchRequests++;
-    }
-  }
-}
-
-function urlListener(aFolder)
-{
-  this.mFolder = aFolder;
-}
-
-urlListener.prototype = {
-  OnStartRunningUrl: function(aUrl)
-  {
-  },
-
-  OnStopRunningUrl: function(aUrl, aExitCode)
-  {
-    var folderSummaryInfoEl = document.getElementById('folderSummaryInfo');
-    var asyncFetch = {};
-    folderSummaryInfoEl.parseFolder(this.mFolder, null, asyncFetch);
-    gPendingPreviewFetchRequests--;
-
-    // when we are done running all of our urls for fetching the preview text,
-    // start the alert.
-    if (!gPendingPreviewFetchRequests)
-      showAlert();
-  }
-}
-
-function onAlertLoad()
-{
-  prefillAlertInfo();
-  // read out our initial settings from prefs.
-  try 
-  {
-    gSlideTime = Services.prefs.getIntPref("alerts.slideIncrementTime");
-    gOpenTime = Services.prefs.getIntPref("alerts.totalOpenTime");
-  } catch (ex) {}
-  
-  // bogus call to make sure the window is moved offscreen until we are ready for it.
-  resizeAlert(true);
-
-  // if we aren't waiting to fetch preview text, then go ahead and 
-  // start showing the alert.
-  if (!gPendingPreviewFetchRequests)
-    setTimeout(showAlert, 0); // let the JS thread unwind, to give layout 
-                              // a chance to recompute the styles and widths for our alert text.
-}
-
-// If the user initiated the alert, show it right away, otherwise start opening the alert with
-// the fade effect. 
-function showAlert()
-{
-  if (!gUserInitiated) // set the initial opacity before we resize the window
-    document.getElementById('alertContainer').style.opacity = 0;
-  
-  // resize the alert based on our current content  
-  resizeAlert(false);
-  
-  if (document.getElementById('folderSummaryInfo').hasMessages)
-  {
-    if (!gUserInitiated) // don't fade in if the user opened the alert
-      setTimeout(fadeOpen, gSlideTime);
-  }
-  else
-    closeAlert(); // no mail, so don't bother showing the alert...
-}
-
-function resizeAlert(aMoveOffScreen)
-{
-  // sizeToContent is not working. It isn't honoring the max widths we are attaching to our inner
-  // objects like the folder summary element. While the folder summary element is cropping, 
-  // sizeToContent ends up thinking the window needs to be much wider than it should be. 
-  // use resizeTo and make up our measurements...
-  //sizeToContent();
-  
-  // Use the wider of the alert groove and the folderSummaryInfo box, then 
-  // add on the width of alertImageBox + some small amount of fudge. For the height, 
-  // just use the size of the alertBox, that appears to be pretty accurate.
-  var windowWidth = Math.max (document.getBoxObjectFor(document.getElementById('alertGroove')).width,
-                              document.getBoxObjectFor(document.getElementById('folderSummaryInfo')).width);
-  resizeTo(windowWidth + document.getBoxObjectFor(document.getElementById('alertImageBox')).width + 30, 
-           document.getBoxObjectFor(document.getElementById('alertBox')).height + 10);                     
-  
-  // leftover hack to get the window properly hidden when we first open it
-  if (aMoveOffScreen)
-    window.outerHeight = 1;
-
-  // Determine position and move window
-  var x = gOrigin & LEFT ? screen.availLeft :
-          (screen.availLeft + screen.availWidth - window.outerWidth);
-  var y = gOrigin & TOP ? screen.availTop :
-          (screen.availTop + screen.availHeight - window.outerHeight);
-  window.moveTo(x, y);
-}
-
-function fadeOpen()
-{
-  var alertContainer = document.getElementById('alertContainer');
-  var newOpacity = parseFloat(window.getComputedStyle(alertContainer, "").opacity) + gFadeIncrement;
-  alertContainer.style.opacity = newOpacity;
-  
-  if (newOpacity < 1.0)    
-    setTimeout(fadeOpen, gSlideTime);
-  else // switch gears and start closing the alert
-    setTimeout(fadeClose, gOpenTime);  
-}
-
-function fadeClose()
-{
-  var alertContainer = document.getElementById('alertContainer');
-  var newOpacity = parseFloat(window.getComputedStyle(alertContainer, "").opacity) - gFadeIncrement;
-  alertContainer.style.opacity = newOpacity;
-  
-  if (newOpacity <= 0)
-    closeAlert();
-  else
-    setTimeout(fadeClose, gSlideTime);
-}
-
-function closeAlert()
-{
-  if (gAlertListener)
-    gAlertListener.observe(null, "alertfinished", ""); 
-  window.close(); 
-}
deleted file mode 100644
--- a/mail/base/content/newmailalert.xul
+++ /dev/null
@@ -1,37 +0,0 @@
-<?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://messenger/skin/newmailalert.css" type="text/css"?>
-
-<window id="newMailAlertNotification"
-        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-        windowtype="alert:alert"
-        role="alert"
-        align="start"
-        onload="onAlertLoad()">
-
-  <stringbundle id="bundle_messenger" src="chrome://messenger/locale/messenger.properties"/>
-  <script type="application/javascript" src="chrome://messenger/content/newmailalert.js"/>
-
-  <stack id="alertContainer" mousethrough="always">
-    <hbox id="alertBox">
-      <hbox id ="alertImageBox" align="center" valign="center">
-        <image id="alertImage"/>
-      </hbox>
-
-      <vbox id="alertTextBox">
-        <label id="alertTitle"/>
-        <separator id="alertGroove" class="groove"/>
-        <folderSummary id="folderSummaryInfo" mousethrough="never"/>
-      </vbox>
-    </hbox>
-
-    <hbox align="top">
-      <spacer flex="1"/>
-      <toolbarbutton id="closeButton" onclick="closeAlert();"/>
-    </hbox>
-  </stack>
-</window>
--- a/mail/base/jar.mn
+++ b/mail/base/jar.mn
@@ -65,18 +65,16 @@ messenger.jar:
     content/messenger/searchBar.js                  (content/searchBar.js)
     content/messenger/phishingDetector.js           (content/phishingDetector.js)
     content/messenger/mail-offline.js               (content/mail-offline.js)
     content/messenger/aboutDialog.css               (content/aboutDialog.css)
     content/messenger/messenger.css                 (content/messenger.css)
     content/messenger/search.xml                    (content/search.xml)
     content/messenger/tabmail.xml                   (content/tabmail.xml)
     content/messenger/tabmail.css                   (content/tabmail.css)
-    content/messenger/newmailalert.xul              (content/newmailalert.xul)
-    content/messenger/newmailalert.js               (content/newmailalert.js)
     content/messenger/newTagDialog.xul              (content/newTagDialog.xul)
     content/messenger/newTagDialog.js               (content/newTagDialog.js)
 *   content/messenger/viewSourceOverlay.xul         (content/viewSourceOverlay.xul)
     content/messenger/configEditorOverlay.xul       (content/configEditorOverlay.xul)
     content/messenger/EdSpellCheckOverlay.xul       (content/EdSpellCheckOverlay.xul)
     content/messenger/EdSpellCheckOverlay.js        (content/EdSpellCheckOverlay.js)
     content/messenger/composerOverlay.css           (content/composerOverlay.css)
     content/messenger/threadPane.js                 (content/threadPane.js)
--- a/mail/themes/gnomestripe/mail/newmailalert.css
+++ b/mail/themes/gnomestripe/mail/newmailalert.css
@@ -6,54 +6,37 @@
 /* ===== alert.css =====================================================
   == Styles specific to the alerts dialog.
   ======================================================================= */
 
 @import url("chrome://messenger/skin/");
 
 @namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
 
-/*
- * See bug 332160. Apply these rules on #alertContainer instead of on
- * #newMailAlertNotification like on windows.
- */
-#alertContainer {
+#newMailAlertNotification {
+  -moz-appearance: none;
   min-height: 60px;
   border: ridge #5486DA 4px;
-  background-color: -moz-Dialog;
-  color: -moz-DialogText;
-}
-
-#newMailAlertNotification {
-  border: none; /* See bug 332160. */
 }
 
 #alertImage {
   list-style-image: url("chrome://branding/content/icon64.png");
 }
 
 #alertImageBox {
-  -moz-margin-start: 4px;
-  -moz-margin-end: 6px;
-  min-height: 46px;
+  padding: 4px;
 }
 
 #alertTitle {
   font-weight: bold;
-  text-align: center;
-  /* this right margin keeps us from overlapping with the
-     close button. It's value should be related to the width
-     of the closeButtonImage
-  */
-  -moz-margin-end: 16px;
 }
 
 #alertTextBox {
-  -moz-padding-end: 10px;
-  padding-top: 5px;
+  padding: 4px;
+  -moz-padding-end: 20px;
 }
 
 .folderSummary-message-row
 {
   /* This max width ends up dictating the overall width of the alert window
      because it controls how large the preview, subject and sender text can be
      before cropping kicks in */
   max-width: 450px;
@@ -77,21 +60,17 @@
   color: blue;
 }
 
 #closeButton {
   list-style-image: url("chrome://messenger/skin/icons/close-button.png");
   -moz-image-region: rect(0px, 16px, 16px, 0px);
   -moz-appearance: none;
   border: none !important;
-  padding: 2px 0px 0px;
-}
-
-#closeButton > .toolbarbutton-icon {
-  -moz-margin-end: 0px; /* override toolkit's default value */
+  padding: 2px;
 }
 
 #closeButton:hover {
   -moz-image-region: rect(0px, 32px, 16px, 16px);
 }
 
 #closeButton:hover:active {
   -moz-image-region: rect(0px, 48px, 16px, 32px);
--- a/mail/themes/qute/mail/newmailalert.css
+++ b/mail/themes/qute/mail/newmailalert.css
@@ -9,43 +9,33 @@
 
 @import url("chrome://messenger/skin/");
 
 @namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
 
 #newMailAlertNotification {
   min-height: 60px;
   border: ridge #5486DA 4px;
-  background-color: -moz-Dialog;
-  color: -moz-DialogText;
 }
 
 #alertImage {
   list-style-image: url("chrome://branding/content/icon64.png");
 }
 
 #alertImageBox {
-  -moz-margin-start: 4px;
-  -moz-margin-end: 6px;
-  min-height: 46px;
+  padding: 4px;
 }
 
 #alertTitle {
   font-weight: bold;
-  text-align: center;
-  /* this right margin keeps us from overlapping with the
-     close button. It's value should be related to the width
-     of the closeButtonImage
-  */
-  -moz-margin-end: 16px;
 }
 
 #alertTextBox {
-  -moz-padding-end: 10px;
-  padding-top: 5px;
+  padding: 4px;
+  -moz-padding-end: 20px;
 }
 
 .folderSummary-message-row
 {
   /* This max width ends up dictating the overall width of the alert window
      because it controls how large the preview, subject and sender text can be
      before cropping kicks in */
   max-width: 450px;
@@ -69,21 +59,17 @@
   color: blue;
 }
 
 #closeButton {
   list-style-image: url("chrome://messenger/skin/icons/close-button.png");
   -moz-image-region: rect(0px, 16px, 16px, 0px);
   -moz-appearance: none;
   border: none !important;
-  padding: 2px 0px 0px;
-}
-
-#closeButton > .toolbarbutton-icon {
-  -moz-margin-end: 0px; /* override toolkit's default value */
+  padding: 2px;
 }
 
 #closeButton:hover {
   -moz-image-region: rect(0px, 32px, 16px, 16px);
 }
 
 #closeButton:hover:active {
   -moz-image-region: rect(0px, 48px, 16px, 32px);
rename from suite/mailnews/newmailalert.css
rename to mailnews/base/content/newmailalert.css
--- a/suite/mailnews/newmailalert.css
+++ b/mailnews/base/content/newmailalert.css
@@ -5,19 +5,31 @@
 #alertContainer {
   opacity: 0;
 }
 
 #alertContainer[noanimation] {
   opacity: 1;
 }
 
-#alertContainer[animate] {
+#alertContainer[fade-in] {
   animation-timing-function: ease-out;
-  animation-duration: 4s;
+  animation-duration: 2s;
   animation-fill-mode: both;
-  animation-name: alert-animation;
+  animation-name: fade-in;
 }
 
-@keyframes alert-animation {
+@keyframes fade-in {
   from {opacity: 0;}
   to {opacity: 1;}
 }
+
+#alertContainer[fade-out] {
+  animation-timing-function: ease-in;
+  animation-duration: 2s;
+  animation-fill-mode: both;
+  animation-name: fade-out;
+}
+
+@keyframes fade-out {
+  from {opacity: 1;}
+  to {opacity: 0;}
+}
rename from suite/mailnews/newmailalert.js
rename to mailnews/base/content/newmailalert.js
--- a/suite/mailnews/newmailalert.js
+++ b/mailnews/base/content/newmailalert.js
@@ -17,20 +17,20 @@ var gPendingPreviewFetchRequests = 0;
 var gUserInitiated = false;
 var gOrigin = 0; // Default value: alert from bottom right.
 
 function prefillAlertInfo()
 {
   // unwrap all the args....
   // arguments[0] --> array of folders with new mail
   // arguments[1] --> the observer to call back with notifications about the alert
-  // arguments[2] --> user initiated boolean. true if the user initiated opening the alert 
+  // arguments[2] --> user initiated boolean. true if the user initiated opening the alert
   //                 (which means skip the fade effect and don't auto close the alert)
   // arguments[3] --> the alert origin returned by the look and feel
-  var foldersWithNewMail = window.arguments[0];  
+  var foldersWithNewMail = window.arguments[0];
   gAlertListener = window.arguments[1];
   gUserInitiated = window.arguments[2];
   gOrigin = window.arguments[3];
 
   // For now just grab the first folder which should be a root folder
   // for the account that has new mail. If we can't find a folder, just
   // return to avoid the exception and empty dialog in upper left-hand corner.
   var rootFolder;
@@ -41,17 +41,17 @@ function prefillAlertInfo()
                                  .QueryReferent(Components.interfaces.nsIMsgFolder);
 
   // Generate an account label string based on the root folder.
   var label = document.getElementById('alertTitle');
   var totalNumNewMessages = rootFolder.getNumNewMessages(true);
   var message = totalNumNewMessages == 1 ? "newMailNotification_message"
                                          : "newMailNotification_messages";
   label.value = document.getElementById('bundle_messenger')
-                        .getFormattedString(message, 
+                        .getFormattedString(message,
                                             [rootFolder.prettiestName, totalNumNewMessages]);
 
   // This is really the root folder and we have to walk through the list to
   // find the real folder that has new mail in it...:(
   var allFolders = Components.classes["@mozilla.org/supports-array;1"]
                              .createInstance(Components.interfaces.nsISupportsArray);
   rootFolder.ListDescendents(allFolders);
   var numFolders = allFolders.Count();
@@ -95,72 +95,70 @@ urlListener.prototype =
       showAlert();
   }
 }
 
 function onAlertLoad()
 {
   prefillAlertInfo();
   // read out our initial settings from prefs.
-  try 
+  try
   {
     gOpenTime = Services.prefs.getIntPref("alerts.totalOpenTime");
   } catch (ex) {}
-  
+
   // bogus call to make sure the window is moved offscreen until we are ready for it.
   resizeAlert(true);
 
-  // if we aren't waiting to fetch preview text, then go ahead and 
+  // if we aren't waiting to fetch preview text, then go ahead and
   // start showing the alert.
   if (!gPendingPreviewFetchRequests)
-    setTimeout(showAlert, 0); // let the JS thread unwind, to give layout 
+    setTimeout(showAlert, 0); // let the JS thread unwind, to give layout
                               // a chance to recompute the styles and widths for our alert text.
 }
 
 // If the user initiated the alert, show it right away, otherwise start opening the alert with
-// the fade effect. 
+// the fade effect.
 function showAlert()
 {
-  // resize the alert based on our current content  
+  if (!document.getElementById("folderSummaryInfo").hasMessages) {
+    closeAlert(); // no mail, so don't bother showing the alert...
+    return;
+  }
+
+  // resize the alert based on our current content
   resizeAlert(false);
-  
+
   var alertContainer = document.getElementById("alertContainer");
   // Don't fade in if the user opened the alert or the pref is true.
   if (gUserInitiated ||
       Services.prefs.getBoolPref("alerts.disableSlidingEffect")) {
     alertContainer.setAttribute("noanimation", true);
     setTimeout(closeAlert, gOpenTime);
     return;
   }
-  
-  if (document.getElementById('folderSummaryInfo').hasMessages)
-  {
-    alertContainer.addEventListener("animationend", function hideAlert(event) {
-      if (event.animationName == "alert-animation") {
-        alertContainer.removeEventListener("animationend", hideAlert, false);
-        let remaining = Math.max(Math.round(gOpenTime - event.elapsedTime * 1000), 0);
-        setTimeout(closeAlert, remaining);
-      }
-    }, false);
-    alertContainer.setAttribute("animate", true);
-  }
-  else
-  {
-    closeAlert(); // no mail, so don't bother showing the alert...
-  }
+
+  alertContainer.addEventListener("animationend", function hideAlert(event) {
+    if (event.animationName == "fade-in") {
+      alertContainer.removeEventListener("animationend", hideAlert, false);
+      let remaining = Math.max(Math.round(gOpenTime - event.elapsedTime * 1000), 0);
+      setTimeout(fadeOutAlert, remaining);
+    }
+  }, false);
+  alertContainer.setAttribute("fade-in", true);
 }
 
 function resizeAlert(aMoveOffScreen)
 {
   var alertTextBox = document.getElementById("alertTextBox");
   var alertImageBox = document.getElementById("alertImageBox");
   alertImageBox.style.minHeight = alertTextBox.scrollHeight + "px";
 
   sizeToContent();
-  
+
   // leftover hack to get the window properly hidden when we first open it
   if (aMoveOffScreen)
     window.outerHeight = 1;
 
   // Determine position
   var x = gOrigin & NS_ALERT_LEFT ? screen.availLeft :
           screen.availLeft + screen.availWidth - window.outerWidth;
   var y = gOrigin & NS_ALERT_TOP ? screen.availTop :
@@ -168,14 +166,26 @@ function resizeAlert(aMoveOffScreen)
 
   // Offset the alert by 10 pixels from the edge of the screen
   y += gOrigin & NS_ALERT_TOP ? 10 : -10;
   x += gOrigin & NS_ALERT_LEFT ? 10 : -10;
 
   window.moveTo(x, y);
 }
 
+function fadeOutAlert()
+{
+  var alertContainer = document.getElementById("alertContainer");
+  alertContainer.addEventListener("animationend", function fadeOut(event) {
+    if (event.animationName == "fade-out") {
+      alertContainer.removeEventListener("animationend", fadeOut, false);
+      closeAlert();
+    }
+  }, false);
+  alertContainer.setAttribute("fade-out", true);
+}
+
 function closeAlert()
 {
   if (gAlertListener)
-    gAlertListener.observe(null, "alertfinished", ""); 
-  window.close(); 
+    gAlertListener.observe(null, "alertfinished", "");
+  window.close();
 }
rename from suite/mailnews/newmailalert.xul
rename to mailnews/base/content/newmailalert.xul
--- a/mailnews/jar.mn
+++ b/mailnews/jar.mn
@@ -121,8 +121,11 @@ messenger.jar:
     content/messenger/fieldMapImport.js                                        (import/content/fieldMapImport.js)
     content/messenger/downloadheaders.js                                       (news/content/downloadheaders.js)
     content/messenger/downloadheaders.xul                                      (news/content/downloadheaders.xul)
     content/messenger/markByDate.js                                            (base/content/markByDate.js)
     content/messenger/markByDate.xul                                           (base/content/markByDate.xul)
     content/messenger/dateFormat.js                                            (base/content/dateFormat.js)
     content/messenger/shutdownWindow.xul                                       (base/content/shutdownWindow.xul)
     content/messenger/shutdownWindow.js                                        (base/content/shutdownWindow.js)
+    content/messenger/newmailalert.css                                         (base/content/newmailalert.css)
+    content/messenger/newmailalert.js                                          (base/content/newmailalert.js)
+    content/messenger/newmailalert.xul                                         (base/content/newmailalert.xul)
--- a/mailnews/mailnews.js
+++ b/mailnews/mailnews.js
@@ -603,16 +603,21 @@ pref("mail.imap.confirm_emptyTrashFolder
 pref("mailnews.append_preconfig_accounts.version", 1);
 
 // Pref controlling the updates on the pre-configured smtp servers.
 // In order to add new pre-configured smtp servers (after a version),
 // increase the following version number besides updating the
 // pref mail.smtpservers.appendsmtpservers
 pref("mail.append_preconfig_smtpservers.version", 1);
 
+pref("mail.biff.alert.show_preview", true);
+pref("mail.biff.alert.show_subject", true);
+pref("mail.biff.alert.show_sender",  true);
+pref("mail.biff.alert.preview_length", 40);
+
 pref("mail.biff.play_sound", true);
 // 0 == default system sound, 1 == user specified wav
 pref("mail.biff.play_sound.type", 0);
 // _moz_mailbeep is a magic key, for the default sound.
 // otherwise, this needs to be a file url
 pref("mail.biff.play_sound.url", "");
 pref("mail.biff.show_alert", true);
 pref("mail.biff.show_tray_icon", true); // currently Windows-only
--- a/suite/browser/browser-prefs.js
+++ b/suite/browser/browser-prefs.js
@@ -320,20 +320,16 @@ pref("javascript.options.showInConsole",
 pref("offline.startup_state",            0);
 pref("offline.send.unsent_messages",            0);
 pref("offline.download.download_messages",  0);
 
 pref("browser.offline-apps.notify", true);
 
 pref("browser.formfill.expire_days",        180);
 
-pref("mail.biff.alert.show_preview", true);
-pref("mail.biff.alert.show_subject", true);
-pref("mail.biff.alert.show_sender",  true);
-pref("mail.biff.alert.preview_length", 40);
 pref("mail.biff.show_new_alert",     true);
 
 pref("mailnews.ui.deleteMarksRead", true);
 
 // The maximum amount of decoded image data we'll willingly keep around (we
 // might keep around more than this, but we'll try to get down to this value).
 // (This is intentionally on the high side; see bugs 746055 and 768015.)
 pref("image.mem.max_decoded_image_kb", 256000);
@@ -664,17 +660,17 @@ pref("sidebar.customize.directory.url", 
 pref("sidebar.customize.more_panels.url", "http://dmoz.org/Netscape/Sidebar/");
 pref("sidebar.num_tabs_in_view", 8);
 
 pref("browser.throbber.url","chrome://navigator-region/locale/region.properties");
 
 // pref to control the alert notification 
 pref("alerts.slideIncrement", 1);
 pref("alerts.slideIncrementTime", 10);
-pref("alerts.totalOpenTime", 4000);
+pref("alerts.totalOpenTime", 10000);
 
 // 0 opens the download manager
 // 1 opens a progress dialog
 // 2 and other values, no download manager, no progress dialog. 
 pref("browser.download.manager.behavior", 0);
 
 pref("privacy.popups.sound_enabled",              false);
 pref("privacy.popups.sound_type",                 1);
--- a/suite/mailnews/jar.mn
+++ b/suite/mailnews/jar.mn
@@ -53,19 +53,16 @@ messenger.jar:
     content/messenger/mailEditorOverlay.xul
     content/messenger/mailKeysOverlay.xul
     content/messenger/phishingDetector.js
     content/messenger/mailOverlay.xul
     content/messenger/mailOverlay.js
     content/messenger/mail-offline.js
     content/messenger/mailContextMenus.js
     content/messenger/msgFolderPickerOverlay.xul
-    content/messenger/newmailalert.css
-    content/messenger/newmailalert.js
-    content/messenger/newmailalert.xul
     content/messenger/start.xhtml
     content/messenger/messengerdnd.js
     content/messenger/mailPrefsOverlay.xul                                     (prefs/mailPrefsOverlay.xul)
     content/messenger/pref-mailnews.xul                                        (prefs/pref-mailnews.xul)
     content/messenger/pref-mailnews.js                                         (prefs/pref-mailnews.js)
     content/messenger/pref-notifications.xul                                   (prefs/pref-notifications.xul)
     content/messenger/pref-notifications.js                                    (prefs/pref-notifications.js)
     content/messenger/pref-junk.xul                                            (prefs/pref-junk.xul)