diff --git a/mail/base/content/about3Pane.js b/mail/base/content/about3Pane.js index 8fd7fc807f..3fc2ea2ceb 100644 --- a/mail/base/content/about3Pane.js +++ b/mail/base/content/about3Pane.js @@ -1234,17 +1234,7 @@ var folderPane = { } mode.containerList.replaceChildren(); - - if (typeof mode.init == "function") { - mode.init(); - } - if (typeof mode.initServer == "function") { - for (let account of MailServices.accounts.accounts) { - if (account.incomingServer.type != "im") { - mode.initServer(account.incomingServer); - } - } - } + this._initMode(mode); } Services.xulStore.setValue(XULSTORE_URL, "folderTree", "compact", value); }, @@ -1282,17 +1272,38 @@ var folderPane = { `folderPaneModeHeader_${modeName}` ); mode.containerList = container.querySelector("ul"); + this._initMode(mode); + mode.active = true; + }, + + /** + * Initialize a folder mode with all visible accounts. + * + * @param {object} mode - One of the folder modes from `folderPane._modes`. + */ + _initMode(mode) { if (typeof mode.init == "function") { mode.init(); } - if (typeof mode.initServer == "function") { - for (let account of MailServices.accounts.accounts) { - if (account.incomingServer.type != "im") { - mode.initServer(account.incomingServer); - } - } + if (typeof mode.initServer != "function") { + return; + } + + // `.accounts` is used here because it is ordered, `.allServers` isn't. + for (let account of MailServices.accounts.accounts) { + // Skip IM accounts. + if (account.incomingServer.type == "im") { + continue; + } + // Skip POP3 accounts that are deferred to another account. + if ( + account.incomingServer instanceof Ci.nsIPop3IncomingServer && + account.incomingServer.deferredToAccount + ) { + continue; + } + mode.initServer(account.incomingServer); } - mode.active = true; }, /** @@ -4016,32 +4027,42 @@ var folderListener = { threadTree.invalidate(); } }, - onFolderPropertyChanged(item, property, oldValue, newValue) {}, - onFolderIntPropertyChanged(item, property, oldValue, newValue) { + onFolderPropertyChanged(folder, property, oldValue, newValue) {}, + onFolderIntPropertyChanged(folder, property, oldValue, newValue) { switch (property) { case "BiffState": folderPane.changeNewMessages( - item, + folder, newValue === Ci.nsIMsgFolder.nsMsgBiffState_NewMail ); break; case "FolderFlag": - folderPane.changeFolderFlag(item, oldValue, newValue); + folderPane.changeFolderFlag(folder, oldValue, newValue); break; case "TotalUnreadMessages": - folderPane.changeUnreadCount(item, oldValue, newValue); + folderPane.changeUnreadCount(folder, oldValue, newValue); break; } }, - onFolderBoolPropertyChanged(item, property, oldValue, newValue) { + onFolderBoolPropertyChanged(folder, property, oldValue, newValue) { switch (property) { + case "isDeferred": + if (newValue) { + folderPane.removeFolder(null, folder); + } else { + folderPane.addFolder(null, folder); + for (let f of folder.descendants) { + folderPane.addFolder(f.parent, f); + } + } + break; case "NewMessages": - folderPane.changeNewMessages(item, newValue); + folderPane.changeNewMessages(folder, newValue); break; } }, - onFolderUnicharPropertyChanged(item, property, oldValue, newValue) {}, - onFolderPropertyFlagChanged(item, property, oldFlag, newFlag) {}, + onFolderUnicharPropertyChanged(folder, property, oldValue, newValue) {}, + onFolderPropertyFlagChanged(folder, property, oldFlag, newFlag) {}, onFolderEvent(folder, event) { if (event == "RenameCompleted") { // If a folder is renamed, we get an `onFolderAdded` notification for diff --git a/mail/base/test/browser/browser_folderTreeQuirks.js b/mail/base/test/browser/browser_folderTreeQuirks.js index aea1533c00..75a2534817 100644 --- a/mail/base/test/browser/browser_folderTreeQuirks.js +++ b/mail/base/test/browser/browser_folderTreeQuirks.js @@ -695,6 +695,58 @@ add_task(async function testSearchFolderAddedOnlyOnce() { ]); }); +/** + * Tests deferred POP3 accounts are not displayed in All Folders mode, and + * that a change in their deferred status updates the folder tree. + */ +add_task(async function testDeferredAccount() { + let pop3Account = MailServices.accounts.createAccount(); + let pop3Server = MailServices.accounts.createIncomingServer( + `${pop3Account.key}user`, + "localhost", + "pop3" + ); + pop3Server.QueryInterface(Ci.nsIPop3IncomingServer); + pop3Account.incomingServer = pop3Server.QueryInterface( + Ci.nsIPop3IncomingServer + ); + + let pop3RootFolder = pop3Server.rootFolder; + let pop3Folders = [ + pop3RootFolder, + pop3RootFolder.getChildNamed("Inbox"), + pop3RootFolder.getChildNamed("Trash"), + ]; + let localFolders = [ + rootFolder, + inboxFolder, + trashFolder, + outboxFolder, + folderA, + folderB, + folderC, + ]; + + folderPane.activeModes = ["all"]; + await checkModeListItems("all", [...pop3Folders, ...localFolders]); + + // Defer the account to Local Folders. + pop3Server.deferredToAccount = account.key; + await checkModeListItems("all", localFolders); + + // Remove and add the All mode again to check that an existing deferred + // folder is not shown when the mode initialises. + folderPane.activeModes = ["recent"]; + folderPane.activeModes = ["all"]; + await checkModeListItems("all", localFolders); + + // Stop deferring the account. + pop3Server.deferredToAccount = null; + await checkModeListItems("all", [...pop3Folders, ...localFolders]); + + MailServices.accounts.removeAccount(pop3Account, false); +}); + /** * We deliberately hide the special [Gmail] folder from the folder tree. * Check that it doesn't appear when for a new or existing account.