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 79512 06eab34f121ab03d9753b41cab34617422ad6d5e
parent 79511 2266dd224ea03564189c12ecf5ae4b61d33ba119
child 79513 f715a1cf1e23dccfef21c039784a33a20cb21024
push id21408
push userkhuey@mozilla.com
push dateTue, 01 Nov 2011 14:32:20 +0000
treeherdermozilla-central@cd9add22f090 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbzbarsky
bugs482921, 86355
milestone10.0a1
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 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.