in mailnews/compose/src/nsMsgCompose.cpp [3845:4072]
nsresult nsMsgCompose::ProcessSignature(nsIMsgIdentity* identity, bool aQuoted,
nsString* aMsgBody) {
nsresult rv = NS_OK;
// Now, we can get sort of fancy. This is the time we need to check
// for all sorts of user defined stuff, like signatures and editor
// types and the like!
//
// user_pref(".....sig_file", "y:\\sig.html");
// user_pref(".....attach_signature", true);
// user_pref(".....htmlSigText", "unicode sig");
//
// Note: We will have intelligent signature behavior in that we
// look at the signature file first...if the extension is .htm or
// .html, we assume its HTML, otherwise, we assume it is plain text
//
// ...and that's not all! What we will also do now is look and see if
// the file is an image file. If it is an image file, then we should
// insert the correct HTML into the composer to have it work, but if we
// are doing plain text compose, we should insert some sort of message
// saying "Image Signature Omitted" or something (not done yet).
//
// If there's a sig pref, it will only be used if there is no sig file
// defined, thus if attach_signature is checked, htmlSigText is ignored (bug
// 324495). Plain-text signatures may or may not have a trailing line break
// (bug 428040).
bool attachFile = false;
bool useSigFile = false;
bool htmlSig = false;
bool imageSig = false;
nsAutoString sigData;
nsAutoString sigOutput;
int32_t reply_on_top = 0;
bool sig_bottom = true;
bool suppressSigSep = false;
nsCOMPtr<nsIFile> sigFile;
if (identity) {
if (!CheckIncludeSignaturePrefs(identity)) return NS_OK;
identity->GetReplyOnTop(&reply_on_top);
identity->GetSigBottom(&sig_bottom);
identity->GetSuppressSigSep(&suppressSigSep);
rv = identity->GetAttachSignature(&attachFile);
if (NS_SUCCEEDED(rv) && attachFile) {
rv = identity->GetSignature(getter_AddRefs(sigFile));
if (NS_SUCCEEDED(rv) && sigFile) {
if (!sigFile->NativePath().IsEmpty()) {
bool exists = false;
sigFile->Exists(&exists);
if (exists) {
useSigFile = true; // ok, there's a signature file
// Now, most importantly, we need to figure out what the content
// type is for this signature...if we can't, we assume text
nsAutoCString sigContentType;
nsresult rv2; // don't want to clobber the other rv
nsCOMPtr<nsIMIMEService> mimeFinder(
do_GetService(NS_MIMESERVICE_CONTRACTID, &rv2));
if (NS_SUCCEEDED(rv2)) {
rv2 = mimeFinder->GetTypeFromFile(sigFile, sigContentType);
if (NS_SUCCEEDED(rv2)) {
if (StringBeginsWith(sigContentType, "image/"_ns,
nsCaseInsensitiveCStringComparator))
imageSig = true;
else if (sigContentType.Equals(
TEXT_HTML, nsCaseInsensitiveCStringComparator))
htmlSig = true;
}
}
}
}
}
}
}
// Unless signature to be attached from file, use preference value;
// the htmlSigText value is always going to be treated as html if
// the htmlSigFormat pref is true, otherwise it is considered text
nsAutoString prefSigText;
if (identity && !attachFile) identity->GetHtmlSigText(prefSigText);
// Now, if they didn't even want to use a signature, we should
// just return nicely.
//
if ((!useSigFile && prefSigText.IsEmpty()) || NS_FAILED(rv)) return NS_OK;
static const char htmlBreak[] = "<br>";
static const char dashes[] = "-- ";
static const char htmlsigopen[] = "<div class=\"moz-signature\">";
static const char htmlsigclose[] = "</div>"; /* XXX: Due to a bug in
4.x' HTML editor, it will not be able to
break this HTML sig, if quoted (for the user to
interleave a comment). */
static const char _preopen[] = "<pre class=\"moz-signature\" cols=%d>";
char* preopen;
static const char preclose[] = "</pre>";
int32_t wrapLength = 72; // setup default value in case GetWrapLength failed
GetWrapLength(&wrapLength);
preopen = PR_smprintf(_preopen, wrapLength);
if (!preopen) return NS_ERROR_OUT_OF_MEMORY;
bool paragraphMode =
mozilla::Preferences::GetBool("mail.compose.default_to_paragraph", false);
if (imageSig) {
// We have an image signature. If we're using the in HTML composer, we
// should put in the appropriate HTML for inclusion, otherwise, do nothing.
if (m_composeHTML) {
if (!paragraphMode) sigOutput.AppendLiteral(htmlBreak);
sigOutput.AppendLiteral(htmlsigopen);
if ((mType == nsIMsgCompType::NewsPost || !suppressSigSep) &&
(reply_on_top != 1 || sig_bottom || !aQuoted)) {
sigOutput.AppendLiteral(dashes);
}
sigOutput.AppendLiteral(htmlBreak);
sigOutput.AppendLiteral("<img src='");
nsCOMPtr<nsIURI> fileURI;
nsresult rv = NS_NewFileURI(getter_AddRefs(fileURI), sigFile);
NS_ENSURE_SUCCESS(rv, rv);
nsCString fileURL;
fileURI->GetSpec(fileURL);
nsString dataURL;
rv = DataURLForFileURL(NS_ConvertUTF8toUTF16(fileURL), dataURL);
if (NS_SUCCEEDED(rv)) {
sigOutput.Append(dataURL);
}
sigOutput.AppendLiteral("' border=0>");
sigOutput.AppendLiteral(htmlsigclose);
}
} else if (useSigFile) {
// is this a text sig with an HTML editor?
if ((m_composeHTML) && (!htmlSig)) {
ConvertTextToHTML(sigFile, sigData);
}
// is this a HTML sig with a text window?
else if ((!m_composeHTML) && (htmlSig)) {
ConvertHTMLToText(sigFile, sigData);
} else { // We have a match...
LoadDataFromFile(sigFile, sigData); // Get the data!
ReplaceFileURLs(sigData);
}
}
// if we have a prefSigText, append it to sigData.
if (!prefSigText.IsEmpty()) {
// set htmlSig if the pref is supposed to contain HTML code, defaults to
// false
rv = identity->GetHtmlSigFormat(&htmlSig);
if (NS_FAILED(rv)) htmlSig = false;
if (!m_composeHTML) {
if (htmlSig) ConvertBufToPlainText(prefSigText, false, true, true);
sigData.Append(prefSigText);
} else {
if (!htmlSig) {
nsCString escapedUTF8;
nsAppendEscapedHTML(NS_ConvertUTF16toUTF8(prefSigText), escapedUTF8);
sigData.Append(NS_ConvertUTF8toUTF16(escapedUTF8));
} else {
ReplaceFileURLs(prefSigText);
sigData.Append(prefSigText);
}
}
}
// post-processing for plain-text signatures to ensure we end in CR, LF, or
// CRLF
if (!htmlSig && !m_composeHTML) {
int32_t sigLength = sigData.Length();
if (sigLength > 0 && !(sigData.CharAt(sigLength - 1) == '\r') &&
!(sigData.CharAt(sigLength - 1) == '\n'))
sigData.AppendLiteral(CRLF);
}
// Now that sigData holds data...if any, append it to the body in a nice
// looking manner
if (!sigData.IsEmpty()) {
if (m_composeHTML) {
if (!paragraphMode) sigOutput.AppendLiteral(htmlBreak);
if (htmlSig)
sigOutput.AppendLiteral(htmlsigopen);
else
sigOutput.Append(NS_ConvertASCIItoUTF16(preopen));
}
if ((reply_on_top != 1 || sig_bottom || !aQuoted) &&
sigData.Find(u"\r-- \r") < 0 && sigData.Find(u"\n-- \n") < 0 &&
sigData.Find(u"\n-- \r") < 0) {
nsDependentSubstring firstFourChars(sigData, 0, 4);
if ((mType == nsIMsgCompType::NewsPost || !suppressSigSep) &&
!(firstFourChars.EqualsLiteral("-- \n") ||
firstFourChars.EqualsLiteral("-- \r"))) {
sigOutput.AppendLiteral(dashes);
if (!m_composeHTML || !htmlSig)
sigOutput.AppendLiteral(CRLF);
else if (m_composeHTML)
sigOutput.AppendLiteral(htmlBreak);
}
}
// add CRLF before signature for plain-text mode if signature comes before
// quote
if (!m_composeHTML && reply_on_top == 1 && !sig_bottom && aQuoted)
sigOutput.AppendLiteral(CRLF);
sigOutput.Append(sigData);
if (m_composeHTML) {
if (htmlSig)
sigOutput.AppendLiteral(htmlsigclose);
else
sigOutput.AppendLiteral(preclose);
}
}
aMsgBody->Append(sigOutput);
PR_Free(preopen);
return NS_OK;
}