Bug 959150 part 3 - Move the parts of nsHtml5TreeOpExecutor that the static methods in nsHtml5TreeOperation need to access into a new superclass. r=smaug.
authorHenri Sivonen <hsivonen@hsivonen.fi>
Wed, 05 Mar 2014 21:38:49 +0200
changeset 172303 8885a39733df1446a0f6fcd9424b26ba9e92db34
parent 172302 ec506a5c424cad2753235f194abaa1e362e1ce58
child 172304 5acef36769eb72f297bbea048916101894a7641b
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewerssmaug
bugs959150
milestone30.0a1
Bug 959150 part 3 - Move the parts of nsHtml5TreeOpExecutor that the static methods in nsHtml5TreeOperation need to access into a new superclass. r=smaug.
parser/html/moz.build
parser/html/nsHtml5DocumentBuilder.cpp
parser/html/nsHtml5DocumentBuilder.h
parser/html/nsHtml5TreeOpExecutor.cpp
parser/html/nsHtml5TreeOpExecutor.h
parser/html/nsHtml5TreeOperation.cpp
parser/html/nsHtml5TreeOperation.h
--- a/parser/html/moz.build
+++ b/parser/html/moz.build
@@ -16,16 +16,17 @@ EXPORTS += [
     'nsAHtml5TreeBuilderState.h',
     'nsAHtml5TreeOpSink.h',
     'nsHtml5ArrayCopy.h',
     'nsHtml5AtomList.h',
     'nsHtml5Atoms.h',
     'nsHtml5AtomTable.h',
     'nsHtml5ByteReadable.h',
     'nsHtml5DependentUTF16Buffer.h',
+    'nsHtml5DocumentBuilder.h',
     'nsHtml5DocumentMode.h',
     'nsHtml5HtmlAttributes.h',
     'nsHtml5Macros.h',
     'nsHtml5MetaScanner.h',
     'nsHtml5MetaScannerHSupplement.h',
     'nsHtml5Module.h',
     'nsHtml5NamedCharacters.h',
     'nsHtml5NamedCharactersAccel.h',
@@ -49,16 +50,17 @@ EXPORTS += [
 ]
 
 UNIFIED_SOURCES += [
     'nsHtml5Atom.cpp',
     'nsHtml5Atoms.cpp',
     'nsHtml5AtomTable.cpp',
     'nsHtml5AttributeName.cpp',
     'nsHtml5DependentUTF16Buffer.cpp',
+    'nsHtml5DocumentBuilder.cpp',
     'nsHtml5ElementName.cpp',
     'nsHtml5Highlighter.cpp',
     'nsHtml5HtmlAttributes.cpp',
     'nsHtml5MetaScanner.cpp',
     'nsHtml5Module.cpp',
     'nsHtml5NamedCharacters.cpp',
     'nsHtml5NamedCharactersAccel.cpp',
     'nsHtml5OwningUTF16Buffer.cpp',
new file mode 100644
--- /dev/null
+++ b/parser/html/nsHtml5DocumentBuilder.cpp
@@ -0,0 +1,33 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 sw=2 et tw=78: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsHtml5DocumentBuilder.h"
+
+#include "nsScriptLoader.h"
+#include "mozilla/css/Loader.h"
+#include "nsIDocShell.h"
+
+NS_IMPL_CYCLE_COLLECTION_INHERITED_1(nsHtml5DocumentBuilder, nsContentSink,
+                                     mOwnedElements)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsHtml5DocumentBuilder)
+NS_INTERFACE_MAP_END_INHERITING(nsContentSink)
+
+NS_IMPL_ADDREF_INHERITED(nsHtml5DocumentBuilder, nsContentSink)
+NS_IMPL_RELEASE_INHERITED(nsHtml5DocumentBuilder, nsContentSink)
+
+void
+nsHtml5DocumentBuilder::DropHeldElements()
+{
+  mScriptLoader = nullptr;
+  mDocument = nullptr;
+  mNodeInfoManager = nullptr;
+  mCSSLoader = nullptr;
+  mDocumentURI = nullptr;
+  mDocShell = nullptr;
+  mOwnedElements.Clear();
+}
+
new file mode 100644
--- /dev/null
+++ b/parser/html/nsHtml5DocumentBuilder.h
@@ -0,0 +1,121 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 sw=2 et tw=78: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsHtml5DocumentBuilder_h
+#define nsHtml5DocumentBuilder_h
+
+#include "nsHtml5PendingNotification.h"
+
+typedef nsIContent* nsIContentPtr;
+
+enum eHtml5FlushState {
+  eNotFlushing = 0,  // not flushing
+  eInFlush = 1,      // the Flush() method is on the call stack
+  eInDocUpdate = 2,  // inside an update batch on the document
+  eNotifying = 3     // flushing pending append notifications
+};
+
+class nsHtml5DocumentBuilder : public nsContentSink
+{
+public:
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsHtml5DocumentBuilder,
+                                           nsContentSink)
+
+  NS_DECL_ISUPPORTS_INHERITED
+
+  inline void HoldElement(nsIContent* aContent) {
+    mOwnedElements.AppendElement(aContent);
+  }
+
+  inline bool HaveNotified(nsIContent* aNode) {
+    NS_PRECONDITION(aNode, "HaveNotified called with null argument.");
+    const nsHtml5PendingNotification* start = mPendingNotifications.Elements();
+    const nsHtml5PendingNotification* end = start + mPendingNotifications.Length();
+    for (;;) {
+      nsIContent* parent = aNode->GetParent();
+      if (!parent) {
+        return true;
+      }
+      for (nsHtml5PendingNotification* iter = (nsHtml5PendingNotification*)start; iter < end; ++iter) {
+        if (iter->Contains(parent)) {
+          return iter->HaveNotifiedIndex(parent->IndexOf(aNode));
+        }
+      }
+      aNode = parent;
+    }
+  }
+
+  void PostPendingAppendNotification(nsIContent* aParent, nsIContent* aChild) {
+    bool newParent = true;
+    const nsIContentPtr* first = mElementsSeenInThisAppendBatch.Elements();
+    const nsIContentPtr* last = first + mElementsSeenInThisAppendBatch.Length() - 1;
+    for (const nsIContentPtr* iter = last; iter >= first; --iter) {
+#ifdef DEBUG_NS_HTML5_TREE_OP_EXECUTOR_FLUSH
+      sAppendBatchSlotsExamined++;
+#endif
+      if (*iter == aParent) {
+        newParent = false;
+        break;
+      }
+    }
+    if (aChild->IsElement()) {
+      mElementsSeenInThisAppendBatch.AppendElement(aChild);
+    }
+    mElementsSeenInThisAppendBatch.AppendElement(aParent);
+    if (newParent) {
+      mPendingNotifications.AppendElement(aParent);
+    }
+#ifdef DEBUG_NS_HTML5_TREE_OP_EXECUTOR_FLUSH
+    sAppendBatchExaminations++;
+#endif
+  }
+
+  void FlushPendingAppendNotifications() {
+    NS_PRECONDITION(mFlushState == eInDocUpdate, "Notifications flushed outside update");
+    mFlushState = eNotifying;
+    const nsHtml5PendingNotification* start = mPendingNotifications.Elements();
+    const nsHtml5PendingNotification* end = start + mPendingNotifications.Length();
+    for (nsHtml5PendingNotification* iter = (nsHtml5PendingNotification*)start; iter < end; ++iter) {
+      iter->Fire();
+    }
+    mPendingNotifications.Clear();
+#ifdef DEBUG_NS_HTML5_TREE_OP_EXECUTOR_FLUSH
+    if (mElementsSeenInThisAppendBatch.Length() > sAppendBatchMaxSize) {
+      sAppendBatchMaxSize = mElementsSeenInThisAppendBatch.Length();
+    }
+#endif
+    mElementsSeenInThisAppendBatch.Clear();
+    NS_ASSERTION(mFlushState == eNotifying, "mFlushState out of sync");
+    mFlushState = eInDocUpdate;
+  }
+
+  void DropHeldElements();
+
+  // Getters and setters for fields from nsContentSink
+  nsIDocument* GetDocument() {
+    return mDocument;
+  }
+  nsNodeInfoManager* GetNodeInfoManager() {
+    return mNodeInfoManager;
+  }
+
+  virtual bool BelongsToStringParser() = 0;
+
+protected:
+  inline void SetAppendBatchCapacity(uint32_t aCapacity)
+  {
+    mElementsSeenInThisAppendBatch.SetCapacity(aCapacity);
+  }
+
+private:
+  nsTArray<nsHtml5PendingNotification> mPendingNotifications;
+  nsTArray<nsCOMPtr<nsIContent> >      mOwnedElements;
+  nsTArray<nsIContentPtr>              mElementsSeenInThisAppendBatch;
+protected:
+  eHtml5FlushState                     mFlushState;
+};
+
+#endif // nsHtml5DocumentBuilder_h
--- a/parser/html/nsHtml5TreeOpExecutor.cpp
+++ b/parser/html/nsHtml5TreeOpExecutor.cpp
@@ -30,23 +30,20 @@
 #include "GeckoProfiler.h"
 #include "nsIScriptError.h"
 #include "nsIScriptContext.h"
 #include "mozilla/Preferences.h"
 #include "nsIHTMLDocument.h"
 
 using namespace mozilla;
 
-NS_IMPL_CYCLE_COLLECTION_INHERITED_1(nsHtml5TreeOpExecutor, nsContentSink,
-                                     mOwnedElements)
-
 NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsHtml5TreeOpExecutor)
   NS_INTERFACE_TABLE_INHERITED1(nsHtml5TreeOpExecutor, 
                                 nsIContentSink)
-NS_INTERFACE_TABLE_TAIL_INHERITING(nsContentSink)
+NS_INTERFACE_TABLE_TAIL_INHERITING(nsHtml5DocumentBuilder)
 
 NS_IMPL_ADDREF_INHERITED(nsHtml5TreeOpExecutor, nsContentSink)
 
 NS_IMPL_RELEASE_INHERITED(nsHtml5TreeOpExecutor, nsContentSink)
 
 class nsHtml5ExecutorReflusher : public nsRunnable
 {
   private:
@@ -504,17 +501,17 @@ nsHtml5TreeOpExecutor::RunFlushLoop()
     mFlushState = eInFlush;
 
     nsIContent* scriptElement = nullptr;
     
     BeginDocUpdate();
 
     uint32_t numberOfOpsToFlush = mOpQueue.Length();
 
-    mElementsSeenInThisAppendBatch.SetCapacity(numberOfOpsToFlush * 2);
+    SetAppendBatchCapacity(numberOfOpsToFlush * 2);
 
     const nsHtml5TreeOperation* first = mOpQueue.Elements();
     const nsHtml5TreeOperation* last = first + numberOfOpsToFlush - 1;
     for (nsHtml5TreeOperation* iter = const_cast<nsHtml5TreeOperation*>(first);;) {
       if (MOZ_UNLIKELY(!mParser)) {
         // The previous tree op caused a call to nsIParser::Terminate().
         break;
       }
@@ -608,17 +605,17 @@ nsHtml5TreeOpExecutor::FlushDocumentWrit
 #endif
   
   nsIContent* scriptElement = nullptr;
   
   BeginDocUpdate();
 
   uint32_t numberOfOpsToFlush = mOpQueue.Length();
 
-  mElementsSeenInThisAppendBatch.SetCapacity(numberOfOpsToFlush * 2);
+  SetAppendBatchCapacity(numberOfOpsToFlush * 2);
 
   const nsHtml5TreeOperation* start = mOpQueue.Elements();
   const nsHtml5TreeOperation* end = start + numberOfOpsToFlush;
   for (nsHtml5TreeOperation* iter = const_cast<nsHtml5TreeOperation*>(start);
        iter < end;
        ++iter) {
     if (MOZ_UNLIKELY(!mParser)) {
       // The previous tree op caused a call to nsIParser::Terminate().
@@ -894,28 +891,16 @@ nsHtml5TreeOpExecutor::Reset()
   mStarted = false;
   mFlushState = eNotFlushing;
   mRunFlushLoopOnStack = false;
   MOZ_ASSERT(!mReadingFromStage);
   MOZ_ASSERT(NS_SUCCEEDED(mBroken));
 }
 
 void
-nsHtml5TreeOpExecutor::DropHeldElements()
-{
-  mScriptLoader = nullptr;
-  mDocument = nullptr;
-  mNodeInfoManager = nullptr;
-  mCSSLoader = nullptr;
-  mDocumentURI = nullptr;
-  mDocShell = nullptr;
-  mOwnedElements.Clear();
-}
-
-void
 nsHtml5TreeOpExecutor::MoveOpsFrom(nsTArray<nsHtml5TreeOperation>& aOpQueue)
 {
   NS_PRECONDITION(mFlushState == eNotFlushing, "mOpQueue modified during tree op execution.");
   if (mOpQueue.IsEmpty()) {
     mOpQueue.SwapElements(aOpQueue);
     return;
   }
   mOpQueue.MoveElementsFrom(aOpQueue);
--- a/parser/html/nsHtml5TreeOpExecutor.h
+++ b/parser/html/nsHtml5TreeOpExecutor.h
@@ -1,61 +1,50 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsHtml5TreeOpExecutor_h
 #define nsHtml5TreeOpExecutor_h
 
 #include "nsIAtom.h"
-#include "nsNameSpaceManager.h"
 #include "nsIContent.h"
 #include "nsIDocument.h"
-#include "nsISupportsImpl.h"
+#include "nsTraceRefcnt.h"
 #include "nsHtml5TreeOperation.h"
 #include "nsHtml5SpeculativeLoad.h"
-#include "nsHtml5PendingNotification.h"
 #include "nsTArray.h"
 #include "nsContentSink.h"
 #include "nsNodeInfoManager.h"
 #include "nsHtml5DocumentMode.h"
 #include "nsIScriptElement.h"
 #include "nsIParser.h"
 #include "nsAHtml5TreeOpSink.h"
 #include "nsHtml5TreeOpStage.h"
 #include "nsIURI.h"
 #include "nsTHashtable.h"
 #include "nsHashKeys.h"
 #include "mozilla/LinkedList.h"
+#include "nsHtml5DocumentBuilder.h"
 
 class nsHtml5Parser;
 class nsHtml5TreeBuilder;
 class nsHtml5Tokenizer;
 class nsHtml5StreamParser;
 
-typedef nsIContent* nsIContentPtr;
-
-enum eHtml5FlushState {
-  eNotFlushing = 0,  // not flushing
-  eInFlush = 1,      // the Flush() method is on the call stack
-  eInDocUpdate = 2,  // inside an update batch on the document
-  eNotifying = 3     // flushing pending append notifications
-};
-
-class nsHtml5TreeOpExecutor : public nsContentSink,
+class nsHtml5TreeOpExecutor : public nsHtml5DocumentBuilder,
                               public nsIContentSink,
                               public nsAHtml5TreeOpSink,
                               public mozilla::LinkedListElement<nsHtml5TreeOpExecutor>
 {
   friend class nsHtml5FlushLoopGuard;
 
   public:
     NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
     NS_DECL_ISUPPORTS_INHERITED
-    NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsHtml5TreeOpExecutor, nsContentSink)
 
   private:
     static bool        sExternalViewSource;
 #ifdef DEBUG_NS_HTML5_TREE_OP_EXECUTOR_FLUSH
     static uint32_t    sAppendBatchMaxSize;
     static uint32_t    sAppendBatchSlotsExamined;
     static uint32_t    sAppendBatchExaminations;
     static uint32_t    sLongestTimeOffTheEventLoop;
@@ -64,20 +53,17 @@ class nsHtml5TreeOpExecutor : public nsC
 
     /**
      * Whether EOF needs to be suppressed
      */
     bool                                 mSuppressEOF;
     
     bool                                 mReadingFromStage;
     nsTArray<nsHtml5TreeOperation>       mOpQueue;
-    nsTArray<nsIContentPtr>              mElementsSeenInThisAppendBatch;
-    nsTArray<nsHtml5PendingNotification> mPendingNotifications;
     nsHtml5StreamParser*                 mStreamParser;
-    nsTArray<nsCOMPtr<nsIContent> >      mOwnedElements;
     
     /**
      * URLs already preloaded/preloading.
      */
     nsTHashtable<nsCStringHashKey> mPreloadedURLs;
 
     nsCOMPtr<nsIURI> mSpeculationBaseURI;
 
@@ -85,18 +71,16 @@ class nsHtml5TreeOpExecutor : public nsC
 
     /**
      * Whether the parser has started
      */
     bool                          mStarted;
 
     nsHtml5TreeOpStage            mStage;
 
-    eHtml5FlushState              mFlushState;
-
     bool                          mRunFlushLoopOnStack;
 
     bool                          mCallContinueInterruptedParsingIfEnabled;
 
     /**
      * Non-NS_OK if this parser should refuse to process any more input.
      * For example, the parser needs to be marked as broken if it drops some
      * input due to a memory allocation failure. In such a case, the whole
@@ -175,23 +159,17 @@ class nsHtml5TreeOpExecutor : public nsC
     virtual nsresult FlushTags();
     virtual void ContinueInterruptedParsingAsync();
  
     /**
      * Sets up style sheet load / parse
      */
     void UpdateStyleSheet(nsIContent* aElement);
 
-    // Getters and setters for fields from nsContentSink
-    nsIDocument* GetDocument() {
-      return mDocument;
-    }
-    nsNodeInfoManager* GetNodeInfoManager() {
-      return mNodeInfoManager;
-    }
+    // XXX Does anyone need this?
     nsIDocShell* GetDocShell() {
       return mDocShell;
     }
 
     bool IsScriptExecuting() {
       return IsScriptExecutingImpl();
     }
     
@@ -242,78 +220,17 @@ class nsHtml5TreeOpExecutor : public nsC
       NS_PRECONDITION(mFlushState != eNotifying, "mFlushState out of sync");
       if (mFlushState == eInDocUpdate) {
         FlushPendingAppendNotifications();
         mFlushState = eInFlush;
         mDocument->EndUpdate(UPDATE_CONTENT_MODEL);
       }
     }
 
-    void PostPendingAppendNotification(nsIContent* aParent, nsIContent* aChild) {
-      bool newParent = true;
-      const nsIContentPtr* first = mElementsSeenInThisAppendBatch.Elements();
-      const nsIContentPtr* last = first + mElementsSeenInThisAppendBatch.Length() - 1;
-      for (const nsIContentPtr* iter = last; iter >= first; --iter) {
-#ifdef DEBUG_NS_HTML5_TREE_OP_EXECUTOR_FLUSH
-        sAppendBatchSlotsExamined++;
-#endif
-        if (*iter == aParent) {
-          newParent = false;
-          break;
-        }
-      }
-      if (aChild->IsElement()) {
-        mElementsSeenInThisAppendBatch.AppendElement(aChild);
-      }
-      mElementsSeenInThisAppendBatch.AppendElement(aParent);
-      if (newParent) {
-        mPendingNotifications.AppendElement(aParent);
-      }
-#ifdef DEBUG_NS_HTML5_TREE_OP_EXECUTOR_FLUSH
-      sAppendBatchExaminations++;
-#endif
-    }
-
-    void FlushPendingAppendNotifications() {
-      NS_PRECONDITION(mFlushState == eInDocUpdate, "Notifications flushed outside update");
-      mFlushState = eNotifying;
-      const nsHtml5PendingNotification* start = mPendingNotifications.Elements();
-      const nsHtml5PendingNotification* end = start + mPendingNotifications.Length();
-      for (nsHtml5PendingNotification* iter = (nsHtml5PendingNotification*)start; iter < end; ++iter) {
-        iter->Fire();
-      }
-      mPendingNotifications.Clear();
-#ifdef DEBUG_NS_HTML5_TREE_OP_EXECUTOR_FLUSH
-      if (mElementsSeenInThisAppendBatch.Length() > sAppendBatchMaxSize) {
-        sAppendBatchMaxSize = mElementsSeenInThisAppendBatch.Length();
-      }
-#endif
-      mElementsSeenInThisAppendBatch.Clear();
-      NS_ASSERTION(mFlushState == eNotifying, "mFlushState out of sync");
-      mFlushState = eInDocUpdate;
-    }
     
-    inline bool HaveNotified(nsIContent* aNode) {
-      NS_PRECONDITION(aNode, "HaveNotified called with null argument.");
-      const nsHtml5PendingNotification* start = mPendingNotifications.Elements();
-      const nsHtml5PendingNotification* end = start + mPendingNotifications.Length();
-      for (;;) {
-        nsIContent* parent = aNode->GetParent();
-        if (!parent) {
-          return true;
-        }
-        for (nsHtml5PendingNotification* iter = (nsHtml5PendingNotification*)start; iter < end; ++iter) {
-          if (iter->Contains(parent)) {
-            return iter->HaveNotifiedIndex(parent->IndexOf(aNode));
-          }
-        }
-        aNode = parent;
-      }
-    }
-
     void StartLayout();
     
     void SetDocumentMode(nsHtml5DocumentMode m);
 
     nsresult Init(nsIDocument* aDoc, nsIURI* aURI,
                   nsISupports* aContainer, nsIChannel* aChannel);
 
     void FlushSpeculativeLoads();
@@ -353,22 +270,16 @@ class nsHtml5TreeOpExecutor : public nsC
       return mRunFlushLoopOnStack;
     }
 #endif
     
     void RunScript(nsIContent* aScriptElement);
     
     void Reset();
     
-    inline void HoldElement(nsIContent* aContent) {
-      mOwnedElements.AppendElement(aContent);
-    }
-
-    void DropHeldElements();
-
     /**
      * Flush the operations from the tree operations from the argument
      * queue unconditionally. (This is for the main thread case.)
      */
     virtual void MoveOpsFrom(nsTArray<nsHtml5TreeOperation>& aOpQueue);
     
     nsHtml5TreeOpStage* GetStage() {
       return &mStage;
--- a/parser/html/nsHtml5TreeOperation.cpp
+++ b/parser/html/nsHtml5TreeOperation.cpp
@@ -115,17 +115,17 @@ nsHtml5TreeOperation::~nsHtml5TreeOperat
       break;
   }
 }
 
 nsresult
 nsHtml5TreeOperation::AppendTextToTextNode(const char16_t* aBuffer,
                                            uint32_t aLength,
                                            nsIContent* aTextNode,
-                                           nsHtml5TreeOpExecutor* aBuilder)
+                                           nsHtml5DocumentBuilder* aBuilder)
 {
   NS_PRECONDITION(aTextNode, "Got null text node.");
 
   if (aBuilder->HaveNotified(aTextNode)) {
     // This text node has already been notified on, so it's necessary to
     // notify on the append
     nsresult rv = NS_OK;
     uint32_t oldLength = aTextNode->TextLength();
@@ -147,17 +147,17 @@ nsHtml5TreeOperation::AppendTextToTextNo
   return aTextNode->AppendText(aBuffer, aLength, false);
 }
 
 
 nsresult
 nsHtml5TreeOperation::AppendText(const char16_t* aBuffer,
                                  uint32_t aLength,
                                  nsIContent* aParent,
-                                 nsHtml5TreeOpExecutor* aBuilder)
+                                 nsHtml5DocumentBuilder* aBuilder)
 {
   nsresult rv = NS_OK;
   nsIContent* lastChild = aParent->GetLastChild();
   if (lastChild && lastChild->IsNodeOfType(nsINode::eTEXT)) {
     nsHtml5OtherDocUpdate update(aParent->OwnerDoc(),
                                  aBuilder->GetDocument());
     return AppendTextToTextNode(aBuffer, 
                                 aLength, 
@@ -171,17 +171,17 @@ nsHtml5TreeOperation::AppendText(const c
   NS_ENSURE_SUCCESS(rv, rv);
 
   return Append(text, aParent, aBuilder);
 }
 
 nsresult
 nsHtml5TreeOperation::Append(nsIContent* aNode,
                              nsIContent* aParent,
-                             nsHtml5TreeOpExecutor* aBuilder)
+                             nsHtml5DocumentBuilder* aBuilder)
 {
   nsresult rv = NS_OK;
   nsIDocument* executorDoc = aBuilder->GetDocument();
   NS_ASSERTION(executorDoc, "Null doc on executor");
   nsIDocument* parentDoc = aParent->OwnerDoc();
   NS_ASSERTION(parentDoc, "Null owner doc on old node.");
 
   if (MOZ_LIKELY(executorDoc == parentDoc)) {
@@ -202,17 +202,17 @@ nsHtml5TreeOperation::Append(nsIContent*
     nsNodeUtils::ContentAppended(aParent, aNode, childCount);
   }
   parentDoc->EndUpdate(UPDATE_CONTENT_MODEL);
   return rv;
 }
 
 nsresult
 nsHtml5TreeOperation::AppendToDocument(nsIContent* aNode,
-                                       nsHtml5TreeOpExecutor* aBuilder)
+                                       nsHtml5DocumentBuilder* aBuilder)
 {
   nsresult rv = NS_OK;
   aBuilder->FlushPendingAppendNotifications();
   nsIDocument* doc = aBuilder->GetDocument();
   uint32_t childCount = doc->GetChildCount();
   rv = doc->AppendChildTo(aNode, false);
   NS_ENSURE_SUCCESS(rv, rv);
   nsNodeUtils::ContentInserted(doc, aNode, childCount);
@@ -240,33 +240,33 @@ IsElementOrTemplateContent(nsINode* aNod
         return true;
       }
     }
   }
   return false;
 }
 
 void
-nsHtml5TreeOperation::Detach(nsIContent* aNode, nsHtml5TreeOpExecutor* aBuilder)
+nsHtml5TreeOperation::Detach(nsIContent* aNode, nsHtml5DocumentBuilder* aBuilder)
 {
   aBuilder->FlushPendingAppendNotifications();
   nsCOMPtr<nsINode> parent = aNode->GetParentNode();
   if (parent) {
     nsHtml5OtherDocUpdate update(parent->OwnerDoc(),
         aBuilder->GetDocument());
     int32_t pos = parent->IndexOf(aNode);
     NS_ASSERTION((pos >= 0), "Element not found as child of its parent");
     parent->RemoveChildAt(pos, true);
   }
 }
 
 nsresult
 nsHtml5TreeOperation::AppendChildrenToNewParent(nsIContent* aNode,
                                                 nsIContent* aParent,
-                                                nsHtml5TreeOpExecutor* aBuilder)
+                                                nsHtml5DocumentBuilder* aBuilder)
 {
   aBuilder->FlushPendingAppendNotifications();
 
   nsHtml5OtherDocUpdate update(aParent->OwnerDoc(),
                                aBuilder->GetDocument());
 
   uint32_t childCount = aParent->GetChildCount();
   bool didAppend = false;
@@ -283,17 +283,17 @@ nsHtml5TreeOperation::AppendChildrenToNe
   }
   return NS_OK;
 }
 
 nsresult
 nsHtml5TreeOperation::FosterParent(nsIContent* aNode,
                                    nsIContent* aParent,
                                    nsIContent* aTable,
-                                   nsHtml5TreeOpExecutor* aBuilder)
+                                   nsHtml5DocumentBuilder* aBuilder)
 {
   nsIContent* foster = aTable->GetParent();
 
   if (IsElementOrTemplateContent(foster)) {
     aBuilder->FlushPendingAppendNotifications();
 
     nsHtml5OtherDocUpdate update(foster->OwnerDoc(),
                                  aBuilder->GetDocument());
@@ -306,17 +306,17 @@ nsHtml5TreeOperation::FosterParent(nsICo
   }
 
   return Append(aNode, aParent, aBuilder);
 }
 
 nsresult
 nsHtml5TreeOperation::AddAttributes(nsIContent* aNode,
                                     nsHtml5HtmlAttributes* aAttributes,
-                                    nsHtml5TreeOpExecutor* aBuilder)
+                                    nsHtml5DocumentBuilder* aBuilder)
 {
   dom::Element* node = aNode->AsElement();
   nsHtml5OtherDocUpdate update(node->OwnerDoc(),
                                aBuilder->GetDocument());
 
   int32_t len = aAttributes->getLength();
   for (int32_t i = len; i > 0;) {
     --i;
@@ -340,17 +340,17 @@ nsHtml5TreeOperation::AddAttributes(nsIC
 }
 
 
 nsIContent*
 nsHtml5TreeOperation::CreateElement(int32_t aNs,
                                     nsIAtom* aName,
                                     nsHtml5HtmlAttributes* aAttributes,
                                     bool aFromNetwork,
-                                    nsHtml5TreeOpExecutor* aBuilder)
+                                    nsHtml5DocumentBuilder* aBuilder)
 {
   bool isKeygen = (aName == nsHtml5Atoms::keygen && aNs == kNameSpaceID_XHTML);
   if (MOZ_UNLIKELY(isKeygen)) {
     aName = nsHtml5Atoms::select;
   }
 
   nsCOMPtr<dom::Element> newContent;
   nsCOMPtr<nsINodeInfo> nodeInfo = aBuilder->GetNodeInfoManager()->
@@ -485,17 +485,17 @@ nsHtml5TreeOperation::SetFormElement(nsI
     nsRefPtr<dom::HTMLImageElement> imageElement =
       static_cast<dom::HTMLImageElement*>(domImageElement.get());
     MOZ_ASSERT(imageElement);
     imageElement->SetForm(formElement);
   }
 }
 
 nsresult
-nsHtml5TreeOperation::AppendIsindexPrompt(nsIContent* parent, nsHtml5TreeOpExecutor* aBuilder)
+nsHtml5TreeOperation::AppendIsindexPrompt(nsIContent* parent, nsHtml5DocumentBuilder* aBuilder)
 {
   nsXPIDLString prompt;
   nsresult rv =
       nsContentUtils::GetLocalizedString(nsContentUtils::eFORMS_PROPERTIES,
                                          "IsIndexPromptWithSpace", prompt);
   uint32_t len = prompt.Length();
   if (NS_FAILED(rv)) {
     return rv;
@@ -507,17 +507,17 @@ nsHtml5TreeOperation::AppendIsindexPromp
   return AppendText(prompt.BeginReading(), len, parent, aBuilder);
 }
 
 nsresult
 nsHtml5TreeOperation::FosterParentText(nsIContent* aStackParent,
                                        char16_t* aBuffer,
                                        uint32_t aLength,
                                        nsIContent* aTable,
-                                       nsHtml5TreeOpExecutor* aBuilder)
+                                       nsHtml5DocumentBuilder* aBuilder)
 {
   nsresult rv = NS_OK;
   nsIContent* foster = aTable->GetParent();
 
   if (IsElementOrTemplateContent(foster)) {
     aBuilder->FlushPendingAppendNotifications();
 
     nsHtml5OtherDocUpdate update(foster->OwnerDoc(),
@@ -547,46 +547,46 @@ nsHtml5TreeOperation::FosterParentText(n
 
   return AppendText(aBuffer, aLength, aStackParent, aBuilder);
 }
 
 nsresult
 nsHtml5TreeOperation::AppendComment(nsIContent* aParent,
                                     char16_t* aBuffer,
                                     int32_t aLength,
-                                    nsHtml5TreeOpExecutor* aBuilder)
+                                    nsHtml5DocumentBuilder* aBuilder)
 {
   nsRefPtr<dom::Comment> comment =
     new dom::Comment(aBuilder->GetNodeInfoManager());
   NS_ASSERTION(comment, "Infallible malloc failed?");
   nsresult rv = comment->SetText(aBuffer, aLength, false);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return Append(comment, aParent, aBuilder);
 }
 
 nsresult
 nsHtml5TreeOperation::AppendCommentToDocument(char16_t* aBuffer,
                                               int32_t aLength,
-                                              nsHtml5TreeOpExecutor* aBuilder)
+                                              nsHtml5DocumentBuilder* aBuilder)
 {
   nsRefPtr<dom::Comment> comment =
     new dom::Comment(aBuilder->GetNodeInfoManager());
   NS_ASSERTION(comment, "Infallible malloc failed?");
   nsresult rv = comment->SetText(aBuffer, aLength, false);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return AppendToDocument(comment, aBuilder);
 }
 
 nsresult
 nsHtml5TreeOperation::AppendDoctypeToDocument(nsIAtom* aName,
                                               const nsAString& aPublicId,
                                               const nsAString& aSystemId,
-                                              nsHtml5TreeOpExecutor* aBuilder)
+                                              nsHtml5DocumentBuilder* aBuilder)
 {
   // Adapted from nsXMLContentSink
   // Create a new doctype node
   nsCOMPtr<nsIDOMDocumentType> docType;
   nsAutoString voidString;
   voidString.SetIsVoid(true);
   NS_NewDOMDocumentType(getter_AddRefs(docType),
                         aBuilder->GetNodeInfoManager(),
@@ -613,17 +613,17 @@ nsHtml5TreeOperation::PreventScriptExecu
 {
   nsCOMPtr<nsIScriptElement> sele = do_QueryInterface(aNode);
   MOZ_ASSERT(sele);
   sele->PreventExecution();
 }
 
 void
 nsHtml5TreeOperation::DoneAddingChildren(nsIContent* aNode,
-                                         nsHtml5TreeOpExecutor* aBuilder)
+                                         nsHtml5DocumentBuilder* aBuilder)
 {
   aNode->DoneAddingChildren(aBuilder->HaveNotified(aNode));
 }
 
 void
 nsHtml5TreeOperation::DoneCreatingElement(nsIContent* aNode)
 {
   aNode->DoneCreatingElement();
--- a/parser/html/nsHtml5TreeOperation.h
+++ b/parser/html/nsHtml5TreeOperation.h
@@ -7,16 +7,17 @@
 
 #include "nsHtml5DocumentMode.h"
 #include "nsHtml5HtmlAttributes.h"
 #include "nsXPCOMStrings.h"
 
 class nsIContent;
 class nsHtml5TreeOpExecutor;
 class nsHtml5StateSnapshot;
+class nsHtml5DocumentBuilder;
 
 enum eHtml5TreeOperation {
 #ifdef DEBUG
   eTreeOpUninitialized,
 #endif
   // main HTML5 ops
   eTreeOpAppend,
   eTreeOpDetach,
@@ -108,82 +109,82 @@ class nsHtml5TreeOperation {
       nsAutoString str;
       aAtom->ToString(str);
       return do_GetAtom(str);
     }
 
     static nsresult AppendTextToTextNode(const char16_t* aBuffer,
                                          uint32_t aLength,
                                          nsIContent* aTextNode,
-                                         nsHtml5TreeOpExecutor* aBuilder);
+                                         nsHtml5DocumentBuilder* aBuilder);
 
     static nsresult AppendText(const char16_t* aBuffer,
                                uint32_t aLength,
                                nsIContent* aParent,
-                               nsHtml5TreeOpExecutor* aBuilder);
+                               nsHtml5DocumentBuilder* aBuilder);
 
     static nsresult Append(nsIContent* aNode,
                            nsIContent* aParent,
-                           nsHtml5TreeOpExecutor* aBuilder);
+                           nsHtml5DocumentBuilder* aBuilder);
 
     static nsresult AppendToDocument(nsIContent* aNode,
-                                     nsHtml5TreeOpExecutor* aBuilder);
+                                     nsHtml5DocumentBuilder* aBuilder);
 
-    static void Detach(nsIContent* aNode, nsHtml5TreeOpExecutor* aBuilder);
+    static void Detach(nsIContent* aNode, nsHtml5DocumentBuilder* aBuilder);
 
     static nsresult AppendChildrenToNewParent(nsIContent* aNode,
                                               nsIContent* aParent,
-                                              nsHtml5TreeOpExecutor* aBuilder);
+                                              nsHtml5DocumentBuilder* aBuilder);
 
     static nsresult FosterParent(nsIContent* aNode,
                                  nsIContent* aParent,
                                  nsIContent* aTable,
-                                 nsHtml5TreeOpExecutor* aBuilder);
+                                 nsHtml5DocumentBuilder* aBuilder);
 
     static nsresult AddAttributes(nsIContent* aNode,
                                   nsHtml5HtmlAttributes* aAttributes,
-                                  nsHtml5TreeOpExecutor* aBuilder);
+                                  nsHtml5DocumentBuilder* aBuilder);
 
     static nsIContent* CreateElement(int32_t aNs,
                                      nsIAtom* aName,
                                      nsHtml5HtmlAttributes* aAttributes,
                                      bool aFromNetwork,
-                                     nsHtml5TreeOpExecutor* aBuilder);
+                                     nsHtml5DocumentBuilder* aBuilder);
 
     static void SetFormElement(nsIContent* aNode, nsIContent* aParent);
 
     static nsresult AppendIsindexPrompt(nsIContent* parent,
-                                        nsHtml5TreeOpExecutor* aBuilder);
+                                        nsHtml5DocumentBuilder* aBuilder);
 
     static nsresult FosterParentText(nsIContent* aStackParent,
                                      char16_t* aBuffer,
                                      uint32_t aLength,
                                      nsIContent* aTable,
-                                     nsHtml5TreeOpExecutor* aBuilder);
+                                     nsHtml5DocumentBuilder* aBuilder);
 
     static nsresult AppendComment(nsIContent* aParent,
                                   char16_t* aBuffer,
                                   int32_t aLength,
-                                  nsHtml5TreeOpExecutor* aBuilder);
+                                  nsHtml5DocumentBuilder* aBuilder);
 
     static nsresult AppendCommentToDocument(char16_t* aBuffer,
                                            int32_t aLength,
-                                           nsHtml5TreeOpExecutor* aBuilder);
+                                           nsHtml5DocumentBuilder* aBuilder);
 
     static nsresult AppendDoctypeToDocument(nsIAtom* aName,
                                             const nsAString& aPublicId,
                                             const nsAString& aSystemId,
-                                            nsHtml5TreeOpExecutor* aBuilder);
+                                            nsHtml5DocumentBuilder* aBuilder);
 
     static nsIContent* GetDocumentFragmentForTemplate(nsIContent* aNode);
 
     static void PreventScriptExecution(nsIContent* aNode);
 
     static void DoneAddingChildren(nsIContent* aNode,
-                                   nsHtml5TreeOpExecutor* aBuilder);
+                                   nsHtml5DocumentBuilder* aBuilder);
 
     static void DoneCreatingElement(nsIContent* aNode);
 
     nsHtml5TreeOperation();
 
     ~nsHtml5TreeOperation();
 
     inline void Init(eHtml5TreeOperation aOpCode) {
@@ -436,17 +437,18 @@ class nsHtml5TreeOperation {
     inline void SetSnapshot(nsAHtml5TreeBuilderState* aSnapshot, int32_t aLine) {
       NS_ASSERTION(IsRunScript(), 
         "Setting a snapshot for a tree operation other than eTreeOpRunScript!");
       NS_PRECONDITION(aSnapshot, "Initialized tree op with null snapshot.");
       mTwo.state = aSnapshot;
       mFour.integer = aLine;
     }
 
-    nsresult Perform(nsHtml5TreeOpExecutor* aBuilder, nsIContent** aScriptElement);
+    nsresult Perform(nsHtml5TreeOpExecutor* aBuilder,
+                     nsIContent** aScriptElement);
 
   private:
     // possible optimization:
     // Make the queue take items the size of pointer and make the op code
     // decide how many operands it dequeues after it.
     eHtml5TreeOperation mOpCode;
     union {
       nsIContent**                    node;