Bug 593758 - List are not formated anymore during html to text conversion; r=bzbarsky a=blocking-betaN+
authorEhsan Akhgari <ehsan@mozilla.com>
Tue, 28 Sep 2010 18:37:30 -0400
changeset 55418 7a903a40b8978cb94164f56dfcb2f4eba0376f7d
parent 55417 b829cf5debcea2b9446d839ac37bad78a338fbe4
child 55419 bc5c8ff46d064973c83b11ded890cce4a493a6ab
push id16253
push usereakhgari@mozilla.com
push dateWed, 13 Oct 2010 14:34:48 +0000
treeherdermozilla-central@178f26e21cfc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbzbarsky, blocking-betaN
bugs593758
milestone2.0b8pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 593758 - List are not formated anymore during html to text conversion; r=bzbarsky a=blocking-betaN+
content/base/src/nsPlainTextSerializer.cpp
content/base/src/nsPlainTextSerializer.h
--- a/content/base/src/nsPlainTextSerializer.cpp
+++ b/content/base/src/nsPlainTextSerializer.cpp
@@ -57,16 +57,17 @@
 #include "nsUnicharUtils.h"
 #include "nsCRT.h"
 #include "nsIParserService.h"
 
 #define PREF_STRUCTS "converter.html2txt.structs"
 #define PREF_HEADER_STRATEGY "converter.html2txt.header_strategy"
 
 static const  PRInt32 kTabSize=4;
+static const  PRInt32 kOLNumberWidth = 3;
 static const  PRInt32 kIndentSizeHeaders = 2;  /* Indention of h1, if
                                                 mHeaderStrategy = 1 or = 2.
                                                 Indention of other headers
                                                 is derived from that.
                                                 XXX center h1? */
 static const  PRInt32 kIndentIncrementHeaders = 2;  /* If mHeaderStrategy = 1,
                                                 indent h(x+1) this many
                                                 columns more than h(x) */
@@ -123,24 +124,27 @@ nsPlainTextSerializer::nsPlainTextSerial
   mPreFormatted = PR_FALSE;
   mStartedOutput = PR_FALSE;
 
   // initialize the tag stack to zero:
   mTagStack = new nsHTMLTag[TagStackSize];
   mTagStackIndex = 0;
   mIgnoreAboveIndex = (PRUint32)kNotFound;
 
+  // initialize the OL stack, where numbers for ordered lists are kept
+  mOLStack = new PRInt32[OLStackSize];
   mOLStackIndex = 0;
 
   mULCount = 0;
 }
 
 nsPlainTextSerializer::~nsPlainTextSerializer()
 {
   delete[] mTagStack;
+  delete[] mOLStack;
   NS_WARN_IF_FALSE(mHeadLevel == 0, "Wrong head level!");
 }
 
 NS_IMPL_ISUPPORTS4(nsPlainTextSerializer, 
                    nsIContentSerializer,
                    nsIContentSink,
                    nsIHTMLContentSink,
                    nsIHTMLToTextSink)
@@ -690,19 +694,64 @@ nsPlainTextSerializer::DoOpenContainer(c
     // Indent here to support nested lists, which aren't included in li :-(
     EnsureVerticalSpace(mULCount + mOLStackIndex == 0 ? 1 : 0);
          // Must end the current line before we change indention
     mIndent += kIndentSizeList;
     mULCount++;
   }
   else if (type == eHTMLTag_ol) {
     EnsureVerticalSpace(mULCount + mOLStackIndex == 0 ? 1 : 0);
-    mOLStackIndex++;
+    if (mFlags & nsIDocumentEncoder::OutputFormatted) {
+      // Must end the current line before we change indention
+      if (mOLStackIndex < OLStackSize) {
+        nsAutoString startAttr;
+        PRInt32 startVal = 1;
+        if(NS_SUCCEEDED(GetAttributeValue(aNode, nsGkAtoms::start, startAttr))){
+          PRInt32 rv = 0;
+          startVal = startAttr.ToInteger(&rv);
+          if (NS_FAILED(rv))
+            startVal = 1;
+        }
+        mOLStack[mOLStackIndex++] = startVal;
+      }
+    } else {
+      mOLStackIndex++;
+    }
     mIndent += kIndentSizeList;  // see ul
   }
+  else if (type == eHTMLTag_li &&
+           (mFlags & nsIDocumentEncoder::OutputFormatted)) {
+    if (mTagStackIndex > 1 && IsInOL()) {
+      if (mOLStackIndex > 0) {
+        nsAutoString valueAttr;
+        if(NS_SUCCEEDED(GetAttributeValue(aNode, nsGkAtoms::value, valueAttr))){
+          PRInt32 rv = 0;
+          PRInt32 valueAttrVal = valueAttr.ToInteger(&rv);
+          if (NS_SUCCEEDED(rv))
+            mOLStack[mOLStackIndex-1] = valueAttrVal;
+        }
+        // This is what nsBulletFrame does for OLs:
+        mInIndentString.AppendInt(mOLStack[mOLStackIndex-1]++, 10);
+      }
+      else {
+        mInIndentString.Append(PRUnichar('#'));
+      }
+
+      mInIndentString.Append(PRUnichar('.'));
+
+    }
+    else {
+      static char bulletCharArray[] = "*o+#";
+      PRUint32 index = mULCount > 0 ? (mULCount - 1) : 3;
+      char bulletChar = bulletCharArray[index % 4];
+      mInIndentString.Append(PRUnichar(bulletChar));
+    }
+
+    mInIndentString.Append(PRUnichar(' '));
+  }
   else if (type == eHTMLTag_dl) {
     EnsureVerticalSpace(1);
   }
   else if (type == eHTMLTag_dt) {
     EnsureVerticalSpace(0);
   }
   else if (type == eHTMLTag_dd) {
     EnsureVerticalSpace(0);
@@ -869,17 +918,25 @@ nsPlainTextSerializer::DoCloseContainer(
   }
 
   if (type == eHTMLTag_tr) {
     PopBool(mHasWrittenCellsForRow);
     // Should always end a line, but get no more whitespace
     if (mFloatingLines < 0)
       mFloatingLines = 0;
     mLineBreakDue = PR_TRUE;
-  } 
+  }
+  else if (((type == eHTMLTag_li) ||
+            (type == eHTMLTag_dt)) &&
+           (mFlags & nsIDocumentEncoder::OutputFormatted)) {
+    // Items that should always end a line, but get no more whitespace
+    if (mFloatingLines < 0)
+      mFloatingLines = 0;
+    mLineBreakDue = PR_TRUE;
+  }
   else if (type == eHTMLTag_pre) {
     mFloatingLines = GetLastBool(mIsInCiteBlockquote) ? 0 : 1;
     mLineBreakDue = PR_TRUE;
   }
   else if (type == eHTMLTag_ul) {
     FlushLine();
     mIndent -= kIndentSizeList;
     if (--mULCount + mOLStackIndex == 0) {
--- a/content/base/src/nsPlainTextSerializer.h
+++ b/content/base/src/nsPlainTextSerializer.h
@@ -249,16 +249,18 @@ protected:
 
   // The tag stack: the stack of tags we're operating on, so we can nest:
   nsHTMLTag       *mTagStack;
   PRUint32         mTagStackIndex;
 
   // Content in the stack above this index should be ignored:
   PRUint32          mIgnoreAboveIndex;
 
+  // The stack for ordered lists
+  PRInt32         *mOLStack;
   PRUint32         mOLStackIndex;
 
   PRUint32         mULCount;
 
   nsString                     mLineBreak;
   nsCOMPtr<nsILineBreaker>     mLineBreaker;
 
   // Conveniance constant. It would be nice to have it as a const static