parser/html/nsHtml5TreeBuilder.cpp

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 /*
     2  * Copyright (c) 2007 Henri Sivonen
     3  * Copyright (c) 2007-2011 Mozilla Foundation
     4  * Portions of comments Copyright 2004-2008 Apple Computer, Inc., Mozilla
     5  * Foundation, and Opera Software ASA.
     6  *
     7  * Permission is hereby granted, free of charge, to any person obtaining a
     8  * copy of this software and associated documentation files (the "Software"),
     9  * to deal in the Software without restriction, including without limitation
    10  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
    11  * and/or sell copies of the Software, and to permit persons to whom the
    12  * Software is furnished to do so, subject to the following conditions:
    13  *
    14  * The above copyright notice and this permission notice shall be included in
    15  * all copies or substantial portions of the Software.
    16  *
    17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
    20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    22  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
    23  * DEALINGS IN THE SOFTWARE.
    24  */
    26 /*
    27  * THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
    28  * Please edit TreeBuilder.java instead and regenerate.
    29  */
    31 #define nsHtml5TreeBuilder_cpp__
    33 #include "nsContentUtils.h"
    34 #include "nsIAtom.h"
    35 #include "nsHtml5AtomTable.h"
    36 #include "nsITimer.h"
    37 #include "nsString.h"
    38 #include "nsNameSpaceManager.h"
    39 #include "nsIContent.h"
    40 #include "nsTraceRefcnt.h"
    41 #include "jArray.h"
    42 #include "nsHtml5DocumentMode.h"
    43 #include "nsHtml5ArrayCopy.h"
    44 #include "nsHtml5Parser.h"
    45 #include "nsHtml5Atoms.h"
    46 #include "nsHtml5TreeOperation.h"
    47 #include "nsHtml5PendingNotification.h"
    48 #include "nsHtml5StateSnapshot.h"
    49 #include "nsHtml5StackNode.h"
    50 #include "nsHtml5TreeOpExecutor.h"
    51 #include "nsHtml5StreamParser.h"
    52 #include "nsAHtml5TreeBuilderState.h"
    53 #include "nsHtml5Highlighter.h"
    54 #include "nsHtml5PlainTextUtils.h"
    55 #include "nsHtml5ViewSourceUtils.h"
    56 #include "mozilla/Likely.h"
    57 #include "nsIContentHandle.h"
    58 #include "nsHtml5OplessBuilder.h"
    60 #include "nsHtml5Tokenizer.h"
    61 #include "nsHtml5MetaScanner.h"
    62 #include "nsHtml5AttributeName.h"
    63 #include "nsHtml5ElementName.h"
    64 #include "nsHtml5HtmlAttributes.h"
    65 #include "nsHtml5StackNode.h"
    66 #include "nsHtml5UTF16Buffer.h"
    67 #include "nsHtml5StateSnapshot.h"
    68 #include "nsHtml5Portability.h"
    70 #include "nsHtml5TreeBuilder.h"
    72 char16_t nsHtml5TreeBuilder::REPLACEMENT_CHARACTER[] = { 0xfffd };
    73 static const char* const QUIRKY_PUBLIC_IDS_DATA[] = { "+//silmaril//dtd html pro v0r11 19970101//", "-//advasoft ltd//dtd html 3.0 aswedit + extensions//", "-//as//dtd html 3.0 aswedit + extensions//", "-//ietf//dtd html 2.0 level 1//", "-//ietf//dtd html 2.0 level 2//", "-//ietf//dtd html 2.0 strict level 1//", "-//ietf//dtd html 2.0 strict level 2//", "-//ietf//dtd html 2.0 strict//", "-//ietf//dtd html 2.0//", "-//ietf//dtd html 2.1e//", "-//ietf//dtd html 3.0//", "-//ietf//dtd html 3.2 final//", "-//ietf//dtd html 3.2//", "-//ietf//dtd html 3//", "-//ietf//dtd html level 0//", "-//ietf//dtd html level 1//", "-//ietf//dtd html level 2//", "-//ietf//dtd html level 3//", "-//ietf//dtd html strict level 0//", "-//ietf//dtd html strict level 1//", "-//ietf//dtd html strict level 2//", "-//ietf//dtd html strict level 3//", "-//ietf//dtd html strict//", "-//ietf//dtd html//", "-//metrius//dtd metrius presentational//", "-//microsoft//dtd internet explorer 2.0 html strict//", "-//microsoft//dtd internet explorer 2.0 html//", "-//microsoft//dtd internet explorer 2.0 tables//", "-//microsoft//dtd internet explorer 3.0 html strict//", "-//microsoft//dtd internet explorer 3.0 html//", "-//microsoft//dtd internet explorer 3.0 tables//", "-//netscape comm. corp.//dtd html//", "-//netscape comm. corp.//dtd strict html//", "-//o'reilly and associates//dtd html 2.0//", "-//o'reilly and associates//dtd html extended 1.0//", "-//o'reilly and associates//dtd html extended relaxed 1.0//", "-//softquad software//dtd hotmetal pro 6.0::19990601::extensions to html 4.0//", "-//softquad//dtd hotmetal pro 4.0::19971010::extensions to html 4.0//", "-//spyglass//dtd html 2.0 extended//", "-//sq//dtd html 2.0 hotmetal + extensions//", "-//sun microsystems corp.//dtd hotjava html//", "-//sun microsystems corp.//dtd hotjava strict html//", "-//w3c//dtd html 3 1995-03-24//", "-//w3c//dtd html 3.2 draft//", "-//w3c//dtd html 3.2 final//", "-//w3c//dtd html 3.2//", "-//w3c//dtd html 3.2s draft//", "-//w3c//dtd html 4.0 frameset//", "-//w3c//dtd html 4.0 transitional//", "-//w3c//dtd html experimental 19960712//", "-//w3c//dtd html experimental 970421//", "-//w3c//dtd w3 html//", "-//w3o//dtd w3 html 3.0//", "-//webtechs//dtd mozilla html 2.0//", "-//webtechs//dtd mozilla html//" };
    74 staticJArray<const char*,int32_t> nsHtml5TreeBuilder::QUIRKY_PUBLIC_IDS = { QUIRKY_PUBLIC_IDS_DATA, MOZ_ARRAY_LENGTH(QUIRKY_PUBLIC_IDS_DATA) };
    75 void 
    76 nsHtml5TreeBuilder::startTokenization(nsHtml5Tokenizer* self)
    77 {
    78   tokenizer = self;
    79   stack = jArray<nsHtml5StackNode*,int32_t>::newJArray(64);
    80   templateModeStack = jArray<int32_t,int32_t>::newJArray(64);
    81   listOfActiveFormattingElements = jArray<nsHtml5StackNode*,int32_t>::newJArray(64);
    82   needToDropLF = false;
    83   originalMode = NS_HTML5TREE_BUILDER_INITIAL;
    84   templateModePtr = -1;
    85   currentPtr = -1;
    86   listPtr = -1;
    87   formPointer = nullptr;
    88   headPointer = nullptr;
    89   deepTreeSurrogateParent = nullptr;
    90   start(fragment);
    91   charBufferLen = 0;
    92   charBuffer = jArray<char16_t,int32_t>::newJArray(1024);
    93   framesetOk = true;
    94   if (fragment) {
    95     nsIContentHandle* elt;
    96     if (contextNode) {
    97       elt = contextNode;
    98     } else {
    99       elt = createHtmlElementSetAsRoot(tokenizer->emptyAttributes());
   100     }
   101     nsHtml5StackNode* node = new nsHtml5StackNode(nsHtml5ElementName::ELT_HTML, elt);
   102     currentPtr++;
   103     stack[currentPtr] = node;
   104     if (nsHtml5Atoms::template_ == contextName) {
   105       pushTemplateMode(NS_HTML5TREE_BUILDER_IN_TEMPLATE);
   106     }
   107     resetTheInsertionMode();
   108     formPointer = getFormPointerForContext(contextNode);
   109     if (nsHtml5Atoms::title == contextName || nsHtml5Atoms::textarea == contextName) {
   110       tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_RCDATA, contextName);
   111     } else if (nsHtml5Atoms::style == contextName || nsHtml5Atoms::xmp == contextName || nsHtml5Atoms::iframe == contextName || nsHtml5Atoms::noembed == contextName || nsHtml5Atoms::noframes == contextName || (scriptingEnabled && nsHtml5Atoms::noscript == contextName)) {
   112       tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_RAWTEXT, contextName);
   113     } else if (nsHtml5Atoms::plaintext == contextName) {
   114       tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_PLAINTEXT, contextName);
   115     } else if (nsHtml5Atoms::script == contextName) {
   116       tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_SCRIPT_DATA, contextName);
   117     } else {
   118       tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_DATA, contextName);
   119     }
   120     contextName = nullptr;
   121     contextNode = nullptr;
   122   } else {
   123     mode = NS_HTML5TREE_BUILDER_INITIAL;
   124     if (tokenizer->isViewingXmlSource()) {
   125       nsIContentHandle* elt = createElement(kNameSpaceID_SVG, nsHtml5Atoms::svg, tokenizer->emptyAttributes());
   126       nsHtml5StackNode* node = new nsHtml5StackNode(nsHtml5ElementName::ELT_SVG, nsHtml5Atoms::svg, elt);
   127       currentPtr++;
   128       stack[currentPtr] = node;
   129     }
   130   }
   131 }
   133 void 
   134 nsHtml5TreeBuilder::doctype(nsIAtom* name, nsString* publicIdentifier, nsString* systemIdentifier, bool forceQuirks)
   135 {
   136   needToDropLF = false;
   137   if (!isInForeign() && mode == NS_HTML5TREE_BUILDER_INITIAL) {
   138     nsString* emptyString = nsHtml5Portability::newEmptyString();
   139     appendDoctypeToDocument(!name ? nsHtml5Atoms::emptystring : name, !publicIdentifier ? emptyString : publicIdentifier, !systemIdentifier ? emptyString : systemIdentifier);
   140     nsHtml5Portability::releaseString(emptyString);
   141     if (isQuirky(name, publicIdentifier, systemIdentifier, forceQuirks)) {
   142       errQuirkyDoctype();
   143       documentModeInternal(QUIRKS_MODE, publicIdentifier, systemIdentifier, false);
   144     } else if (isAlmostStandards(publicIdentifier, systemIdentifier)) {
   145       errAlmostStandardsDoctype();
   146       documentModeInternal(ALMOST_STANDARDS_MODE, publicIdentifier, systemIdentifier, false);
   147     } else {
   148       documentModeInternal(STANDARDS_MODE, publicIdentifier, systemIdentifier, false);
   149     }
   150     mode = NS_HTML5TREE_BUILDER_BEFORE_HTML;
   151     return;
   152   }
   153   errStrayDoctype();
   154   return;
   155 }
   157 void 
   158 nsHtml5TreeBuilder::comment(char16_t* buf, int32_t start, int32_t length)
   159 {
   160   needToDropLF = false;
   161   if (!isInForeign()) {
   162     switch(mode) {
   163       case NS_HTML5TREE_BUILDER_INITIAL:
   164       case NS_HTML5TREE_BUILDER_BEFORE_HTML:
   165       case NS_HTML5TREE_BUILDER_AFTER_AFTER_BODY:
   166       case NS_HTML5TREE_BUILDER_AFTER_AFTER_FRAMESET: {
   167         appendCommentToDocument(buf, start, length);
   168         return;
   169       }
   170       case NS_HTML5TREE_BUILDER_AFTER_BODY: {
   171         flushCharacters();
   172         appendComment(stack[0]->node, buf, start, length);
   173         return;
   174       }
   175       default: {
   176         break;
   177       }
   178     }
   179   }
   180   flushCharacters();
   181   appendComment(stack[currentPtr]->node, buf, start, length);
   182   return;
   183 }
   185 void 
   186 nsHtml5TreeBuilder::characters(const char16_t* buf, int32_t start, int32_t length)
   187 {
   188   if (tokenizer->isViewingXmlSource()) {
   189     return;
   190   }
   191   if (needToDropLF) {
   192     needToDropLF = false;
   193     if (buf[start] == '\n') {
   194       start++;
   195       length--;
   196       if (!length) {
   197         return;
   198       }
   199     }
   200   }
   201   switch(mode) {
   202     case NS_HTML5TREE_BUILDER_IN_BODY:
   203     case NS_HTML5TREE_BUILDER_IN_CELL:
   204     case NS_HTML5TREE_BUILDER_IN_CAPTION: {
   205       if (!isInForeignButNotHtmlOrMathTextIntegrationPoint()) {
   206         reconstructTheActiveFormattingElements();
   207       }
   208     }
   209     case NS_HTML5TREE_BUILDER_TEXT: {
   210       accumulateCharacters(buf, start, length);
   211       return;
   212     }
   213     case NS_HTML5TREE_BUILDER_IN_TABLE:
   214     case NS_HTML5TREE_BUILDER_IN_TABLE_BODY:
   215     case NS_HTML5TREE_BUILDER_IN_ROW: {
   216       accumulateCharactersForced(buf, start, length);
   217       return;
   218     }
   219     default: {
   220       int32_t end = start + length;
   221       for (int32_t i = start; i < end; i++) {
   222         switch(buf[i]) {
   223           case ' ':
   224           case '\t':
   225           case '\n':
   226           case '\r':
   227           case '\f': {
   228             switch(mode) {
   229               case NS_HTML5TREE_BUILDER_INITIAL:
   230               case NS_HTML5TREE_BUILDER_BEFORE_HTML:
   231               case NS_HTML5TREE_BUILDER_BEFORE_HEAD: {
   232                 start = i + 1;
   233                 continue;
   234               }
   235               case NS_HTML5TREE_BUILDER_IN_HEAD:
   236               case NS_HTML5TREE_BUILDER_IN_HEAD_NOSCRIPT:
   237               case NS_HTML5TREE_BUILDER_AFTER_HEAD:
   238               case NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP:
   239               case NS_HTML5TREE_BUILDER_IN_FRAMESET:
   240               case NS_HTML5TREE_BUILDER_AFTER_FRAMESET: {
   241                 continue;
   242               }
   243               case NS_HTML5TREE_BUILDER_FRAMESET_OK:
   244               case NS_HTML5TREE_BUILDER_IN_TEMPLATE:
   245               case NS_HTML5TREE_BUILDER_IN_BODY:
   246               case NS_HTML5TREE_BUILDER_IN_CELL:
   247               case NS_HTML5TREE_BUILDER_IN_CAPTION: {
   248                 if (start < i) {
   249                   accumulateCharacters(buf, start, i - start);
   250                   start = i;
   251                 }
   252                 if (!isInForeignButNotHtmlOrMathTextIntegrationPoint()) {
   253                   flushCharacters();
   254                   reconstructTheActiveFormattingElements();
   255                 }
   256                 NS_HTML5_BREAK(charactersloop);
   257               }
   258               case NS_HTML5TREE_BUILDER_IN_SELECT:
   259               case NS_HTML5TREE_BUILDER_IN_SELECT_IN_TABLE: {
   260                 NS_HTML5_BREAK(charactersloop);
   261               }
   262               case NS_HTML5TREE_BUILDER_IN_TABLE:
   263               case NS_HTML5TREE_BUILDER_IN_TABLE_BODY:
   264               case NS_HTML5TREE_BUILDER_IN_ROW: {
   265                 accumulateCharactersForced(buf, i, 1);
   266                 start = i + 1;
   267                 continue;
   268               }
   269               case NS_HTML5TREE_BUILDER_AFTER_BODY:
   270               case NS_HTML5TREE_BUILDER_AFTER_AFTER_BODY:
   271               case NS_HTML5TREE_BUILDER_AFTER_AFTER_FRAMESET: {
   272                 if (start < i) {
   273                   accumulateCharacters(buf, start, i - start);
   274                   start = i;
   275                 }
   276                 flushCharacters();
   277                 reconstructTheActiveFormattingElements();
   278                 continue;
   279               }
   280             }
   281           }
   282           default: {
   283             switch(mode) {
   284               case NS_HTML5TREE_BUILDER_INITIAL: {
   285                 documentModeInternal(QUIRKS_MODE, nullptr, nullptr, false);
   286                 mode = NS_HTML5TREE_BUILDER_BEFORE_HTML;
   287                 i--;
   288                 continue;
   289               }
   290               case NS_HTML5TREE_BUILDER_BEFORE_HTML: {
   291                 appendHtmlElementToDocumentAndPush();
   292                 mode = NS_HTML5TREE_BUILDER_BEFORE_HEAD;
   293                 i--;
   294                 continue;
   295               }
   296               case NS_HTML5TREE_BUILDER_BEFORE_HEAD: {
   297                 if (start < i) {
   298                   accumulateCharacters(buf, start, i - start);
   299                   start = i;
   300                 }
   301                 flushCharacters();
   302                 appendToCurrentNodeAndPushHeadElement(nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES);
   303                 mode = NS_HTML5TREE_BUILDER_IN_HEAD;
   304                 i--;
   305                 continue;
   306               }
   307               case NS_HTML5TREE_BUILDER_IN_HEAD: {
   308                 if (start < i) {
   309                   accumulateCharacters(buf, start, i - start);
   310                   start = i;
   311                 }
   312                 flushCharacters();
   313                 pop();
   314                 mode = NS_HTML5TREE_BUILDER_AFTER_HEAD;
   315                 i--;
   316                 continue;
   317               }
   318               case NS_HTML5TREE_BUILDER_IN_HEAD_NOSCRIPT: {
   319                 if (start < i) {
   320                   accumulateCharacters(buf, start, i - start);
   321                   start = i;
   322                 }
   323                 errNonSpaceInNoscriptInHead();
   324                 flushCharacters();
   325                 pop();
   326                 mode = NS_HTML5TREE_BUILDER_IN_HEAD;
   327                 i--;
   328                 continue;
   329               }
   330               case NS_HTML5TREE_BUILDER_AFTER_HEAD: {
   331                 if (start < i) {
   332                   accumulateCharacters(buf, start, i - start);
   333                   start = i;
   334                 }
   335                 flushCharacters();
   336                 appendToCurrentNodeAndPushBodyElement();
   337                 mode = NS_HTML5TREE_BUILDER_FRAMESET_OK;
   338                 i--;
   339                 continue;
   340               }
   341               case NS_HTML5TREE_BUILDER_FRAMESET_OK: {
   342                 framesetOk = false;
   343                 mode = NS_HTML5TREE_BUILDER_IN_BODY;
   344                 i--;
   345                 continue;
   346               }
   347               case NS_HTML5TREE_BUILDER_IN_TEMPLATE:
   348               case NS_HTML5TREE_BUILDER_IN_BODY:
   349               case NS_HTML5TREE_BUILDER_IN_CELL:
   350               case NS_HTML5TREE_BUILDER_IN_CAPTION: {
   351                 if (start < i) {
   352                   accumulateCharacters(buf, start, i - start);
   353                   start = i;
   354                 }
   355                 if (!isInForeignButNotHtmlOrMathTextIntegrationPoint()) {
   356                   flushCharacters();
   357                   reconstructTheActiveFormattingElements();
   358                 }
   359                 NS_HTML5_BREAK(charactersloop);
   360               }
   361               case NS_HTML5TREE_BUILDER_IN_TABLE:
   362               case NS_HTML5TREE_BUILDER_IN_TABLE_BODY:
   363               case NS_HTML5TREE_BUILDER_IN_ROW: {
   364                 accumulateCharactersForced(buf, i, 1);
   365                 start = i + 1;
   366                 continue;
   367               }
   368               case NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP: {
   369                 if (start < i) {
   370                   accumulateCharacters(buf, start, i - start);
   371                   start = i;
   372                 }
   373                 if (!currentPtr || stack[currentPtr]->getGroup() == NS_HTML5TREE_BUILDER_TEMPLATE) {
   374                   errNonSpaceInColgroupInFragment();
   375                   start = i + 1;
   376                   continue;
   377                 }
   378                 flushCharacters();
   379                 pop();
   380                 mode = NS_HTML5TREE_BUILDER_IN_TABLE;
   381                 i--;
   382                 continue;
   383               }
   384               case NS_HTML5TREE_BUILDER_IN_SELECT:
   385               case NS_HTML5TREE_BUILDER_IN_SELECT_IN_TABLE: {
   386                 NS_HTML5_BREAK(charactersloop);
   387               }
   388               case NS_HTML5TREE_BUILDER_AFTER_BODY: {
   389                 errNonSpaceAfterBody();
   391                 mode = framesetOk ? NS_HTML5TREE_BUILDER_FRAMESET_OK : NS_HTML5TREE_BUILDER_IN_BODY;
   392                 i--;
   393                 continue;
   394               }
   395               case NS_HTML5TREE_BUILDER_IN_FRAMESET: {
   396                 if (start < i) {
   397                   accumulateCharacters(buf, start, i - start);
   398                   start = i;
   399                 }
   400                 errNonSpaceInFrameset();
   401                 start = i + 1;
   402                 continue;
   403               }
   404               case NS_HTML5TREE_BUILDER_AFTER_FRAMESET: {
   405                 if (start < i) {
   406                   accumulateCharacters(buf, start, i - start);
   407                   start = i;
   408                 }
   409                 errNonSpaceAfterFrameset();
   410                 start = i + 1;
   411                 continue;
   412               }
   413               case NS_HTML5TREE_BUILDER_AFTER_AFTER_BODY: {
   414                 errNonSpaceInTrailer();
   415                 mode = framesetOk ? NS_HTML5TREE_BUILDER_FRAMESET_OK : NS_HTML5TREE_BUILDER_IN_BODY;
   416                 i--;
   417                 continue;
   418               }
   419               case NS_HTML5TREE_BUILDER_AFTER_AFTER_FRAMESET: {
   420                 errNonSpaceInTrailer();
   421                 mode = NS_HTML5TREE_BUILDER_IN_FRAMESET;
   422                 i--;
   423                 continue;
   424               }
   425             }
   426           }
   427         }
   428       }
   429       charactersloop_end: ;
   430       if (start < end) {
   431         accumulateCharacters(buf, start, end - start);
   432       }
   433     }
   434   }
   435 }
   437 void 
   438 nsHtml5TreeBuilder::zeroOriginatingReplacementCharacter()
   439 {
   440   if (mode == NS_HTML5TREE_BUILDER_TEXT) {
   441     accumulateCharacters(REPLACEMENT_CHARACTER, 0, 1);
   442     return;
   443   }
   444   if (currentPtr >= 0) {
   445     if (isSpecialParentInForeign(stack[currentPtr])) {
   446       return;
   447     }
   448     accumulateCharacters(REPLACEMENT_CHARACTER, 0, 1);
   449   }
   450 }
   452 void 
   453 nsHtml5TreeBuilder::eof()
   454 {
   455   flushCharacters();
   456   for (; ; ) {
   457     switch(mode) {
   458       case NS_HTML5TREE_BUILDER_INITIAL: {
   459         documentModeInternal(QUIRKS_MODE, nullptr, nullptr, false);
   460         mode = NS_HTML5TREE_BUILDER_BEFORE_HTML;
   461         continue;
   462       }
   463       case NS_HTML5TREE_BUILDER_BEFORE_HTML: {
   464         appendHtmlElementToDocumentAndPush();
   465         mode = NS_HTML5TREE_BUILDER_BEFORE_HEAD;
   466         continue;
   467       }
   468       case NS_HTML5TREE_BUILDER_BEFORE_HEAD: {
   469         appendToCurrentNodeAndPushHeadElement(nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES);
   470         mode = NS_HTML5TREE_BUILDER_IN_HEAD;
   471         continue;
   472       }
   473       case NS_HTML5TREE_BUILDER_IN_HEAD: {
   474         while (currentPtr > 0) {
   475           popOnEof();
   476         }
   477         mode = NS_HTML5TREE_BUILDER_AFTER_HEAD;
   478         continue;
   479       }
   480       case NS_HTML5TREE_BUILDER_IN_HEAD_NOSCRIPT: {
   481         while (currentPtr > 1) {
   482           popOnEof();
   483         }
   484         mode = NS_HTML5TREE_BUILDER_IN_HEAD;
   485         continue;
   486       }
   487       case NS_HTML5TREE_BUILDER_AFTER_HEAD: {
   488         appendToCurrentNodeAndPushBodyElement();
   489         mode = NS_HTML5TREE_BUILDER_IN_BODY;
   490         continue;
   491       }
   492       case NS_HTML5TREE_BUILDER_IN_TABLE_BODY:
   493       case NS_HTML5TREE_BUILDER_IN_ROW:
   494       case NS_HTML5TREE_BUILDER_IN_TABLE:
   495       case NS_HTML5TREE_BUILDER_IN_SELECT_IN_TABLE:
   496       case NS_HTML5TREE_BUILDER_IN_SELECT:
   497       case NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP:
   498       case NS_HTML5TREE_BUILDER_FRAMESET_OK:
   499       case NS_HTML5TREE_BUILDER_IN_CAPTION:
   500       case NS_HTML5TREE_BUILDER_IN_CELL:
   501       case NS_HTML5TREE_BUILDER_IN_BODY: {
   502         if (isTemplateModeStackEmpty()) {
   503           NS_HTML5_BREAK(eofloop);
   504         }
   505       }
   506       case NS_HTML5TREE_BUILDER_IN_TEMPLATE: {
   507         int32_t eltPos = findLast(nsHtml5Atoms::template_);
   508         if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
   509           MOZ_ASSERT(fragment);
   510           NS_HTML5_BREAK(eofloop);
   511         }
   512         if (MOZ_UNLIKELY(mViewSource)) {
   513           errUnclosedElements(eltPos, nsHtml5Atoms::template_);
   514         }
   515         while (currentPtr >= eltPos) {
   516           pop();
   517         }
   518         clearTheListOfActiveFormattingElementsUpToTheLastMarker();
   519         popTemplateMode();
   520         resetTheInsertionMode();
   521         continue;
   522       }
   523       case NS_HTML5TREE_BUILDER_TEXT: {
   524         if (originalMode == NS_HTML5TREE_BUILDER_AFTER_HEAD) {
   525           popOnEof();
   526         }
   527         popOnEof();
   528         mode = originalMode;
   529         continue;
   530       }
   531       case NS_HTML5TREE_BUILDER_IN_FRAMESET: {
   532         NS_HTML5_BREAK(eofloop);
   533       }
   534       case NS_HTML5TREE_BUILDER_AFTER_BODY:
   535       case NS_HTML5TREE_BUILDER_AFTER_FRAMESET:
   536       case NS_HTML5TREE_BUILDER_AFTER_AFTER_BODY:
   537       case NS_HTML5TREE_BUILDER_AFTER_AFTER_FRAMESET:
   538       default: {
   539         NS_HTML5_BREAK(eofloop);
   540       }
   541     }
   542   }
   543   eofloop_end: ;
   544   while (currentPtr > 0) {
   545     popOnEof();
   546   }
   547   if (!fragment) {
   548     popOnEof();
   549   }
   550 }
   552 void 
   553 nsHtml5TreeBuilder::endTokenization()
   554 {
   555   formPointer = nullptr;
   556   headPointer = nullptr;
   557   deepTreeSurrogateParent = nullptr;
   558   templateModeStack = nullptr;
   559   if (stack) {
   560     while (currentPtr > -1) {
   561       stack[currentPtr]->release();
   562       currentPtr--;
   563     }
   564     stack = nullptr;
   565   }
   566   if (listOfActiveFormattingElements) {
   567     while (listPtr > -1) {
   568       if (listOfActiveFormattingElements[listPtr]) {
   569         listOfActiveFormattingElements[listPtr]->release();
   570       }
   571       listPtr--;
   572     }
   573     listOfActiveFormattingElements = nullptr;
   574   }
   575   charBuffer = nullptr;
   576   end();
   577 }
   579 void 
   580 nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes, bool selfClosing)
   581 {
   582   flushCharacters();
   583   int32_t eltPos;
   584   needToDropLF = false;
   585   starttagloop: for (; ; ) {
   586     int32_t group = elementName->getGroup();
   587     nsIAtom* name = elementName->name;
   588     if (isInForeign()) {
   589       nsHtml5StackNode* currentNode = stack[currentPtr];
   590       int32_t currNs = currentNode->ns;
   591       if (!(currentNode->isHtmlIntegrationPoint() || (currNs == kNameSpaceID_MathML && ((currentNode->getGroup() == NS_HTML5TREE_BUILDER_MI_MO_MN_MS_MTEXT && group != NS_HTML5TREE_BUILDER_MGLYPH_OR_MALIGNMARK) || (currentNode->getGroup() == NS_HTML5TREE_BUILDER_ANNOTATION_XML && group == NS_HTML5TREE_BUILDER_SVG))))) {
   592         switch(group) {
   593           case NS_HTML5TREE_BUILDER_B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U:
   594           case NS_HTML5TREE_BUILDER_DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU:
   595           case NS_HTML5TREE_BUILDER_BODY:
   596           case NS_HTML5TREE_BUILDER_BR:
   597           case NS_HTML5TREE_BUILDER_RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR:
   598           case NS_HTML5TREE_BUILDER_DD_OR_DT:
   599           case NS_HTML5TREE_BUILDER_UL_OR_OL_OR_DL:
   600           case NS_HTML5TREE_BUILDER_EMBED:
   601           case NS_HTML5TREE_BUILDER_IMG:
   602           case NS_HTML5TREE_BUILDER_H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6:
   603           case NS_HTML5TREE_BUILDER_HEAD:
   604           case NS_HTML5TREE_BUILDER_HR:
   605           case NS_HTML5TREE_BUILDER_LI:
   606           case NS_HTML5TREE_BUILDER_META:
   607           case NS_HTML5TREE_BUILDER_NOBR:
   608           case NS_HTML5TREE_BUILDER_P:
   609           case NS_HTML5TREE_BUILDER_PRE_OR_LISTING:
   610           case NS_HTML5TREE_BUILDER_TABLE: {
   611             errHtmlStartTagInForeignContext(name);
   612             while (!isSpecialParentInForeign(stack[currentPtr])) {
   613               pop();
   614             }
   615             NS_HTML5_CONTINUE(starttagloop);
   616           }
   617           case NS_HTML5TREE_BUILDER_FONT: {
   618             if (attributes->contains(nsHtml5AttributeName::ATTR_COLOR) || attributes->contains(nsHtml5AttributeName::ATTR_FACE) || attributes->contains(nsHtml5AttributeName::ATTR_SIZE)) {
   619               errHtmlStartTagInForeignContext(name);
   620               while (!isSpecialParentInForeign(stack[currentPtr])) {
   621                 pop();
   622               }
   623               NS_HTML5_CONTINUE(starttagloop);
   624             }
   625           }
   626           default: {
   627             if (kNameSpaceID_SVG == currNs) {
   628               attributes->adjustForSvg();
   629               if (selfClosing) {
   630                 appendVoidElementToCurrentMayFosterSVG(elementName, attributes);
   631                 selfClosing = false;
   632               } else {
   633                 appendToCurrentNodeAndPushElementMayFosterSVG(elementName, attributes);
   634               }
   635               attributes = nullptr;
   636               NS_HTML5_BREAK(starttagloop);
   637             } else {
   638               attributes->adjustForMath();
   639               if (selfClosing) {
   640                 appendVoidElementToCurrentMayFosterMathML(elementName, attributes);
   641                 selfClosing = false;
   642               } else {
   643                 appendToCurrentNodeAndPushElementMayFosterMathML(elementName, attributes);
   644               }
   645               attributes = nullptr;
   646               NS_HTML5_BREAK(starttagloop);
   647             }
   648           }
   649         }
   650       }
   651     }
   652     switch(mode) {
   653       case NS_HTML5TREE_BUILDER_IN_TEMPLATE: {
   654         switch(group) {
   655           case NS_HTML5TREE_BUILDER_COL: {
   656             popTemplateMode();
   657             pushTemplateMode(NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP);
   658             mode = NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP;
   659             continue;
   660           }
   661           case NS_HTML5TREE_BUILDER_CAPTION:
   662           case NS_HTML5TREE_BUILDER_COLGROUP:
   663           case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT: {
   664             popTemplateMode();
   665             pushTemplateMode(NS_HTML5TREE_BUILDER_IN_TABLE);
   666             mode = NS_HTML5TREE_BUILDER_IN_TABLE;
   667             continue;
   668           }
   669           case NS_HTML5TREE_BUILDER_TR: {
   670             popTemplateMode();
   671             pushTemplateMode(NS_HTML5TREE_BUILDER_IN_TABLE_BODY);
   672             mode = NS_HTML5TREE_BUILDER_IN_TABLE_BODY;
   673             continue;
   674           }
   675           case NS_HTML5TREE_BUILDER_TD_OR_TH: {
   676             popTemplateMode();
   677             pushTemplateMode(NS_HTML5TREE_BUILDER_IN_ROW);
   678             mode = NS_HTML5TREE_BUILDER_IN_ROW;
   679             continue;
   680           }
   681           case NS_HTML5TREE_BUILDER_META: {
   682             checkMetaCharset(attributes);
   683             appendVoidElementToCurrentMayFoster(elementName, attributes);
   684             selfClosing = false;
   685             attributes = nullptr;
   686             NS_HTML5_BREAK(starttagloop);
   687           }
   688           case NS_HTML5TREE_BUILDER_TITLE: {
   689             startTagTitleInHead(elementName, attributes);
   690             attributes = nullptr;
   691             NS_HTML5_BREAK(starttagloop);
   692           }
   693           case NS_HTML5TREE_BUILDER_BASE:
   694           case NS_HTML5TREE_BUILDER_LINK_OR_BASEFONT_OR_BGSOUND: {
   695             appendVoidElementToCurrentMayFoster(elementName, attributes);
   696             selfClosing = false;
   697             attributes = nullptr;
   698             NS_HTML5_BREAK(starttagloop);
   699           }
   700           case NS_HTML5TREE_BUILDER_SCRIPT: {
   701             startTagScriptInHead(elementName, attributes);
   702             attributes = nullptr;
   703             NS_HTML5_BREAK(starttagloop);
   704           }
   705           case NS_HTML5TREE_BUILDER_NOFRAMES:
   706           case NS_HTML5TREE_BUILDER_STYLE: {
   707             startTagGenericRawText(elementName, attributes);
   708             attributes = nullptr;
   709             NS_HTML5_BREAK(starttagloop);
   710           }
   711           case NS_HTML5TREE_BUILDER_TEMPLATE: {
   712             startTagTemplateInHead(elementName, attributes);
   713             attributes = nullptr;
   714             NS_HTML5_BREAK(starttagloop);
   715           }
   716           default: {
   717             popTemplateMode();
   718             pushTemplateMode(NS_HTML5TREE_BUILDER_IN_BODY);
   719             mode = NS_HTML5TREE_BUILDER_IN_BODY;
   720             continue;
   721           }
   722         }
   723       }
   724       case NS_HTML5TREE_BUILDER_IN_ROW: {
   725         switch(group) {
   726           case NS_HTML5TREE_BUILDER_TD_OR_TH: {
   727             clearStackBackTo(findLastOrRoot(NS_HTML5TREE_BUILDER_TR));
   728             appendToCurrentNodeAndPushElement(elementName, attributes);
   729             mode = NS_HTML5TREE_BUILDER_IN_CELL;
   730             insertMarker();
   731             attributes = nullptr;
   732             NS_HTML5_BREAK(starttagloop);
   733           }
   734           case NS_HTML5TREE_BUILDER_CAPTION:
   735           case NS_HTML5TREE_BUILDER_COL:
   736           case NS_HTML5TREE_BUILDER_COLGROUP:
   737           case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT:
   738           case NS_HTML5TREE_BUILDER_TR: {
   739             eltPos = findLastOrRoot(NS_HTML5TREE_BUILDER_TR);
   740             if (!eltPos) {
   741               MOZ_ASSERT(fragment || isTemplateContents());
   742               errNoTableRowToClose();
   743               NS_HTML5_BREAK(starttagloop);
   744             }
   745             clearStackBackTo(eltPos);
   746             pop();
   747             mode = NS_HTML5TREE_BUILDER_IN_TABLE_BODY;
   748             continue;
   749           }
   750           default:
   751             ; // fall through
   752         }
   753       }
   754       case NS_HTML5TREE_BUILDER_IN_TABLE_BODY: {
   755         switch(group) {
   756           case NS_HTML5TREE_BUILDER_TR: {
   757             clearStackBackTo(findLastInTableScopeOrRootTemplateTbodyTheadTfoot());
   758             appendToCurrentNodeAndPushElement(elementName, attributes);
   759             mode = NS_HTML5TREE_BUILDER_IN_ROW;
   760             attributes = nullptr;
   761             NS_HTML5_BREAK(starttagloop);
   762           }
   763           case NS_HTML5TREE_BUILDER_TD_OR_TH: {
   764             errStartTagInTableBody(name);
   765             clearStackBackTo(findLastInTableScopeOrRootTemplateTbodyTheadTfoot());
   766             appendToCurrentNodeAndPushElement(nsHtml5ElementName::ELT_TR, nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES);
   767             mode = NS_HTML5TREE_BUILDER_IN_ROW;
   768             continue;
   769           }
   770           case NS_HTML5TREE_BUILDER_CAPTION:
   771           case NS_HTML5TREE_BUILDER_COL:
   772           case NS_HTML5TREE_BUILDER_COLGROUP:
   773           case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT: {
   774             eltPos = findLastInTableScopeOrRootTemplateTbodyTheadTfoot();
   775             if (!eltPos || stack[eltPos]->getGroup() == NS_HTML5TREE_BUILDER_TEMPLATE) {
   776               MOZ_ASSERT(fragment || isTemplateContents());
   777               errStrayStartTag(name);
   778               NS_HTML5_BREAK(starttagloop);
   779             } else {
   780               clearStackBackTo(eltPos);
   781               pop();
   782               mode = NS_HTML5TREE_BUILDER_IN_TABLE;
   783               continue;
   784             }
   785           }
   786           default:
   787             ; // fall through
   788         }
   789       }
   790       case NS_HTML5TREE_BUILDER_IN_TABLE: {
   791         for (; ; ) {
   792           switch(group) {
   793             case NS_HTML5TREE_BUILDER_CAPTION: {
   794               clearStackBackTo(findLastOrRoot(NS_HTML5TREE_BUILDER_TABLE));
   795               insertMarker();
   796               appendToCurrentNodeAndPushElement(elementName, attributes);
   797               mode = NS_HTML5TREE_BUILDER_IN_CAPTION;
   798               attributes = nullptr;
   799               NS_HTML5_BREAK(starttagloop);
   800             }
   801             case NS_HTML5TREE_BUILDER_COLGROUP: {
   802               clearStackBackTo(findLastOrRoot(NS_HTML5TREE_BUILDER_TABLE));
   803               appendToCurrentNodeAndPushElement(elementName, attributes);
   804               mode = NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP;
   805               attributes = nullptr;
   806               NS_HTML5_BREAK(starttagloop);
   807             }
   808             case NS_HTML5TREE_BUILDER_COL: {
   809               clearStackBackTo(findLastOrRoot(NS_HTML5TREE_BUILDER_TABLE));
   810               appendToCurrentNodeAndPushElement(nsHtml5ElementName::ELT_COLGROUP, nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES);
   811               mode = NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP;
   812               NS_HTML5_CONTINUE(starttagloop);
   813             }
   814             case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT: {
   815               clearStackBackTo(findLastOrRoot(NS_HTML5TREE_BUILDER_TABLE));
   816               appendToCurrentNodeAndPushElement(elementName, attributes);
   817               mode = NS_HTML5TREE_BUILDER_IN_TABLE_BODY;
   818               attributes = nullptr;
   819               NS_HTML5_BREAK(starttagloop);
   820             }
   821             case NS_HTML5TREE_BUILDER_TR:
   822             case NS_HTML5TREE_BUILDER_TD_OR_TH: {
   823               clearStackBackTo(findLastOrRoot(NS_HTML5TREE_BUILDER_TABLE));
   824               appendToCurrentNodeAndPushElement(nsHtml5ElementName::ELT_TBODY, nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES);
   825               mode = NS_HTML5TREE_BUILDER_IN_TABLE_BODY;
   826               NS_HTML5_CONTINUE(starttagloop);
   827             }
   828             case NS_HTML5TREE_BUILDER_TEMPLATE: {
   829               NS_HTML5_BREAK(intableloop);
   830             }
   831             case NS_HTML5TREE_BUILDER_TABLE: {
   832               errTableSeenWhileTableOpen();
   833               eltPos = findLastInTableScope(name);
   834               if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
   835                 MOZ_ASSERT(fragment || isTemplateContents());
   836                 NS_HTML5_BREAK(starttagloop);
   837               }
   838               generateImpliedEndTags();
   839               if (!!MOZ_UNLIKELY(mViewSource) && !isCurrent(nsHtml5Atoms::table)) {
   840                 errNoCheckUnclosedElementsOnStack();
   841               }
   842               while (currentPtr >= eltPos) {
   843                 pop();
   844               }
   845               resetTheInsertionMode();
   846               NS_HTML5_CONTINUE(starttagloop);
   847             }
   848             case NS_HTML5TREE_BUILDER_SCRIPT: {
   849               appendToCurrentNodeAndPushElement(elementName, attributes);
   850               originalMode = mode;
   851               mode = NS_HTML5TREE_BUILDER_TEXT;
   852               tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_SCRIPT_DATA, elementName);
   853               attributes = nullptr;
   854               NS_HTML5_BREAK(starttagloop);
   855             }
   856             case NS_HTML5TREE_BUILDER_STYLE: {
   857               appendToCurrentNodeAndPushElement(elementName, attributes);
   858               originalMode = mode;
   859               mode = NS_HTML5TREE_BUILDER_TEXT;
   860               tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_RAWTEXT, elementName);
   861               attributes = nullptr;
   862               NS_HTML5_BREAK(starttagloop);
   863             }
   864             case NS_HTML5TREE_BUILDER_INPUT: {
   865               errStartTagInTable(name);
   866               if (!nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("hidden", attributes->getValue(nsHtml5AttributeName::ATTR_TYPE))) {
   867                 NS_HTML5_BREAK(intableloop);
   868               }
   869               appendVoidElementToCurrent(name, attributes, formPointer);
   870               selfClosing = false;
   871               attributes = nullptr;
   872               NS_HTML5_BREAK(starttagloop);
   873             }
   874             case NS_HTML5TREE_BUILDER_FORM: {
   875               if (!!formPointer || isTemplateContents()) {
   876                 errFormWhenFormOpen();
   877                 NS_HTML5_BREAK(starttagloop);
   878               } else {
   879                 errStartTagInTable(name);
   880                 appendVoidFormToCurrent(attributes);
   881                 attributes = nullptr;
   882                 NS_HTML5_BREAK(starttagloop);
   883               }
   884             }
   885             default: {
   886               errStartTagInTable(name);
   887               NS_HTML5_BREAK(intableloop);
   888             }
   889           }
   890         }
   891         intableloop_end: ;
   892       }
   893       case NS_HTML5TREE_BUILDER_IN_CAPTION: {
   894         switch(group) {
   895           case NS_HTML5TREE_BUILDER_CAPTION:
   896           case NS_HTML5TREE_BUILDER_COL:
   897           case NS_HTML5TREE_BUILDER_COLGROUP:
   898           case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT:
   899           case NS_HTML5TREE_BUILDER_TR:
   900           case NS_HTML5TREE_BUILDER_TD_OR_TH: {
   901             errStrayStartTag(name);
   902             eltPos = findLastInTableScope(nsHtml5Atoms::caption);
   903             if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
   904               NS_HTML5_BREAK(starttagloop);
   905             }
   906             generateImpliedEndTags();
   907             if (!!MOZ_UNLIKELY(mViewSource) && currentPtr != eltPos) {
   908               errNoCheckUnclosedElementsOnStack();
   909             }
   910             while (currentPtr >= eltPos) {
   911               pop();
   912             }
   913             clearTheListOfActiveFormattingElementsUpToTheLastMarker();
   914             mode = NS_HTML5TREE_BUILDER_IN_TABLE;
   915             continue;
   916           }
   917           default:
   918             ; // fall through
   919         }
   920       }
   921       case NS_HTML5TREE_BUILDER_IN_CELL: {
   922         switch(group) {
   923           case NS_HTML5TREE_BUILDER_CAPTION:
   924           case NS_HTML5TREE_BUILDER_COL:
   925           case NS_HTML5TREE_BUILDER_COLGROUP:
   926           case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT:
   927           case NS_HTML5TREE_BUILDER_TR:
   928           case NS_HTML5TREE_BUILDER_TD_OR_TH: {
   929             eltPos = findLastInTableScopeTdTh();
   930             if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
   931               errNoCellToClose();
   932               NS_HTML5_BREAK(starttagloop);
   933             } else {
   934               closeTheCell(eltPos);
   935               continue;
   936             }
   937           }
   938           default:
   939             ; // fall through
   940         }
   941       }
   942       case NS_HTML5TREE_BUILDER_FRAMESET_OK: {
   943         switch(group) {
   944           case NS_HTML5TREE_BUILDER_FRAMESET: {
   945             if (mode == NS_HTML5TREE_BUILDER_FRAMESET_OK) {
   946               if (!currentPtr || stack[1]->getGroup() != NS_HTML5TREE_BUILDER_BODY) {
   947                 MOZ_ASSERT(fragment || isTemplateContents());
   948                 errStrayStartTag(name);
   949                 NS_HTML5_BREAK(starttagloop);
   950               } else {
   951                 errFramesetStart();
   952                 detachFromParent(stack[1]->node);
   953                 while (currentPtr > 0) {
   954                   pop();
   955                 }
   956                 appendToCurrentNodeAndPushElement(elementName, attributes);
   957                 mode = NS_HTML5TREE_BUILDER_IN_FRAMESET;
   958                 attributes = nullptr;
   959                 NS_HTML5_BREAK(starttagloop);
   960               }
   961             } else {
   962               errStrayStartTag(name);
   963               NS_HTML5_BREAK(starttagloop);
   964             }
   965           }
   966           case NS_HTML5TREE_BUILDER_PRE_OR_LISTING:
   967           case NS_HTML5TREE_BUILDER_LI:
   968           case NS_HTML5TREE_BUILDER_DD_OR_DT:
   969           case NS_HTML5TREE_BUILDER_BUTTON:
   970           case NS_HTML5TREE_BUILDER_MARQUEE_OR_APPLET:
   971           case NS_HTML5TREE_BUILDER_OBJECT:
   972           case NS_HTML5TREE_BUILDER_TABLE:
   973           case NS_HTML5TREE_BUILDER_AREA_OR_WBR:
   974           case NS_HTML5TREE_BUILDER_BR:
   975           case NS_HTML5TREE_BUILDER_EMBED:
   976           case NS_HTML5TREE_BUILDER_IMG:
   977           case NS_HTML5TREE_BUILDER_INPUT:
   978           case NS_HTML5TREE_BUILDER_KEYGEN:
   979           case NS_HTML5TREE_BUILDER_HR:
   980           case NS_HTML5TREE_BUILDER_TEXTAREA:
   981           case NS_HTML5TREE_BUILDER_XMP:
   982           case NS_HTML5TREE_BUILDER_IFRAME:
   983           case NS_HTML5TREE_BUILDER_SELECT: {
   984             if (mode == NS_HTML5TREE_BUILDER_FRAMESET_OK && !(group == NS_HTML5TREE_BUILDER_INPUT && nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("hidden", attributes->getValue(nsHtml5AttributeName::ATTR_TYPE)))) {
   985               framesetOk = false;
   986               mode = NS_HTML5TREE_BUILDER_IN_BODY;
   987             }
   988           }
   989           default:
   990             ; // fall through
   991         }
   992       }
   993       case NS_HTML5TREE_BUILDER_IN_BODY: {
   994         for (; ; ) {
   995           switch(group) {
   996             case NS_HTML5TREE_BUILDER_HTML: {
   997               errStrayStartTag(name);
   998               if (!fragment && !isTemplateContents()) {
   999                 addAttributesToHtml(attributes);
  1000                 attributes = nullptr;
  1002               NS_HTML5_BREAK(starttagloop);
  1004             case NS_HTML5TREE_BUILDER_BASE:
  1005             case NS_HTML5TREE_BUILDER_LINK_OR_BASEFONT_OR_BGSOUND:
  1006             case NS_HTML5TREE_BUILDER_META:
  1007             case NS_HTML5TREE_BUILDER_STYLE:
  1008             case NS_HTML5TREE_BUILDER_SCRIPT:
  1009             case NS_HTML5TREE_BUILDER_TITLE:
  1010             case NS_HTML5TREE_BUILDER_TEMPLATE: {
  1011               NS_HTML5_BREAK(inbodyloop);
  1013             case NS_HTML5TREE_BUILDER_BODY: {
  1014               if (!currentPtr || stack[1]->getGroup() != NS_HTML5TREE_BUILDER_BODY || isTemplateContents()) {
  1015                 MOZ_ASSERT(fragment || isTemplateContents());
  1016                 errStrayStartTag(name);
  1017                 NS_HTML5_BREAK(starttagloop);
  1019               errFooSeenWhenFooOpen(name);
  1020               framesetOk = false;
  1021               if (mode == NS_HTML5TREE_BUILDER_FRAMESET_OK) {
  1022                 mode = NS_HTML5TREE_BUILDER_IN_BODY;
  1024               if (addAttributesToBody(attributes)) {
  1025                 attributes = nullptr;
  1027               NS_HTML5_BREAK(starttagloop);
  1029             case NS_HTML5TREE_BUILDER_P:
  1030             case NS_HTML5TREE_BUILDER_DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU:
  1031             case NS_HTML5TREE_BUILDER_UL_OR_OL_OR_DL:
  1032             case NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY: {
  1033               implicitlyCloseP();
  1034               appendToCurrentNodeAndPushElementMayFoster(elementName, attributes);
  1035               attributes = nullptr;
  1036               NS_HTML5_BREAK(starttagloop);
  1038             case NS_HTML5TREE_BUILDER_H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6: {
  1039               implicitlyCloseP();
  1040               if (stack[currentPtr]->getGroup() == NS_HTML5TREE_BUILDER_H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6) {
  1041                 errHeadingWhenHeadingOpen();
  1042                 pop();
  1044               appendToCurrentNodeAndPushElementMayFoster(elementName, attributes);
  1045               attributes = nullptr;
  1046               NS_HTML5_BREAK(starttagloop);
  1048             case NS_HTML5TREE_BUILDER_FIELDSET: {
  1049               implicitlyCloseP();
  1050               appendToCurrentNodeAndPushElementMayFoster(elementName, attributes, formPointer);
  1051               attributes = nullptr;
  1052               NS_HTML5_BREAK(starttagloop);
  1054             case NS_HTML5TREE_BUILDER_PRE_OR_LISTING: {
  1055               implicitlyCloseP();
  1056               appendToCurrentNodeAndPushElementMayFoster(elementName, attributes);
  1057               needToDropLF = true;
  1058               attributes = nullptr;
  1059               NS_HTML5_BREAK(starttagloop);
  1061             case NS_HTML5TREE_BUILDER_FORM: {
  1062               if (!!formPointer && !isTemplateContents()) {
  1063                 errFormWhenFormOpen();
  1064                 NS_HTML5_BREAK(starttagloop);
  1065               } else {
  1066                 implicitlyCloseP();
  1067                 appendToCurrentNodeAndPushFormElementMayFoster(attributes);
  1068                 attributes = nullptr;
  1069                 NS_HTML5_BREAK(starttagloop);
  1072             case NS_HTML5TREE_BUILDER_LI:
  1073             case NS_HTML5TREE_BUILDER_DD_OR_DT: {
  1074               eltPos = currentPtr;
  1075               for (; ; ) {
  1076                 nsHtml5StackNode* node = stack[eltPos];
  1077                 if (node->getGroup() == group) {
  1078                   generateImpliedEndTagsExceptFor(node->name);
  1079                   if (!!MOZ_UNLIKELY(mViewSource) && eltPos != currentPtr) {
  1080                     errUnclosedElementsImplied(eltPos, name);
  1082                   while (currentPtr >= eltPos) {
  1083                     pop();
  1085                   break;
  1086                 } else if (node->isSpecial() && (node->ns != kNameSpaceID_XHTML || (node->name != nsHtml5Atoms::p && node->name != nsHtml5Atoms::address && node->name != nsHtml5Atoms::div))) {
  1087                   break;
  1089                 eltPos--;
  1091               implicitlyCloseP();
  1092               appendToCurrentNodeAndPushElementMayFoster(elementName, attributes);
  1093               attributes = nullptr;
  1094               NS_HTML5_BREAK(starttagloop);
  1096             case NS_HTML5TREE_BUILDER_PLAINTEXT: {
  1097               implicitlyCloseP();
  1098               appendToCurrentNodeAndPushElementMayFoster(elementName, attributes);
  1099               tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_PLAINTEXT, elementName);
  1100               attributes = nullptr;
  1101               NS_HTML5_BREAK(starttagloop);
  1103             case NS_HTML5TREE_BUILDER_A: {
  1104               int32_t activeAPos = findInListOfActiveFormattingElementsContainsBetweenEndAndLastMarker(nsHtml5Atoms::a);
  1105               if (activeAPos != -1) {
  1106                 errFooSeenWhenFooOpen(name);
  1107                 nsHtml5StackNode* activeA = listOfActiveFormattingElements[activeAPos];
  1108                 activeA->retain();
  1109                 adoptionAgencyEndTag(nsHtml5Atoms::a);
  1110                 removeFromStack(activeA);
  1111                 activeAPos = findInListOfActiveFormattingElements(activeA);
  1112                 if (activeAPos != -1) {
  1113                   removeFromListOfActiveFormattingElements(activeAPos);
  1115                 activeA->release();
  1117               reconstructTheActiveFormattingElements();
  1118               appendToCurrentNodeAndPushFormattingElementMayFoster(elementName, attributes);
  1119               attributes = nullptr;
  1120               NS_HTML5_BREAK(starttagloop);
  1122             case NS_HTML5TREE_BUILDER_B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U:
  1123             case NS_HTML5TREE_BUILDER_FONT: {
  1124               reconstructTheActiveFormattingElements();
  1125               maybeForgetEarlierDuplicateFormattingElement(elementName->name, attributes);
  1126               appendToCurrentNodeAndPushFormattingElementMayFoster(elementName, attributes);
  1127               attributes = nullptr;
  1128               NS_HTML5_BREAK(starttagloop);
  1130             case NS_HTML5TREE_BUILDER_NOBR: {
  1131               reconstructTheActiveFormattingElements();
  1132               if (NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK != findLastInScope(nsHtml5Atoms::nobr)) {
  1133                 errFooSeenWhenFooOpen(name);
  1134                 adoptionAgencyEndTag(nsHtml5Atoms::nobr);
  1135                 reconstructTheActiveFormattingElements();
  1137               appendToCurrentNodeAndPushFormattingElementMayFoster(elementName, attributes);
  1138               attributes = nullptr;
  1139               NS_HTML5_BREAK(starttagloop);
  1141             case NS_HTML5TREE_BUILDER_BUTTON: {
  1142               eltPos = findLastInScope(name);
  1143               if (eltPos != NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
  1144                 errFooSeenWhenFooOpen(name);
  1145                 generateImpliedEndTags();
  1146                 if (!!MOZ_UNLIKELY(mViewSource) && !isCurrent(name)) {
  1147                   errUnclosedElementsImplied(eltPos, name);
  1149                 while (currentPtr >= eltPos) {
  1150                   pop();
  1152                 NS_HTML5_CONTINUE(starttagloop);
  1153               } else {
  1154                 reconstructTheActiveFormattingElements();
  1155                 appendToCurrentNodeAndPushElementMayFoster(elementName, attributes, formPointer);
  1156                 attributes = nullptr;
  1157                 NS_HTML5_BREAK(starttagloop);
  1160             case NS_HTML5TREE_BUILDER_OBJECT: {
  1161               reconstructTheActiveFormattingElements();
  1162               appendToCurrentNodeAndPushElementMayFoster(elementName, attributes, formPointer);
  1163               insertMarker();
  1164               attributes = nullptr;
  1165               NS_HTML5_BREAK(starttagloop);
  1167             case NS_HTML5TREE_BUILDER_MARQUEE_OR_APPLET: {
  1168               reconstructTheActiveFormattingElements();
  1169               appendToCurrentNodeAndPushElementMayFoster(elementName, attributes);
  1170               insertMarker();
  1171               attributes = nullptr;
  1172               NS_HTML5_BREAK(starttagloop);
  1174             case NS_HTML5TREE_BUILDER_TABLE: {
  1175               if (!quirks) {
  1176                 implicitlyCloseP();
  1178               appendToCurrentNodeAndPushElementMayFoster(elementName, attributes);
  1179               mode = NS_HTML5TREE_BUILDER_IN_TABLE;
  1180               attributes = nullptr;
  1181               NS_HTML5_BREAK(starttagloop);
  1183             case NS_HTML5TREE_BUILDER_BR:
  1184             case NS_HTML5TREE_BUILDER_EMBED:
  1185             case NS_HTML5TREE_BUILDER_AREA_OR_WBR: {
  1186               reconstructTheActiveFormattingElements();
  1188 #ifdef ENABLE_VOID_MENUITEM
  1189             case NS_HTML5TREE_BUILDER_MENUITEM:
  1190 #endif
  1191             case NS_HTML5TREE_BUILDER_PARAM_OR_SOURCE_OR_TRACK: {
  1192               appendVoidElementToCurrentMayFoster(elementName, attributes);
  1193               selfClosing = false;
  1194               attributes = nullptr;
  1195               NS_HTML5_BREAK(starttagloop);
  1197             case NS_HTML5TREE_BUILDER_HR: {
  1198               implicitlyCloseP();
  1199               appendVoidElementToCurrentMayFoster(elementName, attributes);
  1200               selfClosing = false;
  1201               attributes = nullptr;
  1202               NS_HTML5_BREAK(starttagloop);
  1204             case NS_HTML5TREE_BUILDER_IMAGE: {
  1205               errImage();
  1206               elementName = nsHtml5ElementName::ELT_IMG;
  1207               NS_HTML5_CONTINUE(starttagloop);
  1209             case NS_HTML5TREE_BUILDER_IMG:
  1210             case NS_HTML5TREE_BUILDER_KEYGEN:
  1211             case NS_HTML5TREE_BUILDER_INPUT: {
  1212               reconstructTheActiveFormattingElements();
  1213               appendVoidElementToCurrentMayFoster(name, attributes, formPointer);
  1214               selfClosing = false;
  1215               attributes = nullptr;
  1216               NS_HTML5_BREAK(starttagloop);
  1218             case NS_HTML5TREE_BUILDER_ISINDEX: {
  1219               errIsindex();
  1220               if (!!formPointer && !isTemplateContents()) {
  1221                 NS_HTML5_BREAK(starttagloop);
  1223               implicitlyCloseP();
  1224               nsHtml5HtmlAttributes* formAttrs = new nsHtml5HtmlAttributes(0);
  1225               int32_t actionIndex = attributes->getIndex(nsHtml5AttributeName::ATTR_ACTION);
  1226               if (actionIndex > -1) {
  1227                 formAttrs->addAttribute(nsHtml5AttributeName::ATTR_ACTION, attributes->getValueNoBoundsCheck(actionIndex));
  1229               appendToCurrentNodeAndPushFormElementMayFoster(formAttrs);
  1230               appendVoidElementToCurrentMayFoster(nsHtml5ElementName::ELT_HR, nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES);
  1231               appendToCurrentNodeAndPushElementMayFoster(nsHtml5ElementName::ELT_LABEL, nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES);
  1232               int32_t promptIndex = attributes->getIndex(nsHtml5AttributeName::ATTR_PROMPT);
  1233               if (promptIndex > -1) {
  1234                 autoJArray<char16_t,int32_t> prompt = nsHtml5Portability::newCharArrayFromString(attributes->getValueNoBoundsCheck(promptIndex));
  1235                 appendCharacters(stack[currentPtr]->node, prompt, 0, prompt.length);
  1236               } else {
  1237                 appendIsindexPrompt(stack[currentPtr]->node);
  1239               nsHtml5HtmlAttributes* inputAttributes = new nsHtml5HtmlAttributes(0);
  1240               inputAttributes->addAttribute(nsHtml5AttributeName::ATTR_NAME, nsHtml5Portability::newStringFromLiteral("isindex"));
  1241               for (int32_t i = 0; i < attributes->getLength(); i++) {
  1242                 nsHtml5AttributeName* attributeQName = attributes->getAttributeNameNoBoundsCheck(i);
  1243                 if (nsHtml5AttributeName::ATTR_NAME == attributeQName || nsHtml5AttributeName::ATTR_PROMPT == attributeQName) {
  1244                   attributes->releaseValue(i);
  1245                 } else if (nsHtml5AttributeName::ATTR_ACTION != attributeQName) {
  1246                   inputAttributes->addAttribute(attributeQName, attributes->getValueNoBoundsCheck(i));
  1249               attributes->clearWithoutReleasingContents();
  1250               appendVoidElementToCurrentMayFoster(nsHtml5Atoms::input, inputAttributes, formPointer);
  1251               pop();
  1252               appendVoidElementToCurrentMayFoster(nsHtml5ElementName::ELT_HR, nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES);
  1253               pop();
  1254               if (!isTemplateContents()) {
  1255                 formPointer = nullptr;
  1257               selfClosing = false;
  1258               NS_HTML5_BREAK(starttagloop);
  1260             case NS_HTML5TREE_BUILDER_TEXTAREA: {
  1261               appendToCurrentNodeAndPushElementMayFoster(elementName, attributes, formPointer);
  1262               tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_RCDATA, elementName);
  1263               originalMode = mode;
  1264               mode = NS_HTML5TREE_BUILDER_TEXT;
  1265               needToDropLF = true;
  1266               attributes = nullptr;
  1267               NS_HTML5_BREAK(starttagloop);
  1269             case NS_HTML5TREE_BUILDER_XMP: {
  1270               implicitlyCloseP();
  1271               reconstructTheActiveFormattingElements();
  1272               appendToCurrentNodeAndPushElementMayFoster(elementName, attributes);
  1273               originalMode = mode;
  1274               mode = NS_HTML5TREE_BUILDER_TEXT;
  1275               tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_RAWTEXT, elementName);
  1276               attributes = nullptr;
  1277               NS_HTML5_BREAK(starttagloop);
  1279             case NS_HTML5TREE_BUILDER_NOSCRIPT: {
  1280               if (!scriptingEnabled) {
  1281                 reconstructTheActiveFormattingElements();
  1282                 appendToCurrentNodeAndPushElementMayFoster(elementName, attributes);
  1283                 attributes = nullptr;
  1284                 NS_HTML5_BREAK(starttagloop);
  1285               } else {
  1288             case NS_HTML5TREE_BUILDER_NOFRAMES:
  1289             case NS_HTML5TREE_BUILDER_IFRAME:
  1290             case NS_HTML5TREE_BUILDER_NOEMBED: {
  1291               startTagGenericRawText(elementName, attributes);
  1292               attributes = nullptr;
  1293               NS_HTML5_BREAK(starttagloop);
  1295             case NS_HTML5TREE_BUILDER_SELECT: {
  1296               reconstructTheActiveFormattingElements();
  1297               appendToCurrentNodeAndPushElementMayFoster(elementName, attributes, formPointer);
  1298               switch(mode) {
  1299                 case NS_HTML5TREE_BUILDER_IN_TABLE:
  1300                 case NS_HTML5TREE_BUILDER_IN_CAPTION:
  1301                 case NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP:
  1302                 case NS_HTML5TREE_BUILDER_IN_TABLE_BODY:
  1303                 case NS_HTML5TREE_BUILDER_IN_ROW:
  1304                 case NS_HTML5TREE_BUILDER_IN_CELL: {
  1305                   mode = NS_HTML5TREE_BUILDER_IN_SELECT_IN_TABLE;
  1306                   break;
  1308                 default: {
  1309                   mode = NS_HTML5TREE_BUILDER_IN_SELECT;
  1310                   break;
  1313               attributes = nullptr;
  1314               NS_HTML5_BREAK(starttagloop);
  1316             case NS_HTML5TREE_BUILDER_OPTGROUP:
  1317             case NS_HTML5TREE_BUILDER_OPTION: {
  1318               if (isCurrent(nsHtml5Atoms::option)) {
  1319                 pop();
  1321               reconstructTheActiveFormattingElements();
  1322               appendToCurrentNodeAndPushElementMayFoster(elementName, attributes);
  1323               attributes = nullptr;
  1324               NS_HTML5_BREAK(starttagloop);
  1326             case NS_HTML5TREE_BUILDER_RT_OR_RP: {
  1327               eltPos = findLastInScope(nsHtml5Atoms::ruby);
  1328               if (eltPos != NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
  1329                 generateImpliedEndTags();
  1331               if (eltPos != currentPtr) {
  1332                 if (eltPos != NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
  1333                   errStartTagSeenWithoutRuby(name);
  1334                 } else {
  1335                   errUnclosedChildrenInRuby();
  1338               appendToCurrentNodeAndPushElementMayFoster(elementName, attributes);
  1339               attributes = nullptr;
  1340               NS_HTML5_BREAK(starttagloop);
  1342             case NS_HTML5TREE_BUILDER_MATH: {
  1343               reconstructTheActiveFormattingElements();
  1344               attributes->adjustForMath();
  1345               if (selfClosing) {
  1346                 appendVoidElementToCurrentMayFosterMathML(elementName, attributes);
  1347                 selfClosing = false;
  1348               } else {
  1349                 appendToCurrentNodeAndPushElementMayFosterMathML(elementName, attributes);
  1351               attributes = nullptr;
  1352               NS_HTML5_BREAK(starttagloop);
  1354             case NS_HTML5TREE_BUILDER_SVG: {
  1355               reconstructTheActiveFormattingElements();
  1356               attributes->adjustForSvg();
  1357               if (selfClosing) {
  1358                 appendVoidElementToCurrentMayFosterSVG(elementName, attributes);
  1359                 selfClosing = false;
  1360               } else {
  1361                 appendToCurrentNodeAndPushElementMayFosterSVG(elementName, attributes);
  1363               attributes = nullptr;
  1364               NS_HTML5_BREAK(starttagloop);
  1366             case NS_HTML5TREE_BUILDER_CAPTION:
  1367             case NS_HTML5TREE_BUILDER_COL:
  1368             case NS_HTML5TREE_BUILDER_COLGROUP:
  1369             case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT:
  1370             case NS_HTML5TREE_BUILDER_TR:
  1371             case NS_HTML5TREE_BUILDER_TD_OR_TH:
  1372             case NS_HTML5TREE_BUILDER_FRAME:
  1373             case NS_HTML5TREE_BUILDER_FRAMESET:
  1374             case NS_HTML5TREE_BUILDER_HEAD: {
  1375               errStrayStartTag(name);
  1376               NS_HTML5_BREAK(starttagloop);
  1378             case NS_HTML5TREE_BUILDER_OUTPUT_OR_LABEL: {
  1379               reconstructTheActiveFormattingElements();
  1380               appendToCurrentNodeAndPushElementMayFoster(elementName, attributes, formPointer);
  1381               attributes = nullptr;
  1382               NS_HTML5_BREAK(starttagloop);
  1384             default: {
  1385               reconstructTheActiveFormattingElements();
  1386               appendToCurrentNodeAndPushElementMayFoster(elementName, attributes);
  1387               attributes = nullptr;
  1388               NS_HTML5_BREAK(starttagloop);
  1392         inbodyloop_end: ;
  1394       case NS_HTML5TREE_BUILDER_IN_HEAD: {
  1395         for (; ; ) {
  1396           switch(group) {
  1397             case NS_HTML5TREE_BUILDER_HTML: {
  1398               errStrayStartTag(name);
  1399               if (!fragment && !isTemplateContents()) {
  1400                 addAttributesToHtml(attributes);
  1401                 attributes = nullptr;
  1403               NS_HTML5_BREAK(starttagloop);
  1405             case NS_HTML5TREE_BUILDER_BASE:
  1406             case NS_HTML5TREE_BUILDER_LINK_OR_BASEFONT_OR_BGSOUND: {
  1407               appendVoidElementToCurrentMayFoster(elementName, attributes);
  1408               selfClosing = false;
  1409               attributes = nullptr;
  1410               NS_HTML5_BREAK(starttagloop);
  1412             case NS_HTML5TREE_BUILDER_META: {
  1413               NS_HTML5_BREAK(inheadloop);
  1415             case NS_HTML5TREE_BUILDER_TITLE: {
  1416               startTagTitleInHead(elementName, attributes);
  1417               attributes = nullptr;
  1418               NS_HTML5_BREAK(starttagloop);
  1420             case NS_HTML5TREE_BUILDER_NOSCRIPT: {
  1421               if (scriptingEnabled) {
  1422                 appendToCurrentNodeAndPushElement(elementName, attributes);
  1423                 originalMode = mode;
  1424                 mode = NS_HTML5TREE_BUILDER_TEXT;
  1425                 tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_RAWTEXT, elementName);
  1426               } else {
  1427                 appendToCurrentNodeAndPushElementMayFoster(elementName, attributes);
  1428                 mode = NS_HTML5TREE_BUILDER_IN_HEAD_NOSCRIPT;
  1430               attributes = nullptr;
  1431               NS_HTML5_BREAK(starttagloop);
  1433             case NS_HTML5TREE_BUILDER_SCRIPT: {
  1434               startTagScriptInHead(elementName, attributes);
  1435               attributes = nullptr;
  1436               NS_HTML5_BREAK(starttagloop);
  1438             case NS_HTML5TREE_BUILDER_STYLE:
  1439             case NS_HTML5TREE_BUILDER_NOFRAMES: {
  1440               startTagGenericRawText(elementName, attributes);
  1441               attributes = nullptr;
  1442               NS_HTML5_BREAK(starttagloop);
  1444             case NS_HTML5TREE_BUILDER_HEAD: {
  1445               errFooSeenWhenFooOpen(name);
  1446               NS_HTML5_BREAK(starttagloop);
  1448             case NS_HTML5TREE_BUILDER_TEMPLATE: {
  1449               startTagTemplateInHead(elementName, attributes);
  1450               attributes = nullptr;
  1451               NS_HTML5_BREAK(starttagloop);
  1453             default: {
  1454               pop();
  1455               mode = NS_HTML5TREE_BUILDER_AFTER_HEAD;
  1456               NS_HTML5_CONTINUE(starttagloop);
  1460         inheadloop_end: ;
  1462       case NS_HTML5TREE_BUILDER_IN_HEAD_NOSCRIPT: {
  1463         switch(group) {
  1464           case NS_HTML5TREE_BUILDER_HTML: {
  1465             errStrayStartTag(name);
  1466             if (!fragment && !isTemplateContents()) {
  1467               addAttributesToHtml(attributes);
  1468               attributes = nullptr;
  1470             NS_HTML5_BREAK(starttagloop);
  1472           case NS_HTML5TREE_BUILDER_LINK_OR_BASEFONT_OR_BGSOUND: {
  1473             appendVoidElementToCurrentMayFoster(elementName, attributes);
  1474             selfClosing = false;
  1475             attributes = nullptr;
  1476             NS_HTML5_BREAK(starttagloop);
  1478           case NS_HTML5TREE_BUILDER_META: {
  1479             checkMetaCharset(attributes);
  1480             appendVoidElementToCurrentMayFoster(elementName, attributes);
  1481             selfClosing = false;
  1482             attributes = nullptr;
  1483             NS_HTML5_BREAK(starttagloop);
  1485           case NS_HTML5TREE_BUILDER_STYLE:
  1486           case NS_HTML5TREE_BUILDER_NOFRAMES: {
  1487             appendToCurrentNodeAndPushElement(elementName, attributes);
  1488             originalMode = mode;
  1489             mode = NS_HTML5TREE_BUILDER_TEXT;
  1490             tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_RAWTEXT, elementName);
  1491             attributes = nullptr;
  1492             NS_HTML5_BREAK(starttagloop);
  1494           case NS_HTML5TREE_BUILDER_HEAD: {
  1495             errFooSeenWhenFooOpen(name);
  1496             NS_HTML5_BREAK(starttagloop);
  1498           case NS_HTML5TREE_BUILDER_NOSCRIPT: {
  1499             errFooSeenWhenFooOpen(name);
  1500             NS_HTML5_BREAK(starttagloop);
  1502           default: {
  1503             errBadStartTagInHead(name);
  1504             pop();
  1505             mode = NS_HTML5TREE_BUILDER_IN_HEAD;
  1506             continue;
  1510       case NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP: {
  1511         switch(group) {
  1512           case NS_HTML5TREE_BUILDER_HTML: {
  1513             errStrayStartTag(name);
  1514             if (!fragment && !isTemplateContents()) {
  1515               addAttributesToHtml(attributes);
  1516               attributes = nullptr;
  1518             NS_HTML5_BREAK(starttagloop);
  1520           case NS_HTML5TREE_BUILDER_COL: {
  1521             appendVoidElementToCurrentMayFoster(elementName, attributes);
  1522             selfClosing = false;
  1523             attributes = nullptr;
  1524             NS_HTML5_BREAK(starttagloop);
  1526           case NS_HTML5TREE_BUILDER_TEMPLATE: {
  1527             startTagTemplateInHead(elementName, attributes);
  1528             attributes = nullptr;
  1529             NS_HTML5_BREAK(starttagloop);
  1531           default: {
  1532             if (!currentPtr || stack[currentPtr]->getGroup() == NS_HTML5TREE_BUILDER_TEMPLATE) {
  1533               MOZ_ASSERT(fragment || isTemplateContents());
  1534               errGarbageInColgroup();
  1535               NS_HTML5_BREAK(starttagloop);
  1537             pop();
  1538             mode = NS_HTML5TREE_BUILDER_IN_TABLE;
  1539             continue;
  1543       case NS_HTML5TREE_BUILDER_IN_SELECT_IN_TABLE: {
  1544         switch(group) {
  1545           case NS_HTML5TREE_BUILDER_CAPTION:
  1546           case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT:
  1547           case NS_HTML5TREE_BUILDER_TR:
  1548           case NS_HTML5TREE_BUILDER_TD_OR_TH:
  1549           case NS_HTML5TREE_BUILDER_TABLE: {
  1550             errStartTagWithSelectOpen(name);
  1551             eltPos = findLastInTableScope(nsHtml5Atoms::select);
  1552             if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
  1553               MOZ_ASSERT(fragment);
  1554               NS_HTML5_BREAK(starttagloop);
  1556             while (currentPtr >= eltPos) {
  1557               pop();
  1559             resetTheInsertionMode();
  1560             continue;
  1562           default:
  1563             ; // fall through
  1566       case NS_HTML5TREE_BUILDER_IN_SELECT: {
  1567         switch(group) {
  1568           case NS_HTML5TREE_BUILDER_HTML: {
  1569             errStrayStartTag(name);
  1570             if (!fragment) {
  1571               addAttributesToHtml(attributes);
  1572               attributes = nullptr;
  1574             NS_HTML5_BREAK(starttagloop);
  1576           case NS_HTML5TREE_BUILDER_OPTION: {
  1577             if (isCurrent(nsHtml5Atoms::option)) {
  1578               pop();
  1580             appendToCurrentNodeAndPushElement(elementName, attributes);
  1581             attributes = nullptr;
  1582             NS_HTML5_BREAK(starttagloop);
  1584           case NS_HTML5TREE_BUILDER_OPTGROUP: {
  1585             if (isCurrent(nsHtml5Atoms::option)) {
  1586               pop();
  1588             if (isCurrent(nsHtml5Atoms::optgroup)) {
  1589               pop();
  1591             appendToCurrentNodeAndPushElement(elementName, attributes);
  1592             attributes = nullptr;
  1593             NS_HTML5_BREAK(starttagloop);
  1595           case NS_HTML5TREE_BUILDER_SELECT: {
  1596             errStartSelectWhereEndSelectExpected();
  1597             eltPos = findLastInTableScope(name);
  1598             if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
  1599               MOZ_ASSERT(fragment);
  1600               errNoSelectInTableScope();
  1601               NS_HTML5_BREAK(starttagloop);
  1602             } else {
  1603               while (currentPtr >= eltPos) {
  1604                 pop();
  1606               resetTheInsertionMode();
  1607               NS_HTML5_BREAK(starttagloop);
  1610           case NS_HTML5TREE_BUILDER_INPUT:
  1611           case NS_HTML5TREE_BUILDER_TEXTAREA:
  1612           case NS_HTML5TREE_BUILDER_KEYGEN: {
  1613             errStartTagWithSelectOpen(name);
  1614             eltPos = findLastInTableScope(nsHtml5Atoms::select);
  1615             if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
  1616               MOZ_ASSERT(fragment);
  1617               NS_HTML5_BREAK(starttagloop);
  1619             while (currentPtr >= eltPos) {
  1620               pop();
  1622             resetTheInsertionMode();
  1623             continue;
  1625           case NS_HTML5TREE_BUILDER_SCRIPT: {
  1626             startTagScriptInHead(elementName, attributes);
  1627             attributes = nullptr;
  1628             NS_HTML5_BREAK(starttagloop);
  1630           case NS_HTML5TREE_BUILDER_TEMPLATE: {
  1631             startTagTemplateInHead(elementName, attributes);
  1632             attributes = nullptr;
  1633             NS_HTML5_BREAK(starttagloop);
  1635           default: {
  1636             errStrayStartTag(name);
  1637             NS_HTML5_BREAK(starttagloop);
  1641       case NS_HTML5TREE_BUILDER_AFTER_BODY: {
  1642         switch(group) {
  1643           case NS_HTML5TREE_BUILDER_HTML: {
  1644             errStrayStartTag(name);
  1645             if (!fragment && !isTemplateContents()) {
  1646               addAttributesToHtml(attributes);
  1647               attributes = nullptr;
  1649             NS_HTML5_BREAK(starttagloop);
  1651           default: {
  1652             errStrayStartTag(name);
  1653             mode = framesetOk ? NS_HTML5TREE_BUILDER_FRAMESET_OK : NS_HTML5TREE_BUILDER_IN_BODY;
  1654             continue;
  1658       case NS_HTML5TREE_BUILDER_IN_FRAMESET: {
  1659         switch(group) {
  1660           case NS_HTML5TREE_BUILDER_FRAMESET: {
  1661             appendToCurrentNodeAndPushElement(elementName, attributes);
  1662             attributes = nullptr;
  1663             NS_HTML5_BREAK(starttagloop);
  1665           case NS_HTML5TREE_BUILDER_FRAME: {
  1666             appendVoidElementToCurrentMayFoster(elementName, attributes);
  1667             selfClosing = false;
  1668             attributes = nullptr;
  1669             NS_HTML5_BREAK(starttagloop);
  1671           default:
  1672             ; // fall through
  1675       case NS_HTML5TREE_BUILDER_AFTER_FRAMESET: {
  1676         switch(group) {
  1677           case NS_HTML5TREE_BUILDER_HTML: {
  1678             errStrayStartTag(name);
  1679             if (!fragment && !isTemplateContents()) {
  1680               addAttributesToHtml(attributes);
  1681               attributes = nullptr;
  1683             NS_HTML5_BREAK(starttagloop);
  1685           case NS_HTML5TREE_BUILDER_NOFRAMES: {
  1686             appendToCurrentNodeAndPushElement(elementName, attributes);
  1687             originalMode = mode;
  1688             mode = NS_HTML5TREE_BUILDER_TEXT;
  1689             tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_RAWTEXT, elementName);
  1690             attributes = nullptr;
  1691             NS_HTML5_BREAK(starttagloop);
  1693           default: {
  1694             errStrayStartTag(name);
  1695             NS_HTML5_BREAK(starttagloop);
  1699       case NS_HTML5TREE_BUILDER_INITIAL: {
  1700         errStartTagWithoutDoctype();
  1701         documentModeInternal(QUIRKS_MODE, nullptr, nullptr, false);
  1702         mode = NS_HTML5TREE_BUILDER_BEFORE_HTML;
  1703         continue;
  1705       case NS_HTML5TREE_BUILDER_BEFORE_HTML: {
  1706         switch(group) {
  1707           case NS_HTML5TREE_BUILDER_HTML: {
  1708             if (attributes == nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES) {
  1709               appendHtmlElementToDocumentAndPush();
  1710             } else {
  1711               appendHtmlElementToDocumentAndPush(attributes);
  1713             mode = NS_HTML5TREE_BUILDER_BEFORE_HEAD;
  1714             attributes = nullptr;
  1715             NS_HTML5_BREAK(starttagloop);
  1717           default: {
  1718             appendHtmlElementToDocumentAndPush();
  1719             mode = NS_HTML5TREE_BUILDER_BEFORE_HEAD;
  1720             continue;
  1724       case NS_HTML5TREE_BUILDER_BEFORE_HEAD: {
  1725         switch(group) {
  1726           case NS_HTML5TREE_BUILDER_HTML: {
  1727             errStrayStartTag(name);
  1728             if (!fragment && !isTemplateContents()) {
  1729               addAttributesToHtml(attributes);
  1730               attributes = nullptr;
  1732             NS_HTML5_BREAK(starttagloop);
  1734           case NS_HTML5TREE_BUILDER_HEAD: {
  1735             appendToCurrentNodeAndPushHeadElement(attributes);
  1736             mode = NS_HTML5TREE_BUILDER_IN_HEAD;
  1737             attributes = nullptr;
  1738             NS_HTML5_BREAK(starttagloop);
  1740           default: {
  1741             appendToCurrentNodeAndPushHeadElement(nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES);
  1742             mode = NS_HTML5TREE_BUILDER_IN_HEAD;
  1743             continue;
  1747       case NS_HTML5TREE_BUILDER_AFTER_HEAD: {
  1748         switch(group) {
  1749           case NS_HTML5TREE_BUILDER_HTML: {
  1750             errStrayStartTag(name);
  1751             if (!fragment && !isTemplateContents()) {
  1752               addAttributesToHtml(attributes);
  1753               attributes = nullptr;
  1755             NS_HTML5_BREAK(starttagloop);
  1757           case NS_HTML5TREE_BUILDER_BODY: {
  1758             if (!attributes->getLength()) {
  1759               appendToCurrentNodeAndPushBodyElement();
  1760             } else {
  1761               appendToCurrentNodeAndPushBodyElement(attributes);
  1763             framesetOk = false;
  1764             mode = NS_HTML5TREE_BUILDER_IN_BODY;
  1765             attributes = nullptr;
  1766             NS_HTML5_BREAK(starttagloop);
  1768           case NS_HTML5TREE_BUILDER_FRAMESET: {
  1769             appendToCurrentNodeAndPushElement(elementName, attributes);
  1770             mode = NS_HTML5TREE_BUILDER_IN_FRAMESET;
  1771             attributes = nullptr;
  1772             NS_HTML5_BREAK(starttagloop);
  1774           case NS_HTML5TREE_BUILDER_TEMPLATE: {
  1775             errFooBetweenHeadAndBody(name);
  1776             pushHeadPointerOntoStack();
  1777             nsHtml5StackNode* headOnStack = stack[currentPtr];
  1778             startTagTemplateInHead(elementName, attributes);
  1779             removeFromStack(headOnStack);
  1780             attributes = nullptr;
  1781             NS_HTML5_BREAK(starttagloop);
  1783           case NS_HTML5TREE_BUILDER_BASE:
  1784           case NS_HTML5TREE_BUILDER_LINK_OR_BASEFONT_OR_BGSOUND: {
  1785             errFooBetweenHeadAndBody(name);
  1786             pushHeadPointerOntoStack();
  1787             appendVoidElementToCurrentMayFoster(elementName, attributes);
  1788             selfClosing = false;
  1789             pop();
  1790             attributes = nullptr;
  1791             NS_HTML5_BREAK(starttagloop);
  1793           case NS_HTML5TREE_BUILDER_META: {
  1794             errFooBetweenHeadAndBody(name);
  1795             checkMetaCharset(attributes);
  1796             pushHeadPointerOntoStack();
  1797             appendVoidElementToCurrentMayFoster(elementName, attributes);
  1798             selfClosing = false;
  1799             pop();
  1800             attributes = nullptr;
  1801             NS_HTML5_BREAK(starttagloop);
  1803           case NS_HTML5TREE_BUILDER_SCRIPT: {
  1804             errFooBetweenHeadAndBody(name);
  1805             pushHeadPointerOntoStack();
  1806             appendToCurrentNodeAndPushElement(elementName, attributes);
  1807             originalMode = mode;
  1808             mode = NS_HTML5TREE_BUILDER_TEXT;
  1809             tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_SCRIPT_DATA, elementName);
  1810             attributes = nullptr;
  1811             NS_HTML5_BREAK(starttagloop);
  1813           case NS_HTML5TREE_BUILDER_STYLE:
  1814           case NS_HTML5TREE_BUILDER_NOFRAMES: {
  1815             errFooBetweenHeadAndBody(name);
  1816             pushHeadPointerOntoStack();
  1817             appendToCurrentNodeAndPushElement(elementName, attributes);
  1818             originalMode = mode;
  1819             mode = NS_HTML5TREE_BUILDER_TEXT;
  1820             tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_RAWTEXT, elementName);
  1821             attributes = nullptr;
  1822             NS_HTML5_BREAK(starttagloop);
  1824           case NS_HTML5TREE_BUILDER_TITLE: {
  1825             errFooBetweenHeadAndBody(name);
  1826             pushHeadPointerOntoStack();
  1827             appendToCurrentNodeAndPushElement(elementName, attributes);
  1828             originalMode = mode;
  1829             mode = NS_HTML5TREE_BUILDER_TEXT;
  1830             tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_RCDATA, elementName);
  1831             attributes = nullptr;
  1832             NS_HTML5_BREAK(starttagloop);
  1834           case NS_HTML5TREE_BUILDER_HEAD: {
  1835             errStrayStartTag(name);
  1836             NS_HTML5_BREAK(starttagloop);
  1838           default: {
  1839             appendToCurrentNodeAndPushBodyElement();
  1840             mode = NS_HTML5TREE_BUILDER_FRAMESET_OK;
  1841             continue;
  1845       case NS_HTML5TREE_BUILDER_AFTER_AFTER_BODY: {
  1846         switch(group) {
  1847           case NS_HTML5TREE_BUILDER_HTML: {
  1848             errStrayStartTag(name);
  1849             if (!fragment && !isTemplateContents()) {
  1850               addAttributesToHtml(attributes);
  1851               attributes = nullptr;
  1853             NS_HTML5_BREAK(starttagloop);
  1855           default: {
  1856             errStrayStartTag(name);
  1858             mode = framesetOk ? NS_HTML5TREE_BUILDER_FRAMESET_OK : NS_HTML5TREE_BUILDER_IN_BODY;
  1859             continue;
  1863       case NS_HTML5TREE_BUILDER_AFTER_AFTER_FRAMESET: {
  1864         switch(group) {
  1865           case NS_HTML5TREE_BUILDER_HTML: {
  1866             errStrayStartTag(name);
  1867             if (!fragment && !isTemplateContents()) {
  1868               addAttributesToHtml(attributes);
  1869               attributes = nullptr;
  1871             NS_HTML5_BREAK(starttagloop);
  1873           case NS_HTML5TREE_BUILDER_NOFRAMES: {
  1874             startTagGenericRawText(elementName, attributes);
  1875             attributes = nullptr;
  1876             NS_HTML5_BREAK(starttagloop);
  1878           default: {
  1879             errStrayStartTag(name);
  1880             NS_HTML5_BREAK(starttagloop);
  1884       case NS_HTML5TREE_BUILDER_TEXT: {
  1885         MOZ_ASSERT(false);
  1886         NS_HTML5_BREAK(starttagloop);
  1890   starttagloop_end: ;
  1891   if (selfClosing) {
  1892     errSelfClosing();
  1894   if (!mBuilder && attributes != nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES) {
  1895     delete attributes;
  1899 void 
  1900 nsHtml5TreeBuilder::startTagTitleInHead(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes)
  1902   appendToCurrentNodeAndPushElementMayFoster(elementName, attributes);
  1903   originalMode = mode;
  1904   mode = NS_HTML5TREE_BUILDER_TEXT;
  1905   tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_RCDATA, elementName);
  1908 void 
  1909 nsHtml5TreeBuilder::startTagGenericRawText(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes)
  1911   appendToCurrentNodeAndPushElementMayFoster(elementName, attributes);
  1912   originalMode = mode;
  1913   mode = NS_HTML5TREE_BUILDER_TEXT;
  1914   tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_RAWTEXT, elementName);
  1917 void 
  1918 nsHtml5TreeBuilder::startTagScriptInHead(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes)
  1920   appendToCurrentNodeAndPushElementMayFoster(elementName, attributes);
  1921   originalMode = mode;
  1922   mode = NS_HTML5TREE_BUILDER_TEXT;
  1923   tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_SCRIPT_DATA, elementName);
  1926 void 
  1927 nsHtml5TreeBuilder::startTagTemplateInHead(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes)
  1929   appendToCurrentNodeAndPushElement(elementName, attributes);
  1930   insertMarker();
  1931   framesetOk = false;
  1932   originalMode = mode;
  1933   mode = NS_HTML5TREE_BUILDER_IN_TEMPLATE;
  1934   pushTemplateMode(NS_HTML5TREE_BUILDER_IN_TEMPLATE);
  1937 bool 
  1938 nsHtml5TreeBuilder::isTemplateContents()
  1940   return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK != findLast(nsHtml5Atoms::template_);
  1943 bool 
  1944 nsHtml5TreeBuilder::isTemplateModeStackEmpty()
  1946   return templateModePtr == -1;
  1949 bool 
  1950 nsHtml5TreeBuilder::isSpecialParentInForeign(nsHtml5StackNode* stackNode)
  1952   int32_t ns = stackNode->ns;
  1953   return (kNameSpaceID_XHTML == ns) || (stackNode->isHtmlIntegrationPoint()) || ((kNameSpaceID_MathML == ns) && (stackNode->getGroup() == NS_HTML5TREE_BUILDER_MI_MO_MN_MS_MTEXT));
  1956 nsString* 
  1957 nsHtml5TreeBuilder::extractCharsetFromContent(nsString* attributeValue)
  1959   int32_t charsetState = NS_HTML5TREE_BUILDER_CHARSET_INITIAL;
  1960   int32_t start = -1;
  1961   int32_t end = -1;
  1962   autoJArray<char16_t,int32_t> buffer = nsHtml5Portability::newCharArrayFromString(attributeValue);
  1963   for (int32_t i = 0; i < buffer.length; i++) {
  1964     char16_t c = buffer[i];
  1965     switch(charsetState) {
  1966       case NS_HTML5TREE_BUILDER_CHARSET_INITIAL: {
  1967         switch(c) {
  1968           case 'c':
  1969           case 'C': {
  1970             charsetState = NS_HTML5TREE_BUILDER_CHARSET_C;
  1971             continue;
  1973           default: {
  1974             continue;
  1978       case NS_HTML5TREE_BUILDER_CHARSET_C: {
  1979         switch(c) {
  1980           case 'h':
  1981           case 'H': {
  1982             charsetState = NS_HTML5TREE_BUILDER_CHARSET_H;
  1983             continue;
  1985           default: {
  1986             charsetState = NS_HTML5TREE_BUILDER_CHARSET_INITIAL;
  1987             continue;
  1991       case NS_HTML5TREE_BUILDER_CHARSET_H: {
  1992         switch(c) {
  1993           case 'a':
  1994           case 'A': {
  1995             charsetState = NS_HTML5TREE_BUILDER_CHARSET_A;
  1996             continue;
  1998           default: {
  1999             charsetState = NS_HTML5TREE_BUILDER_CHARSET_INITIAL;
  2000             continue;
  2004       case NS_HTML5TREE_BUILDER_CHARSET_A: {
  2005         switch(c) {
  2006           case 'r':
  2007           case 'R': {
  2008             charsetState = NS_HTML5TREE_BUILDER_CHARSET_R;
  2009             continue;
  2011           default: {
  2012             charsetState = NS_HTML5TREE_BUILDER_CHARSET_INITIAL;
  2013             continue;
  2017       case NS_HTML5TREE_BUILDER_CHARSET_R: {
  2018         switch(c) {
  2019           case 's':
  2020           case 'S': {
  2021             charsetState = NS_HTML5TREE_BUILDER_CHARSET_S;
  2022             continue;
  2024           default: {
  2025             charsetState = NS_HTML5TREE_BUILDER_CHARSET_INITIAL;
  2026             continue;
  2030       case NS_HTML5TREE_BUILDER_CHARSET_S: {
  2031         switch(c) {
  2032           case 'e':
  2033           case 'E': {
  2034             charsetState = NS_HTML5TREE_BUILDER_CHARSET_E;
  2035             continue;
  2037           default: {
  2038             charsetState = NS_HTML5TREE_BUILDER_CHARSET_INITIAL;
  2039             continue;
  2043       case NS_HTML5TREE_BUILDER_CHARSET_E: {
  2044         switch(c) {
  2045           case 't':
  2046           case 'T': {
  2047             charsetState = NS_HTML5TREE_BUILDER_CHARSET_T;
  2048             continue;
  2050           default: {
  2051             charsetState = NS_HTML5TREE_BUILDER_CHARSET_INITIAL;
  2052             continue;
  2056       case NS_HTML5TREE_BUILDER_CHARSET_T: {
  2057         switch(c) {
  2058           case '\t':
  2059           case '\n':
  2060           case '\f':
  2061           case '\r':
  2062           case ' ': {
  2063             continue;
  2065           case '=': {
  2066             charsetState = NS_HTML5TREE_BUILDER_CHARSET_EQUALS;
  2067             continue;
  2069           default: {
  2070             return nullptr;
  2074       case NS_HTML5TREE_BUILDER_CHARSET_EQUALS: {
  2075         switch(c) {
  2076           case '\t':
  2077           case '\n':
  2078           case '\f':
  2079           case '\r':
  2080           case ' ': {
  2081             continue;
  2083           case '\'': {
  2084             start = i + 1;
  2085             charsetState = NS_HTML5TREE_BUILDER_CHARSET_SINGLE_QUOTED;
  2086             continue;
  2088           case '\"': {
  2089             start = i + 1;
  2090             charsetState = NS_HTML5TREE_BUILDER_CHARSET_DOUBLE_QUOTED;
  2091             continue;
  2093           default: {
  2094             start = i;
  2095             charsetState = NS_HTML5TREE_BUILDER_CHARSET_UNQUOTED;
  2096             continue;
  2100       case NS_HTML5TREE_BUILDER_CHARSET_SINGLE_QUOTED: {
  2101         switch(c) {
  2102           case '\'': {
  2103             end = i;
  2104             NS_HTML5_BREAK(charsetloop);
  2106           default: {
  2107             continue;
  2111       case NS_HTML5TREE_BUILDER_CHARSET_DOUBLE_QUOTED: {
  2112         switch(c) {
  2113           case '\"': {
  2114             end = i;
  2115             NS_HTML5_BREAK(charsetloop);
  2117           default: {
  2118             continue;
  2122       case NS_HTML5TREE_BUILDER_CHARSET_UNQUOTED: {
  2123         switch(c) {
  2124           case '\t':
  2125           case '\n':
  2126           case '\f':
  2127           case '\r':
  2128           case ' ':
  2129           case ';': {
  2130             end = i;
  2131             NS_HTML5_BREAK(charsetloop);
  2133           default: {
  2134             continue;
  2140   charsetloop_end: ;
  2141   nsString* charset = nullptr;
  2142   if (start != -1) {
  2143     if (end == -1) {
  2144       end = buffer.length;
  2146     charset = nsHtml5Portability::newStringFromBuffer(buffer, start, end - start);
  2148   return charset;
  2151 void 
  2152 nsHtml5TreeBuilder::checkMetaCharset(nsHtml5HtmlAttributes* attributes)
  2154   nsString* charset = attributes->getValue(nsHtml5AttributeName::ATTR_CHARSET);
  2155   if (charset) {
  2156     if (tokenizer->internalEncodingDeclaration(charset)) {
  2157       requestSuspension();
  2158       return;
  2160     return;
  2162   if (!nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("content-type", attributes->getValue(nsHtml5AttributeName::ATTR_HTTP_EQUIV))) {
  2163     return;
  2165   nsString* content = attributes->getValue(nsHtml5AttributeName::ATTR_CONTENT);
  2166   if (content) {
  2167     nsString* extract = nsHtml5TreeBuilder::extractCharsetFromContent(content);
  2168     if (extract) {
  2169       if (tokenizer->internalEncodingDeclaration(extract)) {
  2170         requestSuspension();
  2173     nsHtml5Portability::releaseString(extract);
  2177 void 
  2178 nsHtml5TreeBuilder::endTag(nsHtml5ElementName* elementName)
  2180   flushCharacters();
  2181   needToDropLF = false;
  2182   int32_t eltPos;
  2183   int32_t group = elementName->getGroup();
  2184   nsIAtom* name = elementName->name;
  2185   for (; ; ) {
  2186     if (isInForeign()) {
  2187       if (stack[currentPtr]->name != name) {
  2188         errEndTagDidNotMatchCurrentOpenElement(name, stack[currentPtr]->popName);
  2190       eltPos = currentPtr;
  2191       for (; ; ) {
  2192         if (stack[eltPos]->name == name) {
  2193           while (currentPtr >= eltPos) {
  2194             pop();
  2196           NS_HTML5_BREAK(endtagloop);
  2198         if (stack[--eltPos]->ns == kNameSpaceID_XHTML) {
  2199           break;
  2203     switch(mode) {
  2204       case NS_HTML5TREE_BUILDER_IN_TEMPLATE: {
  2205         switch(group) {
  2206           case NS_HTML5TREE_BUILDER_TEMPLATE: {
  2207             break;
  2209           default: {
  2210             errStrayEndTag(name);
  2211             NS_HTML5_BREAK(endtagloop);
  2215       case NS_HTML5TREE_BUILDER_IN_ROW: {
  2216         switch(group) {
  2217           case NS_HTML5TREE_BUILDER_TR: {
  2218             eltPos = findLastOrRoot(NS_HTML5TREE_BUILDER_TR);
  2219             if (!eltPos) {
  2220               MOZ_ASSERT(fragment || isTemplateContents());
  2221               errNoTableRowToClose();
  2222               NS_HTML5_BREAK(endtagloop);
  2224             clearStackBackTo(eltPos);
  2225             pop();
  2226             mode = NS_HTML5TREE_BUILDER_IN_TABLE_BODY;
  2227             NS_HTML5_BREAK(endtagloop);
  2229           case NS_HTML5TREE_BUILDER_TABLE: {
  2230             eltPos = findLastOrRoot(NS_HTML5TREE_BUILDER_TR);
  2231             if (!eltPos) {
  2232               MOZ_ASSERT(fragment || isTemplateContents());
  2233               errNoTableRowToClose();
  2234               NS_HTML5_BREAK(endtagloop);
  2236             clearStackBackTo(eltPos);
  2237             pop();
  2238             mode = NS_HTML5TREE_BUILDER_IN_TABLE_BODY;
  2239             continue;
  2241           case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT: {
  2242             if (findLastInTableScope(name) == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
  2243               errStrayEndTag(name);
  2244               NS_HTML5_BREAK(endtagloop);
  2246             eltPos = findLastOrRoot(NS_HTML5TREE_BUILDER_TR);
  2247             if (!eltPos) {
  2248               MOZ_ASSERT(fragment || isTemplateContents());
  2249               errNoTableRowToClose();
  2250               NS_HTML5_BREAK(endtagloop);
  2252             clearStackBackTo(eltPos);
  2253             pop();
  2254             mode = NS_HTML5TREE_BUILDER_IN_TABLE_BODY;
  2255             continue;
  2257           case NS_HTML5TREE_BUILDER_BODY:
  2258           case NS_HTML5TREE_BUILDER_CAPTION:
  2259           case NS_HTML5TREE_BUILDER_COL:
  2260           case NS_HTML5TREE_BUILDER_COLGROUP:
  2261           case NS_HTML5TREE_BUILDER_HTML:
  2262           case NS_HTML5TREE_BUILDER_TD_OR_TH: {
  2263             errStrayEndTag(name);
  2264             NS_HTML5_BREAK(endtagloop);
  2266           default:
  2267             ; // fall through
  2270       case NS_HTML5TREE_BUILDER_IN_TABLE_BODY: {
  2271         switch(group) {
  2272           case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT: {
  2273             eltPos = findLastOrRoot(name);
  2274             if (!eltPos) {
  2275               errStrayEndTag(name);
  2276               NS_HTML5_BREAK(endtagloop);
  2278             clearStackBackTo(eltPos);
  2279             pop();
  2280             mode = NS_HTML5TREE_BUILDER_IN_TABLE;
  2281             NS_HTML5_BREAK(endtagloop);
  2283           case NS_HTML5TREE_BUILDER_TABLE: {
  2284             eltPos = findLastInTableScopeOrRootTemplateTbodyTheadTfoot();
  2285             if (!eltPos || stack[eltPos]->getGroup() == NS_HTML5TREE_BUILDER_TEMPLATE) {
  2286               MOZ_ASSERT(fragment || isTemplateContents());
  2287               errStrayEndTag(name);
  2288               NS_HTML5_BREAK(endtagloop);
  2290             clearStackBackTo(eltPos);
  2291             pop();
  2292             mode = NS_HTML5TREE_BUILDER_IN_TABLE;
  2293             continue;
  2295           case NS_HTML5TREE_BUILDER_BODY:
  2296           case NS_HTML5TREE_BUILDER_CAPTION:
  2297           case NS_HTML5TREE_BUILDER_COL:
  2298           case NS_HTML5TREE_BUILDER_COLGROUP:
  2299           case NS_HTML5TREE_BUILDER_HTML:
  2300           case NS_HTML5TREE_BUILDER_TD_OR_TH:
  2301           case NS_HTML5TREE_BUILDER_TR: {
  2302             errStrayEndTag(name);
  2303             NS_HTML5_BREAK(endtagloop);
  2305           default:
  2306             ; // fall through
  2309       case NS_HTML5TREE_BUILDER_IN_TABLE: {
  2310         switch(group) {
  2311           case NS_HTML5TREE_BUILDER_TABLE: {
  2312             eltPos = findLast(nsHtml5Atoms::table);
  2313             if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
  2314               MOZ_ASSERT(fragment || isTemplateContents());
  2315               errStrayEndTag(name);
  2316               NS_HTML5_BREAK(endtagloop);
  2318             while (currentPtr >= eltPos) {
  2319               pop();
  2321             resetTheInsertionMode();
  2322             NS_HTML5_BREAK(endtagloop);
  2324           case NS_HTML5TREE_BUILDER_BODY:
  2325           case NS_HTML5TREE_BUILDER_CAPTION:
  2326           case NS_HTML5TREE_BUILDER_COL:
  2327           case NS_HTML5TREE_BUILDER_COLGROUP:
  2328           case NS_HTML5TREE_BUILDER_HTML:
  2329           case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT:
  2330           case NS_HTML5TREE_BUILDER_TD_OR_TH:
  2331           case NS_HTML5TREE_BUILDER_TR: {
  2332             errStrayEndTag(name);
  2333             NS_HTML5_BREAK(endtagloop);
  2335           case NS_HTML5TREE_BUILDER_TEMPLATE: {
  2336             break;
  2338           default: {
  2339             errStrayEndTag(name);
  2343       case NS_HTML5TREE_BUILDER_IN_CAPTION: {
  2344         switch(group) {
  2345           case NS_HTML5TREE_BUILDER_CAPTION: {
  2346             eltPos = findLastInTableScope(nsHtml5Atoms::caption);
  2347             if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
  2348               NS_HTML5_BREAK(endtagloop);
  2350             generateImpliedEndTags();
  2351             if (!!MOZ_UNLIKELY(mViewSource) && currentPtr != eltPos) {
  2352               errUnclosedElements(eltPos, name);
  2354             while (currentPtr >= eltPos) {
  2355               pop();
  2357             clearTheListOfActiveFormattingElementsUpToTheLastMarker();
  2358             mode = NS_HTML5TREE_BUILDER_IN_TABLE;
  2359             NS_HTML5_BREAK(endtagloop);
  2361           case NS_HTML5TREE_BUILDER_TABLE: {
  2362             errTableClosedWhileCaptionOpen();
  2363             eltPos = findLastInTableScope(nsHtml5Atoms::caption);
  2364             if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
  2365               NS_HTML5_BREAK(endtagloop);
  2367             generateImpliedEndTags();
  2368             if (!!MOZ_UNLIKELY(mViewSource) && currentPtr != eltPos) {
  2369               errUnclosedElements(eltPos, name);
  2371             while (currentPtr >= eltPos) {
  2372               pop();
  2374             clearTheListOfActiveFormattingElementsUpToTheLastMarker();
  2375             mode = NS_HTML5TREE_BUILDER_IN_TABLE;
  2376             continue;
  2378           case NS_HTML5TREE_BUILDER_BODY:
  2379           case NS_HTML5TREE_BUILDER_COL:
  2380           case NS_HTML5TREE_BUILDER_COLGROUP:
  2381           case NS_HTML5TREE_BUILDER_HTML:
  2382           case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT:
  2383           case NS_HTML5TREE_BUILDER_TD_OR_TH:
  2384           case NS_HTML5TREE_BUILDER_TR: {
  2385             errStrayEndTag(name);
  2386             NS_HTML5_BREAK(endtagloop);
  2388           default:
  2389             ; // fall through
  2392       case NS_HTML5TREE_BUILDER_IN_CELL: {
  2393         switch(group) {
  2394           case NS_HTML5TREE_BUILDER_TD_OR_TH: {
  2395             eltPos = findLastInTableScope(name);
  2396             if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
  2397               errStrayEndTag(name);
  2398               NS_HTML5_BREAK(endtagloop);
  2400             generateImpliedEndTags();
  2401             if (!!MOZ_UNLIKELY(mViewSource) && !isCurrent(name)) {
  2402               errUnclosedElements(eltPos, name);
  2404             while (currentPtr >= eltPos) {
  2405               pop();
  2407             clearTheListOfActiveFormattingElementsUpToTheLastMarker();
  2408             mode = NS_HTML5TREE_BUILDER_IN_ROW;
  2409             NS_HTML5_BREAK(endtagloop);
  2411           case NS_HTML5TREE_BUILDER_TABLE:
  2412           case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT:
  2413           case NS_HTML5TREE_BUILDER_TR: {
  2414             if (findLastInTableScope(name) == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
  2415               MOZ_ASSERT(name == nsHtml5Atoms::tbody || name == nsHtml5Atoms::tfoot || name == nsHtml5Atoms::thead || fragment || isTemplateContents());
  2416               errStrayEndTag(name);
  2417               NS_HTML5_BREAK(endtagloop);
  2419             closeTheCell(findLastInTableScopeTdTh());
  2420             continue;
  2422           case NS_HTML5TREE_BUILDER_BODY:
  2423           case NS_HTML5TREE_BUILDER_CAPTION:
  2424           case NS_HTML5TREE_BUILDER_COL:
  2425           case NS_HTML5TREE_BUILDER_COLGROUP:
  2426           case NS_HTML5TREE_BUILDER_HTML: {
  2427             errStrayEndTag(name);
  2428             NS_HTML5_BREAK(endtagloop);
  2430           default:
  2431             ; // fall through
  2434       case NS_HTML5TREE_BUILDER_FRAMESET_OK:
  2435       case NS_HTML5TREE_BUILDER_IN_BODY: {
  2436         switch(group) {
  2437           case NS_HTML5TREE_BUILDER_BODY: {
  2438             if (!isSecondOnStackBody()) {
  2439               MOZ_ASSERT(fragment || isTemplateContents());
  2440               errStrayEndTag(name);
  2441               NS_HTML5_BREAK(endtagloop);
  2443             MOZ_ASSERT(currentPtr >= 1);
  2444             if (MOZ_UNLIKELY(mViewSource)) {
  2445               for (int32_t i = 2; i <= currentPtr; i++) {
  2446                 switch(stack[i]->getGroup()) {
  2447                   case NS_HTML5TREE_BUILDER_DD_OR_DT:
  2448                   case NS_HTML5TREE_BUILDER_LI:
  2449                   case NS_HTML5TREE_BUILDER_OPTGROUP:
  2450                   case NS_HTML5TREE_BUILDER_OPTION:
  2451                   case NS_HTML5TREE_BUILDER_P:
  2452                   case NS_HTML5TREE_BUILDER_RT_OR_RP:
  2453                   case NS_HTML5TREE_BUILDER_TD_OR_TH:
  2454                   case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT: {
  2455                     break;
  2457                   default: {
  2458                     errEndWithUnclosedElements(name);
  2459                     NS_HTML5_BREAK(uncloseloop1);
  2463               uncloseloop1_end: ;
  2465             mode = NS_HTML5TREE_BUILDER_AFTER_BODY;
  2466             NS_HTML5_BREAK(endtagloop);
  2468           case NS_HTML5TREE_BUILDER_HTML: {
  2469             if (!isSecondOnStackBody()) {
  2470               MOZ_ASSERT(fragment || isTemplateContents());
  2471               errStrayEndTag(name);
  2472               NS_HTML5_BREAK(endtagloop);
  2474             if (MOZ_UNLIKELY(mViewSource)) {
  2475               for (int32_t i = 0; i <= currentPtr; i++) {
  2476                 switch(stack[i]->getGroup()) {
  2477                   case NS_HTML5TREE_BUILDER_DD_OR_DT:
  2478                   case NS_HTML5TREE_BUILDER_LI:
  2479                   case NS_HTML5TREE_BUILDER_P:
  2480                   case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT:
  2481                   case NS_HTML5TREE_BUILDER_TD_OR_TH:
  2482                   case NS_HTML5TREE_BUILDER_BODY:
  2483                   case NS_HTML5TREE_BUILDER_HTML: {
  2484                     break;
  2486                   default: {
  2487                     errEndWithUnclosedElements(name);
  2488                     NS_HTML5_BREAK(uncloseloop2);
  2492               uncloseloop2_end: ;
  2494             mode = NS_HTML5TREE_BUILDER_AFTER_BODY;
  2495             continue;
  2497           case NS_HTML5TREE_BUILDER_DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU:
  2498           case NS_HTML5TREE_BUILDER_UL_OR_OL_OR_DL:
  2499           case NS_HTML5TREE_BUILDER_PRE_OR_LISTING:
  2500           case NS_HTML5TREE_BUILDER_FIELDSET:
  2501           case NS_HTML5TREE_BUILDER_BUTTON:
  2502           case NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY: {
  2503             eltPos = findLastInScope(name);
  2504             if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
  2505               errStrayEndTag(name);
  2506             } else {
  2507               generateImpliedEndTags();
  2508               if (!!MOZ_UNLIKELY(mViewSource) && !isCurrent(name)) {
  2509                 errUnclosedElements(eltPos, name);
  2511               while (currentPtr >= eltPos) {
  2512                 pop();
  2515             NS_HTML5_BREAK(endtagloop);
  2517           case NS_HTML5TREE_BUILDER_FORM: {
  2518             if (!isTemplateContents()) {
  2519               if (!formPointer) {
  2520                 errStrayEndTag(name);
  2521                 NS_HTML5_BREAK(endtagloop);
  2523               formPointer = nullptr;
  2524               eltPos = findLastInScope(name);
  2525               if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
  2526                 errStrayEndTag(name);
  2527                 NS_HTML5_BREAK(endtagloop);
  2529               generateImpliedEndTags();
  2530               if (!!MOZ_UNLIKELY(mViewSource) && !isCurrent(name)) {
  2531                 errUnclosedElements(eltPos, name);
  2533               removeFromStack(eltPos);
  2534               NS_HTML5_BREAK(endtagloop);
  2535             } else {
  2536               eltPos = findLastInScope(name);
  2537               if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
  2538                 errStrayEndTag(name);
  2539                 NS_HTML5_BREAK(endtagloop);
  2541               generateImpliedEndTags();
  2542               if (!!MOZ_UNLIKELY(mViewSource) && !isCurrent(name)) {
  2543                 errUnclosedElements(eltPos, name);
  2545               while (currentPtr >= eltPos) {
  2546                 pop();
  2548               NS_HTML5_BREAK(endtagloop);
  2551           case NS_HTML5TREE_BUILDER_P: {
  2552             eltPos = findLastInButtonScope(nsHtml5Atoms::p);
  2553             if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
  2554               errNoElementToCloseButEndTagSeen(nsHtml5Atoms::p);
  2555               if (isInForeign()) {
  2556                 errHtmlStartTagInForeignContext(name);
  2557                 while (stack[currentPtr]->ns != kNameSpaceID_XHTML) {
  2558                   pop();
  2561               appendVoidElementToCurrentMayFoster(elementName, nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES);
  2562               NS_HTML5_BREAK(endtagloop);
  2564             generateImpliedEndTagsExceptFor(nsHtml5Atoms::p);
  2565             MOZ_ASSERT(eltPos != NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK);
  2566             if (!!MOZ_UNLIKELY(mViewSource) && eltPos != currentPtr) {
  2567               errUnclosedElements(eltPos, name);
  2569             while (currentPtr >= eltPos) {
  2570               pop();
  2572             NS_HTML5_BREAK(endtagloop);
  2574           case NS_HTML5TREE_BUILDER_LI: {
  2575             eltPos = findLastInListScope(name);
  2576             if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
  2577               errNoElementToCloseButEndTagSeen(name);
  2578             } else {
  2579               generateImpliedEndTagsExceptFor(name);
  2580               if (!!MOZ_UNLIKELY(mViewSource) && eltPos != currentPtr) {
  2581                 errUnclosedElements(eltPos, name);
  2583               while (currentPtr >= eltPos) {
  2584                 pop();
  2587             NS_HTML5_BREAK(endtagloop);
  2589           case NS_HTML5TREE_BUILDER_DD_OR_DT: {
  2590             eltPos = findLastInScope(name);
  2591             if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
  2592               errNoElementToCloseButEndTagSeen(name);
  2593             } else {
  2594               generateImpliedEndTagsExceptFor(name);
  2595               if (!!MOZ_UNLIKELY(mViewSource) && eltPos != currentPtr) {
  2596                 errUnclosedElements(eltPos, name);
  2598               while (currentPtr >= eltPos) {
  2599                 pop();
  2602             NS_HTML5_BREAK(endtagloop);
  2604           case NS_HTML5TREE_BUILDER_H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6: {
  2605             eltPos = findLastInScopeHn();
  2606             if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
  2607               errStrayEndTag(name);
  2608             } else {
  2609               generateImpliedEndTags();
  2610               if (!!MOZ_UNLIKELY(mViewSource) && !isCurrent(name)) {
  2611                 errUnclosedElements(eltPos, name);
  2613               while (currentPtr >= eltPos) {
  2614                 pop();
  2617             NS_HTML5_BREAK(endtagloop);
  2619           case NS_HTML5TREE_BUILDER_OBJECT:
  2620           case NS_HTML5TREE_BUILDER_MARQUEE_OR_APPLET: {
  2621             eltPos = findLastInScope(name);
  2622             if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
  2623               errStrayEndTag(name);
  2624             } else {
  2625               generateImpliedEndTags();
  2626               if (!!MOZ_UNLIKELY(mViewSource) && !isCurrent(name)) {
  2627                 errUnclosedElements(eltPos, name);
  2629               while (currentPtr >= eltPos) {
  2630                 pop();
  2632               clearTheListOfActiveFormattingElementsUpToTheLastMarker();
  2634             NS_HTML5_BREAK(endtagloop);
  2636           case NS_HTML5TREE_BUILDER_BR: {
  2637             errEndTagBr();
  2638             if (isInForeign()) {
  2639               errHtmlStartTagInForeignContext(name);
  2640               while (stack[currentPtr]->ns != kNameSpaceID_XHTML) {
  2641                 pop();
  2644             reconstructTheActiveFormattingElements();
  2645             appendVoidElementToCurrentMayFoster(elementName, nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES);
  2646             NS_HTML5_BREAK(endtagloop);
  2648           case NS_HTML5TREE_BUILDER_TEMPLATE: {
  2649             break;
  2651           case NS_HTML5TREE_BUILDER_AREA_OR_WBR:
  2652 #ifdef ENABLE_VOID_MENUITEM
  2653           case NS_HTML5TREE_BUILDER_MENUITEM:
  2654 #endif
  2655           case NS_HTML5TREE_BUILDER_PARAM_OR_SOURCE_OR_TRACK:
  2656           case NS_HTML5TREE_BUILDER_EMBED:
  2657           case NS_HTML5TREE_BUILDER_IMG:
  2658           case NS_HTML5TREE_BUILDER_IMAGE:
  2659           case NS_HTML5TREE_BUILDER_INPUT:
  2660           case NS_HTML5TREE_BUILDER_KEYGEN:
  2661           case NS_HTML5TREE_BUILDER_HR:
  2662           case NS_HTML5TREE_BUILDER_ISINDEX:
  2663           case NS_HTML5TREE_BUILDER_IFRAME:
  2664           case NS_HTML5TREE_BUILDER_NOEMBED:
  2665           case NS_HTML5TREE_BUILDER_NOFRAMES:
  2666           case NS_HTML5TREE_BUILDER_SELECT:
  2667           case NS_HTML5TREE_BUILDER_TABLE:
  2668           case NS_HTML5TREE_BUILDER_TEXTAREA: {
  2669             errStrayEndTag(name);
  2670             NS_HTML5_BREAK(endtagloop);
  2672           case NS_HTML5TREE_BUILDER_NOSCRIPT: {
  2673             if (scriptingEnabled) {
  2674               errStrayEndTag(name);
  2675               NS_HTML5_BREAK(endtagloop);
  2676             } else {
  2679           case NS_HTML5TREE_BUILDER_A:
  2680           case NS_HTML5TREE_BUILDER_B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U:
  2681           case NS_HTML5TREE_BUILDER_FONT:
  2682           case NS_HTML5TREE_BUILDER_NOBR: {
  2683             if (adoptionAgencyEndTag(name)) {
  2684               NS_HTML5_BREAK(endtagloop);
  2687           default: {
  2688             if (isCurrent(name)) {
  2689               pop();
  2690               NS_HTML5_BREAK(endtagloop);
  2692             eltPos = currentPtr;
  2693             for (; ; ) {
  2694               nsHtml5StackNode* node = stack[eltPos];
  2695               if (node->ns == kNameSpaceID_XHTML && node->name == name) {
  2696                 generateImpliedEndTags();
  2697                 if (!!MOZ_UNLIKELY(mViewSource) && !isCurrent(name)) {
  2698                   errUnclosedElements(eltPos, name);
  2700                 while (currentPtr >= eltPos) {
  2701                   pop();
  2703                 NS_HTML5_BREAK(endtagloop);
  2704               } else if (node->isSpecial()) {
  2705                 errStrayEndTag(name);
  2706                 NS_HTML5_BREAK(endtagloop);
  2708               eltPos--;
  2713       case NS_HTML5TREE_BUILDER_IN_HEAD: {
  2714         switch(group) {
  2715           case NS_HTML5TREE_BUILDER_HEAD: {
  2716             pop();
  2717             mode = NS_HTML5TREE_BUILDER_AFTER_HEAD;
  2718             NS_HTML5_BREAK(endtagloop);
  2720           case NS_HTML5TREE_BUILDER_BR:
  2721           case NS_HTML5TREE_BUILDER_HTML:
  2722           case NS_HTML5TREE_BUILDER_BODY: {
  2723             pop();
  2724             mode = NS_HTML5TREE_BUILDER_AFTER_HEAD;
  2725             continue;
  2727           case NS_HTML5TREE_BUILDER_TEMPLATE: {
  2728             endTagTemplateInHead();
  2729             NS_HTML5_BREAK(endtagloop);
  2731           default: {
  2732             errStrayEndTag(name);
  2733             NS_HTML5_BREAK(endtagloop);
  2737       case NS_HTML5TREE_BUILDER_IN_HEAD_NOSCRIPT: {
  2738         switch(group) {
  2739           case NS_HTML5TREE_BUILDER_NOSCRIPT: {
  2740             pop();
  2741             mode = NS_HTML5TREE_BUILDER_IN_HEAD;
  2742             NS_HTML5_BREAK(endtagloop);
  2744           case NS_HTML5TREE_BUILDER_BR: {
  2745             errStrayEndTag(name);
  2746             pop();
  2747             mode = NS_HTML5TREE_BUILDER_IN_HEAD;
  2748             continue;
  2750           default: {
  2751             errStrayEndTag(name);
  2752             NS_HTML5_BREAK(endtagloop);
  2756       case NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP: {
  2757         switch(group) {
  2758           case NS_HTML5TREE_BUILDER_COLGROUP: {
  2759             if (!currentPtr || stack[currentPtr]->getGroup() == NS_HTML5TREE_BUILDER_TEMPLATE) {
  2760               MOZ_ASSERT(fragment || isTemplateContents());
  2761               errGarbageInColgroup();
  2762               NS_HTML5_BREAK(endtagloop);
  2764             pop();
  2765             mode = NS_HTML5TREE_BUILDER_IN_TABLE;
  2766             NS_HTML5_BREAK(endtagloop);
  2768           case NS_HTML5TREE_BUILDER_COL: {
  2769             errStrayEndTag(name);
  2770             NS_HTML5_BREAK(endtagloop);
  2772           case NS_HTML5TREE_BUILDER_TEMPLATE: {
  2773             endTagTemplateInHead();
  2774             NS_HTML5_BREAK(endtagloop);
  2776           default: {
  2777             if (!currentPtr || stack[currentPtr]->getGroup() == NS_HTML5TREE_BUILDER_TEMPLATE) {
  2778               MOZ_ASSERT(fragment || isTemplateContents());
  2779               errGarbageInColgroup();
  2780               NS_HTML5_BREAK(endtagloop);
  2782             pop();
  2783             mode = NS_HTML5TREE_BUILDER_IN_TABLE;
  2784             continue;
  2788       case NS_HTML5TREE_BUILDER_IN_SELECT_IN_TABLE: {
  2789         switch(group) {
  2790           case NS_HTML5TREE_BUILDER_CAPTION:
  2791           case NS_HTML5TREE_BUILDER_TABLE:
  2792           case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT:
  2793           case NS_HTML5TREE_BUILDER_TR:
  2794           case NS_HTML5TREE_BUILDER_TD_OR_TH: {
  2795             errEndTagSeenWithSelectOpen(name);
  2796             if (findLastInTableScope(name) != NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
  2797               eltPos = findLastInTableScope(nsHtml5Atoms::select);
  2798               if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
  2799                 MOZ_ASSERT(fragment);
  2800                 NS_HTML5_BREAK(endtagloop);
  2802               while (currentPtr >= eltPos) {
  2803                 pop();
  2805               resetTheInsertionMode();
  2806               continue;
  2807             } else {
  2808               NS_HTML5_BREAK(endtagloop);
  2811           default:
  2812             ; // fall through
  2815       case NS_HTML5TREE_BUILDER_IN_SELECT: {
  2816         switch(group) {
  2817           case NS_HTML5TREE_BUILDER_OPTION: {
  2818             if (isCurrent(nsHtml5Atoms::option)) {
  2819               pop();
  2820               NS_HTML5_BREAK(endtagloop);
  2821             } else {
  2822               errStrayEndTag(name);
  2823               NS_HTML5_BREAK(endtagloop);
  2826           case NS_HTML5TREE_BUILDER_OPTGROUP: {
  2827             if (isCurrent(nsHtml5Atoms::option) && nsHtml5Atoms::optgroup == stack[currentPtr - 1]->name) {
  2828               pop();
  2830             if (isCurrent(nsHtml5Atoms::optgroup)) {
  2831               pop();
  2832             } else {
  2833               errStrayEndTag(name);
  2835             NS_HTML5_BREAK(endtagloop);
  2837           case NS_HTML5TREE_BUILDER_SELECT: {
  2838             eltPos = findLastInTableScope(nsHtml5Atoms::select);
  2839             if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
  2840               MOZ_ASSERT(fragment);
  2841               errStrayEndTag(name);
  2842               NS_HTML5_BREAK(endtagloop);
  2844             while (currentPtr >= eltPos) {
  2845               pop();
  2847             resetTheInsertionMode();
  2848             NS_HTML5_BREAK(endtagloop);
  2850           case NS_HTML5TREE_BUILDER_TEMPLATE: {
  2851             endTagTemplateInHead();
  2852             NS_HTML5_BREAK(endtagloop);
  2854           default: {
  2855             errStrayEndTag(name);
  2856             NS_HTML5_BREAK(endtagloop);
  2860       case NS_HTML5TREE_BUILDER_AFTER_BODY: {
  2861         switch(group) {
  2862           case NS_HTML5TREE_BUILDER_HTML: {
  2863             if (fragment) {
  2864               errStrayEndTag(name);
  2865               NS_HTML5_BREAK(endtagloop);
  2866             } else {
  2867               mode = NS_HTML5TREE_BUILDER_AFTER_AFTER_BODY;
  2868               NS_HTML5_BREAK(endtagloop);
  2871           default: {
  2872             errEndTagAfterBody();
  2873             mode = framesetOk ? NS_HTML5TREE_BUILDER_FRAMESET_OK : NS_HTML5TREE_BUILDER_IN_BODY;
  2874             continue;
  2878       case NS_HTML5TREE_BUILDER_IN_FRAMESET: {
  2879         switch(group) {
  2880           case NS_HTML5TREE_BUILDER_FRAMESET: {
  2881             if (!currentPtr) {
  2882               MOZ_ASSERT(fragment);
  2883               errStrayEndTag(name);
  2884               NS_HTML5_BREAK(endtagloop);
  2886             pop();
  2887             if ((!fragment) && !isCurrent(nsHtml5Atoms::frameset)) {
  2888               mode = NS_HTML5TREE_BUILDER_AFTER_FRAMESET;
  2890             NS_HTML5_BREAK(endtagloop);
  2892           default: {
  2893             errStrayEndTag(name);
  2894             NS_HTML5_BREAK(endtagloop);
  2898       case NS_HTML5TREE_BUILDER_AFTER_FRAMESET: {
  2899         switch(group) {
  2900           case NS_HTML5TREE_BUILDER_HTML: {
  2901             mode = NS_HTML5TREE_BUILDER_AFTER_AFTER_FRAMESET;
  2902             NS_HTML5_BREAK(endtagloop);
  2904           default: {
  2905             errStrayEndTag(name);
  2906             NS_HTML5_BREAK(endtagloop);
  2910       case NS_HTML5TREE_BUILDER_INITIAL: {
  2911         errEndTagSeenWithoutDoctype();
  2912         documentModeInternal(QUIRKS_MODE, nullptr, nullptr, false);
  2913         mode = NS_HTML5TREE_BUILDER_BEFORE_HTML;
  2914         continue;
  2916       case NS_HTML5TREE_BUILDER_BEFORE_HTML: {
  2917         switch(group) {
  2918           case NS_HTML5TREE_BUILDER_HEAD:
  2919           case NS_HTML5TREE_BUILDER_BR:
  2920           case NS_HTML5TREE_BUILDER_HTML:
  2921           case NS_HTML5TREE_BUILDER_BODY: {
  2922             appendHtmlElementToDocumentAndPush();
  2923             mode = NS_HTML5TREE_BUILDER_BEFORE_HEAD;
  2924             continue;
  2926           default: {
  2927             errStrayEndTag(name);
  2928             NS_HTML5_BREAK(endtagloop);
  2932       case NS_HTML5TREE_BUILDER_BEFORE_HEAD: {
  2933         switch(group) {
  2934           case NS_HTML5TREE_BUILDER_HEAD:
  2935           case NS_HTML5TREE_BUILDER_BR:
  2936           case NS_HTML5TREE_BUILDER_HTML:
  2937           case NS_HTML5TREE_BUILDER_BODY: {
  2938             appendToCurrentNodeAndPushHeadElement(nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES);
  2939             mode = NS_HTML5TREE_BUILDER_IN_HEAD;
  2940             continue;
  2942           default: {
  2943             errStrayEndTag(name);
  2944             NS_HTML5_BREAK(endtagloop);
  2948       case NS_HTML5TREE_BUILDER_AFTER_HEAD: {
  2949         switch(group) {
  2950           case NS_HTML5TREE_BUILDER_TEMPLATE: {
  2951             endTagTemplateInHead();
  2952             NS_HTML5_BREAK(endtagloop);
  2954           case NS_HTML5TREE_BUILDER_HTML:
  2955           case NS_HTML5TREE_BUILDER_BODY:
  2956           case NS_HTML5TREE_BUILDER_BR: {
  2957             appendToCurrentNodeAndPushBodyElement();
  2958             mode = NS_HTML5TREE_BUILDER_FRAMESET_OK;
  2959             continue;
  2961           default: {
  2962             errStrayEndTag(name);
  2963             NS_HTML5_BREAK(endtagloop);
  2967       case NS_HTML5TREE_BUILDER_AFTER_AFTER_BODY: {
  2968         errStrayEndTag(name);
  2969         mode = framesetOk ? NS_HTML5TREE_BUILDER_FRAMESET_OK : NS_HTML5TREE_BUILDER_IN_BODY;
  2970         continue;
  2972       case NS_HTML5TREE_BUILDER_AFTER_AFTER_FRAMESET: {
  2973         errStrayEndTag(name);
  2974         NS_HTML5_BREAK(endtagloop);
  2976       case NS_HTML5TREE_BUILDER_TEXT: {
  2977         pop();
  2978         if (originalMode == NS_HTML5TREE_BUILDER_AFTER_HEAD) {
  2979           silentPop();
  2981         mode = originalMode;
  2982         NS_HTML5_BREAK(endtagloop);
  2986   endtagloop_end: ;
  2989 void 
  2990 nsHtml5TreeBuilder::endTagTemplateInHead()
  2992   int32_t eltPos = findLast(nsHtml5Atoms::template_);
  2993   if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
  2994     errStrayEndTag(nsHtml5Atoms::template_);
  2995     return;
  2997   generateImpliedEndTags();
  2998   if (!!MOZ_UNLIKELY(mViewSource) && !isCurrent(nsHtml5Atoms::template_)) {
  2999     errUnclosedElements(eltPos, nsHtml5Atoms::template_);
  3001   while (currentPtr >= eltPos) {
  3002     pop();
  3004   clearTheListOfActiveFormattingElementsUpToTheLastMarker();
  3005   popTemplateMode();
  3006   resetTheInsertionMode();
  3009 int32_t 
  3010 nsHtml5TreeBuilder::findLastInTableScopeOrRootTemplateTbodyTheadTfoot()
  3012   for (int32_t i = currentPtr; i > 0; i--) {
  3013     if (stack[i]->getGroup() == NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT || stack[i]->getGroup() == NS_HTML5TREE_BUILDER_TEMPLATE) {
  3014       return i;
  3017   return 0;
  3020 int32_t 
  3021 nsHtml5TreeBuilder::findLast(nsIAtom* name)
  3023   for (int32_t i = currentPtr; i > 0; i--) {
  3024     if (stack[i]->ns == kNameSpaceID_XHTML && stack[i]->name == name) {
  3025       return i;
  3028   return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK;
  3031 int32_t 
  3032 nsHtml5TreeBuilder::findLastInTableScope(nsIAtom* name)
  3034   for (int32_t i = currentPtr; i > 0; i--) {
  3035     if (stack[i]->ns == kNameSpaceID_XHTML) {
  3036       if (stack[i]->name == name) {
  3037         return i;
  3038       } else if (stack[i]->name == nsHtml5Atoms::table || stack[i]->name == nsHtml5Atoms::template_) {
  3039         return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK;
  3043   return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK;
  3046 int32_t 
  3047 nsHtml5TreeBuilder::findLastInButtonScope(nsIAtom* name)
  3049   for (int32_t i = currentPtr; i > 0; i--) {
  3050     if (stack[i]->ns == kNameSpaceID_XHTML) {
  3051       if (stack[i]->name == name) {
  3052         return i;
  3053       } else if (stack[i]->name == nsHtml5Atoms::button) {
  3054         return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK;
  3057     if (stack[i]->isScoping()) {
  3058       return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK;
  3061   return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK;
  3064 int32_t 
  3065 nsHtml5TreeBuilder::findLastInScope(nsIAtom* name)
  3067   for (int32_t i = currentPtr; i > 0; i--) {
  3068     if (stack[i]->ns == kNameSpaceID_XHTML && stack[i]->name == name) {
  3069       return i;
  3070     } else if (stack[i]->isScoping()) {
  3071       return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK;
  3074   return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK;
  3077 int32_t 
  3078 nsHtml5TreeBuilder::findLastInListScope(nsIAtom* name)
  3080   for (int32_t i = currentPtr; i > 0; i--) {
  3081     if (stack[i]->ns == kNameSpaceID_XHTML) {
  3082       if (stack[i]->name == name) {
  3083         return i;
  3084       } else if (stack[i]->name == nsHtml5Atoms::ul || stack[i]->name == nsHtml5Atoms::ol) {
  3085         return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK;
  3088     if (stack[i]->isScoping()) {
  3089       return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK;
  3092   return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK;
  3095 int32_t 
  3096 nsHtml5TreeBuilder::findLastInScopeHn()
  3098   for (int32_t i = currentPtr; i > 0; i--) {
  3099     if (stack[i]->getGroup() == NS_HTML5TREE_BUILDER_H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6) {
  3100       return i;
  3101     } else if (stack[i]->isScoping()) {
  3102       return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK;
  3105   return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK;
  3108 void 
  3109 nsHtml5TreeBuilder::generateImpliedEndTagsExceptFor(nsIAtom* name)
  3111   for (; ; ) {
  3112     nsHtml5StackNode* node = stack[currentPtr];
  3113     switch(node->getGroup()) {
  3114       case NS_HTML5TREE_BUILDER_P:
  3115       case NS_HTML5TREE_BUILDER_LI:
  3116       case NS_HTML5TREE_BUILDER_DD_OR_DT:
  3117       case NS_HTML5TREE_BUILDER_OPTION:
  3118       case NS_HTML5TREE_BUILDER_OPTGROUP:
  3119       case NS_HTML5TREE_BUILDER_RT_OR_RP: {
  3120         if (node->ns == kNameSpaceID_XHTML && node->name == name) {
  3121           return;
  3123         pop();
  3124         continue;
  3126       default: {
  3127         return;
  3133 void 
  3134 nsHtml5TreeBuilder::generateImpliedEndTags()
  3136   for (; ; ) {
  3137     switch(stack[currentPtr]->getGroup()) {
  3138       case NS_HTML5TREE_BUILDER_P:
  3139       case NS_HTML5TREE_BUILDER_LI:
  3140       case NS_HTML5TREE_BUILDER_DD_OR_DT:
  3141       case NS_HTML5TREE_BUILDER_OPTION:
  3142       case NS_HTML5TREE_BUILDER_OPTGROUP:
  3143       case NS_HTML5TREE_BUILDER_RT_OR_RP: {
  3144         pop();
  3145         continue;
  3147       default: {
  3148         return;
  3154 bool 
  3155 nsHtml5TreeBuilder::isSecondOnStackBody()
  3157   return currentPtr >= 1 && stack[1]->getGroup() == NS_HTML5TREE_BUILDER_BODY;
  3160 void 
  3161 nsHtml5TreeBuilder::documentModeInternal(nsHtml5DocumentMode m, nsString* publicIdentifier, nsString* systemIdentifier, bool html4SpecificAdditionalErrorChecks)
  3163   if (isSrcdocDocument) {
  3164     quirks = false;
  3165     if (this) {
  3166       this->documentMode(STANDARDS_MODE);
  3168     return;
  3170   quirks = (m == QUIRKS_MODE);
  3171   if (this) {
  3172     this->documentMode(m);
  3176 bool 
  3177 nsHtml5TreeBuilder::isAlmostStandards(nsString* publicIdentifier, nsString* systemIdentifier)
  3179   if (nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("-//w3c//dtd xhtml 1.0 transitional//en", publicIdentifier)) {
  3180     return true;
  3182   if (nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("-//w3c//dtd xhtml 1.0 frameset//en", publicIdentifier)) {
  3183     return true;
  3185   if (systemIdentifier) {
  3186     if (nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("-//w3c//dtd html 4.01 transitional//en", publicIdentifier)) {
  3187       return true;
  3189     if (nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("-//w3c//dtd html 4.01 frameset//en", publicIdentifier)) {
  3190       return true;
  3193   return false;
  3196 bool 
  3197 nsHtml5TreeBuilder::isQuirky(nsIAtom* name, nsString* publicIdentifier, nsString* systemIdentifier, bool forceQuirks)
  3199   if (forceQuirks) {
  3200     return true;
  3202   if (name != nsHtml5Atoms::html) {
  3203     return true;
  3205   if (publicIdentifier) {
  3206     for (int32_t i = 0; i < nsHtml5TreeBuilder::QUIRKY_PUBLIC_IDS.length; i++) {
  3207       if (nsHtml5Portability::lowerCaseLiteralIsPrefixOfIgnoreAsciiCaseString(nsHtml5TreeBuilder::QUIRKY_PUBLIC_IDS[i], publicIdentifier)) {
  3208         return true;
  3211     if (nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("-//w3o//dtd w3 html strict 3.0//en//", publicIdentifier) || nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("-/w3c/dtd html 4.0 transitional/en", publicIdentifier) || nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("html", publicIdentifier)) {
  3212       return true;
  3215   if (!systemIdentifier) {
  3216     if (nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("-//w3c//dtd html 4.01 transitional//en", publicIdentifier)) {
  3217       return true;
  3218     } else if (nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("-//w3c//dtd html 4.01 frameset//en", publicIdentifier)) {
  3219       return true;
  3221   } else if (nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd", systemIdentifier)) {
  3222     return true;
  3224   return false;
  3227 void 
  3228 nsHtml5TreeBuilder::closeTheCell(int32_t eltPos)
  3230   generateImpliedEndTags();
  3231   if (!!MOZ_UNLIKELY(mViewSource) && eltPos != currentPtr) {
  3232     errUnclosedElementsCell(eltPos);
  3234   while (currentPtr >= eltPos) {
  3235     pop();
  3237   clearTheListOfActiveFormattingElementsUpToTheLastMarker();
  3238   mode = NS_HTML5TREE_BUILDER_IN_ROW;
  3239   return;
  3242 int32_t 
  3243 nsHtml5TreeBuilder::findLastInTableScopeTdTh()
  3245   for (int32_t i = currentPtr; i > 0; i--) {
  3246     nsIAtom* name = stack[i]->name;
  3247     if (stack[i]->ns == kNameSpaceID_XHTML) {
  3248       if (nsHtml5Atoms::td == name || nsHtml5Atoms::th == name) {
  3249         return i;
  3250       } else if (name == nsHtml5Atoms::table || name == nsHtml5Atoms::template_) {
  3251         return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK;
  3255   return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK;
  3258 void 
  3259 nsHtml5TreeBuilder::clearStackBackTo(int32_t eltPos)
  3261   int32_t eltGroup = stack[eltPos]->getGroup();
  3262   while (currentPtr > eltPos) {
  3263     if (stack[currentPtr]->ns == kNameSpaceID_XHTML && stack[currentPtr]->getGroup() == NS_HTML5TREE_BUILDER_TEMPLATE && (eltGroup == NS_HTML5TREE_BUILDER_TABLE || eltGroup == NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT || eltGroup == NS_HTML5TREE_BUILDER_TR || eltGroup == NS_HTML5TREE_BUILDER_HTML)) {
  3264       return;
  3266     pop();
  3270 void 
  3271 nsHtml5TreeBuilder::resetTheInsertionMode()
  3273   nsHtml5StackNode* node;
  3274   nsIAtom* name;
  3275   int32_t ns;
  3276   for (int32_t i = currentPtr; i >= 0; i--) {
  3277     node = stack[i];
  3278     name = node->name;
  3279     ns = node->ns;
  3280     if (!i) {
  3281       if (!(contextNamespace == kNameSpaceID_XHTML && (contextName == nsHtml5Atoms::td || contextName == nsHtml5Atoms::th))) {
  3282         if (fragment) {
  3283           name = contextName;
  3284           ns = contextNamespace;
  3286       } else {
  3287         mode = framesetOk ? NS_HTML5TREE_BUILDER_FRAMESET_OK : NS_HTML5TREE_BUILDER_IN_BODY;
  3288         return;
  3291     if (nsHtml5Atoms::select == name) {
  3292       int32_t ancestorIndex = i;
  3293       while (ancestorIndex > 0) {
  3294         nsHtml5StackNode* ancestor = stack[ancestorIndex--];
  3295         if (kNameSpaceID_XHTML == ancestor->ns) {
  3296           if (nsHtml5Atoms::template_ == ancestor->name) {
  3297             break;
  3299           if (nsHtml5Atoms::table == ancestor->name) {
  3300             mode = NS_HTML5TREE_BUILDER_IN_SELECT_IN_TABLE;
  3301             return;
  3305       mode = NS_HTML5TREE_BUILDER_IN_SELECT;
  3306       return;
  3307     } else if (nsHtml5Atoms::td == name || nsHtml5Atoms::th == name) {
  3308       mode = NS_HTML5TREE_BUILDER_IN_CELL;
  3309       return;
  3310     } else if (nsHtml5Atoms::tr == name) {
  3311       mode = NS_HTML5TREE_BUILDER_IN_ROW;
  3312       return;
  3313     } else if (nsHtml5Atoms::tbody == name || nsHtml5Atoms::thead == name || nsHtml5Atoms::tfoot == name) {
  3314       mode = NS_HTML5TREE_BUILDER_IN_TABLE_BODY;
  3315       return;
  3316     } else if (nsHtml5Atoms::caption == name) {
  3317       mode = NS_HTML5TREE_BUILDER_IN_CAPTION;
  3318       return;
  3319     } else if (nsHtml5Atoms::colgroup == name) {
  3320       mode = NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP;
  3321       return;
  3322     } else if (nsHtml5Atoms::table == name) {
  3323       mode = NS_HTML5TREE_BUILDER_IN_TABLE;
  3324       return;
  3325     } else if (kNameSpaceID_XHTML != ns) {
  3326       mode = framesetOk ? NS_HTML5TREE_BUILDER_FRAMESET_OK : NS_HTML5TREE_BUILDER_IN_BODY;
  3327       return;
  3328     } else if (nsHtml5Atoms::template_ == name) {
  3329       MOZ_ASSERT(templateModePtr >= 0);
  3330       mode = templateModeStack[templateModePtr];
  3331       return;
  3332     } else if (nsHtml5Atoms::head == name) {
  3333       if (name == contextName) {
  3334         mode = framesetOk ? NS_HTML5TREE_BUILDER_FRAMESET_OK : NS_HTML5TREE_BUILDER_IN_BODY;
  3335       } else {
  3336         mode = NS_HTML5TREE_BUILDER_IN_HEAD;
  3338       return;
  3339     } else if (nsHtml5Atoms::body == name) {
  3340       mode = framesetOk ? NS_HTML5TREE_BUILDER_FRAMESET_OK : NS_HTML5TREE_BUILDER_IN_BODY;
  3341       return;
  3342     } else if (nsHtml5Atoms::frameset == name) {
  3343       mode = NS_HTML5TREE_BUILDER_IN_FRAMESET;
  3344       return;
  3345     } else if (nsHtml5Atoms::html == name) {
  3346       if (!headPointer) {
  3347         mode = NS_HTML5TREE_BUILDER_BEFORE_HEAD;
  3348       } else {
  3349         mode = NS_HTML5TREE_BUILDER_AFTER_HEAD;
  3351       return;
  3352     } else if (!i) {
  3353       mode = framesetOk ? NS_HTML5TREE_BUILDER_FRAMESET_OK : NS_HTML5TREE_BUILDER_IN_BODY;
  3354       return;
  3359 void 
  3360 nsHtml5TreeBuilder::implicitlyCloseP()
  3362   int32_t eltPos = findLastInButtonScope(nsHtml5Atoms::p);
  3363   if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
  3364     return;
  3366   generateImpliedEndTagsExceptFor(nsHtml5Atoms::p);
  3367   if (!!MOZ_UNLIKELY(mViewSource) && eltPos != currentPtr) {
  3368     errUnclosedElementsImplied(eltPos, nsHtml5Atoms::p);
  3370   while (currentPtr >= eltPos) {
  3371     pop();
  3375 bool 
  3376 nsHtml5TreeBuilder::debugOnlyClearLastStackSlot()
  3378   stack[currentPtr] = nullptr;
  3379   return true;
  3382 bool 
  3383 nsHtml5TreeBuilder::debugOnlyClearLastListSlot()
  3385   listOfActiveFormattingElements[listPtr] = nullptr;
  3386   return true;
  3389 void 
  3390 nsHtml5TreeBuilder::pushTemplateMode(int32_t mode)
  3392   templateModePtr++;
  3393   if (templateModePtr == templateModeStack.length) {
  3394     jArray<int32_t,int32_t> newStack = jArray<int32_t,int32_t>::newJArray(templateModeStack.length + 64);
  3395     nsHtml5ArrayCopy::arraycopy(templateModeStack, newStack, templateModeStack.length);
  3396     templateModeStack = newStack;
  3398   templateModeStack[templateModePtr] = mode;
  3401 void 
  3402 nsHtml5TreeBuilder::push(nsHtml5StackNode* node)
  3404   currentPtr++;
  3405   if (currentPtr == stack.length) {
  3406     jArray<nsHtml5StackNode*,int32_t> newStack = jArray<nsHtml5StackNode*,int32_t>::newJArray(stack.length + 64);
  3407     nsHtml5ArrayCopy::arraycopy(stack, newStack, stack.length);
  3408     stack = newStack;
  3410   stack[currentPtr] = node;
  3411   elementPushed(node->ns, node->popName, node->node);
  3414 void 
  3415 nsHtml5TreeBuilder::silentPush(nsHtml5StackNode* node)
  3417   currentPtr++;
  3418   if (currentPtr == stack.length) {
  3419     jArray<nsHtml5StackNode*,int32_t> newStack = jArray<nsHtml5StackNode*,int32_t>::newJArray(stack.length + 64);
  3420     nsHtml5ArrayCopy::arraycopy(stack, newStack, stack.length);
  3421     stack = newStack;
  3423   stack[currentPtr] = node;
  3426 void 
  3427 nsHtml5TreeBuilder::append(nsHtml5StackNode* node)
  3429   listPtr++;
  3430   if (listPtr == listOfActiveFormattingElements.length) {
  3431     jArray<nsHtml5StackNode*,int32_t> newList = jArray<nsHtml5StackNode*,int32_t>::newJArray(listOfActiveFormattingElements.length + 64);
  3432     nsHtml5ArrayCopy::arraycopy(listOfActiveFormattingElements, newList, listOfActiveFormattingElements.length);
  3433     listOfActiveFormattingElements = newList;
  3435   listOfActiveFormattingElements[listPtr] = node;
  3438 void 
  3439 nsHtml5TreeBuilder::clearTheListOfActiveFormattingElementsUpToTheLastMarker()
  3441   while (listPtr > -1) {
  3442     if (!listOfActiveFormattingElements[listPtr]) {
  3443       --listPtr;
  3444       return;
  3446     listOfActiveFormattingElements[listPtr]->release();
  3447     --listPtr;
  3451 void 
  3452 nsHtml5TreeBuilder::removeFromStack(int32_t pos)
  3454   if (currentPtr == pos) {
  3455     pop();
  3456   } else {
  3458     stack[pos]->release();
  3459     nsHtml5ArrayCopy::arraycopy(stack, pos + 1, pos, currentPtr - pos);
  3460     MOZ_ASSERT(debugOnlyClearLastStackSlot());
  3461     currentPtr--;
  3465 void 
  3466 nsHtml5TreeBuilder::removeFromStack(nsHtml5StackNode* node)
  3468   if (stack[currentPtr] == node) {
  3469     pop();
  3470   } else {
  3471     int32_t pos = currentPtr - 1;
  3472     while (pos >= 0 && stack[pos] != node) {
  3473       pos--;
  3475     if (pos == -1) {
  3476       return;
  3479     node->release();
  3480     nsHtml5ArrayCopy::arraycopy(stack, pos + 1, pos, currentPtr - pos);
  3481     currentPtr--;
  3485 void 
  3486 nsHtml5TreeBuilder::removeFromListOfActiveFormattingElements(int32_t pos)
  3488   MOZ_ASSERT(!!listOfActiveFormattingElements[pos]);
  3489   listOfActiveFormattingElements[pos]->release();
  3490   if (pos == listPtr) {
  3491     MOZ_ASSERT(debugOnlyClearLastListSlot());
  3492     listPtr--;
  3493     return;
  3495   MOZ_ASSERT(pos < listPtr);
  3496   nsHtml5ArrayCopy::arraycopy(listOfActiveFormattingElements, pos + 1, pos, listPtr - pos);
  3497   MOZ_ASSERT(debugOnlyClearLastListSlot());
  3498   listPtr--;
  3501 bool 
  3502 nsHtml5TreeBuilder::adoptionAgencyEndTag(nsIAtom* name)
  3504   if (stack[currentPtr]->ns == kNameSpaceID_XHTML && stack[currentPtr]->name == name && findInListOfActiveFormattingElements(stack[currentPtr]) == -1) {
  3505     pop();
  3506     return true;
  3508   for (int32_t i = 0; i < 8; ++i) {
  3509     int32_t formattingEltListPos = listPtr;
  3510     while (formattingEltListPos > -1) {
  3511       nsHtml5StackNode* listNode = listOfActiveFormattingElements[formattingEltListPos];
  3512       if (!listNode) {
  3513         formattingEltListPos = -1;
  3514         break;
  3515       } else if (listNode->name == name) {
  3516         break;
  3518       formattingEltListPos--;
  3520     if (formattingEltListPos == -1) {
  3521       return false;
  3523     nsHtml5StackNode* formattingElt = listOfActiveFormattingElements[formattingEltListPos];
  3524     int32_t formattingEltStackPos = currentPtr;
  3525     bool inScope = true;
  3526     while (formattingEltStackPos > -1) {
  3527       nsHtml5StackNode* node = stack[formattingEltStackPos];
  3528       if (node == formattingElt) {
  3529         break;
  3530       } else if (node->isScoping()) {
  3531         inScope = false;
  3533       formattingEltStackPos--;
  3535     if (formattingEltStackPos == -1) {
  3536       errNoElementToCloseButEndTagSeen(name);
  3537       removeFromListOfActiveFormattingElements(formattingEltListPos);
  3538       return true;
  3540     if (!inScope) {
  3541       errNoElementToCloseButEndTagSeen(name);
  3542       return true;
  3544     if (formattingEltStackPos != currentPtr) {
  3545       errEndTagViolatesNestingRules(name);
  3547     int32_t furthestBlockPos = formattingEltStackPos + 1;
  3548     while (furthestBlockPos <= currentPtr) {
  3549       nsHtml5StackNode* node = stack[furthestBlockPos];
  3550       if (node->isSpecial()) {
  3551         break;
  3553       furthestBlockPos++;
  3555     if (furthestBlockPos > currentPtr) {
  3556       while (currentPtr >= formattingEltStackPos) {
  3557         pop();
  3559       removeFromListOfActiveFormattingElements(formattingEltListPos);
  3560       return true;
  3562     nsHtml5StackNode* commonAncestor = stack[formattingEltStackPos - 1];
  3563     nsHtml5StackNode* furthestBlock = stack[furthestBlockPos];
  3564     int32_t bookmark = formattingEltListPos;
  3565     int32_t nodePos = furthestBlockPos;
  3566     nsHtml5StackNode* lastNode = furthestBlock;
  3567     int32_t j = 0;
  3568     for (; ; ) {
  3569       ++j;
  3570       nodePos--;
  3571       if (nodePos == formattingEltStackPos) {
  3572         break;
  3574       nsHtml5StackNode* node = stack[nodePos];
  3575       int32_t nodeListPos = findInListOfActiveFormattingElements(node);
  3576       if (j > 3 && nodeListPos != -1) {
  3577         removeFromListOfActiveFormattingElements(nodeListPos);
  3578         if (nodeListPos <= formattingEltListPos) {
  3579           formattingEltListPos--;
  3581         if (nodeListPos <= bookmark) {
  3582           bookmark--;
  3584         nodeListPos = -1;
  3586       if (nodeListPos == -1) {
  3587         MOZ_ASSERT(formattingEltStackPos < nodePos);
  3588         MOZ_ASSERT(bookmark < nodePos);
  3589         MOZ_ASSERT(furthestBlockPos > nodePos);
  3590         removeFromStack(nodePos);
  3591         furthestBlockPos--;
  3592         continue;
  3594       if (nodePos == furthestBlockPos) {
  3595         bookmark = nodeListPos + 1;
  3597       MOZ_ASSERT(node == listOfActiveFormattingElements[nodeListPos]);
  3598       MOZ_ASSERT(node == stack[nodePos]);
  3599       nsIContentHandle* clone = createElement(kNameSpaceID_XHTML, node->name, node->attributes->cloneAttributes(nullptr));
  3600       nsHtml5StackNode* newNode = new nsHtml5StackNode(node->getFlags(), node->ns, node->name, clone, node->popName, node->attributes);
  3601       node->dropAttributes();
  3602       stack[nodePos] = newNode;
  3603       newNode->retain();
  3604       listOfActiveFormattingElements[nodeListPos] = newNode;
  3605       node->release();
  3606       node->release();
  3607       node = newNode;
  3608       detachFromParent(lastNode->node);
  3609       appendElement(lastNode->node, node->node);
  3610       lastNode = node;
  3612     if (commonAncestor->isFosterParenting()) {
  3614       detachFromParent(lastNode->node);
  3615       insertIntoFosterParent(lastNode->node);
  3616     } else {
  3617       detachFromParent(lastNode->node);
  3618       appendElement(lastNode->node, commonAncestor->node);
  3620     nsIContentHandle* clone = createElement(kNameSpaceID_XHTML, formattingElt->name, formattingElt->attributes->cloneAttributes(nullptr));
  3621     nsHtml5StackNode* formattingClone = new nsHtml5StackNode(formattingElt->getFlags(), formattingElt->ns, formattingElt->name, clone, formattingElt->popName, formattingElt->attributes);
  3622     formattingElt->dropAttributes();
  3623     appendChildrenToNewParent(furthestBlock->node, clone);
  3624     appendElement(clone, furthestBlock->node);
  3625     removeFromListOfActiveFormattingElements(formattingEltListPos);
  3626     insertIntoListOfActiveFormattingElements(formattingClone, bookmark);
  3627     MOZ_ASSERT(formattingEltStackPos < furthestBlockPos);
  3628     removeFromStack(formattingEltStackPos);
  3629     insertIntoStack(formattingClone, furthestBlockPos);
  3631   return true;
  3634 void 
  3635 nsHtml5TreeBuilder::insertIntoStack(nsHtml5StackNode* node, int32_t position)
  3637   MOZ_ASSERT(currentPtr + 1 < stack.length);
  3638   MOZ_ASSERT(position <= currentPtr + 1);
  3639   if (position == currentPtr + 1) {
  3640     push(node);
  3641   } else {
  3642     nsHtml5ArrayCopy::arraycopy(stack, position, position + 1, (currentPtr - position) + 1);
  3643     currentPtr++;
  3644     stack[position] = node;
  3648 void 
  3649 nsHtml5TreeBuilder::insertIntoListOfActiveFormattingElements(nsHtml5StackNode* formattingClone, int32_t bookmark)
  3651   formattingClone->retain();
  3652   MOZ_ASSERT(listPtr + 1 < listOfActiveFormattingElements.length);
  3653   if (bookmark <= listPtr) {
  3654     nsHtml5ArrayCopy::arraycopy(listOfActiveFormattingElements, bookmark, bookmark + 1, (listPtr - bookmark) + 1);
  3656   listPtr++;
  3657   listOfActiveFormattingElements[bookmark] = formattingClone;
  3660 int32_t 
  3661 nsHtml5TreeBuilder::findInListOfActiveFormattingElements(nsHtml5StackNode* node)
  3663   for (int32_t i = listPtr; i >= 0; i--) {
  3664     if (node == listOfActiveFormattingElements[i]) {
  3665       return i;
  3668   return -1;
  3671 int32_t 
  3672 nsHtml5TreeBuilder::findInListOfActiveFormattingElementsContainsBetweenEndAndLastMarker(nsIAtom* name)
  3674   for (int32_t i = listPtr; i >= 0; i--) {
  3675     nsHtml5StackNode* node = listOfActiveFormattingElements[i];
  3676     if (!node) {
  3677       return -1;
  3678     } else if (node->name == name) {
  3679       return i;
  3682   return -1;
  3685 void 
  3686 nsHtml5TreeBuilder::maybeForgetEarlierDuplicateFormattingElement(nsIAtom* name, nsHtml5HtmlAttributes* attributes)
  3688   int32_t candidate = -1;
  3689   int32_t count = 0;
  3690   for (int32_t i = listPtr; i >= 0; i--) {
  3691     nsHtml5StackNode* node = listOfActiveFormattingElements[i];
  3692     if (!node) {
  3693       break;
  3695     if (node->name == name && node->attributes->equalsAnother(attributes)) {
  3696       candidate = i;
  3697       ++count;
  3700   if (count >= 3) {
  3701     removeFromListOfActiveFormattingElements(candidate);
  3705 int32_t 
  3706 nsHtml5TreeBuilder::findLastOrRoot(nsIAtom* name)
  3708   for (int32_t i = currentPtr; i > 0; i--) {
  3709     if (stack[i]->ns == kNameSpaceID_XHTML && stack[i]->name == name) {
  3710       return i;
  3713   return 0;
  3716 int32_t 
  3717 nsHtml5TreeBuilder::findLastOrRoot(int32_t group)
  3719   for (int32_t i = currentPtr; i > 0; i--) {
  3720     if (stack[i]->getGroup() == group) {
  3721       return i;
  3724   return 0;
  3727 bool 
  3728 nsHtml5TreeBuilder::addAttributesToBody(nsHtml5HtmlAttributes* attributes)
  3730   if (currentPtr >= 1) {
  3731     nsHtml5StackNode* body = stack[1];
  3732     if (body->getGroup() == NS_HTML5TREE_BUILDER_BODY) {
  3733       addAttributesToElement(body->node, attributes);
  3734       return true;
  3737   return false;
  3740 void 
  3741 nsHtml5TreeBuilder::addAttributesToHtml(nsHtml5HtmlAttributes* attributes)
  3743   addAttributesToElement(stack[0]->node, attributes);
  3746 void 
  3747 nsHtml5TreeBuilder::pushHeadPointerOntoStack()
  3749   MOZ_ASSERT(!!headPointer);
  3750   MOZ_ASSERT(mode == NS_HTML5TREE_BUILDER_AFTER_HEAD);
  3752   silentPush(new nsHtml5StackNode(nsHtml5ElementName::ELT_HEAD, headPointer));
  3755 void 
  3756 nsHtml5TreeBuilder::reconstructTheActiveFormattingElements()
  3758   if (listPtr == -1) {
  3759     return;
  3761   nsHtml5StackNode* mostRecent = listOfActiveFormattingElements[listPtr];
  3762   if (!mostRecent || isInStack(mostRecent)) {
  3763     return;
  3765   int32_t entryPos = listPtr;
  3766   for (; ; ) {
  3767     entryPos--;
  3768     if (entryPos == -1) {
  3769       break;
  3771     if (!listOfActiveFormattingElements[entryPos]) {
  3772       break;
  3774     if (isInStack(listOfActiveFormattingElements[entryPos])) {
  3775       break;
  3778   while (entryPos < listPtr) {
  3779     entryPos++;
  3780     nsHtml5StackNode* entry = listOfActiveFormattingElements[entryPos];
  3781     nsIContentHandle* clone = createElement(kNameSpaceID_XHTML, entry->name, entry->attributes->cloneAttributes(nullptr));
  3782     nsHtml5StackNode* entryClone = new nsHtml5StackNode(entry->getFlags(), entry->ns, entry->name, clone, entry->popName, entry->attributes);
  3783     entry->dropAttributes();
  3784     nsHtml5StackNode* currentNode = stack[currentPtr];
  3785     if (currentNode->isFosterParenting()) {
  3786       insertIntoFosterParent(clone);
  3787     } else {
  3788       appendElement(clone, currentNode->node);
  3790     push(entryClone);
  3791     listOfActiveFormattingElements[entryPos] = entryClone;
  3792     entry->release();
  3793     entryClone->retain();
  3797 void 
  3798 nsHtml5TreeBuilder::insertIntoFosterParent(nsIContentHandle* child)
  3800   int32_t tablePos = findLastOrRoot(NS_HTML5TREE_BUILDER_TABLE);
  3801   int32_t templatePos = findLastOrRoot(NS_HTML5TREE_BUILDER_TEMPLATE);
  3802   if (templatePos >= tablePos) {
  3803     appendElement(child, stack[templatePos]->node);
  3804     return;
  3806   nsHtml5StackNode* node = stack[tablePos];
  3807   insertFosterParentedChild(child, node->node, stack[tablePos - 1]->node);
  3810 bool 
  3811 nsHtml5TreeBuilder::isInStack(nsHtml5StackNode* node)
  3813   for (int32_t i = currentPtr; i >= 0; i--) {
  3814     if (stack[i] == node) {
  3815       return true;
  3818   return false;
  3821 void 
  3822 nsHtml5TreeBuilder::popTemplateMode()
  3824   templateModePtr--;
  3827 void 
  3828 nsHtml5TreeBuilder::pop()
  3830   nsHtml5StackNode* node = stack[currentPtr];
  3831   MOZ_ASSERT(debugOnlyClearLastStackSlot());
  3832   currentPtr--;
  3833   elementPopped(node->ns, node->popName, node->node);
  3834   node->release();
  3837 void 
  3838 nsHtml5TreeBuilder::silentPop()
  3840   nsHtml5StackNode* node = stack[currentPtr];
  3841   MOZ_ASSERT(debugOnlyClearLastStackSlot());
  3842   currentPtr--;
  3843   node->release();
  3846 void 
  3847 nsHtml5TreeBuilder::popOnEof()
  3849   nsHtml5StackNode* node = stack[currentPtr];
  3850   MOZ_ASSERT(debugOnlyClearLastStackSlot());
  3851   currentPtr--;
  3852   markMalformedIfScript(node->node);
  3853   elementPopped(node->ns, node->popName, node->node);
  3854   node->release();
  3857 void 
  3858 nsHtml5TreeBuilder::appendHtmlElementToDocumentAndPush(nsHtml5HtmlAttributes* attributes)
  3860   nsIContentHandle* elt = createHtmlElementSetAsRoot(attributes);
  3861   nsHtml5StackNode* node = new nsHtml5StackNode(nsHtml5ElementName::ELT_HTML, elt);
  3862   push(node);
  3865 void 
  3866 nsHtml5TreeBuilder::appendHtmlElementToDocumentAndPush()
  3868   appendHtmlElementToDocumentAndPush(tokenizer->emptyAttributes());
  3871 void 
  3872 nsHtml5TreeBuilder::appendToCurrentNodeAndPushHeadElement(nsHtml5HtmlAttributes* attributes)
  3874   nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, nsHtml5Atoms::head, attributes);
  3875   appendElement(elt, stack[currentPtr]->node);
  3876   headPointer = elt;
  3877   nsHtml5StackNode* node = new nsHtml5StackNode(nsHtml5ElementName::ELT_HEAD, elt);
  3878   push(node);
  3881 void 
  3882 nsHtml5TreeBuilder::appendToCurrentNodeAndPushBodyElement(nsHtml5HtmlAttributes* attributes)
  3884   appendToCurrentNodeAndPushElement(nsHtml5ElementName::ELT_BODY, attributes);
  3887 void 
  3888 nsHtml5TreeBuilder::appendToCurrentNodeAndPushBodyElement()
  3890   appendToCurrentNodeAndPushBodyElement(tokenizer->emptyAttributes());
  3893 void 
  3894 nsHtml5TreeBuilder::appendToCurrentNodeAndPushFormElementMayFoster(nsHtml5HtmlAttributes* attributes)
  3896   nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, nsHtml5Atoms::form, attributes);
  3897   if (!isTemplateContents()) {
  3898     formPointer = elt;
  3900   nsHtml5StackNode* current = stack[currentPtr];
  3901   if (current->isFosterParenting()) {
  3903     insertIntoFosterParent(elt);
  3904   } else {
  3905     appendElement(elt, current->node);
  3907   nsHtml5StackNode* node = new nsHtml5StackNode(nsHtml5ElementName::ELT_FORM, elt);
  3908   push(node);
  3911 void 
  3912 nsHtml5TreeBuilder::appendToCurrentNodeAndPushFormattingElementMayFoster(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes)
  3914   nsHtml5HtmlAttributes* clone = attributes->cloneAttributes(nullptr);
  3915   nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, elementName->name, attributes);
  3916   nsHtml5StackNode* current = stack[currentPtr];
  3917   if (current->isFosterParenting()) {
  3919     insertIntoFosterParent(elt);
  3920   } else {
  3921     appendElement(elt, current->node);
  3923   nsHtml5StackNode* node = new nsHtml5StackNode(elementName, elt, clone);
  3924   push(node);
  3925   append(node);
  3926   node->retain();
  3929 void 
  3930 nsHtml5TreeBuilder::appendToCurrentNodeAndPushElement(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes)
  3932   nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, elementName->name, attributes);
  3933   appendElement(elt, stack[currentPtr]->node);
  3934   if (nsHtml5ElementName::ELT_TEMPLATE == elementName) {
  3935     elt = getDocumentFragmentForTemplate(elt);
  3937   nsHtml5StackNode* node = new nsHtml5StackNode(elementName, elt);
  3938   push(node);
  3941 void 
  3942 nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFoster(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes)
  3944   nsIAtom* popName = elementName->name;
  3945   nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, popName, attributes);
  3946   nsHtml5StackNode* current = stack[currentPtr];
  3947   if (current->isFosterParenting()) {
  3949     insertIntoFosterParent(elt);
  3950   } else {
  3951     appendElement(elt, current->node);
  3953   nsHtml5StackNode* node = new nsHtml5StackNode(elementName, elt, popName);
  3954   push(node);
  3957 void 
  3958 nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFosterMathML(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes)
  3960   nsIAtom* popName = elementName->name;
  3961   bool markAsHtmlIntegrationPoint = false;
  3962   if (nsHtml5ElementName::ELT_ANNOTATION_XML == elementName && annotationXmlEncodingPermitsHtml(attributes)) {
  3963     markAsHtmlIntegrationPoint = true;
  3965   nsIContentHandle* elt = createElement(kNameSpaceID_MathML, popName, attributes);
  3966   nsHtml5StackNode* current = stack[currentPtr];
  3967   if (current->isFosterParenting()) {
  3969     insertIntoFosterParent(elt);
  3970   } else {
  3971     appendElement(elt, current->node);
  3973   nsHtml5StackNode* node = new nsHtml5StackNode(elementName, elt, popName, markAsHtmlIntegrationPoint);
  3974   push(node);
  3977 bool 
  3978 nsHtml5TreeBuilder::annotationXmlEncodingPermitsHtml(nsHtml5HtmlAttributes* attributes)
  3980   nsString* encoding = attributes->getValue(nsHtml5AttributeName::ATTR_ENCODING);
  3981   if (!encoding) {
  3982     return false;
  3984   return nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("application/xhtml+xml", encoding) || nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("text/html", encoding);
  3987 void 
  3988 nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFosterSVG(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes)
  3990   nsIAtom* popName = elementName->camelCaseName;
  3991   nsIContentHandle* elt = createElement(kNameSpaceID_SVG, popName, attributes);
  3992   nsHtml5StackNode* current = stack[currentPtr];
  3993   if (current->isFosterParenting()) {
  3995     insertIntoFosterParent(elt);
  3996   } else {
  3997     appendElement(elt, current->node);
  3999   nsHtml5StackNode* node = new nsHtml5StackNode(elementName, popName, elt);
  4000   push(node);
  4003 void 
  4004 nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFoster(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes, nsIContentHandle* form)
  4006   nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, elementName->name, attributes, !form || fragment || isTemplateContents() ? nullptr : form);
  4007   nsHtml5StackNode* current = stack[currentPtr];
  4008   if (current->isFosterParenting()) {
  4010     insertIntoFosterParent(elt);
  4011   } else {
  4012     appendElement(elt, current->node);
  4014   nsHtml5StackNode* node = new nsHtml5StackNode(elementName, elt);
  4015   push(node);
  4018 void 
  4019 nsHtml5TreeBuilder::appendVoidElementToCurrentMayFoster(nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContentHandle* form)
  4021   nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, name, attributes, !form || fragment || isTemplateContents() ? nullptr : form);
  4022   nsHtml5StackNode* current = stack[currentPtr];
  4023   if (current->isFosterParenting()) {
  4025     insertIntoFosterParent(elt);
  4026   } else {
  4027     appendElement(elt, current->node);
  4029   elementPushed(kNameSpaceID_XHTML, name, elt);
  4030   elementPopped(kNameSpaceID_XHTML, name, elt);
  4033 void 
  4034 nsHtml5TreeBuilder::appendVoidElementToCurrentMayFoster(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes)
  4036   nsIAtom* popName = elementName->name;
  4037   nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, popName, attributes);
  4038   nsHtml5StackNode* current = stack[currentPtr];
  4039   if (current->isFosterParenting()) {
  4041     insertIntoFosterParent(elt);
  4042   } else {
  4043     appendElement(elt, current->node);
  4045   elementPushed(kNameSpaceID_XHTML, popName, elt);
  4046   elementPopped(kNameSpaceID_XHTML, popName, elt);
  4049 void 
  4050 nsHtml5TreeBuilder::appendVoidElementToCurrentMayFosterSVG(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes)
  4052   nsIAtom* popName = elementName->camelCaseName;
  4053   nsIContentHandle* elt = createElement(kNameSpaceID_SVG, popName, attributes);
  4054   nsHtml5StackNode* current = stack[currentPtr];
  4055   if (current->isFosterParenting()) {
  4057     insertIntoFosterParent(elt);
  4058   } else {
  4059     appendElement(elt, current->node);
  4061   elementPushed(kNameSpaceID_SVG, popName, elt);
  4062   elementPopped(kNameSpaceID_SVG, popName, elt);
  4065 void 
  4066 nsHtml5TreeBuilder::appendVoidElementToCurrentMayFosterMathML(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes)
  4068   nsIAtom* popName = elementName->name;
  4069   nsIContentHandle* elt = createElement(kNameSpaceID_MathML, popName, attributes);
  4070   nsHtml5StackNode* current = stack[currentPtr];
  4071   if (current->isFosterParenting()) {
  4073     insertIntoFosterParent(elt);
  4074   } else {
  4075     appendElement(elt, current->node);
  4077   elementPushed(kNameSpaceID_MathML, popName, elt);
  4078   elementPopped(kNameSpaceID_MathML, popName, elt);
  4081 void 
  4082 nsHtml5TreeBuilder::appendVoidElementToCurrent(nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContentHandle* form)
  4084   nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, name, attributes, !form || fragment || isTemplateContents() ? nullptr : form);
  4085   nsHtml5StackNode* current = stack[currentPtr];
  4086   appendElement(elt, current->node);
  4087   elementPushed(kNameSpaceID_XHTML, name, elt);
  4088   elementPopped(kNameSpaceID_XHTML, name, elt);
  4091 void 
  4092 nsHtml5TreeBuilder::appendVoidFormToCurrent(nsHtml5HtmlAttributes* attributes)
  4094   nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, nsHtml5Atoms::form, attributes);
  4095   formPointer = elt;
  4096   nsHtml5StackNode* current = stack[currentPtr];
  4097   appendElement(elt, current->node);
  4098   elementPushed(kNameSpaceID_XHTML, nsHtml5Atoms::form, elt);
  4099   elementPopped(kNameSpaceID_XHTML, nsHtml5Atoms::form, elt);
  4102 void 
  4103 nsHtml5TreeBuilder::requestSuspension()
  4105   tokenizer->requestSuspension();
  4108 bool 
  4109 nsHtml5TreeBuilder::isInForeign()
  4111   return currentPtr >= 0 && stack[currentPtr]->ns != kNameSpaceID_XHTML;
  4114 bool 
  4115 nsHtml5TreeBuilder::isInForeignButNotHtmlOrMathTextIntegrationPoint()
  4117   if (currentPtr < 0) {
  4118     return false;
  4120   return !isSpecialParentInForeign(stack[currentPtr]);
  4123 void 
  4124 nsHtml5TreeBuilder::setFragmentContext(nsIAtom* context, int32_t ns, nsIContentHandle* node, bool quirks)
  4126   this->contextName = context;
  4127   this->contextNamespace = ns;
  4128   this->contextNode = node;
  4129   this->fragment = (!!contextName);
  4130   this->quirks = quirks;
  4133 nsIContentHandle* 
  4134 nsHtml5TreeBuilder::currentNode()
  4136   return stack[currentPtr]->node;
  4139 bool 
  4140 nsHtml5TreeBuilder::isScriptingEnabled()
  4142   return scriptingEnabled;
  4145 void 
  4146 nsHtml5TreeBuilder::setScriptingEnabled(bool scriptingEnabled)
  4148   this->scriptingEnabled = scriptingEnabled;
  4151 void 
  4152 nsHtml5TreeBuilder::setIsSrcdocDocument(bool isSrcdocDocument)
  4154   this->isSrcdocDocument = isSrcdocDocument;
  4157 void 
  4158 nsHtml5TreeBuilder::flushCharacters()
  4160   if (charBufferLen > 0) {
  4161     if ((mode == NS_HTML5TREE_BUILDER_IN_TABLE || mode == NS_HTML5TREE_BUILDER_IN_TABLE_BODY || mode == NS_HTML5TREE_BUILDER_IN_ROW) && charBufferContainsNonWhitespace()) {
  4162       errNonSpaceInTable();
  4163       reconstructTheActiveFormattingElements();
  4164       if (!stack[currentPtr]->isFosterParenting()) {
  4165         appendCharacters(currentNode(), charBuffer, 0, charBufferLen);
  4166         charBufferLen = 0;
  4167         return;
  4169       int32_t tablePos = findLastOrRoot(NS_HTML5TREE_BUILDER_TABLE);
  4170       int32_t templatePos = findLastOrRoot(NS_HTML5TREE_BUILDER_TEMPLATE);
  4171       if (templatePos >= tablePos) {
  4172         appendCharacters(stack[templatePos]->node, charBuffer, 0, charBufferLen);
  4173         charBufferLen = 0;
  4174         return;
  4176       nsHtml5StackNode* tableElt = stack[tablePos];
  4177       insertFosterParentedCharacters(charBuffer, 0, charBufferLen, tableElt->node, stack[tablePos - 1]->node);
  4178       charBufferLen = 0;
  4179       return;
  4181     appendCharacters(currentNode(), charBuffer, 0, charBufferLen);
  4182     charBufferLen = 0;
  4186 bool 
  4187 nsHtml5TreeBuilder::charBufferContainsNonWhitespace()
  4189   for (int32_t i = 0; i < charBufferLen; i++) {
  4190     switch(charBuffer[i]) {
  4191       case ' ':
  4192       case '\t':
  4193       case '\n':
  4194       case '\r':
  4195       case '\f': {
  4196         continue;
  4198       default: {
  4199         return true;
  4203   return false;
  4206 nsAHtml5TreeBuilderState* 
  4207 nsHtml5TreeBuilder::newSnapshot()
  4209   jArray<nsHtml5StackNode*,int32_t> listCopy = jArray<nsHtml5StackNode*,int32_t>::newJArray(listPtr + 1);
  4210   for (int32_t i = 0; i < listCopy.length; i++) {
  4211     nsHtml5StackNode* node = listOfActiveFormattingElements[i];
  4212     if (node) {
  4213       nsHtml5StackNode* newNode = new nsHtml5StackNode(node->getFlags(), node->ns, node->name, node->node, node->popName, node->attributes->cloneAttributes(nullptr));
  4214       listCopy[i] = newNode;
  4215     } else {
  4216       listCopy[i] = nullptr;
  4219   jArray<nsHtml5StackNode*,int32_t> stackCopy = jArray<nsHtml5StackNode*,int32_t>::newJArray(currentPtr + 1);
  4220   for (int32_t i = 0; i < stackCopy.length; i++) {
  4221     nsHtml5StackNode* node = stack[i];
  4222     int32_t listIndex = findInListOfActiveFormattingElements(node);
  4223     if (listIndex == -1) {
  4224       nsHtml5StackNode* newNode = new nsHtml5StackNode(node->getFlags(), node->ns, node->name, node->node, node->popName, nullptr);
  4225       stackCopy[i] = newNode;
  4226     } else {
  4227       stackCopy[i] = listCopy[listIndex];
  4228       stackCopy[i]->retain();
  4231   jArray<int32_t,int32_t> templateModeStackCopy = jArray<int32_t,int32_t>::newJArray(templateModePtr + 1);
  4232   nsHtml5ArrayCopy::arraycopy(templateModeStack, templateModeStackCopy, templateModeStackCopy.length);
  4233   return new nsHtml5StateSnapshot(stackCopy, listCopy, templateModeStackCopy, formPointer, headPointer, deepTreeSurrogateParent, mode, originalMode, framesetOk, needToDropLF, quirks);
  4236 bool 
  4237 nsHtml5TreeBuilder::snapshotMatches(nsAHtml5TreeBuilderState* snapshot)
  4239   jArray<nsHtml5StackNode*,int32_t> stackCopy = snapshot->getStack();
  4240   int32_t stackLen = snapshot->getStackLength();
  4241   jArray<nsHtml5StackNode*,int32_t> listCopy = snapshot->getListOfActiveFormattingElements();
  4242   int32_t listLen = snapshot->getListOfActiveFormattingElementsLength();
  4243   jArray<int32_t,int32_t> templateModeStackCopy = snapshot->getTemplateModeStack();
  4244   int32_t templateModeStackLen = snapshot->getTemplateModeStackLength();
  4245   if (stackLen != currentPtr + 1 || listLen != listPtr + 1 || templateModeStackLen != templateModePtr + 1 || formPointer != snapshot->getFormPointer() || headPointer != snapshot->getHeadPointer() || deepTreeSurrogateParent != snapshot->getDeepTreeSurrogateParent() || mode != snapshot->getMode() || originalMode != snapshot->getOriginalMode() || framesetOk != snapshot->isFramesetOk() || needToDropLF != snapshot->isNeedToDropLF() || quirks != snapshot->isQuirks()) {
  4246     return false;
  4248   for (int32_t i = listLen - 1; i >= 0; i--) {
  4249     if (!listCopy[i] && !listOfActiveFormattingElements[i]) {
  4250       continue;
  4251     } else if (!listCopy[i] || !listOfActiveFormattingElements[i]) {
  4252       return false;
  4254     if (listCopy[i]->node != listOfActiveFormattingElements[i]->node) {
  4255       return false;
  4258   for (int32_t i = stackLen - 1; i >= 0; i--) {
  4259     if (stackCopy[i]->node != stack[i]->node) {
  4260       return false;
  4263   for (int32_t i = templateModeStackLen - 1; i >= 0; i--) {
  4264     if (templateModeStackCopy[i] != templateModeStack[i]) {
  4265       return false;
  4268   return true;
  4271 void 
  4272 nsHtml5TreeBuilder::loadState(nsAHtml5TreeBuilderState* snapshot, nsHtml5AtomTable* interner)
  4274   jArray<nsHtml5StackNode*,int32_t> stackCopy = snapshot->getStack();
  4275   int32_t stackLen = snapshot->getStackLength();
  4276   jArray<nsHtml5StackNode*,int32_t> listCopy = snapshot->getListOfActiveFormattingElements();
  4277   int32_t listLen = snapshot->getListOfActiveFormattingElementsLength();
  4278   jArray<int32_t,int32_t> templateModeStackCopy = snapshot->getTemplateModeStack();
  4279   int32_t templateModeStackLen = snapshot->getTemplateModeStackLength();
  4280   for (int32_t i = 0; i <= listPtr; i++) {
  4281     if (listOfActiveFormattingElements[i]) {
  4282       listOfActiveFormattingElements[i]->release();
  4285   if (listOfActiveFormattingElements.length < listLen) {
  4286     listOfActiveFormattingElements = jArray<nsHtml5StackNode*,int32_t>::newJArray(listLen);
  4288   listPtr = listLen - 1;
  4289   for (int32_t i = 0; i <= currentPtr; i++) {
  4290     stack[i]->release();
  4292   if (stack.length < stackLen) {
  4293     stack = jArray<nsHtml5StackNode*,int32_t>::newJArray(stackLen);
  4295   currentPtr = stackLen - 1;
  4296   if (templateModeStack.length < templateModeStackLen) {
  4297     templateModeStack = jArray<int32_t,int32_t>::newJArray(templateModeStackLen);
  4299   templateModePtr = templateModeStackLen - 1;
  4300   for (int32_t i = 0; i < listLen; i++) {
  4301     nsHtml5StackNode* node = listCopy[i];
  4302     if (node) {
  4303       nsHtml5StackNode* newNode = new nsHtml5StackNode(node->getFlags(), node->ns, nsHtml5Portability::newLocalFromLocal(node->name, interner), node->node, nsHtml5Portability::newLocalFromLocal(node->popName, interner), node->attributes->cloneAttributes(nullptr));
  4304       listOfActiveFormattingElements[i] = newNode;
  4305     } else {
  4306       listOfActiveFormattingElements[i] = nullptr;
  4309   for (int32_t i = 0; i < stackLen; i++) {
  4310     nsHtml5StackNode* node = stackCopy[i];
  4311     int32_t listIndex = findInArray(node, listCopy);
  4312     if (listIndex == -1) {
  4313       nsHtml5StackNode* newNode = new nsHtml5StackNode(node->getFlags(), node->ns, nsHtml5Portability::newLocalFromLocal(node->name, interner), node->node, nsHtml5Portability::newLocalFromLocal(node->popName, interner), nullptr);
  4314       stack[i] = newNode;
  4315     } else {
  4316       stack[i] = listOfActiveFormattingElements[listIndex];
  4317       stack[i]->retain();
  4320   nsHtml5ArrayCopy::arraycopy(templateModeStackCopy, templateModeStack, templateModeStackLen);
  4321   formPointer = snapshot->getFormPointer();
  4322   headPointer = snapshot->getHeadPointer();
  4323   deepTreeSurrogateParent = snapshot->getDeepTreeSurrogateParent();
  4324   mode = snapshot->getMode();
  4325   originalMode = snapshot->getOriginalMode();
  4326   framesetOk = snapshot->isFramesetOk();
  4327   needToDropLF = snapshot->isNeedToDropLF();
  4328   quirks = snapshot->isQuirks();
  4331 int32_t 
  4332 nsHtml5TreeBuilder::findInArray(nsHtml5StackNode* node, jArray<nsHtml5StackNode*,int32_t> arr)
  4334   for (int32_t i = listPtr; i >= 0; i--) {
  4335     if (node == arr[i]) {
  4336       return i;
  4339   return -1;
  4342 nsIContentHandle* 
  4343 nsHtml5TreeBuilder::getFormPointer()
  4345   return formPointer;
  4348 nsIContentHandle* 
  4349 nsHtml5TreeBuilder::getHeadPointer()
  4351   return headPointer;
  4354 nsIContentHandle* 
  4355 nsHtml5TreeBuilder::getDeepTreeSurrogateParent()
  4357   return deepTreeSurrogateParent;
  4360 jArray<nsHtml5StackNode*,int32_t> 
  4361 nsHtml5TreeBuilder::getListOfActiveFormattingElements()
  4363   return listOfActiveFormattingElements;
  4366 jArray<nsHtml5StackNode*,int32_t> 
  4367 nsHtml5TreeBuilder::getStack()
  4369   return stack;
  4372 jArray<int32_t,int32_t> 
  4373 nsHtml5TreeBuilder::getTemplateModeStack()
  4375   return templateModeStack;
  4378 int32_t 
  4379 nsHtml5TreeBuilder::getMode()
  4381   return mode;
  4384 int32_t 
  4385 nsHtml5TreeBuilder::getOriginalMode()
  4387   return originalMode;
  4390 bool 
  4391 nsHtml5TreeBuilder::isFramesetOk()
  4393   return framesetOk;
  4396 bool 
  4397 nsHtml5TreeBuilder::isNeedToDropLF()
  4399   return needToDropLF;
  4402 bool 
  4403 nsHtml5TreeBuilder::isQuirks()
  4405   return quirks;
  4408 int32_t 
  4409 nsHtml5TreeBuilder::getListOfActiveFormattingElementsLength()
  4411   return listPtr + 1;
  4414 int32_t 
  4415 nsHtml5TreeBuilder::getStackLength()
  4417   return currentPtr + 1;
  4420 int32_t 
  4421 nsHtml5TreeBuilder::getTemplateModeStackLength()
  4423   return templateModePtr + 1;
  4426 void
  4427 nsHtml5TreeBuilder::initializeStatics()
  4431 void
  4432 nsHtml5TreeBuilder::releaseStatics()
  4437 #include "nsHtml5TreeBuilderCppSupplement.h"

mercurial