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