Bug 624843: PopupNotifications need to work after customizing the location bar, r=dolske, a=blocking

This commit is contained in:
Gavin Sharp 2011-01-18 00:11:08 -08:00
Родитель 13b5e05893
Коммит 25a4fc8408
5 изменённых файлов: 83 добавлений и 20 удалений

Просмотреть файл

@ -3542,6 +3542,12 @@ function BrowserToolboxCustomizeDone(aToolboxChanged) {
#ifndef XP_MACOSX
updateEditUIVisibility();
#endif
// Hacky: update the PopupNotifications' object's reference to the iconBox,
// if it already exists, since it may have changed if the URL bar was
// added/removed.
if (!__lookupGetter__("PopupNotifications"))
PopupNotifications.iconBox = document.getElementById("notification-popup-box");
}
PlacesToolbarHelper.customizeDone();

Просмотреть файл

@ -170,6 +170,7 @@ _BROWSER_FILES = \
browser_bug624734.js \
browser_contextSearchTabPosition.js \
browser_ctrlTab.js \
browser_customize_popupNotification.js \
browser_disablechrome.js \
browser_discovery.js \
browser_duplicateIDs.js \

Просмотреть файл

@ -0,0 +1,29 @@
/*
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
*/
function test() {
waitForExplicitFinish();
var newWin = openDialog(location, "", "chrome,all,dialog=no", "about:blank");
registerCleanupFunction(function () {
newWin.close();
});
newWin.addEventListener("load", function test_win_onLoad() {
// Remove the URL bar
newWin.gURLBar.parentNode.removeChild(newWin.gURLBar);
waitForFocus(function () {
let PN = newWin.PopupNotifications;
try {
let notification = PN.show(newWin.gBrowser.selectedBrowser, "some-notification", "Some message");
ok(notification, "showed the notification");
ok(PN.isPanelOpen, "panel is open");
is(PN.panel.anchorNode, newWin.gBrowser.selectedTab, "notification is correctly anchored to the tab");
} catch (ex) {
ok(false, "threw exception: " + ex);
}
finish();
}, newWin);
}, false);
}

Просмотреть файл

@ -58,6 +58,7 @@ function cleanUp() {
var gActiveListeners = {};
var gActiveObservers = {};
var gShownState = {};
function runNextTest() {
let nextTest = tests[gTestIndex];
@ -91,6 +92,7 @@ function runNextTest() {
info("[Test #" + gTestIndex + "] popup showing");
});
doOnPopupEvent("popupshown", function () {
gShownState[gTestIndex] = true;
info("[Test #" + gTestIndex + "] popup shown");
nextTest.onShown(this);
});
@ -101,6 +103,11 @@ function runNextTest() {
nextTest.onHidden :
[nextTest.onHidden];
doOnPopupEvent("popuphidden", function () {
if (!gShownState[gTestIndex]) {
// This is expected to happen for test 9, so let's not treat it as a failure.
info("Popup from test " + gTestIndex + " was hidden before its popupshown fired");
}
let onHidden = onHiddenArray.shift();
info("[Test #" + gTestIndex + "] popup hidden (" + onHiddenArray.length + " hides remaining)");
onHidden.call(nextTest, this);

Просмотреть файл

@ -68,6 +68,9 @@ Notification.prototype = {
},
get anchorElement() {
if (!this.owner.iconBox)
return null;
let anchorElement = null;
if (this.anchorID)
anchorElement = this.owner.iconBox.querySelector("#"+this.anchorID);
@ -99,27 +102,21 @@ Notification.prototype = {
function PopupNotifications(tabbrowser, panel, iconBox) {
if (!(tabbrowser instanceof Ci.nsIDOMXULElement))
throw "Invalid tabbrowser";
if (!(iconBox instanceof Ci.nsIDOMXULElement))
if (iconBox && !(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);
this._onIconBoxCommand = this._onIconBoxCommand.bind(this);
this.iconBox = iconBox;
this.panel.addEventListener("popuphidden", this._onPopupHidden.bind(this), true);
let self = this;
function updateFromListeners() {
// setTimeout(..., 0) needed, otherwise openPopup from "activate" event
// handler results in the popup being hidden again for some reason...
@ -132,6 +129,22 @@ function PopupNotifications(tabbrowser, panel, iconBox) {
}
PopupNotifications.prototype = {
set iconBox(iconBox) {
// Remove the listeners on the old iconBox, if needed
if (this._iconBox) {
this._iconBox.removeEventListener("click", this._onIconBoxCommand, false);
this._iconBox.removeEventListener("keypress", this._onIconBoxCommand, false);
}
this._iconBox = iconBox;
if (iconBox) {
iconBox.addEventListener("click", this._onIconBoxCommand, false);
iconBox.addEventListener("keypress", this._onIconBoxCommand, false);
}
},
get iconBox() {
return this._iconBox;
},
/**
* Retrieve a Notification object associated with the browser/ID pair.
* @param id
@ -419,12 +432,17 @@ PopupNotifications.prototype = {
// safe to call even if the panel is already hidden.)
this._hidePanel();
// If the anchor element is hidden, use the tab as the anchor. We only ever
// show notifications for the current browser, so we can just use the
// current tab.
let bo = anchorElement.boxObject;
if (bo.height == 0 && bo.width == 0)
anchorElement = this.tabbrowser.selectedTab;
// If the anchor element is hidden or null, use the tab as the anchor. We
// only ever show notifications for the current browser, so we can just use
// the current tab.
let selectedTab = this.tabbrowser.selectedTab;
if (anchorElement) {
let bo = anchorElement.boxObject;
if (bo.height == 0 && bo.width == 0)
anchorElement = selectedTab; // hidden
} else {
anchorElement = selectedTab; // null
}
this._currentAnchorElement = anchorElement;
@ -447,8 +465,10 @@ PopupNotifications.prototype = {
// notifications will be shown once these are dismissed.
anchorElement = anchor || this._currentNotifications[0].anchorElement;
this.iconBox.hidden = false;
this.iconBox.setAttribute("anchorid", anchorElement.id);
if (this.iconBox) {
this.iconBox.hidden = false;
this.iconBox.setAttribute("anchorid", anchorElement.id);
}
// Also filter out notifications that have been dismissed.
notificationsToShow = this._currentNotifications.filter(function (n) {