Bug 911981 - Chat panels are lost while detaching/attaching, r=mixedpuppy.

This commit is contained in:
Florian Quèze 2014-01-14 23:08:20 +01:00
parent cc0f3db794
commit 75672b073a
2 changed files with 119 additions and 4 deletions

View File

@ -143,6 +143,7 @@
<parameter name="aTarget"/>
<body><![CDATA[
aTarget.setAttribute('label', this.contentDocument.title);
aTarget.src = this.src;
aTarget.content.setAttribute("origin", this.content.getAttribute("origin"));
aTarget.content.popupnotificationanchor.className = this.content.popupnotificationanchor.className;
this.content.socialErrorListener.remove();
@ -192,7 +193,16 @@
let win = findChromeWindowForChats();
let chatbar = win.SocialChatBar.chatbar;
chatbar.openChat(provider, "about:blank", win => {
this.swapDocShells(chatbar.selectedChat);
let cb = chatbar.selectedChat;
this.swapDocShells(cb);
// chatboxForURL is a map of URL -> chatbox used to avoid opening
// duplicate chat windows. Ensure reattached chat windows aren't
// registered with about:blank as their URL, otherwise reattaching
// more than one chat window isn't possible.
chatbar.chatboxForURL.delete("about:blank");
chatbar.chatboxForURL.set(this.src, Cu.getWeakReference(cb));
chatbar.focus();
this.close();
});
@ -503,7 +513,7 @@
this.menuitemMap.delete(aChatbox);
this.menupopup.removeChild(menuitem);
}
this.chatboxForURL.delete(aChatbox.getAttribute('src'));
this.chatboxForURL.delete(aChatbox.src);
]]></body>
</method>
@ -643,7 +653,8 @@
for (let name in aOptions)
options += "," + name + "=" + aOptions[name];
let otherWin = window.openDialog("chrome://browser/content/chatWindow.xul", null, "chrome,all,dialog=no" + options);
let otherWin = window.openDialog("chrome://browser/content/chatWindow.xul",
"_blank", "chrome,all,dialog=no" + options);
otherWin.addEventListener("load", function _chatLoad(event) {
if (event.target != otherWin.document)

View File

@ -199,4 +199,108 @@ var tests = {
port.postMessage({topic: "test-worker-chat", data: chatUrl});
},
}
testReattachTwice: function(next) {
let chats = document.getElementById("pinnedchats");
const chatUrl = "https://example.com/browser/browser/base/content/test/social/social_chat.html";
let chatBoxCount = 0, reattachCount = 0;
let port = Social.provider.getWorkerPort();
ok(port, "provider has a port");
port.postMessage({topic: "test-init"});
port.onmessage = function (e) {
let topic = e.data.topic;
switch (topic) {
case "got-chatbox-visibility":
// chatbox is open, lets detach. The new chat window will be caught in
// the window watcher below
let doc = chats.selectedChat.contentDocument;
// This message is (sometimes!) received a second time
// before we start our tests from the onCloseWindow
// callback.
if (doc.location == "about:blank")
return;
if (++chatBoxCount != 2) {
// open the second chat window
port.postMessage({topic: "test-worker-chat", data: chatUrl + "?id=2"});
return;
}
info("chatbox is open, detach from window");
let chat1 = chats.firstChild;
let chat2 = chat1.nextSibling;
document.getAnonymousElementByAttribute(chat1, "anonid", "swap").click();
document.getAnonymousElementByAttribute(chat2, "anonid", "swap").click();
break;
}
};
let firstChatWindowDoc;
Services.wm.addListener({
onWindowTitleChange: function() {},
onCloseWindow: function(xulwindow) {},
onOpenWindow: function(xulwindow) {
let listener = this;
let domwindow = xulwindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindow);
// wait for load to ensure the window is ready for us to test, make sure
// we're not getting called for about:blank
domwindow.addEventListener("load", function _load(event) {
let doc = domwindow.document;
if (event.target != doc)
return;
domwindow.removeEventListener("load", _load, false);
domwindow.addEventListener("unload", function _close(event) {
if (event.target != doc)
return;
domwindow.removeEventListener("unload", _close, false);
ok(true, "window has been closed");
waitForCondition(function() {
return chats.selectedChat && chats.selectedChat.contentDocument &&
chats.selectedChat.contentDocument.readyState == "complete";
}, function () {
++reattachCount;
if (reattachCount == 1) {
info("reattaching second chat window");
let chatbox = firstChatWindowDoc.getElementById("chatter");
firstChatWindowDoc.getAnonymousElementByAttribute(chatbox, "anonid", "swap").click();
firstChatWindowDoc = null;
}
else if (reattachCount == 2) {
is(chats.children.length, 2, "both chat windows should be reattached");
chats.removeAll();
waitForCondition(() => chats.children.length == 0, function () {
info("no chat window left");
is(chats.chatboxForURL.size, 0, "chatboxForURL map should be empty");
next();
});
}
}, "waited too long for the window to reattach");
}, false);
is(doc.documentElement.getAttribute("windowtype"), "Social:Chat", "Social:Chat window opened");
if (!firstChatWindowDoc) {
firstChatWindowDoc = doc;
return;
}
Services.wm.removeListener(listener);
// window is loaded, but the docswap does not happen until after load,
// and we have no event to wait on, so we'll wait for document state
// to be ready
let chatbox = doc.getElementById("chatter");
waitForCondition(function() {
return chats.children.length == 0 &&
chatbox.contentDocument &&
chatbox.contentDocument.readyState == "complete";
},function() {
info("reattaching chat window");
doc.getAnonymousElementByAttribute(chatbox, "anonid", "swap").click();
}, "waited too long for the chat window to be detached");
}, false);
}
});
port.postMessage({topic: "test-worker-chat", data: chatUrl + "?id=1"});
}
};