in suite/mailnews/components/compose/content/MsgComposeCommands.js [1198:1563]
function ComposeStartup(aParams)
{
var params = null; // New way to pass parameters to the compose window as a nsIMsgComposeParameters object
var args = null; // old way, parameters are passed as a string
gBodyFromArgs = false;
if (aParams)
params = aParams;
else if (window.arguments && window.arguments[0]) {
try {
if (window.arguments[0] instanceof Ci.nsIMsgComposeParams)
params = window.arguments[0];
else
params = handleMailtoArgs(window.arguments[0]);
}
catch(ex) { dump("ERROR with parameters: " + ex + "\n"); }
// if still no dice, try and see if the params is an old fashioned list of string attributes
// XXX can we get rid of this yet?
if (!params)
{
args = GetArgs(window.arguments[0]);
}
}
// Set the document language to the preference as early as possible.
document.documentElement
.setAttribute("lang", Services.prefs.getCharPref("spellchecker.dictionary"));
var identityList = GetMsgIdentityElement();
document.addEventListener("paste", onPasteOrDrop);
document.addEventListener("drop", onPasteOrDrop);
if (identityList)
FillIdentityList(identityList);
if (!params) {
// This code will go away soon as now arguments are passed to the window
// using a object of type nsMsgComposeParams instead of a string.
params = Cc["@mozilla.org/messengercompose/composeparams;1"]
.createInstance(Ci.nsIMsgComposeParams);
params.composeFields = Cc["@mozilla.org/messengercompose/composefields;1"]
.createInstance(Ci.nsIMsgCompFields);
if (args) { //Convert old fashion arguments into params
var composeFields = params.composeFields;
if (args.bodyislink && args.bodyislink == "true")
params.bodyIsLink = true;
if (args.type)
params.type = args.type;
if (args.format) {
// Only use valid values.
if (args.format == Ci.nsIMsgCompFormat.PlainText ||
args.format == Ci.nsIMsgCompFormat.HTML ||
args.format == Ci.nsIMsgCompFormat.OppositeOfDefault)
params.format = args.format;
else if (args.format.toLowerCase().trim() == "html")
params.format = Ci.nsIMsgCompFormat.HTML;
else if (args.format.toLowerCase().trim() == "text")
params.format = Ci.nsIMsgCompFormat.PlainText;
}
if (args.originalMsgURI)
params.originalMsgURI = args.originalMsgURI;
if (args.preselectid)
params.identity = getIdentityForKey(args.preselectid);
if (args.from)
composeFields.from = args.from;
if (args.to)
composeFields.to = args.to;
if (args.cc)
composeFields.cc = args.cc;
if (args.bcc)
composeFields.bcc = args.bcc;
if (args.newsgroups)
composeFields.newsgroups = args.newsgroups;
if (args.subject)
composeFields.subject = args.subject;
if (args.attachment)
{
var attachmentList = args.attachment.split(",");
var commandLine = Cc["@mozilla.org/toolkit/command-line;1"]
.createInstance();
for (let i = 0; i < attachmentList.length; i++)
{
let attachmentStr = attachmentList[i];
let uri = commandLine.resolveURI(attachmentStr);
let attachment = Cc["@mozilla.org/messengercompose/attachment;1"]
.createInstance(Ci.nsIMsgAttachment);
if (uri instanceof Ci.nsIFileURL)
{
if (uri.file.exists())
attachment.size = uri.file.fileSize;
else
attachment = null;
}
// Only want to attach if a file that exists or it is not a file.
if (attachment)
{
attachment.url = uri.spec;
composeFields.addAttachment(attachment);
}
else
{
let title = sComposeMsgsBundle.getString("errorFileAttachTitle");
let msg = sComposeMsgsBundle.getFormattedString("errorFileAttachMessage",
[attachmentStr]);
Services.prompt.alert(null, title, msg);
}
}
}
if (args.newshost)
composeFields.newshost = args.newshost;
if (args.message) {
let msgFile = Cc["@mozilla.org/file/local;1"]
.createInstance(Ci.nsIFile);
if (OS.Path.dirname(args.message) == ".") {
let workingDir = Services.dirsvc.get("CurWorkD", Ci.nsIFile);
args.message = OS.Path.join(workingDir.path, OS.Path.basename(args.message));
}
msgFile.initWithPath(args.message);
if (!msgFile.exists()) {
let title = sComposeMsgsBundle.getString("errorFileMessageTitle");
let msg = sComposeMsgsBundle.getFormattedString("errorFileMessageMessage",
[args.message]);
Services.prompt.alert(null, title, msg);
} else {
let data = "";
let fstream = null;
let cstream = null;
try {
fstream = Cc["@mozilla.org/network/file-input-stream;1"]
.createInstance(Ci.nsIFileInputStream);
cstream = Cc["@mozilla.org/intl/converter-input-stream;1"]
.createInstance(Ci.nsIConverterInputStream);
fstream.init(msgFile, -1, 0, 0); // Open file in default/read-only mode.
cstream.init(fstream, "UTF-8", 0, 0);
let str = {};
let read = 0;
do {
// Read as much as we can and put it in str.value.
read = cstream.readString(0xffffffff, str);
data += str.value;
} while (read != 0);
} catch (e) {
let title = sComposeMsgsBundle.getString("errorFileMessageTitle");
let msg = sComposeMsgsBundle.getFormattedString("errorLoadFileMessageMessage",
[args.message]);
Services.prompt.alert(null, title, msg);
} finally {
if (cstream)
cstream.close();
if (fstream)
fstream.close();
}
if (data) {
let pos = data.search(/\S/); // Find first non-whitespace character.
if (params.format != Ci.nsIMsgCompFormat.PlainText &&
(args.message.endsWith(".htm") ||
args.message.endsWith(".html") ||
data.substr(pos, 14).toLowerCase() == "<!doctype html" ||
data.substr(pos, 5).toLowerCase() == "<html")) {
// We replace line breaks because otherwise they'll be converted
// to <br> in nsMsgCompose::BuildBodyMessageAndSignature().
// Don't do the conversion if the user asked explicitly for plain
// text.
data = data.replace(/\r?\n/g, " ");
}
gBodyFromArgs = true;
composeFields.body = data;
}
}
} else if (args.body) {
gBodyFromArgs = true;
composeFields.body = args.body;
}
}
}
gComposeType = params.type;
// Detect correct identity when missing or mismatched.
// An identity with no email is likely not valid.
// When editing a draft, 'params.identity' is pre-populated with the identity
// that created the draft or the identity owning the draft folder for a
// "foreign", draft, see ComposeMessage() in mailCommands.js. We don't want
// the latter, so use the creator identity which could be null.
if (gComposeType == Ci.nsIMsgCompType.Draft) {
let creatorKey = params.composeFields.creatorIdentityKey;
params.identity = creatorKey ? getIdentityForKey(creatorKey) : null;
}
let from = [];
if (params.composeFields.from)
from = MailServices.headerParser
.parseEncodedHeader(params.composeFields.from, null);
from = (from.length && from[0] && from[0].email) ?
from[0].email.toLowerCase().trim() : null;
if (!params.identity || !params.identity.email ||
(from && !emailSimilar(from, params.identity.email))) {
let identities = MailServices.accounts.allIdentities;
let suitableCount = 0;
// Search for a matching identity.
if (from) {
for (let ident of identities) {
if (ident.email && from == ident.email.toLowerCase()) {
if (suitableCount == 0)
params.identity = ident;
suitableCount++;
if (suitableCount > 1)
break; // No need to find more, it's already not unique.
}
}
}
if (!params.identity || !params.identity.email) {
let identity = null;
// No preset identity and no match, so use the default account.
let defaultAccount = MailServices.accounts.defaultAccount;
if (defaultAccount) {
identity = defaultAccount.defaultIdentity;
}
if (!identity) {
// Get the first identity we have in the list.
let identitykey = identityList.getItemAtIndex(0).getAttribute("identitykey");
identity = MailServices.accounts.getIdentity(identitykey);
}
params.identity = identity;
}
// Warn if no or more than one match was found.
// But don't warn for +suffix additions (a+b@c.com).
if (from && (suitableCount > 1 ||
(suitableCount == 0 && !emailSimilar(from, params.identity.email))))
gComposeNotificationBar.setIdentityWarning(params.identity.identityName);
}
identityList.selectedItem =
identityList.getElementsByAttribute("identitykey", params.identity.key)[0];
if (params.composeFields.from)
identityList.value = MailServices.headerParser.parseDecodedHeader(params.composeFields.from)[0].toString();
LoadIdentity(true);
// Get the <editor> element to startup an editor
var editorElement = GetCurrentEditorElement();
// Remember the original message URI. When editing a draft which is a reply
// or forwarded message, this gets overwritten by the ancestor's message URI
// so the disposition flags ("replied" or "forwarded") can be set on the
// ancestor.
// For our purposes we need the URI of the message being processed, not its
// original ancestor.
gOriginalMsgURI = params.originalMsgURI;
gMsgCompose = MailServices.compose.initCompose(params, window,
editorElement.docShell);
document.getElementById("returnReceiptMenu")
.setAttribute("checked", gMsgCompose.compFields.returnReceipt);
document.getElementById("dsnMenu")
.setAttribute('checked', gMsgCompose.compFields.DSN);
document.getElementById("cmd_attachVCard")
.setAttribute("checked", gMsgCompose.compFields.attachVCard);
document.getElementById("menu_inlineSpellCheck")
.setAttribute("checked",
Services.prefs.getBoolPref("mail.spellcheck.inline"));
let editortype = gMsgCompose.composeHTML ? "htmlmail" : "textmail";
editorElement.makeEditable(editortype, true);
// setEditorType MUST be call before setContentWindow
if (gMsgCompose.composeHTML) {
initLocalFontFaceMenu(document.getElementById("FontFacePopup"));
} else {
//Remove HTML toolbar, format and insert menus as we are editing in plain
//text mode.
let toolbar = document.getElementById("FormatToolbar");
toolbar.hidden = true;
toolbar.setAttribute("hideinmenu", "true");
document.getElementById("outputFormatMenu").setAttribute("hidden", true);
document.getElementById("formatMenu").setAttribute("hidden", true);
document.getElementById("insertMenu").setAttribute("hidden", true);
}
// Do setup common to Message Composer and Web Composer.
EditorSharedStartup();
if (params.bodyIsLink) {
let body = gMsgCompose.compFields.body;
if (gMsgCompose.composeHTML) {
let cleanBody;
try {
cleanBody = decodeURI(body);
} catch(e) {
cleanBody = body;
}
body = body.replace(/&/g, "&");
gMsgCompose.compFields.body =
"<br /><a href=\"" + body + "\">" + cleanBody + "</a><br />";
} else {
gMsgCompose.compFields.body = "\n<" + body + ">\n";
}
}
GetMsgSubjectElement().value = gMsgCompose.compFields.subject;
var attachments = gMsgCompose.compFields.attachments;
while (attachments.hasMoreElements()) {
AddAttachment(attachments.getNext().QueryInterface(Ci.nsIMsgAttachment));
}
var event = document.createEvent('Events');
event.initEvent('compose-window-init', false, true);
document.getElementById("msgcomposeWindow").dispatchEvent(event);
gMsgCompose.RegisterStateListener(stateListener);
// Add an observer to be called when document is done loading,
// which creates the editor.
try {
GetCurrentCommandManager().addCommandObserver(gMsgEditorCreationObserver,
"obs_documentCreated");
// Load empty page to create the editor
editorElement.webNavigation.loadURI("about:blank",
Ci.nsIWebNavigation.LOAD_FLAGS_NONE,
null, // referrer
null, // post-data stream
null, // HTTP headers
Services.scriptSecurityManager.getSystemPrincipal());
} catch (e) {
dump(" Failed to startup editor: "+e+"\n");
}
// create URI of the folder from draftId
var draftId = gMsgCompose.compFields.draftId;
var folderURI = draftId.substring(0, draftId.indexOf("#")).replace("-message", "");
try {
var folder = sRDF.GetResource(folderURI);
gEditingDraft = (folder instanceof Ci.nsIMsgFolder) &&
(folder.flags & Ci.nsMsgFolderFlags.Drafts);
}
catch (ex) {
gEditingDraft = false;
}
gAutoSaveKickedIn = false;
gAutoSaveInterval = Services.prefs.getBoolPref("mail.compose.autosave")
? Services.prefs.getIntPref("mail.compose.autosaveinterval") * 60000
: 0;
if (gAutoSaveInterval)
gAutoSaveTimeout = setTimeout(AutoSave, gAutoSaveInterval);
}