From 9232d18cceea08bba09e916b2ab440b9baa3801c Mon Sep 17 00:00:00 2001 From: "reed@reedloden.com" Date: Sun, 30 Sep 2007 20:29:16 -0700 Subject: [PATCH] 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 | 39 ++++++++++++++++------ 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/content/base/src/nsPlainTextSerializer.cpp b/content/base/src/nsPlainTextSerializer.cpp index 577b453720c..a96590bbe90 100644 --- a/content/base/src/nsPlainTextSerializer.cpp +++ b/content/base/src/nsPlainTextSerializer.cpp @@ -1570,8 +1570,12 @@ nsPlainTextSerializer::OutputQuotesAndIndent(PRBool stripTrailingSpaces /* = PR_ * 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); @@ -1580,17 +1584,32 @@ nsPlainTextSerializer::Write(const nsAString& aString) 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 @@ -1610,8 +1629,8 @@ nsPlainTextSerializer::Write(const nsAString& aString) // 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; @@ -1627,7 +1646,7 @@ nsPlainTextSerializer::Write(const nsAString& aString) // 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 == ' ') || @@ -1645,7 +1664,9 @@ nsPlainTextSerializer::Write(const nsAString& aString) } 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; @@ -1682,10 +1703,6 @@ nsPlainTextSerializer::Write(const nsAString& aString) 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