Bug 456053 - Don't trim trailing space of quoted lines. r=masayuki
authorJorg K
Thu, 29 Sep 2016 07:10:00 +0200
changeset 419070 18faa8438eebdf4b25f37b54f645087585b7f5fa
parent 419069 f325ed1abef16a4090cd6d3fd7a81d245c2de705
child 419071 f64158062a657b86a2c29a7152afc929b6440993
push id30835
push userwcosta@mozilla.com
push dateThu, 29 Sep 2016 17:05:21 +0000
reviewersmasayuki
bugs456053
milestone52.0a1
Bug 456053 - Don't trim trailing space of quoted lines. r=masayuki
dom/base/nsPlainTextSerializer.cpp
dom/base/nsPlainTextSerializer.h
dom/base/test/TestPlainTextSerializer.cpp
--- a/dom/base/nsPlainTextSerializer.cpp
+++ b/dom/base/nsPlainTextSerializer.cpp
@@ -1577,17 +1577,17 @@ nsPlainTextSerializer::Write(const nsASt
         break;
     }
   }
 
   // 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 ((mPreFormattedMail && !mWrapColumn) || (IsInPre() && !mPreFormattedMail)
-      || (mSpanLevel > 0 && mEmptyLines >= 0 && str.First() == char16_t('>'))) {
+      || (mSpanLevel > 0 && mEmptyLines >= 0 && IsQuotedLine(str))) {
     // No intelligent wrapping.
 
     // This mustn't be mixed with intelligent wrapping without clearing
     // the mCurrentLine buffer before!!!
     NS_ASSERTION(mCurrentLine.IsEmpty() || (IsInPre() && !mPreFormattedMail),
                  "Mixed wrapping data and nonwrapping data on the same line");
     if (!mCurrentLine.IsEmpty()) {
       FlushLine();
@@ -1652,20 +1652,21 @@ nsPlainTextSerializer::Write(const nsASt
           // over the LF.
           bol++;
         }
       }
 
       mCurrentLine.Truncate();
       if (mFlags & nsIDocumentEncoder::OutputFormatFlowed) {
         if ((outputLineBreak || !spacesOnly) && // bugs 261467,125928
+            !IsQuotedLine(stringpart) &&
             !stringpart.EqualsLiteral("-- ") &&
             !stringpart.EqualsLiteral("- -- "))
           stringpart.Trim(" ", false, true, true);
-        if (IsSpaceStuffable(stringpart.get()) && stringpart[0] != '>')
+        if (IsSpaceStuffable(stringpart.get()) && !IsQuotedLine(stringpart))
           mCurrentLine.Append(char16_t(' '));
       }
       mCurrentLine.Append(stringpart);
 
       if (outputQuotes) {
         // Note: this call messes with mAtFirstColumn
         OutputQuotesAndIndent();
       }
--- a/dom/base/nsPlainTextSerializer.h
+++ b/dom/base/nsPlainTextSerializer.h
@@ -105,16 +105,21 @@ private:
     return !(mFlags & nsIDocumentEncoder::OutputDisallowLineBreaking);
   }
 
   inline bool DoOutput()
   {
     return mHeadLevel == 0;
   }
 
+  inline bool IsQuotedLine(const nsAString& aLine)
+  {
+    return !aLine.IsEmpty() && aLine.First() == char16_t('>');
+  }
+
   // Stack handling functions
   bool GetLastBool(const nsTArray<bool>& aStack);
   void SetLastBool(nsTArray<bool>& aStack, bool aValue);
   void PushBool(nsTArray<bool>& aStack, bool aValue);
   bool PopBool(nsTArray<bool>& aStack);
 
   bool ShouldReplaceContainerWithPlaceholder(nsIAtom* aTag);
   bool IsIgnorableRubyAnnotation(nsIAtom* aTag);
--- a/dom/base/test/TestPlainTextSerializer.cpp
+++ b/dom/base/test/TestPlainTextSerializer.cpp
@@ -125,16 +125,53 @@ TestCJKWithDisallowLineBreaking()
     return NS_ERROR_FAILURE;
   }
 
   passed("HTML to CJK text serialization with OutputDisallowLineBreaking");
 
   return NS_OK;
 }
 
+// Test for ASCII with format=flowed; and quoted lines in preformatted span.
+nsresult
+TestPreformatFlowedQuotes()
+{
+  nsString test;
+  nsString result;
+
+  test.AssignLiteral("<html><body>"
+                     "<span style=\"white-space: pre-wrap;\">"
+                     "&gt; Firefox Firefox Firefox Firefox <br>"
+                     "&gt; Firefox Firefox Firefox Firefox<br>"
+                     "&gt;<br>"
+                     "&gt;&gt; Firefox Firefox Firefox Firefox <br>"
+                     "&gt;&gt; Firefox Firefox Firefox Firefox<br>"
+                     "</span></body></html>");
+
+  ConvertBufToPlainText(test, nsIDocumentEncoder::OutputFormatted |
+                              nsIDocumentEncoder::OutputCRLineBreak |
+                              nsIDocumentEncoder::OutputLFLineBreak |
+                              nsIDocumentEncoder::OutputFormatFlowed);
+
+  // create result case
+  result.AssignLiteral("> Firefox Firefox Firefox Firefox \r\n"
+                       "> Firefox Firefox Firefox Firefox\r\n"
+                       ">\r\n"
+                       ">> Firefox Firefox Firefox Firefox \r\n"
+                       ">> Firefox Firefox Firefox Firefox\r\n");
+  if (!test.Equals(result)) {
+    fail("Wrong HTML to ASCII text serialization with format=flowed; and quoted lines");
+    return NS_ERROR_FAILURE;
+  }
+
+  passed("HTML to ASCII text serialization with format=flowed; and quoted lines");
+
+  return NS_OK;
+}
+
 nsresult
 TestPrettyPrintedHtml()
 {
   nsString test;
   test.AppendLiteral(
     "<html>" NS_LINEBREAK
     "<body>" NS_LINEBREAK
     "  first<br>" NS_LINEBREAK
@@ -262,16 +299,19 @@ TestPlainTextSerializer()
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = TestPreWrapElementForThunderbird();
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = TestCJKWithDisallowLineBreaking();
   NS_ENSURE_SUCCESS(rv, rv);
 
+  rv = TestPreformatFlowedQuotes();
+  NS_ENSURE_SUCCESS(rv, rv);
+
   // Add new tests here...
   return NS_OK;
 }
 
 int main(int argc, char** argv)
 {
   ScopedXPCOM xpcom("PlainTextSerializer");
   if (xpcom.failed())