From 951174421d327232a8ee7ef33bb40a29fd861522 Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Thu, 26 Feb 2015 15:26:12 -0500 Subject: [PATCH] Bug 1125963 - Part 1: Fix serialization of the pre-wrap elements that Thunderbird relies on; r=bzbarsky This ensures that the plaintext serializer doesn't use the preformatted text code path if we have encountered a pre-wrap element that Thunderbird uses (which means setting white-space: pre-wrap and width: NNch on the body element.) It also ensures that we use 0 as the wrap column number passed down to the plaintext serializer, instead of -1, which this code seems to be unable to handle properly. --- dom/base/nsPlainTextSerializer.cpp | 4 +-- dom/base/test/TestPlainTextSerializer.cpp | 36 +++++++++++++++++++++++ dom/html/HTMLInputElement.cpp | 2 +- dom/html/HTMLTextAreaElement.cpp | 2 +- dom/html/nsTextEditorState.cpp | 2 +- 5 files changed, 41 insertions(+), 5 deletions(-) diff --git a/dom/base/nsPlainTextSerializer.cpp b/dom/base/nsPlainTextSerializer.cpp index b721008e63b..370d16b2150 100644 --- a/dom/base/nsPlainTextSerializer.cpp +++ b/dom/base/nsPlainTextSerializer.cpp @@ -1556,14 +1556,14 @@ nsPlainTextSerializer::Write(const nsAString& aStr) // We have two major codepaths here. One that does preformatted text and one // that does normal formatted text. The one for preformatted text calls // Output directly while the other code path goes through AddToLine. - if ((mPreFormatted && !mWrapColumn) || IsInPre() + if ((mPreFormatted && !mWrapColumn) || (IsInPre() && !mPreFormatted) || ((mSpanLevel > 0 || mDontWrapAnyQuotes) && mEmptyLines >= 0 && str.First() == char16_t('>'))) { // No intelligent wrapping. // This mustn't be mixed with intelligent wrapping without clearing // the mCurrentLine buffer before!!! - NS_ASSERTION(mCurrentLine.IsEmpty() || IsInPre(), + NS_ASSERTION(mCurrentLine.IsEmpty() || (IsInPre() && !mPreFormatted), "Mixed wrapping data and nonwrapping data on the same line"); if (!mCurrentLine.IsEmpty()) { FlushLine(); diff --git a/dom/base/test/TestPlainTextSerializer.cpp b/dom/base/test/TestPlainTextSerializer.cpp index b1a7f241350..eab7a83d22c 100644 --- a/dom/base/test/TestPlainTextSerializer.cpp +++ b/dom/base/test/TestPlainTextSerializer.cpp @@ -162,6 +162,39 @@ TestBlockElement() return NS_OK; } +nsresult +TestPreWrapElementForThunderbird() +{ + // This test examines the magic pre-wrap setup that Thunderbird relies on. + nsString test; + test.AppendLiteral( + "" NS_LINEBREAK + "" NS_LINEBREAK + "
" NS_LINEBREAK
+    "  first line is too long" NS_LINEBREAK
+    "  second line is even loooonger  " NS_LINEBREAK
+    "
" NS_LINEBREAK + "" NS_LINEBREAK ""); + + ConvertBufToPlainText(test, nsIDocumentEncoder::OutputWrap); + // "\n\n first\nline is\ntoo long\n second\nline is\neven\nloooonger\n\n\n" + if (!test.EqualsLiteral(NS_LINEBREAK NS_LINEBREAK + " first" NS_LINEBREAK + "line is" NS_LINEBREAK + "too long" NS_LINEBREAK + " second" NS_LINEBREAK + "line is" NS_LINEBREAK + "even" NS_LINEBREAK + "loooonger" NS_LINEBREAK + NS_LINEBREAK NS_LINEBREAK)) { + fail("Wrong prettyprinted html to text serialization"); + return NS_ERROR_FAILURE; + } + + passed("prettyprinted HTML to text serialization test"); + return NS_OK; +} + nsresult TestPlainTextSerializer() { @@ -191,6 +224,9 @@ TestPlainTextSerializer() rv = TestBlockElement(); NS_ENSURE_SUCCESS(rv, rv); + rv = TestPreWrapElementForThunderbird(); + NS_ENSURE_SUCCESS(rv, rv); + // Add new tests here... return NS_OK; } diff --git a/dom/html/HTMLInputElement.cpp b/dom/html/HTMLInputElement.cpp index 6d756bb540b..156bb2bfa33 100644 --- a/dom/html/HTMLInputElement.cpp +++ b/dom/html/HTMLInputElement.cpp @@ -7219,7 +7219,7 @@ HTMLInputElement::GetCols() NS_IMETHODIMP_(int32_t) HTMLInputElement::GetWrapCols() { - return -1; // only textarea's can have wrap cols + return 0; // only textarea's can have wrap cols } NS_IMETHODIMP_(int32_t) diff --git a/dom/html/HTMLTextAreaElement.cpp b/dom/html/HTMLTextAreaElement.cpp index e988c0e8e2a..a0903f92ab5 100644 --- a/dom/html/HTMLTextAreaElement.cpp +++ b/dom/html/HTMLTextAreaElement.cpp @@ -1480,7 +1480,7 @@ HTMLTextAreaElement::GetWrapCols() nsITextControlElement::GetWrapPropertyEnum(this, wrapProp); if (wrapProp == nsITextControlElement::eHTMLTextWrap_Off) { // do not wrap when wrap=off - return -1; + return 0; } // Otherwise we just wrap at the given number of columns diff --git a/dom/html/nsTextEditorState.cpp b/dom/html/nsTextEditorState.cpp index 92e82675366..88da8f64eb4 100644 --- a/dom/html/nsTextEditorState.cpp +++ b/dom/html/nsTextEditorState.cpp @@ -1713,7 +1713,7 @@ nsTextEditorState::InitializeRootNode() nsAutoString classValue; classValue.AppendLiteral("anonymous-div"); int32_t wrapCols = GetWrapCols(); - if (wrapCols >= 0) { + if (wrapCols > 0) { classValue.AppendLiteral(" wrap"); } if (!IsSingleLineTextControl()) {