Bug 1026444 fix error pages in social panels, r=markh

This commit is contained in:
Shane Caraveo 2014-12-19 12:41:09 -08:00
Родитель a30dcdfd1e
Коммит 86661a50ea
7 изменённых файлов: 193 добавлений и 85 удалений

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

@ -423,9 +423,6 @@ SocialFlyout = {
iframe.removeEventListener("load", documentLoaded, true);
cb();
}, true);
// Force a layout flush by calling .clientTop so
// that the docShell of this frame is created
iframe.clientTop;
Social.setErrorListener(iframe, SocialFlyout.setFlyoutErrorMessage.bind(SocialFlyout))
iframe.setAttribute("src", aURL);
} else {
@ -1299,11 +1296,11 @@ SocialStatus = {
}
},
_onclose: function() {
let notificationFrameId = "social-status-" + origin;
let frame = document.getElementById(notificationFrameId);
_onclose: function(frame) {
frame.removeEventListener("close", this._onclose, true);
frame.removeEventListener("click", this._onclick, true);
if (frame.socialErrorListener)
frame.socialErrorListener.remove();
},
_onclick: function() {
@ -1318,8 +1315,9 @@ SocialStatus = {
PanelFrame.showPopup(window, aToolbarButton, "social", origin,
provider.statusURL, provider.getPageSize("status"),
(frame) => {
frame.addEventListener("close", this._onclose, true);
frame.addEventListener("close", () => { SocialStatus._onclose(frame) }, true);
frame.addEventListener("click", this._onclick, true);
Social.setErrorListener(frame, this.setPanelErrorMessage.bind(this));
});
Services.telemetry.getHistogramById("SOCIAL_TOOLBAR_BUTTONS").add(1);
},

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

@ -204,18 +204,40 @@
});
}
}.bind(this);
contentWindow.addEventListener("socialMarkUpdate", markUpdate);
contentWindow.addEventListener("unload", function unload() {
let unload = () => {
contentWindow.removeEventListener("unload", unload);
contentWindow.removeEventListener("socialMarkUpdate", markUpdate);
});
if (this.content.socialErrorListener)
this.content.socialErrorListener.remove();
}
contentWindow.addEventListener("socialMarkUpdate", markUpdate);
contentWindow.addEventListener("unload", unload);
}
this.content.addEventListener("DOMContentLoaded", DOMContentLoaded, true);
Social.setErrorListener(this.content, this.setErrorMessage.bind(this));
this._loading = true;
this.content.setAttribute("src", endpoint);
]]></body>
</method>
<method name="setErrorMessage">
<parameter name="aNotificationFrame"/>
<body><![CDATA[
if (!aNotificationFrame)
return;
let src = aNotificationFrame.getAttribute("src");
aNotificationFrame.removeAttribute("src");
let origin = aNotificationFrame.getAttribute("origin");
aNotificationFrame.webNavigation.loadURI("about:socialerror?mode=tryAgainOnly&url=" +
encodeURIComponent(src) + "&origin=" +
encodeURIComponent(origin),
null, null, null, null);
// ensure the panel is open if error occurs on first click
this.openPanel();
]]></body>
</method>
<method name="openPanel">
<parameter name="aResetOnClose"/>
<body><![CDATA[

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

@ -11,47 +11,6 @@ function gc() {
let openChatWindow = Cu.import("resource://gre/modules/MozSocialAPI.jsm", {}).openChatWindow;
// Support for going on and offline.
// (via browser/base/content/test/browser_bookmark_titles.js)
let origProxyType = Services.prefs.getIntPref('network.proxy.type');
function toggleOfflineStatus(goOffline) {
// Bug 968887 fix. when going on/offline, wait for notification before continuing
let deferred = Promise.defer();
if (!goOffline) {
Services.prefs.setIntPref('network.proxy.type', origProxyType);
}
if (goOffline != Services.io.offline) {
info("initial offline state " + Services.io.offline);
let expect = !Services.io.offline;
Services.obs.addObserver(function offlineChange(subject, topic, data) {
Services.obs.removeObserver(offlineChange, "network:offline-status-changed");
info("offline state changed to " + Services.io.offline);
is(expect, Services.io.offline, "network:offline-status-changed successful toggle");
deferred.resolve();
}, "network:offline-status-changed", false);
BrowserOffline.toggleOfflineStatus();
} else {
deferred.resolve();
}
if (goOffline) {
Services.prefs.setIntPref('network.proxy.type', 0);
// LOAD_FLAGS_BYPASS_CACHE isn't good enough. So clear the cache.
Services.cache2.clear();
}
return deferred.promise;
}
function goOffline() {
// Simulate a network outage with offline mode. (Localhost is still
// accessible in offline mode, so disable the test proxy as well.)
return toggleOfflineStatus(true);
}
function goOnline(callback) {
return toggleOfflineStatus(false);
}
function openPanel(url, panelCallback, loadCallback) {
// open a flyout
SocialFlyout.open(url, 0, panelCallback);

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

@ -87,8 +87,7 @@ var tests = {
// we expect the addon install dialog to appear, we need to accept the
// install from the dialog.
let panel = document.getElementById("servicesInstall-notification");
PopupNotifications.panel.addEventListener("popupshown", function onpopupshown() {
PopupNotifications.panel.removeEventListener("popupshown", onpopupshown);
ensureEventFired(PopupNotifications.panel, "popupshown").then(() => {
info("servicesInstall-notification panel opened");
panel.button.click();
});
@ -121,8 +120,7 @@ var tests = {
testButtonOnEnable: function(next) {
let panel = document.getElementById("servicesInstall-notification");
PopupNotifications.panel.addEventListener("popupshown", function onpopupshown() {
PopupNotifications.panel.removeEventListener("popupshown", onpopupshown);
ensureEventFired(PopupNotifications.panel, "popupshown").then(() => {
info("servicesInstall-notification panel opened");
panel.button.click();
});
@ -187,8 +185,8 @@ var tests = {
// synthesize so the command event happens
EventUtils.synthesizeMouseAtCenter(btn, {});
// wait for the button to be marked, click to open panel
is(btn.panel.state, "closed", "panel should not be visible yet");
waitForCondition(function() btn.isMarked, function() {
is(btn.panel.state, "closed", "panel should not be visible yet");
EventUtils.synthesizeMouseAtCenter(btn, {});
}, "button is marked");
break;
@ -196,23 +194,21 @@ var tests = {
ok(true, "got the panel message " + e.data.result);
if (e.data.result == "shown") {
// unmark the page via the button in the page
let doc = btn.contentDocument;
let unmarkBtn = doc.getElementById("unmark");
ok(unmarkBtn, "got the panel unmark button");
EventUtils.sendMouseEvent({type: "click"}, unmarkBtn, btn.contentWindow);
ensureFrameLoaded(btn.content).then(() => {
let doc = btn.contentDocument;
let unmarkBtn = doc.getElementById("unmark");
ok(unmarkBtn, "testMarkPanel - got the panel unmark button");
EventUtils.sendMouseEvent({type: "click"}, unmarkBtn, btn.contentWindow);
});
} else {
// page should no longer be marked
port.close();
waitForCondition(function() !btn.isMarked, function() {
// cleanup after the page has been unmarked
gBrowser.tabContainer.addEventListener("TabClose", function onTabClose() {
gBrowser.tabContainer.removeEventListener("TabClose", onTabClose);
executeSoon(function () {
ok(btn.disabled, "button is disabled");
next();
});
ensureBrowserTabClosed(tab).then(() => {
ok(btn.disabled, "button is disabled");
next();
});
gBrowser.removeTab(tab);
}, "button unmarked");
}
break;
@ -222,6 +218,39 @@ var tests = {
});
},
testMarkPanelOffline: function(next) {
// click on panel to open and wait for visibility
let provider = Social._getProviderFromOrigin(manifest2.origin);
ok(provider.enabled, "provider is enabled");
let id = SocialMarks._toolbarHelper.idFromOrigin(manifest2.origin);
let widget = CustomizableUI.getWidget(id);
let btn = widget.forWindow(window).node;
ok(btn, "got a mark button");
// verify markbutton is disabled when there is no browser url
ok(btn.disabled, "button is disabled");
let activationURL = manifest2.origin + "/browser/browser/base/content/test/social/social_activate.html"
addTab(activationURL, function(tab) {
ok(!btn.disabled, "button is enabled");
goOffline().then(function() {
info("testing offline error page");
// wait for popupshown
ensureEventFired(btn.panel, "popupshown").then(() => {
info("marks panel is open");
ensureFrameLoaded(btn.content).then(() => {
is(btn.contentDocument.location.href.indexOf("about:socialerror?"), 0, "social error page is showing");
// cleanup after the page has been unmarked
ensureBrowserTabClosed(tab).then(() => {
ok(btn.disabled, "button is disabled");
goOnline().then(next);
});
});
});
btn.markCurrentPage();
});
});
},
testMarkPanelLoggedOut: function(next) {
// click on panel to open and wait for visibility
let provider = Social._getProviderFromOrigin(manifest2.origin);
@ -259,23 +288,21 @@ var tests = {
// our test marks the page during the load event (see
// social_mark.html) regardless of login state, unmark the page
// via the button in the page
let doc = btn.contentDocument;
let unmarkBtn = doc.getElementById("unmark");
ok(unmarkBtn, "got the panel unmark button");
EventUtils.sendMouseEvent({type: "click"}, unmarkBtn, btn.contentWindow);
ensureFrameLoaded(btn.content).then(() => {
let doc = btn.contentDocument;
let unmarkBtn = doc.getElementById("unmark");
ok(unmarkBtn, "testMarkPanelLoggedOut - got the panel unmark button");
EventUtils.sendMouseEvent({type: "click"}, unmarkBtn, btn.contentWindow);
});
} else {
// page should no longer be marked
port.close();
waitForCondition(function() !btn.isMarked, function() {
// cleanup after the page has been unmarked
gBrowser.tabContainer.addEventListener("TabClose", function onTabClose() {
gBrowser.tabContainer.removeEventListener("TabClose", onTabClose);
executeSoon(function () {
ok(btn.disabled, "button is disabled");
next();
});
ensureBrowserTabClosed(tab).then(() => {
ok(btn.disabled, "button is disabled");
next();
});
gBrowser.removeTab(tab);
}, "button unmarked");
}
break;
@ -323,11 +350,10 @@ var tests = {
}
info("INSTALLING " + manifest.origin);
let panel = document.getElementById("servicesInstall-notification");
PopupNotifications.panel.addEventListener("popupshown", function onpopupshown() {
PopupNotifications.panel.removeEventListener("popupshown", onpopupshown);
ensureEventFired(PopupNotifications.panel, "popupshown").then(() => {
info("servicesInstall-notification panel opened");
panel.button.click();
})
});
let activationURL = manifest.origin + "/browser/browser/base/content/test/social/social_activate.html"
let id = SocialMarks._toolbarHelper.idFromOrigin(manifest.origin);

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

@ -57,8 +57,7 @@ var tests = {
// we expect the addon install dialog to appear, we need to accept the
// install from the dialog.
let panel = document.getElementById("servicesInstall-notification");
PopupNotifications.panel.addEventListener("popupshown", function onpopupshown() {
PopupNotifications.panel.removeEventListener("popupshown", onpopupshown);
ensureEventFired(PopupNotifications.panel, "popupshown").then(() => {
info("servicesInstall-notification panel opened");
panel.button.click();
})
@ -89,8 +88,7 @@ var tests = {
},
testButtonOnEnable: function(next) {
let panel = document.getElementById("servicesInstall-notification");
PopupNotifications.panel.addEventListener("popupshown", function onpopupshown() {
PopupNotifications.panel.removeEventListener("popupshown", onpopupshown);
ensureEventFired(PopupNotifications.panel, "popupshown").then(() => {
info("servicesInstall-notification panel opened");
panel.button.click();
});
@ -165,6 +163,39 @@ var tests = {
};
port.postMessage({topic: "test-init"});
},
testPanelOffline: function(next) {
// click on panel to open and wait for visibility
let provider = Social._getProviderFromOrigin(manifest2.origin);
ok(provider.enabled, "provider is enabled");
let id = SocialStatus._toolbarHelper.idFromOrigin(manifest2.origin);
let widget = CustomizableUI.getWidget(id);
let btn = widget.forWindow(window).node;
ok(btn, "got a status button");
let frameId = btn.getAttribute("notificationFrameId");
let frame = document.getElementById(frameId);
let port = provider.getWorkerPort();
port.postMessage({topic: "test-init"});
goOffline().then(function() {
info("testing offline error page");
// wait for popupshown
let panel = document.getElementById("social-notification-panel");
ensureEventFired(panel, "popupshown").then(() => {
ensureFrameLoaded(frame).then(() => {
is(frame.contentDocument.location.href.indexOf("about:socialerror?"), 0, "social error page is showing "+frame.contentDocument.location.href);
panel.hidePopup();
goOnline().then(next);
});
});
// reload after going offline, wait for unload to open panel
ensureEventFired(frame, "unload").then(() => {
btn.click();
});
frame.contentDocument.location.reload();
});
},
testButtonOnDisable: function(next) {
// enable the provider now
let provider = Social._getProviderFromOrigin(manifest2.origin);

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

@ -395,6 +395,15 @@ function selectBrowserTab(tab, callback) {
gBrowser.selectedTab = tab;
}
function ensureEventFired(elem, event) {
let deferred = Promise.defer();
elem.addEventListener(event, function handler() {
elem.removeEventListener(event, handler, true);
deferred.resolve()
}, true);
return deferred.promise;
}
function loadIntoTab(tab, url, callback) {
tab.linkedBrowser.addEventListener("load", function tabLoad(event) {
tab.linkedBrowser.removeEventListener("load", tabLoad, true);
@ -403,6 +412,24 @@ function loadIntoTab(tab, url, callback) {
tab.linkedBrowser.loadURI(url);
}
function ensureBrowserTabClosed(tab) {
let promise = ensureEventFired(gBrowser.tabContainer, "TabClose");
gBrowser.removeTab(tab);
return promise;
}
function ensureFrameLoaded(frame) {
let deferred = Promise.defer();
if (frame.contentDocument && frame.contentDocument.readyState == "complete") {
deferred.resolve();
} else {
frame.addEventListener("load", function handler() {
frame.removeEventListener("load", handler, true);
deferred.resolve()
}, true);
}
return deferred.promise;
}
// chat test help functions
@ -593,3 +620,45 @@ function closeAllChats() {
chatbar.selectedChat.close();
}
}
// Support for going on and offline.
// (via browser/base/content/test/browser_bookmark_titles.js)
let origProxyType = Services.prefs.getIntPref('network.proxy.type');
function toggleOfflineStatus(goOffline) {
// Bug 968887 fix. when going on/offline, wait for notification before continuing
let deferred = Promise.defer();
if (!goOffline) {
Services.prefs.setIntPref('network.proxy.type', origProxyType);
}
if (goOffline != Services.io.offline) {
info("initial offline state " + Services.io.offline);
let expect = !Services.io.offline;
Services.obs.addObserver(function offlineChange(subject, topic, data) {
Services.obs.removeObserver(offlineChange, "network:offline-status-changed");
info("offline state changed to " + Services.io.offline);
is(expect, Services.io.offline, "network:offline-status-changed successful toggle");
deferred.resolve();
}, "network:offline-status-changed", false);
BrowserOffline.toggleOfflineStatus();
} else {
deferred.resolve();
}
if (goOffline) {
Services.prefs.setIntPref('network.proxy.type', 0);
// LOAD_FLAGS_BYPASS_CACHE isn't good enough. So clear the cache.
Services.cache2.clear();
}
return deferred.promise;
}
function goOffline() {
// Simulate a network outage with offline mode. (Localhost is still
// accessible in offline mode, so disable the test proxy as well.)
return toggleOfflineStatus(true);
}
function goOnline(callback) {
return toggleOfflineStatus(false);
}

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

@ -327,6 +327,9 @@ function SocialErrorListener(iframe, errorHandler) {
this.setErrorMessage = errorHandler;
this.iframe = iframe;
iframe.socialErrorListener = this;
// Force a layout flush by calling .clientTop so that the docShell of this
// frame is created for the error listener
iframe.clientTop;
iframe.docShell.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebProgress)
.addProgressListener(this,