Bug 1801566 - Split mailContext.js into two files. r=aleca

Half of this file is not related to the mail context menu, it's just there because the file is common to about:3pane and about:message.

Differential Revision: https://phabricator.services.mozilla.com/D162531

--HG--
rename : mail/base/content/mailContext.js => mail/base/content/mailCommon.js
extra : rebase_source : 7045f27f2d8d10198584a4612a22ec7dad03e0e3
extra : source : 86363f94d3a56a4b605014e3c0ced84f83b41bbe
This commit is contained in:
Geoff Lankow 2022-11-14 21:24:32 +13:00
Родитель 0fb226cd68
Коммит e7687eaa17
9 изменённых файлов: 654 добавлений и 644 удалений

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

@ -2,10 +2,18 @@
* 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/. */
/* globals commandController, dbViewWrapperListener, mailContextMenu
nsMsgViewIndex_None */ // mailContext.js
/* globals goDoCommand */ // globalOverlay.js
/* globals MailOfflineMgr */ // mail-offline.js
// mailCommon.js
/* globals commandController, dbViewWrapperListener, nsMsgViewIndex_None */
// mailContext.js
/* globals mailContextMenu */
// globalOverlay.js
/* globals goDoCommand */
// mail-offline.js
/* globals MailOfflineMgr */
// junkCommands.js
/* globals analyzeMessagesForJunk deleteJunkInFolder filterFolderForJunk */

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

@ -40,6 +40,7 @@
<script defer="defer" src="chrome://messenger/content/tree-listbox.js"></script>
<script defer="defer" src="chrome://messenger/content/jsTreeView.js"></script>
<script defer="defer" src="chrome://messenger/content/mailContext.js"></script>
<script defer="defer" src="chrome://messenger/content/mailCommon.js"></script>
<script defer="defer" src="chrome://messenger/content/about3Pane.js"></script>
</head>
<body class="layout-classic">

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

@ -4,7 +4,7 @@
/* globals MailE10SUtils */
// mailContext.js
// mailCommon.js
/* globals commandController, dbViewWrapperListener */
// msgHdrView.js

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

@ -72,6 +72,7 @@
<script defer="defer" src="chrome://calendar/content/widgets/calendar-invitation-panel.js"></script>
<script defer="defer" src="chrome://messenger/content/mailCore.js"></script>
<script defer="defer" src="chrome://messenger/content/mailContext.js"></script>
<script defer="defer" src="chrome://messenger/content/mailCommon.js"></script>
<script defer="defer" src="chrome://messenger/content/msgHdrView.js"></script>
<script defer="defer" src="chrome://messenger/content/aboutMessage.js"></script>
</head>

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

@ -7,9 +7,6 @@
/* import-globals-from mailWindow.js */
/* import-globals-from utilityOverlay.js */
var { PlacesUtils } = ChromeUtils.importESModule(
"resource://gre/modules/PlacesUtils.sys.mjs"
);
var { XPCOMUtils } = ChromeUtils.importESModule(
"resource://gre/modules/XPCOMUtils.sys.mjs"
);

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

@ -0,0 +1,624 @@
/* 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/. */
// mailContext.js
/* globals mailContextMenu */
// about:3pane and about:message must BOTH provide these:
/* globals CrossFolderNavigation */ // msgViewNavigation.js
/* globals displayMessage, gDBView, gFolder, gViewWrapper */
var { MailServices } = ChromeUtils.import(
"resource:///modules/MailServices.jsm"
);
var { XPCOMUtils } = ChromeUtils.importESModule(
"resource://gre/modules/XPCOMUtils.sys.mjs"
);
XPCOMUtils.defineLazyModuleGetters(this, {
ConversationOpener: "resource:///modules/ConversationOpener.jsm",
MailUtils: "resource:///modules/MailUtils.jsm",
MessageArchiver: "resource:///modules/MessageArchiver.jsm",
});
const nsMsgViewIndex_None = 0xffffffff;
const nsMsgKey_None = 0xffffffff;
var commandController = {
_composeCommands: {
cmd_editDraftMsg: Ci.nsIMsgCompType.Draft,
cmd_newMsgFromTemplate: Ci.nsIMsgCompType.Template,
cmd_editTemplateMsg: Ci.nsIMsgCompType.EditTemplate,
cmd_newMessage: Ci.nsIMsgCompType.New,
cmd_replyGroup: Ci.nsIMsgCompType.ReplyToGroup,
cmd_replySender: Ci.nsIMsgCompType.ReplyToSender,
cmd_replyall: Ci.nsIMsgCompType.ReplyAll,
cmd_replylist: Ci.nsIMsgCompType.ReplyToList,
cmd_forwardInline: Ci.nsIMsgCompType.ForwardInline,
cmd_forwardAttachment: Ci.nsIMsgCompType.ForwardAsAttachment,
cmd_redirect: Ci.nsIMsgCompType.Redirect,
cmd_editAsNew: Ci.nsIMsgCompType.EditAsNew,
},
_navigationCommands: {
// TODO: Back and forward are broken because they rely on nsIMessenger.
cmd_goForward: Ci.nsMsgNavigationType.forward,
cmd_goBack: Ci.nsMsgNavigationType.back,
cmd_nextUnreadMsg: Ci.nsMsgNavigationType.nextUnreadMessage,
cmd_nextUnreadThread: Ci.nsMsgNavigationType.nextUnreadThread,
cmd_nextMsg: Ci.nsMsgNavigationType.nextMessage,
cmd_nextFlaggedMsg: Ci.nsMsgNavigationType.nextFlagged,
cmd_previousMsg: Ci.nsMsgNavigationType.previousMessage,
cmd_previousUnreadMsg: Ci.nsMsgNavigationType.previousUnreadMessage,
cmd_previousFlaggedMsg: Ci.nsMsgNavigationType.previousFlagged,
},
_viewCommands: {
cmd_toggleRead: Ci.nsMsgViewCommandType.toggleMessageRead,
cmd_markAsRead: Ci.nsMsgViewCommandType.markMessagesRead,
cmd_markAsUnread: Ci.nsMsgViewCommandType.markMessagesUnread,
cmd_markThreadAsRead: Ci.nsMsgViewCommandType.markThreadRead,
cmd_markAllRead: Ci.nsMsgViewCommandType.markAllRead,
cmd_markAsNotJunk: Ci.nsMsgViewCommandType.unjunk,
cmd_watchThread: Ci.nsMsgViewCommandType.toggleThreadWatched,
},
_callbackCommands: {
cmd_openConversation() {
new ConversationOpener(window).openConversationForMessages(
gDBView.getSelectedMsgHdrs()
);
},
cmd_reply(event) {
if (gFolder?.flags & Ci.nsMsgFolderFlags.Newsgroup) {
commandController.doCommand("cmd_replyGroup", event);
} else {
commandController.doCommand("cmd_replySender", event);
}
},
cmd_forward() {
if (Services.prefs.getIntPref("mail.forward_message_mode", 0) == 0) {
commandController.doCommand("cmd_forwardAttachment");
} else {
commandController.doCommand("cmd_forwardInline");
}
},
cmd_openMessage(event) {
MailUtils.displayMessages(
gDBView.getSelectedMsgHdrs(),
gViewWrapper,
window.browsingContext.topChromeWindow.document.getElementById(
"tabmail"
)
);
},
cmd_tag() {
// Does nothing, just here to enable/disable the tags sub-menu.
},
cmd_tag1: mailContextMenu._toggleMessageTagKey.bind(mailContextMenu, 1),
cmd_tag2: mailContextMenu._toggleMessageTagKey.bind(mailContextMenu, 2),
cmd_tag3: mailContextMenu._toggleMessageTagKey.bind(mailContextMenu, 3),
cmd_tag4: mailContextMenu._toggleMessageTagKey.bind(mailContextMenu, 4),
cmd_tag5: mailContextMenu._toggleMessageTagKey.bind(mailContextMenu, 5),
cmd_tag6: mailContextMenu._toggleMessageTagKey.bind(mailContextMenu, 6),
cmd_tag7: mailContextMenu._toggleMessageTagKey.bind(mailContextMenu, 7),
cmd_tag8: mailContextMenu._toggleMessageTagKey.bind(mailContextMenu, 8),
cmd_tag9: mailContextMenu._toggleMessageTagKey.bind(mailContextMenu, 9),
cmd_addTag() {
mailContextMenu.addTag();
},
cmd_manageTags() {
window.browsingContext.topChromeWindow.openOptionsDialog(
"paneGeneral",
"tagsCategory"
);
},
cmd_removeTags() {
mailContextMenu.removeAllMessageTags();
},
cmd_toggleTag(event) {
mailContextMenu._toggleMessageTag(
event.target.value,
event.target.getAttribute("checked") == "true"
);
},
cmd_markReadByDate() {
window.browsingContext.topChromeWindow.openDialog(
"chrome://messenger/content/markByDate.xhtml",
"",
"chrome,modal,titlebar,centerscreen",
gFolder
);
},
cmd_markAsFlagged() {
gViewWrapper.dbView.doCommand(
gDBView.hdrForFirstSelectedMessage.isFlagged
? Ci.nsMsgViewCommandType.unflagMessages
: Ci.nsMsgViewCommandType.flagMessages
);
},
cmd_markAsJunk() {
if (
Services.prefs.getBoolPref("mailnews.ui.junk.manualMarkAsJunkMarksRead")
) {
gViewWrapper.dbView.doCommand(Ci.nsMsgViewCommandType.markMessagesRead);
}
gViewWrapper.dbView.doCommand(Ci.nsMsgViewCommandType.junk);
},
/**
* Moves the selected messages to the destination folder.
*
* @param {nsIMsgFolder} destFolder - the destination folder
*/
cmd_moveMessage(destFolder) {
gViewWrapper.dbView.doCommandWithFolder(
Ci.nsMsgViewCommandType.moveMessages,
destFolder
);
Services.prefs.setCharPref(
"mail.last_msg_movecopy_target_uri",
destFolder.URI
);
Services.prefs.setBoolPref("mail.last_msg_movecopy_was_move", true);
},
/**
* Copies the selected messages to the destination folder.
*
* @param {nsIMsgFolder} destFolder - the destination folder
*/
cmd_copyMessage(destFolder) {
if (window.messageHeaderSink?.dummyMsgHeader) {
let file = Services.io
.newURI(window.gMessageURI)
.QueryInterface(Ci.nsIFileURL).file;
MailServices.copy.copyFileMessage(
file,
destFolder,
null,
false,
Ci.nsMsgMessageFlags.Read,
"",
null,
window.msgWindow
);
} else {
gViewWrapper.dbView.doCommandWithFolder(
Ci.nsMsgViewCommandType.copyMessages,
destFolder
);
}
Services.prefs.setCharPref(
"mail.last_msg_movecopy_target_uri",
destFolder.URI
);
Services.prefs.setBoolPref("mail.last_msg_movecopy_was_move", false);
},
cmd_archive() {
let archiver = new MessageArchiver();
archiver.archiveMessages(gViewWrapper.dbView.getSelectedMsgHdrs());
},
cmd_moveToFolderAgain() {
let folder = MailUtils.getOrCreateFolder(
Services.prefs.getStringPref("mail.last_msg_movecopy_target_uri")
);
if (Services.prefs.getBoolPref("mail.last_msg_movecopy_was_move")) {
mailContextMenu.moveMessage(folder);
} else {
mailContextMenu.copyMessage(folder);
}
},
cmd_delete() {
gViewWrapper.dbView.doCommand(Ci.nsMsgViewCommandType.markMessagesRead);
gViewWrapper.dbView.doCommand(Ci.nsMsgViewCommandType.deleteMsg);
},
cmd_shiftDelete() {
gViewWrapper.dbView.doCommand(Ci.nsMsgViewCommandType.deleteNoTrash);
},
cmd_createFilterFromMenu() {
let msgHdr = gDBView.hdrForFirstSelectedMessage;
let emailAddress = MailServices.headerParser.extractHeaderAddressMailboxes(
msgHdr.author
);
if (emailAddress) {
top.MsgFilters(emailAddress, msgHdr.folder);
}
},
cmd_killThread() {
// TODO: show notification (ShowIgnoredMessageNotification)
commandController._navigate(Ci.nsMsgNavigationType.toggleThreadKilled);
},
cmd_killSubthread() {
// TODO: show notification (ShowIgnoredMessageNotification)
commandController._navigate(Ci.nsMsgNavigationType.toggleSubthreadKilled);
},
cmd_viewPageSource() {
window.browsingContext.topChromeWindow.ViewPageSource(
gDBView.getURIsForSelection()
);
},
cmd_saveAsFile() {
top.SaveAsFile(gDBView.getURIsForSelection());
},
cmd_saveAsTemplate() {
top.SaveAsTemplate(gDBView.getURIsForSelection()[0]);
},
cmd_applyFilters() {
let curFilterList = gFolder.getFilterList(window.msgWindow);
// Create a new filter list and copy over the enabled filters to it.
// We do this instead of having the filter after the fact code ignore
// disabled filters because the Filter Dialog filter after the fact
// code would have to clone filters to allow disabled filters to run,
// and we don't support cloning filters currently.
let tempFilterList = MailServices.filters.getTempFilterList(gFolder);
let numFilters = curFilterList.filterCount;
// Make sure the temp filter list uses the same log stream.
tempFilterList.loggingEnabled = curFilterList.loggingEnabled;
tempFilterList.logStream = curFilterList.logStream;
let newFilterIndex = 0;
for (let i = 0; i < numFilters; i++) {
let curFilter = curFilterList.getFilterAt(i);
// Only add enabled, UI visible filters that are in the manual context.
if (
curFilter.enabled &&
!curFilter.temporary &&
curFilter.filterType & Ci.nsMsgFilterType.Manual
) {
tempFilterList.insertFilterAt(newFilterIndex, curFilter);
newFilterIndex++;
}
}
MailServices.filters.applyFiltersToFolders(
tempFilterList,
[gFolder],
window.msgWindow
);
},
cmd_applyFiltersToSelection() {
let selectedMessages = gDBView.getSelectedMsgHdrs();
if (selectedMessages.length) {
MailServices.filters.applyFilters(
Ci.nsMsgFilterType.Manual,
selectedMessages,
gFolder,
window.msgWindow
);
}
},
cmd_space() {
// TODO: Implement
},
},
_isCallbackEnabled: {},
registerCallback(name, callback, isEnabled = true) {
this._callbackCommands[name] = callback;
this._isCallbackEnabled[name] = isEnabled;
},
supportsCommand(command) {
return (
command in this._composeCommands ||
command in this._navigationCommands ||
command in this._viewCommands ||
command in this._callbackCommands
);
},
isCommandEnabled(command) {
let type = typeof this._isCallbackEnabled[command];
if (type == "function") {
return this._isCallbackEnabled[command]();
} else if (type == "boolean") {
return this._isCallbackEnabled[command];
}
if (command == "cmd_newMessage") {
// TODO: This shouldn't be here, or should return false if there are no identities.
return true;
}
if (!gViewWrapper) {
return false;
}
let isDummyMessage = !gFolder;
if (command in this._navigationCommands) {
return !isDummyMessage;
}
let numSelectedMessages = isDummyMessage ? 1 : gDBView.numSelected;
let isNewsgroup = gFolder?.isSpecialFolder(
Ci.nsMsgFolderFlags.Newsgroup,
true
);
let canMove =
numSelectedMessages >= 1 && !isNewsgroup && gFolder?.canDeleteMessages;
switch (command) {
case "cmd_openConversation":
return gDBView
.getSelectedMsgHdrs()
.some(m => ConversationOpener.isMessageIndexed(m));
case "cmd_reply":
case "cmd_replySender":
case "cmd_replyall":
case "cmd_replylist":
case "cmd_forward":
case "cmd_redirect":
case "cmd_editAsNew":
case "cmd_viewPageSource":
case "cmd_saveAsTemplate":
return numSelectedMessages == 1;
case "cmd_forwardInline":
case "cmd_forwardAttachment":
case "cmd_copyMessage":
case "cmd_saveAsFile":
return numSelectedMessages >= 1;
case "cmd_openMessage":
case "cmd_tag":
case "cmd_tag1":
case "cmd_tag2":
case "cmd_tag3":
case "cmd_tag4":
case "cmd_tag5":
case "cmd_tag6":
case "cmd_tag7":
case "cmd_tag8":
case "cmd_tag9":
case "cmd_addTag":
case "cmd_manageTags":
case "cmd_removeTags":
case "cmd_toggleTag":
case "cmd_toggleRead":
case "cmd_markReadByDate":
case "cmd_markAsFlagged":
case "cmd_moveMessage":
case "cmd_killThread":
case "cmd_killSubthread":
case "cmd_applyFiltersToSelection":
return numSelectedMessages >= 1 && !isDummyMessage;
case "cmd_editDraftMsg":
return (
numSelectedMessages == 1 &&
gFolder?.isSpecialFolder(Ci.nsMsgFolderFlags.Drafts, true)
);
case "cmd_newMsgFromTemplate":
case "cmd_editTemplateMsg":
return (
numSelectedMessages == 1 &&
gFolder?.isSpecialFolder(Ci.nsMsgFolderFlags.Templates, true)
);
case "cmd_replyGroup":
return isNewsgroup;
case "cmd_markAsRead":
return (
numSelectedMessages >= 1 &&
!isDummyMessage &&
gViewWrapper.dbView.getSelectedMsgHdrs().some(msg => !msg.isRead)
);
case "cmd_markAsUnread":
return (
numSelectedMessages >= 1 &&
!isDummyMessage &&
gViewWrapper.dbView.getSelectedMsgHdrs().some(msg => msg.isRead)
);
case "cmd_markThreadAsRead": {
if (numSelectedMessages != 1 || isDummyMessage) {
return false;
}
let selectedIndex = {};
gViewWrapper.dbView.selection?.getRangeAt(0, selectedIndex, {});
return (
gViewWrapper.dbView.getThreadContainingIndex(selectedIndex.value)
.numUnreadChildren > 0
);
}
case "cmd_markAllRead":
return gDBView?.msgFolder?.getNumUnread(false) > 0;
case "cmd_markAsJunk":
case "cmd_markAsNotJunk":
return this._getViewCommandStatus(Ci.nsMsgViewCommandType.junk);
case "cmd_archive":
return MessageArchiver.canArchive(
gDBView.getSelectedMsgHdrs(),
gViewWrapper.isSingleFolder
);
case "cmd_moveToFolderAgain": {
// Disable "Move to <folder> Again" for news and other read only
// folders since we can't really move messages from there - only copy.
let canMoveAgain = numSelectedMessages >= 1;
if (Services.prefs.getBoolPref("mail.last_msg_movecopy_was_move")) {
canMoveAgain = canMove;
}
if (canMoveAgain) {
let targetURI = Services.prefs.getStringPref(
"mail.last_msg_movecopy_target_uri"
);
canMoveAgain = targetURI && MailUtils.getExistingFolder(targetURI);
}
return canMoveAgain;
}
case "cmd_delete":
return isNewsgroup || canMove;
case "cmd_shiftDelete":
return this._getViewCommandStatus(
Ci.nsMsgViewCommandType.deleteNoTrash
);
case "cmd_createFilterFromMenu":
return (
numSelectedMessages == 1 &&
gDBView.hdrForFirstSelectedMessage?.folder?.server.canHaveFilters
);
case "cmd_watchThread": {
if (!gViewWrapper.dbView) {
return false;
}
let enabledObj = {};
let checkStatusObj = {};
gViewWrapper.dbView.getCommandStatus(
Ci.nsMsgViewCommandType.toggleThreadWatched,
enabledObj,
checkStatusObj
);
return enabledObj.value;
}
case "cmd_applyFilters": {
return this._getViewCommandStatus(Ci.nsMsgViewCommandType.applyFilters);
}
}
return false;
},
doCommand(command, ...args) {
if (!this.isCommandEnabled(command)) {
return;
}
if (command in this._composeCommands) {
this._composeMsgByType(this._composeCommands[command], ...args);
return;
}
if (command in this._navigationCommands) {
this._navigate(this._navigationCommands[command]);
return;
}
if (command in this._viewCommands) {
if (command.endsWith("Read") || command.endsWith("Unread")) {
if (window.ClearPendingReadTimer) {
window.ClearPendingReadTimer();
} else {
window.messageBrowser.contentWindow.ClearPendingReadTimer();
}
}
gViewWrapper.dbView.doCommand(this._viewCommands[command]);
return;
}
if (command in this._callbackCommands) {
this._callbackCommands[command](...args);
}
},
_getViewCommandStatus(commandType) {
if (!gViewWrapper.dbView) {
return false;
}
let enabledObj = {};
let checkStatusObj = {};
gViewWrapper.dbView.getCommandStatus(
commandType,
enabledObj,
checkStatusObj
);
return enabledObj.value;
},
/**
* Calls the ComposeMessage function with the desired type, and proper default
* based on the event that fired it.
*
* @param composeType the nsIMsgCompType to pass to the function
* @param event (optional) the event that triggered the call
*/
_composeMsgByType(composeType, event) {
// If we're the hidden window, then we're not going to have a gFolderDisplay
// to work out existing folders, so just use null.
let msgFolder = gFolder;
let msgUris = window.messageHeaderSink?.dummyMsgHeader
? [window.gMessageURI]
: gDBView?.getURIsForSelection();
if (event && event.shiftKey) {
window.browsingContext.topChromeWindow.ComposeMessage(
composeType,
Ci.nsIMsgCompFormat.OppositeOfDefault,
msgFolder,
msgUris
);
} else {
window.browsingContext.topChromeWindow.ComposeMessage(
composeType,
Ci.nsIMsgCompFormat.Default,
msgFolder,
msgUris
);
}
},
_navigate(navigationType) {
let resultKey = {};
let resultIndex = {};
let threadIndex = {};
gViewWrapper.dbView.viewNavigate(
navigationType,
resultKey,
resultIndex,
threadIndex,
true
);
if (resultIndex.value == nsMsgViewIndex_None) {
// Not in about:message
if (window.displayFolder) {
CrossFolderNavigation(navigationType);
}
return;
}
if (resultKey.value == nsMsgKey_None) {
return;
}
gViewWrapper.dbView.selection.select(resultIndex.value);
if (window.threadTree) {
window.threadTree.scrollToIndex(resultIndex.value);
window.threadTree.focus();
}
displayMessage(gViewWrapper.dbView.URIForFirstSelectedMessage);
},
};
/**
* Dummy DBViewWrapperListener so that we can have a DBViewWrapper. Some of
* this will no doubt need to be filled in later.
*/
var dbViewWrapperListener = {
messenger: null,
msgWindow: null,
threadPaneCommandUpdater: null,
get shouldUseMailViews() {
return false;
},
get shouldDeferMessageDisplayUntilAfterServerConnect() {
return false;
},
shouldMarkMessagesReadOnLeavingFolder(msgFolder) {
return false;
},
onFolderLoading(isFolderLoading) {},
onSearching(isSearching) {},
onCreatedView() {
if (window.threadTree) {
// eslint-disable-next-line no-global-assign
window.threadTree.view = gDBView = gViewWrapper.dbView;
}
},
onDestroyingView(folderIsComingBack) {},
onLoadingFolder(dbFolderInfo) {},
onDisplayingFolder() {},
onLeavingFolder() {},
onMessagesLoaded(all) {
if (all) {
window.threadTree?.invalidate();
}
},
onMailViewChanged() {},
onSortChanged() {
window.threadTree?.invalidate();
},
onMessagesRemoved() {},
onMessageRemovalFailed() {},
onMessageCountsChanged() {},
};

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

@ -2,11 +2,13 @@
* 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/. */
// mailCommon.js
/* globals commandController */
// about:3pane and about:message must BOTH provide these:
/* globals goDoCommand */ // globalOverlay.js
/* globals CrossFolderNavigation */ // msgViewNavigation.js
/* globals displayMessage, gDBView, gFolder, gViewWrapper, messengerBundle */
/* globals gDBView, gFolder, gViewWrapper, messengerBundle */
var { MailServices } = ChromeUtils.import(
"resource:///modules/MailServices.jsm"
@ -15,23 +17,12 @@ var { XPCOMUtils } = ChromeUtils.importESModule(
"resource://gre/modules/XPCOMUtils.sys.mjs"
);
var LazyModules = {};
ChromeUtils.defineESModuleGetters(LazyModules, {
PlacesUtils: "resource://gre/modules/PlacesUtils.sys.mjs",
});
XPCOMUtils.defineLazyModuleGetters(LazyModules, {
ConversationOpener: "resource:///modules/ConversationOpener.jsm",
XPCOMUtils.defineLazyModuleGetters(this, {
MailUtils: "resource:///modules/MailUtils.jsm",
MessageArchiver: "resource:///modules/MessageArchiver.jsm",
PhishingDetector: "resource:///modules/PhishingDetector.jsm",
TagUtils: "resource:///modules/TagUtils.jsm",
});
const nsMsgViewIndex_None = 0xffffffff;
const nsMsgKey_None = 0xffffffff;
window.addEventListener("DOMContentLoaded", event => {
if (
event.target != document ||
@ -359,7 +350,9 @@ var mailContextMenu = {
// this._openInBrowser();
// break;
case "mailContext-openLinkInBrowser":
this._openLinkInBrowser();
// Only called in about:message.
// eslint-disable-next-line no-undef
openLinkExternally(this.context.linkURL);
break;
case "mailContext-copylink":
goDoCommand("cmd_copyLink");
@ -377,7 +370,7 @@ var mailContextMenu = {
// );
// break;
case "mailContext-reportPhishingURL":
LazyModules.PhishingDetector.reportPhishingURL(this.context.linkURL);
PhishingDetector.reportPhishingURL(this.context.linkURL);
break;
case "mailContext-addemail":
topChromeWindow.addEmail(this.context.linkURL);
@ -444,9 +437,7 @@ var mailContextMenu = {
);
break;
case "mailContext-openContainingFolder":
LazyModules.MailUtils.displayMessageInFolderTab(
gDBView.hdrForFirstSelectedMessage
);
MailUtils.displayMessageInFolderTab(gDBView.hdrForFirstSelectedMessage);
break;
// Move/copy/archive/convert/delete
@ -494,22 +485,6 @@ var mailContextMenu = {
}
},
_openLinkInBrowser() {
LazyModules.PlacesUtils.history
.insert({
url: this.context.linkURL,
visits: [
{
date: new Date(),
},
],
})
.catch(Cu.reportError);
Cc["@mozilla.org/uriloader/external-protocol-service;1"]
.getService(Ci.nsIExternalProtocolService)
.loadURI(Services.io.newURI(this.context.linkURL));
},
// Tags sub-menu
/**
@ -681,7 +656,7 @@ var mailContextMenu = {
okCallback(name, color) {
MailServices.tags.addTag(name, color, "");
let key = MailServices.tags.getKeyForTag(name);
LazyModules.TagUtils.addTagToAllDocumentSheets(key, color);
TagUtils.addTagToAllDocumentSheets(key, color);
try {
this._toggleMessageTag(key, true);
@ -694,601 +669,3 @@ var mailContextMenu = {
);
},
};
var commandController = {
_composeCommands: {
cmd_editDraftMsg: Ci.nsIMsgCompType.Draft,
cmd_newMsgFromTemplate: Ci.nsIMsgCompType.Template,
cmd_editTemplateMsg: Ci.nsIMsgCompType.EditTemplate,
cmd_newMessage: Ci.nsIMsgCompType.New,
cmd_replyGroup: Ci.nsIMsgCompType.ReplyToGroup,
cmd_replySender: Ci.nsIMsgCompType.ReplyToSender,
cmd_replyall: Ci.nsIMsgCompType.ReplyAll,
cmd_replylist: Ci.nsIMsgCompType.ReplyToList,
cmd_forwardInline: Ci.nsIMsgCompType.ForwardInline,
cmd_forwardAttachment: Ci.nsIMsgCompType.ForwardAsAttachment,
cmd_redirect: Ci.nsIMsgCompType.Redirect,
cmd_editAsNew: Ci.nsIMsgCompType.EditAsNew,
},
_navigationCommands: {
// TODO: Back and forward are broken because they rely on nsIMessenger.
cmd_goForward: Ci.nsMsgNavigationType.forward,
cmd_goBack: Ci.nsMsgNavigationType.back,
cmd_nextUnreadMsg: Ci.nsMsgNavigationType.nextUnreadMessage,
cmd_nextUnreadThread: Ci.nsMsgNavigationType.nextUnreadThread,
cmd_nextMsg: Ci.nsMsgNavigationType.nextMessage,
cmd_nextFlaggedMsg: Ci.nsMsgNavigationType.nextFlagged,
cmd_previousMsg: Ci.nsMsgNavigationType.previousMessage,
cmd_previousUnreadMsg: Ci.nsMsgNavigationType.previousUnreadMessage,
cmd_previousFlaggedMsg: Ci.nsMsgNavigationType.previousFlagged,
},
_viewCommands: {
cmd_toggleRead: Ci.nsMsgViewCommandType.toggleMessageRead,
cmd_markAsRead: Ci.nsMsgViewCommandType.markMessagesRead,
cmd_markAsUnread: Ci.nsMsgViewCommandType.markMessagesUnread,
cmd_markThreadAsRead: Ci.nsMsgViewCommandType.markThreadRead,
cmd_markAllRead: Ci.nsMsgViewCommandType.markAllRead,
cmd_markAsNotJunk: Ci.nsMsgViewCommandType.unjunk,
cmd_watchThread: Ci.nsMsgViewCommandType.toggleThreadWatched,
},
_callbackCommands: {
cmd_openConversation() {
new LazyModules.ConversationOpener(window).openConversationForMessages(
gDBView.getSelectedMsgHdrs()
);
},
cmd_reply(event) {
if (gFolder?.flags & Ci.nsMsgFolderFlags.Newsgroup) {
commandController.doCommand("cmd_replyGroup", event);
} else {
commandController.doCommand("cmd_replySender", event);
}
},
cmd_forward() {
if (Services.prefs.getIntPref("mail.forward_message_mode", 0) == 0) {
commandController.doCommand("cmd_forwardAttachment");
} else {
commandController.doCommand("cmd_forwardInline");
}
},
cmd_openMessage(event) {
LazyModules.MailUtils.displayMessages(
gDBView.getSelectedMsgHdrs(),
gViewWrapper,
window.browsingContext.topChromeWindow.document.getElementById(
"tabmail"
)
);
},
cmd_tag() {
// Does nothing, just here to enable/disable the tags sub-menu.
},
cmd_tag1: mailContextMenu._toggleMessageTagKey.bind(mailContextMenu, 1),
cmd_tag2: mailContextMenu._toggleMessageTagKey.bind(mailContextMenu, 2),
cmd_tag3: mailContextMenu._toggleMessageTagKey.bind(mailContextMenu, 3),
cmd_tag4: mailContextMenu._toggleMessageTagKey.bind(mailContextMenu, 4),
cmd_tag5: mailContextMenu._toggleMessageTagKey.bind(mailContextMenu, 5),
cmd_tag6: mailContextMenu._toggleMessageTagKey.bind(mailContextMenu, 6),
cmd_tag7: mailContextMenu._toggleMessageTagKey.bind(mailContextMenu, 7),
cmd_tag8: mailContextMenu._toggleMessageTagKey.bind(mailContextMenu, 8),
cmd_tag9: mailContextMenu._toggleMessageTagKey.bind(mailContextMenu, 9),
cmd_addTag() {
mailContextMenu.addTag();
},
cmd_manageTags() {
window.browsingContext.topChromeWindow.openOptionsDialog(
"paneGeneral",
"tagsCategory"
);
},
cmd_removeTags() {
mailContextMenu.removeAllMessageTags();
},
cmd_toggleTag(event) {
mailContextMenu._toggleMessageTag(
event.target.value,
event.target.getAttribute("checked") == "true"
);
},
cmd_markReadByDate() {
window.browsingContext.topChromeWindow.openDialog(
"chrome://messenger/content/markByDate.xhtml",
"",
"chrome,modal,titlebar,centerscreen",
gFolder
);
},
cmd_markAsFlagged() {
gViewWrapper.dbView.doCommand(
gDBView.hdrForFirstSelectedMessage.isFlagged
? Ci.nsMsgViewCommandType.unflagMessages
: Ci.nsMsgViewCommandType.flagMessages
);
},
cmd_markAsJunk() {
if (
Services.prefs.getBoolPref("mailnews.ui.junk.manualMarkAsJunkMarksRead")
) {
gViewWrapper.dbView.doCommand(Ci.nsMsgViewCommandType.markMessagesRead);
}
gViewWrapper.dbView.doCommand(Ci.nsMsgViewCommandType.junk);
},
/**
* Moves the selected messages to the destination folder.
*
* @param {nsIMsgFolder} destFolder - the destination folder
*/
cmd_moveMessage(destFolder) {
gViewWrapper.dbView.doCommandWithFolder(
Ci.nsMsgViewCommandType.moveMessages,
destFolder
);
Services.prefs.setCharPref(
"mail.last_msg_movecopy_target_uri",
destFolder.URI
);
Services.prefs.setBoolPref("mail.last_msg_movecopy_was_move", true);
},
/**
* Copies the selected messages to the destination folder.
*
* @param {nsIMsgFolder} destFolder - the destination folder
*/
cmd_copyMessage(destFolder) {
if (window.messageHeaderSink?.dummyMsgHeader) {
let file = Services.io
.newURI(window.gMessageURI)
.QueryInterface(Ci.nsIFileURL).file;
MailServices.copy.copyFileMessage(
file,
destFolder,
null,
false,
Ci.nsMsgMessageFlags.Read,
"",
null,
window.msgWindow
);
} else {
gViewWrapper.dbView.doCommandWithFolder(
Ci.nsMsgViewCommandType.copyMessages,
destFolder
);
}
Services.prefs.setCharPref(
"mail.last_msg_movecopy_target_uri",
destFolder.URI
);
Services.prefs.setBoolPref("mail.last_msg_movecopy_was_move", false);
},
cmd_archive() {
let archiver = new LazyModules.MessageArchiver();
archiver.archiveMessages(gViewWrapper.dbView.getSelectedMsgHdrs());
},
cmd_moveToFolderAgain() {
let folder = LazyModules.MailUtils.getOrCreateFolder(
Services.prefs.getStringPref("mail.last_msg_movecopy_target_uri")
);
if (Services.prefs.getBoolPref("mail.last_msg_movecopy_was_move")) {
mailContextMenu.moveMessage(folder);
} else {
mailContextMenu.copyMessage(folder);
}
},
cmd_delete() {
gViewWrapper.dbView.doCommand(Ci.nsMsgViewCommandType.markMessagesRead);
gViewWrapper.dbView.doCommand(Ci.nsMsgViewCommandType.deleteMsg);
},
cmd_shiftDelete() {
gViewWrapper.dbView.doCommand(Ci.nsMsgViewCommandType.deleteNoTrash);
},
cmd_createFilterFromMenu() {
let msgHdr = gDBView.hdrForFirstSelectedMessage;
let emailAddress = MailServices.headerParser.extractHeaderAddressMailboxes(
msgHdr.author
);
if (emailAddress) {
top.MsgFilters(emailAddress, msgHdr.folder);
}
},
cmd_killThread() {
// TODO: show notification (ShowIgnoredMessageNotification)
commandController._navigate(Ci.nsMsgNavigationType.toggleThreadKilled);
},
cmd_killSubthread() {
// TODO: show notification (ShowIgnoredMessageNotification)
commandController._navigate(Ci.nsMsgNavigationType.toggleSubthreadKilled);
},
cmd_viewPageSource() {
window.browsingContext.topChromeWindow.ViewPageSource(
gDBView.getURIsForSelection()
);
},
cmd_saveAsFile() {
top.SaveAsFile(gDBView.getURIsForSelection());
},
cmd_saveAsTemplate() {
top.SaveAsTemplate(gDBView.getURIsForSelection()[0]);
},
cmd_applyFilters() {
let curFilterList = gFolder.getFilterList(window.msgWindow);
// Create a new filter list and copy over the enabled filters to it.
// We do this instead of having the filter after the fact code ignore
// disabled filters because the Filter Dialog filter after the fact
// code would have to clone filters to allow disabled filters to run,
// and we don't support cloning filters currently.
let tempFilterList = MailServices.filters.getTempFilterList(gFolder);
let numFilters = curFilterList.filterCount;
// Make sure the temp filter list uses the same log stream.
tempFilterList.loggingEnabled = curFilterList.loggingEnabled;
tempFilterList.logStream = curFilterList.logStream;
let newFilterIndex = 0;
for (let i = 0; i < numFilters; i++) {
let curFilter = curFilterList.getFilterAt(i);
// Only add enabled, UI visible filters that are in the manual context.
if (
curFilter.enabled &&
!curFilter.temporary &&
curFilter.filterType & Ci.nsMsgFilterType.Manual
) {
tempFilterList.insertFilterAt(newFilterIndex, curFilter);
newFilterIndex++;
}
}
MailServices.filters.applyFiltersToFolders(
tempFilterList,
[gFolder],
window.msgWindow
);
},
cmd_applyFiltersToSelection() {
let selectedMessages = gDBView.getSelectedMsgHdrs();
if (selectedMessages.length) {
MailServices.filters.applyFilters(
Ci.nsMsgFilterType.Manual,
selectedMessages,
gFolder,
window.msgWindow
);
}
},
cmd_space() {
// TODO: Implement
},
},
_isCallbackEnabled: {},
registerCallback(name, callback, isEnabled = true) {
this._callbackCommands[name] = callback;
this._isCallbackEnabled[name] = isEnabled;
},
supportsCommand(command) {
return (
command in this._composeCommands ||
command in this._navigationCommands ||
command in this._viewCommands ||
command in this._callbackCommands
);
},
isCommandEnabled(command) {
let type = typeof this._isCallbackEnabled[command];
if (type == "function") {
return this._isCallbackEnabled[command]();
} else if (type == "boolean") {
return this._isCallbackEnabled[command];
}
if (command == "cmd_newMessage") {
// TODO: This shouldn't be here, or should return false if there are no identities.
return true;
}
if (!gViewWrapper) {
return false;
}
let isDummyMessage = !gFolder;
if (command in this._navigationCommands) {
return !isDummyMessage;
}
let numSelectedMessages = isDummyMessage ? 1 : gDBView.numSelected;
let isNewsgroup = gFolder?.isSpecialFolder(
Ci.nsMsgFolderFlags.Newsgroup,
true
);
let canMove =
numSelectedMessages >= 1 && !isNewsgroup && gFolder?.canDeleteMessages;
switch (command) {
case "cmd_openConversation":
return gDBView
.getSelectedMsgHdrs()
.some(m => LazyModules.ConversationOpener.isMessageIndexed(m));
case "cmd_reply":
case "cmd_replySender":
case "cmd_replyall":
case "cmd_replylist":
case "cmd_forward":
case "cmd_redirect":
case "cmd_editAsNew":
case "cmd_viewPageSource":
case "cmd_saveAsTemplate":
return numSelectedMessages == 1;
case "cmd_forwardInline":
case "cmd_forwardAttachment":
case "cmd_copyMessage":
case "cmd_saveAsFile":
return numSelectedMessages >= 1;
case "cmd_openMessage":
case "cmd_tag":
case "cmd_tag1":
case "cmd_tag2":
case "cmd_tag3":
case "cmd_tag4":
case "cmd_tag5":
case "cmd_tag6":
case "cmd_tag7":
case "cmd_tag8":
case "cmd_tag9":
case "cmd_addTag":
case "cmd_manageTags":
case "cmd_removeTags":
case "cmd_toggleTag":
case "cmd_toggleRead":
case "cmd_markReadByDate":
case "cmd_markAsFlagged":
case "cmd_moveMessage":
case "cmd_killThread":
case "cmd_killSubthread":
case "cmd_applyFiltersToSelection":
return numSelectedMessages >= 1 && !isDummyMessage;
case "cmd_editDraftMsg":
return (
numSelectedMessages == 1 &&
gFolder?.isSpecialFolder(Ci.nsMsgFolderFlags.Drafts, true)
);
case "cmd_newMsgFromTemplate":
case "cmd_editTemplateMsg":
return (
numSelectedMessages == 1 &&
gFolder?.isSpecialFolder(Ci.nsMsgFolderFlags.Templates, true)
);
case "cmd_replyGroup":
return isNewsgroup;
case "cmd_markAsRead":
return (
numSelectedMessages >= 1 &&
!isDummyMessage &&
gViewWrapper.dbView.getSelectedMsgHdrs().some(msg => !msg.isRead)
);
case "cmd_markAsUnread":
return (
numSelectedMessages >= 1 &&
!isDummyMessage &&
gViewWrapper.dbView.getSelectedMsgHdrs().some(msg => msg.isRead)
);
case "cmd_markThreadAsRead": {
if (numSelectedMessages != 1 || isDummyMessage) {
return false;
}
let selectedIndex = {};
gViewWrapper.dbView.selection?.getRangeAt(0, selectedIndex, {});
return (
gViewWrapper.dbView.getThreadContainingIndex(selectedIndex.value)
.numUnreadChildren > 0
);
}
case "cmd_markAllRead":
return gDBView?.msgFolder?.getNumUnread(false) > 0;
case "cmd_markAsJunk":
case "cmd_markAsNotJunk":
return this._getViewCommandStatus(Ci.nsMsgViewCommandType.junk);
case "cmd_archive":
return LazyModules.MessageArchiver.canArchive(
gDBView.getSelectedMsgHdrs(),
gViewWrapper.isSingleFolder
);
case "cmd_moveToFolderAgain": {
// Disable "Move to <folder> Again" for news and other read only
// folders since we can't really move messages from there - only copy.
let canMoveAgain = numSelectedMessages >= 1;
if (Services.prefs.getBoolPref("mail.last_msg_movecopy_was_move")) {
canMoveAgain = canMove;
}
if (canMoveAgain) {
let targetURI = Services.prefs.getStringPref(
"mail.last_msg_movecopy_target_uri"
);
canMoveAgain =
targetURI && LazyModules.MailUtils.getExistingFolder(targetURI);
}
return canMoveAgain;
}
case "cmd_delete":
return isNewsgroup || canMove;
case "cmd_shiftDelete":
return this._getViewCommandStatus(
Ci.nsMsgViewCommandType.deleteNoTrash
);
case "cmd_createFilterFromMenu":
return (
numSelectedMessages == 1 &&
gDBView.hdrForFirstSelectedMessage?.folder?.server.canHaveFilters
);
case "cmd_watchThread": {
if (!gViewWrapper.dbView) {
return false;
}
let enabledObj = {};
let checkStatusObj = {};
gViewWrapper.dbView.getCommandStatus(
Ci.nsMsgViewCommandType.toggleThreadWatched,
enabledObj,
checkStatusObj
);
return enabledObj.value;
}
case "cmd_applyFilters": {
return this._getViewCommandStatus(Ci.nsMsgViewCommandType.applyFilters);
}
}
return false;
},
doCommand(command, ...args) {
if (!this.isCommandEnabled(command)) {
return;
}
if (command in this._composeCommands) {
this._composeMsgByType(this._composeCommands[command], ...args);
return;
}
if (command in this._navigationCommands) {
this._navigate(this._navigationCommands[command]);
return;
}
if (command in this._viewCommands) {
if (command.endsWith("Read") || command.endsWith("Unread")) {
if (window.ClearPendingReadTimer) {
window.ClearPendingReadTimer();
} else {
window.messageBrowser.contentWindow.ClearPendingReadTimer();
}
}
gViewWrapper.dbView.doCommand(this._viewCommands[command]);
return;
}
if (command in this._callbackCommands) {
this._callbackCommands[command](...args);
}
},
_getViewCommandStatus(commandType) {
if (!gViewWrapper.dbView) {
return false;
}
let enabledObj = {};
let checkStatusObj = {};
gViewWrapper.dbView.getCommandStatus(
commandType,
enabledObj,
checkStatusObj
);
return enabledObj.value;
},
/**
* Calls the ComposeMessage function with the desired type, and proper default
* based on the event that fired it.
*
* @param composeType the nsIMsgCompType to pass to the function
* @param event (optional) the event that triggered the call
*/
_composeMsgByType(composeType, event) {
// If we're the hidden window, then we're not going to have a gFolderDisplay
// to work out existing folders, so just use null.
let msgFolder = gFolder;
let msgUris = window.messageHeaderSink?.dummyMsgHeader
? [window.gMessageURI]
: gDBView?.getURIsForSelection();
if (event && event.shiftKey) {
window.browsingContext.topChromeWindow.ComposeMessage(
composeType,
Ci.nsIMsgCompFormat.OppositeOfDefault,
msgFolder,
msgUris
);
} else {
window.browsingContext.topChromeWindow.ComposeMessage(
composeType,
Ci.nsIMsgCompFormat.Default,
msgFolder,
msgUris
);
}
},
_navigate(navigationType) {
let resultKey = {};
let resultIndex = {};
let threadIndex = {};
gViewWrapper.dbView.viewNavigate(
navigationType,
resultKey,
resultIndex,
threadIndex,
true
);
if (resultIndex.value == nsMsgViewIndex_None) {
// Not in about:message
if (window.displayFolder) {
CrossFolderNavigation(navigationType);
}
return;
}
if (resultKey.value == nsMsgKey_None) {
return;
}
gViewWrapper.dbView.selection.select(resultIndex.value);
if (window.threadTree) {
window.threadTree.scrollToIndex(resultIndex.value);
window.threadTree.focus();
}
displayMessage(gViewWrapper.dbView.URIForFirstSelectedMessage);
},
};
/**
* Dummy DBViewWrapperListener so that we can have a DBViewWrapper. Some of
* this will no doubt need to be filled in later.
*/
var dbViewWrapperListener = {
messenger: null,
msgWindow: null,
threadPaneCommandUpdater: null,
get shouldUseMailViews() {
return false;
},
get shouldDeferMessageDisplayUntilAfterServerConnect() {
return false;
},
shouldMarkMessagesReadOnLeavingFolder(msgFolder) {
return false;
},
onFolderLoading(isFolderLoading) {},
onSearching(isSearching) {},
onCreatedView() {
if (window.threadTree) {
// eslint-disable-next-line no-global-assign
window.threadTree.view = gDBView = gViewWrapper.dbView;
}
},
onDestroyingView(folderIsComingBack) {},
onLoadingFolder(dbFolderInfo) {},
onDisplayingFolder() {},
onLeavingFolder() {},
onMessagesLoaded(all) {
if (all) {
window.threadTree?.invalidate();
}
},
onMailViewChanged() {},
onSortChanged() {
window.threadTree?.invalidate();
},
onMessagesRemoved() {},
onMessageRemovalFailed() {},
onMessageCountsChanged() {},
};

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

@ -33,6 +33,7 @@ XPCOMUtils.defineLazyModuleGetters(this, {
Gloda: "resource:///modules/gloda/GlodaPublic.jsm",
GlodaUtils: "resource:///modules/gloda/GlodaUtils.jsm",
MailUtils: "resource:///modules/MailUtils.jsm",
MessageArchiver: "resource:///modules/MessageArchiver.jsm",
PgpSqliteDb2: "chrome://openpgp/content/modules/sqliteDb.jsm",
PluralForm: "resource://gre/modules/PluralForm.jsm",
});
@ -4171,7 +4172,7 @@ function MsgReplyToListMessage(event) {
* @param event the event that caused us to call this function
*/
function MsgArchiveSelectedMessages(event) {
let archiver = new LazyModules.MessageArchiver();
let archiver = new MessageArchiver();
archiver.folderDisplay = gFolderDisplay;
archiver.msgWindow = msgWindow;
archiver.archiveMessages(gFolderDisplay.selectedMessages);
@ -4835,7 +4836,7 @@ function OnMsgParsed(aUrl) {
if (
msgHdr &&
!msgHdr.getUint32Property("notAPhishMessage") &&
LazyModules.PhishingDetector.analyzeMsgForPhishingURLs(aUrl, browser)
PhishingDetector.analyzeMsgForPhishingURLs(aUrl, browser)
) {
gMessageNotificationBar.setPhishingMsg();
}

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

@ -46,6 +46,7 @@ messenger.jar:
content/messenger/mail-offline.js (content/mail-offline.js)
content/messenger/mail3PaneWindowCommands.js (content/mail3PaneWindowCommands.js)
content/messenger/mailCommands.js (content/mailCommands.js)
content/messenger/mailCommon.js (content/mailCommon.js)
content/messenger/mailContext.js (content/mailContext.js)
content/messenger/mailCore.js (content/mailCore.js)
content/messenger/mailTabs.js (content/mailTabs.js)