Revision control

Copy as Markdown

Other Tools

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at http://mozilla.org/MPL/2.0/. */
var { MailServices } = ChromeUtils.importESModule(
);
var { MailUtils } = ChromeUtils.importESModule(
);
var { MessageGenerator } = ChromeUtils.importESModule(
);
let folderA, messagesA, folderB, messagesB;
add_setup(async function () {
const tabmail = document.getElementById("tabmail");
Assert.equal(tabmail.tabInfo.length, 1, "should be set up with one tab");
tabmail.closeOtherTabs(0);
const generator = new MessageGenerator();
const account = MailServices.accounts.createLocalMailAccount();
const rootFolder = account.incomingServer.rootFolder.QueryInterface(
Ci.nsIMsgLocalMailFolder
);
folderA = rootFolder
.createLocalSubfolder("mailTabsA")
.QueryInterface(Ci.nsIMsgLocalMailFolder);
folderA.addMessageBatch(
generator
.makeMessages({ count: 5 })
.map(message => message.toMessageString())
);
messagesA = [...folderA.messages];
folderB = rootFolder
.createLocalSubfolder("mailTabsB")
.QueryInterface(Ci.nsIMsgLocalMailFolder);
folderB.addMessageBatch(
generator
.makeMessages({ count: 2 })
.map(message => message.toMessageString())
);
messagesB = [...folderB.messages];
registerCleanupFunction(() => {
Services.prefs.clearUserPref("mail.tabs.loadInBackground");
MailServices.accounts.removeAccount(account, false);
});
});
add_task(async function testTabs() {
const tabmail = document.getElementById("tabmail");
Assert.equal(tabmail.tabInfo.length, 1, "should start off with one tab open");
Assert.deepEqual(
tabmail.tabInfo.map(t => t.selected),
[true]
);
Assert.equal(tabmail.currentTabInfo, tabmail.tabInfo[0], "should show tab 0");
info("Check the first tab.");
const firstTab = tabmail.currentTabInfo;
Assert.equal(firstTab.mode.name, "mail3PaneTab");
Assert.equal(firstTab.mode.tabType.name, "mailTab");
const firstChromeBrowser = firstTab.chromeBrowser;
Assert.equal(firstChromeBrowser.currentURI.spec, "about:3pane");
Assert.equal(tabmail.currentAbout3Pane, firstChromeBrowser.contentWindow);
const firstWebBrowser =
firstChromeBrowser.contentDocument.getElementById("webBrowser");
const firstMultiMessageBrowser =
firstChromeBrowser.contentDocument.getElementById("multiMessageBrowser");
const firstMessageBrowser =
firstChromeBrowser.contentDocument.getElementById("messageBrowser");
Assert.equal(firstMessageBrowser.currentURI.spec, "about:message");
const firstMessagePane =
firstMessageBrowser.contentDocument.getElementById("messagepane");
Assert.equal(firstMessagePane.currentURI.spec, "about:blank");
Assert.equal(
tabmail.currentAboutMessage,
null,
"currentAboutMessage should be null with no message selected"
);
Assert.equal(firstTab.browser, null);
Assert.equal(firstTab.linkedBrowser, null);
Assert.ok(
!firstWebBrowser.docShellIsActive,
"first web browser should NOT be visible"
);
Assert.ok(
!firstMessagePane.docShellIsActive,
"first message browser should NOT be visible"
);
const { folderTree, threadTree, messagePane, paneLayout } =
firstChromeBrowser.contentWindow;
firstTab.folder = folderA;
Assert.equal(firstTab.folder, folderA);
Assert.equal(
folderTree.querySelector(".selected .name").textContent,
"mailTabsA"
);
Assert.equal(threadTree.view.rowCount, 5);
Assert.equal(threadTree.selectedIndex, -1);
Assert.equal(firstTab.message, null);
threadTree.selectedIndex = 0;
Assert.equal(
tabmail.currentAboutMessage,
firstMessageBrowser.contentWindow,
"currentAboutMessage should have a value with a message selected"
);
Assert.equal(firstTab.message, messagesA[0]);
Assert.equal(firstTab.browser, firstMessagePane);
Assert.equal(firstTab.linkedBrowser, firstMessagePane);
Assert.ok(
!firstWebBrowser.docShellIsActive,
"first web browser should NOT be visible"
);
Assert.ok(
firstMessagePane.docShellIsActive,
"first message browser should be visible"
);
Assert.ok(BrowserTestUtils.isVisible(folderTree));
Assert.ok(BrowserTestUtils.isVisible(firstMessageBrowser));
paneLayout.folderPaneVisible = false;
Assert.ok(BrowserTestUtils.isHidden(folderTree));
Assert.ok(BrowserTestUtils.isVisible(firstMessageBrowser));
paneLayout.messagePaneVisible = false;
Assert.ok(BrowserTestUtils.isHidden(folderTree));
Assert.ok(BrowserTestUtils.isHidden(firstMessageBrowser));
Assert.equal(
tabmail.currentAboutMessage,
null,
"currentAboutMessage should be null with the message pane hidden"
);
Assert.equal(firstTab.browser, null);
Assert.equal(firstTab.linkedBrowser, null);
paneLayout.folderPaneVisible = true;
Assert.ok(BrowserTestUtils.isVisible(folderTree));
Assert.ok(BrowserTestUtils.isHidden(firstMessageBrowser));
paneLayout.messagePaneVisible = true;
Assert.ok(BrowserTestUtils.isVisible(folderTree));
Assert.ok(BrowserTestUtils.isVisible(firstMessageBrowser));
Assert.equal(
tabmail.currentAboutMessage,
firstMessageBrowser.contentWindow,
"currentAboutMessage should have a value with the message pane shown"
);
Assert.equal(firstTab.browser, firstMessagePane);
Assert.equal(firstTab.linkedBrowser, firstMessagePane);
Assert.equal(firstChromeBrowser.contentWindow.tabOrWindow, firstTab);
Assert.equal(firstMessageBrowser.contentWindow.tabOrWindow, firstTab);
info("Select multiple messages.");
threadTree.selectedIndices = [1, 2];
Assert.ok(BrowserTestUtils.isHidden(firstWebBrowser));
Assert.ok(BrowserTestUtils.isHidden(firstMessageBrowser));
Assert.ok(BrowserTestUtils.isVisible(firstMultiMessageBrowser));
Assert.equal(
tabmail.currentAboutMessage,
null,
"currentAboutMessage should be null with multiple messages selected"
);
Assert.equal(firstTab.browser, null);
Assert.equal(firstTab.linkedBrowser, null);
Assert.ok(
!firstWebBrowser.docShellIsActive,
"first web browser should NOT be visible"
);
Assert.ok(
!firstMessagePane.docShellIsActive,
"first message browser should NOT be visible"
);
info("Load a web page.");
const loadedPromise = BrowserTestUtils.browserLoaded(
firstWebBrowser,
false,
);
messagePane.displayWebPage("http://mochi.test:8888/");
await loadedPromise;
Assert.ok(BrowserTestUtils.isVisible(firstWebBrowser));
Assert.ok(BrowserTestUtils.isHidden(firstMessageBrowser));
Assert.ok(BrowserTestUtils.isHidden(firstMultiMessageBrowser));
Assert.equal(firstWebBrowser.currentURI.spec, "http://mochi.test:8888/");
Assert.equal(
tabmail.currentAboutMessage,
null,
"currentAboutMessage should be null with a web page loaded"
);
Assert.equal(firstTab.browser, firstWebBrowser);
Assert.equal(firstTab.linkedBrowser, firstWebBrowser);
Assert.ok(
firstWebBrowser.docShellIsActive,
"first web browser should be visible"
);
Assert.ok(
!firstMessagePane.docShellIsActive,
"first message browser should NOT be visible"
);
info("Go back to a single selection.");
threadTree.selectedIndex = 0;
Assert.ok(BrowserTestUtils.isHidden(firstWebBrowser));
Assert.ok(BrowserTestUtils.isVisible(firstMessageBrowser));
Assert.ok(BrowserTestUtils.isHidden(firstMultiMessageBrowser));
Assert.equal(
tabmail.currentAboutMessage,
firstMessageBrowser.contentWindow,
"currentAboutMessage should have a value with a single message selected"
);
Assert.equal(firstTab.browser, firstMessagePane);
Assert.equal(firstTab.linkedBrowser, firstMessagePane);
Assert.ok(
!firstWebBrowser.docShellIsActive,
"first web browser should NOT be visible"
);
Assert.ok(
firstMessagePane.docShellIsActive,
"first message browser should be visible"
);
Services.prefs.setBoolPref("mail.tabs.loadInBackground", true);
info("Open some more tabs. These should open in the background.");
window.MsgOpenNewTabForFolders([folderB], {
folderPaneVisible: true,
messagePaneVisible: true,
});
for (const message of messagesB) {
window.OpenMessageInNewTab(message, {});
}
Assert.equal(tabmail.tabInfo.length, 4);
Assert.deepEqual(
tabmail.tabInfo.map(t => t.selected),
[true, false, false, false]
);
Assert.equal(tabmail.currentTabInfo, firstTab);
Assert.equal(tabmail.currentAbout3Pane, firstChromeBrowser.contentWindow);
Assert.equal(tabmail.currentAboutMessage, firstMessageBrowser.contentWindow);
info("Check the second tab.");
const secondTab = tabmail.tabInfo[1];
Assert.equal(secondTab.mode.name, "mail3PaneTab");
Assert.equal(secondTab.mode.tabType.name, "mailTab");
const secondChromeBrowser = secondTab.chromeBrowser;
await ensureBrowserLoaded(secondChromeBrowser);
Assert.equal(secondChromeBrowser.currentURI.spec, "about:3pane");
const secondWebBrowser =
secondChromeBrowser.contentDocument.getElementById("webBrowser");
const secondMessageBrowser =
secondChromeBrowser.contentDocument.getElementById("messageBrowser");
await ensureBrowserLoaded(secondMessageBrowser);
Assert.equal(secondMessageBrowser.currentURI.spec, "about:message");
const secondMessagePane =
secondMessageBrowser.contentDocument.getElementById("messagepane");
Assert.equal(secondMessagePane.currentURI.spec, "about:blank");
Assert.equal(secondTab.browser, null);
Assert.equal(secondTab.linkedBrowser, null);
Assert.equal(secondTab.folder, folderB);
Assert.ok(
!secondWebBrowser.docShellIsActive,
"second web browser should NOT be visible"
);
Assert.ok(
!secondMessagePane.docShellIsActive,
"second message browser should NOT be visible"
);
tabmail.switchToTab(1);
Assert.deepEqual(
tabmail.tabInfo.map(t => t.selected),
[false, true, false, false]
);
Assert.equal(tabmail.currentTabInfo, tabmail.tabInfo[1]);
Assert.equal(tabmail.currentAbout3Pane, secondChromeBrowser.contentWindow);
Assert.equal(
tabmail.currentAboutMessage,
null,
"currentAboutMessage should be null with no message selected"
);
Assert.ok(
!secondWebBrowser.docShellIsActive,
"second web browser should NOT be visible"
);
Assert.ok(
!secondMessagePane.docShellIsActive,
"second message browser should NOT be visible"
);
Assert.ok(
!firstWebBrowser.docShellIsActive,
"first web browser should NOT be visible"
);
Assert.ok(
!firstMessagePane.docShellIsActive,
"first message browser should NOT be visible"
);
secondChromeBrowser.contentWindow.threadTree.selectedIndex = 0;
Assert.equal(
tabmail.currentAboutMessage,
secondMessageBrowser.contentWindow,
"currentAboutMessage should have a value with a message selected"
);
Assert.ok(
!secondWebBrowser.docShellIsActive,
"second web browser should NOT be visible"
);
Assert.ok(
secondMessagePane.docShellIsActive,
"second message browser should be visible"
);
Assert.equal(secondChromeBrowser.contentWindow.tabOrWindow, secondTab);
Assert.equal(secondMessageBrowser.contentWindow.tabOrWindow, secondTab);
info("Check the third tab.");
const thirdTab = tabmail.tabInfo[2];
Assert.equal(thirdTab.mode.name, "mailMessageTab");
Assert.equal(thirdTab.mode.tabType.name, "mailTab");
const thirdChromeBrowser = thirdTab.chromeBrowser;
await ensureBrowserLoaded(thirdChromeBrowser);
Assert.equal(thirdChromeBrowser.currentURI.spec, "about:message");
const thirdMessagePane =
thirdChromeBrowser.contentDocument.getElementById("messagepane");
Assert.equal(thirdMessagePane.currentURI.spec, messageToURL(messagesB[0]));
Assert.equal(thirdTab.browser, thirdMessagePane);
Assert.equal(thirdTab.linkedBrowser, thirdMessagePane);
Assert.ok(
!thirdMessagePane.docShellIsActive,
"third message browser should NOT be visible"
);
tabmail.switchToTab(2);
Assert.deepEqual(
tabmail.tabInfo.map(t => t.selected),
[false, false, true, false]
);
Assert.equal(tabmail.currentTabInfo, tabmail.tabInfo[2]);
Assert.equal(tabmail.currentAbout3Pane, null);
Assert.equal(tabmail.currentAboutMessage, thirdChromeBrowser.contentWindow);
Assert.ok(
thirdMessagePane.docShellIsActive,
"third message browser should be visible"
);
Assert.ok(
!secondWebBrowser.docShellIsActive,
"second web browser should NOT be visible"
);
Assert.ok(
!secondMessagePane.docShellIsActive,
"second message browser should NOT be visible"
);
Assert.equal(thirdTab.folder, folderB);
Assert.equal(thirdTab.message, messagesB[0]);
Assert.equal(thirdChromeBrowser.contentWindow.tabOrWindow, thirdTab);
info("Check the fourth tab.");
const fourthTab = tabmail.tabInfo[3];
Assert.equal(fourthTab.mode.name, "mailMessageTab");
Assert.equal(fourthTab.mode.tabType.name, "mailTab");
const fourthChromeBrowser = fourthTab.chromeBrowser;
await ensureBrowserLoaded(fourthChromeBrowser);
Assert.equal(fourthChromeBrowser.currentURI.spec, "about:message");
const fourthMessagePane =
fourthChromeBrowser.contentDocument.getElementById("messagepane");
Assert.equal(fourthMessagePane.currentURI.spec, messageToURL(messagesB[1]));
Assert.equal(fourthTab.browser, fourthMessagePane);
Assert.equal(fourthTab.linkedBrowser, fourthMessagePane);
Assert.equal(fourthTab.folder, folderB);
Assert.equal(fourthTab.message, messagesB[1]);
Assert.ok(
!fourthMessagePane.docShellIsActive,
"fourth message browser should NOT be visible"
);
tabmail.switchToTab(3);
Assert.deepEqual(
tabmail.tabInfo.map(t => t.selected),
[false, false, false, true]
);
Assert.equal(tabmail.currentTabInfo, tabmail.tabInfo[3]);
Assert.equal(tabmail.currentAbout3Pane, null);
Assert.equal(tabmail.currentAboutMessage, fourthChromeBrowser.contentWindow);
Assert.ok(
fourthMessagePane.docShellIsActive,
"fourth message browser should be visible"
);
Assert.ok(
!thirdMessagePane.docShellIsActive,
"third message browser should NOT be visible"
);
Assert.equal(fourthChromeBrowser.contentWindow.tabOrWindow, fourthTab);
info("Close tabs.");
tabmail.closeTab(3);
Assert.deepEqual(
tabmail.tabInfo.map(t => t.selected),
[false, false, true]
);
Assert.equal(tabmail.currentTabInfo, thirdTab);
Assert.equal(tabmail.currentAbout3Pane, null);
Assert.equal(tabmail.currentAboutMessage, thirdChromeBrowser.contentWindow);
tabmail.closeTab(2);
Assert.deepEqual(
tabmail.tabInfo.map(t => t.selected),
[false, true]
);
Assert.equal(tabmail.currentTabInfo, secondTab);
Assert.equal(tabmail.currentAbout3Pane, secondChromeBrowser.contentWindow);
Assert.equal(tabmail.currentAboutMessage, secondMessageBrowser.contentWindow);
tabmail.closeTab(1);
Assert.deepEqual(
tabmail.tabInfo.map(t => t.selected),
[true]
);
Assert.equal(tabmail.currentTabInfo, firstTab);
Assert.equal(tabmail.currentAbout3Pane, firstChromeBrowser.contentWindow);
Assert.equal(tabmail.currentAboutMessage, firstMessageBrowser.contentWindow);
Assert.equal(firstTab.browser, firstMessagePane);
Assert.equal(firstTab.linkedBrowser, firstMessagePane);
Assert.ok(
!firstWebBrowser.docShellIsActive,
"first web browser should NOT be visible"
);
Assert.ok(
firstMessagePane.docShellIsActive,
"first message browser should be visible"
);
Services.prefs.setBoolPref("mail.tabs.loadInBackground", false);
info("Open a new mail tab. Focus should switch to the new tab.");
window.OpenMessageInNewTab(messagesB[0], {});
Assert.equal(tabmail.tabInfo.length, 2);
Assert.deepEqual(
tabmail.tabInfo.map(t => t.selected),
[false, true]
);
const secondOpenedTab = tabmail.tabInfo[1];
Assert.equal(secondOpenedTab.mode.name, "mailMessageTab");
Assert.equal(secondOpenedTab.mode.tabType.name, "mailTab");
const secondOpenedChromeBrowser = secondOpenedTab.chromeBrowser;
await ensureBrowserLoaded(secondOpenedChromeBrowser);
Assert.equal(secondOpenedChromeBrowser.currentURI.spec, "about:message");
const secondOpenedMessagePane =
secondOpenedChromeBrowser.contentDocument.getElementById("messagepane");
await ensureBrowserLoaded(secondOpenedMessagePane);
Assert.equal(
secondOpenedMessagePane.currentURI.spec,
messageToURL(messagesB[0])
);
Assert.equal(secondOpenedTab.browser, secondOpenedMessagePane);
Assert.equal(secondOpenedTab.linkedBrowser, secondOpenedMessagePane);
tabmail.closeTab(1);
Assert.equal(tabmail.tabInfo.length, 1);
Assert.deepEqual(
tabmail.tabInfo.map(t => t.selected),
[true]
);
info("Open a content tab.");
// This test isn't about content tabs, but we're testing docShell visibility
// for everything else, and we need another tab to test about:3pane, so this
// seemed like a good place to test docShell visibility for content tabs.
const contentTab = tabmail.openTab("contentTab", {
background: true,
});
const contentTabBrowser = contentTab.browser;
Assert.ok(
!contentTabBrowser.docShellIsActive,
"content tab browser should NOT be visible"
);
tabmail.switchToTab(contentTab);
Assert.ok(
contentTabBrowser.docShellIsActive,
"content tab browser should be visible"
);
Assert.ok(
!firstWebBrowser.docShellIsActive,
"first web browser should NOT be visible"
);
Assert.ok(
!firstMessagePane.docShellIsActive,
"first message browser should NOT be visible"
);
info("While in the background, load a web page.");
messagePane.displayWebPage("https://example.org/");
Assert.ok(
!firstWebBrowser.docShellIsActive,
"first web browser should NOT be visible"
);
Assert.ok(
!firstMessagePane.docShellIsActive,
"first message browser should NOT be visible"
);
tabmail.switchToTab(firstTab);
Assert.ok(
!contentTabBrowser.docShellIsActive,
"content tab browser should NOT be visible"
);
Assert.ok(
firstWebBrowser.docShellIsActive,
"first web browser should be visible"
);
Assert.ok(
!firstMessagePane.docShellIsActive,
"first message browser should NOT be visible"
);
tabmail.switchToTab(contentTab);
Assert.ok(
contentTabBrowser.docShellIsActive,
"content tab browser should be visible"
);
Assert.ok(
!firstWebBrowser.docShellIsActive,
"first web browser should NOT be visible"
);
Assert.ok(
!firstMessagePane.docShellIsActive,
"first message browser should NOT be visible"
);
info("While in the background, load a message.");
threadTree.selectedIndex = 1;
Assert.ok(
!firstWebBrowser.docShellIsActive,
"first web browser should NOT be visible"
);
Assert.ok(
!firstMessagePane.docShellIsActive,
"first message browser should NOT be visible"
);
tabmail.closeTab(contentTab);
Assert.ok(
!firstWebBrowser.docShellIsActive,
"first web browser should NOT be visible"
);
Assert.ok(
firstMessagePane.docShellIsActive,
"first message browser should be visible"
);
threadTree.selectedIndex = -1;
Assert.ok(
!firstMessagePane.docShellIsActive,
"first message browser should NOT be visible"
);
});
add_task(async function testMessageWindow() {
const messageWindowPromise = BrowserTestUtils.domWindowOpenedAndLoaded(
undefined,
async win =>
win.document.documentURI ==
);
MailUtils.openMessageInNewWindow(messagesB[0]);
const messageWindow = await messageWindowPromise;
const messageBrowser = messageWindow.messageBrowser;
await ensureBrowserLoaded(messageBrowser);
Assert.equal(messageBrowser.contentWindow.tabOrWindow, messageWindow);
await BrowserTestUtils.closeWindow(messageWindow);
});
async function ensureBrowserLoaded(browser) {
await TestUtils.waitForCondition(
() =>
browser.currentURI.spec != "about:blank" &&
browser.contentDocument.readyState == "complete",
"waiting for browser to finish loading"
);
}
function messageToURL(message) {
const messageService =
MailServices.messageServiceFromURI("mailbox-message://");
const uri = message.folder.getUriForMsg(message);
return messageService.getUrlForUri(uri).spec;
}