/* 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/. */ /* import-globals-from ../../../../../toolkit/content/contentAreaUtils.js */ /* import-globals-from ../../../../mailnews/addrbook/content/abDragDrop.js */ /* import-globals-from ../../../../mailnews/base/prefs/content/accountUtils.js */ /* import-globals-from ../../../base/content/contentAreaClick.js */ /* import-globals-from ../../../base/content/mailCore.js */ /* import-globals-from ../../../base/content/messenger-customization.js */ /* import-globals-from ../../../base/content/toolbarIconColor.js */ /* import-globals-from ../../../base/content/utilityOverlay.js */ /* import-globals-from ../../../base/content/viewZoomOverlay.js */ /* import-globals-from ../../../base/content/widgets/browserPopups.js */ /* import-globals-from ../../../extensions/openpgp/content/ui/keyAssistant.js */ /* import-globals-from addressingWidgetOverlay.js */ /* import-globals-from cloudAttachmentLinkManager.js */ /* import-globals-from ComposerCommands.js */ /* import-globals-from editor.js */ /* import-globals-from editorUtilities.js */ /** * Commands for the message composition window. */ // Ensure the activity modules are loaded for this window. ChromeUtils.import("resource:///modules/activity/activityModules.jsm"); var { AttachmentChecker } = ChromeUtils.import( "resource:///modules/AttachmentChecker.jsm" ); var { cloudFileAccounts } = ChromeUtils.import( "resource:///modules/cloudFileAccounts.jsm" ); var { MimeParser } = ChromeUtils.import("resource:///modules/mimeParser.jsm"); var { MailServices } = ChromeUtils.import( "resource:///modules/MailServices.jsm" ); var { PluralForm } = ChromeUtils.importESModule( "resource://gre/modules/PluralForm.sys.mjs" ); var { AppConstants } = ChromeUtils.importESModule( "resource://gre/modules/AppConstants.sys.mjs" ); var { ExtensionParent } = ChromeUtils.importESModule( "resource://gre/modules/ExtensionParent.sys.mjs" ); ChromeUtils.defineESModuleGetters(this, { SelectionUtils: "resource://gre/modules/SelectionUtils.sys.mjs", ShortcutUtils: "resource://gre/modules/ShortcutUtils.sys.mjs", }); XPCOMUtils.defineLazyModuleGetters(this, { FolderUtils: "resource:///modules/FolderUtils.jsm", MailUtils: "resource:///modules/MailUtils.jsm", EnigmailKeyRing: "chrome://openpgp/content/modules/keyRing.jsm", BondOpenPGP: "chrome://openpgp/content/BondOpenPGP.jsm", UIFontSize: "resource:///modules/UIFontSize.jsm", UIDensity: "resource:///modules/UIDensity.jsm", }); XPCOMUtils.defineLazyGetter( this, "l10nCompose", () => new Localization([ "branding/brand.ftl", "messenger/messengercompose/messengercompose.ftl", ]) ); XPCOMUtils.defineLazyGetter( this, "l10nComposeSync", () => new Localization( ["branding/brand.ftl", "messenger/messengercompose/messengercompose.ftl"], true ) ); XPCOMUtils.defineLazyServiceGetter( this, "gMIMEService", "@mozilla.org/mime;1", "nsIMIMEService" ); XPCOMUtils.defineLazyScriptGetter( this, "PrintUtils", "chrome://messenger/content/printUtils.js" ); const lazy = {}; XPCOMUtils.defineLazyModuleGetters(lazy, { MailStringUtils: "resource:///modules/MailStringUtils.jsm", }); /** * Global message window object. This is used by mail-offline.js and therefore * should not be renamed. We need to avoid doing this kind of cross file global * stuff in the future and instead pass this object as parameter when needed by * functions in the other js file. */ var msgWindow; var gMessenger; /** * Global variables, need to be re-initialized every time mostly because * we need to release them when the window closes. */ var gMsgCompose; var gOriginalMsgURI; var gWindowLocked; var gSendLocked; var gContentChanged; var gSubjectChanged; var gAutoSaving; var gCurrentIdentity; var defaultSaveOperation; var gSendOperationInProgress; var gSaveOperationInProgress; var gCloseWindowAfterSave; var gSavedSendNowKey; var gContextMenu; var gLastFocusElement = null; var gLoadingComplete = false; var gAttachmentBucket; var gAttachmentCounter; /** * typedef {Object} FocusArea * * @property {Element} root - The root of a given area of the UI. * @property {moveFocusWithin} focus - A method to move the focus within the * root. */ /** * @callback moveFocusWithin * * @param {Element} root - The element to move the focus within. * * @returns {boolean} - Whether the focus was successfully moved to within the * given element. */ /** * An ordered list of non-intersecting areas we want to jump focus between. * Ordering should be in the same order as tab focus. See * {@link moveFocusToNeighbouringArea}. * * @type {FocusArea[]} */ var gFocusAreas; // TODO: Maybe the following two variables can be combined. var gManualAttachmentReminder; var gDisableAttachmentReminder; var gComposeType; var gLanguageObserver; var gRecipientObserver; var gWantCannotEncryptBCCNotification = true; var gRecipientKeysObserver; var gCheckPublicRecipientsTimer; var gBodyFromArgs; // gSMFields is the nsIMsgComposeSecure instance for S/MIME. // gMsgCompose.compFields.composeSecure is set to this instance most of // the time. Because the S/MIME code has no knowledge of the OpenPGP // implementation, gMsgCompose.compFields.composeSecure is set to an // instance of PgpMimeEncrypt only temporarily. Keeping variable // gSMFields separate allows switching as needed. var gSMFields = null; var gSMPendingCertLookupSet = new Set(); var gSMCertsAlreadyLookedUpInLDAP = new Set(); var gSelectedTechnologyIsPGP = false; // The initial flags store the value we used at composer open time. // Some flags might be automatically changed as a consequence of other // changes. When reverting automatic actions, the initial flags help // us know what value we should use for restoring. var gSendSigned = false; var gAttachMyPublicPGPKey = false; var gSendEncrypted = false; // gEncryptSubject contains the preference for subject encryption, // considered only if encryption is enabled and the technology allows it. // In other words, gEncryptSubject might be set to true, but if // encryption is disabled, or if S/MIME is used, // gEncryptSubject==true is ignored. var gEncryptSubject = false; var gUserTouchedSendEncrypted = false; var gUserTouchedSendSigned = false; var gUserTouchedAttachMyPubKey = false; var gUserTouchedEncryptSubject = false; var gIsRelatedToEncryptedOriginal = false; var gOpened = Date.now(); var gEncryptedURIService = Cc[ "@mozilla.org/messenger-smime/smime-encrypted-uris-service;1" ].getService(Ci.nsIEncryptedSMIMEURIsService); try { var gDragService = Cc["@mozilla.org/widget/dragservice;1"].getService( Ci.nsIDragService ); } catch (e) {} /** * Boolean variable to keep track of the dragging action of files above the * compose window. * * @type {boolean} */ var gIsDraggingAttachments; /** * Boolean variable to allow showing the attach inline overlay when dragging * links that otherwise would only trigger the add as attachment overlay. * * @type {boolean} */ var gIsValidInline; // i18n globals var _gComposeBundle; function getComposeBundle() { // That one has to be lazy. Getting a reference to an element with a XBL // binding attached will cause the XBL constructors to fire if they haven't // already. If we get a reference to the compose bundle at script load-time, // this will cause the XBL constructor that's responsible for the personas to // fire up, thus executing the personas code while the DOM is not fully built. // Since this