From 9730e0d3594240090a4aad83ba6f9afccf314e10 Mon Sep 17 00:00:00 2001 From: Jonathan Kamens Date: Tue, 21 Sep 2010 15:02:55 +0200 Subject: [PATCH] bug 564737 - plaintext serializer shouldn't take care of leading spaces in a block. tests by David :Bienvenu. r=laurentj sr+a=jst --- content/base/src/nsPlainTextSerializer.cpp | 37 +++++++++---------- content/base/test/TestPlainTextSerializer.cpp | 25 +++++++++++++ content/base/test/test_copypaste.html | 30 +++++++-------- 3 files changed, 58 insertions(+), 34 deletions(-) diff --git a/content/base/src/nsPlainTextSerializer.cpp b/content/base/src/nsPlainTextSerializer.cpp index aae3b11a535..df3a5b367aa 100644 --- a/content/base/src/nsPlainTextSerializer.cpp +++ b/content/base/src/nsPlainTextSerializer.cpp @@ -119,7 +119,7 @@ nsPlainTextSerializer::nsPlainTextSerializer() // Flow mEmptyLines = 1; // The start of the document is an "empty line" in itself, - mInWhitespace = PR_TRUE; + mInWhitespace = PR_FALSE; mPreFormatted = PR_FALSE; mStartedOutput = PR_FALSE; @@ -638,6 +638,8 @@ nsPlainTextSerializer::DoOpenContainer(const nsIParserNode* aNode, PRInt32 aTag) } } else { + /* See comment at end of function. */ + mInWhitespace = PR_TRUE; mPreFormatted = PR_FALSE; } @@ -807,6 +809,13 @@ nsPlainTextSerializer::DoOpenContainer(const nsIParserNode* aNode, PRInt32 aTag) Write(NS_LITERAL_STRING("_")); } + /* Container elements are always block elements, so we shouldn't + output any whitespace immediately after the container tag even if + there's extra whitespace there because the HTML is pretty-printed + or something. To ensure that happens, tell the serializer we're + already in whitespace so it won't output more. */ + mInWhitespace = PR_TRUE; + return NS_OK; } @@ -1073,38 +1082,26 @@ nsPlainTextSerializer::DoAddLeaf(const nsIParserNode *aNode, PRInt32 aTag, EnsureVerticalSpace(mEmptyLines+1); } } - else if (type == eHTMLTag_whitespace) { + else if (type == eHTMLTag_whitespace || type == eHTMLTag_newline) { // The only times we want to pass along whitespace from the original // html source are if we're forced into preformatted mode via flags, // or if we're prettyprinting and we're inside a
.
     // Otherwise, either we're collapsing to minimal text, or we're
     // prettyprinting to mimic the html format, and in neither case
     // does the formatting of the html source help us.
-    // One exception: at the very beginning of a selection,
-    // we want to preserve whitespace.
     if (mFlags & nsIDocumentEncoder::OutputPreformatted ||
         (mPreFormatted && !mWrapColumn) ||
         IsInPre()) {
-      Write(aText);
+      if (type == eHTMLTag_newline)
+        EnsureVerticalSpace(mEmptyLines+1);
+      else  
+        Write(aText);
     }
-    else if(!mInWhitespace ||
-            (!mStartedOutput
-             && mFlags | nsIDocumentEncoder::OutputSelectionOnly)) {
-      mInWhitespace = PR_FALSE;
+    else if(!mInWhitespace) {
       Write(kSpace);
       mInWhitespace = PR_TRUE;
     }
   }
-  else if (type == eHTMLTag_newline) {
-    if (mFlags & nsIDocumentEncoder::OutputPreformatted ||
-        (mPreFormatted && !mWrapColumn) ||
-        IsInPre()) {
-      EnsureVerticalSpace(mEmptyLines+1);
-    }
-    else {
-      Write(kSpace);
-    }
-  }
   else if (type == eHTMLTag_hr &&
            (mFlags & nsIDocumentEncoder::OutputFormatted)) {
     EnsureVerticalSpace(0);
@@ -1161,10 +1158,12 @@ nsPlainTextSerializer::EnsureVerticalSpace(PRInt32 noOfRows)
   // realize that we should start a new line.
   if(noOfRows >= 0 && !mInIndentString.IsEmpty()) {
     EndLine(PR_FALSE);
+    mInWhitespace = PR_TRUE;
   }
 
   while(mEmptyLines < noOfRows) {
     EndLine(PR_FALSE);
+    mInWhitespace = PR_TRUE;
   }
   mLineBreakDue = PR_FALSE;
   mFloatingLines = -1;
diff --git a/content/base/test/TestPlainTextSerializer.cpp b/content/base/test/TestPlainTextSerializer.cpp
index 21ad5d58a85..8b76aee95e9 100644
--- a/content/base/test/TestPlainTextSerializer.cpp
+++ b/content/base/test/TestPlainTextSerializer.cpp
@@ -46,6 +46,7 @@
 #include "nsStringGlue.h"
 #include "nsParserCIID.h"
 #include "nsIDocumentEncoder.h"
+#include "nsCRT.h"
 
 static NS_DEFINE_CID(kCParserCID, NS_PARSER_CID);
 
@@ -143,6 +144,27 @@ TestCJKWithFlowedDelSp()
   return NS_OK;
 }
 
+nsresult
+TestPrettyPrintedHtml()
+{
+  nsString test;
+  test.AppendLiteral(
+    "" NS_LINEBREAK
+    "" NS_LINEBREAK
+    "  first
" NS_LINEBREAK + " second
" NS_LINEBREAK + "" NS_LINEBREAK ""); + + ConvertBufToPlainText(test, 0); + if (!test.EqualsLiteral("first" NS_LINEBREAK "second" 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() { @@ -163,6 +185,9 @@ TestPlainTextSerializer() rv = TestCJKWithFlowedDelSp(); NS_ENSURE_SUCCESS(rv, rv); + rv = TestPrettyPrintedHtml(); + NS_ENSURE_SUCCESS(rv, rv); + // Add new tests here... return NS_OK; } diff --git a/content/base/test/test_copypaste.html b/content/base/test/test_copypaste.html index 9a81b5bff6e..5b33f9b7907 100644 --- a/content/base/test/test_copypaste.html +++ b/content/base/test/test_copypaste.html @@ -112,36 +112,36 @@ function testCopyPaste () { testPasteText("This is a draggable bit of text."); copyChildrenToClipboard("alist"); - testSelectionToString("bla\n\n foo\n bar\n\n"); - testClipboardValue("text/unicode", " bla\n\n foo\n bar\n\n"); + testSelectionToString(" bla\n\n foo\n bar\n\n"); + testClipboardValue("text/unicode", "bla\n\n foo\n bar\n\n"); testClipboardValue("text/html", "
\n bla\n
    \n
  • foo
  • \n \n
  • bar
  • \n
\n
"); - testPasteText(" bla\n\n foo\n bar\n\n"); + testPasteText("bla\n\n foo\n bar\n\n"); copyChildrenToClipboard("blist"); - testSelectionToString("mozilla\n\n foo\n bar\n\n"); - testClipboardValue("text/unicode", " mozilla\n\n foo\n bar\n\n"); + testSelectionToString(" mozilla\n\n foo\n bar\n\n"); + testClipboardValue("text/unicode", "mozilla\n\n foo\n bar\n\n"); testClipboardValue("text/html", "
\n mozilla\n
    \n
  1. foo
  2. \n \n
  3. bar
  4. \n
\n
"); - testPasteText(" mozilla\n\n foo\n bar\n\n"); + testPasteText("mozilla\n\n foo\n bar\n\n"); copyChildrenToClipboard("clist"); - testSelectionToString("mzla\n\n foo\n bazzinga!\n bar\n\n"); - testClipboardValue("text/unicode", " mzla\n\n foo\n bazzinga!\n bar\n\n"); + testSelectionToString(" mzla\n\n foo\n bazzinga!\n bar\n\n"); + testClipboardValue("text/unicode", "mzla\n\n foo\n bazzinga!\n bar\n\n"); testClipboardValue("text/html", "
\n mzla\n
    \n
  • foo
      \n
    • bazzinga!
    • \n
  • \n \n
  • bar
  • \n
\n
"); - testPasteText(" mzla\n\n foo\n bazzinga!\n bar\n\n"); + testPasteText("mzla\n\n foo\n bazzinga!\n bar\n\n"); copyChildrenToClipboard("div4"); - testSelectionToString("Tt t t "); - testClipboardValue("text/unicode", " Tt t t "); + testSelectionToString(" Tt t t "); + testClipboardValue("text/unicode", "Tt t t "); testClipboardValue("text/html", "
\n T\n
"); testInnerHTML("div4", "\n T\n"); - testPasteText(" Tt t t "); + testPasteText("Tt t t "); copyChildrenToClipboard("div5"); - testSelectionToString("T "); - testClipboardValue("text/unicode", " T "); + testSelectionToString(" T "); + testClipboardValue("text/unicode", "T "); testClipboardValue("text/html", "
\n T\n
"); testInnerHTML("div5", "\n T\n"); - testPasteText(" T "); + testPasteText("T "); copyRangeToClipboard($("div6").childNodes[0],0, $("div6").childNodes[1],1); testSelectionToString("");