Bug 782211 - Part 8: Updated existing XUL alerts to implement the Notification API. r=enn

This commit is contained in:
William Chen 2013-03-18 06:24:54 -07:00
parent 18996f8701
commit 3210246027
20 changed files with 529 additions and 108 deletions

View File

@ -15,6 +15,7 @@ FORCE_STATIC_LIB = 1
LIBXUL_LIBRARY = 1
CPPSRCS = \
nsAlertsService.cpp \
nsXULAlerts.cpp \
$(NULL)
LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/components/build/

View File

@ -12,17 +12,11 @@
#include "AndroidBridge.h"
#else
#include "nsISupportsArray.h"
#include "nsXPCOM.h"
#include "nsISupportsPrimitives.h"
#include "nsIServiceManager.h"
#include "nsIDOMWindow.h"
#include "nsIWindowWatcher.h"
#include "nsPromiseFlatString.h"
#include "nsToolkitCompsCID.h"
#include "mozilla/LookAndFeel.h"
#define ALERT_CHROME_URL "chrome://global/content/alerts/alert.xul"
#endif // !MOZ_WIDGET_ANDROID
@ -118,74 +112,10 @@ NS_IMETHODIMP nsAlertsService::ShowAlertNotification(const nsAString & aImageUrl
return NS_ERROR_NOT_IMPLEMENTED;
#endif
nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
nsCOMPtr<nsIDOMWindow> newWindow;
nsCOMPtr<nsISupportsArray> argsArray;
rv = NS_NewISupportsArray(getter_AddRefs(argsArray));
NS_ENSURE_SUCCESS(rv, rv);
// create scriptable versions of our strings that we can store in our nsISupportsArray....
nsCOMPtr<nsISupportsString> scriptableImageUrl (do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID));
NS_ENSURE_TRUE(scriptableImageUrl, NS_ERROR_FAILURE);
scriptableImageUrl->SetData(aImageUrl);
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);
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);
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);
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);
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);
int32_t origin =
LookAndFeel::GetInt(LookAndFeel::eIntID_AlertNotificationOrigin);
scriptableOrigin->SetData(origin);
rv = argsArray->AppendElement(scriptableOrigin);
NS_ENSURE_SUCCESS(rv, rv);
if (aAlertListener)
{
nsCOMPtr<nsISupportsInterfacePointer> ifptr = do_CreateInstance(NS_SUPPORTS_INTERFACE_POINTER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsISupports> iSupports (do_QueryInterface(aAlertListener));
ifptr->SetData(iSupports);
ifptr->SetDataIID(&NS_GET_IID(nsIObserver));
rv = argsArray->AppendElement(ifptr);
NS_ENSURE_SUCCESS(rv, rv);
}
rv = wwatch->OpenWindow(0, ALERT_CHROME_URL, "_blank",
"chrome,dialog=yes,titlebar=no,popup=yes", argsArray,
getter_AddRefs(newWindow));
// Use XUL notifications as a fallback if above methods have failed.
rv = mXULAlerts.ShowAlertNotification(aImageUrl, aAlertTitle, aAlertText, aAlertTextClickable,
aAlertCookie, aAlertListener, aAlertName,
aBidi, aLang);
return rv;
#endif // !MOZ_WIDGET_ANDROID
}
@ -214,7 +144,7 @@ NS_IMETHODIMP nsAlertsService::CloseAlert(const nsAString& aAlertName)
NS_ENSURE_SUCCESS(rv, rv);
}
return NS_ERROR_NOT_IMPLEMENTED;
return mXULAlerts.CloseAlert(aAlertName);
#endif // !MOZ_WIDGET_ANDROID
}

View File

@ -8,6 +8,7 @@
#include "nsIAlertsService.h"
#include "nsCOMPtr.h"
#include "nsXULAlerts.h"
#ifdef XP_WIN
typedef enum tagMOZ_QUERY_USER_NOTIFICATION_STATE {
@ -39,6 +40,7 @@ public:
protected:
bool ShouldShowAlert();
nsXULAlerts mXULAlerts;
};
#endif /* nsAlertsService_h__ */

View File

@ -0,0 +1,159 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode:nil; c-basic-offset: 2 -*- */
/* 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/. */
#include "nsXULAlerts.h"
#include "nsAutoPtr.h"
#include "mozilla/LookAndFeel.h"
#include "nsIServiceManager.h"
#include "nsISupportsArray.h"
#include "nsISupportsPrimitives.h"
#include "nsIWindowWatcher.h"
#define ALERT_CHROME_URL "chrome://global/content/alerts/alert.xul"
NS_IMPL_ISUPPORTS1(nsXULAlertObserver, nsIObserver)
NS_IMETHODIMP
nsXULAlertObserver::Observe(nsISupports* aSubject, const char* aTopic,
const PRUnichar* aData)
{
if (!strcmp("alertfinished", aTopic)) {
nsIDOMWindow* currentAlert = mXULAlerts->mNamedWindows.GetWeak(mAlertName);
// The window in mNamedWindows might be a replacement, thus it should only
// be removed if it is the same window that is associated with this listener.
if (currentAlert == mAlertWindow) {
mXULAlerts->mNamedWindows.Remove(mAlertName);
}
}
nsresult rv = NS_OK;
if (mObserver) {
rv = mObserver->Observe(aSubject, aTopic, aData);
}
return rv;
}
nsresult
nsXULAlerts::ShowAlertNotification(const nsAString& aImageUrl, const nsAString& aAlertTitle,
const nsAString& aAlertText, bool aAlertTextClickable,
const nsAString& aAlertCookie, nsIObserver* aAlertListener,
const nsAString& aAlertName, const nsAString& aBidi,
const nsAString& aLang)
{
nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
nsCOMPtr<nsIDOMWindow> newWindow;
nsCOMPtr<nsISupportsArray> argsArray;
nsresult rv = NS_NewISupportsArray(getter_AddRefs(argsArray));
NS_ENSURE_SUCCESS(rv, rv);
// create scriptable versions of our strings that we can store in our nsISupportsArray....
nsCOMPtr<nsISupportsString> scriptableImageUrl (do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID));
NS_ENSURE_TRUE(scriptableImageUrl, NS_ERROR_FAILURE);
scriptableImageUrl->SetData(aImageUrl);
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);
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);
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);
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);
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);
int32_t origin =
LookAndFeel::GetInt(LookAndFeel::eIntID_AlertNotificationOrigin);
scriptableOrigin->SetData(origin);
rv = argsArray->AppendElement(scriptableOrigin);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsISupportsString> scriptableBidi (do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID));
NS_ENSURE_TRUE(scriptableBidi, NS_ERROR_FAILURE);
scriptableBidi->SetData(aBidi);
rv = argsArray->AppendElement(scriptableBidi);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsISupportsString> scriptableLang (do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID));
NS_ENSURE_TRUE(scriptableLang, NS_ERROR_FAILURE);
scriptableLang->SetData(aLang);
rv = argsArray->AppendElement(scriptableLang);
NS_ENSURE_SUCCESS(rv, rv);
// Alerts with the same name should replace the old alert in the same position.
// Provide the new alert window with a pointer to the replaced window so that
// it may take the same position.
nsCOMPtr<nsISupportsInterfacePointer> replacedWindow = do_CreateInstance(NS_SUPPORTS_INTERFACE_POINTER_CONTRACTID, &rv);
NS_ENSURE_TRUE(replacedWindow, NS_ERROR_FAILURE);
nsIDOMWindow* previousAlert = mNamedWindows.GetWeak(aAlertName);
replacedWindow->SetData(previousAlert);
replacedWindow->SetDataIID(&NS_GET_IID(nsIDOMWindow));
rv = argsArray->AppendElement(replacedWindow);
NS_ENSURE_SUCCESS(rv, rv);
nsRefPtr<nsXULAlertObserver> alertObserver;
if (aAlertListener)
{
nsCOMPtr<nsISupportsInterfacePointer> ifptr = do_CreateInstance(NS_SUPPORTS_INTERFACE_POINTER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
alertObserver = new nsXULAlertObserver(this, aAlertName, aAlertListener);
nsCOMPtr<nsISupports> iSupports(do_QueryInterface(alertObserver));
ifptr->SetData(iSupports);
ifptr->SetDataIID(&NS_GET_IID(nsIObserver));
rv = argsArray->AppendElement(ifptr);
NS_ENSURE_SUCCESS(rv, rv);
}
rv = wwatch->OpenWindow(0, ALERT_CHROME_URL, "_blank",
"chrome,dialog=yes,titlebar=no,popup=yes", argsArray,
getter_AddRefs(newWindow));
mNamedWindows.Put(aAlertName, newWindow);
if (alertObserver) {
alertObserver->SetAlertWindow(newWindow);
}
return rv;
}
nsresult
nsXULAlerts::CloseAlert(const nsAString& aAlertName)
{
nsCOMPtr<nsIDOMWindow> domWindow = mNamedWindows.Get(aAlertName);
if (domWindow) {
return domWindow->Close();
}
return NS_OK;
}

View File

@ -0,0 +1,64 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode:nil; c-basic-offset: 2 -*- */
/* 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/. */
#ifndef nsXULAlerts_h__
#define nsXULAlerts_h__
#include "nsHashKeys.h"
#include "nsInterfaceHashtable.h"
#include "nsIDOMWindow.h"
#include "nsIObserver.h"
using namespace mozilla;
class nsXULAlerts {
friend class nsXULAlertObserver;
public:
nsXULAlerts()
{
mNamedWindows.Init();
}
virtual ~nsXULAlerts() {}
nsresult ShowAlertNotification(const nsAString& aImageUrl, const nsAString& aAlertTitle,
const nsAString& aAlertText, bool aAlertTextClickable,
const nsAString& aAlertCookie, nsIObserver* aAlertListener,
const nsAString& aAlertName, const nsAString& aBidi,
const nsAString& aLang);
nsresult CloseAlert(const nsAString& aAlertName);
protected:
nsInterfaceHashtable<nsStringHashKey, nsIDOMWindow> mNamedWindows;
};
/**
* This class wraps observers for alerts and watches
* for the "alertfinished" event in order to release
* the reference on the nsIDOMWindow of the XUL alert.
*/
class nsXULAlertObserver : public nsIObserver {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
nsXULAlertObserver(nsXULAlerts* aXULAlerts, const nsAString& aAlertName,
nsIObserver* aObserver)
: mXULAlerts(aXULAlerts), mAlertName(aAlertName),
mObserver(aObserver) {}
void SetAlertWindow(nsIDOMWindow* aWindow) { mAlertWindow = aWindow; }
virtual ~nsXULAlertObserver() {}
protected:
nsXULAlerts* mXULAlerts;
nsString mAlertName;
nsCOMPtr<nsIDOMWindow> mAlertWindow;
nsCOMPtr<nsIObserver> mObserver;
};
#endif /* nsXULAlerts_h__ */

View File

@ -6,16 +6,25 @@
Components.utils.import("resource://gre/modules/Services.jsm");
const Ci = Components.interfaces;
const Cc = Components.classes;
var windowMediator = Cc["@mozilla.org/appshell/window-mediator;1"]
.getService(Ci.nsIWindowMediator);
// Copied from nsILookAndFeel.h, see comments on eMetric_AlertNotificationOrigin
const NS_ALERT_HORIZONTAL = 1;
const NS_ALERT_LEFT = 2;
const NS_ALERT_TOP = 4;
const WINDOW_MARGIN = 10;
var gOrigin = 0; // Default value: alert from bottom right.
var gReplacedWindow = null;
var gAlertListener = null;
var gAlertTextClickable = false;
var gAlertCookie = "";
var gIsReplaced = false;
function prefillAlertInfo() {
// unwrap all the args....
@ -25,12 +34,17 @@ function prefillAlertInfo() {
// 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)
// arguments[6] --> bidi
// arguments[7] --> lang
// arguments[8] --> replaced alert window (nsIDOMWindow)
// arguments[9] --> an optional callback listener (nsIObserver)
switch (window.arguments.length) {
default:
case 7:
gAlertListener = window.arguments[6];
case 10:
gAlertListener = window.arguments[9];
case 9:
gReplacedWindow = window.arguments[8];
case 6:
gOrigin = window.arguments[5];
case 5:
@ -46,7 +60,9 @@ function prefillAlertInfo() {
case 2:
document.getElementById('alertTitleLabel').setAttribute('value', window.arguments[1]);
case 1:
document.getElementById('alertImage').setAttribute('src', window.arguments[0]);
if (window.arguments[0]) {
document.getElementById('alertImage').setAttribute('src', window.arguments[0]);
}
case 0:
break;
}
@ -60,20 +76,16 @@ function onAlertLoad() {
sizeToContent();
// Determine position
let x = gOrigin & NS_ALERT_LEFT ? screen.availLeft :
screen.availLeft + screen.availWidth - window.outerWidth;
let 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
y += gOrigin & NS_ALERT_TOP ? 10 : -10;
x += gOrigin & NS_ALERT_LEFT ? 10 : -10;
window.moveTo(x, y);
if (gReplacedWindow) {
moveWindowToReplace(gReplacedWindow);
gReplacedWindow.gIsReplaced = true;
gReplacedWindow.close();
} else {
moveWindowToEnd();
}
if (Services.prefs.getBoolPref("alerts.disableSlidingEffect")) {
setTimeout(closeAlert, ALERT_DURATION_IMMEDIATE);
setTimeout(function() { window.close(); }, ALERT_DURATION_IMMEDIATE);
return;
}
@ -81,20 +93,100 @@ function onAlertLoad() {
alertBox.addEventListener("animationend", function hideAlert(event) {
if (event.animationName == "alert-animation") {
alertBox.removeEventListener("animationend", hideAlert, false);
closeAlert();
window.close();
}
}, false);
alertBox.setAttribute("animate", true);
if (gAlertListener) {
gAlertListener.observe(null, "alertshow", gAlertCookie);
}
}
function closeAlert() {
if (gAlertListener)
function moveWindowToReplace(aReplacedAlert) {
let heightDelta = window.outerHeight - aReplacedAlert.outerHeight;
// Move windows that come after the replaced alert if the height is different.
if (heightDelta != 0) {
let windows = windowMediator.getEnumerator('alert:alert');
while (windows.hasMoreElements()) {
let alertWindow = windows.getNext();
// boolean to determine if the alert window is after the replaced alert.
let alertIsAfter = gOrigin & NS_ALERT_TOP ?
alertWindow.screenY > aReplacedAlert.screenY :
aReplacedAlert.screenY > alertWindow.screenY;
if (alertIsAfter) {
// The new Y position of the window.
let adjustedY = gOrigin & NS_ALERT_TOP ?
alertWindow.screenY + heightDelta :
alertWindow.screenY - heightDelta;
alertWindow.moveTo(alertWindow.screenX, adjustedY);
}
}
}
let adjustedY = gOrigin & NS_ALERT_TOP ? aReplacedAlert.screenY :
aReplacedAlert.screenY - heightDelta;
window.moveTo(aReplacedAlert.screenX, adjustedY);
}
function moveWindowToEnd() {
// Determine position
let x = gOrigin & NS_ALERT_LEFT ? screen.availLeft :
screen.availLeft + screen.availWidth - window.outerWidth;
let y = gOrigin & NS_ALERT_TOP ? screen.availTop :
screen.availTop + screen.availHeight - window.outerHeight;
// Position the window at the end of all alerts.
let windows = windowMediator.getEnumerator('alert:alert');
while (windows.hasMoreElements()) {
let alertWindow = windows.getNext();
if (alertWindow != window) {
if (gOrigin & NS_ALERT_TOP) {
y = Math.max(y, alertWindow.screenY + alertWindow.outerHeight);
} else {
y = Math.min(y, alertWindow.screenY - window.outerHeight);
}
}
}
// Offset the alert by WINDOW_MARGIN pixels from the edge of the screen
y += gOrigin & NS_ALERT_TOP ? WINDOW_MARGIN : -WINDOW_MARGIN;
x += gOrigin & NS_ALERT_LEFT ? WINDOW_MARGIN : -WINDOW_MARGIN;
window.moveTo(x, y);
}
function onAlertBeforeUnload() {
if (!gIsReplaced) {
// Move other alert windows to fill the gap left by closing alert.
let heightDelta = window.outerHeight + WINDOW_MARGIN;
let windows = windowMediator.getEnumerator('alert:alert');
while (windows.hasMoreElements()) {
let alertWindow = windows.getNext();
if (alertWindow != window) {
if (gOrigin & NS_ALERT_TOP) {
if (alertWindow.screenY > window.screenY) {
alertWindow.moveTo(alertWindow.screenX, alertWindow.screenY - heightDelta);
}
} else {
if (window.screenY > alertWindow.screenY) {
alertWindow.moveTo(alertWindow.screenX, alertWindow.screenY + heightDelta);
}
}
}
}
}
if (gAlertListener) {
gAlertListener.observe(null, "alertfinished", gAlertCookie);
window.close();
}
}
function onAlertClick() {
if (gAlertListener && gAlertTextClickable)
if (gAlertListener && gAlertTextClickable) {
gAlertListener.observe(null, "alertclickcallback", gAlertCookie);
closeAlert();
}
window.close();
}

View File

@ -3,6 +3,11 @@
- 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/. -->
<!DOCTYPE window [
<!ENTITY % alertDTD SYSTEM "chrome://alerts/locale/alert.dtd">
%alertDTD;
]>
<?xml-stylesheet href="chrome://global/content/alerts/alert.css" type="text/css"?>
<?xml-stylesheet href="chrome://global/skin/alerts/alert.css" type="text/css"?>
@ -12,22 +17,30 @@
xmlns:xhtml="http://www.w3.org/1999/xhtml"
xhtml:role="alert"
pack="start"
onload="onAlertLoad()"
onclick="onAlertClick();">
onload="onAlertLoad();"
onclick="onAlertClick();"
onbeforeunload="onAlertBeforeUnload();">
<script type="application/javascript" src="chrome://global/content/alerts/alert.js"/>
<box id="alertBox" class="alertBox">
<hbox id="alertImageBox" class="alertImageBox" align="center" pack="center">
<image id="alertImage"/>
</hbox>
<box>
<hbox id="alertImageBox" class="alertImageBox" align="center" pack="center">
<image id="alertImage"/>
</hbox>
<vbox id="alertTextBox" class="alertTextBox">
<label id="alertTitleLabel" class="alertTitle plain"/>
<label id="alertTextLabel" class="alertText plain"/>
<vbox id="alertTextBox" class="alertTextBox">
<label id="alertTitleLabel" class="alertTitle plain"/>
<label id="alertTextLabel" class="alertText plain"/>
</vbox>
</box>
<vbox class="alertCloseBox">
<toolbarbutton class="alertCloseButton"
tooltiptext="&closeAlert.tooltip;"
onclick="event.stopPropagation();"
oncommand="close();"/>
</vbox>
</box>
<!-- This method is called inline because we want to make sure we establish the width

View File

@ -0,0 +1,5 @@
<!-- 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/. -->
<!ENTITY closeAlert.tooltip "Close this notification">

View File

@ -113,6 +113,7 @@
locale/@AB_CD@/mozapps/xpinstall/xpinstallConfirm.dtd (%chrome/mozapps/extensions/xpinstallConfirm.dtd)
locale/@AB_CD@/mozapps/xpinstall/xpinstallConfirm.properties (%chrome/mozapps/extensions/xpinstallConfirm.properties)
% locale alerts @AB_CD@ %locale/@AB_CD@/alerts/
locale/@AB_CD@/alerts/alert.dtd (%chrome/alerts/alert.dtd)
locale/@AB_CD@/alerts/notificationNames.properties (%chrome/alerts/notificationNames.properties)
% locale cookie @AB_CD@ %locale/@AB_CD@/cookie/
locale/@AB_CD@/cookie/cookieAcceptDialog.dtd (%chrome/cookie/cookieAcceptDialog.dtd)

View File

@ -26,6 +26,10 @@
padding: 8px;
-moz-padding-start: 16px;
width: 255px;
}
.alertTextBox,
.alertCloseBox {
background-image: linear-gradient(rgba(255,255,255,0.2), rgba(255,255,255,0.1));
}
@ -37,6 +41,7 @@
#alertImage {
max-width: 48px;
max-height: 48px;
list-style-image: url(chrome://global/skin/alerts/notification-48.png);
}
#alertNotification[clickable="true"] {
@ -55,3 +60,15 @@ label {
.alertText[clickable="true"]:hover:active {
color: -moz-activehyperlinktext;
}
.alertCloseButton {
list-style-image: url("moz-icon://stock/gtk-close?size=button");
}
.alertCloseButton > .toolbarbutton-icon {
margin: -4px;
}
.alertCloseButton > .toolbarbutton-text {
display: none;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -34,6 +34,7 @@ toolkit.jar:
+ skin/classic/global/toolbarbutton.css
+ skin/classic/global/tree.css
+ skin/classic/global/alerts/alert.css (alerts/alert.css)
+ skin/classic/global/alerts/notification-48.png (alerts/notification-48.png)
+ skin/classic/global/console/console.css (console/console.css)
+ skin/classic/global/console/console.png (console/console.png)
+ skin/classic/global/console/console-toolbar.png (console/console-toolbar.png)

View File

@ -0,0 +1,100 @@
/* 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/. */
/* ===== alert.css =====================================================
== Styles specific to the alerts dialog.
======================================================================= */
@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;
}
.alertImageBox {
padding: 8px 0;
width: 64px;
background-image: linear-gradient(rgba(255,255,255,0.7), rgba(255,255,255,0.6));
-moz-border-end: 1px solid rgba(0,0,0,.1);
}
.alertTextBox {
padding: 8px;
-moz-padding-start: 16px;
width: 255px;
}
.alertTextBox,
.alertCloseBox {
background-image: linear-gradient(rgba(255,255,255,0.2), rgba(255,255,255,0.1));
}
.alertTitle {
font-weight: bold;
font-size: 110%;
}
#alertImage {
max-width: 48px;
max-height: 48px;
list-style-image: url(chrome://global/skin/alerts/notification-48.png);
}
#alertNotification[clickable="true"] {
cursor: pointer;
}
label {
cursor: inherit;
}
.alertText[clickable="true"] {
color: -moz-nativehyperlinktext;
text-decoration: underline;
}
.alertText[clickable="true"]:hover:active {
color: -moz-activehyperlinktext;
}
@keyframes alert-animation {
from {
opacity: 0;
}
6.25% {
opacity: 1;
}
93.75% {
opacity: 1;
}
to {
opacity: 0;
}
}
.alertCloseButton {
-moz-appearance: none;
padding: 0;
margin: 0 2px;
list-style-image: url("chrome://global/skin/icons/close.png");
border: none;
-moz-image-region: rect(0, 16px, 16px, 0);
}
.alertCloseButton > .toolbarbutton-text {
display: none;
}
.alertCloseButton:hover {
-moz-image-region: rect(0, 32px, 16px, 16px);
}
.alertCloseButton:hover:active {
-moz-image-region: rect(0, 48px, 16px, 32px);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -57,6 +57,8 @@ toolkit.jar:
* skin/classic/global/tree.css
* skin/classic/global/viewbuttons.css
skin/classic/global/wizard.css
skin/classic/global/alerts/alert.css (alerts/alert.css)
skin/classic/global/alerts/notification-48.png (alerts/notification-48.png)
skin/classic/global/arrow/arrow-dn-dis.gif (arrow/arrow-dn-dis.gif)
skin/classic/global/arrow/arrow-dn-dis.png (arrow/arrow-dn-dis.png)
skin/classic/global/arrow/arrow-dn-sharp.gif (arrow/arrow-dn-sharp.gif)

View File

@ -27,6 +27,10 @@
padding: 8px;
-moz-padding-start: 16px;
width: 255px;
}
.alertTextBox,
.alertCloseBox {
background-image: linear-gradient(rgba(255,255,255,0.2), rgba(255,255,255,0.1));
}
@ -38,6 +42,7 @@
#alertImage {
max-width: 48px;
max-height: 48px;
list-style-image: url(chrome://global/skin/alerts/notification-48.png);
}
#alertNotification[clickable="true"] {
@ -71,3 +76,24 @@ label {
opacity: 0;
}
}
.alertCloseButton {
list-style-image: url("chrome://global/skin/icons/close.png");
-moz-appearance: none;
-moz-image-region: rect(0, 16px, 16px, 0);
padding: 4px 2px;
border: none !important;
}
.alertCloseButton > .toolbarbutton-text {
display: none;
}
.alertCloseButton:hover {
-moz-image-region: rect(0, 32px, 16px, 16px);
}
.alertCloseButton:hover:active {
-moz-image-region: rect(0, 48px, 16px, 32px);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -61,6 +61,7 @@ toolkit.jar:
skin/classic/global/tree.css
skin/classic/global/wizard.css
skin/classic/global/alerts/alert.css (alerts/alert.css)
skin/classic/global/alerts/notification-48.png (alerts/notification-48.png)
skin/classic/global/arrow/arrow-dn.gif (arrow/arrow-dn.gif)
skin/classic/global/arrow/arrow-dn-dis.gif (arrow/arrow-dn-dis.gif)
skin/classic/global/arrow/arrow-dn-hov.gif (arrow/arrow-dn-hov.gif)
@ -239,6 +240,7 @@ toolkit.jar:
* skin/classic/aero/global/tree.css (tree-aero.css)
skin/classic/aero/global/wizard.css
skin/classic/aero/global/alerts/alert.css (alerts/alert.css)
skin/classic/aero/global/alerts/notification-48.png (alerts/notification-48.png)
skin/classic/aero/global/arrow/arrow-dn.gif (arrow/arrow-dn.gif)
skin/classic/aero/global/arrow/arrow-dn-dis.gif (arrow/arrow-dn-dis.gif)
skin/classic/aero/global/arrow/arrow-dn-hov.gif (arrow/arrow-dn-hov.gif)

View File

@ -371,6 +371,9 @@ nsLookAndFeel::GetIntImpl(IntID aID, int32_t &aResult)
case eIntID_MacLionTheme:
aResult = nsCocoaFeatures::OnLionOrLater();
break;
case eIntID_AlertNotificationOrigin:
aResult = NS_ALERT_TOP;
break;
case eIntID_TabFocusModel:
{
// we should probably cache this

View File

@ -540,6 +540,9 @@ nsLookAndFeel::GetIntImpl(IntID aID, int32_t &aResult)
aResult = 0;
res = NS_ERROR_NOT_IMPLEMENTED;
break;
case eIntID_AlertNotificationOrigin:
aResult = NS_ALERT_TOP;
break;
case eIntID_IMERawInputUnderlineStyle:
case eIntID_IMEConvertedTextUnderlineStyle:
aResult = NS_STYLE_TEXT_DECORATION_STYLE_SOLID;