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.

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

mercurial