# HG changeset patch # User Jorg K # Date 1528746207 -7200 # Node ID 69b679d3217a37cc969e4590ef93a1ac269a9a69 # Parent 0bfa3e78ea751306ca9f57336ab84ba28c10078f Bug 1464667 - Remove plaintext tag from HTML. r=mkmelin a=jorgk diff --git a/mailnews/compose/src/nsMsgCompose.cpp b/mailnews/compose/src/nsMsgCompose.cpp --- a/mailnews/compose/src/nsMsgCompose.cpp +++ b/mailnews/compose/src/nsMsgCompose.cpp @@ -616,16 +616,41 @@ nsMsgCompose::InsertDivWrappedTextAtSele if (selection) selection->Collapse(parent, offset + 1); } if (divElem) divElem->SetAttribute(NS_LITERAL_STRING("class"), classStr); } +/* + * The following function replaces tags with <x-plaintext>. + * <plaintext> is a funny beast: It leads to everything following it + * being displayed verbatim, even a </plaintext> tag is ignored. + */ +static void +remove_plaintext_tag(nsString &body) +{ + // Replace all <plaintext> and </plaintext> tags. + int32_t index = 0; + bool replaced = false; + while ((index = body.Find("<plaintext", /* ignoreCase = */ true, index)) != kNotFound) { + body.Insert(u"x-", index+1); + index += 12; + replaced = true; + } + if (replaced) { + index = 0; + while ((index = body.Find("</plaintext", /* ignoreCase = */ true, index)) != kNotFound) { + body.Insert(u"x-", index+2); + index += 13; + } + } +} + NS_IMETHODIMP nsMsgCompose::ConvertAndLoadComposeWindow(nsString& aPrefix, nsString& aBuf, nsString& aSignature, bool aQuoted, bool aHTMLEditor) { NS_ASSERTION(m_editor, "ConvertAndLoadComposeWindow but no editor\n"); @@ -701,25 +726,27 @@ nsMsgCompose::ConvertAndLoadComposeWindo InsertDivWrappedTextAtSelection(aPrefix, NS_LITERAL_STRING("moz-cite-prefix")); } if (!aBuf.IsEmpty() && mailEditor) { // This leaves the caret at the right place to insert a bottom signature. - if (aHTMLEditor) - mailEditor->InsertAsCitedQuotation(aBuf, + if (aHTMLEditor) { + nsAutoString body(aBuf); + remove_plaintext_tag(body); + mailEditor->InsertAsCitedQuotation(body, mCiteReference, true, getter_AddRefs(nodeInserted)); - else + } else { mailEditor->InsertAsQuotation(aBuf, getter_AddRefs(nodeInserted)); - + } } mInsertingQuotedContent = false; (void)TagEmbeddedObjects(mailEditor); if (!aSignature.IsEmpty()) { @@ -753,16 +780,17 @@ nsMsgCompose::ConvertAndLoadComposeWindo // forwarded content like this: // <HTML><BODY><BR><BR> + forwarded header + header table. // Note: We only do this when we prepare the message to be forwarded, // a re-opened saved draft of a forwarded message does not repeat this. nsString newBody(aBuf); nsString divTag; divTag.AssignLiteral("<div class=\"moz-forward-container\">"); newBody.Insert(divTag, sizeof(MIME_FORWARD_HTML_PREFIX)-1-8); + remove_plaintext_tag(newBody); htmlEditor->RebuildDocumentFromSource(newBody); } else { htmlEditor->RebuildDocumentFromSource(aBuf); } mInsertingQuotedContent = false; // when forwarding a message as inline, tag any embedded objects // which refer to local images or files so we know not to include @@ -3120,21 +3148,24 @@ QuotingOutputStreamListener::InsertToCom nsCOMPtr<nsIPlaintextEditor> textEditor (do_QueryInterface(aEditor)); if (textEditor) textEditor->InsertText(mCitePrefix); } nsCOMPtr<nsIEditorMailSupport> mailEditor (do_QueryInterface(aEditor)); if (mailEditor) { - if (aHTMLEditor) - mailEditor->InsertAsCitedQuotation(mMsgBody, EmptyString(), true, + if (aHTMLEditor) { + nsAutoString body(mMsgBody); + remove_plaintext_tag(body); + mailEditor->InsertAsCitedQuotation(body, EmptyString(), true, getter_AddRefs(nodeInserted)); - else + } else { mailEditor->InsertAsQuotation(mMsgBody, getter_AddRefs(nodeInserted)); + } } compose->SetInsertingQuotedContent(false); } if (aEditor) { nsCOMPtr<nsIPlaintextEditor> textEditor = do_QueryInterface(aEditor); if (textEditor) diff --git a/mailnews/mime/src/mimeTextHTMLParsed.cpp b/mailnews/mime/src/mimeTextHTMLParsed.cpp --- a/mailnews/mime/src/mimeTextHTMLParsed.cpp +++ b/mailnews/mime/src/mimeTextHTMLParsed.cpp @@ -128,16 +128,17 @@ MimeInlineTextHTMLParsed_parse_eof(MimeO rv = encoder->Init(document, NS_LITERAL_STRING("text/html"), aFlags); NS_ENSURE_SUCCESS(rv, -1); rv = encoder->EncodeToString(parsed); NS_ENSURE_SUCCESS(rv, -1); // Write it out. NS_ConvertUTF16toUTF8 resultCStr(parsed); MimeInlineTextHTML_insert_lang_div(obj, resultCStr); + MimeInlineTextHTML_remove_plaintext_tag(obj, resultCStr); status = ((MimeObjectClass*)&MIME_SUPERCLASS)->parse_line( resultCStr.BeginWriting(), resultCStr.Length(), obj); rawHTML.Truncate(); return status; } void MimeInlineTextHTMLParsed_finalize(MimeObject *obj) diff --git a/mailnews/mime/src/mimethsa.cpp b/mailnews/mime/src/mimethsa.cpp --- a/mailnews/mime/src/mimethsa.cpp +++ b/mailnews/mime/src/mimethsa.cpp @@ -119,16 +119,18 @@ MimeInlineTextHTMLSanitized_parse_eof(Mi nsString sanitized; // Sanitize. HTMLSanitize(cb, sanitized); // Write it out. NS_ConvertUTF16toUTF8 resultCStr(sanitized); MimeInlineTextHTML_insert_lang_div(obj, resultCStr); + // Call to MimeInlineTextHTML_remove_plaintext_tag() not needed since + // sanitization already removes that tag. status = ((MimeObjectClass*)&MIME_SUPERCLASS)->parse_line( resultCStr.BeginWriting(), resultCStr.Length(), obj); cb.Truncate(); return status; } diff --git a/mailnews/mime/src/mimethtm.cpp b/mailnews/mime/src/mimethtm.cpp --- a/mailnews/mime/src/mimethtm.cpp +++ b/mailnews/mime/src/mimethtm.cpp @@ -188,17 +188,17 @@ MimeInlineTextHTML_parse_eof (MimeObject void MimeInlineTextHTML_insert_lang_div(MimeObject *obj, nsCString &message) { if (obj->options->format_out != nsMimeOutput::nsMimeMessageBodyDisplay && obj->options->format_out != nsMimeOutput::nsMimeMessagePrintOutput) return; // Make sure we have a <body> before we start. - int32_t index = message.Find("<body"); + int32_t index = message.Find("<body", /* ignoreCase = */ true); if (index == kNotFound) return; index = message.FindChar('>', index) + 1; // Insert <div class="moz-text-html" lang="..."> for the following two purposes: // 1) Users can configure their HTML display via CSS for .moz-text-html. // 2) The language group in the 'lang' attribure is used by Gecko to determine // which font to use. @@ -213,12 +213,42 @@ MimeInlineTextHTML_insert_lang_div(MimeO index); } else { message.Insert(NS_LITERAL_CSTRING("<div class=\"moz-text-html\">"), index); } - index = message.RFind("</body>"); + index = message.RFind("</body>", /* ignoreCase = */ true); if (index != kNotFound) message.Insert(NS_LITERAL_CSTRING("</div>"), index); } + +/* + * The following function replaces <plaintext> tags with <x-plaintext>. + * <plaintext> is a funny beast: It leads to everything following it + * being displayed verbatim, even a </plaintext> tag is ignored. + */ +void +MimeInlineTextHTML_remove_plaintext_tag(MimeObject *obj, nsCString &message) +{ + if (obj->options->format_out != nsMimeOutput::nsMimeMessageBodyDisplay && + obj->options->format_out != nsMimeOutput::nsMimeMessagePrintOutput) + return; + + // Replace all <plaintext> and </plaintext> tags. + int32_t index = 0; + bool replaced = false; + while ((index = message.Find("<plaintext", /* ignoreCase = */ true, index)) != kNotFound) { + message.Insert("x-", index+1); + index += 12; + replaced = true; + } + if (replaced) { + index = 0; + while ((index = message.Find("</plaintext", /* ignoreCase = */ true, index)) != kNotFound) { + message.Insert("x-", index+2); + index += 13; + } + } +} + diff --git a/mailnews/mime/src/mimethtm.h b/mailnews/mime/src/mimethtm.h --- a/mailnews/mime/src/mimethtm.h +++ b/mailnews/mime/src/mimethtm.h @@ -25,9 +25,11 @@ struct MimeInlineTextHTML { char *charset; /* If we sniffed a charset, do some converting! */ }; #define MimeInlineTextHTMLClassInitializer(ITYPE,CSUPER) \ { MimeInlineTextClassInitializer(ITYPE,CSUPER) } void MimeInlineTextHTML_insert_lang_div(MimeObject *obj, nsCString &message); +void +MimeInlineTextHTML_remove_plaintext_tag(MimeObject *obj, nsCString &message); #endif /* _MIMETHTM_H_ */