Bug 641892 - Support showing multiple popup notification icons at the same time. r=margaret

This commit is contained in:
OHZEKI Tetsuharu 2012-05-03 18:33:47 -04:00
parent fd49ebbe60
commit 39aba4daa3
5 changed files with 119 additions and 18 deletions

View File

@ -430,20 +430,11 @@ window[chromehidden~="toolbar"] toolbar:not(.toolbar-primary):not(.chromeclass-m
/* notification anchors should only be visible when their associated
notifications are */
.notification-anchor-icon {
display: none;
-moz-user-focus: normal;
}
/* We use the iconBox as the notification anchor when a popup notification is
created with a null anchorID, so in that case use a default anchor icon. */
#notification-popup-box[anchorid="notification-popup-box"] > #default-notification-icon,
#notification-popup-box[anchorid="geo-notification-icon"] > #geo-notification-icon,
#notification-popup-box[anchorid="indexedDB-notification-icon"] > #indexedDB-notification-icon,
#notification-popup-box[anchorid="addons-notification-icon"] > #addons-notification-icon,
#notification-popup-box[anchorid="password-notification-icon"] > #password-notification-icon,
#notification-popup-box[anchorid="webapps-notification-icon"] > #webapps-notification-icon,
#notification-popup-box[anchorid="plugins-notification-icon"] > #plugins-notification-icon {
display: -moz-box;
.notification-anchor-icon:not([showing]) {
display: none;
}
#invalid-form-popup > description {

View File

@ -642,6 +642,84 @@ var tests = [
ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered");
}
},
// Test multiple notification icons are shown
{ // Test #21
run: function () {
this.notifyObj1 = new basicNotification();
this.notifyObj1.id += "_1";
this.notifyObj1.anchorID = "default-notification-icon";
this.notification1 = showNotification(this.notifyObj1);
this.notifyObj2 = new basicNotification();
this.notifyObj2.id += "_2";
this.notifyObj2.anchorID = "geo-notification-icon";
this.notification2 = showNotification(this.notifyObj2);
},
onShown: function (popup) {
checkPopup(popup, this.notifyObj2);
// check notifyObj1 anchor icon is showing
isnot(document.getElementById("default-notification-icon").boxObject.width, 0,
"default anchor should be visible");
// check notifyObj2 anchor icon is showing
isnot(document.getElementById("geo-notification-icon").boxObject.width, 0,
"geo anchor should be visible");
dismissNotification(popup);
},
onHidden: [
function (popup) {
},
function (popup) {
this.notification1.remove();
ok(this.notifyObj1.removedCallbackTriggered, "removed callback triggered");
this.notification2.remove();
ok(this.notifyObj2.removedCallbackTriggered, "removed callback triggered");
}
],
},
// Test that multiple notification icons are removed when switching tabs
{ // Test #22
run: function () {
// show the notification on old tab.
this.notifyObjOld = new basicNotification();
this.notifyObjOld.anchorID = "default-notification-icon";
this.notificationOld = showNotification(this.notifyObjOld);
// switch tab
this.oldSelectedTab = gBrowser.selectedTab;
gBrowser.selectedTab = gBrowser.addTab("about:blank");
// show the notification on new tab.
this.notifyObjNew = new basicNotification();
this.notifyObjNew.anchorID = "geo-notification-icon";
this.notificationNew = showNotification(this.notifyObjNew);
},
onShown: function (popup) {
checkPopup(popup, this.notifyObjNew);
// check notifyObjOld anchor icon is removed
is(document.getElementById("default-notification-icon").boxObject.width, 0,
"default anchor shouldn't be visible");
// check notifyObjNew anchor icon is showing
isnot(document.getElementById("geo-notification-icon").boxObject.width, 0,
"geo anchor should be visible");
dismissNotification(popup);
},
onHidden: [
function (popup) {
},
function (popup) {
this.notificationNew.remove();
gBrowser.removeTab(gBrowser.selectedTab);
gBrowser.selectedTab = this.oldSelectedTab;
this.notificationOld.remove();
}
],
}
];
function showNotification(notifyObj) {

View File

@ -1260,6 +1260,7 @@ toolbar[iconsize="small"] #feed-button {
.notification-anchor-icon {
width: 16px;
height: 16px;
margin: 0 2px;
}
.notification-anchor-icon:-moz-focusring {

View File

@ -2321,6 +2321,7 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] {
.notification-anchor-icon {
width: 16px;
height: 16px;
margin: 0 2px;
}
.notification-anchor-icon:-moz-focusring {

View File

@ -46,6 +46,9 @@ const NOTIFICATION_EVENT_DISMISSED = "dismissed";
const NOTIFICATION_EVENT_REMOVED = "removed";
const NOTIFICATION_EVENT_SHOWN = "shown";
const ICON_SELECTOR = ".notification-anchor-icon";
const ICON_ATTRIBUTE_SHOWING = "showing";
/**
* Notification object describes a single popup notification.
*
@ -82,15 +85,18 @@ Notification.prototype = {
},
get anchorElement() {
if (!this.owner.iconBox)
let iconBox = this.owner.iconBox;
if (!iconBox)
return null;
let anchorElement = null;
if (this.anchorID)
anchorElement = this.owner.iconBox.querySelector("#"+this.anchorID);
anchorElement = iconBox.querySelector("#"+this.anchorID);
// Use a default anchor icon if it's available
if (!anchorElement)
anchorElement = this.owner.iconBox;
anchorElement = iconBox.querySelector("#default-notification-icon") ||
iconBox;
return anchorElement;
}
@ -393,6 +399,8 @@ PopupNotifications.prototype = {
if (index == -1)
return;
notification.anchorElement.removeAttribute(ICON_ATTRIBUTE_SHOWING);
// remove the notification
notifications.splice(index, 1);
this._fireCallback(notification, NOTIFICATION_EVENT_REMOVED);
@ -502,21 +510,27 @@ PopupNotifications.prototype = {
* selection changes.
*/
_update: function PopupNotifications_update(anchor) {
if (this.iconBox) {
// hide icons of the previous tab.
this._hideIcons();
}
let anchorElement, notificationsToShow = [];
let haveNotifications = this._currentNotifications.length > 0;
let currentNotifications = this._currentNotifications;
let haveNotifications = currentNotifications.length > 0;
if (haveNotifications) {
// Only show the notifications that have the passed-in anchor (or the
// first notification's anchor, if none was passed in). Other
// notifications will be shown once these are dismissed.
anchorElement = anchor || this._currentNotifications[0].anchorElement;
anchorElement = anchor || currentNotifications[0].anchorElement;
if (this.iconBox) {
this._showIcons(currentNotifications);
this.iconBox.hidden = false;
this.iconBox.setAttribute("anchorid", anchorElement.id);
}
// Also filter out notifications that have been dismissed.
notificationsToShow = this._currentNotifications.filter(function (n) {
notificationsToShow = currentNotifications.filter(function (n) {
return !n.dismissed && n.anchorElement == anchorElement &&
!n.options.neverShow;
});
@ -539,6 +553,22 @@ PopupNotifications.prototype = {
}
},
_showIcons: function PopupNotifications_showIcons(aCurrentNotifications) {
for (let notification of aCurrentNotifications) {
let anchorElm = notification.anchorElement;
if (anchorElm) {
anchorElm.setAttribute(ICON_ATTRIBUTE_SHOWING, "true");
}
}
},
_hideIcons: function PopupNotifications_hideIcons() {
let icons = this.iconBox.querySelectorAll(ICON_SELECTOR);
for (let icon of icons) {
icon.removeAttribute(ICON_ATTRIBUTE_SHOWING);
}
},
_getNotificationsForBrowser: function PopupNotifications_getNotifications(browser) {
if (browser.popupNotifications)
return browser.popupNotifications;