parser/html/nsHtml5TreeBuilderCppSupplement.h

Fri, 16 Jan 2015 18:13:44 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 16 Jan 2015 18:13:44 +0100
branch
TOR_BUG_9701
changeset 14
925c144e1f1f
permissions
-rw-r--r--

Integrate suggestion from review to improve consistency with existing 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/. */
     7 #include "nsError.h"
     8 #include "nsIPresShell.h"
     9 #include "nsNodeUtils.h"
    10 #include "nsIFrame.h"
    11 #include "mozilla/Likely.h"
    13 class nsPresContext;
    15 nsHtml5TreeBuilder::nsHtml5TreeBuilder(nsHtml5OplessBuilder* aBuilder)
    16   : scriptingEnabled(false)
    17   , fragment(false)
    18   , contextNode(nullptr)
    19   , formPointer(nullptr)
    20   , headPointer(nullptr)
    21   , mBuilder(aBuilder)
    22   , mViewSource(nullptr)
    23   , mOpSink(nullptr)
    24   , mHandles(nullptr)
    25   , mHandlesUsed(0)
    26   , mSpeculativeLoadStage(nullptr)
    27   , mCurrentHtmlScriptIsAsyncOrDefer(false)
    28   , mPreventScriptExecution(false)
    29 #ifdef DEBUG
    30   , mActive(false)
    31 #endif
    32 {
    33   MOZ_COUNT_CTOR(nsHtml5TreeBuilder);
    34 }
    36 nsHtml5TreeBuilder::nsHtml5TreeBuilder(nsAHtml5TreeOpSink* aOpSink,
    37                                        nsHtml5TreeOpStage* aStage)
    38   : scriptingEnabled(false)
    39   , fragment(false)
    40   , contextNode(nullptr)
    41   , formPointer(nullptr)
    42   , headPointer(nullptr)
    43   , mBuilder(nullptr)
    44   , mViewSource(nullptr)
    45   , mOpSink(aOpSink)
    46   , mHandles(new nsIContent*[NS_HTML5_TREE_BUILDER_HANDLE_ARRAY_LENGTH])
    47   , mHandlesUsed(0)
    48   , mSpeculativeLoadStage(aStage)
    49   , mCurrentHtmlScriptIsAsyncOrDefer(false)
    50   , mPreventScriptExecution(false)
    51 #ifdef DEBUG
    52   , mActive(false)
    53 #endif
    54 {
    55   MOZ_COUNT_CTOR(nsHtml5TreeBuilder);
    56 }
    58 nsHtml5TreeBuilder::~nsHtml5TreeBuilder()
    59 {
    60   MOZ_COUNT_DTOR(nsHtml5TreeBuilder);
    61   NS_ASSERTION(!mActive, "nsHtml5TreeBuilder deleted without ever calling end() on it!");
    62   mOpQueue.Clear();
    63 }
    65 nsIContentHandle*
    66 nsHtml5TreeBuilder::createElement(int32_t aNamespace, nsIAtom* aName, nsHtml5HtmlAttributes* aAttributes)
    67 {
    68   NS_PRECONDITION(aAttributes, "Got null attributes.");
    69   NS_PRECONDITION(aName, "Got null name.");
    70   NS_PRECONDITION(aNamespace == kNameSpaceID_XHTML || 
    71                   aNamespace == kNameSpaceID_SVG || 
    72                   aNamespace == kNameSpaceID_MathML,
    73                   "Bogus namespace.");
    75   if (mBuilder) {
    76     nsCOMPtr<nsIAtom> name = nsHtml5TreeOperation::Reget(aName);
    77     nsIContent* elem =
    78       nsHtml5TreeOperation::CreateElement(aNamespace,
    79                                           name,
    80                                           aAttributes,
    81                                           mozilla::dom::FROM_PARSER_FRAGMENT,
    82                                           mBuilder);
    83     if (MOZ_UNLIKELY(aAttributes != tokenizer->GetAttributes() &&
    84                      aAttributes != nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES)) {
    85       delete aAttributes;
    86     }
    87     return elem;
    88   }
    90   nsIContentHandle* content = AllocateContentHandle();
    91   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
    92   NS_ASSERTION(treeOp, "Tree op allocation failed.");
    93   treeOp->Init(aNamespace,
    94                aName,
    95                aAttributes,
    96                content,
    97                !!mSpeculativeLoadStage);
    98   // mSpeculativeLoadStage is non-null only in the off-the-main-thread
    99   // tree builder, which handles the network stream
   101   // Start wall of code for speculative loading and line numbers
   103   if (mSpeculativeLoadStage) {
   104     switch (aNamespace) {
   105       case kNameSpaceID_XHTML:
   106         if (nsHtml5Atoms::img == aName) {
   107           nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_SRC);
   108           if (url) {
   109             nsString* crossOrigin =
   110               aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
   111             mSpeculativeLoadQueue.AppendElement()->
   112               InitImage(*url,
   113                         crossOrigin ? *crossOrigin : NullString());
   114           }
   115         } else if (nsHtml5Atoms::script == aName) {
   116           nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   117           NS_ASSERTION(treeOp, "Tree op allocation failed.");
   118           treeOp->Init(eTreeOpSetScriptLineNumberAndFreeze, content, tokenizer->getLineNumber());
   120           nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_SRC);
   121           if (url) {
   122             nsString* charset = aAttributes->getValue(nsHtml5AttributeName::ATTR_CHARSET);
   123             nsString* type = aAttributes->getValue(nsHtml5AttributeName::ATTR_TYPE);
   124             nsString* crossOrigin =
   125               aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
   126             mSpeculativeLoadQueue.AppendElement()->
   127               InitScript(*url,
   128                          (charset) ? *charset : EmptyString(),
   129                          (type) ? *type : EmptyString(),
   130                          (crossOrigin) ? *crossOrigin : NullString(),
   131                          mode == NS_HTML5TREE_BUILDER_IN_HEAD);
   132             mCurrentHtmlScriptIsAsyncOrDefer = 
   133               aAttributes->contains(nsHtml5AttributeName::ATTR_ASYNC) ||
   134               aAttributes->contains(nsHtml5AttributeName::ATTR_DEFER);
   135           }
   136         } else if (nsHtml5Atoms::link == aName) {
   137           nsString* rel = aAttributes->getValue(nsHtml5AttributeName::ATTR_REL);
   138           // Not splitting on space here is bogus but the old parser didn't even
   139           // do a case-insensitive check.
   140           if (rel && rel->LowerCaseEqualsASCII("stylesheet")) {
   141             nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_HREF);
   142             if (url) {
   143               nsString* charset = aAttributes->getValue(nsHtml5AttributeName::ATTR_CHARSET);
   144               nsString* crossOrigin =
   145                 aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
   146               mSpeculativeLoadQueue.AppendElement()->
   147                 InitStyle(*url,
   148                           (charset) ? *charset : EmptyString(),
   149                           (crossOrigin) ? *crossOrigin : NullString());
   150             }
   151           }
   152         } else if (nsHtml5Atoms::video == aName) {
   153           nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_POSTER);
   154           if (url) {
   155             mSpeculativeLoadQueue.AppendElement()->InitImage(*url, NullString());
   156           }
   157         } else if (nsHtml5Atoms::style == aName) {
   158           nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   159           NS_ASSERTION(treeOp, "Tree op allocation failed.");
   160           treeOp->Init(eTreeOpSetStyleLineNumber, content, tokenizer->getLineNumber());
   161         } else if (nsHtml5Atoms::html == aName) {
   162           nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_MANIFEST);
   163           if (url) {
   164             mSpeculativeLoadQueue.AppendElement()->InitManifest(*url);
   165           } else {
   166             mSpeculativeLoadQueue.AppendElement()->InitManifest(EmptyString());
   167           }
   168         } else if (nsHtml5Atoms::base == aName) {
   169           nsString* url =
   170               aAttributes->getValue(nsHtml5AttributeName::ATTR_HREF);
   171           if (url) {
   172             mSpeculativeLoadQueue.AppendElement()->InitBase(*url);
   173           }
   174         }
   175         break;
   176       case kNameSpaceID_SVG:
   177         if (nsHtml5Atoms::image == aName) {
   178           nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_XLINK_HREF);
   179           if (url) {
   180             mSpeculativeLoadQueue.AppendElement()->InitImage(*url, NullString());
   181           }
   182         } else if (nsHtml5Atoms::script == aName) {
   183           nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   184           NS_ASSERTION(treeOp, "Tree op allocation failed.");
   185           treeOp->Init(eTreeOpSetScriptLineNumberAndFreeze, content, tokenizer->getLineNumber());
   187           nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_XLINK_HREF);
   188           if (url) {
   189             nsString* type = aAttributes->getValue(nsHtml5AttributeName::ATTR_TYPE);
   190             nsString* crossOrigin =
   191               aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
   192             mSpeculativeLoadQueue.AppendElement()->
   193               InitScript(*url,
   194                          EmptyString(),
   195                          (type) ? *type : EmptyString(),
   196                          (crossOrigin) ? *crossOrigin : NullString(),
   197                          mode == NS_HTML5TREE_BUILDER_IN_HEAD);
   198           }
   199         } else if (nsHtml5Atoms::style == aName) {
   200           nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   201           NS_ASSERTION(treeOp, "Tree op allocation failed.");
   202           treeOp->Init(eTreeOpSetStyleLineNumber, content, tokenizer->getLineNumber());
   204           nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_XLINK_HREF);
   205           if (url) {
   206             nsString* crossOrigin =
   207               aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
   208             mSpeculativeLoadQueue.AppendElement()->
   209               InitStyle(*url, EmptyString(),
   210                         (crossOrigin) ? *crossOrigin : NullString());
   211           }
   212         }        
   213         break;
   214     }
   215   } else if (aNamespace != kNameSpaceID_MathML) {
   216     // No speculative loader--just line numbers and defer/async check
   217     if (nsHtml5Atoms::style == aName) {
   218       nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   219       NS_ASSERTION(treeOp, "Tree op allocation failed.");
   220       treeOp->Init(eTreeOpSetStyleLineNumber, content, tokenizer->getLineNumber());
   221     } else if (nsHtml5Atoms::script == aName) {
   222       nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   223       NS_ASSERTION(treeOp, "Tree op allocation failed.");
   224       treeOp->Init(eTreeOpSetScriptLineNumberAndFreeze, content, tokenizer->getLineNumber());
   225       if (aNamespace == kNameSpaceID_XHTML) {
   226         mCurrentHtmlScriptIsAsyncOrDefer = 
   227           aAttributes->contains(nsHtml5AttributeName::ATTR_SRC) &&
   228           (aAttributes->contains(nsHtml5AttributeName::ATTR_ASYNC) ||
   229            aAttributes->contains(nsHtml5AttributeName::ATTR_DEFER));
   230       }
   231     } else if (aNamespace == kNameSpaceID_XHTML && nsHtml5Atoms::html == aName) {
   232       nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_MANIFEST);
   233       nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   234       NS_ASSERTION(treeOp, "Tree op allocation failed.");
   235       if (url) {
   236         treeOp->Init(eTreeOpProcessOfflineManifest, *url);
   237       } else {
   238         treeOp->Init(eTreeOpProcessOfflineManifest, EmptyString());
   239       }
   240     }
   241   }
   243   // End wall of code for speculative loading
   245   return content;
   246 }
   248 nsIContentHandle*
   249 nsHtml5TreeBuilder::createElement(int32_t aNamespace, nsIAtom* aName, nsHtml5HtmlAttributes* aAttributes, nsIContentHandle* aFormElement)
   250 {
   251   nsIContentHandle* content = createElement(aNamespace, aName, aAttributes);
   252   if (aFormElement) {
   253     if (mBuilder) {
   254       nsHtml5TreeOperation::SetFormElement(static_cast<nsIContent*>(content),
   255         static_cast<nsIContent*>(aFormElement));
   256     } else {
   257       nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   258       NS_ASSERTION(treeOp, "Tree op allocation failed.");
   259       treeOp->Init(eTreeOpSetFormElement, content, aFormElement);
   260     }
   261   }
   262   return content;
   263 }
   265 nsIContentHandle*
   266 nsHtml5TreeBuilder::createHtmlElementSetAsRoot(nsHtml5HtmlAttributes* aAttributes)
   267 {
   268   nsIContentHandle* content = createElement(kNameSpaceID_XHTML, nsHtml5Atoms::html, aAttributes);
   269   if (mBuilder) {
   270     nsresult rv = nsHtml5TreeOperation::AppendToDocument(static_cast<nsIContent*>(content),
   271                                                          mBuilder);
   272     if (NS_FAILED(rv)) {
   273       MarkAsBrokenAndRequestSuspension(rv);
   274     }
   275   } else {
   276     nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   277     NS_ASSERTION(treeOp, "Tree op allocation failed.");
   278     treeOp->Init(eTreeOpAppendToDocument, content);
   279   }
   280   return content;
   281 }
   283 void
   284 nsHtml5TreeBuilder::detachFromParent(nsIContentHandle* aElement)
   285 {
   286   NS_PRECONDITION(aElement, "Null element");
   288   if (mBuilder) {
   289     nsHtml5TreeOperation::Detach(static_cast<nsIContent*>(aElement),
   290                                  mBuilder);
   291     return;
   292   }
   294   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   295   NS_ASSERTION(treeOp, "Tree op allocation failed.");
   296   treeOp->Init(eTreeOpDetach, aElement);
   297 }
   299 void
   300 nsHtml5TreeBuilder::appendElement(nsIContentHandle* aChild, nsIContentHandle* aParent)
   301 {
   302   NS_PRECONDITION(aChild, "Null child");
   303   NS_PRECONDITION(aParent, "Null parent");
   304   if (deepTreeSurrogateParent) {
   305     return;
   306   }
   308   if (mBuilder) {
   309     nsresult rv = nsHtml5TreeOperation::Append(static_cast<nsIContent*>(aChild),
   310                                                static_cast<nsIContent*>(aParent),
   311                                                mBuilder);
   312     if (NS_FAILED(rv)) {
   313       MarkAsBrokenAndRequestSuspension(rv);
   314     }
   315     return;
   316   }
   318   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   319   NS_ASSERTION(treeOp, "Tree op allocation failed.");
   320   treeOp->Init(eTreeOpAppend, aChild, aParent);
   321 }
   323 void
   324 nsHtml5TreeBuilder::appendChildrenToNewParent(nsIContentHandle* aOldParent, nsIContentHandle* aNewParent)
   325 {
   326   NS_PRECONDITION(aOldParent, "Null old parent");
   327   NS_PRECONDITION(aNewParent, "Null new parent");
   329   if (mBuilder) {
   330     nsresult rv = nsHtml5TreeOperation::AppendChildrenToNewParent(
   331       static_cast<nsIContent*>(aOldParent),
   332       static_cast<nsIContent*>(aNewParent),
   333       mBuilder);
   334     if (NS_FAILED(rv)) {
   335       MarkAsBrokenAndRequestSuspension(rv);
   336     }
   337     return;
   338   }
   340   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   341   NS_ASSERTION(treeOp, "Tree op allocation failed.");
   342   treeOp->Init(eTreeOpAppendChildrenToNewParent, aOldParent, aNewParent);
   343 }
   345 void
   346 nsHtml5TreeBuilder::insertFosterParentedCharacters(char16_t* aBuffer, int32_t aStart, int32_t aLength, nsIContentHandle* aTable, nsIContentHandle* aStackParent)
   347 {
   348   NS_PRECONDITION(aBuffer, "Null buffer");
   349   NS_PRECONDITION(aTable, "Null table");
   350   NS_PRECONDITION(aStackParent, "Null stack parent");
   351   MOZ_ASSERT(!aStart, "aStart must always be zero.");
   353   if (mBuilder) {
   354     nsresult rv = nsHtml5TreeOperation::FosterParentText(
   355       static_cast<nsIContent*>(aStackParent),
   356       aBuffer, // XXX aStart always ignored???
   357       aLength,
   358       static_cast<nsIContent*>(aTable),
   359       mBuilder);
   360     if (NS_FAILED(rv)) {
   361       MarkAsBrokenAndRequestSuspension(rv);
   362     }
   363     return;
   364   }
   366   char16_t* bufferCopy = new char16_t[aLength];
   367   memcpy(bufferCopy, aBuffer, aLength * sizeof(char16_t));
   369   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   370   NS_ASSERTION(treeOp, "Tree op allocation failed.");
   371   treeOp->Init(eTreeOpFosterParentText, bufferCopy, aLength, aStackParent, aTable);
   372 }
   374 void
   375 nsHtml5TreeBuilder::insertFosterParentedChild(nsIContentHandle* aChild, nsIContentHandle* aTable, nsIContentHandle* aStackParent)
   376 {
   377   NS_PRECONDITION(aChild, "Null child");
   378   NS_PRECONDITION(aTable, "Null table");
   379   NS_PRECONDITION(aStackParent, "Null stack parent");
   381   if (mBuilder) {
   382     nsresult rv = nsHtml5TreeOperation::FosterParent(
   383       static_cast<nsIContent*>(aChild),
   384       static_cast<nsIContent*>(aStackParent),
   385       static_cast<nsIContent*>(aTable),
   386       mBuilder);
   387     if (NS_FAILED(rv)) {
   388       MarkAsBrokenAndRequestSuspension(rv);
   389     }
   390     return;
   391   }
   393   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   394   NS_ASSERTION(treeOp, "Tree op allocation failed.");
   395   treeOp->Init(eTreeOpFosterParent, aChild, aStackParent, aTable);
   396 }
   398 void
   399 nsHtml5TreeBuilder::appendCharacters(nsIContentHandle* aParent, char16_t* aBuffer, int32_t aStart, int32_t aLength)
   400 {
   401   NS_PRECONDITION(aBuffer, "Null buffer");
   402   NS_PRECONDITION(aParent, "Null parent");
   403   MOZ_ASSERT(!aStart, "aStart must always be zero.");
   405   if (mBuilder) {
   406     nsresult rv = nsHtml5TreeOperation::AppendText(
   407       aBuffer, // XXX aStart always ignored???
   408       aLength,
   409       static_cast<nsIContent*>(deepTreeSurrogateParent ?
   410                                deepTreeSurrogateParent : aParent),
   411       mBuilder);
   412     if (NS_FAILED(rv)) {
   413       MarkAsBrokenAndRequestSuspension(rv);
   414     }
   415     return;
   416   }
   418   char16_t* bufferCopy = new char16_t[aLength];
   419   memcpy(bufferCopy, aBuffer, aLength * sizeof(char16_t));
   421   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   422   NS_ASSERTION(treeOp, "Tree op allocation failed.");
   423   treeOp->Init(eTreeOpAppendText, bufferCopy, aLength,
   424       deepTreeSurrogateParent ? deepTreeSurrogateParent : aParent);
   425 }
   427 void
   428 nsHtml5TreeBuilder::appendIsindexPrompt(nsIContentHandle* aParent)
   429 {
   430   NS_PRECONDITION(aParent, "Null parent");
   432   if (mBuilder) {
   433     nsresult rv = nsHtml5TreeOperation::AppendIsindexPrompt(
   434       static_cast<nsIContent*>(aParent),
   435       mBuilder);
   436     if (NS_FAILED(rv)) {
   437       MarkAsBrokenAndRequestSuspension(rv);
   438     }
   439     return;
   440   }
   442   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   443   NS_ASSERTION(treeOp, "Tree op allocation failed.");
   444   treeOp->Init(eTreeOpAppendIsindexPrompt, aParent);
   445 }
   447 void
   448 nsHtml5TreeBuilder::appendComment(nsIContentHandle* aParent, char16_t* aBuffer, int32_t aStart, int32_t aLength)
   449 {
   450   NS_PRECONDITION(aBuffer, "Null buffer");
   451   NS_PRECONDITION(aParent, "Null parent");
   452   MOZ_ASSERT(!aStart, "aStart must always be zero.");
   454   if (deepTreeSurrogateParent) {
   455     return;
   456   }
   458   if (mBuilder) {
   459     nsresult rv = nsHtml5TreeOperation::AppendComment(
   460       static_cast<nsIContent*>(aParent),
   461       aBuffer, // XXX aStart always ignored???
   462       aLength,
   463       mBuilder);
   464     if (NS_FAILED(rv)) {
   465       MarkAsBrokenAndRequestSuspension(rv);
   466     }
   467     return;
   468   }
   470   char16_t* bufferCopy = new char16_t[aLength];
   471   memcpy(bufferCopy, aBuffer, aLength * sizeof(char16_t));
   473   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   474   NS_ASSERTION(treeOp, "Tree op allocation failed.");
   475   treeOp->Init(eTreeOpAppendComment, bufferCopy, aLength, aParent);
   476 }
   478 void
   479 nsHtml5TreeBuilder::appendCommentToDocument(char16_t* aBuffer, int32_t aStart, int32_t aLength)
   480 {
   481   NS_PRECONDITION(aBuffer, "Null buffer");
   482   MOZ_ASSERT(!aStart, "aStart must always be zero.");
   484   if (mBuilder) {
   485     nsresult rv = nsHtml5TreeOperation::AppendCommentToDocument(
   486       aBuffer, // XXX aStart always ignored???
   487       aLength,
   488       mBuilder);
   489     if (NS_FAILED(rv)) {
   490       MarkAsBrokenAndRequestSuspension(rv);
   491     }
   492     return;
   493   }
   495   char16_t* bufferCopy = new char16_t[aLength];
   496   memcpy(bufferCopy, aBuffer, aLength * sizeof(char16_t));
   498   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   499   NS_ASSERTION(treeOp, "Tree op allocation failed.");
   500   treeOp->Init(eTreeOpAppendCommentToDocument, bufferCopy, aLength);
   501 }
   503 void
   504 nsHtml5TreeBuilder::addAttributesToElement(nsIContentHandle* aElement, nsHtml5HtmlAttributes* aAttributes)
   505 {
   506   NS_PRECONDITION(aElement, "Null element");
   507   NS_PRECONDITION(aAttributes, "Null attributes");
   509   if (aAttributes == nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES) {
   510     return;
   511   }
   513   if (mBuilder) {
   514     MOZ_ASSERT(aAttributes == tokenizer->GetAttributes(),
   515       "Using attribute other than the tokenizer's to add to body or html.");
   516     nsresult rv = nsHtml5TreeOperation::AddAttributes(
   517       static_cast<nsIContent*>(aElement),
   518       aAttributes,
   519       mBuilder);
   520     if (NS_FAILED(rv)) {
   521       MarkAsBrokenAndRequestSuspension(rv);
   522     }
   523     return;
   524   }
   526   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   527   NS_ASSERTION(treeOp, "Tree op allocation failed.");
   528   treeOp->Init(aElement, aAttributes);
   529 }
   531 void
   532 nsHtml5TreeBuilder::markMalformedIfScript(nsIContentHandle* aElement)
   533 {
   534   NS_PRECONDITION(aElement, "Null element");
   536   if (mBuilder) {
   537     nsHtml5TreeOperation::MarkMalformedIfScript(
   538       static_cast<nsIContent*>(aElement));
   539     return;
   540   }
   542   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   543   NS_ASSERTION(treeOp, "Tree op allocation failed.");
   544   treeOp->Init(eTreeOpMarkMalformedIfScript, aElement);
   545 }
   547 void
   548 nsHtml5TreeBuilder::start(bool fragment)
   549 {
   550   mCurrentHtmlScriptIsAsyncOrDefer = false;
   551   deepTreeSurrogateParent = nullptr;
   552 #ifdef DEBUG
   553   mActive = true;
   554 #endif
   555 }
   557 void
   558 nsHtml5TreeBuilder::end()
   559 {
   560   mOpQueue.Clear();
   561 #ifdef DEBUG
   562   mActive = false;
   563 #endif
   564 }
   566 void
   567 nsHtml5TreeBuilder::appendDoctypeToDocument(nsIAtom* aName, nsString* aPublicId, nsString* aSystemId)
   568 {
   569   NS_PRECONDITION(aName, "Null name");
   571   if (mBuilder) {
   572     nsCOMPtr<nsIAtom> name = nsHtml5TreeOperation::Reget(aName);
   573     nsresult rv =
   574       nsHtml5TreeOperation::AppendDoctypeToDocument(name,
   575                                                     *aPublicId,
   576                                                     *aSystemId,
   577                                                     mBuilder);
   578     if (NS_FAILED(rv)) {
   579       MarkAsBrokenAndRequestSuspension(rv);
   580     }
   581     return;
   582   }
   584   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   585   NS_ASSERTION(treeOp, "Tree op allocation failed.");
   586   treeOp->Init(aName, *aPublicId, *aSystemId);
   587   // nsXMLContentSink can flush here, but what's the point?
   588   // It can also interrupt here, but we can't.
   589 }
   591 void
   592 nsHtml5TreeBuilder::elementPushed(int32_t aNamespace, nsIAtom* aName, nsIContentHandle* aElement)
   593 {
   594   NS_ASSERTION(aNamespace == kNameSpaceID_XHTML || aNamespace == kNameSpaceID_SVG || aNamespace == kNameSpaceID_MathML, "Element isn't HTML, SVG or MathML!");
   595   NS_ASSERTION(aName, "Element doesn't have local name!");
   596   NS_ASSERTION(aElement, "No element!");
   597   /*
   598    * The frame constructor uses recursive algorithms, so it can't deal with
   599    * arbitrarily deep trees. This is especially a problem on Windows where
   600    * the permitted depth of the runtime stack is rather small.
   601    *
   602    * The following is a protection against author incompetence--not against
   603    * malice. There are other ways to make the DOM deep anyway.
   604    *
   605    * The basic idea is that when the tree builder stack gets too deep,
   606    * append operations no longer append to the node that the HTML parsing
   607    * algorithm says they should but instead text nodes are append to the last
   608    * element that was seen before a magic tree builder stack threshold was
   609    * reached and element and comment nodes aren't appended to the DOM at all.
   610    *
   611    * However, for security reasons, non-child descendant text nodes inside an
   612    * SVG script or style element should not become children. Also, non-cell
   613    * table elements shouldn't be used as surrogate parents for user experience
   614    * reasons.
   615    */
   616   if (!deepTreeSurrogateParent && currentPtr >= MAX_REFLOW_DEPTH &&
   617       !(aName == nsHtml5Atoms::script ||
   618         aName == nsHtml5Atoms::table ||
   619         aName == nsHtml5Atoms::thead ||
   620         aName == nsHtml5Atoms::tfoot ||
   621         aName == nsHtml5Atoms::tbody ||
   622         aName == nsHtml5Atoms::tr ||
   623         aName == nsHtml5Atoms::colgroup ||
   624         aName == nsHtml5Atoms::style)) {
   625     deepTreeSurrogateParent = aElement;
   626   }
   627   if (aNamespace != kNameSpaceID_XHTML) {
   628     return;
   629   }
   630   if (aName == nsHtml5Atoms::body || aName == nsHtml5Atoms::frameset) {
   631     if (mBuilder) {
   632       // InnerHTML and DOMParser shouldn't start layout anyway
   633       return;
   634     }
   635     nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   636     NS_ASSERTION(treeOp, "Tree op allocation failed.");
   637     treeOp->Init(eTreeOpStartLayout);
   638     return;
   639   }
   640   if (aName == nsHtml5Atoms::input ||
   641       aName == nsHtml5Atoms::button) {
   642     if (!formPointer) {
   643       // If form inputs don't belong to a form, their state preservation
   644       // won't work right without an append notification flush at this
   645       // point. See bug 497861.
   646       if (mBuilder) {
   647         mBuilder->FlushPendingAppendNotifications();
   648       } else {
   649         mOpQueue.AppendElement()->Init(eTreeOpFlushPendingAppendNotifications);
   650       }
   651     }
   652     if (mBuilder) {
   653       nsHtml5TreeOperation::DoneCreatingElement(static_cast<nsIContent*>(aElement));
   654     } else {
   655       mOpQueue.AppendElement()->Init(eTreeOpDoneCreatingElement, aElement);
   656     }
   657     return;
   658   }
   659   if (aName == nsHtml5Atoms::audio ||
   660       aName == nsHtml5Atoms::video ||
   661       aName == nsHtml5Atoms::menuitem) {
   662     if (mBuilder) {
   663       nsHtml5TreeOperation::DoneCreatingElement(static_cast<nsIContent*>(aElement));
   664     } else {
   665       mOpQueue.AppendElement()->Init(eTreeOpDoneCreatingElement, aElement);
   666     }
   667     return;
   668   }
   669 }
   671 void
   672 nsHtml5TreeBuilder::elementPopped(int32_t aNamespace, nsIAtom* aName, nsIContentHandle* aElement)
   673 {
   674   NS_ASSERTION(aNamespace == kNameSpaceID_XHTML || aNamespace == kNameSpaceID_SVG || aNamespace == kNameSpaceID_MathML, "Element isn't HTML, SVG or MathML!");
   675   NS_ASSERTION(aName, "Element doesn't have local name!");
   676   NS_ASSERTION(aElement, "No element!");
   677   if (deepTreeSurrogateParent && currentPtr <= MAX_REFLOW_DEPTH) {
   678     deepTreeSurrogateParent = nullptr;
   679   }
   680   if (aNamespace == kNameSpaceID_MathML) {
   681     return;
   682   }
   683   // we now have only SVG and HTML
   684   if (aName == nsHtml5Atoms::script) {
   685     if (mPreventScriptExecution) {
   686       if (mBuilder) {
   687         nsHtml5TreeOperation::PreventScriptExecution(static_cast<nsIContent*>(aElement));
   688         return;
   689       }
   690       mOpQueue.AppendElement()->Init(eTreeOpPreventScriptExecution, aElement);
   691       return;
   692     }
   693     if (mBuilder) {
   694       return;
   695     }
   696     if (mCurrentHtmlScriptIsAsyncOrDefer) {
   697       NS_ASSERTION(aNamespace == kNameSpaceID_XHTML, 
   698                    "Only HTML scripts may be async/defer.");
   699       nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   700       NS_ASSERTION(treeOp, "Tree op allocation failed.");
   701       treeOp->Init(eTreeOpRunScriptAsyncDefer, aElement);      
   702       mCurrentHtmlScriptIsAsyncOrDefer = false;
   703       return;
   704     }
   705     requestSuspension();
   706     nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   707     NS_ASSERTION(treeOp, "Tree op allocation failed.");
   708     treeOp->InitScript(aElement);
   709     return;
   710   }
   711   if (aName == nsHtml5Atoms::title) {
   712     if (mBuilder) {
   713       nsHtml5TreeOperation::DoneAddingChildren(static_cast<nsIContent*>(aElement), mBuilder);
   714       return;
   715     }
   716     nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   717     NS_ASSERTION(treeOp, "Tree op allocation failed.");
   718     treeOp->Init(eTreeOpDoneAddingChildren, aElement);
   719     return;
   720   }
   721   if (aName == nsHtml5Atoms::style || (aNamespace == kNameSpaceID_XHTML && aName == nsHtml5Atoms::link)) {
   722     if (mBuilder) {
   723       MOZ_ASSERT(!nsContentUtils::IsSafeToRunScript(),
   724         "Scripts must be blocked.");
   725       mBuilder->FlushPendingAppendNotifications();
   726       mBuilder->UpdateStyleSheet(static_cast<nsIContent*>(aElement));
   727       return;
   728     }
   729     nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   730     NS_ASSERTION(treeOp, "Tree op allocation failed.");
   731     treeOp->Init(eTreeOpUpdateStyleSheet, aElement);
   732     return;
   733   }
   734   if (aNamespace == kNameSpaceID_SVG) {
   735     if (aName == nsHtml5Atoms::svg) {
   736       if (mBuilder) {
   737         nsHtml5TreeOperation::SvgLoad(static_cast<nsIContent*>(aElement));
   738         return;
   739       }
   740       nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   741       NS_ASSERTION(treeOp, "Tree op allocation failed.");
   742       treeOp->Init(eTreeOpSvgLoad, aElement);
   743     }
   744     return;
   745   }
   746   // we now have only HTML
   747   // Some HTML nodes need DoneAddingChildren() called to initialize
   748   // properly (e.g. form state restoration).
   749   // XXX expose ElementName group here and do switch
   750   if (aName == nsHtml5Atoms::object ||
   751       aName == nsHtml5Atoms::applet) {
   752     if (mBuilder) {
   753       nsHtml5TreeOperation::DoneAddingChildren(static_cast<nsIContent*>(aElement), mBuilder);
   754       return;
   755     }
   756     nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   757     NS_ASSERTION(treeOp, "Tree op allocation failed.");
   758     treeOp->Init(eTreeOpDoneAddingChildren, aElement);
   759     return;
   760   }
   761   if (aName == nsHtml5Atoms::select || 
   762       aName == nsHtml5Atoms::textarea) {
   763     if (!formPointer) {
   764       // If form inputs don't belong to a form, their state preservation
   765       // won't work right without an append notification flush at this 
   766       // point. See bug 497861 and bug 539895.
   767       if (mBuilder) {
   768         mBuilder->FlushPendingAppendNotifications();
   769       } else {
   770         nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   771         NS_ASSERTION(treeOp, "Tree op allocation failed.");
   772         treeOp->Init(eTreeOpFlushPendingAppendNotifications);
   773       }
   774     }
   775     if (mBuilder) {
   776       nsHtml5TreeOperation::DoneAddingChildren(static_cast<nsIContent*>(aElement), mBuilder);
   777       return;
   778     }
   779     nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   780     NS_ASSERTION(treeOp, "Tree op allocation failed.");
   781     treeOp->Init(eTreeOpDoneAddingChildren, aElement);
   782     return;
   783   }
   784   if (aName == nsHtml5Atoms::meta && !fragment && !mBuilder) {
   785     nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   786     NS_ASSERTION(treeOp, "Tree op allocation failed.");
   787     treeOp->Init(eTreeOpProcessMeta, aElement);
   788     return;
   789   }
   790   return;
   791 }
   793 void
   794 nsHtml5TreeBuilder::accumulateCharacters(const char16_t* aBuf, int32_t aStart, int32_t aLength)
   795 {
   796   int32_t newFillLen = charBufferLen + aLength;
   797   if (newFillLen > charBuffer.length) {
   798     int32_t newAllocLength = newFillLen + (newFillLen >> 1);
   799     jArray<char16_t,int32_t> newBuf = jArray<char16_t,int32_t>::newJArray(newAllocLength);
   800     memcpy(newBuf, charBuffer, sizeof(char16_t) * charBufferLen);
   801     charBuffer = newBuf;
   802   }
   803   memcpy(charBuffer + charBufferLen, aBuf + aStart, sizeof(char16_t) * aLength);
   804   charBufferLen = newFillLen;
   805 }
   807 nsIContentHandle*
   808 nsHtml5TreeBuilder::AllocateContentHandle()
   809 {
   810   if (MOZ_UNLIKELY(mBuilder)) {
   811     MOZ_ASSUME_UNREACHABLE("Must never allocate a handle with builder.");
   812     return nullptr;
   813   }
   814   if (mHandlesUsed == NS_HTML5_TREE_BUILDER_HANDLE_ARRAY_LENGTH) {
   815     mOldHandles.AppendElement(mHandles.forget());
   816     mHandles = new nsIContent*[NS_HTML5_TREE_BUILDER_HANDLE_ARRAY_LENGTH];
   817     mHandlesUsed = 0;
   818   }
   819 #ifdef DEBUG
   820   mHandles[mHandlesUsed] = (nsIContent*)0xC0DEDBAD;
   821 #endif
   822   return &mHandles[mHandlesUsed++];
   823 }
   825 bool
   826 nsHtml5TreeBuilder::HasScript()
   827 {
   828   uint32_t len = mOpQueue.Length();
   829   if (!len) {
   830     return false;
   831   }
   832   return mOpQueue.ElementAt(len - 1).IsRunScript();
   833 }
   835 bool
   836 nsHtml5TreeBuilder::Flush(bool aDiscretionary)
   837 {
   838   if (MOZ_UNLIKELY(mBuilder)) {
   839     MOZ_ASSUME_UNREACHABLE("Must never flush with builder.");
   840     return false;
   841   }
   842   if (!aDiscretionary ||
   843       !(charBufferLen &&
   844         currentPtr >= 0 &&
   845         stack[currentPtr]->isFosterParenting())) {
   846     // Don't flush text on discretionary flushes if the current element on
   847     // the stack is a foster-parenting element and there's pending text,
   848     // because flushing in that case would make the tree shape dependent on
   849     // where the flush points fall.
   850     flushCharacters();
   851   }
   852   FlushLoads();
   853   if (mOpSink) {
   854     bool hasOps = !mOpQueue.IsEmpty();
   855     if (hasOps) {
   856       mOpSink->MoveOpsFrom(mOpQueue);
   857     }
   858     return hasOps;
   859   }
   860   // no op sink: throw away ops
   861   mOpQueue.Clear();
   862   return false;
   863 }
   865 void
   866 nsHtml5TreeBuilder::FlushLoads()
   867 {
   868   if (MOZ_UNLIKELY(mBuilder)) {
   869     MOZ_ASSUME_UNREACHABLE("Must never flush loads with builder.");
   870     return;
   871   }
   872   if (!mSpeculativeLoadQueue.IsEmpty()) {
   873     mSpeculativeLoadStage->MoveSpeculativeLoadsFrom(mSpeculativeLoadQueue);
   874   }
   875 }
   877 void
   878 nsHtml5TreeBuilder::SetDocumentCharset(nsACString& aCharset, 
   879                                        int32_t aCharsetSource)
   880 {
   881   if (mBuilder) {
   882     mBuilder->SetDocumentCharsetAndSource(aCharset, aCharsetSource);
   883   } else if (mSpeculativeLoadStage) {
   884     mSpeculativeLoadQueue.AppendElement()->InitSetDocumentCharset(
   885       aCharset, aCharsetSource);
   886   } else {
   887     mOpQueue.AppendElement()->Init(
   888       eTreeOpSetDocumentCharset, aCharset, aCharsetSource);
   889   }
   890 }
   892 void
   893 nsHtml5TreeBuilder::StreamEnded()
   894 {
   895   MOZ_ASSERT(!mBuilder, "Must not call StreamEnded with builder.");
   896   MOZ_ASSERT(!fragment, "Must not parse fragments off the main thread.");
   897   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   898   NS_ASSERTION(treeOp, "Tree op allocation failed.");
   899   treeOp->Init(eTreeOpStreamEnded);
   900 }
   902 void
   903 nsHtml5TreeBuilder::NeedsCharsetSwitchTo(const nsACString& aCharset,
   904                                          int32_t aCharsetSource,
   905                                          int32_t aLineNumber)
   906 {
   907   if (MOZ_UNLIKELY(mBuilder)) {
   908     MOZ_ASSUME_UNREACHABLE("Must never switch charset with builder.");
   909     return;
   910   }
   911   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   912   NS_ASSERTION(treeOp, "Tree op allocation failed.");
   913   treeOp->Init(eTreeOpNeedsCharsetSwitchTo,
   914                aCharset,
   915                aCharsetSource,
   916                aLineNumber);
   917 }
   919 void
   920 nsHtml5TreeBuilder::MaybeComplainAboutCharset(const char* aMsgId,
   921                                               bool aError,
   922                                               int32_t aLineNumber)
   923 {
   924   if (MOZ_UNLIKELY(mBuilder)) {
   925     MOZ_ASSUME_UNREACHABLE("Must never complain about charset with builder.");
   926     return;
   927   }
   928   mOpQueue.AppendElement()->Init(aMsgId, aError, aLineNumber);
   929 }
   931 void
   932 nsHtml5TreeBuilder::AddSnapshotToScript(nsAHtml5TreeBuilderState* aSnapshot, int32_t aLine)
   933 {
   934   if (MOZ_UNLIKELY(mBuilder)) {
   935     MOZ_ASSUME_UNREACHABLE("Must never use snapshots with builder.");
   936     return;
   937   }
   938   NS_PRECONDITION(HasScript(), "No script to add a snapshot to!");
   939   NS_PRECONDITION(aSnapshot, "Got null snapshot.");
   940   mOpQueue.ElementAt(mOpQueue.Length() - 1).SetSnapshot(aSnapshot, aLine);
   941 }
   943 void
   944 nsHtml5TreeBuilder::DropHandles()
   945 {
   946   MOZ_ASSERT(!mBuilder, "Must not drop handles with builder.");
   947   mOldHandles.Clear();
   948   mHandlesUsed = 0;
   949 }
   951 void
   952 nsHtml5TreeBuilder::MarkAsBroken(nsresult aRv)
   953 {
   954   if (MOZ_UNLIKELY(mBuilder)) {
   955     MOZ_ASSUME_UNREACHABLE("Must not call this with builder.");
   956     return;
   957   }
   958   mOpQueue.Clear(); // Previous ops don't matter anymore
   959   mOpQueue.AppendElement()->Init(aRv);
   960 }
   962 void
   963 nsHtml5TreeBuilder::StartPlainTextViewSource(const nsAutoString& aTitle)
   964 {
   965   MOZ_ASSERT(!mBuilder, "Must not view source with builder.");
   966   startTag(nsHtml5ElementName::ELT_TITLE,
   967            nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES,
   968            false);
   970   // XUL will add the "Source of: " prefix.
   971   uint32_t length = aTitle.Length();
   972   if (length > INT32_MAX) {
   973     length = INT32_MAX;
   974   }
   975   characters(aTitle.get(), 0, (int32_t)length);
   976   endTag(nsHtml5ElementName::ELT_TITLE);
   978   startTag(nsHtml5ElementName::ELT_LINK,
   979            nsHtml5ViewSourceUtils::NewLinkAttributes(),
   980            false);
   982   startTag(nsHtml5ElementName::ELT_BODY,
   983            nsHtml5ViewSourceUtils::NewBodyAttributes(),
   984            false);
   986   StartPlainTextBody();
   987 }
   989 void
   990 nsHtml5TreeBuilder::StartPlainText()
   991 {
   992   MOZ_ASSERT(!mBuilder, "Must not view source with builder.");
   993   startTag(nsHtml5ElementName::ELT_LINK,
   994            nsHtml5PlainTextUtils::NewLinkAttributes(),
   995            false);
   997   StartPlainTextBody();
   998 }
  1000 void
  1001 nsHtml5TreeBuilder::StartPlainTextBody()
  1003   MOZ_ASSERT(!mBuilder, "Must not view source with builder.");
  1004   startTag(nsHtml5ElementName::ELT_PRE,
  1005            nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES,
  1006            false);
  1007   needToDropLF = false;
  1010 // DocumentModeHandler
  1011 void
  1012 nsHtml5TreeBuilder::documentMode(nsHtml5DocumentMode m)
  1014   if (mBuilder) {
  1015     mBuilder->SetDocumentMode(m);
  1016     return;
  1018   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
  1019   NS_ASSERTION(treeOp, "Tree op allocation failed.");
  1020   treeOp->Init(m);
  1023 nsIContentHandle*
  1024 nsHtml5TreeBuilder::getDocumentFragmentForTemplate(nsIContentHandle* aTemplate)
  1026   if (mBuilder) {
  1027     return nsHtml5TreeOperation::GetDocumentFragmentForTemplate(static_cast<nsIContent*>(aTemplate));
  1029   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
  1030   NS_ASSERTION(treeOp, "Tree op allocation failed.");
  1031   nsIContentHandle* fragHandle = AllocateContentHandle();
  1032   treeOp->Init(eTreeOpGetDocumentFragmentForTemplate, aTemplate, fragHandle);
  1033   return fragHandle;
  1036 nsIContentHandle*
  1037 nsHtml5TreeBuilder::getFormPointerForContext(nsIContentHandle* aContext)
  1039   MOZ_ASSERT(mBuilder, "Must have builder.");
  1040   if (!aContext) {
  1041     return nullptr;
  1044   MOZ_ASSERT(NS_IsMainThread());
  1046   // aContext must always be an element that already exists
  1047   // in the document.
  1048   nsIContent* contextNode = static_cast<nsIContent*>(aContext);
  1049   nsIContent* currentAncestor = contextNode;
  1051   // We traverse the ancestors of the context node to find the nearest
  1052   // form pointer. This traversal is why aContext must not be an emtpy handle.
  1053   nsIContent* nearestForm = nullptr;
  1054   while (currentAncestor) {
  1055     if (currentAncestor->IsHTML(nsGkAtoms::form)) {
  1056       nearestForm = currentAncestor;
  1057       break;
  1059     currentAncestor = currentAncestor->GetParent();
  1062   if (!nearestForm) {
  1063     return nullptr;
  1066   return nearestForm;
  1069 // Error reporting
  1071 void
  1072 nsHtml5TreeBuilder::EnableViewSource(nsHtml5Highlighter* aHighlighter)
  1074   MOZ_ASSERT(!mBuilder, "Must not view source with builder.");
  1075   mViewSource = aHighlighter;
  1078 void
  1079 nsHtml5TreeBuilder::errStrayStartTag(nsIAtom* aName)
  1081   if (MOZ_UNLIKELY(mViewSource)) {
  1082     mViewSource->AddErrorToCurrentRun("errStrayStartTag2", aName);
  1086 void
  1087 nsHtml5TreeBuilder::errStrayEndTag(nsIAtom* aName)
  1089   if (MOZ_UNLIKELY(mViewSource)) {
  1090     mViewSource->AddErrorToCurrentRun("errStrayEndTag", aName);
  1094 void
  1095 nsHtml5TreeBuilder::errUnclosedElements(int32_t aIndex, nsIAtom* aName)
  1097   if (MOZ_UNLIKELY(mViewSource)) {
  1098     mViewSource->AddErrorToCurrentRun("errUnclosedElements", aName);
  1102 void
  1103 nsHtml5TreeBuilder::errUnclosedElementsImplied(int32_t aIndex, nsIAtom* aName)
  1105   if (MOZ_UNLIKELY(mViewSource)) {
  1106     mViewSource->AddErrorToCurrentRun("errUnclosedElementsImplied",
  1107         aName);
  1111 void
  1112 nsHtml5TreeBuilder::errUnclosedElementsCell(int32_t aIndex)
  1114   if (MOZ_UNLIKELY(mViewSource)) {
  1115     mViewSource->AddErrorToCurrentRun("errUnclosedElementsCell");
  1119 void
  1120 nsHtml5TreeBuilder::errStrayDoctype()
  1122   if (MOZ_UNLIKELY(mViewSource)) {
  1123     mViewSource->AddErrorToCurrentRun("errStrayDoctype");
  1127 void
  1128 nsHtml5TreeBuilder::errAlmostStandardsDoctype()
  1130   if (MOZ_UNLIKELY(mViewSource) && !isSrcdocDocument) {
  1131     mViewSource->AddErrorToCurrentRun("errAlmostStandardsDoctype");
  1135 void
  1136 nsHtml5TreeBuilder::errQuirkyDoctype()
  1138   if (MOZ_UNLIKELY(mViewSource) && !isSrcdocDocument) {
  1139     mViewSource->AddErrorToCurrentRun("errQuirkyDoctype");
  1143 void
  1144 nsHtml5TreeBuilder::errNonSpaceInTrailer()
  1146   if (MOZ_UNLIKELY(mViewSource)) {
  1147     mViewSource->AddErrorToCurrentRun("errNonSpaceInTrailer");
  1151 void
  1152 nsHtml5TreeBuilder::errNonSpaceAfterFrameset()
  1154   if (MOZ_UNLIKELY(mViewSource)) {
  1155     mViewSource->AddErrorToCurrentRun("errNonSpaceAfterFrameset");
  1159 void
  1160 nsHtml5TreeBuilder::errNonSpaceInFrameset()
  1162   if (MOZ_UNLIKELY(mViewSource)) {
  1163     mViewSource->AddErrorToCurrentRun("errNonSpaceInFrameset");
  1167 void
  1168 nsHtml5TreeBuilder::errNonSpaceAfterBody()
  1170   if (MOZ_UNLIKELY(mViewSource)) {
  1171     mViewSource->AddErrorToCurrentRun("errNonSpaceAfterBody");
  1175 void
  1176 nsHtml5TreeBuilder::errNonSpaceInColgroupInFragment()
  1178   if (MOZ_UNLIKELY(mViewSource)) {
  1179     mViewSource->AddErrorToCurrentRun("errNonSpaceInColgroupInFragment");
  1183 void
  1184 nsHtml5TreeBuilder::errNonSpaceInNoscriptInHead()
  1186   if (MOZ_UNLIKELY(mViewSource)) {
  1187     mViewSource->AddErrorToCurrentRun("errNonSpaceInNoscriptInHead");
  1191 void
  1192 nsHtml5TreeBuilder::errFooBetweenHeadAndBody(nsIAtom* aName)
  1194   if (MOZ_UNLIKELY(mViewSource)) {
  1195     mViewSource->AddErrorToCurrentRun("errFooBetweenHeadAndBody", aName);
  1199 void
  1200 nsHtml5TreeBuilder::errStartTagWithoutDoctype()
  1202   if (MOZ_UNLIKELY(mViewSource) && !isSrcdocDocument) {
  1203     mViewSource->AddErrorToCurrentRun("errStartTagWithoutDoctype");
  1207 void
  1208 nsHtml5TreeBuilder::errNoSelectInTableScope()
  1210   if (MOZ_UNLIKELY(mViewSource)) {
  1211     mViewSource->AddErrorToCurrentRun("errNoSelectInTableScope");
  1215 void
  1216 nsHtml5TreeBuilder::errStartSelectWhereEndSelectExpected()
  1218   if (MOZ_UNLIKELY(mViewSource)) {
  1219     mViewSource->AddErrorToCurrentRun(
  1220         "errStartSelectWhereEndSelectExpected");
  1224 void
  1225 nsHtml5TreeBuilder::errStartTagWithSelectOpen(nsIAtom* aName)
  1227   if (MOZ_UNLIKELY(mViewSource)) {
  1228     mViewSource->AddErrorToCurrentRun("errStartTagWithSelectOpen", aName);
  1232 void
  1233 nsHtml5TreeBuilder::errBadStartTagInHead(nsIAtom* aName)
  1235   if (MOZ_UNLIKELY(mViewSource)) {
  1236     mViewSource->AddErrorToCurrentRun("errBadStartTagInHead2", aName);
  1240 void
  1241 nsHtml5TreeBuilder::errImage()
  1243   if (MOZ_UNLIKELY(mViewSource)) {
  1244     mViewSource->AddErrorToCurrentRun("errImage");
  1248 void
  1249 nsHtml5TreeBuilder::errIsindex()
  1251   if (MOZ_UNLIKELY(mViewSource)) {
  1252     mViewSource->AddErrorToCurrentRun("errIsindex");
  1256 void
  1257 nsHtml5TreeBuilder::errFooSeenWhenFooOpen(nsIAtom* aName)
  1259   if (MOZ_UNLIKELY(mViewSource)) {
  1260     mViewSource->AddErrorToCurrentRun("errFooSeenWhenFooOpen", aName);
  1264 void
  1265 nsHtml5TreeBuilder::errHeadingWhenHeadingOpen()
  1267   if (MOZ_UNLIKELY(mViewSource)) {
  1268     mViewSource->AddErrorToCurrentRun("errHeadingWhenHeadingOpen");
  1272 void
  1273 nsHtml5TreeBuilder::errFramesetStart()
  1275   if (MOZ_UNLIKELY(mViewSource)) {
  1276     mViewSource->AddErrorToCurrentRun("errFramesetStart");
  1280 void
  1281 nsHtml5TreeBuilder::errNoCellToClose()
  1283   if (MOZ_UNLIKELY(mViewSource)) {
  1284     mViewSource->AddErrorToCurrentRun("errNoCellToClose");
  1288 void
  1289 nsHtml5TreeBuilder::errStartTagInTable(nsIAtom* aName)
  1291   if (MOZ_UNLIKELY(mViewSource)) {
  1292     mViewSource->AddErrorToCurrentRun("errStartTagInTable", aName);
  1296 void
  1297 nsHtml5TreeBuilder::errFormWhenFormOpen()
  1299   if (MOZ_UNLIKELY(mViewSource)) {
  1300     mViewSource->AddErrorToCurrentRun("errFormWhenFormOpen");
  1304 void
  1305 nsHtml5TreeBuilder::errTableSeenWhileTableOpen()
  1307   if (MOZ_UNLIKELY(mViewSource)) {
  1308     mViewSource->AddErrorToCurrentRun("errTableSeenWhileTableOpen");
  1312 void
  1313 nsHtml5TreeBuilder::errStartTagInTableBody(nsIAtom* aName)
  1315   if (MOZ_UNLIKELY(mViewSource)) {
  1316     mViewSource->AddErrorToCurrentRun("errStartTagInTableBody", aName);
  1320 void
  1321 nsHtml5TreeBuilder::errEndTagSeenWithoutDoctype()
  1323   if (MOZ_UNLIKELY(mViewSource) && !isSrcdocDocument) {
  1324     mViewSource->AddErrorToCurrentRun("errEndTagSeenWithoutDoctype");
  1328 void
  1329 nsHtml5TreeBuilder::errEndTagAfterBody()
  1331   if (MOZ_UNLIKELY(mViewSource)) {
  1332     mViewSource->AddErrorToCurrentRun("errEndTagAfterBody");
  1336 void
  1337 nsHtml5TreeBuilder::errEndTagSeenWithSelectOpen(nsIAtom* aName)
  1339   if (MOZ_UNLIKELY(mViewSource)) {
  1340     mViewSource->AddErrorToCurrentRun("errEndTagSeenWithSelectOpen",
  1341         aName);
  1345 void
  1346 nsHtml5TreeBuilder::errGarbageInColgroup()
  1348   if (MOZ_UNLIKELY(mViewSource)) {
  1349     mViewSource->AddErrorToCurrentRun("errGarbageInColgroup");
  1353 void
  1354 nsHtml5TreeBuilder::errEndTagBr()
  1356   if (MOZ_UNLIKELY(mViewSource)) {
  1357     mViewSource->AddErrorToCurrentRun("errEndTagBr");
  1361 void
  1362 nsHtml5TreeBuilder::errNoElementToCloseButEndTagSeen(nsIAtom* aName)
  1364   if (MOZ_UNLIKELY(mViewSource)) {
  1365     mViewSource->AddErrorToCurrentRun(
  1366         "errNoElementToCloseButEndTagSeen", aName);
  1370 void
  1371 nsHtml5TreeBuilder::errHtmlStartTagInForeignContext(nsIAtom* aName)
  1373   if (MOZ_UNLIKELY(mViewSource)) {
  1374     mViewSource->AddErrorToCurrentRun("errHtmlStartTagInForeignContext",
  1375         aName);
  1379 void
  1380 nsHtml5TreeBuilder::errTableClosedWhileCaptionOpen()
  1382   if (MOZ_UNLIKELY(mViewSource)) {
  1383     mViewSource->AddErrorToCurrentRun("errTableClosedWhileCaptionOpen");
  1387 void
  1388 nsHtml5TreeBuilder::errNoTableRowToClose()
  1390   if (MOZ_UNLIKELY(mViewSource)) {
  1391     mViewSource->AddErrorToCurrentRun("errNoTableRowToClose");
  1395 void
  1396 nsHtml5TreeBuilder::errNonSpaceInTable()
  1398   if (MOZ_UNLIKELY(mViewSource)) {
  1399     mViewSource->AddErrorToCurrentRun("errNonSpaceInTable");
  1403 void
  1404 nsHtml5TreeBuilder::errUnclosedChildrenInRuby()
  1406   if (MOZ_UNLIKELY(mViewSource)) {
  1407     mViewSource->AddErrorToCurrentRun("errUnclosedChildrenInRuby");
  1411 void
  1412 nsHtml5TreeBuilder::errStartTagSeenWithoutRuby(nsIAtom* aName)
  1414   if (MOZ_UNLIKELY(mViewSource)) {
  1415     mViewSource->AddErrorToCurrentRun("errStartTagSeenWithoutRuby",
  1416         aName);
  1420 void
  1421 nsHtml5TreeBuilder::errSelfClosing()
  1423   if (MOZ_UNLIKELY(mViewSource)) {
  1424     mViewSource->AddErrorToCurrentSlash("errSelfClosing");
  1428 void
  1429 nsHtml5TreeBuilder::errNoCheckUnclosedElementsOnStack()
  1431   if (MOZ_UNLIKELY(mViewSource)) {
  1432     mViewSource->AddErrorToCurrentRun(
  1433         "errNoCheckUnclosedElementsOnStack");
  1437 void
  1438 nsHtml5TreeBuilder::errEndTagDidNotMatchCurrentOpenElement(nsIAtom* aName,
  1439                                                            nsIAtom* aOther)
  1441   if (MOZ_UNLIKELY(mViewSource)) {
  1442     mViewSource->AddErrorToCurrentRun(
  1443         "errEndTagDidNotMatchCurrentOpenElement", aName, aOther);
  1447 void
  1448 nsHtml5TreeBuilder::errEndTagViolatesNestingRules(nsIAtom* aName)
  1450   if (MOZ_UNLIKELY(mViewSource)) {
  1451     mViewSource->AddErrorToCurrentRun("errEndTagViolatesNestingRules", aName);
  1455 void
  1456 nsHtml5TreeBuilder::errEndWithUnclosedElements(nsIAtom* aName)
  1458   if (MOZ_UNLIKELY(mViewSource)) {
  1459     mViewSource->AddErrorToCurrentRun("errEndWithUnclosedElements", aName);

mercurial