Bug 345238: Make XPFE alerts service use alert origin reported by look and feel. Ported from the toolkit patch by Jens Bannmann <jens.b@web.de>, r=neil, sr=biesi

This commit is contained in:
smontagu%smontagu.org 2006-12-13 16:06:20 +00:00
parent d8d349dea3
commit 7ed556d4fe
6 changed files with 171 additions and 42 deletions

View File

@ -52,18 +52,24 @@
min-height: 50px;
}
.alertImageBox {
margin-left: 4px;
margin-right: 6px;
.alertBox[orient="horizontal"] > .alertImageBox {
-moz-margin-start: 4px;
-moz-margin-end: 6px;
min-height: 46px;
}
.alertBox[orient="vertical"] > .alertImageBox {
margin-top: 6px;
margin-bottom: 4px;
min-width: 46px;
}
.alertTitle {
font-weight: bold;
}
.alertText {
margin-right: 6px;
-moz-margin-end: 6px;
}
.alertText[clickable="true"] {
@ -76,9 +82,15 @@
color: #424F63;
}
.alertTextBox
.alertBox[orient="horizontal"] > .alertTextBox
{
padding-right: 10px;
-moz-padding-start: 10px;
padding-top: 5px;
}
.alertBox[orient="vertical"] > .alertTextBox {
-moz-padding-start: 5px;
-moz-padding-end: 5px;
margin-bottom: 8px;
-moz-box-align: center; /* also hard-coded in alert.js, see bug 311557 */
}

View File

@ -52,11 +52,18 @@
min-height: 50px;
}
.alertImageBox {
margin-left: 4px;
.alertBox[orient="horizontal"] > .alertImageBox {
-moz-margin-start: 4px;
-moz-margin-end: 6px;
min-height: 46px;
}
.alertBox[orient="vertical"] > .alertImageBox {
margin-top: 6px;
margin-bottom: 4px;
min-width: 46px;
}
.alertTitle {
font-weight: bold;
}
@ -68,7 +75,7 @@
}
.alertText {
margin-right: 6px;
-moz-margin-end: 6px;
}
.alertText[clickable="true"] {

View File

@ -21,6 +21,7 @@
* Contributor(s):
* Scott MacGregor <mscott@netscape.com>
* Jens Bannmann <jens.b@web.de>
* Simon Montagu <smontagu@smontagu.org>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
@ -36,10 +37,18 @@
*
* ***** END LICENSE BLOCK ***** */
var gFinalHeight = 50;
// 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 gAlertListener = null;
var gAlertTextClickable = false;
@ -53,19 +62,31 @@ function prefillAlertInfo()
// arguments[2] --> the alert text
// arguments[3] --> is the text clickable?
// arguments[4] --> the alert cookie to be passed back to the listener
// arguments[5] --> an optional callback listener (nsIObserver)
// arguments[5] --> the alert origin reported by the look and feel
// arguments[6] --> an optional callback listener (nsIObserver)
document.getElementById('alertImage').setAttribute('src', window.arguments[0]);
document.getElementById('alertTitleLabel').setAttribute('value', window.arguments[1]);
document.getElementById('alertTextLabel').setAttribute('value', window.arguments[2]);
gAlertTextClickable = window.arguments[3];
gAlertCookie = window.arguments[4];
if (gAlertTextClickable)
document.getElementById('alertTextLabel').setAttribute('clickable', true);
// the 5th argument is optional
gAlertListener = window.arguments[5];
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:
gAlertTextClickable = window.arguments[3];
if (gAlertTextClickable)
document.getElementById('alertTextLabel').setAttribute('clickable', true);
case 3:
document.getElementById('alertTextLabel').setAttribute('value', window.arguments[2]);
case 2:
document.getElementById('alertTitleLabel').setAttribute('value', window.arguments[1]);
case 1:
document.getElementById('alertImage').setAttribute('src', window.arguments[0]);
case 0:
break;
}
}
function onAlertLoad()
@ -81,6 +102,35 @@ function onAlertLoad()
gOpenTime = prefBranch.getIntPref("alerts.totalOpenTime");
} catch (ex) {}
// 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)
document.documentElement.pack = "end";
// Additionally, change the orientation so the packing works as intended
document.documentElement.orient = "horizontal";
}
else
{
if (gOrigin & NS_ALERT_TOP)
document.documentElement.pack = "end";
}
var alertBox = document.getElementById("alertBox");
alertBox.orient = (gOrigin & NS_ALERT_HORIZONTAL) ? "vertical" : "horizontal";
// The above doesn't cause the labels in alertTextBox to reflow,
// see bug 311557. As the theme's -moz-box-align css rule gets ignored,
// we work around the bug by setting the align property.
if (gOrigin & NS_ALERT_HORIZONTAL)
{
document.getElementById("alertTextBox").align = "center";
}
sizeToContent();
// work around a bug where sizeToContent() leaves a border outside of the content
@ -88,23 +138,60 @@ function onAlertLoad()
if (window.innerWidth == contentDim.width + 1)
--window.innerWidth;
gFinalHeight = window.outerHeight;
gCurrentSize = 1;
// start with a 1px height, because 0 causes trouble with gtk1/2
window.outerHeight = 1;
// Determine final size
if (gOrigin & NS_ALERT_HORIZONTAL)
{
gFinalSize = window.outerWidth;
window.outerWidth = gCurrentSize;
}
else
{
gFinalSize = window.outerHeight;
window.outerHeight = gCurrentSize;
}
// be sure to offset the alert by 10 pixels from the far right edge of the screen
window.moveTo( (screen.availLeft + screen.availWidth - window.outerWidth) - 10, screen.availTop + screen.availHeight - window.outerHeight);
// 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;
window.moveTo(x, y);
setTimeout(animateAlert, gSlideTime);
}
function animate(step)
{
gCurrentSize += step;
if (gOrigin & NS_ALERT_HORIZONTAL)
{
if (!(gOrigin & NS_ALERT_LEFT))
window.screenX -= step;
window.outerWidth = gCurrentSize;
}
else
{
if (!(gOrigin & NS_ALERT_TOP))
window.screenY -= step;
window.outerHeight = gCurrentSize;
}
}
function animateAlert()
{
if (window.outerHeight < gFinalHeight)
if (gCurrentSize < gFinalSize)
{
window.screenY -= gSlideIncrement;
window.outerHeight += gSlideIncrement;
animate(gSlideIncrement);
setTimeout(animateAlert, gSlideTime);
}
else
@ -113,10 +200,9 @@ function animateAlert()
function closeAlert()
{
if (window.outerHeight > 1)
if (gCurrentSize > 1)
{
window.screenY += gSlideIncrement;
window.outerHeight -= gSlideIncrement;
animate(-gSlideIncrement);
setTimeout(closeAlert, gSlideTime);
}
else

View File

@ -41,14 +41,14 @@
<window id="alertNotification"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
windowtype="alert:alert"
align="start"
pack="start"
onload="onAlertLoad()">
<script type="application/x-javascript" src="chrome://communicator/content/alerts/alert.js"/>
<hbox id="alertBox" class="alertBox">
<box id="alertBox" class="alertBox">
<hbox class="alertImageBox" align="center" valign="center">
<hbox class="alertImageBox" align="center" pack="center">
<image id="alertImage"/>
</hbox>
@ -57,7 +57,7 @@
<label id="alertTextLabel" class="alertText plain" onclick="onAlertClick();"/>
</vbox>
</hbox>
</box>
<!-- This method is called inline because we want to make sure we establish the width
and height of the alert before we fire the onload handler. -->

View File

@ -51,6 +51,8 @@ REQUIRES = xpcom \
string \
windowwatcher \
dom \
widget \
gfx \
$(NULL)
CPPSRCS = \

View File

@ -21,6 +21,8 @@
*
* Contributor(s):
* Scott MacGregor <mscott@netscape.com>
* Jens Bannmann <jens.b@web.de>
* Simon Montagu <smontagu@smontagu.org>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
@ -44,6 +46,8 @@
#include "nsIDOMWindowInternal.h"
#include "nsIWindowWatcher.h"
#include "nsDependentString.h"
#include "nsWidgetsCID.h"
#include "nsILookAndFeel.h"
#define ALERT_CHROME_URL "chrome://communicator/content/alerts/alert.xul"
@ -80,31 +84,49 @@ NS_IMETHODIMP nsAlertsService::ShowAlertNotification(const nsAString & aImageUrl
NS_ENSURE_TRUE(scriptableImageUrl, NS_ERROR_FAILURE);
scriptableImageUrl->SetData(aImageUrl);
argsArray->AppendElement(scriptableImageUrl);
rv = argsArray->AppendElement(scriptableImageUrl);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsISupportsString> scriptableAlertTitle (do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID));
NS_ENSURE_TRUE(scriptableAlertTitle, NS_ERROR_FAILURE);
scriptableAlertTitle->SetData(aAlertTitle);
argsArray->AppendElement(scriptableAlertTitle);
rv = argsArray->AppendElement(scriptableAlertTitle);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsISupportsString> scriptableAlertText (do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID));
NS_ENSURE_TRUE(scriptableAlertText, NS_ERROR_FAILURE);
scriptableAlertText->SetData(aAlertText);
argsArray->AppendElement(scriptableAlertText);
rv = argsArray->AppendElement(scriptableAlertText);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsISupportsPRBool> scriptableIsClickable (do_CreateInstance(NS_SUPPORTS_PRBOOL_CONTRACTID));
NS_ENSURE_TRUE(scriptableIsClickable, NS_ERROR_FAILURE);
scriptableIsClickable->SetData(aAlertTextClickable);
argsArray->AppendElement(scriptableIsClickable);
rv = argsArray->AppendElement(scriptableIsClickable);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsISupportsString> scriptableAlertCookie (do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID));
NS_ENSURE_TRUE(scriptableAlertCookie, NS_ERROR_FAILURE);
scriptableAlertCookie->SetData(aAlertCookie);
argsArray->AppendElement(scriptableAlertCookie);
rv = argsArray->AppendElement(scriptableAlertCookie);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsISupportsPRInt32> scriptableOrigin (do_CreateInstance(NS_SUPPORTS_PRINT32_CONTRACTID));
NS_ENSURE_TRUE(scriptableOrigin, NS_ERROR_FAILURE);
nsCOMPtr<nsILookAndFeel> lookAndFeel = do_GetService("@mozilla.org/widget/lookandfeel;1");
if (lookAndFeel)
{
PRInt32 origin;
lookAndFeel->GetMetric(nsILookAndFeel::eMetric_AlertNotificationOrigin,
origin);
scriptableOrigin->SetData(origin);
}
rv = argsArray->AppendElement(scriptableOrigin);
NS_ENSURE_SUCCESS(rv, rv);
if (aAlertListener)
{