LCOV - code coverage report
Current view: top level - parser/html - nsHtml5TreeBuilderCppSupplement.h (source / functions) Hit Total Coverage
Test: output.info Lines: 252 866 29.1 %
Date: 2017-07-14 16:53:18 Functions: 27 92 29.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=2 sw=2 et tw=78: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "nsError.h"
       8             : #include "nsIPresShell.h"
       9             : #include "nsNodeUtils.h"
      10             : #include "nsIFrame.h"
      11             : #include "mozilla/Likely.h"
      12             : #include "mozilla/UniquePtr.h"
      13             : 
      14           0 : nsHtml5TreeBuilder::nsHtml5TreeBuilder(nsHtml5OplessBuilder* aBuilder)
      15             :   : scriptingEnabled(false)
      16             :   , fragment(false)
      17             :   , contextName(nullptr)
      18             :   , contextNamespace(kNameSpaceID_None)
      19             :   , contextNode(nullptr)
      20             :   , formPointer(nullptr)
      21             :   , headPointer(nullptr)
      22             :   , mBuilder(aBuilder)
      23             :   , mViewSource(nullptr)
      24             :   , mOpSink(nullptr)
      25             :   , mHandles(nullptr)
      26             :   , mHandlesUsed(0)
      27             :   , mSpeculativeLoadStage(nullptr)
      28             :   , mBroken(NS_OK)
      29             :   , mCurrentHtmlScriptIsAsyncOrDefer(false)
      30             :   , mPreventScriptExecution(false)
      31             : #ifdef DEBUG
      32           0 :   , mActive(false)
      33             : #endif
      34             : {
      35           0 :   MOZ_COUNT_CTOR(nsHtml5TreeBuilder);
      36           0 : }
      37             : 
      38           4 : nsHtml5TreeBuilder::nsHtml5TreeBuilder(nsAHtml5TreeOpSink* aOpSink,
      39           4 :                                        nsHtml5TreeOpStage* aStage)
      40             :   : scriptingEnabled(false)
      41             :   , fragment(false)
      42             :   , contextName(nullptr)
      43             :   , contextNamespace(kNameSpaceID_None)
      44             :   , contextNode(nullptr)
      45             :   , formPointer(nullptr)
      46             :   , headPointer(nullptr)
      47             :   , mBuilder(nullptr)
      48             :   , mViewSource(nullptr)
      49             :   , mOpSink(aOpSink)
      50           4 :   , mHandles(new nsIContent*[NS_HTML5_TREE_BUILDER_HANDLE_ARRAY_LENGTH])
      51             :   , mHandlesUsed(0)
      52             :   , mSpeculativeLoadStage(aStage)
      53             :   , mBroken(NS_OK)
      54             :   , mCurrentHtmlScriptIsAsyncOrDefer(false)
      55             :   , mPreventScriptExecution(false)
      56             : #ifdef DEBUG
      57           8 :   , mActive(false)
      58             : #endif
      59             : {
      60           4 :   MOZ_COUNT_CTOR(nsHtml5TreeBuilder);
      61           4 : }
      62             : 
      63           3 : nsHtml5TreeBuilder::~nsHtml5TreeBuilder()
      64             : {
      65           1 :   MOZ_COUNT_DTOR(nsHtml5TreeBuilder);
      66           1 :   NS_ASSERTION(!mActive, "nsHtml5TreeBuilder deleted without ever calling end() on it!");
      67           1 :   mOpQueue.Clear();
      68           3 : }
      69             : 
      70             : nsIContentHandle*
      71          14 : nsHtml5TreeBuilder::createElement(int32_t aNamespace, nsIAtom* aName,
      72             :                                   nsHtml5HtmlAttributes* aAttributes,
      73             :                                   nsIContentHandle* aIntendedParent)
      74             : {
      75          14 :   NS_PRECONDITION(aAttributes, "Got null attributes.");
      76          14 :   NS_PRECONDITION(aName, "Got null name.");
      77          14 :   NS_PRECONDITION(aNamespace == kNameSpaceID_XHTML || 
      78             :                   aNamespace == kNameSpaceID_SVG || 
      79             :                   aNamespace == kNameSpaceID_MathML,
      80             :                   "Bogus namespace.");
      81             : 
      82          14 :   if (mBuilder) {
      83           0 :     nsCOMPtr<nsIAtom> name = nsHtml5TreeOperation::Reget(aName);
      84             : 
      85             :     nsIContent* intendedParent = aIntendedParent ?
      86           0 :       static_cast<nsIContent*>(aIntendedParent) : nullptr;
      87             : 
      88             :     // intendedParent == nullptr is a special case where the
      89             :     // intended parent is the document.
      90           0 :     nsNodeInfoManager* nodeInfoManager = intendedParent ?
      91           0 :        intendedParent->OwnerDoc()->NodeInfoManager() :
      92           0 :        mBuilder->GetNodeInfoManager();
      93             : 
      94             :     nsIContent* elem =
      95           0 :       nsHtml5TreeOperation::CreateElement(aNamespace,
      96             :                                           name,
      97             :                                           aAttributes,
      98             :                                           mozilla::dom::FROM_PARSER_FRAGMENT,
      99             :                                           nodeInfoManager,
     100           0 :                                           mBuilder);
     101           0 :     if (MOZ_UNLIKELY(aAttributes != tokenizer->GetAttributes() &&
     102             :                      aAttributes != nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES)) {
     103           0 :       delete aAttributes;
     104             :     }
     105           0 :     return elem;
     106             :   }
     107             : 
     108          14 :   nsIContentHandle* content = AllocateContentHandle();
     109          14 :   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
     110          14 :   NS_ASSERTION(treeOp, "Tree op allocation failed.");
     111          14 :   treeOp->Init(aNamespace,
     112             :                aName,
     113             :                aAttributes,
     114             :                content,
     115             :                aIntendedParent,
     116          28 :                !!mSpeculativeLoadStage);
     117             :   // mSpeculativeLoadStage is non-null only in the off-the-main-thread
     118             :   // tree builder, which handles the network stream
     119             : 
     120             :   // Start wall of code for speculative loading and line numbers
     121             : 
     122          14 :   if (mSpeculativeLoadStage) {
     123          14 :     switch (aNamespace) {
     124             :       case kNameSpaceID_XHTML:
     125          14 :         if (nsGkAtoms::img == aName) {
     126             :           nsHtml5String url =
     127           0 :             aAttributes->getValue(nsHtml5AttributeName::ATTR_SRC);
     128             :           nsHtml5String srcset =
     129           0 :             aAttributes->getValue(nsHtml5AttributeName::ATTR_SRCSET);
     130             :           nsHtml5String crossOrigin =
     131           0 :             aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
     132             :           nsHtml5String referrerPolicy =
     133           0 :             aAttributes->getValue(nsHtml5AttributeName::ATTR_REFERRERPOLICY);
     134             :           nsHtml5String sizes =
     135           0 :             aAttributes->getValue(nsHtml5AttributeName::ATTR_SIZES);
     136           0 :           mSpeculativeLoadQueue.AppendElement()->InitImage(
     137           0 :             url, crossOrigin, referrerPolicy, srcset, sizes);
     138          14 :         } else if (nsGkAtoms::source == aName) {
     139             :           nsHtml5String srcset =
     140           0 :             aAttributes->getValue(nsHtml5AttributeName::ATTR_SRCSET);
     141             :           // Sources without srcset cannot be selected. The source could also be
     142             :           // for a media element, but in that context doesn't use srcset.  See
     143             :           // comments in nsHtml5SpeculativeLoad.h about <picture> preloading
     144           0 :           if (srcset) {
     145             :             nsHtml5String sizes =
     146           0 :               aAttributes->getValue(nsHtml5AttributeName::ATTR_SIZES);
     147             :             nsHtml5String type =
     148           0 :               aAttributes->getValue(nsHtml5AttributeName::ATTR_TYPE);
     149             :             nsHtml5String media =
     150           0 :               aAttributes->getValue(nsHtml5AttributeName::ATTR_MEDIA);
     151           0 :             mSpeculativeLoadQueue.AppendElement()->InitPictureSource(
     152           0 :               srcset, sizes, type, media);
     153             :           }
     154          14 :         } else if (nsGkAtoms::script == aName) {
     155           5 :           nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
     156           5 :           NS_ASSERTION(treeOp, "Tree op allocation failed.");
     157           5 :           treeOp->Init(eTreeOpSetScriptLineNumberAndFreeze, content, tokenizer->getLineNumber());
     158             : 
     159             :           nsHtml5String url =
     160           5 :             aAttributes->getValue(nsHtml5AttributeName::ATTR_SRC);
     161           5 :           if (url) {
     162             :             nsHtml5String charset =
     163           4 :               aAttributes->getValue(nsHtml5AttributeName::ATTR_CHARSET);
     164             :             nsHtml5String type =
     165           4 :               aAttributes->getValue(nsHtml5AttributeName::ATTR_TYPE);
     166             :             nsHtml5String crossOrigin =
     167           4 :               aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
     168             :             nsHtml5String integrity =
     169           4 :               aAttributes->getValue(nsHtml5AttributeName::ATTR_INTEGRITY);
     170           4 :             mSpeculativeLoadQueue.AppendElement()->InitScript(
     171             :               url,
     172             :               charset,
     173             :               type,
     174             :               crossOrigin,
     175             :               integrity,
     176           8 :               mode == nsHtml5TreeBuilder::IN_HEAD);
     177           4 :             mCurrentHtmlScriptIsAsyncOrDefer =
     178           8 :               aAttributes->contains(nsHtml5AttributeName::ATTR_ASYNC) ||
     179           4 :               aAttributes->contains(nsHtml5AttributeName::ATTR_DEFER);
     180             :           }
     181           9 :         } else if (nsGkAtoms::link == aName) {
     182             :           nsHtml5String rel =
     183           0 :             aAttributes->getValue(nsHtml5AttributeName::ATTR_REL);
     184             :           // Not splitting on space here is bogus but the old parser didn't even
     185             :           // do a case-insensitive check.
     186           0 :           if (rel) {
     187           0 :             if (rel.LowerCaseEqualsASCII("stylesheet")) {
     188             :               nsHtml5String url =
     189           0 :                 aAttributes->getValue(nsHtml5AttributeName::ATTR_HREF);
     190           0 :               if (url) {
     191             :                 nsHtml5String charset =
     192           0 :                   aAttributes->getValue(nsHtml5AttributeName::ATTR_CHARSET);
     193             :                 nsHtml5String crossOrigin =
     194           0 :                   aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
     195             :                 nsHtml5String integrity =
     196           0 :                   aAttributes->getValue(nsHtml5AttributeName::ATTR_INTEGRITY);
     197           0 :                 mSpeculativeLoadQueue.AppendElement()->InitStyle(
     198           0 :                   url, charset, crossOrigin, integrity);
     199             :               }
     200           0 :             } else if (rel.LowerCaseEqualsASCII("preconnect")) {
     201             :               nsHtml5String url =
     202           0 :                 aAttributes->getValue(nsHtml5AttributeName::ATTR_HREF);
     203           0 :               if (url) {
     204             :                 nsHtml5String crossOrigin =
     205           0 :                   aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
     206           0 :                 mSpeculativeLoadQueue.AppendElement()->InitPreconnect(
     207           0 :                   url, crossOrigin);
     208             :               }
     209             :             }
     210             :           }
     211           9 :         } else if (nsGkAtoms::video == aName) {
     212             :           nsHtml5String url =
     213           0 :             aAttributes->getValue(nsHtml5AttributeName::ATTR_POSTER);
     214           0 :           if (url) {
     215           0 :             mSpeculativeLoadQueue.AppendElement()->InitImage(
     216           0 :               url, nullptr, nullptr, nullptr, nullptr);
     217             :           }
     218           9 :         } else if (nsGkAtoms::style == aName) {
     219           0 :           nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
     220           0 :           NS_ASSERTION(treeOp, "Tree op allocation failed.");
     221           0 :           treeOp->Init(eTreeOpSetStyleLineNumber, content, tokenizer->getLineNumber());
     222           9 :         } else if (nsGkAtoms::html == aName) {
     223             :           nsHtml5String url =
     224           2 :             aAttributes->getValue(nsHtml5AttributeName::ATTR_MANIFEST);
     225           2 :           mSpeculativeLoadQueue.AppendElement()->InitManifest(url);
     226           7 :         } else if (nsGkAtoms::base == aName) {
     227             :           nsHtml5String url =
     228           0 :             aAttributes->getValue(nsHtml5AttributeName::ATTR_HREF);
     229           0 :           if (url) {
     230           0 :             mSpeculativeLoadQueue.AppendElement()->InitBase(url);
     231             :           }
     232           7 :         } else if (nsGkAtoms::meta == aName) {
     233           2 :           if (nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString(
     234             :                       "content-security-policy",
     235             :                       aAttributes->getValue(nsHtml5AttributeName::ATTR_HTTP_EQUIV))) {
     236             :             nsHtml5String csp =
     237           0 :               aAttributes->getValue(nsHtml5AttributeName::ATTR_CONTENT);
     238           0 :             if (csp) {
     239           0 :               mSpeculativeLoadQueue.AppendElement()->InitMetaCSP(csp);
     240             :             }
     241             :           }
     242           2 :           else if (nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString(
     243             :                       "referrer",
     244             :                       aAttributes->getValue(nsHtml5AttributeName::ATTR_NAME))) {
     245             :             nsHtml5String referrerPolicy =
     246           0 :               aAttributes->getValue(nsHtml5AttributeName::ATTR_CONTENT);
     247           0 :             if (referrerPolicy) {
     248           0 :               mSpeculativeLoadQueue.AppendElement()->InitMetaReferrerPolicy(
     249           0 :                 referrerPolicy);
     250             :             }
     251             :           }
     252             :         }
     253          14 :         break;
     254             :       case kNameSpaceID_SVG:
     255           0 :         if (nsGkAtoms::image == aName) {
     256             :           nsHtml5String url =
     257           0 :             aAttributes->getValue(nsHtml5AttributeName::ATTR_XLINK_HREF);
     258           0 :           if (url) {
     259           0 :             mSpeculativeLoadQueue.AppendElement()->InitImage(
     260           0 :               url, nullptr, nullptr, nullptr, nullptr);
     261             :           }
     262           0 :         } else if (nsGkAtoms::script == aName) {
     263           0 :           nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
     264           0 :           NS_ASSERTION(treeOp, "Tree op allocation failed.");
     265           0 :           treeOp->Init(eTreeOpSetScriptLineNumberAndFreeze, content, tokenizer->getLineNumber());
     266             : 
     267             :           nsHtml5String url =
     268           0 :             aAttributes->getValue(nsHtml5AttributeName::ATTR_XLINK_HREF);
     269           0 :           if (url) {
     270             :             nsHtml5String type =
     271           0 :               aAttributes->getValue(nsHtml5AttributeName::ATTR_TYPE);
     272             :             nsHtml5String crossOrigin =
     273           0 :               aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
     274             :             nsHtml5String integrity =
     275           0 :               aAttributes->getValue(nsHtml5AttributeName::ATTR_INTEGRITY);
     276           0 :             mSpeculativeLoadQueue.AppendElement()->InitScript(
     277             :               url,
     278             :               nullptr,
     279             :               type,
     280             :               crossOrigin,
     281             :               integrity,
     282           0 :               mode == nsHtml5TreeBuilder::IN_HEAD);
     283             :           }
     284           0 :         } else if (nsGkAtoms::style == aName) {
     285           0 :           nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
     286           0 :           NS_ASSERTION(treeOp, "Tree op allocation failed.");
     287           0 :           treeOp->Init(eTreeOpSetStyleLineNumber, content, tokenizer->getLineNumber());
     288             : 
     289             :           nsHtml5String url =
     290           0 :             aAttributes->getValue(nsHtml5AttributeName::ATTR_XLINK_HREF);
     291           0 :           if (url) {
     292             :             nsHtml5String crossOrigin =
     293           0 :               aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
     294             :             nsHtml5String integrity =
     295           0 :               aAttributes->getValue(nsHtml5AttributeName::ATTR_INTEGRITY);
     296           0 :             mSpeculativeLoadQueue.AppendElement()->InitStyle(
     297           0 :               url, nullptr, crossOrigin, integrity);
     298             :           }
     299             :         }
     300           0 :         break;
     301             :     }
     302           0 :   } else if (aNamespace != kNameSpaceID_MathML) {
     303             :     // No speculative loader--just line numbers and defer/async check
     304           0 :     if (nsGkAtoms::style == aName) {
     305           0 :       nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
     306           0 :       NS_ASSERTION(treeOp, "Tree op allocation failed.");
     307           0 :       treeOp->Init(eTreeOpSetStyleLineNumber, content, tokenizer->getLineNumber());
     308           0 :     } else if (nsGkAtoms::script == aName) {
     309           0 :       nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
     310           0 :       NS_ASSERTION(treeOp, "Tree op allocation failed.");
     311           0 :       treeOp->Init(eTreeOpSetScriptLineNumberAndFreeze, content, tokenizer->getLineNumber());
     312           0 :       if (aNamespace == kNameSpaceID_XHTML) {
     313           0 :         mCurrentHtmlScriptIsAsyncOrDefer = 
     314           0 :           aAttributes->contains(nsHtml5AttributeName::ATTR_SRC) &&
     315           0 :           (aAttributes->contains(nsHtml5AttributeName::ATTR_ASYNC) ||
     316           0 :            aAttributes->contains(nsHtml5AttributeName::ATTR_DEFER));
     317             :       }
     318           0 :     } else if (aNamespace == kNameSpaceID_XHTML) {
     319           0 :       if (nsGkAtoms::html == aName) {
     320             :         nsHtml5String url =
     321           0 :           aAttributes->getValue(nsHtml5AttributeName::ATTR_MANIFEST);
     322           0 :         nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
     323           0 :         NS_ASSERTION(treeOp, "Tree op allocation failed.");
     324           0 :         if (url) {
     325             :           nsString
     326           0 :             urlString; // Not Auto, because using it to hold nsStringBuffer*
     327           0 :           url.ToString(urlString);
     328           0 :           treeOp->Init(eTreeOpProcessOfflineManifest, urlString);
     329             :         } else {
     330           0 :           treeOp->Init(eTreeOpProcessOfflineManifest, EmptyString());
     331             :         }
     332           0 :       } else if (nsGkAtoms::base == aName && mViewSource) {
     333             :         nsHtml5String url =
     334           0 :           aAttributes->getValue(nsHtml5AttributeName::ATTR_HREF);
     335           0 :         if (url) {
     336           0 :           mViewSource->AddBase(url);
     337             :         } 
     338             :       }
     339             :     }
     340             :   }
     341             : 
     342             :   // End wall of code for speculative loading
     343             :   
     344          14 :   return content;
     345             : }
     346             : 
     347             : nsIContentHandle*
     348           0 : nsHtml5TreeBuilder::createElement(int32_t aNamespace, nsIAtom* aName,
     349             :                                   nsHtml5HtmlAttributes* aAttributes,
     350             :                                   nsIContentHandle* aFormElement,
     351             :                                   nsIContentHandle* aIntendedParent)
     352             : {
     353             :   nsIContentHandle* content = createElement(aNamespace, aName, aAttributes,
     354           0 :                                             aIntendedParent);
     355           0 :   if (aFormElement) {
     356           0 :     if (mBuilder) {
     357             :       nsHtml5TreeOperation::SetFormElement(static_cast<nsIContent*>(content),
     358           0 :         static_cast<nsIContent*>(aFormElement));
     359             :     } else {
     360           0 :       nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
     361           0 :       NS_ASSERTION(treeOp, "Tree op allocation failed.");
     362           0 :       treeOp->Init(eTreeOpSetFormElement, content, aFormElement);
     363             :     }
     364             :   }
     365           0 :   return content;
     366             : }
     367             : 
     368             : nsIContentHandle*
     369           2 : nsHtml5TreeBuilder::createHtmlElementSetAsRoot(nsHtml5HtmlAttributes* aAttributes)
     370             : {
     371             :   nsIContentHandle* content =
     372           2 :     createElement(kNameSpaceID_XHTML, nsGkAtoms::html, aAttributes, nullptr);
     373           2 :   if (mBuilder) {
     374             :     nsresult rv = nsHtml5TreeOperation::AppendToDocument(static_cast<nsIContent*>(content),
     375           0 :                                                          mBuilder);
     376           0 :     if (NS_FAILED(rv)) {
     377           0 :       MarkAsBrokenAndRequestSuspension(rv);
     378             :     }
     379             :   } else {
     380           2 :     nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
     381           2 :     NS_ASSERTION(treeOp, "Tree op allocation failed.");
     382           2 :     treeOp->Init(eTreeOpAppendToDocument, content);
     383             :   }
     384           2 :   return content;
     385             : }
     386             : 
     387             : nsIContentHandle*
     388           0 : nsHtml5TreeBuilder::createAndInsertFosterParentedElement(int32_t aNamespace, nsIAtom* aName,
     389             :                                                          nsHtml5HtmlAttributes* aAttributes,
     390             :                                                          nsIContentHandle* aFormElement,
     391             :                                                          nsIContentHandle* aTable,
     392             :                                                          nsIContentHandle* aStackParent)
     393             : {
     394           0 :   NS_PRECONDITION(aTable, "Null table");
     395           0 :   NS_PRECONDITION(aStackParent, "Null stack parent");
     396             : 
     397           0 :   if (mBuilder) {
     398             :     // Get the foster parent to use as the intended parent when creating
     399             :     // the child element.
     400             :     nsIContent* fosterParent = nsHtml5TreeOperation::GetFosterParent(
     401             :       static_cast<nsIContent*>(aTable),
     402           0 :       static_cast<nsIContent*>(aStackParent));
     403             : 
     404             :     nsIContentHandle* child = createElement(aNamespace, aName, aAttributes,
     405           0 :       aFormElement, fosterParent);
     406             : 
     407           0 :     insertFosterParentedChild(child, aTable, aStackParent);
     408             : 
     409           0 :     return child;
     410             :   }
     411             : 
     412             :   // Tree op to get the foster parent that we use as the intended parent
     413             :   // when creating the child element.
     414           0 :   nsHtml5TreeOperation* fosterParentTreeOp = mOpQueue.AppendElement();
     415           0 :   NS_ASSERTION(fosterParentTreeOp, "Tree op allocation failed.");
     416           0 :   nsIContentHandle* fosterParentHandle = AllocateContentHandle();
     417             :   fosterParentTreeOp->Init(eTreeOpGetFosterParent, aTable,
     418           0 :                            aStackParent, fosterParentHandle);
     419             : 
     420             :   // Create the element with the correct intended parent.
     421             :   nsIContentHandle* child = createElement(aNamespace, aName, aAttributes,
     422           0 :     aFormElement, fosterParentHandle);
     423             : 
     424             :   // Insert the child into the foster parent.
     425           0 :   insertFosterParentedChild(child, aTable, aStackParent);
     426             : 
     427           0 :   return child;
     428             : }
     429             : 
     430             : void
     431           0 : nsHtml5TreeBuilder::detachFromParent(nsIContentHandle* aElement)
     432             : {
     433           0 :   NS_PRECONDITION(aElement, "Null element");
     434             : 
     435           0 :   if (mBuilder) {
     436             :     nsHtml5TreeOperation::Detach(static_cast<nsIContent*>(aElement),
     437           0 :                                  mBuilder);
     438           0 :     return;
     439             :   }
     440             : 
     441           0 :   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
     442           0 :   NS_ASSERTION(treeOp, "Tree op allocation failed.");
     443           0 :   treeOp->Init(eTreeOpDetach, aElement);
     444             : }
     445             : 
     446             : void
     447          12 : nsHtml5TreeBuilder::appendElement(nsIContentHandle* aChild, nsIContentHandle* aParent)
     448             : {
     449          12 :   NS_PRECONDITION(aChild, "Null child");
     450          12 :   NS_PRECONDITION(aParent, "Null parent");
     451          12 :   if (deepTreeSurrogateParent) {
     452           0 :     return;
     453             :   }
     454             : 
     455          12 :   if (mBuilder) {
     456             :     nsresult rv = nsHtml5TreeOperation::Append(static_cast<nsIContent*>(aChild),
     457             :                                                static_cast<nsIContent*>(aParent),
     458           0 :                                                mBuilder);
     459           0 :     if (NS_FAILED(rv)) {
     460           0 :       MarkAsBrokenAndRequestSuspension(rv);
     461             :     }
     462           0 :     return;
     463             :   }
     464             : 
     465          12 :   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
     466          12 :   NS_ASSERTION(treeOp, "Tree op allocation failed.");
     467          12 :   treeOp->Init(eTreeOpAppend, aChild, aParent);
     468             : }
     469             : 
     470             : void
     471           0 : nsHtml5TreeBuilder::appendChildrenToNewParent(nsIContentHandle* aOldParent, nsIContentHandle* aNewParent)
     472             : {
     473           0 :   NS_PRECONDITION(aOldParent, "Null old parent");
     474           0 :   NS_PRECONDITION(aNewParent, "Null new parent");
     475             : 
     476           0 :   if (mBuilder) {
     477             :     nsresult rv = nsHtml5TreeOperation::AppendChildrenToNewParent(
     478             :       static_cast<nsIContent*>(aOldParent),
     479             :       static_cast<nsIContent*>(aNewParent),
     480           0 :       mBuilder);
     481           0 :     if (NS_FAILED(rv)) {
     482           0 :       MarkAsBrokenAndRequestSuspension(rv);
     483             :     }
     484           0 :     return;
     485             :   }
     486             : 
     487           0 :   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
     488           0 :   NS_ASSERTION(treeOp, "Tree op allocation failed.");
     489           0 :   treeOp->Init(eTreeOpAppendChildrenToNewParent, aOldParent, aNewParent);
     490             : }
     491             : 
     492             : void
     493           0 : nsHtml5TreeBuilder::insertFosterParentedCharacters(char16_t* aBuffer, int32_t aStart, int32_t aLength, nsIContentHandle* aTable, nsIContentHandle* aStackParent)
     494             : {
     495           0 :   NS_PRECONDITION(aBuffer, "Null buffer");
     496           0 :   NS_PRECONDITION(aTable, "Null table");
     497           0 :   NS_PRECONDITION(aStackParent, "Null stack parent");
     498           0 :   MOZ_ASSERT(!aStart, "aStart must always be zero.");
     499             : 
     500           0 :   if (mBuilder) {
     501           0 :     nsresult rv = nsHtml5TreeOperation::FosterParentText(
     502             :       static_cast<nsIContent*>(aStackParent),
     503             :       aBuffer, // XXX aStart always ignored???
     504             :       aLength,
     505             :       static_cast<nsIContent*>(aTable),
     506           0 :       mBuilder);
     507           0 :     if (NS_FAILED(rv)) {
     508           0 :       MarkAsBrokenAndRequestSuspension(rv);
     509             :     }
     510           0 :     return;
     511             :   }
     512             : 
     513           0 :   char16_t* bufferCopy = new (mozilla::fallible) char16_t[aLength];
     514           0 :   if (!bufferCopy) {
     515             :     // Just assigning mBroken instead of generating tree op. The caller
     516             :     // of tokenizeBuffer() will call MarkAsBroken() as appropriate.
     517           0 :     mBroken = NS_ERROR_OUT_OF_MEMORY;
     518           0 :     requestSuspension();
     519           0 :     return;
     520             :   }
     521             : 
     522           0 :   memcpy(bufferCopy, aBuffer, aLength * sizeof(char16_t));
     523             :   
     524           0 :   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
     525           0 :   NS_ASSERTION(treeOp, "Tree op allocation failed.");
     526           0 :   treeOp->Init(eTreeOpFosterParentText, bufferCopy, aLength, aStackParent, aTable);
     527             : }
     528             : 
     529             : void
     530           0 : nsHtml5TreeBuilder::insertFosterParentedChild(nsIContentHandle* aChild, nsIContentHandle* aTable, nsIContentHandle* aStackParent)
     531             : {
     532           0 :   NS_PRECONDITION(aChild, "Null child");
     533           0 :   NS_PRECONDITION(aTable, "Null table");
     534           0 :   NS_PRECONDITION(aStackParent, "Null stack parent");
     535             : 
     536           0 :   if (mBuilder) {
     537             :     nsresult rv = nsHtml5TreeOperation::FosterParent(
     538             :       static_cast<nsIContent*>(aChild),
     539             :       static_cast<nsIContent*>(aStackParent),
     540             :       static_cast<nsIContent*>(aTable),
     541           0 :       mBuilder);
     542           0 :     if (NS_FAILED(rv)) {
     543           0 :       MarkAsBrokenAndRequestSuspension(rv);
     544             :     }
     545           0 :     return;
     546             :   }
     547             : 
     548           0 :   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
     549           0 :   NS_ASSERTION(treeOp, "Tree op allocation failed.");
     550           0 :   treeOp->Init(eTreeOpFosterParent, aChild, aStackParent, aTable);
     551             : }
     552             : 
     553             : void
     554          12 : nsHtml5TreeBuilder::appendCharacters(nsIContentHandle* aParent, char16_t* aBuffer, int32_t aStart, int32_t aLength)
     555             : {
     556          12 :   NS_PRECONDITION(aBuffer, "Null buffer");
     557          12 :   NS_PRECONDITION(aParent, "Null parent");
     558          12 :   MOZ_ASSERT(!aStart, "aStart must always be zero.");
     559             : 
     560          12 :   if (mBuilder) {
     561           0 :     nsresult rv = nsHtml5TreeOperation::AppendText(
     562             :       aBuffer, // XXX aStart always ignored???
     563             :       aLength,
     564           0 :       static_cast<nsIContent*>(deepTreeSurrogateParent ?
     565             :                                deepTreeSurrogateParent : aParent),
     566           0 :       mBuilder);
     567           0 :     if (NS_FAILED(rv)) {
     568           0 :       MarkAsBrokenAndRequestSuspension(rv);
     569             :     }
     570           0 :     return;
     571             :   }
     572             : 
     573          24 :   char16_t* bufferCopy = new (mozilla::fallible) char16_t[aLength];
     574          12 :   if (!bufferCopy) {
     575             :     // Just assigning mBroken instead of generating tree op. The caller
     576             :     // of tokenizeBuffer() will call MarkAsBroken() as appropriate.
     577           0 :     mBroken = NS_ERROR_OUT_OF_MEMORY;
     578           0 :     requestSuspension();
     579           0 :     return;
     580             :   }
     581             : 
     582          12 :   memcpy(bufferCopy, aBuffer, aLength * sizeof(char16_t));
     583             :   
     584          12 :   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
     585          12 :   NS_ASSERTION(treeOp, "Tree op allocation failed.");
     586          12 :   treeOp->Init(eTreeOpAppendText, bufferCopy, aLength,
     587          24 :       deepTreeSurrogateParent ? deepTreeSurrogateParent : aParent);
     588             : }
     589             : 
     590             : void
     591           0 : nsHtml5TreeBuilder::appendIsindexPrompt(nsIContentHandle* aParent)
     592             : {
     593           0 :   NS_PRECONDITION(aParent, "Null parent");
     594             : 
     595           0 :   if (mBuilder) {
     596             :     nsresult rv = nsHtml5TreeOperation::AppendIsindexPrompt(
     597             :       static_cast<nsIContent*>(aParent),
     598           0 :       mBuilder);
     599           0 :     if (NS_FAILED(rv)) {
     600           0 :       MarkAsBrokenAndRequestSuspension(rv);
     601             :     }
     602           0 :     return;
     603             :   }
     604             : 
     605           0 :   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
     606           0 :   NS_ASSERTION(treeOp, "Tree op allocation failed.");
     607           0 :   treeOp->Init(eTreeOpAppendIsindexPrompt, aParent);
     608             : }
     609             : 
     610             : void
     611           3 : nsHtml5TreeBuilder::appendComment(nsIContentHandle* aParent, char16_t* aBuffer, int32_t aStart, int32_t aLength)
     612             : {
     613           3 :   NS_PRECONDITION(aBuffer, "Null buffer");
     614           3 :   NS_PRECONDITION(aParent, "Null parent");
     615           3 :   MOZ_ASSERT(!aStart, "aStart must always be zero.");
     616             : 
     617           3 :   if (deepTreeSurrogateParent) {
     618           0 :     return;
     619             :   }
     620             : 
     621           3 :   if (mBuilder) {
     622             :     nsresult rv = nsHtml5TreeOperation::AppendComment(
     623             :       static_cast<nsIContent*>(aParent),
     624             :       aBuffer, // XXX aStart always ignored???
     625             :       aLength,
     626           0 :       mBuilder);
     627           0 :     if (NS_FAILED(rv)) {
     628           0 :       MarkAsBrokenAndRequestSuspension(rv);
     629             :     }
     630           0 :     return;
     631             :   }
     632             : 
     633           6 :   char16_t* bufferCopy = new (mozilla::fallible) char16_t[aLength];
     634           3 :   if (!bufferCopy) {
     635             :     // Just assigning mBroken instead of generating tree op. The caller
     636             :     // of tokenizeBuffer() will call MarkAsBroken() as appropriate.
     637           0 :     mBroken = NS_ERROR_OUT_OF_MEMORY;
     638           0 :     requestSuspension();
     639           0 :     return;
     640             :   }
     641             : 
     642           3 :   memcpy(bufferCopy, aBuffer, aLength * sizeof(char16_t));
     643             :   
     644           3 :   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
     645           3 :   NS_ASSERTION(treeOp, "Tree op allocation failed.");
     646           3 :   treeOp->Init(eTreeOpAppendComment, bufferCopy, aLength, aParent);
     647             : }
     648             : 
     649             : void
     650           2 : nsHtml5TreeBuilder::appendCommentToDocument(char16_t* aBuffer, int32_t aStart, int32_t aLength)
     651             : {
     652           2 :   NS_PRECONDITION(aBuffer, "Null buffer");
     653           2 :   MOZ_ASSERT(!aStart, "aStart must always be zero.");
     654             : 
     655           2 :   if (mBuilder) {
     656             :     nsresult rv = nsHtml5TreeOperation::AppendCommentToDocument(
     657             :       aBuffer, // XXX aStart always ignored???
     658             :       aLength,
     659           0 :       mBuilder);
     660           0 :     if (NS_FAILED(rv)) {
     661           0 :       MarkAsBrokenAndRequestSuspension(rv);
     662             :     }
     663           0 :     return;
     664             :   }
     665             : 
     666           4 :   char16_t* bufferCopy = new (mozilla::fallible) char16_t[aLength];
     667           2 :   if (!bufferCopy) {
     668             :     // Just assigning mBroken instead of generating tree op. The caller
     669             :     // of tokenizeBuffer() will call MarkAsBroken() as appropriate.
     670           0 :     mBroken = NS_ERROR_OUT_OF_MEMORY;
     671           0 :     requestSuspension();
     672           0 :     return;
     673             :   }
     674             : 
     675           2 :   memcpy(bufferCopy, aBuffer, aLength * sizeof(char16_t));
     676             :   
     677           2 :   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
     678           2 :   NS_ASSERTION(treeOp, "Tree op allocation failed.");
     679           2 :   treeOp->Init(eTreeOpAppendCommentToDocument, bufferCopy, aLength);
     680             : }
     681             : 
     682             : void
     683           0 : nsHtml5TreeBuilder::addAttributesToElement(nsIContentHandle* aElement, nsHtml5HtmlAttributes* aAttributes)
     684             : {
     685           0 :   NS_PRECONDITION(aElement, "Null element");
     686           0 :   NS_PRECONDITION(aAttributes, "Null attributes");
     687             : 
     688           0 :   if (aAttributes == nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES) {
     689           0 :     return;
     690             :   }
     691             : 
     692           0 :   if (mBuilder) {
     693           0 :     MOZ_ASSERT(aAttributes == tokenizer->GetAttributes(),
     694             :       "Using attribute other than the tokenizer's to add to body or html.");
     695             :     nsresult rv = nsHtml5TreeOperation::AddAttributes(
     696             :       static_cast<nsIContent*>(aElement),
     697             :       aAttributes,
     698           0 :       mBuilder);
     699           0 :     if (NS_FAILED(rv)) {
     700           0 :       MarkAsBrokenAndRequestSuspension(rv);
     701             :     }
     702           0 :     return;
     703             :   }
     704             : 
     705           0 :   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
     706           0 :   NS_ASSERTION(treeOp, "Tree op allocation failed.");
     707           0 :   treeOp->Init(aElement, aAttributes);
     708             : }
     709             : 
     710             : void
     711           4 : nsHtml5TreeBuilder::markMalformedIfScript(nsIContentHandle* aElement)
     712             : {
     713           4 :   NS_PRECONDITION(aElement, "Null element");
     714             : 
     715           4 :   if (mBuilder) {
     716             :     nsHtml5TreeOperation::MarkMalformedIfScript(
     717           0 :       static_cast<nsIContent*>(aElement));
     718           0 :     return;
     719             :   }
     720             : 
     721           4 :   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
     722           4 :   NS_ASSERTION(treeOp, "Tree op allocation failed.");
     723           4 :   treeOp->Init(eTreeOpMarkMalformedIfScript, aElement);
     724             : }
     725             : 
     726             : void
     727           4 : nsHtml5TreeBuilder::start(bool fragment)
     728             : {
     729           4 :   mCurrentHtmlScriptIsAsyncOrDefer = false;
     730           4 :   deepTreeSurrogateParent = nullptr;
     731             : #ifdef DEBUG
     732           4 :   mActive = true;
     733             : #endif
     734           4 : }
     735             : 
     736             : void
     737           1 : nsHtml5TreeBuilder::end()
     738             : {
     739           1 :   mOpQueue.Clear();
     740             : #ifdef DEBUG
     741           1 :   mActive = false;
     742             : #endif
     743           1 : }
     744             : 
     745             : void
     746           1 : nsHtml5TreeBuilder::appendDoctypeToDocument(nsIAtom* aName,
     747             :                                             nsHtml5String aPublicId,
     748             :                                             nsHtml5String aSystemId)
     749             : {
     750           1 :   NS_PRECONDITION(aName, "Null name");
     751           2 :   nsString publicId; // Not Auto, because using it to hold nsStringBuffer*
     752           2 :   nsString systemId; // Not Auto, because using it to hold nsStringBuffer*
     753           1 :   aPublicId.ToString(publicId);
     754           1 :   aSystemId.ToString(systemId);
     755           1 :   if (mBuilder) {
     756           0 :     nsCOMPtr<nsIAtom> name = nsHtml5TreeOperation::Reget(aName);
     757           0 :     nsresult rv = nsHtml5TreeOperation::AppendDoctypeToDocument(
     758           0 :       name, publicId, systemId, mBuilder);
     759           0 :     if (NS_FAILED(rv)) {
     760           0 :       MarkAsBrokenAndRequestSuspension(rv);
     761             :     }
     762           0 :     return;
     763             :   }
     764             : 
     765           1 :   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
     766           1 :   NS_ASSERTION(treeOp, "Tree op allocation failed.");
     767           1 :   treeOp->Init(aName, publicId, systemId);
     768             :   // nsXMLContentSink can flush here, but what's the point?
     769             :   // It can also interrupt here, but we can't.
     770             : }
     771             : 
     772             : void
     773          14 : nsHtml5TreeBuilder::elementPushed(int32_t aNamespace, nsIAtom* aName, nsIContentHandle* aElement)
     774             : {
     775          14 :   NS_ASSERTION(aNamespace == kNameSpaceID_XHTML || aNamespace == kNameSpaceID_SVG || aNamespace == kNameSpaceID_MathML, "Element isn't HTML, SVG or MathML!");
     776          14 :   NS_ASSERTION(aName, "Element doesn't have local name!");
     777          14 :   NS_ASSERTION(aElement, "No element!");
     778             :   /*
     779             :    * The frame constructor uses recursive algorithms, so it can't deal with
     780             :    * arbitrarily deep trees. This is especially a problem on Windows where
     781             :    * the permitted depth of the runtime stack is rather small.
     782             :    *
     783             :    * The following is a protection against author incompetence--not against
     784             :    * malice. There are other ways to make the DOM deep anyway.
     785             :    *
     786             :    * The basic idea is that when the tree builder stack gets too deep,
     787             :    * append operations no longer append to the node that the HTML parsing
     788             :    * algorithm says they should but instead text nodes are append to the last
     789             :    * element that was seen before a magic tree builder stack threshold was
     790             :    * reached and element and comment nodes aren't appended to the DOM at all.
     791             :    *
     792             :    * However, for security reasons, non-child descendant text nodes inside an
     793             :    * SVG script or style element should not become children. Also, non-cell
     794             :    * table elements shouldn't be used as surrogate parents for user experience
     795             :    * reasons.
     796             :    */
     797          14 :   if (!deepTreeSurrogateParent && currentPtr >= MAX_REFLOW_DEPTH &&
     798           0 :       !(aName == nsGkAtoms::script || aName == nsGkAtoms::table ||
     799           0 :         aName == nsGkAtoms::thead || aName == nsGkAtoms::tfoot ||
     800           0 :         aName == nsGkAtoms::tbody || aName == nsGkAtoms::tr ||
     801           0 :         aName == nsGkAtoms::colgroup || aName == nsGkAtoms::style)) {
     802           0 :     deepTreeSurrogateParent = aElement;
     803             :   }
     804          14 :   if (aNamespace != kNameSpaceID_XHTML) {
     805           0 :     return;
     806             :   }
     807          14 :   if (aName == nsGkAtoms::body || aName == nsGkAtoms::frameset) {
     808           2 :     if (mBuilder) {
     809             :       // InnerHTML and DOMParser shouldn't start layout anyway
     810           0 :       return;
     811             :     }
     812           2 :     nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
     813           2 :     NS_ASSERTION(treeOp, "Tree op allocation failed.");
     814           2 :     treeOp->Init(eTreeOpStartLayout);
     815           2 :     return;
     816             :   }
     817          12 :   if (aName == nsGkAtoms::input || aName == nsGkAtoms::button) {
     818           0 :     if (mBuilder) {
     819           0 :       nsHtml5TreeOperation::DoneCreatingElement(static_cast<nsIContent*>(aElement));
     820             :     } else {
     821           0 :       mOpQueue.AppendElement()->Init(eTreeOpDoneCreatingElement, aElement);
     822             :     }
     823           0 :     return;
     824             :   }
     825          24 :   if (aName == nsGkAtoms::audio || aName == nsGkAtoms::video ||
     826          12 :       aName == nsGkAtoms::menuitem) {
     827           0 :     if (mBuilder) {
     828           0 :       nsHtml5TreeOperation::DoneCreatingElement(static_cast<nsIContent*>(aElement));
     829             :     } else {
     830           0 :       mOpQueue.AppendElement()->Init(eTreeOpDoneCreatingElement, aElement);
     831             :     }
     832           0 :     return;
     833             :   }
     834          12 :   if (mSpeculativeLoadStage && aName == nsGkAtoms::picture) {
     835             :     // mSpeculativeLoadStage is non-null only in the off-the-main-thread
     836             :     // tree builder, which handles the network stream
     837             :     //
     838             :     // See comments in nsHtml5SpeculativeLoad.h about <picture> preloading
     839           0 :     mSpeculativeLoadQueue.AppendElement()->InitOpenPicture();
     840             :   }
     841             : }
     842             : 
     843             : void
     844          14 : nsHtml5TreeBuilder::elementPopped(int32_t aNamespace, nsIAtom* aName, nsIContentHandle* aElement)
     845             : {
     846          14 :   NS_ASSERTION(aNamespace == kNameSpaceID_XHTML || aNamespace == kNameSpaceID_SVG || aNamespace == kNameSpaceID_MathML, "Element isn't HTML, SVG or MathML!");
     847          14 :   NS_ASSERTION(aName, "Element doesn't have local name!");
     848          14 :   NS_ASSERTION(aElement, "No element!");
     849          14 :   if (deepTreeSurrogateParent && currentPtr <= MAX_REFLOW_DEPTH) {
     850           0 :     deepTreeSurrogateParent = nullptr;
     851             :   }
     852          14 :   if (aNamespace == kNameSpaceID_MathML) {
     853           0 :     return;
     854             :   }
     855             :   // we now have only SVG and HTML
     856          14 :   if (aName == nsGkAtoms::script) {
     857           5 :     if (mPreventScriptExecution) {
     858           0 :       if (mBuilder) {
     859           0 :         nsHtml5TreeOperation::PreventScriptExecution(static_cast<nsIContent*>(aElement));
     860           0 :         return;
     861             :       }
     862           0 :       mOpQueue.AppendElement()->Init(eTreeOpPreventScriptExecution, aElement);
     863           0 :       return;
     864             :     }
     865           5 :     if (mBuilder) {
     866           0 :       return;
     867             :     }
     868           5 :     if (mCurrentHtmlScriptIsAsyncOrDefer) {
     869           0 :       NS_ASSERTION(aNamespace == kNameSpaceID_XHTML, 
     870             :                    "Only HTML scripts may be async/defer.");
     871           0 :       nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
     872           0 :       NS_ASSERTION(treeOp, "Tree op allocation failed.");
     873           0 :       treeOp->Init(eTreeOpRunScriptAsyncDefer, aElement);      
     874           0 :       mCurrentHtmlScriptIsAsyncOrDefer = false;
     875           0 :       return;
     876             :     }
     877           5 :     requestSuspension();
     878           5 :     nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
     879           5 :     NS_ASSERTION(treeOp, "Tree op allocation failed.");
     880           5 :     treeOp->InitScript(aElement);
     881           5 :     return;
     882             :   }
     883           9 :   if (aName == nsGkAtoms::title) {
     884           1 :     if (mBuilder) {
     885           0 :       nsHtml5TreeOperation::DoneAddingChildren(static_cast<nsIContent*>(aElement));
     886           0 :       return;
     887             :     }
     888           1 :     nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
     889           1 :     NS_ASSERTION(treeOp, "Tree op allocation failed.");
     890           1 :     treeOp->Init(eTreeOpDoneAddingChildren, aElement);
     891           1 :     return;
     892             :   }
     893           8 :   if (aName == nsGkAtoms::style ||
     894           8 :       (aNamespace == kNameSpaceID_XHTML && aName == nsGkAtoms::link)) {
     895           0 :     if (mBuilder) {
     896           0 :       MOZ_ASSERT(!nsContentUtils::IsSafeToRunScript(),
     897             :         "Scripts must be blocked.");
     898           0 :       mBuilder->UpdateStyleSheet(static_cast<nsIContent*>(aElement));
     899           0 :       return;
     900             :     }
     901           0 :     nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
     902           0 :     NS_ASSERTION(treeOp, "Tree op allocation failed.");
     903           0 :     treeOp->Init(eTreeOpUpdateStyleSheet, aElement);
     904           0 :     return;
     905             :   }
     906           8 :   if (aNamespace == kNameSpaceID_SVG) {
     907           0 :     if (aName == nsGkAtoms::svg) {
     908           0 :       if (mBuilder) {
     909           0 :         nsHtml5TreeOperation::SvgLoad(static_cast<nsIContent*>(aElement));
     910           0 :         return;
     911             :       }
     912           0 :       nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
     913           0 :       NS_ASSERTION(treeOp, "Tree op allocation failed.");
     914           0 :       treeOp->Init(eTreeOpSvgLoad, aElement);
     915             :     }
     916           0 :     return;
     917             :   }
     918             :   // we now have only HTML
     919             :   // Some HTML nodes need DoneAddingChildren() called to initialize
     920             :   // properly (e.g. form state restoration).
     921             :   // XXX expose ElementName group here and do switch
     922          16 :   if (aName == nsGkAtoms::object || aName == nsGkAtoms::applet ||
     923          24 :       aName == nsGkAtoms::select || aName == nsGkAtoms::textarea ||
     924           8 :       aName == nsGkAtoms::output) {
     925           0 :     if (mBuilder) {
     926           0 :       nsHtml5TreeOperation::DoneAddingChildren(static_cast<nsIContent*>(aElement));
     927           0 :       return;
     928             :     }
     929           0 :     nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
     930           0 :     NS_ASSERTION(treeOp, "Tree op allocation failed.");
     931           0 :     treeOp->Init(eTreeOpDoneAddingChildren, aElement);
     932           0 :     return;
     933             :   }
     934           8 :   if (aName == nsGkAtoms::meta && !fragment && !mBuilder) {
     935           2 :     nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
     936           2 :     NS_ASSERTION(treeOp, "Tree op allocation failed.");
     937           2 :     treeOp->Init(eTreeOpProcessMeta, aElement);
     938           2 :     return;
     939             :   }
     940           6 :   if (mSpeculativeLoadStage && aName == nsGkAtoms::picture) {
     941             :     // mSpeculativeLoadStage is non-null only in the off-the-main-thread
     942             :     // tree builder, which handles the network stream
     943             :     //
     944             :     // See comments in nsHtml5SpeculativeLoad.h about <picture> preloading
     945           0 :     mSpeculativeLoadQueue.AppendElement()->InitEndPicture();
     946             :   }
     947           6 :   return;
     948             : }
     949             : 
     950             : void
     951          20 : nsHtml5TreeBuilder::accumulateCharacters(const char16_t* aBuf, int32_t aStart, int32_t aLength)
     952             : {
     953          20 :   MOZ_RELEASE_ASSERT(charBufferLen + aLength <= charBuffer.length,
     954             :                      "About to memcpy past the end of the buffer!");
     955          20 :   memcpy(charBuffer + charBufferLen, aBuf + aStart, sizeof(char16_t) * aLength);
     956          20 :   charBufferLen += aLength;
     957          20 : }
     958             : 
     959             : // INT32_MAX is (2^31)-1. Therefore, the highest power-of-two that fits
     960             : // is 2^30. Note that this is counting char16_t units. The underlying
     961             : // bytes will be twice that, but they fit even in 32-bit size_t even
     962             : // if a contiguous chunk of memory of that size is pretty unlikely to
     963             : // be available on a 32-bit system.
     964             : #define MAX_POWER_OF_TWO_IN_INT32 0x40000000
     965             : 
     966             : bool
     967           9 : nsHtml5TreeBuilder::EnsureBufferSpace(int32_t aLength)
     968             : {
     969             :   // TODO: Unify nsHtml5Tokenizer::strBuf and nsHtml5TreeBuilder::charBuffer
     970             :   // so that this method becomes unnecessary.
     971           9 :   CheckedInt<int32_t> worstCase(charBufferLen);
     972           9 :   worstCase += aLength;
     973           9 :   if (!worstCase.isValid()) {
     974           0 :     return false;
     975             :   }
     976           9 :   if (worstCase.value() > MAX_POWER_OF_TWO_IN_INT32) {
     977           0 :     return false;
     978             :   }
     979           9 :   if (!charBuffer) {
     980           2 :     if (worstCase.value() < MAX_POWER_OF_TWO_IN_INT32) {
     981             :       // Add one to round to the next power of two to avoid immediate
     982             :       // reallocation once there are a few characters in the buffer.
     983           2 :       worstCase += 1;
     984             :     }
     985           2 :     charBuffer = jArray<char16_t,int32_t>::newFallibleJArray(mozilla::RoundUpPow2(worstCase.value()));
     986           2 :     if (!charBuffer) {
     987           0 :       return false;
     988             :     }
     989           7 :   } else if (worstCase.value() > charBuffer.length) {
     990           0 :     jArray<char16_t,int32_t> newBuf = jArray<char16_t,int32_t>::newFallibleJArray(mozilla::RoundUpPow2(worstCase.value()));
     991           0 :     if (!newBuf) {
     992           0 :       return false;
     993             :     }
     994           0 :     memcpy(newBuf, charBuffer, sizeof(char16_t) * size_t(charBufferLen));
     995           0 :     charBuffer = newBuf;
     996             :   }
     997           9 :   return true;
     998             : }
     999             : 
    1000             : nsIContentHandle*
    1001          14 : nsHtml5TreeBuilder::AllocateContentHandle()
    1002             : {
    1003          14 :   if (MOZ_UNLIKELY(mBuilder)) {
    1004           0 :     MOZ_ASSERT_UNREACHABLE("Must never allocate a handle with builder.");
    1005             :     return nullptr;
    1006             :   }
    1007          14 :   if (mHandlesUsed == NS_HTML5_TREE_BUILDER_HANDLE_ARRAY_LENGTH) {
    1008           0 :     mOldHandles.AppendElement(Move(mHandles));
    1009           0 :     mHandles = MakeUnique<nsIContent*[]>(NS_HTML5_TREE_BUILDER_HANDLE_ARRAY_LENGTH);
    1010           0 :     mHandlesUsed = 0;
    1011             :   }
    1012             : #ifdef DEBUG
    1013          14 :   mHandles[mHandlesUsed] = reinterpret_cast<nsIContent*>(uintptr_t(0xC0DEDBAD));
    1014             : #endif
    1015          14 :   return &mHandles[mHandlesUsed++];
    1016             : }
    1017             : 
    1018             : bool
    1019          14 : nsHtml5TreeBuilder::HasScript()
    1020             : {
    1021          14 :   uint32_t len = mOpQueue.Length();
    1022          14 :   if (!len) {
    1023           0 :     return false;
    1024             :   }
    1025          14 :   return mOpQueue.ElementAt(len - 1).IsRunScript();
    1026             : }
    1027             : 
    1028             : bool
    1029          14 : nsHtml5TreeBuilder::Flush(bool aDiscretionary)
    1030             : {
    1031          14 :   if (MOZ_UNLIKELY(mBuilder)) {
    1032           0 :     MOZ_ASSERT_UNREACHABLE("Must never flush with builder.");
    1033             :     return false;
    1034             :   }
    1035          14 :   if (NS_SUCCEEDED(mBroken)) {
    1036          30 :     if (!aDiscretionary ||
    1037           2 :         !(charBufferLen &&
    1038           0 :           currentPtr >= 0 &&
    1039           0 :           stack[currentPtr]->isFosterParenting())) {
    1040             :       // Don't flush text on discretionary flushes if the current element on
    1041             :       // the stack is a foster-parenting element and there's pending text,
    1042             :       // because flushing in that case would make the tree shape dependent on
    1043             :       // where the flush points fall.
    1044          14 :       flushCharacters();
    1045             :     }
    1046          14 :     FlushLoads();
    1047             :   }
    1048          14 :   if (mOpSink) {
    1049          14 :     bool hasOps = !mOpQueue.IsEmpty();
    1050          14 :     if (hasOps) {
    1051             :       // If the builder is broken and mOpQueue is not empty, there must be
    1052             :       // one op and it must be eTreeOpMarkAsBroken.
    1053           8 :       if (NS_FAILED(mBroken)) {
    1054           0 :         MOZ_ASSERT(mOpQueue.Length() == 1,
    1055             :           "Tree builder is broken with a non-empty op queue whose length isn't 1.");
    1056           0 :         MOZ_ASSERT(mOpQueue[0].IsMarkAsBroken(),
    1057             :           "Tree builder is broken but the op in queue is not marked as broken.");
    1058             :       }
    1059           8 :       mOpSink->MoveOpsFrom(mOpQueue);
    1060             :     }
    1061          14 :     return hasOps;
    1062             :   }
    1063             :   // no op sink: throw away ops
    1064           0 :   mOpQueue.Clear();
    1065           0 :   return false;
    1066             : }
    1067             : 
    1068             : void
    1069          16 : nsHtml5TreeBuilder::FlushLoads()
    1070             : {
    1071          16 :   if (MOZ_UNLIKELY(mBuilder)) {
    1072           0 :     MOZ_ASSERT_UNREACHABLE("Must never flush loads with builder.");
    1073             :     return;
    1074             :   }
    1075          16 :   if (!mSpeculativeLoadQueue.IsEmpty()) {
    1076           5 :     mSpeculativeLoadStage->MoveSpeculativeLoadsFrom(mSpeculativeLoadQueue);
    1077             :   }
    1078          16 : }
    1079             : 
    1080             : void
    1081           2 : nsHtml5TreeBuilder::SetDocumentCharset(NotNull<const Encoding*> aEncoding, 
    1082             :                                        int32_t aCharsetSource)
    1083             : {
    1084           2 :   if (mBuilder) {
    1085           0 :     mBuilder->SetDocumentCharsetAndSource(aEncoding, aCharsetSource);
    1086           2 :   } else if (mSpeculativeLoadStage) {
    1087           4 :     nsAutoCString charset;
    1088           2 :     aEncoding->Name(charset);
    1089           2 :     mSpeculativeLoadQueue.AppendElement()->InitSetDocumentCharset(
    1090           2 :       charset, aCharsetSource);
    1091             :   } else {
    1092           0 :     mOpQueue.AppendElement()->Init(
    1093           0 :       eTreeOpSetDocumentCharset, aEncoding, aCharsetSource);
    1094             :   }
    1095           2 : }
    1096             : 
    1097             : void
    1098           2 : nsHtml5TreeBuilder::StreamEnded()
    1099             : {
    1100           2 :   MOZ_ASSERT(!mBuilder, "Must not call StreamEnded with builder.");
    1101           2 :   MOZ_ASSERT(!fragment, "Must not parse fragments off the main thread.");
    1102           2 :   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
    1103           2 :   NS_ASSERTION(treeOp, "Tree op allocation failed.");
    1104           2 :   treeOp->Init(eTreeOpStreamEnded);
    1105           2 : }
    1106             : 
    1107             : void
    1108           0 : nsHtml5TreeBuilder::NeedsCharsetSwitchTo(NotNull<const Encoding*> aEncoding,
    1109             :                                          int32_t aCharsetSource,
    1110             :                                          int32_t aLineNumber)
    1111             : {
    1112           0 :   if (MOZ_UNLIKELY(mBuilder)) {
    1113           0 :     MOZ_ASSERT_UNREACHABLE("Must never switch charset with builder.");
    1114             :     return;
    1115             :   }
    1116           0 :   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
    1117           0 :   NS_ASSERTION(treeOp, "Tree op allocation failed.");
    1118             :   treeOp->Init(eTreeOpNeedsCharsetSwitchTo,
    1119             :                aEncoding,
    1120             :                aCharsetSource,
    1121           0 :                aLineNumber);
    1122           0 : }
    1123             : 
    1124             : void
    1125           0 : nsHtml5TreeBuilder::MaybeComplainAboutCharset(const char* aMsgId,
    1126             :                                               bool aError,
    1127             :                                               int32_t aLineNumber)
    1128             : {
    1129           0 :   if (MOZ_UNLIKELY(mBuilder)) {
    1130           0 :     MOZ_ASSERT_UNREACHABLE("Must never complain about charset with builder.");
    1131             :     return;
    1132             :   }
    1133           0 :   mOpQueue.AppendElement()->Init(aMsgId, aError, aLineNumber);
    1134           0 : }
    1135             : 
    1136             : void
    1137           5 : nsHtml5TreeBuilder::AddSnapshotToScript(nsAHtml5TreeBuilderState* aSnapshot, int32_t aLine)
    1138             : {
    1139           5 :   if (MOZ_UNLIKELY(mBuilder)) {
    1140           0 :     MOZ_ASSERT_UNREACHABLE("Must never use snapshots with builder.");
    1141             :     return;
    1142             :   }
    1143           5 :   NS_PRECONDITION(HasScript(), "No script to add a snapshot to!");
    1144           5 :   NS_PRECONDITION(aSnapshot, "Got null snapshot.");
    1145           5 :   mOpQueue.ElementAt(mOpQueue.Length() - 1).SetSnapshot(aSnapshot, aLine);
    1146           5 : }
    1147             : 
    1148             : void
    1149           0 : nsHtml5TreeBuilder::DropHandles()
    1150             : {
    1151           0 :   MOZ_ASSERT(!mBuilder, "Must not drop handles with builder.");
    1152           0 :   mOldHandles.Clear();
    1153           0 :   mHandlesUsed = 0;
    1154           0 : }
    1155             : 
    1156             : void
    1157           0 : nsHtml5TreeBuilder::MarkAsBroken(nsresult aRv)
    1158             : {
    1159           0 :   if (MOZ_UNLIKELY(mBuilder)) {
    1160           0 :     MOZ_ASSERT_UNREACHABLE("Must not call this with builder.");
    1161             :     return;
    1162             :   }
    1163           0 :   mBroken = aRv;
    1164           0 :   mOpQueue.Clear(); // Previous ops don't matter anymore
    1165           0 :   mOpQueue.AppendElement()->Init(aRv);
    1166           0 : }
    1167             : 
    1168             : void
    1169           0 : nsHtml5TreeBuilder::MarkAsBrokenFromPortability(nsresult aRv)
    1170             : {
    1171           0 :   if (mBuilder) {
    1172           0 :     MarkAsBrokenAndRequestSuspension(aRv);
    1173           0 :     return;
    1174             :   }
    1175           0 :   mBroken = aRv;
    1176           0 :   requestSuspension();
    1177             : }
    1178             : 
    1179             : void
    1180           0 : nsHtml5TreeBuilder::StartPlainTextViewSource(const nsAutoString& aTitle)
    1181             : {
    1182           0 :   MOZ_ASSERT(!mBuilder, "Must not view source with builder.");
    1183             :   startTag(nsHtml5ElementName::ELT_TITLE,
    1184             :            nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES,
    1185           0 :            false);
    1186             : 
    1187             :   // XUL will add the "Source of: " prefix.
    1188           0 :   uint32_t length = aTitle.Length();
    1189           0 :   if (length > INT32_MAX) {
    1190           0 :     length = INT32_MAX;
    1191             :   }
    1192           0 :   characters(aTitle.get(), 0, (int32_t)length);
    1193           0 :   endTag(nsHtml5ElementName::ELT_TITLE);
    1194             : 
    1195           0 :   startTag(nsHtml5ElementName::ELT_LINK,
    1196             :            nsHtml5ViewSourceUtils::NewLinkAttributes(),
    1197           0 :            false);
    1198             : 
    1199           0 :   startTag(nsHtml5ElementName::ELT_BODY,
    1200             :            nsHtml5ViewSourceUtils::NewBodyAttributes(),
    1201           0 :            false);
    1202             : 
    1203           0 :   StartPlainTextBody();
    1204           0 : }
    1205             : 
    1206             : void
    1207           0 : nsHtml5TreeBuilder::StartPlainText()
    1208             : {
    1209           0 :   MOZ_ASSERT(!mBuilder, "Must not view source with builder.");
    1210           0 :   startTag(nsHtml5ElementName::ELT_LINK,
    1211             :            nsHtml5PlainTextUtils::NewLinkAttributes(),
    1212           0 :            false);
    1213             : 
    1214           0 :   StartPlainTextBody();
    1215           0 : }
    1216             : 
    1217             : void
    1218           0 : nsHtml5TreeBuilder::StartPlainTextBody()
    1219             : {
    1220           0 :   MOZ_ASSERT(!mBuilder, "Must not view source with builder.");
    1221             :   startTag(nsHtml5ElementName::ELT_PRE,
    1222             :            nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES,
    1223           0 :            false);
    1224           0 :   needToDropLF = false;
    1225           0 : }
    1226             : 
    1227             : // DocumentModeHandler
    1228             : void
    1229           2 : nsHtml5TreeBuilder::documentMode(nsHtml5DocumentMode m)
    1230             : {
    1231           2 :   if (mBuilder) {
    1232           0 :     mBuilder->SetDocumentMode(m);
    1233           0 :     return;
    1234             :   }
    1235           2 :   if (mSpeculativeLoadStage) {
    1236           2 :     mSpeculativeLoadQueue.AppendElement()->InitSetDocumentMode(m);
    1237           2 :     return;
    1238             :   }
    1239           0 :   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
    1240           0 :   NS_ASSERTION(treeOp, "Tree op allocation failed.");
    1241           0 :   treeOp->Init(m);
    1242             : }
    1243             : 
    1244             : nsIContentHandle*
    1245           0 : nsHtml5TreeBuilder::getDocumentFragmentForTemplate(nsIContentHandle* aTemplate)
    1246             : {
    1247           0 :   if (mBuilder) {
    1248           0 :     return nsHtml5TreeOperation::GetDocumentFragmentForTemplate(static_cast<nsIContent*>(aTemplate));
    1249             :   }
    1250           0 :   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
    1251           0 :   NS_ASSERTION(treeOp, "Tree op allocation failed.");
    1252           0 :   nsIContentHandle* fragHandle = AllocateContentHandle();
    1253           0 :   treeOp->Init(eTreeOpGetDocumentFragmentForTemplate, aTemplate, fragHandle);
    1254           0 :   return fragHandle;
    1255             : }
    1256             : 
    1257             : nsIContentHandle*
    1258           0 : nsHtml5TreeBuilder::getFormPointerForContext(nsIContentHandle* aContext)
    1259             : {
    1260           0 :   MOZ_ASSERT(mBuilder, "Must have builder.");
    1261           0 :   if (!aContext) {
    1262           0 :     return nullptr;
    1263             :   }
    1264             : 
    1265           0 :   MOZ_ASSERT(NS_IsMainThread());
    1266             : 
    1267             :   // aContext must always be an element that already exists
    1268             :   // in the document.
    1269           0 :   nsIContent* contextNode = static_cast<nsIContent*>(aContext);
    1270           0 :   nsIContent* currentAncestor = contextNode;
    1271             : 
    1272             :   // We traverse the ancestors of the context node to find the nearest
    1273             :   // form pointer. This traversal is why aContext must not be an emtpy handle.
    1274           0 :   nsIContent* nearestForm = nullptr;
    1275           0 :   while (currentAncestor) {
    1276           0 :     if (currentAncestor->IsHTMLElement(nsGkAtoms::form)) {
    1277           0 :       nearestForm = currentAncestor;
    1278           0 :       break;
    1279             :     }
    1280           0 :     currentAncestor = currentAncestor->GetParent();
    1281             :   }
    1282             : 
    1283           0 :   if (!nearestForm) {
    1284           0 :     return nullptr;
    1285             :   }
    1286             : 
    1287           0 :   return nearestForm;
    1288             : }
    1289             : 
    1290             : // Error reporting
    1291             : 
    1292             : void
    1293           0 : nsHtml5TreeBuilder::EnableViewSource(nsHtml5Highlighter* aHighlighter)
    1294             : {
    1295           0 :   MOZ_ASSERT(!mBuilder, "Must not view source with builder.");
    1296           0 :   mViewSource = aHighlighter;
    1297           0 : }
    1298             : 
    1299             : void
    1300           0 : nsHtml5TreeBuilder::errStrayStartTag(nsIAtom* aName)
    1301             : {
    1302           0 :   if (MOZ_UNLIKELY(mViewSource)) {
    1303           0 :     mViewSource->AddErrorToCurrentRun("errStrayStartTag2", aName);
    1304             :   }
    1305           0 : }
    1306             : 
    1307             : void
    1308           0 : nsHtml5TreeBuilder::errStrayEndTag(nsIAtom* aName)
    1309             : {
    1310           0 :   if (MOZ_UNLIKELY(mViewSource)) {
    1311           0 :     mViewSource->AddErrorToCurrentRun("errStrayEndTag", aName);
    1312             :   }
    1313           0 : }
    1314             : 
    1315             : void
    1316           0 : nsHtml5TreeBuilder::errUnclosedElements(int32_t aIndex, nsIAtom* aName)
    1317             : {
    1318           0 :   if (MOZ_UNLIKELY(mViewSource)) {
    1319           0 :     mViewSource->AddErrorToCurrentRun("errUnclosedElements", aName);
    1320             :   }
    1321           0 : }
    1322             : 
    1323             : void
    1324           0 : nsHtml5TreeBuilder::errUnclosedElementsImplied(int32_t aIndex, nsIAtom* aName)
    1325             : {
    1326           0 :   if (MOZ_UNLIKELY(mViewSource)) {
    1327           0 :     mViewSource->AddErrorToCurrentRun("errUnclosedElementsImplied",
    1328           0 :         aName);
    1329             :   }
    1330           0 : }
    1331             : 
    1332             : void
    1333           0 : nsHtml5TreeBuilder::errUnclosedElementsCell(int32_t aIndex)
    1334             : {
    1335           0 :   if (MOZ_UNLIKELY(mViewSource)) {
    1336           0 :     mViewSource->AddErrorToCurrentRun("errUnclosedElementsCell");
    1337             :   }
    1338           0 : }
    1339             : 
    1340             : void
    1341           0 : nsHtml5TreeBuilder::errStrayDoctype()
    1342             : {
    1343           0 :   if (MOZ_UNLIKELY(mViewSource)) {
    1344           0 :     mViewSource->AddErrorToCurrentRun("errStrayDoctype");
    1345             :   }
    1346           0 : }
    1347             : 
    1348             : void
    1349           0 : nsHtml5TreeBuilder::errAlmostStandardsDoctype()
    1350             : {
    1351           0 :   if (MOZ_UNLIKELY(mViewSource) && !isSrcdocDocument) {
    1352           0 :     mViewSource->AddErrorToCurrentRun("errAlmostStandardsDoctype");
    1353             :   }
    1354           0 : }
    1355             : 
    1356             : void
    1357           1 : nsHtml5TreeBuilder::errQuirkyDoctype()
    1358             : {
    1359           1 :   if (MOZ_UNLIKELY(mViewSource) && !isSrcdocDocument) {
    1360           0 :     mViewSource->AddErrorToCurrentRun("errQuirkyDoctype");
    1361             :   }
    1362           1 : }
    1363             : 
    1364             : void
    1365           0 : nsHtml5TreeBuilder::errNonSpaceInTrailer()
    1366             : {
    1367           0 :   if (MOZ_UNLIKELY(mViewSource)) {
    1368           0 :     mViewSource->AddErrorToCurrentRun("errNonSpaceInTrailer");
    1369             :   }
    1370           0 : }
    1371             : 
    1372             : void
    1373           0 : nsHtml5TreeBuilder::errNonSpaceAfterFrameset()
    1374             : {
    1375           0 :   if (MOZ_UNLIKELY(mViewSource)) {
    1376           0 :     mViewSource->AddErrorToCurrentRun("errNonSpaceAfterFrameset");
    1377             :   }
    1378           0 : }
    1379             : 
    1380             : void
    1381           0 : nsHtml5TreeBuilder::errNonSpaceInFrameset()
    1382             : {
    1383           0 :   if (MOZ_UNLIKELY(mViewSource)) {
    1384           0 :     mViewSource->AddErrorToCurrentRun("errNonSpaceInFrameset");
    1385             :   }
    1386           0 : }
    1387             : 
    1388             : void
    1389           0 : nsHtml5TreeBuilder::errNonSpaceAfterBody()
    1390             : {
    1391           0 :   if (MOZ_UNLIKELY(mViewSource)) {
    1392           0 :     mViewSource->AddErrorToCurrentRun("errNonSpaceAfterBody");
    1393             :   }
    1394           0 : }
    1395             : 
    1396             : void
    1397           0 : nsHtml5TreeBuilder::errNonSpaceInColgroupInFragment()
    1398             : {
    1399           0 :   if (MOZ_UNLIKELY(mViewSource)) {
    1400           0 :     mViewSource->AddErrorToCurrentRun("errNonSpaceInColgroupInFragment");
    1401             :   }
    1402           0 : }
    1403             : 
    1404             : void
    1405           0 : nsHtml5TreeBuilder::errNonSpaceInNoscriptInHead()
    1406             : {
    1407           0 :   if (MOZ_UNLIKELY(mViewSource)) {
    1408           0 :     mViewSource->AddErrorToCurrentRun("errNonSpaceInNoscriptInHead");
    1409             :   }
    1410           0 : }
    1411             : 
    1412             : void
    1413           0 : nsHtml5TreeBuilder::errFooBetweenHeadAndBody(nsIAtom* aName)
    1414             : {
    1415           0 :   if (MOZ_UNLIKELY(mViewSource)) {
    1416           0 :     mViewSource->AddErrorToCurrentRun("errFooBetweenHeadAndBody", aName);
    1417             :   }
    1418           0 : }
    1419             : 
    1420             : void
    1421           1 : nsHtml5TreeBuilder::errStartTagWithoutDoctype()
    1422             : {
    1423           1 :   if (MOZ_UNLIKELY(mViewSource) && !isSrcdocDocument) {
    1424           0 :     mViewSource->AddErrorToCurrentRun("errStartTagWithoutDoctype");
    1425             :   }
    1426           1 : }
    1427             : 
    1428             : void
    1429           0 : nsHtml5TreeBuilder::errNoSelectInTableScope()
    1430             : {
    1431           0 :   if (MOZ_UNLIKELY(mViewSource)) {
    1432           0 :     mViewSource->AddErrorToCurrentRun("errNoSelectInTableScope");
    1433             :   }
    1434           0 : }
    1435             : 
    1436             : void
    1437           0 : nsHtml5TreeBuilder::errStartSelectWhereEndSelectExpected()
    1438             : {
    1439           0 :   if (MOZ_UNLIKELY(mViewSource)) {
    1440           0 :     mViewSource->AddErrorToCurrentRun(
    1441           0 :         "errStartSelectWhereEndSelectExpected");
    1442             :   }
    1443           0 : }
    1444             : 
    1445             : void
    1446           0 : nsHtml5TreeBuilder::errStartTagWithSelectOpen(nsIAtom* aName)
    1447             : {
    1448           0 :   if (MOZ_UNLIKELY(mViewSource)) {
    1449           0 :     mViewSource->AddErrorToCurrentRun("errStartTagWithSelectOpen", aName);
    1450             :   }
    1451           0 : }
    1452             : 
    1453             : void
    1454           0 : nsHtml5TreeBuilder::errBadStartTagInHead(nsIAtom* aName)
    1455             : {
    1456           0 :   if (MOZ_UNLIKELY(mViewSource)) {
    1457           0 :     mViewSource->AddErrorToCurrentRun("errBadStartTagInHead2", aName);
    1458             :   }
    1459           0 : }
    1460             : 
    1461             : void
    1462           0 : nsHtml5TreeBuilder::errImage()
    1463             : {
    1464           0 :   if (MOZ_UNLIKELY(mViewSource)) {
    1465           0 :     mViewSource->AddErrorToCurrentRun("errImage");
    1466             :   }
    1467           0 : }
    1468             : 
    1469             : void
    1470           0 : nsHtml5TreeBuilder::errIsindex()
    1471             : {
    1472           0 :   if (MOZ_UNLIKELY(mViewSource)) {
    1473           0 :     mViewSource->AddErrorToCurrentRun("errIsindex");
    1474             :   }
    1475           0 : }
    1476             : 
    1477             : void
    1478           0 : nsHtml5TreeBuilder::errFooSeenWhenFooOpen(nsIAtom* aName)
    1479             : {
    1480           0 :   if (MOZ_UNLIKELY(mViewSource)) {
    1481           0 :     mViewSource->AddErrorToCurrentRun("errFooSeenWhenFooOpen", aName);
    1482             :   }
    1483           0 : }
    1484             : 
    1485             : void
    1486           0 : nsHtml5TreeBuilder::errHeadingWhenHeadingOpen()
    1487             : {
    1488           0 :   if (MOZ_UNLIKELY(mViewSource)) {
    1489           0 :     mViewSource->AddErrorToCurrentRun("errHeadingWhenHeadingOpen");
    1490             :   }
    1491           0 : }
    1492             : 
    1493             : void
    1494           0 : nsHtml5TreeBuilder::errFramesetStart()
    1495             : {
    1496           0 :   if (MOZ_UNLIKELY(mViewSource)) {
    1497           0 :     mViewSource->AddErrorToCurrentRun("errFramesetStart");
    1498             :   }
    1499           0 : }
    1500             : 
    1501             : void
    1502           0 : nsHtml5TreeBuilder::errNoCellToClose()
    1503             : {
    1504           0 :   if (MOZ_UNLIKELY(mViewSource)) {
    1505           0 :     mViewSource->AddErrorToCurrentRun("errNoCellToClose");
    1506             :   }
    1507           0 : }
    1508             : 
    1509             : void
    1510           0 : nsHtml5TreeBuilder::errStartTagInTable(nsIAtom* aName)
    1511             : {
    1512           0 :   if (MOZ_UNLIKELY(mViewSource)) {
    1513           0 :     mViewSource->AddErrorToCurrentRun("errStartTagInTable", aName);
    1514             :   }
    1515           0 : }
    1516             : 
    1517             : void
    1518           0 : nsHtml5TreeBuilder::errFormWhenFormOpen()
    1519             : {
    1520           0 :   if (MOZ_UNLIKELY(mViewSource)) {
    1521           0 :     mViewSource->AddErrorToCurrentRun("errFormWhenFormOpen");
    1522             :   }
    1523           0 : }
    1524             : 
    1525             : void
    1526           0 : nsHtml5TreeBuilder::errTableSeenWhileTableOpen()
    1527             : {
    1528           0 :   if (MOZ_UNLIKELY(mViewSource)) {
    1529           0 :     mViewSource->AddErrorToCurrentRun("errTableSeenWhileTableOpen");
    1530             :   }
    1531           0 : }
    1532             : 
    1533             : void
    1534           0 : nsHtml5TreeBuilder::errStartTagInTableBody(nsIAtom* aName)
    1535             : {
    1536           0 :   if (MOZ_UNLIKELY(mViewSource)) {
    1537           0 :     mViewSource->AddErrorToCurrentRun("errStartTagInTableBody", aName);
    1538             :   }
    1539           0 : }
    1540             : 
    1541             : void
    1542           0 : nsHtml5TreeBuilder::errEndTagSeenWithoutDoctype()
    1543             : {
    1544           0 :   if (MOZ_UNLIKELY(mViewSource) && !isSrcdocDocument) {
    1545           0 :     mViewSource->AddErrorToCurrentRun("errEndTagSeenWithoutDoctype");
    1546             :   }
    1547           0 : }
    1548             : 
    1549             : void
    1550           0 : nsHtml5TreeBuilder::errEndTagAfterBody()
    1551             : {
    1552           0 :   if (MOZ_UNLIKELY(mViewSource)) {
    1553           0 :     mViewSource->AddErrorToCurrentRun("errEndTagAfterBody");
    1554             :   }
    1555           0 : }
    1556             : 
    1557             : void
    1558           0 : nsHtml5TreeBuilder::errEndTagSeenWithSelectOpen(nsIAtom* aName)
    1559             : {
    1560           0 :   if (MOZ_UNLIKELY(mViewSource)) {
    1561           0 :     mViewSource->AddErrorToCurrentRun("errEndTagSeenWithSelectOpen",
    1562           0 :         aName);
    1563             :   }
    1564           0 : }
    1565             : 
    1566             : void
    1567           0 : nsHtml5TreeBuilder::errGarbageInColgroup()
    1568             : {
    1569           0 :   if (MOZ_UNLIKELY(mViewSource)) {
    1570           0 :     mViewSource->AddErrorToCurrentRun("errGarbageInColgroup");
    1571             :   }
    1572           0 : }
    1573             : 
    1574             : void
    1575           0 : nsHtml5TreeBuilder::errEndTagBr()
    1576             : {
    1577           0 :   if (MOZ_UNLIKELY(mViewSource)) {
    1578           0 :     mViewSource->AddErrorToCurrentRun("errEndTagBr");
    1579             :   }
    1580           0 : }
    1581             : 
    1582             : void
    1583           0 : nsHtml5TreeBuilder::errNoElementToCloseButEndTagSeen(nsIAtom* aName)
    1584             : {
    1585           0 :   if (MOZ_UNLIKELY(mViewSource)) {
    1586           0 :     mViewSource->AddErrorToCurrentRun(
    1587           0 :         "errNoElementToCloseButEndTagSeen", aName);
    1588             :   }
    1589           0 : }
    1590             : 
    1591             : void
    1592           0 : nsHtml5TreeBuilder::errHtmlStartTagInForeignContext(nsIAtom* aName)
    1593             : {
    1594           0 :   if (MOZ_UNLIKELY(mViewSource)) {
    1595           0 :     mViewSource->AddErrorToCurrentRun("errHtmlStartTagInForeignContext",
    1596           0 :         aName);
    1597             :   }
    1598           0 : }
    1599             : 
    1600             : void
    1601           0 : nsHtml5TreeBuilder::errTableClosedWhileCaptionOpen()
    1602             : {
    1603           0 :   if (MOZ_UNLIKELY(mViewSource)) {
    1604           0 :     mViewSource->AddErrorToCurrentRun("errTableClosedWhileCaptionOpen");
    1605             :   }
    1606           0 : }
    1607             : 
    1608             : void
    1609           0 : nsHtml5TreeBuilder::errNoTableRowToClose()
    1610             : {
    1611           0 :   if (MOZ_UNLIKELY(mViewSource)) {
    1612           0 :     mViewSource->AddErrorToCurrentRun("errNoTableRowToClose");
    1613             :   }
    1614           0 : }
    1615             : 
    1616             : void
    1617           0 : nsHtml5TreeBuilder::errNonSpaceInTable()
    1618             : {
    1619           0 :   if (MOZ_UNLIKELY(mViewSource)) {
    1620           0 :     mViewSource->AddErrorToCurrentRun("errNonSpaceInTable");
    1621             :   }
    1622           0 : }
    1623             : 
    1624             : void
    1625           0 : nsHtml5TreeBuilder::errUnclosedChildrenInRuby()
    1626             : {
    1627           0 :   if (MOZ_UNLIKELY(mViewSource)) {
    1628           0 :     mViewSource->AddErrorToCurrentRun("errUnclosedChildrenInRuby");
    1629             :   }
    1630           0 : }
    1631             : 
    1632             : void
    1633           0 : nsHtml5TreeBuilder::errStartTagSeenWithoutRuby(nsIAtom* aName)
    1634             : {
    1635           0 :   if (MOZ_UNLIKELY(mViewSource)) {
    1636           0 :     mViewSource->AddErrorToCurrentRun("errStartTagSeenWithoutRuby",
    1637           0 :         aName);
    1638             :   }
    1639           0 : }
    1640             : 
    1641             : void
    1642           0 : nsHtml5TreeBuilder::errSelfClosing()
    1643             : {
    1644           0 :   if (MOZ_UNLIKELY(mViewSource)) {
    1645           0 :     mViewSource->AddErrorToCurrentSlash("errSelfClosing");
    1646             :   }
    1647           0 : }
    1648             : 
    1649             : void
    1650           0 : nsHtml5TreeBuilder::errNoCheckUnclosedElementsOnStack()
    1651             : {
    1652           0 :   if (MOZ_UNLIKELY(mViewSource)) {
    1653           0 :     mViewSource->AddErrorToCurrentRun(
    1654           0 :         "errNoCheckUnclosedElementsOnStack");
    1655             :   }
    1656           0 : }
    1657             : 
    1658             : void
    1659           0 : nsHtml5TreeBuilder::errEndTagDidNotMatchCurrentOpenElement(nsIAtom* aName,
    1660             :                                                            nsIAtom* aOther)
    1661             : {
    1662           0 :   if (MOZ_UNLIKELY(mViewSource)) {
    1663           0 :     mViewSource->AddErrorToCurrentRun(
    1664           0 :         "errEndTagDidNotMatchCurrentOpenElement", aName, aOther);
    1665             :   }
    1666           0 : }
    1667             : 
    1668             : void
    1669           0 : nsHtml5TreeBuilder::errEndTagViolatesNestingRules(nsIAtom* aName)
    1670             : {
    1671           0 :   if (MOZ_UNLIKELY(mViewSource)) {
    1672           0 :     mViewSource->AddErrorToCurrentRun("errEndTagViolatesNestingRules", aName);
    1673             :   }
    1674           0 : }
    1675             : 
    1676             : void
    1677           0 : nsHtml5TreeBuilder::errEndWithUnclosedElements(nsIAtom* aName)
    1678             : {
    1679           0 :   if (MOZ_UNLIKELY(mViewSource)) {
    1680           0 :     mViewSource->AddErrorToCurrentRun("errEndWithUnclosedElements", aName);
    1681             :   }
    1682           0 : }

Generated by: LCOV version 1.13