bug 809085 make permissions panels work with social content, r=felipe

This commit is contained in:
Shane Caraveo
2013-06-21 16:14:22 -07:00
parent ae2b0f331e
commit eb553a84b0
10 changed files with 155 additions and 33 deletions

View File

@@ -1013,7 +1013,7 @@ SocialToolbar = {
if (tbi) { if (tbi) {
// SocialMark is the last button allways // SocialMark is the last button allways
let next = SocialMark.button.previousSibling; let next = SocialMark.button.previousSibling;
while (next != tbi.firstChild) { while (next != this.button) {
tbi.removeChild(next); tbi.removeChild(next);
next = SocialMark.button.previousSibling; next = SocialMark.button.previousSibling;
} }

View File

@@ -820,6 +820,10 @@ var gBrowserInit = {
// setup our MozApplicationManifest listener // setup our MozApplicationManifest listener
gBrowser.addEventListener("MozApplicationManifest", gBrowser.addEventListener("MozApplicationManifest",
OfflineApps, false); OfflineApps, false);
// listen for offline apps on social
let socialBrowser = document.getElementById("social-sidebar-browser");
socialBrowser.addEventListener("MozApplicationManifest",
OfflineApps, false);
// setup simple gestures support // setup simple gestures support
gGestureSupport.init(true); gGestureSupport.init(true);
@@ -5622,6 +5626,14 @@ var OfflineApps = {
if (browser.contentWindow == aContentWindow) if (browser.contentWindow == aContentWindow)
return browser; return browser;
} }
// handle other browser/iframe elements that may need popupnotifications
let browser = aContentWindow
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell)
.chromeEventHandler;
if (browser.getAttribute("popupnotificationanchor"))
return browser;
return null; return null;
}, },
@@ -5658,6 +5670,15 @@ var OfflineApps = {
} }
} }
// is this from a non-tab browser/iframe?
browsers = document.querySelectorAll("iframe[popupnotificationanchor] | browser[popupnotificationanchor]");
for (let browser of browsers) {
uri = this._getManifestURI(browser.contentWindow);
if (uri && uri.equals(aCacheUpdate.manifestURI)) {
return browser;
}
}
return null; return null;
}, },

View File

@@ -743,6 +743,9 @@
hidden="true" hidden="true"
skipintoolbarset="true" skipintoolbarset="true"
observes="socialActiveBroadcaster"> observes="socialActiveBroadcaster">
<toolbarbutton id="social-notification-icon" class="default-notification-icon toolbarbutton-1 notification-anchor-icon"
oncommand="PopupNotifications._reshowNotifications(this,
document.getElementById('social-sidebar-browser'));"/>
<toolbarbutton id="social-provider-button" <toolbarbutton id="social-provider-button"
class="toolbarbutton-1" class="toolbarbutton-1"
type="menu"> type="menu">
@@ -1082,6 +1085,7 @@
context="contentAreaContextMenu" context="contentAreaContextMenu"
disableglobalhistory="true" disableglobalhistory="true"
tooltip="aHTMLTooltip" tooltip="aHTMLTooltip"
popupnotificationanchor="social-notification-icon"
flex="1" flex="1"
style="min-width: 14em; width: 18em; max-width: 36em;"/> style="min-width: 14em; width: 18em; max-width: 36em;"/>
</vbox> </vbox>

View File

@@ -12,6 +12,8 @@
<xul:image class="chat-status-icon" xbl:inherits="src=image"/> <xul:image class="chat-status-icon" xbl:inherits="src=image"/>
<xul:label class="chat-title" flex="1" xbl:inherits="value=label" crop="center"/> <xul:label class="chat-title" flex="1" xbl:inherits="value=label" crop="center"/>
</xul:hbox> </xul:hbox>
<xul:toolbarbutton id="notification-icon" class="notification-anchor-icon chat-toolbarbutton"
oncommand="document.getBindingParent(this).showNotifications(); event.stopPropagation();"/>
<xul:toolbarbutton anonid="minimize" class="chat-minimize-button chat-toolbarbutton" <xul:toolbarbutton anonid="minimize" class="chat-minimize-button chat-toolbarbutton"
oncommand="document.getBindingParent(this).toggle();"/> oncommand="document.getBindingParent(this).toggle();"/>
<xul:toolbarbutton anonid="swap" class="chat-swap-button chat-toolbarbutton" <xul:toolbarbutton anonid="swap" class="chat-swap-button chat-toolbarbutton"
@@ -29,6 +31,8 @@
<implementation implements="nsIDOMEventListener"> <implementation implements="nsIDOMEventListener">
<constructor><![CDATA[ <constructor><![CDATA[
let Social = Components.utils.import("resource:///modules/Social.jsm", {}).Social; let Social = Components.utils.import("resource:///modules/Social.jsm", {}).Social;
this.content.__defineGetter__("popupnotificationanchor",
() => document.getAnonymousElementByAttribute(this, "id", "notification-icon"));
Social.setErrorListener(this.content, function(aBrowser) { Social.setErrorListener(this.content, function(aBrowser) {
aBrowser.webNavigation.loadURI("about:socialerror?mode=compactInfo", null, null, null, null); aBrowser.webNavigation.loadURI("about:socialerror?mode=compactInfo", null, null, null, null);
}); });
@@ -127,6 +131,13 @@
this.contentDocument.documentElement.dispatchEvent(evt); this.contentDocument.documentElement.dispatchEvent(evt);
</setter> </setter>
</property> </property>
<method name="showNotifications">
<body><![CDATA[
PopupNotifications._reshowNotifications(this.content.popupnotificationanchor,
this.content);
]]></body>
</method>
<method name="swapDocShells"> <method name="swapDocShells">
<parameter name="aTarget"/> <parameter name="aTarget"/>

View File

@@ -1673,6 +1673,13 @@ ContentPermissionPrompt.prototype = {
var requestingWindow = aRequest.window.top; var requestingWindow = aRequest.window.top;
var chromeWin = this._getChromeWindow(requestingWindow).wrappedJSObject; var chromeWin = this._getChromeWindow(requestingWindow).wrappedJSObject;
var browser = chromeWin.gBrowser.getBrowserForDocument(requestingWindow.document); var browser = chromeWin.gBrowser.getBrowserForDocument(requestingWindow.document);
if (!browser) {
// find the requesting browser or iframe
browser = requestingWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell)
.chromeEventHandler;
}
var requestPrincipal = aRequest.principal; var requestPrincipal = aRequest.principal;
// Transform the prompt actions into PopupNotification actions. // Transform the prompt actions into PopupNotification actions.

View File

@@ -1276,14 +1276,17 @@ toolbar[iconsize="small"] #webrtc-status-button {
outline: 1px dotted -moz-DialogText; outline: 1px dotted -moz-DialogText;
} }
.default-notification-icon,
#default-notification-icon { #default-notification-icon {
list-style-image: url(chrome://global/skin/icons/information-16.png); list-style-image: url(chrome://global/skin/icons/information-16.png);
} }
.identity-notification-icon,
#identity-notification-icon { #identity-notification-icon {
list-style-image: url(chrome://mozapps/skin/profile/profileicon.png); list-style-image: url(chrome://mozapps/skin/profile/profileicon.png);
} }
.geo-notification-icon,
#geo-notification-icon { #geo-notification-icon {
list-style-image: url(chrome://browser/skin/Geolocation-16.png); list-style-image: url(chrome://browser/skin/Geolocation-16.png);
} }
@@ -1292,6 +1295,7 @@ toolbar[iconsize="small"] #webrtc-status-button {
list-style-image: url(chrome://mozapps/skin/extensions/extensionGeneric-16.png); list-style-image: url(chrome://mozapps/skin/extensions/extensionGeneric-16.png);
} }
.indexedDB-notification-icon,
#indexedDB-notification-icon { #indexedDB-notification-icon {
list-style-image: url(chrome://global/skin/icons/question-16.png); list-style-image: url(chrome://global/skin/icons/question-16.png);
} }
@@ -1336,18 +1340,22 @@ toolbar[iconsize="small"] #webrtc-status-button {
} }
} }
.mixed-content-blocked-notification-icon,
#mixed-content-blocked-notification-icon { #mixed-content-blocked-notification-icon {
list-style-image: url(chrome://browser/skin/mixed-content-blocked-16.png); list-style-image: url(chrome://browser/skin/mixed-content-blocked-16.png);
} }
.webRTC-shareDevices-notification-icon,
#webRTC-shareDevices-notification-icon { #webRTC-shareDevices-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-shareDevice-16.png); list-style-image: url(chrome://browser/skin/webRTC-shareDevice-16.png);
} }
.webRTC-sharingDevices-notification-icon,
#webRTC-sharingDevices-notification-icon { #webRTC-sharingDevices-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-sharingDevice-16.png); list-style-image: url(chrome://browser/skin/webRTC-sharingDevice-16.png);
} }
.web-notifications-notification-icon,
#web-notifications-notification-icon { #web-notifications-notification-icon {
list-style-image: url(chrome://browser/skin/notification-16.png); list-style-image: url(chrome://browser/skin/notification-16.png);
} }

View File

@@ -3056,24 +3056,29 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
0 0 3px 2px -moz-mac-focusring; 0 0 3px 2px -moz-mac-focusring;
} }
.default-notification-icon,
#default-notification-icon { #default-notification-icon {
list-style-image: url(chrome://global/skin/icons/information-16.png); list-style-image: url(chrome://global/skin/icons/information-16.png);
} }
@media (min-resolution: 2dppx) { @media (min-resolution: 2dppx) {
.default-notification-icon,
#default-notification-icon { #default-notification-icon {
list-style-image: url(chrome://global/skin/icons/information-32.png); list-style-image: url(chrome://global/skin/icons/information-32.png);
} }
} }
.identity-notification-icon,
#identity-notification-icon { #identity-notification-icon {
list-style-image: url(chrome://mozapps/skin/profile/profileicon.png); list-style-image: url(chrome://mozapps/skin/profile/profileicon.png);
} }
/* XXX: need HiDPI version */ /* XXX: need HiDPI version */
.geo-notification-icon,
#geo-notification-icon { #geo-notification-icon {
list-style-image: url(chrome://browser/skin/Geolocation-16.png); list-style-image: url(chrome://browser/skin/Geolocation-16.png);
} }
@media (min-resolution: 2dppx) { @media (min-resolution: 2dppx) {
.geo-notification-icon,
#geo-notification-icon { #geo-notification-icon {
list-style-image: url(chrome://browser/skin/Geolocation-16@2x.png); list-style-image: url(chrome://browser/skin/Geolocation-16@2x.png);
} }
@@ -3083,10 +3088,12 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
-moz-margin-start: 0; /* override default label margin to match description margin */ -moz-margin-start: 0; /* override default label margin to match description margin */
} }
.indexedDB-notification-icon,
#indexedDB-notification-icon { #indexedDB-notification-icon {
list-style-image: url(chrome://global/skin/icons/question-16.png); list-style-image: url(chrome://global/skin/icons/question-16.png);
} }
@media (min-resolution: 2dppx) { @media (min-resolution: 2dppx) {
.indexedDB-notification-icon,
#indexedDB-notification-icon { #indexedDB-notification-icon {
list-style-image: url(chrome://global/skin/icons/question-32.png); list-style-image: url(chrome://global/skin/icons/question-32.png);
} }
@@ -3110,10 +3117,12 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
} }
} }
.webapps-notification-icon,
#webapps-notification-icon { #webapps-notification-icon {
list-style-image: url(chrome://browser/skin/webapps-16.png); list-style-image: url(chrome://browser/skin/webapps-16.png);
} }
@media (min-resolution: 2dppx) { @media (min-resolution: 2dppx) {
.webapps-notification-icon,
#webapps-notification-icon { #webapps-notification-icon {
list-style-image: url(chrome://browser/skin/webapps-16@2x.png); list-style-image: url(chrome://browser/skin/webapps-16@2x.png);
} }
@@ -3177,37 +3186,45 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
} }
} }
.webRTC-shareDevices-notification-icon,
#webRTC-shareDevices-notification-icon { #webRTC-shareDevices-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-shareDevice-16.png); list-style-image: url(chrome://browser/skin/webRTC-shareDevice-16.png);
} }
@media (min-resolution: 2dppx) { @media (min-resolution: 2dppx) {
.webRTC-shareDevices-notification-icon,
#webRTC-shareDevices-notification-icon { #webRTC-shareDevices-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-shareDevice-16@2x.png); list-style-image: url(chrome://browser/skin/webRTC-shareDevice-16@2x.png);
} }
} }
.webRTC-sharingDevices-notification-icon,
#webRTC-sharingDevices-notification-icon { #webRTC-sharingDevices-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-sharingDevice-16.png); list-style-image: url(chrome://browser/skin/webRTC-sharingDevice-16.png);
} }
@media (min-resolution: 2dppx) { @media (min-resolution: 2dppx) {
.webRTC-sharingDevices-notification-icon,
#webRTC-sharingDevices-notification-icon { #webRTC-sharingDevices-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-sharingDevice-16@2x.png); list-style-image: url(chrome://browser/skin/webRTC-sharingDevice-16@2x.png);
} }
} }
.web-notifications-notification-icon,
#web-notifications-notification-icon { #web-notifications-notification-icon {
list-style-image: url(chrome://browser/skin/notification-16.png); list-style-image: url(chrome://browser/skin/notification-16.png);
} }
@media (min-resolution: 2dppx) { @media (min-resolution: 2dppx) {
.web-notifications-notification-icon,
#web-notifications-notification-icon { #web-notifications-notification-icon {
list-style-image: url(chrome://browser/skin/notification-16@2x.png); list-style-image: url(chrome://browser/skin/notification-16@2x.png);
} }
} }
.pointerLock-notification-icon,
#pointerLock-notification-icon { #pointerLock-notification-icon {
list-style-image: url(chrome://browser/skin/pointerLock-16.png); list-style-image: url(chrome://browser/skin/pointerLock-16.png);
} }
@media (min-resolution: 2dppx) { @media (min-resolution: 2dppx) {
.pointerLock-notification-icon,
#pointerLock-notification-icon { #pointerLock-notification-icon {
list-style-image: url(chrome://browser/skin/pointerLock-16@2x.png); list-style-image: url(chrome://browser/skin/pointerLock-16@2x.png);
} }

View File

@@ -81,6 +81,11 @@ chatbar > chatbox > .chat-titlebar > .chat-swap-button:hover {
cursor: pointer; cursor: pointer;
} }
.chat-titlebar > .notification-anchor-icon {
margin-left: 2px;
margin-right: 2px;
}
.chat-titlebar[minimized="true"] { .chat-titlebar[minimized="true"] {
border-bottom: none; border-bottom: none;
} }

View File

@@ -2515,14 +2515,17 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] {
outline-offset: -3px; outline-offset: -3px;
} }
.default-notification-icon,
#default-notification-icon { #default-notification-icon {
list-style-image: url(chrome://global/skin/icons/information-16.png); list-style-image: url(chrome://global/skin/icons/information-16.png);
} }
.identity-notification-icon,
#identity-notification-icon { #identity-notification-icon {
list-style-image: url(chrome://mozapps/skin/profile/profileicon.png); list-style-image: url(chrome://mozapps/skin/profile/profileicon.png);
} }
.geo-notification-icon,
#geo-notification-icon { #geo-notification-icon {
list-style-image: url(chrome://browser/skin/Geolocation-16.png); list-style-image: url(chrome://browser/skin/Geolocation-16.png);
} }
@@ -2531,6 +2534,7 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] {
list-style-image: url(chrome://mozapps/skin/extensions/extensionGeneric-16.png); list-style-image: url(chrome://mozapps/skin/extensions/extensionGeneric-16.png);
} }
.indexedDB-notification-icon,
#indexedDB-notification-icon { #indexedDB-notification-icon {
list-style-image: url(chrome://global/skin/icons/question-16.png); list-style-image: url(chrome://global/skin/icons/question-16.png);
} }
@@ -2575,18 +2579,22 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] {
} }
} }
.mixed-content-blocked-notification-icon,
#mixed-content-blocked-notification-icon { #mixed-content-blocked-notification-icon {
list-style-image: url(chrome://browser/skin/mixed-content-blocked-16.png); list-style-image: url(chrome://browser/skin/mixed-content-blocked-16.png);
} }
.webRTC-shareDevices-notification-icon,
#webRTC-shareDevices-notification-icon { #webRTC-shareDevices-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-shareDevice-16.png); list-style-image: url(chrome://browser/skin/webRTC-shareDevice-16.png);
} }
.webRTC-sharingDevices-notification-icon,
#webRTC-sharingDevices-notification-icon { #webRTC-sharingDevices-notification-icon {
list-style-image: url(chrome://browser/skin/webRTC-sharingDevice-16.png); list-style-image: url(chrome://browser/skin/webRTC-sharingDevice-16.png);
} }
.web-notifications-notification-icon,
#web-notifications-notification-icon { #web-notifications-notification-icon {
list-style-image: url(chrome://browser/skin/notification-16.png); list-style-image: url(chrome://browser/skin/notification-16.png);
} }

View File

@@ -63,7 +63,17 @@ Notification.prototype = {
return null; return null;
let anchorElement = null; let anchorElement = null;
if (this.anchorID) let anchor = this.browser.getAttribute("popupnotificationanchor") ||
this.browser.popupnotificationanchor;
if (anchor) {
if (anchor instanceof Ci.nsIDOMXULElement) {
anchorElement = anchor;
} else {
anchorElement = iconBox.ownerDocument.getElementById(anchor);
}
}
if (!anchorElement && this.anchorID)
anchorElement = iconBox.querySelector("#"+this.anchorID); anchorElement = iconBox.querySelector("#"+this.anchorID);
// Use a default anchor icon if it's available // Use a default anchor icon if it's available
@@ -75,7 +85,7 @@ Notification.prototype = {
}, },
reshow: function() { reshow: function() {
this.owner._reshowNotificationForAnchor(this.anchorElement); this.owner._reshowNotifications(this.anchorElement, this.browser);
} }
}; };
@@ -254,9 +264,9 @@ PopupNotifications.prototype = {
notifications.push(notification); notifications.push(notification);
let fm = Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager); let fm = Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager);
if (browser == this.tabbrowser.selectedBrowser && fm.activeWindow == this.window) { if (browser.docShell.isActive && fm.activeWindow == this.window) {
// show panel now // show panel now
this._update(notification.anchorElement, true); this._update(notifications, notification.anchorElement, true);
} else { } else {
// Otherwise, update() will display the notification the next time the // Otherwise, update() will display the notification the next time the
// relevant tab/window is selected. // relevant tab/window is selected.
@@ -264,10 +274,16 @@ PopupNotifications.prototype = {
// If the tab is selected but the window is in the background, let the OS // If the tab is selected but the window is in the background, let the OS
// tell the user that there's a notification waiting in that window. // tell the user that there's a notification waiting in that window.
// At some point we might want to do something about background tabs here // At some point we might want to do something about background tabs here
// too. // too. When the user switches to this window, we'll show the panel if
if (!notification.dismissed && // this browser is a tab (thus showing the anchor icon). For
browser == this.tabbrowser.selectedBrowser) // non-tabbrowser browsers, we need to make the icon visible now or the
// user will not be able to open the panel.
if (!notification.dismissed && browser.docShell.isActive) {
this.window.getAttention(); this.window.getAttention();
if (notification.anchorElement.parentNode != this.iconBox) {
notification.anchorElement.setAttribute(ICON_ATTRIBUTE_SHOWING, "true");
}
}
// Notify observers that we're not showing the popup (useful for testing) // Notify observers that we're not showing the popup (useful for testing)
this._notify("backgroundShow"); this._notify("backgroundShow");
@@ -326,8 +342,8 @@ PopupNotifications.prototype = {
this._setNotificationsForBrowser(aBrowser, notifications); this._setNotificationsForBrowser(aBrowser, notifications);
if (aBrowser == this.tabbrowser.selectedBrowser) if (aBrowser.docShell.isActive)
this._update(); this._update(notifications);
}, },
/** /**
@@ -336,12 +352,12 @@ PopupNotifications.prototype = {
* The Notification object to remove. * The Notification object to remove.
*/ */
remove: function PopupNotifications_remove(notification) { remove: function PopupNotifications_remove(notification) {
let isCurrent = notification.browser == this.tabbrowser.selectedBrowser;
this._remove(notification); this._remove(notification);
// update the panel, if needed if (notification.browser.docShell.isActive) {
if (isCurrent) let notifications = this._getNotificationsForBrowser(notification.browser);
this._update(); this._update(notifications, notification.anchorElement);
}
}, },
handleEvent: function (aEvent) { handleEvent: function (aEvent) {
@@ -390,7 +406,7 @@ PopupNotifications.prototype = {
if (index == -1) if (index == -1)
return; return;
if (notification.browser == this.tabbrowser.selectedBrowser) if (notification.browser.docShell.isActive)
notification.anchorElement.removeAttribute(ICON_ATTRIBUTE_SHOWING); notification.anchorElement.removeAttribute(ICON_ATTRIBUTE_SHOWING);
// remove the notification // remove the notification
@@ -566,34 +582,54 @@ PopupNotifications.prototype = {
* Updates the notification state in response to window activation or tab * Updates the notification state in response to window activation or tab
* selection changes. * selection changes.
* *
* @param anchor is a XUL element reprensenting the anchor whose notifications * @param notifications an array of Notification instances. if null,
* should be shown. * notifications will be retrieved off the current
* browser tab
* @param anchor is a XUL element that the notifications panel will be
* anchored to
* @param dismissShowing if true, dismiss any currently visible notifications * @param dismissShowing if true, dismiss any currently visible notifications
* if there are no notifications to show. Otherwise, * if there are no notifications to show. Otherwise,
* currently displayed notifications will be left alone. * currently displayed notifications will be left alone.
*/ */
_update: function PopupNotifications_update(anchor, dismissShowing = false) { _update: function PopupNotifications_update(notifications, anchor, dismissShowing = false) {
if (this.iconBox) { let useIconBox = this.iconBox && (!anchor || anchor.parentNode == this.iconBox);
if (useIconBox) {
// hide icons of the previous tab. // hide icons of the previous tab.
this._hideIcons(); this._hideIcons();
} }
let anchorElement, notificationsToShow = []; let anchorElement = anchor, notificationsToShow = [];
let currentNotifications = this._currentNotifications; if (!notifications)
let haveNotifications = currentNotifications.length > 0; notifications = this._currentNotifications;
let haveNotifications = notifications.length > 0;
if (haveNotifications) { if (haveNotifications) {
// Only show the notifications that have the passed-in anchor (or the // Only show the notifications that have the passed-in anchor (or the
// first notification's anchor, if none was passed in). Other // first notification's anchor, if none was passed in). Other
// notifications will be shown once these are dismissed. // notifications will be shown once these are dismissed.
anchorElement = anchor || currentNotifications[0].anchorElement; anchorElement = anchor || notifications[0].anchorElement;
if (this.iconBox) { if (useIconBox) {
this._showIcons(currentNotifications); this._showIcons(notifications);
this.iconBox.hidden = false; this.iconBox.hidden = false;
} else if (anchorElement) {
anchorElement.setAttribute(ICON_ATTRIBUTE_SHOWING, "true");
// use the anchorID as a class along with the default icon class as a
// fallback if anchorID is not defined in CSS. We always use the first
// notifications icon, so in the case of multiple notifications we'll
// only use the default icon
if (anchorElement.classList.contains("notification-anchor-icon")) {
// remove previous icon classes
let className = anchorElement.className.replace(/([-\w]+-notification-icon\s?)/g,"")
className = "default-notification-icon " + className;
if (notifications.length == 1) {
className = notifications[0].anchorID + " " + className;
}
anchorElement.className = className;
}
} }
// Also filter out notifications that have been dismissed. // Also filter out notifications that have been dismissed.
notificationsToShow = currentNotifications.filter(function (n) { notificationsToShow = notifications.filter(function (n) {
return !n.dismissed && n.anchorElement == anchorElement && return !n.dismissed && n.anchorElement == anchorElement &&
!n.options.neverShow; !n.options.neverShow;
}); });
@@ -614,8 +650,12 @@ PopupNotifications.prototype = {
// Only hide the iconBox if we actually have no notifications (as opposed // Only hide the iconBox if we actually have no notifications (as opposed
// to not having any showable notifications) // to not having any showable notifications)
if (this.iconBox && !haveNotifications) if (!haveNotifications) {
this.iconBox.hidden = true; if (useIconBox)
this.iconBox.hidden = true;
else if (anchorElement)
anchorElement.removeAttribute(ICON_ATTRIBUTE_SHOWING);
}
} }
}, },
@@ -671,18 +711,19 @@ PopupNotifications.prototype = {
while (anchor && anchor.parentNode != this.iconBox) while (anchor && anchor.parentNode != this.iconBox)
anchor = anchor.parentNode; anchor = anchor.parentNode;
this._reshowNotificationForAnchor(anchor); this._reshowNotifications(anchor);
}, },
_reshowNotificationForAnchor: function PopupNotifications_reshowNotificationForAnchor(anchor) { _reshowNotifications: function PopupNotifications_reshowNotifications(anchor, browser) {
// Mark notifications anchored to this anchor as un-dismissed // Mark notifications anchored to this anchor as un-dismissed
this._currentNotifications.forEach(function (n) { let notifications = this._getNotificationsForBrowser(browser || this.tabbrowser.selectedBrowser);
notifications.forEach(function (n) {
if (n.anchorElement == anchor) if (n.anchorElement == anchor)
n.dismissed = false; n.dismissed = false;
}); });
// ...and then show them. // ...and then show them.
this._update(anchor); this._update(notifications, anchor);
}, },
_fireCallback: function PopupNotifications_fireCallback(n, event) { _fireCallback: function PopupNotifications_fireCallback(n, event) {