зеркало из https://github.com/mozilla/pjs.git
Bug 572967: don't remove notifications once dismissed, and instead allow them to be re-opened from the anchor icon, r=dolske
This commit is contained in:
Родитель
16f0a7a2da
Коммит
28d45e6b89
|
@ -326,6 +326,7 @@ window[chromehidden~="toolbar"] toolbar:not(.toolbar-primary):not(.chromeclass-m
|
|||
notifications are */
|
||||
.notification-anchor-icon {
|
||||
display: none;
|
||||
-moz-user-focus: normal;
|
||||
}
|
||||
|
||||
#notification-popup-box[anchorid="geo-notification-icon"] > #geo-notification-icon,
|
||||
|
|
|
@ -159,9 +159,13 @@ XPCOMUtils.defineLazyGetter(this, "Weave", function() {
|
|||
XPCOMUtils.defineLazyGetter(this, "PopupNotifications", function () {
|
||||
let tmp = {};
|
||||
Cu.import("resource://gre/modules/PopupNotifications.jsm", tmp);
|
||||
return new tmp.PopupNotifications(gBrowser,
|
||||
document.getElementById("notification-popup"),
|
||||
document.getElementById("notification-popup-box"));
|
||||
try {
|
||||
return new tmp.PopupNotifications(gBrowser,
|
||||
document.getElementById("notification-popup"),
|
||||
document.getElementById("notification-popup-box"));
|
||||
} catch (ex) {
|
||||
Cu.reportError(ex);
|
||||
}
|
||||
});
|
||||
|
||||
let gInitialPages = [
|
||||
|
|
|
@ -705,8 +705,8 @@
|
|||
onfocus="document.getElementById('identity-box').style.MozUserFocus= 'normal'"
|
||||
onblur="setTimeout(function() document.getElementById('identity-box').style.MozUserFocus = '', 0);">
|
||||
<box id="notification-popup-box" hidden="true" align="center">
|
||||
<image id="geo-notification-icon" class="notification-anchor-icon"/>
|
||||
<image id="addons-notification-icon" class="notification-anchor-icon"/>
|
||||
<image id="geo-notification-icon" class="notification-anchor-icon" role="button"/>
|
||||
<image id="addons-notification-icon" class="notification-anchor-icon" role="button"/>
|
||||
</box>
|
||||
<!-- Use onclick instead of normal popup= syntax since the popup
|
||||
code fires onmousedown, and hence eats our favicon drag events.
|
||||
|
|
|
@ -296,7 +296,7 @@ var tests = [
|
|||
this.firstNotification = showNotification(this.notifyObj);
|
||||
this.notifyObj2 = new basicNotification();
|
||||
this.notifyObj2.id += "-2";
|
||||
this.notifyObj2.anchorID = "urlbar";
|
||||
this.notifyObj2.anchorID = "addons-notification-icon";
|
||||
// Second showNotification() overrides the first
|
||||
this.secondNotification = showNotification(this.notifyObj2);
|
||||
},
|
||||
|
@ -485,15 +485,17 @@ function triggerSecondaryCommand(popup, index) {
|
|||
}
|
||||
|
||||
function loadURI(uri, callback) {
|
||||
gBrowser.addEventListener("load", function() {
|
||||
// Ignore the about:blank load
|
||||
if (gBrowser.currentURI.spec != uri)
|
||||
return;
|
||||
if (callback) {
|
||||
gBrowser.addEventListener("load", function() {
|
||||
// Ignore the about:blank load
|
||||
if (gBrowser.currentURI.spec != uri)
|
||||
return;
|
||||
|
||||
gBrowser.removeEventListener("load", arguments.callee, true);
|
||||
gBrowser.removeEventListener("load", arguments.callee, true);
|
||||
|
||||
callback();
|
||||
}, true);
|
||||
callback();
|
||||
}, true);
|
||||
}
|
||||
gBrowser.loadURI(uri);
|
||||
}
|
||||
|
||||
|
@ -502,4 +504,4 @@ function dismissNotification(popup) {
|
|||
executeSoon(function () {
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", {});
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1007,6 +1007,10 @@ toolbar[iconsize="small"] #fullscreen-button {
|
|||
height: 16px;
|
||||
}
|
||||
|
||||
.notification-anchor-icon:-moz-focusring {
|
||||
outline: 1px dotted -moz-DialogText;
|
||||
}
|
||||
|
||||
#geo-notification-icon {
|
||||
list-style-image: url(chrome://browser/skin/Geolocation-16.png);
|
||||
}
|
||||
|
|
|
@ -1868,6 +1868,11 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
|
|||
margin: 0 2px;
|
||||
}
|
||||
|
||||
.notification-anchor-icon:-moz-focusring {
|
||||
-moz-box-shadow: 0 0 3px 1px -moz-mac-focusring inset,
|
||||
0 0 3px 2px -moz-mac-focusring;
|
||||
}
|
||||
|
||||
#geo-notification-icon {
|
||||
list-style-image: url(chrome://browser/skin/Geolocation-16.png);
|
||||
}
|
||||
|
|
|
@ -1665,6 +1665,11 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] {
|
|||
height: 16px;
|
||||
}
|
||||
|
||||
.notification-anchor-icon:-moz-focusring {
|
||||
outline: 1px dotted -moz-DialogText;
|
||||
outline-offset: -3px;
|
||||
}
|
||||
|
||||
#geo-notification-icon {
|
||||
list-style-image: url(chrome://browser/skin/Geolocation-16.png);
|
||||
}
|
||||
|
|
|
@ -69,7 +69,7 @@ Notification.prototype = {
|
|||
get anchorElement() {
|
||||
let anchorElement = null;
|
||||
if (this.anchorID)
|
||||
anchorElement = this.owner.window.document.getElementById(this.anchorID);
|
||||
anchorElement = this.owner.iconBox.querySelector("#"+this.anchorID);
|
||||
|
||||
if (!anchorElement)
|
||||
anchorElement = this.owner.iconBox;
|
||||
|
@ -89,17 +89,32 @@ Notification.prototype = {
|
|||
* populated with <popupnotification> children and displayed it as
|
||||
* needed.
|
||||
* @param iconBox
|
||||
* Optional reference to a container element that should be hidden or
|
||||
* unhidden when notifications are hidden or shown. Used as a fallback
|
||||
* popup anchor if notifications do not specify anchor IDs.
|
||||
* Reference to a container element that should be hidden or
|
||||
* unhidden when notifications are hidden or shown. It should be the
|
||||
* parent of anchor elements whose IDs are passed to show().
|
||||
* It is used as a fallback popup anchor if notifications specify
|
||||
* invalid or non-existent anchor IDs.
|
||||
*/
|
||||
function PopupNotifications(tabbrowser, panel, iconBox) {
|
||||
if (!(tabbrowser instanceof Ci.nsIDOMXULElement))
|
||||
throw "Invalid tabbrowser";
|
||||
if (!(iconBox instanceof Ci.nsIDOMXULElement))
|
||||
throw "Invalid iconBox";
|
||||
if (!(panel instanceof Ci.nsIDOMXULElement))
|
||||
throw "Invalid panel";
|
||||
|
||||
this.window = tabbrowser.ownerDocument.defaultView;
|
||||
this.panel = panel;
|
||||
this.iconBox = iconBox;
|
||||
this.tabbrowser = tabbrowser;
|
||||
|
||||
let self = this;
|
||||
this.iconBox.addEventListener("click", function (event) {
|
||||
self._onIconBoxCommand(event);
|
||||
}, false);
|
||||
this.iconBox.addEventListener("keypress", function (event) {
|
||||
self._onIconBoxCommand(event);
|
||||
}, false);
|
||||
this.panel.addEventListener("popuphidden", function (event) {
|
||||
self._onPopupHidden(event);
|
||||
}, true);
|
||||
|
@ -171,6 +186,9 @@ PopupNotifications.prototype = {
|
|||
* dismiss for this many page loads.
|
||||
* timeout: A time in milliseconds. The notification will not
|
||||
* automatically dismiss before this time.
|
||||
* dismissed: Whether the notification should be added as a dismissed
|
||||
* notification. Dismissed notifications can be activated
|
||||
* by clicking on their anchorElement.
|
||||
* @returns the Notification object corresponding to the added notification.
|
||||
*/
|
||||
show: function PopupNotifications_show(browser, id, message, anchorID,
|
||||
|
@ -193,6 +211,8 @@ PopupNotifications.prototype = {
|
|||
let notification = new Notification(id, message, anchorID, mainAction,
|
||||
secondaryActions, browser, this, options);
|
||||
|
||||
if (options && options.dismissed)
|
||||
notification.dismissed = true;
|
||||
|
||||
let existingNotification = this.getNotification(id, browser);
|
||||
if (existingNotification)
|
||||
|
@ -366,19 +386,19 @@ PopupNotifications.prototype = {
|
|||
*/
|
||||
_update: function PopupNotifications_update(anchor) {
|
||||
let anchorElement, notificationsToShow = [];
|
||||
if (this._currentNotifications.length > 0) {
|
||||
let haveNotifications = this._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;
|
||||
|
||||
if (this.iconBox) {
|
||||
this.iconBox.hidden = false;
|
||||
this.iconBox.setAttribute("anchorid", anchorElement.id);
|
||||
}
|
||||
this.iconBox.hidden = false;
|
||||
this.iconBox.setAttribute("anchorid", anchorElement.id);
|
||||
|
||||
// Also filter out notifications that have been dismissed.
|
||||
notificationsToShow = this._currentNotifications.filter(function (n) {
|
||||
return n.anchorElement == anchorElement;
|
||||
return !n.dismissed && n.anchorElement == anchorElement;
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -390,7 +410,9 @@ PopupNotifications.prototype = {
|
|||
|
||||
this._hidePanel();
|
||||
|
||||
if (this.iconBox)
|
||||
// Only hide the iconBox if we actually have no notifications (as opposed
|
||||
// to not having any showable notifications)
|
||||
if (this.iconBox && !haveNotifications)
|
||||
this.iconBox.hidden = true;
|
||||
}
|
||||
},
|
||||
|
@ -402,14 +424,40 @@ PopupNotifications.prototype = {
|
|||
return browser.popupNotifications = [];
|
||||
},
|
||||
|
||||
_onIconBoxCommand: function PopupNotifications_onIconBoxCommand(event) {
|
||||
// Left click, space or enter only
|
||||
let type = event.type;
|
||||
if (type == "click" && event.button != 0)
|
||||
return;
|
||||
|
||||
if (type == "keypress" &&
|
||||
!(event.charCode == Ci.nsIDOMKeyEvent.DOM_VK_SPACE ||
|
||||
event.keyCode == Ci.nsIDOMKeyEvent.DOM_VK_RETURN))
|
||||
return;
|
||||
|
||||
if (this._currentNotifications.length == 0)
|
||||
return;
|
||||
|
||||
let anchor = event.originalTarget;
|
||||
|
||||
// Mark notifications anchored to this anchor as un-dismissed
|
||||
this._currentNotifications.forEach(function (n) {
|
||||
if (n.anchorElement == anchor)
|
||||
n.dismissed = false;
|
||||
});
|
||||
|
||||
// ...and then show them.
|
||||
this._update(anchor);
|
||||
},
|
||||
|
||||
_onPopupHidden: function PopupNotifications_onPopupHidden(event) {
|
||||
if (event.target != this.panel || this._ignoreDismissal)
|
||||
return;
|
||||
|
||||
// Remove notifications being dismissed
|
||||
// Mark notifications as dismissed
|
||||
Array.forEach(this.panel.childNodes, function (nEl) {
|
||||
let notificationObj = nEl.notification;
|
||||
this._remove(notificationObj);
|
||||
notificationObj.dismissed = true;
|
||||
}, this);
|
||||
|
||||
this._update();
|
||||
|
|
Загрузка…
Ссылка в новой задаче