mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 11:55:49 +00:00
Bug 807997 - allow chats to open in any suitable top-level window. r=gavin
This commit is contained in:
parent
6a72436e40
commit
c76347ad1f
@ -250,10 +250,13 @@ let SocialChatBar = {
|
||||
if (!SocialUI.haveLoggedInUser())
|
||||
return false;
|
||||
let docElem = document.documentElement;
|
||||
let chromeless = docElem.getAttribute("disablechrome") ||
|
||||
docElem.getAttribute("chromehidden").indexOf("extrachrome") >= 0;
|
||||
let chromeless = docElem.getAttribute("chromehidden").indexOf("extrachrome") >= 0;
|
||||
return Social.uiVisible && !chromeless;
|
||||
},
|
||||
// Does this chatbar have any chats (whether minimized, collapsed or normal)
|
||||
get hasChats() {
|
||||
return !!this.chatbar.firstElementChild;
|
||||
},
|
||||
openChat: function(aProvider, aURL, aCallback, aMode) {
|
||||
if (this.isAvailable)
|
||||
this.chatbar.openChat(aProvider, aURL, aCallback, aMode);
|
||||
|
@ -434,6 +434,50 @@ var tests = {
|
||||
port.postMessage({topic: "test-init"});
|
||||
},
|
||||
|
||||
testChatWindowChooser: function(next) {
|
||||
// Tests that when a worker creates a chat, it is opened in the correct
|
||||
// window.
|
||||
const chatUrl = "https://example.com/browser/browser/base/content/test/social_chat.html";
|
||||
let chatId = 1;
|
||||
let port = Social.provider.getWorkerPort();
|
||||
port.postMessage({topic: "test-init"});
|
||||
|
||||
function openChat(callback) {
|
||||
port.onmessage = function(e) {
|
||||
if (e.data.topic == "got-chatbox-message")
|
||||
callback();
|
||||
}
|
||||
let url = chatUrl + "?" + (chatId++);
|
||||
port.postMessage({topic: "test-worker-chat", data: url});
|
||||
}
|
||||
|
||||
// open a chat (it will open in the main window)
|
||||
ok(!window.SocialChatBar.hasChats, "first window should start with no chats");
|
||||
openChat(function() {
|
||||
ok(window.SocialChatBar.hasChats, "first window has the chat");
|
||||
// create a second window - although this will be the "most recent",
|
||||
// the fact the first window has a chat open means the first will be targetted.
|
||||
let secondWindow = OpenBrowserWindow();
|
||||
secondWindow.addEventListener("load", function loadListener() {
|
||||
secondWindow.removeEventListener("load", loadListener);
|
||||
ok(!secondWindow.SocialChatBar.hasChats, "second window has no chats");
|
||||
openChat(function() {
|
||||
ok(!secondWindow.SocialChatBar.hasChats, "second window still has no chats");
|
||||
is(window.SocialChatBar.chatbar.childElementCount, 2, "first window now has 2 chats");
|
||||
window.SocialChatBar.chatbar.removeAll();
|
||||
// now open another chat - it should open in the second window (as
|
||||
// it is the "most recent" and no other windows have chats)
|
||||
openChat(function() {
|
||||
ok(!window.SocialChatBar.hasChats, "first window has no chats");
|
||||
ok(secondWindow.SocialChatBar.hasChats, "second window has a chat");
|
||||
secondWindow.close();
|
||||
next();
|
||||
});
|
||||
});
|
||||
})
|
||||
});
|
||||
},
|
||||
|
||||
// XXX - note this must be the last test until we restore the login state
|
||||
// between tests...
|
||||
testCloseOnLogout: function(next) {
|
||||
|
@ -249,12 +249,51 @@ function ensureProviderOrigin(provider, url) {
|
||||
return fullURL;
|
||||
}
|
||||
|
||||
function isWindowGoodForChats(win) {
|
||||
return win.SocialChatBar && win.SocialChatBar.isAvailable;
|
||||
}
|
||||
|
||||
function findChromeWindowForChats(preferredWindow) {
|
||||
if (preferredWindow && isWindowGoodForChats(preferredWindow))
|
||||
return preferredWindow;
|
||||
// no good - so let's go hunting. We are now looking for a navigator:browser
|
||||
// window that is suitable and already has chats open, or failing that,
|
||||
// any suitable navigator:browser window.
|
||||
let first, best, enumerator;
|
||||
// *sigh* - getZOrderDOMWindowEnumerator is broken everywhere other than
|
||||
// Windows. We use BROKEN_WM_Z_ORDER as that is what the c++ code uses
|
||||
// and a few bugs recommend searching mxr for this symbol to identify the
|
||||
// workarounds - we want this code to be hit in such searches.
|
||||
const BROKEN_WM_Z_ORDER = Services.appinfo.OS != "WINNT";
|
||||
if (BROKEN_WM_Z_ORDER) {
|
||||
// this is oldest to newest and no way to change the order.
|
||||
enumerator = Services.wm.getEnumerator("navigator:browser");
|
||||
} else {
|
||||
// here we explicitly ask for bottom-to-top so we can use the same logic
|
||||
// where BROKEN_WM_Z_ORDER is true.
|
||||
enumerator = Services.wm.getZOrderDOMWindowEnumerator("navigator:browser", false);
|
||||
}
|
||||
while (enumerator.hasMoreElements()) {
|
||||
let win = enumerator.getNext();
|
||||
if (win && isWindowGoodForChats(win)) {
|
||||
first = win;
|
||||
if (win.SocialChatBar.hasChats)
|
||||
best = win;
|
||||
}
|
||||
}
|
||||
return best || first;
|
||||
}
|
||||
|
||||
this.openChatWindow =
|
||||
function openChatWindow(chromeWindow, provider, url, callback, mode) {
|
||||
if (!chromeWindow.SocialChatBar)
|
||||
chromeWindow = findChromeWindowForChats(chromeWindow);
|
||||
if (!chromeWindow)
|
||||
return;
|
||||
let fullURL = ensureProviderOrigin(provider, url);
|
||||
if (!fullURL)
|
||||
return;
|
||||
chromeWindow.SocialChatBar.openChat(provider, fullURL, callback, mode);
|
||||
// getAttention is ignored if the target window is already foreground, so
|
||||
// we can call it unconditionally.
|
||||
chromeWindow.getAttention();
|
||||
}
|
||||
|
@ -80,8 +80,7 @@ WorkerAPI.prototype = {
|
||||
data: results});
|
||||
},
|
||||
'social.request-chat': function(data) {
|
||||
let xulWindow = Services.wm.getMostRecentWindow("navigator:browser").getTopWin();
|
||||
openChatWindow(xulWindow, this._provider, data, null, "minimized");
|
||||
openChatWindow(null, this._provider, data, null, "minimized");
|
||||
},
|
||||
'social.notification-create': function(data) {
|
||||
if (!Services.prefs.getBoolPref("social.toast-notifications.enabled"))
|
||||
|
Loading…
Reference in New Issue
Block a user