Bug 125928 - "HTML composition converted to PlainText fails to strip spaces before hard breaks with format=flowed" [p=andrit@ukr.net (Andriy Tkachuk) r=mscott r=BenB sr=bzbarsky (NPOFx)]
authorreed@reedloden.com
Sun, 30 Sep 2007 20:29:16 -0700
changeset 6470 80f1459fc59ff0ecea23260dc8a60b2f4d0cf71c
parent 6469 b4484956dd0640a49da450b5b703b41bf66e1459
child 6471 88dee8ed6ddb0b7478c0b51c8571ddad9c8e64e3
push id1
push userbsmedberg@mozilla.com
push dateThu, 20 Mar 2008 16:49:24 +0000
treeherdermozilla-central@61007906a1f8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmscott, BenB, bzbarsky
bugs125928
milestone1.9a9pre
Bug 125928 - "HTML composition converted to PlainText fails to strip spaces before hard breaks with format=flowed" [p=andrit@ukr.net (Andriy Tkachuk) r=mscott r=BenB sr=bzbarsky (NPOFx)]
content/base/src/nsPlainTextSerializer.cpp
--- a/content/base/src/nsPlainTextSerializer.cpp
+++ b/content/base/src/nsPlainTextSerializer.cpp
@@ -1565,37 +1565,56 @@ nsPlainTextSerializer::OutputQuotesAndIn
 }
 
 /**
  * Write a string. This is the highlevel function to use to get text output.
  * By using AddToLine, Output, EndLine and other functions it handles quotation,
  * line wrapping, indentation, whitespace compression and other things.
  */
 void
-nsPlainTextSerializer::Write(const nsAString& aString)
+nsPlainTextSerializer::Write(const nsAString& aStr)
 {
+  // XXX Copy necessary to use nsString methods and gain
+  // access to underlying buffer
+  nsAutoString str(aStr);
+
 #ifdef DEBUG_wrapping
   printf("Write(%s): wrap col = %d\n",
          NS_ConvertUTF16toUTF8(aString).get(), mWrapColumn);
 #endif
 
   PRInt32 bol = 0;
   PRInt32 newline;
   
-  PRInt32 totLen = aString.Length();
+  PRInt32 totLen = str.Length();
 
   // If the string is empty, do nothing:
   if (totLen <= 0) return;
 
+  // For Flowed text change nbsp-ses to spaces at end of lines to allow them
+  // to be cut off along with usual spaces if required. (bug #125928)
+  if (mFlags & nsIDocumentEncoder::OutputFormatFlowed) {
+    PRUnichar nbsp = 160;
+    for (PRUint32 i = totLen-1; i >= 0; i--) {
+      PRUnichar c = str[i];
+      if ('\n' == c || '\r' == c || ' ' == c || '\t' == c)
+        continue;
+      if (nbsp == c)
+        str.Replace(i, 1, ' ');
+      else
+        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 ((mPreFormatted && !mWrapColumn) || IsInPre()
       || ((((!mQuotesPreformatted && mSpanLevel > 0) || mDontWrapAnyQuotes))
-          && mEmptyLines >= 0 && aString.First() == PRUnichar('>'))) {
+          && mEmptyLines >= 0 && str.First() == PRUnichar('>'))) {
     // No intelligent wrapping.
 
     // This mustn't be mixed with intelligent wrapping without clearing
     // the mCurrentLine buffer before!!!
     NS_ASSERTION(mCurrentLine.IsEmpty(),
                  "Mixed wrapping data and nonwrapping data on the same line");
     if (!mCurrentLine.IsEmpty()) {
       FlushLine();
@@ -1605,34 +1624,34 @@ nsPlainTextSerializer::Write(const nsASt
     // Have to put it in before every line.
     while(bol<totLen) {
       PRBool outputQuotes = mAtFirstColumn;
       PRBool atFirstColumn = mAtFirstColumn;
       PRBool outputLineBreak = PR_FALSE;
 
       // Find one of '\n' or '\r' using iterators since nsAString
       // doesn't have the old FindCharInSet function.
-      nsAString::const_iterator iter;           aString.BeginReading(iter);
-      nsAString::const_iterator done_searching; aString.EndReading(done_searching);
+      nsAString::const_iterator iter;           str.BeginReading(iter);
+      nsAString::const_iterator done_searching; str.EndReading(done_searching);
       iter.advance(bol); 
       PRInt32 new_newline = bol;
       newline = kNotFound;
       while(iter != done_searching) {
         if('\n' == *iter || '\r' == *iter) {
           newline = new_newline;
           break;
         }
         ++new_newline;
         ++iter;
       }
 
       // Done searching
       if(newline == kNotFound) {
         // No new lines.
-        nsAutoString stringpart(Substring(aString, bol, totLen - bol));
+        nsAutoString stringpart(Substring(str, bol, totLen - bol));
         if(!stringpart.IsEmpty()) {
           PRUnichar lastchar = stringpart[stringpart.Length()-1];
           if((lastchar == '\t') || (lastchar == ' ') ||
              (lastchar == '\r') ||(lastchar == '\n')) {
             mInWhitespace = PR_TRUE;
           } 
           else {
             mInWhitespace = PR_FALSE;
@@ -1640,17 +1659,19 @@ nsPlainTextSerializer::Write(const nsASt
         }
         mCurrentLine.Assign(stringpart);
         mEmptyLines=-1;
         atFirstColumn = mAtFirstColumn && (totLen-bol)==0;
         bol = totLen;
       } 
       else {
         // There is a newline
-        nsAutoString stringpart(Substring(aString, bol, newline-bol));
+        nsAutoString stringpart(Substring(str, bol, newline-bol));
+        if (mFlags & nsIDocumentEncoder::OutputFormatFlowed)
+          stringpart.Trim(" ", PR_FALSE, PR_TRUE, PR_TRUE);
         mInWhitespace = PR_TRUE;
         mCurrentLine.Assign(stringpart);
         outputLineBreak = PR_TRUE;
         mEmptyLines=0;
         atFirstColumn = PR_TRUE;
         bol = newline+1;
         if('\r' == *iter && bol < totLen && '\n' == *++iter) {
           // There was a CRLF in the input. This used to be illegal and
@@ -1677,20 +1698,16 @@ nsPlainTextSerializer::Write(const nsASt
 
 #ifdef DEBUG_wrapping
     printf("No wrapping: newline is %d, totLen is %d\n",
            newline, totLen);
 #endif
     return;
   }
 
-  // XXX Copy necessary to use nsString methods and gain
-  // access to underlying buffer
-  nsAutoString str(aString);
-
   // Intelligent handling of text
   // If needed, strip out all "end of lines"
   // and multiple whitespace between words
   PRInt32 nextpos;
   const PRUnichar * offsetIntoBuffer = nsnull;
   
   while (bol < totLen) {    // Loop over lines
     // Find a place where we may have to do whitespace compression