Bug 482921 part 8 - Start a new <pre> occasionally in View Source refixing bug 86355. r=bzbarsky.
authorHenri Sivonen <hsivonen@iki.fi>
Tue, 01 Nov 2011 13:33:11 +0200
changeset 80154 06eab34f121ab03d9753b41cab34617422ad6d5e
parent 80153 2266dd224ea03564189c12ecf5ae4b61d33ba119
child 80155 f715a1cf1e23dccfef21c039784a33a20cb21024
push id506
push userclegnitto@mozilla.com
push dateWed, 09 Nov 2011 02:03:18 +0000
treeherdermozilla-aurora@63587fc7bb93 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbzbarsky
bugs482921, 86355
milestone10.0a1
Bug 482921 part 8 - Start a new <pre> occasionally in View Source refixing bug 86355. r=bzbarsky.
parser/html/nsHtml5Highlighter.cpp
parser/html/nsHtml5Highlighter.h
--- a/parser/html/nsHtml5Highlighter.cpp
+++ b/parser/html/nsHtml5Highlighter.cpp
@@ -40,16 +40,20 @@
 #include "nsHtml5Tokenizer.h"
 #include "nsHtml5AttributeName.h"
 #include "nsString.h"
 #include "nsThreadUtils.h"
 #include "mozilla/Preferences.h"
 
 using namespace mozilla;
 
+// The old code had a limit of 16 tokens. 1300 is a number picked my measuring
+// the size of 16 tokens on cnn.com.
+#define NS_HTML5_HIGHLIGHTER_PRE_BREAK_THRESHOLD 1300
+
 PRUnichar nsHtml5Highlighter::sComment[] =
   { 'c', 'o', 'm', 'm', 'e', 'n', 't', 0 };
 
 PRUnichar nsHtml5Highlighter::sCdata[] =
   { 'c', 'd', 'a', 't', 'a', 0 };
 
 PRUnichar nsHtml5Highlighter::sEntity[] =
   { 'e', 'n', 't', 'i', 't', 'y', 0 };
@@ -73,16 +77,17 @@ PRUnichar nsHtml5Highlighter::sDoctype[]
 PRUnichar nsHtml5Highlighter::sPi[] =
   { 'p', 'i', 0 };
 
 nsHtml5Highlighter::nsHtml5Highlighter(nsAHtml5TreeOpSink* aOpSink)
  : mState(NS_HTML5TOKENIZER_DATA)
  , mCStart(PR_INT32_MAX)
  , mPos(0)
  , mLineNumber(1)
+ , mUnicharsInThisPre(0)
  , mInlinesOpen(0)
  , mInCharacters(false)
  , mBuffer(nsnull)
  , mSyntaxHighlight(Preferences::GetBool("view_source.syntax_highlight",
                                          true))
  , mWrapLongLines(Preferences::GetBool("view_source.wrap_long_lines", true))
  , mTabSize(Preferences::GetInt("view_source.tab_size", 4))
  , mOpSink(aOpSink)
@@ -614,35 +619,52 @@ nsHtml5Highlighter::FlushChars()
           // to show consistent LF line breaks to layout. It is OK to mutate
           // the input data, because there are no reparses in the View Source
           // case, so we won't need the original data in the buffer anymore.
           buf[i] = '\n';
           // fall through
         case '\n': {
           ++i;
           if (mCStart < i) {
-            AppendCharacters(buf, mCStart, i - mCStart);
+            PRInt32 len = i - mCStart;
+            AppendCharacters(buf, mCStart, len);
             mCStart = i;
+            mUnicharsInThisPre += len;
           }
           ++mLineNumber;
+          if (mUnicharsInThisPre > NS_HTML5_HIGHLIGHTER_PRE_BREAK_THRESHOLD &&
+              !mInlinesOpen && mInCharacters) {
+            mUnicharsInThisPre = 0;
+            // Split the pre. See bug 86355.
+            Pop(); // span
+            Pop(); // pre
+            Push(nsGkAtoms::pre, nsnull);
+            nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
+            NS_ASSERTION(treeOp, "Tree op allocation failed.");
+            treeOp->InitAddLineNumberId(CurrentNode(), mLineNumber);
+            Push(nsGkAtoms::span, nsnull);
+            break;
+          }
           Push(nsGkAtoms::span, nsnull);
           nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
           NS_ASSERTION(treeOp, "Tree op allocation failed.");
           treeOp->InitAddLineNumberId(CurrentNode(), mLineNumber);
           Pop();
           break;
         }
         default:
           ++i;
           break;
       }
     }
     if (mCStart < mPos) {
-      AppendCharacters(buf, mCStart, mPos - mCStart);
+      PRInt32 len = mPos - mCStart;
+      AppendCharacters(buf, mCStart, len);
       mCStart = mPos;
+      mUnicharsInThisPre += len;
     }
   }
 }
 
 void
 nsHtml5Highlighter::FlushCurrent()
 {
   mPos++;
--- a/parser/html/nsHtml5Highlighter.h
+++ b/parser/html/nsHtml5Highlighter.h
@@ -312,16 +312,22 @@ class nsHtml5Highlighter
     PRInt32 mPos;
 
     /**
      * The current line number.
      */
     PRInt32 mLineNumber;
 
     /**
+     * The number of PRUnichars flushed since the start of the current pre
+     * block.
+     */
+    PRInt32 mUnicharsInThisPre;
+
+    /**
      * The number of inline elements open inside the <pre> excluding the
      * span potentially wrapping a run of characters.
      */
     PRInt32 mInlinesOpen;
 
     /**
      * Whether there's a span wrapping a run of characters (excluding CDATA
      * section) open.