Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(952)

Side by Side Diff: third_party/WebKit/Source/core/html/parser/HTMLTreeBuilder.cpp

Issue 2751483005: Replace ASSERT, ASSERT_NOT_REACHED, and RELEASE_ASSERT in core/html/parser/ (Closed)
Patch Set: rebase Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2010 Google, Inc. All Rights Reserved. 2 * Copyright (C) 2010 Google, Inc. All Rights Reserved.
3 * Copyright (C) 2011, 2014 Apple Inc. All rights reserved. 3 * Copyright (C) 2011, 2014 Apple Inc. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 } 109 }
110 110
111 class HTMLTreeBuilder::CharacterTokenBuffer { 111 class HTMLTreeBuilder::CharacterTokenBuffer {
112 WTF_MAKE_NONCOPYABLE(CharacterTokenBuffer); 112 WTF_MAKE_NONCOPYABLE(CharacterTokenBuffer);
113 113
114 public: 114 public:
115 explicit CharacterTokenBuffer(AtomicHTMLToken* token) 115 explicit CharacterTokenBuffer(AtomicHTMLToken* token)
116 : m_characters(token->characters().impl()), 116 : m_characters(token->characters().impl()),
117 m_current(0), 117 m_current(0),
118 m_end(token->characters().length()) { 118 m_end(token->characters().length()) {
119 ASSERT(!isEmpty()); 119 DCHECK(!isEmpty());
120 } 120 }
121 121
122 explicit CharacterTokenBuffer(const String& characters) 122 explicit CharacterTokenBuffer(const String& characters)
123 : m_characters(characters.impl()), 123 : m_characters(characters.impl()),
124 m_current(0), 124 m_current(0),
125 m_end(characters.length()) { 125 m_end(characters.length()) {
126 ASSERT(!isEmpty()); 126 DCHECK(!isEmpty());
127 } 127 }
128 128
129 ~CharacterTokenBuffer() { ASSERT(isEmpty()); } 129 ~CharacterTokenBuffer() { DCHECK(isEmpty()); }
130 130
131 bool isEmpty() const { return m_current == m_end; } 131 bool isEmpty() const { return m_current == m_end; }
132 132
133 void skipAtMostOneLeadingNewline() { 133 void skipAtMostOneLeadingNewline() {
134 ASSERT(!isEmpty()); 134 DCHECK(!isEmpty());
135 if ((*m_characters)[m_current] == '\n') 135 if ((*m_characters)[m_current] == '\n')
136 ++m_current; 136 ++m_current;
137 } 137 }
138 138
139 void skipLeadingWhitespace() { skipLeading<isHTMLSpace<UChar>>(); } 139 void skipLeadingWhitespace() { skipLeading<isHTMLSpace<UChar>>(); }
140 140
141 StringView takeLeadingWhitespace() { 141 StringView takeLeadingWhitespace() {
142 return takeLeading<isHTMLSpace<UChar>>(); 142 return takeLeading<isHTMLSpace<UChar>>();
143 } 143 }
144 144
145 void skipLeadingNonWhitespace() { skipLeading<isNotHTMLSpace<UChar>>(); } 145 void skipLeadingNonWhitespace() { skipLeading<isNotHTMLSpace<UChar>>(); }
146 146
147 void skipRemaining() { m_current = m_end; } 147 void skipRemaining() { m_current = m_end; }
148 148
149 StringView takeRemaining() { 149 StringView takeRemaining() {
150 ASSERT(!isEmpty()); 150 DCHECK(!isEmpty());
151 unsigned start = m_current; 151 unsigned start = m_current;
152 m_current = m_end; 152 m_current = m_end;
153 return StringView(m_characters.get(), start, m_end - start); 153 return StringView(m_characters.get(), start, m_end - start);
154 } 154 }
155 155
156 void giveRemainingTo(StringBuilder& recipient) { 156 void giveRemainingTo(StringBuilder& recipient) {
157 if (m_characters->is8Bit()) 157 if (m_characters->is8Bit())
158 recipient.append(m_characters->characters8() + m_current, 158 recipient.append(m_characters->characters8() + m_current,
159 m_end - m_current); 159 m_end - m_current);
160 else 160 else
161 recipient.append(m_characters->characters16() + m_current, 161 recipient.append(m_characters->characters16() + m_current,
162 m_end - m_current); 162 m_end - m_current);
163 m_current = m_end; 163 m_current = m_end;
164 } 164 }
165 165
166 String takeRemainingWhitespace() { 166 String takeRemainingWhitespace() {
167 ASSERT(!isEmpty()); 167 DCHECK(!isEmpty());
168 const unsigned start = m_current; 168 const unsigned start = m_current;
169 m_current = m_end; // One way or another, we're taking everything! 169 m_current = m_end; // One way or another, we're taking everything!
170 170
171 unsigned length = 0; 171 unsigned length = 0;
172 for (unsigned i = start; i < m_end; ++i) { 172 for (unsigned i = start; i < m_end; ++i) {
173 if (isHTMLSpace<UChar>((*m_characters)[i])) 173 if (isHTMLSpace<UChar>((*m_characters)[i]))
174 ++length; 174 ++length;
175 } 175 }
176 // Returning the null string when there aren't any whitespace 176 // Returning the null string when there aren't any whitespace
177 // characters is slightly cleaner semantically because we don't want 177 // characters is slightly cleaner semantically because we don't want
(...skipping 10 matching lines...) Expand all
188 if (isHTMLSpace<UChar>(c)) 188 if (isHTMLSpace<UChar>(c))
189 result.append(c); 189 result.append(c);
190 } 190 }
191 191
192 return result.toString(); 192 return result.toString();
193 } 193 }
194 194
195 private: 195 private:
196 template <bool characterPredicate(UChar)> 196 template <bool characterPredicate(UChar)>
197 void skipLeading() { 197 void skipLeading() {
198 ASSERT(!isEmpty()); 198 DCHECK(!isEmpty());
199 while (characterPredicate((*m_characters)[m_current])) { 199 while (characterPredicate((*m_characters)[m_current])) {
200 if (++m_current == m_end) 200 if (++m_current == m_end)
201 return; 201 return;
202 } 202 }
203 } 203 }
204 204
205 template <bool characterPredicate(UChar)> 205 template <bool characterPredicate(UChar)>
206 StringView takeLeading() { 206 StringView takeLeading() {
207 ASSERT(!isEmpty()); 207 DCHECK(!isEmpty());
208 const unsigned start = m_current; 208 const unsigned start = m_current;
209 skipLeading<characterPredicate>(); 209 skipLeading<characterPredicate>();
210 return StringView(m_characters.get(), start, m_current - start); 210 return StringView(m_characters.get(), start, m_current - start);
211 } 211 }
212 212
213 RefPtr<StringImpl> m_characters; 213 RefPtr<StringImpl> m_characters;
214 unsigned m_current; 214 unsigned m_current;
215 unsigned m_end; 215 unsigned m_end;
216 }; 216 };
217 217
(...skipping 13 matching lines...) Expand all
231 231
232 HTMLTreeBuilder::HTMLTreeBuilder(HTMLDocumentParser* parser, 232 HTMLTreeBuilder::HTMLTreeBuilder(HTMLDocumentParser* parser,
233 DocumentFragment* fragment, 233 DocumentFragment* fragment,
234 Element* contextElement, 234 Element* contextElement,
235 ParserContentPolicy parserContentPolicy, 235 ParserContentPolicy parserContentPolicy,
236 const HTMLParserOptions& options) 236 const HTMLParserOptions& options)
237 : HTMLTreeBuilder(parser, 237 : HTMLTreeBuilder(parser,
238 fragment->document(), 238 fragment->document(),
239 parserContentPolicy, 239 parserContentPolicy,
240 options) { 240 options) {
241 ASSERT(isMainThread()); 241 DCHECK(isMainThread());
242 ASSERT(contextElement); 242 DCHECK(contextElement);
243 m_tree.initFragmentParsing(fragment, contextElement); 243 m_tree.initFragmentParsing(fragment, contextElement);
244 m_fragmentContext.init(fragment, contextElement); 244 m_fragmentContext.init(fragment, contextElement);
245 245
246 // Steps 4.2-4.6 of the HTML5 Fragment Case parsing algorithm: 246 // Steps 4.2-4.6 of the HTML5 Fragment Case parsing algorithm:
247 // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#fr agment-case 247 // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#fr agment-case
248 // For efficiency, we skip step 4.2 ("Let root be a new html element with no 248 // For efficiency, we skip step 4.2 ("Let root be a new html element with no
249 // attributes") and instead use the DocumentFragment as a root node. 249 // attributes") and instead use the DocumentFragment as a root node.
250 m_tree.openElements()->pushRootNode(HTMLStackItem::create( 250 m_tree.openElements()->pushRootNode(HTMLStackItem::create(
251 fragment, HTMLStackItem::ItemForDocumentFragmentNode)); 251 fragment, HTMLStackItem::ItemForDocumentFragmentNode));
252 252
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 // DocumentParser expects detach() to always be called before it's destroyed. 285 // DocumentParser expects detach() to always be called before it's destroyed.
286 m_isAttached = false; 286 m_isAttached = false;
287 #endif 287 #endif
288 // HTMLConstructionSite might be on the callstack when detach() is called 288 // HTMLConstructionSite might be on the callstack when detach() is called
289 // otherwise we'd just call m_tree.clear() here instead. 289 // otherwise we'd just call m_tree.clear() here instead.
290 m_tree.detach(); 290 m_tree.detach();
291 } 291 }
292 292
293 Element* HTMLTreeBuilder::takeScriptToProcess( 293 Element* HTMLTreeBuilder::takeScriptToProcess(
294 TextPosition& scriptStartPosition) { 294 TextPosition& scriptStartPosition) {
295 ASSERT(m_scriptToProcess); 295 DCHECK(m_scriptToProcess);
296 ASSERT(!m_tree.hasPendingTasks()); 296 DCHECK(!m_tree.hasPendingTasks());
297 // Unpause ourselves, callers may pause us again when processing the script. 297 // Unpause ourselves, callers may pause us again when processing the script.
298 // The HTML5 spec is written as though scripts are executed inside the tree 298 // The HTML5 spec is written as though scripts are executed inside the tree
299 // builder. We pause the parser to exit the tree builder, and then resume 299 // builder. We pause the parser to exit the tree builder, and then resume
300 // before running scripts. 300 // before running scripts.
301 scriptStartPosition = m_scriptToProcessStartPosition; 301 scriptStartPosition = m_scriptToProcessStartPosition;
302 m_scriptToProcessStartPosition = uninitializedPositionValue1(); 302 m_scriptToProcessStartPosition = uninitializedPositionValue1();
303 return m_scriptToProcess.release(); 303 return m_scriptToProcess.release();
304 } 304 }
305 305
306 void HTMLTreeBuilder::constructTree(AtomicHTMLToken* token) { 306 void HTMLTreeBuilder::constructTree(AtomicHTMLToken* token) {
(...skipping 29 matching lines...) Expand all
336 336
337 // Any non-character token needs to cause us to flush any pending text 337 // Any non-character token needs to cause us to flush any pending text
338 // immediately. NOTE: flush() can cause any queued tasks to execute, possibly 338 // immediately. NOTE: flush() can cause any queued tasks to execute, possibly
339 // re-entering the parser. 339 // re-entering the parser.
340 m_tree.flush(FlushAlways); 340 m_tree.flush(FlushAlways);
341 m_shouldSkipLeadingNewline = false; 341 m_shouldSkipLeadingNewline = false;
342 342
343 switch (token->type()) { 343 switch (token->type()) {
344 case HTMLToken::Uninitialized: 344 case HTMLToken::Uninitialized:
345 case HTMLToken::Character: 345 case HTMLToken::Character:
346 ASSERT_NOT_REACHED(); 346 NOTREACHED();
347 break; 347 break;
348 case HTMLToken::DOCTYPE: 348 case HTMLToken::DOCTYPE:
349 processDoctypeToken(token); 349 processDoctypeToken(token);
350 break; 350 break;
351 case HTMLToken::StartTag: 351 case HTMLToken::StartTag:
352 processStartTag(token); 352 processStartTag(token);
353 break; 353 break;
354 case HTMLToken::EndTag: 354 case HTMLToken::EndTag:
355 processEndTag(token); 355 processEndTag(token);
356 break; 356 break;
357 case HTMLToken::Comment: 357 case HTMLToken::Comment:
358 processComment(token); 358 processComment(token);
359 break; 359 break;
360 case HTMLToken::EndOfFile: 360 case HTMLToken::EndOfFile:
361 processEndOfFile(token); 361 processEndOfFile(token);
362 break; 362 break;
363 } 363 }
364 } 364 }
365 365
366 void HTMLTreeBuilder::processDoctypeToken(AtomicHTMLToken* token) { 366 void HTMLTreeBuilder::processDoctypeToken(AtomicHTMLToken* token) {
367 ASSERT(token->type() == HTMLToken::DOCTYPE); 367 DCHECK_EQ(token->type(), HTMLToken::DOCTYPE);
368 if (m_insertionMode == InitialMode) { 368 if (m_insertionMode == InitialMode) {
369 m_tree.insertDoctype(token); 369 m_tree.insertDoctype(token);
370 setInsertionMode(BeforeHTMLMode); 370 setInsertionMode(BeforeHTMLMode);
371 return; 371 return;
372 } 372 }
373 if (m_insertionMode == InTableTextMode) { 373 if (m_insertionMode == InTableTextMode) {
374 defaultForInTableText(); 374 defaultForInTableText();
375 processDoctypeToken(token); 375 processDoctypeToken(token);
376 return; 376 return;
377 } 377 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 } // namespace 418 } // namespace
419 419
420 template <bool shouldClose(const HTMLStackItem*)> 420 template <bool shouldClose(const HTMLStackItem*)>
421 void HTMLTreeBuilder::processCloseWhenNestedTag(AtomicHTMLToken* token) { 421 void HTMLTreeBuilder::processCloseWhenNestedTag(AtomicHTMLToken* token) {
422 m_framesetOk = false; 422 m_framesetOk = false;
423 HTMLElementStack::ElementRecord* nodeRecord = 423 HTMLElementStack::ElementRecord* nodeRecord =
424 m_tree.openElements()->topRecord(); 424 m_tree.openElements()->topRecord();
425 while (1) { 425 while (1) {
426 HTMLStackItem* item = nodeRecord->stackItem(); 426 HTMLStackItem* item = nodeRecord->stackItem();
427 if (shouldClose(item)) { 427 if (shouldClose(item)) {
428 ASSERT(item->isElementNode()); 428 DCHECK(item->isElementNode());
429 processFakeEndTag(item->localName()); 429 processFakeEndTag(item->localName());
430 break; 430 break;
431 } 431 }
432 if (item->isSpecialNode() && !item->hasTagName(addressTag) && 432 if (item->isSpecialNode() && !item->hasTagName(addressTag) &&
433 !item->hasTagName(divTag) && !item->hasTagName(pTag)) 433 !item->hasTagName(divTag) && !item->hasTagName(pTag))
434 break; 434 break;
435 nodeRecord = nodeRecord->next(); 435 nodeRecord = nodeRecord->next();
436 } 436 }
437 processFakePEndTagIfPInButtonScope(); 437 processFakePEndTagIfPInButtonScope();
438 m_tree.insertHTMLElement(token); 438 m_tree.insertHTMLElement(token);
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
526 526
527 for (unsigned i = 0; i < token->attributes().size(); ++i) { 527 for (unsigned i = 0; i < token->attributes().size(); ++i) {
528 Attribute& tokenAttribute = token->attributes().at(i); 528 Attribute& tokenAttribute = token->attributes().at(i);
529 const QualifiedName& name = map->at(tokenAttribute.localName()); 529 const QualifiedName& name = map->at(tokenAttribute.localName());
530 if (!name.localName().isNull()) 530 if (!name.localName().isNull())
531 tokenAttribute.parserSetName(name); 531 tokenAttribute.parserSetName(name);
532 } 532 }
533 } 533 }
534 534
535 void HTMLTreeBuilder::processStartTagForInBody(AtomicHTMLToken* token) { 535 void HTMLTreeBuilder::processStartTagForInBody(AtomicHTMLToken* token) {
536 ASSERT(token->type() == HTMLToken::StartTag); 536 DCHECK_EQ(token->type(), HTMLToken::StartTag);
537 if (token->name() == htmlTag) { 537 if (token->name() == htmlTag) {
538 processHtmlStartTagForInBody(token); 538 processHtmlStartTagForInBody(token);
539 return; 539 return;
540 } 540 }
541 if (token->name() == baseTag || token->name() == basefontTag || 541 if (token->name() == baseTag || token->name() == basefontTag ||
542 token->name() == bgsoundTag || token->name() == commandTag || 542 token->name() == bgsoundTag || token->name() == commandTag ||
543 token->name() == linkTag || token->name() == metaTag || 543 token->name() == linkTag || token->name() == metaTag ||
544 token->name() == noframesTag || token->name() == scriptTag || 544 token->name() == noframesTag || token->name() == scriptTag ||
545 token->name() == styleTag || token->name() == titleTag) { 545 token->name() == styleTag || token->name() == titleTag) {
546 bool didProcess = processStartTagForInHead(token); 546 bool didProcess = processStartTagForInHead(token);
547 DCHECK(didProcess); 547 DCHECK(didProcess);
548 return; 548 return;
549 } 549 }
550 if (token->name() == bodyTag) { 550 if (token->name() == bodyTag) {
551 parseError(token); 551 parseError(token);
552 if (!m_tree.openElements()->secondElementIsHTMLBodyElement() || 552 if (!m_tree.openElements()->secondElementIsHTMLBodyElement() ||
553 m_tree.openElements()->hasOnlyOneElement() || 553 m_tree.openElements()->hasOnlyOneElement() ||
554 m_tree.openElements()->hasTemplateInHTMLScope()) { 554 m_tree.openElements()->hasTemplateInHTMLScope()) {
555 ASSERT(isParsingFragmentOrTemplateContents()); 555 DCHECK(isParsingFragmentOrTemplateContents());
556 return; 556 return;
557 } 557 }
558 m_framesetOk = false; 558 m_framesetOk = false;
559 m_tree.insertHTMLBodyStartTagInBody(token); 559 m_tree.insertHTMLBodyStartTagInBody(token);
560 return; 560 return;
561 } 561 }
562 if (token->name() == framesetTag) { 562 if (token->name() == framesetTag) {
563 parseError(token); 563 parseError(token);
564 if (!m_tree.openElements()->secondElementIsHTMLBodyElement() || 564 if (!m_tree.openElements()->secondElementIsHTMLBodyElement() ||
565 m_tree.openElements()->hasOnlyOneElement()) { 565 m_tree.openElements()->hasOnlyOneElement()) {
566 ASSERT(isParsingFragmentOrTemplateContents()); 566 DCHECK(isParsingFragmentOrTemplateContents());
567 return; 567 return;
568 } 568 }
569 if (!m_framesetOk) 569 if (!m_framesetOk)
570 return; 570 return;
571 m_tree.openElements()->bodyElement()->remove(ASSERT_NO_EXCEPTION); 571 m_tree.openElements()->bodyElement()->remove(ASSERT_NO_EXCEPTION);
572 m_tree.openElements()->popUntil(m_tree.openElements()->bodyElement()); 572 m_tree.openElements()->popUntil(m_tree.openElements()->bodyElement());
573 m_tree.openElements()->popHTMLBodyElement(); 573 m_tree.openElements()->popHTMLBodyElement();
574 574
575 // Note: in the fragment case the root is a DocumentFragment instead of 575 // Note: in the fragment case the root is a DocumentFragment instead of
576 // a proper html element which is a quirk in Blink's implementation. 576 // a proper html element which is a quirk in Blink's implementation.
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
846 846
847 void HTMLTreeBuilder::processTemplateStartTag(AtomicHTMLToken* token) { 847 void HTMLTreeBuilder::processTemplateStartTag(AtomicHTMLToken* token) {
848 m_tree.activeFormattingElements()->appendMarker(); 848 m_tree.activeFormattingElements()->appendMarker();
849 m_tree.insertHTMLElement(token); 849 m_tree.insertHTMLElement(token);
850 m_framesetOk = false; 850 m_framesetOk = false;
851 m_templateInsertionModes.push_back(TemplateContentsMode); 851 m_templateInsertionModes.push_back(TemplateContentsMode);
852 setInsertionMode(TemplateContentsMode); 852 setInsertionMode(TemplateContentsMode);
853 } 853 }
854 854
855 bool HTMLTreeBuilder::processTemplateEndTag(AtomicHTMLToken* token) { 855 bool HTMLTreeBuilder::processTemplateEndTag(AtomicHTMLToken* token) {
856 ASSERT(token->name() == templateTag.localName()); 856 DCHECK_EQ(token->name(), templateTag.localName());
857 if (!m_tree.openElements()->hasTemplateInHTMLScope()) { 857 if (!m_tree.openElements()->hasTemplateInHTMLScope()) {
858 ASSERT(m_templateInsertionModes.isEmpty() || 858 DCHECK(m_templateInsertionModes.isEmpty() ||
859 (m_templateInsertionModes.size() == 1 && 859 (m_templateInsertionModes.size() == 1 &&
860 isHTMLTemplateElement(m_fragmentContext.contextElement()))); 860 isHTMLTemplateElement(m_fragmentContext.contextElement())));
861 parseError(token); 861 parseError(token);
862 return false; 862 return false;
863 } 863 }
864 m_tree.generateImpliedEndTags(); 864 m_tree.generateImpliedEndTags();
865 if (!m_tree.currentStackItem()->hasTagName(templateTag)) 865 if (!m_tree.currentStackItem()->hasTagName(templateTag))
866 parseError(token); 866 parseError(token);
867 m_tree.openElements()->popUntilPopped(templateTag); 867 m_tree.openElements()->popUntilPopped(templateTag);
868 m_tree.activeFormattingElements()->clearToLastMarker(); 868 m_tree.activeFormattingElements()->clearToLastMarker();
869 m_templateInsertionModes.pop_back(); 869 m_templateInsertionModes.pop_back();
870 resetInsertionModeAppropriately(); 870 resetInsertionModeAppropriately();
871 return true; 871 return true;
872 } 872 }
873 873
874 bool HTMLTreeBuilder::processEndOfFileForInTemplateContents( 874 bool HTMLTreeBuilder::processEndOfFileForInTemplateContents(
875 AtomicHTMLToken* token) { 875 AtomicHTMLToken* token) {
876 AtomicHTMLToken endTemplate(HTMLToken::EndTag, templateTag.localName()); 876 AtomicHTMLToken endTemplate(HTMLToken::EndTag, templateTag.localName());
877 if (!processTemplateEndTag(&endTemplate)) 877 if (!processTemplateEndTag(&endTemplate))
878 return false; 878 return false;
879 879
880 processEndOfFile(token); 880 processEndOfFile(token);
881 return true; 881 return true;
882 } 882 }
883 883
884 bool HTMLTreeBuilder::processColgroupEndTagForInColumnGroup() { 884 bool HTMLTreeBuilder::processColgroupEndTagForInColumnGroup() {
885 if (m_tree.currentIsRootNode() || 885 if (m_tree.currentIsRootNode() ||
886 isHTMLTemplateElement(*m_tree.currentNode())) { 886 isHTMLTemplateElement(*m_tree.currentNode())) {
887 ASSERT(isParsingFragmentOrTemplateContents()); 887 DCHECK(isParsingFragmentOrTemplateContents());
888 // FIXME: parse error 888 // FIXME: parse error
889 return false; 889 return false;
890 } 890 }
891 m_tree.openElements()->pop(); 891 m_tree.openElements()->pop();
892 setInsertionMode(InTableMode); 892 setInsertionMode(InTableMode);
893 return true; 893 return true;
894 } 894 }
895 895
896 // http://www.whatwg.org/specs/web-apps/current-work/#adjusted-current-node 896 // http://www.whatwg.org/specs/web-apps/current-work/#adjusted-current-node
897 HTMLStackItem* HTMLTreeBuilder::adjustedCurrentStackItem() const { 897 HTMLStackItem* HTMLTreeBuilder::adjustedCurrentStackItem() const {
898 ASSERT(!m_tree.isEmpty()); 898 DCHECK(!m_tree.isEmpty());
899 if (isParsingFragment() && m_tree.openElements()->hasOnlyOneElement()) 899 if (isParsingFragment() && m_tree.openElements()->hasOnlyOneElement())
900 return m_fragmentContext.contextElementStackItem(); 900 return m_fragmentContext.contextElementStackItem();
901 901
902 return m_tree.currentStackItem(); 902 return m_tree.currentStackItem();
903 } 903 }
904 904
905 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html #close-the-cell 905 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html #close-the-cell
906 void HTMLTreeBuilder::closeTheCell() { 906 void HTMLTreeBuilder::closeTheCell() {
907 ASSERT(getInsertionMode() == InCellMode); 907 DCHECK_EQ(getInsertionMode(), InCellMode);
908 if (m_tree.openElements()->inTableScope(tdTag)) { 908 if (m_tree.openElements()->inTableScope(tdTag)) {
909 ASSERT(!m_tree.openElements()->inTableScope(thTag)); 909 DCHECK(!m_tree.openElements()->inTableScope(thTag));
910 processFakeEndTag(tdTag); 910 processFakeEndTag(tdTag);
911 return; 911 return;
912 } 912 }
913 ASSERT(m_tree.openElements()->inTableScope(thTag)); 913 DCHECK(m_tree.openElements()->inTableScope(thTag));
914 processFakeEndTag(thTag); 914 processFakeEndTag(thTag);
915 ASSERT(getInsertionMode() == InRowMode); 915 DCHECK_EQ(getInsertionMode(), InRowMode);
916 } 916 }
917 917
918 void HTMLTreeBuilder::processStartTagForInTable(AtomicHTMLToken* token) { 918 void HTMLTreeBuilder::processStartTagForInTable(AtomicHTMLToken* token) {
919 ASSERT(token->type() == HTMLToken::StartTag); 919 DCHECK_EQ(token->type(), HTMLToken::StartTag);
920 if (token->name() == captionTag) { 920 if (token->name() == captionTag) {
921 m_tree.openElements()->popUntilTableScopeMarker(); 921 m_tree.openElements()->popUntilTableScopeMarker();
922 m_tree.activeFormattingElements()->appendMarker(); 922 m_tree.activeFormattingElements()->appendMarker();
923 m_tree.insertHTMLElement(token); 923 m_tree.insertHTMLElement(token);
924 setInsertionMode(InCaptionMode); 924 setInsertionMode(InCaptionMode);
925 return; 925 return;
926 } 926 }
927 if (token->name() == colgroupTag) { 927 if (token->name() == colgroupTag) {
928 m_tree.openElements()->popUntilTableScopeMarker(); 928 m_tree.openElements()->popUntilTableScopeMarker();
929 m_tree.insertHTMLElement(token); 929 m_tree.insertHTMLElement(token);
930 setInsertionMode(InColumnGroupMode); 930 setInsertionMode(InColumnGroupMode);
931 return; 931 return;
932 } 932 }
933 if (token->name() == colTag) { 933 if (token->name() == colTag) {
934 processFakeStartTag(colgroupTag); 934 processFakeStartTag(colgroupTag);
935 ASSERT(InColumnGroupMode); 935 DCHECK(InColumnGroupMode);
936 processStartTag(token); 936 processStartTag(token);
937 return; 937 return;
938 } 938 }
939 if (isTableBodyContextTag(token->name())) { 939 if (isTableBodyContextTag(token->name())) {
940 m_tree.openElements()->popUntilTableScopeMarker(); 940 m_tree.openElements()->popUntilTableScopeMarker();
941 m_tree.insertHTMLElement(token); 941 m_tree.insertHTMLElement(token);
942 setInsertionMode(InTableBodyMode); 942 setInsertionMode(InTableBodyMode);
943 return; 943 return;
944 } 944 }
945 if (isTableCellContextTag(token->name()) || token->name() == trTag) { 945 if (isTableCellContextTag(token->name()) || token->name() == trTag) {
946 processFakeStartTag(tbodyTag); 946 processFakeStartTag(tbodyTag);
947 ASSERT(getInsertionMode() == InTableBodyMode); 947 DCHECK_EQ(getInsertionMode(), InTableBodyMode);
948 processStartTag(token); 948 processStartTag(token);
949 return; 949 return;
950 } 950 }
951 if (token->name() == tableTag) { 951 if (token->name() == tableTag) {
952 parseError(token); 952 parseError(token);
953 if (!processTableEndTagForInTable()) { 953 if (!processTableEndTagForInTable()) {
954 ASSERT(isParsingFragmentOrTemplateContents()); 954 DCHECK(isParsingFragmentOrTemplateContents());
955 return; 955 return;
956 } 956 }
957 processStartTag(token); 957 processStartTag(token);
958 return; 958 return;
959 } 959 }
960 if (token->name() == styleTag || token->name() == scriptTag) { 960 if (token->name() == styleTag || token->name() == scriptTag) {
961 processStartTagForInHead(token); 961 processStartTagForInHead(token);
962 return; 962 return;
963 } 963 }
964 if (token->name() == inputTag) { 964 if (token->name() == inputTag) {
(...skipping 16 matching lines...) Expand all
981 if (token->name() == templateTag) { 981 if (token->name() == templateTag) {
982 processTemplateStartTag(token); 982 processTemplateStartTag(token);
983 return; 983 return;
984 } 984 }
985 parseError(token); 985 parseError(token);
986 HTMLConstructionSite::RedirectToFosterParentGuard redirecter(m_tree); 986 HTMLConstructionSite::RedirectToFosterParentGuard redirecter(m_tree);
987 processStartTagForInBody(token); 987 processStartTagForInBody(token);
988 } 988 }
989 989
990 void HTMLTreeBuilder::processStartTag(AtomicHTMLToken* token) { 990 void HTMLTreeBuilder::processStartTag(AtomicHTMLToken* token) {
991 ASSERT(token->type() == HTMLToken::StartTag); 991 DCHECK_EQ(token->type(), HTMLToken::StartTag);
992 switch (getInsertionMode()) { 992 switch (getInsertionMode()) {
993 case InitialMode: 993 case InitialMode:
994 ASSERT(getInsertionMode() == InitialMode); 994 DCHECK_EQ(getInsertionMode(), InitialMode);
995 defaultForInitial(); 995 defaultForInitial();
996 // Fall through. 996 // Fall through.
997 case BeforeHTMLMode: 997 case BeforeHTMLMode:
998 ASSERT(getInsertionMode() == BeforeHTMLMode); 998 DCHECK_EQ(getInsertionMode(), BeforeHTMLMode);
999 if (token->name() == htmlTag) { 999 if (token->name() == htmlTag) {
1000 m_tree.insertHTMLHtmlStartTagBeforeHTML(token); 1000 m_tree.insertHTMLHtmlStartTagBeforeHTML(token);
1001 setInsertionMode(BeforeHeadMode); 1001 setInsertionMode(BeforeHeadMode);
1002 return; 1002 return;
1003 } 1003 }
1004 defaultForBeforeHTML(); 1004 defaultForBeforeHTML();
1005 // Fall through. 1005 // Fall through.
1006 case BeforeHeadMode: 1006 case BeforeHeadMode:
1007 ASSERT(getInsertionMode() == BeforeHeadMode); 1007 DCHECK_EQ(getInsertionMode(), BeforeHeadMode);
1008 if (token->name() == htmlTag) { 1008 if (token->name() == htmlTag) {
1009 processHtmlStartTagForInBody(token); 1009 processHtmlStartTagForInBody(token);
1010 return; 1010 return;
1011 } 1011 }
1012 if (token->name() == headTag) { 1012 if (token->name() == headTag) {
1013 m_tree.insertHTMLHeadElement(token); 1013 m_tree.insertHTMLHeadElement(token);
1014 setInsertionMode(InHeadMode); 1014 setInsertionMode(InHeadMode);
1015 return; 1015 return;
1016 } 1016 }
1017 defaultForBeforeHead(); 1017 defaultForBeforeHead();
1018 // Fall through. 1018 // Fall through.
1019 case InHeadMode: 1019 case InHeadMode:
1020 ASSERT(getInsertionMode() == InHeadMode); 1020 DCHECK_EQ(getInsertionMode(), InHeadMode);
1021 if (processStartTagForInHead(token)) 1021 if (processStartTagForInHead(token))
1022 return; 1022 return;
1023 defaultForInHead(); 1023 defaultForInHead();
1024 // Fall through. 1024 // Fall through.
1025 case AfterHeadMode: 1025 case AfterHeadMode:
1026 ASSERT(getInsertionMode() == AfterHeadMode); 1026 DCHECK_EQ(getInsertionMode(), AfterHeadMode);
1027 if (token->name() == htmlTag) { 1027 if (token->name() == htmlTag) {
1028 processHtmlStartTagForInBody(token); 1028 processHtmlStartTagForInBody(token);
1029 return; 1029 return;
1030 } 1030 }
1031 if (token->name() == bodyTag) { 1031 if (token->name() == bodyTag) {
1032 m_framesetOk = false; 1032 m_framesetOk = false;
1033 m_tree.insertHTMLBodyElement(token); 1033 m_tree.insertHTMLBodyElement(token);
1034 setInsertionMode(InBodyMode); 1034 setInsertionMode(InBodyMode);
1035 return; 1035 return;
1036 } 1036 }
1037 if (token->name() == framesetTag) { 1037 if (token->name() == framesetTag) {
1038 m_tree.insertHTMLElement(token); 1038 m_tree.insertHTMLElement(token);
1039 setInsertionMode(InFramesetMode); 1039 setInsertionMode(InFramesetMode);
1040 return; 1040 return;
1041 } 1041 }
1042 if (token->name() == baseTag || token->name() == basefontTag || 1042 if (token->name() == baseTag || token->name() == basefontTag ||
1043 token->name() == bgsoundTag || token->name() == linkTag || 1043 token->name() == bgsoundTag || token->name() == linkTag ||
1044 token->name() == metaTag || token->name() == noframesTag || 1044 token->name() == metaTag || token->name() == noframesTag ||
1045 token->name() == scriptTag || token->name() == styleTag || 1045 token->name() == scriptTag || token->name() == styleTag ||
1046 token->name() == templateTag || token->name() == titleTag) { 1046 token->name() == templateTag || token->name() == titleTag) {
1047 parseError(token); 1047 parseError(token);
1048 ASSERT(m_tree.head()); 1048 DCHECK(m_tree.head());
1049 m_tree.openElements()->pushHTMLHeadElement(m_tree.headStackItem()); 1049 m_tree.openElements()->pushHTMLHeadElement(m_tree.headStackItem());
1050 processStartTagForInHead(token); 1050 processStartTagForInHead(token);
1051 m_tree.openElements()->removeHTMLHeadElement(m_tree.head()); 1051 m_tree.openElements()->removeHTMLHeadElement(m_tree.head());
1052 return; 1052 return;
1053 } 1053 }
1054 if (token->name() == headTag) { 1054 if (token->name() == headTag) {
1055 parseError(token); 1055 parseError(token);
1056 return; 1056 return;
1057 } 1057 }
1058 defaultForAfterHead(); 1058 defaultForAfterHead();
1059 // Fall through 1059 // Fall through
1060 case InBodyMode: 1060 case InBodyMode:
1061 ASSERT(getInsertionMode() == InBodyMode); 1061 DCHECK_EQ(getInsertionMode(), InBodyMode);
1062 processStartTagForInBody(token); 1062 processStartTagForInBody(token);
1063 break; 1063 break;
1064 case InTableMode: 1064 case InTableMode:
1065 ASSERT(getInsertionMode() == InTableMode); 1065 DCHECK_EQ(getInsertionMode(), InTableMode);
1066 processStartTagForInTable(token); 1066 processStartTagForInTable(token);
1067 break; 1067 break;
1068 case InCaptionMode: 1068 case InCaptionMode:
1069 ASSERT(getInsertionMode() == InCaptionMode); 1069 DCHECK_EQ(getInsertionMode(), InCaptionMode);
1070 if (isCaptionColOrColgroupTag(token->name()) || 1070 if (isCaptionColOrColgroupTag(token->name()) ||
1071 isTableBodyContextTag(token->name()) || 1071 isTableBodyContextTag(token->name()) ||
1072 isTableCellContextTag(token->name()) || token->name() == trTag) { 1072 isTableCellContextTag(token->name()) || token->name() == trTag) {
1073 parseError(token); 1073 parseError(token);
1074 if (!processCaptionEndTagForInCaption()) { 1074 if (!processCaptionEndTagForInCaption()) {
1075 ASSERT(isParsingFragment()); 1075 DCHECK(isParsingFragment());
1076 return; 1076 return;
1077 } 1077 }
1078 processStartTag(token); 1078 processStartTag(token);
1079 return; 1079 return;
1080 } 1080 }
1081 processStartTagForInBody(token); 1081 processStartTagForInBody(token);
1082 break; 1082 break;
1083 case InColumnGroupMode: 1083 case InColumnGroupMode:
1084 ASSERT(getInsertionMode() == InColumnGroupMode); 1084 DCHECK_EQ(getInsertionMode(), InColumnGroupMode);
1085 if (token->name() == htmlTag) { 1085 if (token->name() == htmlTag) {
1086 processHtmlStartTagForInBody(token); 1086 processHtmlStartTagForInBody(token);
1087 return; 1087 return;
1088 } 1088 }
1089 if (token->name() == colTag) { 1089 if (token->name() == colTag) {
1090 m_tree.insertSelfClosingHTMLElementDestroyingToken(token); 1090 m_tree.insertSelfClosingHTMLElementDestroyingToken(token);
1091 return; 1091 return;
1092 } 1092 }
1093 if (token->name() == templateTag) { 1093 if (token->name() == templateTag) {
1094 processTemplateStartTag(token); 1094 processTemplateStartTag(token);
1095 return; 1095 return;
1096 } 1096 }
1097 if (!processColgroupEndTagForInColumnGroup()) { 1097 if (!processColgroupEndTagForInColumnGroup()) {
1098 ASSERT(isParsingFragmentOrTemplateContents()); 1098 DCHECK(isParsingFragmentOrTemplateContents());
1099 return; 1099 return;
1100 } 1100 }
1101 processStartTag(token); 1101 processStartTag(token);
1102 break; 1102 break;
1103 case InTableBodyMode: 1103 case InTableBodyMode:
1104 ASSERT(getInsertionMode() == InTableBodyMode); 1104 DCHECK_EQ(getInsertionMode(), InTableBodyMode);
1105 if (token->name() == trTag) { 1105 if (token->name() == trTag) {
1106 // How is there ever anything to pop? 1106 // How is there ever anything to pop?
1107 m_tree.openElements()->popUntilTableBodyScopeMarker(); 1107 m_tree.openElements()->popUntilTableBodyScopeMarker();
1108 m_tree.insertHTMLElement(token); 1108 m_tree.insertHTMLElement(token);
1109 setInsertionMode(InRowMode); 1109 setInsertionMode(InRowMode);
1110 return; 1110 return;
1111 } 1111 }
1112 if (isTableCellContextTag(token->name())) { 1112 if (isTableCellContextTag(token->name())) {
1113 parseError(token); 1113 parseError(token);
1114 processFakeStartTag(trTag); 1114 processFakeStartTag(trTag);
1115 ASSERT(getInsertionMode() == InRowMode); 1115 DCHECK_EQ(getInsertionMode(), InRowMode);
1116 processStartTag(token); 1116 processStartTag(token);
1117 return; 1117 return;
1118 } 1118 }
1119 if (isCaptionColOrColgroupTag(token->name()) || 1119 if (isCaptionColOrColgroupTag(token->name()) ||
1120 isTableBodyContextTag(token->name())) { 1120 isTableBodyContextTag(token->name())) {
1121 // FIXME: This is slow. 1121 // FIXME: This is slow.
1122 if (!m_tree.openElements()->inTableScope(tbodyTag) && 1122 if (!m_tree.openElements()->inTableScope(tbodyTag) &&
1123 !m_tree.openElements()->inTableScope(theadTag) && 1123 !m_tree.openElements()->inTableScope(theadTag) &&
1124 !m_tree.openElements()->inTableScope(tfootTag)) { 1124 !m_tree.openElements()->inTableScope(tfootTag)) {
1125 ASSERT(isParsingFragmentOrTemplateContents()); 1125 DCHECK(isParsingFragmentOrTemplateContents());
1126 parseError(token); 1126 parseError(token);
1127 return; 1127 return;
1128 } 1128 }
1129 m_tree.openElements()->popUntilTableBodyScopeMarker(); 1129 m_tree.openElements()->popUntilTableBodyScopeMarker();
1130 ASSERT(isTableBodyContextTag(m_tree.currentStackItem()->localName())); 1130 DCHECK(isTableBodyContextTag(m_tree.currentStackItem()->localName()));
1131 processFakeEndTag(m_tree.currentStackItem()->localName()); 1131 processFakeEndTag(m_tree.currentStackItem()->localName());
1132 processStartTag(token); 1132 processStartTag(token);
1133 return; 1133 return;
1134 } 1134 }
1135 processStartTagForInTable(token); 1135 processStartTagForInTable(token);
1136 break; 1136 break;
1137 case InRowMode: 1137 case InRowMode:
1138 ASSERT(getInsertionMode() == InRowMode); 1138 DCHECK_EQ(getInsertionMode(), InRowMode);
1139 if (isTableCellContextTag(token->name())) { 1139 if (isTableCellContextTag(token->name())) {
1140 m_tree.openElements()->popUntilTableRowScopeMarker(); 1140 m_tree.openElements()->popUntilTableRowScopeMarker();
1141 m_tree.insertHTMLElement(token); 1141 m_tree.insertHTMLElement(token);
1142 setInsertionMode(InCellMode); 1142 setInsertionMode(InCellMode);
1143 m_tree.activeFormattingElements()->appendMarker(); 1143 m_tree.activeFormattingElements()->appendMarker();
1144 return; 1144 return;
1145 } 1145 }
1146 if (token->name() == trTag || isCaptionColOrColgroupTag(token->name()) || 1146 if (token->name() == trTag || isCaptionColOrColgroupTag(token->name()) ||
1147 isTableBodyContextTag(token->name())) { 1147 isTableBodyContextTag(token->name())) {
1148 if (!processTrEndTagForInRow()) { 1148 if (!processTrEndTagForInRow()) {
1149 ASSERT(isParsingFragmentOrTemplateContents()); 1149 DCHECK(isParsingFragmentOrTemplateContents());
1150 return; 1150 return;
1151 } 1151 }
1152 ASSERT(getInsertionMode() == InTableBodyMode); 1152 DCHECK_EQ(getInsertionMode(), InTableBodyMode);
1153 processStartTag(token); 1153 processStartTag(token);
1154 return; 1154 return;
1155 } 1155 }
1156 processStartTagForInTable(token); 1156 processStartTagForInTable(token);
1157 break; 1157 break;
1158 case InCellMode: 1158 case InCellMode:
1159 ASSERT(getInsertionMode() == InCellMode); 1159 DCHECK_EQ(getInsertionMode(), InCellMode);
1160 if (isCaptionColOrColgroupTag(token->name()) || 1160 if (isCaptionColOrColgroupTag(token->name()) ||
1161 isTableCellContextTag(token->name()) || token->name() == trTag || 1161 isTableCellContextTag(token->name()) || token->name() == trTag ||
1162 isTableBodyContextTag(token->name())) { 1162 isTableBodyContextTag(token->name())) {
1163 // FIXME: This could be more efficient. 1163 // FIXME: This could be more efficient.
1164 if (!m_tree.openElements()->inTableScope(tdTag) && 1164 if (!m_tree.openElements()->inTableScope(tdTag) &&
1165 !m_tree.openElements()->inTableScope(thTag)) { 1165 !m_tree.openElements()->inTableScope(thTag)) {
1166 ASSERT(isParsingFragment()); 1166 DCHECK(isParsingFragment());
1167 parseError(token); 1167 parseError(token);
1168 return; 1168 return;
1169 } 1169 }
1170 closeTheCell(); 1170 closeTheCell();
1171 processStartTag(token); 1171 processStartTag(token);
1172 return; 1172 return;
1173 } 1173 }
1174 processStartTagForInBody(token); 1174 processStartTagForInBody(token);
1175 break; 1175 break;
1176 case AfterBodyMode: 1176 case AfterBodyMode:
1177 case AfterAfterBodyMode: 1177 case AfterAfterBodyMode:
1178 ASSERT(getInsertionMode() == AfterBodyMode || 1178 DCHECK(getInsertionMode() == AfterBodyMode ||
1179 getInsertionMode() == AfterAfterBodyMode); 1179 getInsertionMode() == AfterAfterBodyMode);
1180 if (token->name() == htmlTag) { 1180 if (token->name() == htmlTag) {
1181 processHtmlStartTagForInBody(token); 1181 processHtmlStartTagForInBody(token);
1182 return; 1182 return;
1183 } 1183 }
1184 setInsertionMode(InBodyMode); 1184 setInsertionMode(InBodyMode);
1185 processStartTag(token); 1185 processStartTag(token);
1186 break; 1186 break;
1187 case InHeadNoscriptMode: 1187 case InHeadNoscriptMode:
1188 ASSERT(getInsertionMode() == InHeadNoscriptMode); 1188 DCHECK_EQ(getInsertionMode(), InHeadNoscriptMode);
1189 if (token->name() == htmlTag) { 1189 if (token->name() == htmlTag) {
1190 processHtmlStartTagForInBody(token); 1190 processHtmlStartTagForInBody(token);
1191 return; 1191 return;
1192 } 1192 }
1193 if (token->name() == basefontTag || token->name() == bgsoundTag || 1193 if (token->name() == basefontTag || token->name() == bgsoundTag ||
1194 token->name() == linkTag || token->name() == metaTag || 1194 token->name() == linkTag || token->name() == metaTag ||
1195 token->name() == noframesTag || token->name() == styleTag) { 1195 token->name() == noframesTag || token->name() == styleTag) {
1196 bool didProcess = processStartTagForInHead(token); 1196 bool didProcess = processStartTagForInHead(token);
1197 DCHECK(didProcess); 1197 DCHECK(didProcess);
1198 return; 1198 return;
1199 } 1199 }
1200 if (token->name() == htmlTag || token->name() == noscriptTag) { 1200 if (token->name() == htmlTag || token->name() == noscriptTag) {
1201 parseError(token); 1201 parseError(token);
1202 return; 1202 return;
1203 } 1203 }
1204 defaultForInHeadNoscript(); 1204 defaultForInHeadNoscript();
1205 processToken(token); 1205 processToken(token);
1206 break; 1206 break;
1207 case InFramesetMode: 1207 case InFramesetMode:
1208 ASSERT(getInsertionMode() == InFramesetMode); 1208 DCHECK_EQ(getInsertionMode(), InFramesetMode);
1209 if (token->name() == htmlTag) { 1209 if (token->name() == htmlTag) {
1210 processHtmlStartTagForInBody(token); 1210 processHtmlStartTagForInBody(token);
1211 return; 1211 return;
1212 } 1212 }
1213 if (token->name() == framesetTag) { 1213 if (token->name() == framesetTag) {
1214 m_tree.insertHTMLElement(token); 1214 m_tree.insertHTMLElement(token);
1215 return; 1215 return;
1216 } 1216 }
1217 if (token->name() == frameTag) { 1217 if (token->name() == frameTag) {
1218 m_tree.insertSelfClosingHTMLElementDestroyingToken(token); 1218 m_tree.insertSelfClosingHTMLElementDestroyingToken(token);
1219 return; 1219 return;
1220 } 1220 }
1221 if (token->name() == noframesTag) { 1221 if (token->name() == noframesTag) {
1222 processStartTagForInHead(token); 1222 processStartTagForInHead(token);
1223 return; 1223 return;
1224 } 1224 }
1225 if (token->name() == templateTag) { 1225 if (token->name() == templateTag) {
1226 processTemplateStartTag(token); 1226 processTemplateStartTag(token);
1227 return; 1227 return;
1228 } 1228 }
1229 parseError(token); 1229 parseError(token);
1230 break; 1230 break;
1231 case AfterFramesetMode: 1231 case AfterFramesetMode:
1232 case AfterAfterFramesetMode: 1232 case AfterAfterFramesetMode:
1233 ASSERT(getInsertionMode() == AfterFramesetMode || 1233 DCHECK(getInsertionMode() == AfterFramesetMode ||
1234 getInsertionMode() == AfterAfterFramesetMode); 1234 getInsertionMode() == AfterAfterFramesetMode);
1235 if (token->name() == htmlTag) { 1235 if (token->name() == htmlTag) {
1236 processHtmlStartTagForInBody(token); 1236 processHtmlStartTagForInBody(token);
1237 return; 1237 return;
1238 } 1238 }
1239 if (token->name() == noframesTag) { 1239 if (token->name() == noframesTag) {
1240 processStartTagForInHead(token); 1240 processStartTagForInHead(token);
1241 return; 1241 return;
1242 } 1242 }
1243 parseError(token); 1243 parseError(token);
1244 break; 1244 break;
1245 case InSelectInTableMode: 1245 case InSelectInTableMode:
1246 ASSERT(getInsertionMode() == InSelectInTableMode); 1246 DCHECK_EQ(getInsertionMode(), InSelectInTableMode);
1247 if (token->name() == captionTag || token->name() == tableTag || 1247 if (token->name() == captionTag || token->name() == tableTag ||
1248 isTableBodyContextTag(token->name()) || token->name() == trTag || 1248 isTableBodyContextTag(token->name()) || token->name() == trTag ||
1249 isTableCellContextTag(token->name())) { 1249 isTableCellContextTag(token->name())) {
1250 parseError(token); 1250 parseError(token);
1251 AtomicHTMLToken endSelect(HTMLToken::EndTag, selectTag.localName()); 1251 AtomicHTMLToken endSelect(HTMLToken::EndTag, selectTag.localName());
1252 processEndTag(&endSelect); 1252 processEndTag(&endSelect);
1253 processStartTag(token); 1253 processStartTag(token);
1254 return; 1254 return;
1255 } 1255 }
1256 // Fall through 1256 // Fall through
1257 case InSelectMode: 1257 case InSelectMode:
1258 ASSERT(getInsertionMode() == InSelectMode || 1258 DCHECK(getInsertionMode() == InSelectMode ||
1259 getInsertionMode() == InSelectInTableMode); 1259 getInsertionMode() == InSelectInTableMode);
1260 if (token->name() == htmlTag) { 1260 if (token->name() == htmlTag) {
1261 processHtmlStartTagForInBody(token); 1261 processHtmlStartTagForInBody(token);
1262 return; 1262 return;
1263 } 1263 }
1264 if (token->name() == optionTag) { 1264 if (token->name() == optionTag) {
1265 if (m_tree.currentStackItem()->hasTagName(optionTag)) { 1265 if (m_tree.currentStackItem()->hasTagName(optionTag)) {
1266 AtomicHTMLToken endOption(HTMLToken::EndTag, optionTag.localName()); 1266 AtomicHTMLToken endOption(HTMLToken::EndTag, optionTag.localName());
1267 processEndTag(&endOption); 1267 processEndTag(&endOption);
1268 } 1268 }
(...skipping 16 matching lines...) Expand all
1285 if (token->name() == selectTag) { 1285 if (token->name() == selectTag) {
1286 parseError(token); 1286 parseError(token);
1287 AtomicHTMLToken endSelect(HTMLToken::EndTag, selectTag.localName()); 1287 AtomicHTMLToken endSelect(HTMLToken::EndTag, selectTag.localName());
1288 processEndTag(&endSelect); 1288 processEndTag(&endSelect);
1289 return; 1289 return;
1290 } 1290 }
1291 if (token->name() == inputTag || token->name() == keygenTag || 1291 if (token->name() == inputTag || token->name() == keygenTag ||
1292 token->name() == textareaTag) { 1292 token->name() == textareaTag) {
1293 parseError(token); 1293 parseError(token);
1294 if (!m_tree.openElements()->inSelectScope(selectTag)) { 1294 if (!m_tree.openElements()->inSelectScope(selectTag)) {
1295 ASSERT(isParsingFragment()); 1295 DCHECK(isParsingFragment());
1296 return; 1296 return;
1297 } 1297 }
1298 AtomicHTMLToken endSelect(HTMLToken::EndTag, selectTag.localName()); 1298 AtomicHTMLToken endSelect(HTMLToken::EndTag, selectTag.localName());
1299 processEndTag(&endSelect); 1299 processEndTag(&endSelect);
1300 processStartTag(token); 1300 processStartTag(token);
1301 return; 1301 return;
1302 } 1302 }
1303 if (token->name() == scriptTag) { 1303 if (token->name() == scriptTag) {
1304 bool didProcess = processStartTagForInHead(token); 1304 bool didProcess = processStartTagForInHead(token);
1305 DCHECK(didProcess); 1305 DCHECK(didProcess);
1306 return; 1306 return;
1307 } 1307 }
1308 if (token->name() == templateTag) { 1308 if (token->name() == templateTag) {
1309 processTemplateStartTag(token); 1309 processTemplateStartTag(token);
1310 return; 1310 return;
1311 } 1311 }
1312 break; 1312 break;
1313 case InTableTextMode: 1313 case InTableTextMode:
1314 defaultForInTableText(); 1314 defaultForInTableText();
1315 processStartTag(token); 1315 processStartTag(token);
1316 break; 1316 break;
1317 case TextMode: 1317 case TextMode:
1318 ASSERT_NOT_REACHED(); 1318 NOTREACHED();
1319 break; 1319 break;
1320 case TemplateContentsMode: 1320 case TemplateContentsMode:
1321 if (token->name() == templateTag) { 1321 if (token->name() == templateTag) {
1322 processTemplateStartTag(token); 1322 processTemplateStartTag(token);
1323 return; 1323 return;
1324 } 1324 }
1325 1325
1326 if (token->name() == linkTag || token->name() == scriptTag || 1326 if (token->name() == linkTag || token->name() == scriptTag ||
1327 token->name() == styleTag || token->name() == metaTag) { 1327 token->name() == styleTag || token->name() == metaTag) {
1328 processStartTagForInHead(token); 1328 processStartTagForInHead(token);
1329 return; 1329 return;
1330 } 1330 }
1331 1331
1332 InsertionMode insertionMode = TemplateContentsMode; 1332 InsertionMode insertionMode = TemplateContentsMode;
1333 if (token->name() == frameTag) 1333 if (token->name() == frameTag)
1334 insertionMode = InFramesetMode; 1334 insertionMode = InFramesetMode;
1335 else if (token->name() == colTag) 1335 else if (token->name() == colTag)
1336 insertionMode = InColumnGroupMode; 1336 insertionMode = InColumnGroupMode;
1337 else if (isCaptionColOrColgroupTag(token->name()) || 1337 else if (isCaptionColOrColgroupTag(token->name()) ||
1338 isTableBodyContextTag(token->name())) 1338 isTableBodyContextTag(token->name()))
1339 insertionMode = InTableMode; 1339 insertionMode = InTableMode;
1340 else if (token->name() == trTag) 1340 else if (token->name() == trTag)
1341 insertionMode = InTableBodyMode; 1341 insertionMode = InTableBodyMode;
1342 else if (isTableCellContextTag(token->name())) 1342 else if (isTableCellContextTag(token->name()))
1343 insertionMode = InRowMode; 1343 insertionMode = InRowMode;
1344 else 1344 else
1345 insertionMode = InBodyMode; 1345 insertionMode = InBodyMode;
1346 1346
1347 ASSERT(insertionMode != TemplateContentsMode); 1347 DCHECK_NE(insertionMode, TemplateContentsMode);
1348 ASSERT(m_templateInsertionModes.back() == TemplateContentsMode); 1348 DCHECK_EQ(m_templateInsertionModes.back(), TemplateContentsMode);
1349 m_templateInsertionModes.back() = insertionMode; 1349 m_templateInsertionModes.back() = insertionMode;
1350 setInsertionMode(insertionMode); 1350 setInsertionMode(insertionMode);
1351 1351
1352 processStartTag(token); 1352 processStartTag(token);
1353 break; 1353 break;
1354 } 1354 }
1355 } 1355 }
1356 1356
1357 void HTMLTreeBuilder::processHtmlStartTagForInBody(AtomicHTMLToken* token) { 1357 void HTMLTreeBuilder::processHtmlStartTagForInBody(AtomicHTMLToken* token) {
1358 parseError(token); 1358 parseError(token);
1359 if (m_tree.openElements()->hasTemplateInHTMLScope()) { 1359 if (m_tree.openElements()->hasTemplateInHTMLScope()) {
1360 ASSERT(isParsingTemplateContents()); 1360 DCHECK(isParsingTemplateContents());
1361 return; 1361 return;
1362 } 1362 }
1363 m_tree.insertHTMLHtmlStartTagInBody(token); 1363 m_tree.insertHTMLHtmlStartTagInBody(token);
1364 } 1364 }
1365 1365
1366 bool HTMLTreeBuilder::processBodyEndTagForInBody(AtomicHTMLToken* token) { 1366 bool HTMLTreeBuilder::processBodyEndTagForInBody(AtomicHTMLToken* token) {
1367 ASSERT(token->type() == HTMLToken::EndTag); 1367 DCHECK_EQ(token->type(), HTMLToken::EndTag);
1368 ASSERT(token->name() == bodyTag); 1368 DCHECK(token->name() == bodyTag);
1369 if (!m_tree.openElements()->inScope(bodyTag.localName())) { 1369 if (!m_tree.openElements()->inScope(bodyTag.localName())) {
1370 parseError(token); 1370 parseError(token);
1371 return false; 1371 return false;
1372 } 1372 }
1373 // Emit a more specific parse error based on stack contents. 1373 // Emit a more specific parse error based on stack contents.
1374 DVLOG(1) << "Not implmeneted."; 1374 DVLOG(1) << "Not implmeneted.";
1375 setInsertionMode(AfterBodyMode); 1375 setInsertionMode(AfterBodyMode);
1376 return true; 1376 return true;
1377 } 1377 }
1378 1378
1379 void HTMLTreeBuilder::processAnyOtherEndTagForInBody(AtomicHTMLToken* token) { 1379 void HTMLTreeBuilder::processAnyOtherEndTagForInBody(AtomicHTMLToken* token) {
1380 ASSERT(token->type() == HTMLToken::EndTag); 1380 DCHECK_EQ(token->type(), HTMLToken::EndTag);
1381 if (token->name() == menuitemTag) 1381 if (token->name() == menuitemTag)
1382 UseCounter::count(m_tree.currentNode()->document(), 1382 UseCounter::count(m_tree.currentNode()->document(),
1383 UseCounter::MenuItemCloseTag); 1383 UseCounter::MenuItemCloseTag);
1384 HTMLElementStack::ElementRecord* record = m_tree.openElements()->topRecord(); 1384 HTMLElementStack::ElementRecord* record = m_tree.openElements()->topRecord();
1385 while (1) { 1385 while (1) {
1386 HTMLStackItem* item = record->stackItem(); 1386 HTMLStackItem* item = record->stackItem();
1387 if (item->matchesHTMLTag(token->name())) { 1387 if (item->matchesHTMLTag(token->name())) {
1388 m_tree.generateImpliedEndTagsWithExclusion(token->name()); 1388 m_tree.generateImpliedEndTagsWithExclusion(token->name());
1389 if (!m_tree.currentStackItem()->matchesHTMLTag(token->name())) 1389 if (!m_tree.currentStackItem()->matchesHTMLTag(token->name()))
1390 parseError(token); 1390 parseError(token);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1440 HTMLElementStack::ElementRecord* furthestBlock = 1440 HTMLElementStack::ElementRecord* furthestBlock =
1441 m_tree.openElements()->furthestBlockForFormattingElement( 1441 m_tree.openElements()->furthestBlockForFormattingElement(
1442 formattingElement); 1442 formattingElement);
1443 // 6. 1443 // 6.
1444 if (!furthestBlock) { 1444 if (!furthestBlock) {
1445 m_tree.openElements()->popUntilPopped(formattingElement); 1445 m_tree.openElements()->popUntilPopped(formattingElement);
1446 m_tree.activeFormattingElements()->remove(formattingElement); 1446 m_tree.activeFormattingElements()->remove(formattingElement);
1447 return; 1447 return;
1448 } 1448 }
1449 // 7. 1449 // 7.
1450 ASSERT(furthestBlock->isAbove(formattingElementRecord)); 1450 DCHECK(furthestBlock->isAbove(formattingElementRecord));
1451 HTMLStackItem* commonAncestor = 1451 HTMLStackItem* commonAncestor =
1452 formattingElementRecord->next()->stackItem(); 1452 formattingElementRecord->next()->stackItem();
1453 // 8. 1453 // 8.
1454 HTMLFormattingElementList::Bookmark bookmark = 1454 HTMLFormattingElementList::Bookmark bookmark =
1455 m_tree.activeFormattingElements()->bookmarkFor(formattingElement); 1455 m_tree.activeFormattingElements()->bookmarkFor(formattingElement);
1456 // 9. 1456 // 9.
1457 HTMLElementStack::ElementRecord* node = furthestBlock; 1457 HTMLElementStack::ElementRecord* node = furthestBlock;
1458 HTMLElementStack::ElementRecord* nextNode = node->next(); 1458 HTMLElementStack::ElementRecord* nextNode = node->next();
1459 HTMLElementStack::ElementRecord* lastNode = furthestBlock; 1459 HTMLElementStack::ElementRecord* lastNode = furthestBlock;
1460 // 9.1, 9.2, 9.3 and 9.11 are covered by the for() loop. 1460 // 9.1, 9.2, 9.3 and 9.11 are covered by the for() loop.
1461 for (int i = 0; i < innerIterationLimit; ++i) { 1461 for (int i = 0; i < innerIterationLimit; ++i) {
1462 // 9.4 1462 // 9.4
1463 node = nextNode; 1463 node = nextNode;
1464 ASSERT(node); 1464 DCHECK(node);
1465 // Save node->next() for the next iteration in case node is deleted in 1465 // Save node->next() for the next iteration in case node is deleted in
1466 // 9.5. 1466 // 9.5.
1467 nextNode = node->next(); 1467 nextNode = node->next();
1468 // 9.5 1468 // 9.5
1469 if (!m_tree.activeFormattingElements()->contains(node->element())) { 1469 if (!m_tree.activeFormattingElements()->contains(node->element())) {
1470 m_tree.openElements()->remove(node->element()); 1470 m_tree.openElements()->remove(node->element());
1471 node = 0; 1471 node = 0;
1472 continue; 1472 continue;
1473 } 1473 }
1474 // 9.6 1474 // 9.6
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1557 } 1557 }
1558 if (item->hasTagName(bodyTag)) 1558 if (item->hasTagName(bodyTag))
1559 return setInsertionMode(InBodyMode); 1559 return setInsertionMode(InBodyMode);
1560 if (item->hasTagName(framesetTag)) { 1560 if (item->hasTagName(framesetTag)) {
1561 return setInsertionMode(InFramesetMode); 1561 return setInsertionMode(InFramesetMode);
1562 } 1562 }
1563 if (item->hasTagName(htmlTag)) { 1563 if (item->hasTagName(htmlTag)) {
1564 if (m_tree.headStackItem()) 1564 if (m_tree.headStackItem())
1565 return setInsertionMode(AfterHeadMode); 1565 return setInsertionMode(AfterHeadMode);
1566 1566
1567 ASSERT(isParsingFragment()); 1567 DCHECK(isParsingFragment());
1568 return setInsertionMode(BeforeHeadMode); 1568 return setInsertionMode(BeforeHeadMode);
1569 } 1569 }
1570 if (last) { 1570 if (last) {
1571 ASSERT(isParsingFragment()); 1571 DCHECK(isParsingFragment());
1572 return setInsertionMode(InBodyMode); 1572 return setInsertionMode(InBodyMode);
1573 } 1573 }
1574 nodeRecord = nodeRecord->next(); 1574 nodeRecord = nodeRecord->next();
1575 } 1575 }
1576 } 1576 }
1577 1577
1578 void HTMLTreeBuilder::processEndTagForInTableBody(AtomicHTMLToken* token) { 1578 void HTMLTreeBuilder::processEndTagForInTableBody(AtomicHTMLToken* token) {
1579 ASSERT(token->type() == HTMLToken::EndTag); 1579 DCHECK_EQ(token->type(), HTMLToken::EndTag);
1580 if (isTableBodyContextTag(token->name())) { 1580 if (isTableBodyContextTag(token->name())) {
1581 if (!m_tree.openElements()->inTableScope(token->name())) { 1581 if (!m_tree.openElements()->inTableScope(token->name())) {
1582 parseError(token); 1582 parseError(token);
1583 return; 1583 return;
1584 } 1584 }
1585 m_tree.openElements()->popUntilTableBodyScopeMarker(); 1585 m_tree.openElements()->popUntilTableBodyScopeMarker();
1586 m_tree.openElements()->pop(); 1586 m_tree.openElements()->pop();
1587 setInsertionMode(InTableMode); 1587 setInsertionMode(InTableMode);
1588 return; 1588 return;
1589 } 1589 }
1590 if (token->name() == tableTag) { 1590 if (token->name() == tableTag) {
1591 // FIXME: This is slow. 1591 // FIXME: This is slow.
1592 if (!m_tree.openElements()->inTableScope(tbodyTag) && 1592 if (!m_tree.openElements()->inTableScope(tbodyTag) &&
1593 !m_tree.openElements()->inTableScope(theadTag) && 1593 !m_tree.openElements()->inTableScope(theadTag) &&
1594 !m_tree.openElements()->inTableScope(tfootTag)) { 1594 !m_tree.openElements()->inTableScope(tfootTag)) {
1595 ASSERT(isParsingFragmentOrTemplateContents()); 1595 DCHECK(isParsingFragmentOrTemplateContents());
1596 parseError(token); 1596 parseError(token);
1597 return; 1597 return;
1598 } 1598 }
1599 m_tree.openElements()->popUntilTableBodyScopeMarker(); 1599 m_tree.openElements()->popUntilTableBodyScopeMarker();
1600 ASSERT(isTableBodyContextTag(m_tree.currentStackItem()->localName())); 1600 DCHECK(isTableBodyContextTag(m_tree.currentStackItem()->localName()));
1601 processFakeEndTag(m_tree.currentStackItem()->localName()); 1601 processFakeEndTag(m_tree.currentStackItem()->localName());
1602 processEndTag(token); 1602 processEndTag(token);
1603 return; 1603 return;
1604 } 1604 }
1605 if (token->name() == bodyTag || isCaptionColOrColgroupTag(token->name()) || 1605 if (token->name() == bodyTag || isCaptionColOrColgroupTag(token->name()) ||
1606 token->name() == htmlTag || isTableCellContextTag(token->name()) || 1606 token->name() == htmlTag || isTableCellContextTag(token->name()) ||
1607 token->name() == trTag) { 1607 token->name() == trTag) {
1608 parseError(token); 1608 parseError(token);
1609 return; 1609 return;
1610 } 1610 }
1611 processEndTagForInTable(token); 1611 processEndTagForInTable(token);
1612 } 1612 }
1613 1613
1614 void HTMLTreeBuilder::processEndTagForInRow(AtomicHTMLToken* token) { 1614 void HTMLTreeBuilder::processEndTagForInRow(AtomicHTMLToken* token) {
1615 ASSERT(token->type() == HTMLToken::EndTag); 1615 DCHECK_EQ(token->type(), HTMLToken::EndTag);
1616 if (token->name() == trTag) { 1616 if (token->name() == trTag) {
1617 processTrEndTagForInRow(); 1617 processTrEndTagForInRow();
1618 return; 1618 return;
1619 } 1619 }
1620 if (token->name() == tableTag) { 1620 if (token->name() == tableTag) {
1621 if (!processTrEndTagForInRow()) { 1621 if (!processTrEndTagForInRow()) {
1622 ASSERT(isParsingFragmentOrTemplateContents()); 1622 DCHECK(isParsingFragmentOrTemplateContents());
1623 return; 1623 return;
1624 } 1624 }
1625 ASSERT(getInsertionMode() == InTableBodyMode); 1625 DCHECK_EQ(getInsertionMode(), InTableBodyMode);
1626 processEndTag(token); 1626 processEndTag(token);
1627 return; 1627 return;
1628 } 1628 }
1629 if (isTableBodyContextTag(token->name())) { 1629 if (isTableBodyContextTag(token->name())) {
1630 if (!m_tree.openElements()->inTableScope(token->name())) { 1630 if (!m_tree.openElements()->inTableScope(token->name())) {
1631 parseError(token); 1631 parseError(token);
1632 return; 1632 return;
1633 } 1633 }
1634 processFakeEndTag(trTag); 1634 processFakeEndTag(trTag);
1635 ASSERT(getInsertionMode() == InTableBodyMode); 1635 DCHECK_EQ(getInsertionMode(), InTableBodyMode);
1636 processEndTag(token); 1636 processEndTag(token);
1637 return; 1637 return;
1638 } 1638 }
1639 if (token->name() == bodyTag || isCaptionColOrColgroupTag(token->name()) || 1639 if (token->name() == bodyTag || isCaptionColOrColgroupTag(token->name()) ||
1640 token->name() == htmlTag || isTableCellContextTag(token->name())) { 1640 token->name() == htmlTag || isTableCellContextTag(token->name())) {
1641 parseError(token); 1641 parseError(token);
1642 return; 1642 return;
1643 } 1643 }
1644 processEndTagForInTable(token); 1644 processEndTagForInTable(token);
1645 } 1645 }
1646 1646
1647 void HTMLTreeBuilder::processEndTagForInCell(AtomicHTMLToken* token) { 1647 void HTMLTreeBuilder::processEndTagForInCell(AtomicHTMLToken* token) {
1648 ASSERT(token->type() == HTMLToken::EndTag); 1648 DCHECK_EQ(token->type(), HTMLToken::EndTag);
1649 if (isTableCellContextTag(token->name())) { 1649 if (isTableCellContextTag(token->name())) {
1650 if (!m_tree.openElements()->inTableScope(token->name())) { 1650 if (!m_tree.openElements()->inTableScope(token->name())) {
1651 parseError(token); 1651 parseError(token);
1652 return; 1652 return;
1653 } 1653 }
1654 m_tree.generateImpliedEndTags(); 1654 m_tree.generateImpliedEndTags();
1655 if (!m_tree.currentStackItem()->matchesHTMLTag(token->name())) 1655 if (!m_tree.currentStackItem()->matchesHTMLTag(token->name()))
1656 parseError(token); 1656 parseError(token);
1657 m_tree.openElements()->popUntilPopped(token->name()); 1657 m_tree.openElements()->popUntilPopped(token->name());
1658 m_tree.activeFormattingElements()->clearToLastMarker(); 1658 m_tree.activeFormattingElements()->clearToLastMarker();
1659 setInsertionMode(InRowMode); 1659 setInsertionMode(InRowMode);
1660 return; 1660 return;
1661 } 1661 }
1662 if (token->name() == bodyTag || isCaptionColOrColgroupTag(token->name()) || 1662 if (token->name() == bodyTag || isCaptionColOrColgroupTag(token->name()) ||
1663 token->name() == htmlTag) { 1663 token->name() == htmlTag) {
1664 parseError(token); 1664 parseError(token);
1665 return; 1665 return;
1666 } 1666 }
1667 if (token->name() == tableTag || token->name() == trTag || 1667 if (token->name() == tableTag || token->name() == trTag ||
1668 isTableBodyContextTag(token->name())) { 1668 isTableBodyContextTag(token->name())) {
1669 if (!m_tree.openElements()->inTableScope(token->name())) { 1669 if (!m_tree.openElements()->inTableScope(token->name())) {
1670 ASSERT(isTableBodyContextTag(token->name()) || 1670 DCHECK(isTableBodyContextTag(token->name()) ||
1671 m_tree.openElements()->inTableScope(templateTag) || 1671 m_tree.openElements()->inTableScope(templateTag) ||
1672 isParsingFragment()); 1672 isParsingFragment());
1673 parseError(token); 1673 parseError(token);
1674 return; 1674 return;
1675 } 1675 }
1676 closeTheCell(); 1676 closeTheCell();
1677 processEndTag(token); 1677 processEndTag(token);
1678 return; 1678 return;
1679 } 1679 }
1680 processEndTagForInBody(token); 1680 processEndTagForInBody(token);
1681 } 1681 }
1682 1682
1683 void HTMLTreeBuilder::processEndTagForInBody(AtomicHTMLToken* token) { 1683 void HTMLTreeBuilder::processEndTagForInBody(AtomicHTMLToken* token) {
1684 ASSERT(token->type() == HTMLToken::EndTag); 1684 DCHECK_EQ(token->type(), HTMLToken::EndTag);
1685 if (token->name() == bodyTag) { 1685 if (token->name() == bodyTag) {
1686 processBodyEndTagForInBody(token); 1686 processBodyEndTagForInBody(token);
1687 return; 1687 return;
1688 } 1688 }
1689 if (token->name() == htmlTag) { 1689 if (token->name() == htmlTag) {
1690 AtomicHTMLToken endBody(HTMLToken::EndTag, bodyTag.localName()); 1690 AtomicHTMLToken endBody(HTMLToken::EndTag, bodyTag.localName());
1691 if (processBodyEndTagForInBody(&endBody)) 1691 if (processBodyEndTagForInBody(&endBody))
1692 processEndTag(token); 1692 processEndTag(token);
1693 return; 1693 return;
1694 } 1694 }
(...skipping 28 matching lines...) Expand all
1723 } 1723 }
1724 m_tree.generateImpliedEndTags(); 1724 m_tree.generateImpliedEndTags();
1725 if (m_tree.currentElement() != node) 1725 if (m_tree.currentElement() != node)
1726 parseError(token); 1726 parseError(token);
1727 m_tree.openElements()->remove(node); 1727 m_tree.openElements()->remove(node);
1728 } 1728 }
1729 if (token->name() == pTag) { 1729 if (token->name() == pTag) {
1730 if (!m_tree.openElements()->inButtonScope(token->name())) { 1730 if (!m_tree.openElements()->inButtonScope(token->name())) {
1731 parseError(token); 1731 parseError(token);
1732 processFakeStartTag(pTag); 1732 processFakeStartTag(pTag);
1733 ASSERT(m_tree.openElements()->inScope(token->name())); 1733 DCHECK(m_tree.openElements()->inScope(token->name()));
1734 processEndTag(token); 1734 processEndTag(token);
1735 return; 1735 return;
1736 } 1736 }
1737 m_tree.generateImpliedEndTagsWithExclusion(token->name()); 1737 m_tree.generateImpliedEndTagsWithExclusion(token->name());
1738 if (!m_tree.currentStackItem()->matchesHTMLTag(token->name())) 1738 if (!m_tree.currentStackItem()->matchesHTMLTag(token->name()))
1739 parseError(token); 1739 parseError(token);
1740 m_tree.openElements()->popUntilPopped(token->name()); 1740 m_tree.openElements()->popUntilPopped(token->name());
1741 return; 1741 return;
1742 } 1742 }
1743 if (token->name() == liTag) { 1743 if (token->name() == liTag) {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1797 } 1797 }
1798 if (token->name() == templateTag) { 1798 if (token->name() == templateTag) {
1799 processTemplateEndTag(token); 1799 processTemplateEndTag(token);
1800 return; 1800 return;
1801 } 1801 }
1802 processAnyOtherEndTagForInBody(token); 1802 processAnyOtherEndTagForInBody(token);
1803 } 1803 }
1804 1804
1805 bool HTMLTreeBuilder::processCaptionEndTagForInCaption() { 1805 bool HTMLTreeBuilder::processCaptionEndTagForInCaption() {
1806 if (!m_tree.openElements()->inTableScope(captionTag.localName())) { 1806 if (!m_tree.openElements()->inTableScope(captionTag.localName())) {
1807 ASSERT(isParsingFragment()); 1807 DCHECK(isParsingFragment());
1808 // FIXME: parse error 1808 // FIXME: parse error
1809 return false; 1809 return false;
1810 } 1810 }
1811 m_tree.generateImpliedEndTags(); 1811 m_tree.generateImpliedEndTags();
1812 // FIXME: parse error if (!m_tree.currentStackItem()->hasTagName(captionTag)) 1812 // FIXME: parse error if (!m_tree.currentStackItem()->hasTagName(captionTag))
1813 m_tree.openElements()->popUntilPopped(captionTag.localName()); 1813 m_tree.openElements()->popUntilPopped(captionTag.localName());
1814 m_tree.activeFormattingElements()->clearToLastMarker(); 1814 m_tree.activeFormattingElements()->clearToLastMarker();
1815 setInsertionMode(InTableMode); 1815 setInsertionMode(InTableMode);
1816 return true; 1816 return true;
1817 } 1817 }
1818 1818
1819 bool HTMLTreeBuilder::processTrEndTagForInRow() { 1819 bool HTMLTreeBuilder::processTrEndTagForInRow() {
1820 if (!m_tree.openElements()->inTableScope(trTag)) { 1820 if (!m_tree.openElements()->inTableScope(trTag)) {
1821 ASSERT(isParsingFragmentOrTemplateContents()); 1821 DCHECK(isParsingFragmentOrTemplateContents());
1822 // FIXME: parse error 1822 // FIXME: parse error
1823 return false; 1823 return false;
1824 } 1824 }
1825 m_tree.openElements()->popUntilTableRowScopeMarker(); 1825 m_tree.openElements()->popUntilTableRowScopeMarker();
1826 ASSERT(m_tree.currentStackItem()->hasTagName(trTag)); 1826 DCHECK(m_tree.currentStackItem()->hasTagName(trTag));
1827 m_tree.openElements()->pop(); 1827 m_tree.openElements()->pop();
1828 setInsertionMode(InTableBodyMode); 1828 setInsertionMode(InTableBodyMode);
1829 return true; 1829 return true;
1830 } 1830 }
1831 1831
1832 bool HTMLTreeBuilder::processTableEndTagForInTable() { 1832 bool HTMLTreeBuilder::processTableEndTagForInTable() {
1833 if (!m_tree.openElements()->inTableScope(tableTag)) { 1833 if (!m_tree.openElements()->inTableScope(tableTag)) {
1834 ASSERT(isParsingFragmentOrTemplateContents()); 1834 DCHECK(isParsingFragmentOrTemplateContents());
1835 // FIXME: parse error. 1835 // FIXME: parse error.
1836 return false; 1836 return false;
1837 } 1837 }
1838 m_tree.openElements()->popUntilPopped(tableTag.localName()); 1838 m_tree.openElements()->popUntilPopped(tableTag.localName());
1839 resetInsertionModeAppropriately(); 1839 resetInsertionModeAppropriately();
1840 return true; 1840 return true;
1841 } 1841 }
1842 1842
1843 void HTMLTreeBuilder::processEndTagForInTable(AtomicHTMLToken* token) { 1843 void HTMLTreeBuilder::processEndTagForInTable(AtomicHTMLToken* token) {
1844 ASSERT(token->type() == HTMLToken::EndTag); 1844 DCHECK_EQ(token->type(), HTMLToken::EndTag);
1845 if (token->name() == tableTag) { 1845 if (token->name() == tableTag) {
1846 processTableEndTagForInTable(); 1846 processTableEndTagForInTable();
1847 return; 1847 return;
1848 } 1848 }
1849 if (token->name() == bodyTag || isCaptionColOrColgroupTag(token->name()) || 1849 if (token->name() == bodyTag || isCaptionColOrColgroupTag(token->name()) ||
1850 token->name() == htmlTag || isTableBodyContextTag(token->name()) || 1850 token->name() == htmlTag || isTableBodyContextTag(token->name()) ||
1851 isTableCellContextTag(token->name()) || token->name() == trTag) { 1851 isTableCellContextTag(token->name()) || token->name() == trTag) {
1852 parseError(token); 1852 parseError(token);
1853 return; 1853 return;
1854 } 1854 }
1855 parseError(token); 1855 parseError(token);
1856 // Is this redirection necessary here? 1856 // Is this redirection necessary here?
1857 HTMLConstructionSite::RedirectToFosterParentGuard redirecter(m_tree); 1857 HTMLConstructionSite::RedirectToFosterParentGuard redirecter(m_tree);
1858 processEndTagForInBody(token); 1858 processEndTagForInBody(token);
1859 } 1859 }
1860 1860
1861 void HTMLTreeBuilder::processEndTag(AtomicHTMLToken* token) { 1861 void HTMLTreeBuilder::processEndTag(AtomicHTMLToken* token) {
1862 ASSERT(token->type() == HTMLToken::EndTag); 1862 DCHECK_EQ(token->type(), HTMLToken::EndTag);
1863 switch (getInsertionMode()) { 1863 switch (getInsertionMode()) {
1864 case InitialMode: 1864 case InitialMode:
1865 ASSERT(getInsertionMode() == InitialMode); 1865 DCHECK_EQ(getInsertionMode(), InitialMode);
1866 defaultForInitial(); 1866 defaultForInitial();
1867 // Fall through. 1867 // Fall through.
1868 case BeforeHTMLMode: 1868 case BeforeHTMLMode:
1869 ASSERT(getInsertionMode() == BeforeHTMLMode); 1869 DCHECK_EQ(getInsertionMode(), BeforeHTMLMode);
1870 if (token->name() != headTag && token->name() != bodyTag && 1870 if (token->name() != headTag && token->name() != bodyTag &&
1871 token->name() != htmlTag && token->name() != brTag) { 1871 token->name() != htmlTag && token->name() != brTag) {
1872 parseError(token); 1872 parseError(token);
1873 return; 1873 return;
1874 } 1874 }
1875 defaultForBeforeHTML(); 1875 defaultForBeforeHTML();
1876 // Fall through. 1876 // Fall through.
1877 case BeforeHeadMode: 1877 case BeforeHeadMode:
1878 ASSERT(getInsertionMode() == BeforeHeadMode); 1878 DCHECK_EQ(getInsertionMode(), BeforeHeadMode);
1879 if (token->name() != headTag && token->name() != bodyTag && 1879 if (token->name() != headTag && token->name() != bodyTag &&
1880 token->name() != htmlTag && token->name() != brTag) { 1880 token->name() != htmlTag && token->name() != brTag) {
1881 parseError(token); 1881 parseError(token);
1882 return; 1882 return;
1883 } 1883 }
1884 defaultForBeforeHead(); 1884 defaultForBeforeHead();
1885 // Fall through. 1885 // Fall through.
1886 case InHeadMode: 1886 case InHeadMode:
1887 ASSERT(getInsertionMode() == InHeadMode); 1887 DCHECK_EQ(getInsertionMode(), InHeadMode);
1888 // FIXME: This case should be broken out into processEndTagForInHead, 1888 // FIXME: This case should be broken out into processEndTagForInHead,
1889 // because other end tag cases now refer to it ("process the token for 1889 // because other end tag cases now refer to it ("process the token for
1890 // using the rules of the "in head" insertion mode"). but because the 1890 // using the rules of the "in head" insertion mode"). but because the
1891 // logic falls through to AfterHeadMode, that gets a little messy. 1891 // logic falls through to AfterHeadMode, that gets a little messy.
1892 if (token->name() == templateTag) { 1892 if (token->name() == templateTag) {
1893 processTemplateEndTag(token); 1893 processTemplateEndTag(token);
1894 return; 1894 return;
1895 } 1895 }
1896 if (token->name() == headTag) { 1896 if (token->name() == headTag) {
1897 m_tree.openElements()->popHTMLHeadElement(); 1897 m_tree.openElements()->popHTMLHeadElement();
1898 setInsertionMode(AfterHeadMode); 1898 setInsertionMode(AfterHeadMode);
1899 return; 1899 return;
1900 } 1900 }
1901 if (token->name() != bodyTag && token->name() != htmlTag && 1901 if (token->name() != bodyTag && token->name() != htmlTag &&
1902 token->name() != brTag) { 1902 token->name() != brTag) {
1903 parseError(token); 1903 parseError(token);
1904 return; 1904 return;
1905 } 1905 }
1906 defaultForInHead(); 1906 defaultForInHead();
1907 // Fall through. 1907 // Fall through.
1908 case AfterHeadMode: 1908 case AfterHeadMode:
1909 ASSERT(getInsertionMode() == AfterHeadMode); 1909 DCHECK_EQ(getInsertionMode(), AfterHeadMode);
1910 if (token->name() != bodyTag && token->name() != htmlTag && 1910 if (token->name() != bodyTag && token->name() != htmlTag &&
1911 token->name() != brTag) { 1911 token->name() != brTag) {
1912 parseError(token); 1912 parseError(token);
1913 return; 1913 return;
1914 } 1914 }
1915 defaultForAfterHead(); 1915 defaultForAfterHead();
1916 // Fall through 1916 // Fall through
1917 case InBodyMode: 1917 case InBodyMode:
1918 ASSERT(getInsertionMode() == InBodyMode); 1918 DCHECK_EQ(getInsertionMode(), InBodyMode);
1919 processEndTagForInBody(token); 1919 processEndTagForInBody(token);
1920 break; 1920 break;
1921 case InTableMode: 1921 case InTableMode:
1922 ASSERT(getInsertionMode() == InTableMode); 1922 DCHECK_EQ(getInsertionMode(), InTableMode);
1923 processEndTagForInTable(token); 1923 processEndTagForInTable(token);
1924 break; 1924 break;
1925 case InCaptionMode: 1925 case InCaptionMode:
1926 ASSERT(getInsertionMode() == InCaptionMode); 1926 DCHECK_EQ(getInsertionMode(), InCaptionMode);
1927 if (token->name() == captionTag) { 1927 if (token->name() == captionTag) {
1928 processCaptionEndTagForInCaption(); 1928 processCaptionEndTagForInCaption();
1929 return; 1929 return;
1930 } 1930 }
1931 if (token->name() == tableTag) { 1931 if (token->name() == tableTag) {
1932 parseError(token); 1932 parseError(token);
1933 if (!processCaptionEndTagForInCaption()) { 1933 if (!processCaptionEndTagForInCaption()) {
1934 ASSERT(isParsingFragment()); 1934 DCHECK(isParsingFragment());
1935 return; 1935 return;
1936 } 1936 }
1937 processEndTag(token); 1937 processEndTag(token);
1938 return; 1938 return;
1939 } 1939 }
1940 if (token->name() == bodyTag || token->name() == colTag || 1940 if (token->name() == bodyTag || token->name() == colTag ||
1941 token->name() == colgroupTag || token->name() == htmlTag || 1941 token->name() == colgroupTag || token->name() == htmlTag ||
1942 isTableBodyContextTag(token->name()) || 1942 isTableBodyContextTag(token->name()) ||
1943 isTableCellContextTag(token->name()) || token->name() == trTag) { 1943 isTableCellContextTag(token->name()) || token->name() == trTag) {
1944 parseError(token); 1944 parseError(token);
1945 return; 1945 return;
1946 } 1946 }
1947 processEndTagForInBody(token); 1947 processEndTagForInBody(token);
1948 break; 1948 break;
1949 case InColumnGroupMode: 1949 case InColumnGroupMode:
1950 ASSERT(getInsertionMode() == InColumnGroupMode); 1950 DCHECK_EQ(getInsertionMode(), InColumnGroupMode);
1951 if (token->name() == colgroupTag) { 1951 if (token->name() == colgroupTag) {
1952 processColgroupEndTagForInColumnGroup(); 1952 processColgroupEndTagForInColumnGroup();
1953 return; 1953 return;
1954 } 1954 }
1955 if (token->name() == colTag) { 1955 if (token->name() == colTag) {
1956 parseError(token); 1956 parseError(token);
1957 return; 1957 return;
1958 } 1958 }
1959 if (token->name() == templateTag) { 1959 if (token->name() == templateTag) {
1960 processTemplateEndTag(token); 1960 processTemplateEndTag(token);
1961 return; 1961 return;
1962 } 1962 }
1963 if (!processColgroupEndTagForInColumnGroup()) { 1963 if (!processColgroupEndTagForInColumnGroup()) {
1964 ASSERT(isParsingFragmentOrTemplateContents()); 1964 DCHECK(isParsingFragmentOrTemplateContents());
1965 return; 1965 return;
1966 } 1966 }
1967 processEndTag(token); 1967 processEndTag(token);
1968 break; 1968 break;
1969 case InRowMode: 1969 case InRowMode:
1970 ASSERT(getInsertionMode() == InRowMode); 1970 DCHECK_EQ(getInsertionMode(), InRowMode);
1971 processEndTagForInRow(token); 1971 processEndTagForInRow(token);
1972 break; 1972 break;
1973 case InCellMode: 1973 case InCellMode:
1974 ASSERT(getInsertionMode() == InCellMode); 1974 DCHECK_EQ(getInsertionMode(), InCellMode);
1975 processEndTagForInCell(token); 1975 processEndTagForInCell(token);
1976 break; 1976 break;
1977 case InTableBodyMode: 1977 case InTableBodyMode:
1978 ASSERT(getInsertionMode() == InTableBodyMode); 1978 DCHECK_EQ(getInsertionMode(), InTableBodyMode);
1979 processEndTagForInTableBody(token); 1979 processEndTagForInTableBody(token);
1980 break; 1980 break;
1981 case AfterBodyMode: 1981 case AfterBodyMode:
1982 ASSERT(getInsertionMode() == AfterBodyMode); 1982 DCHECK_EQ(getInsertionMode(), AfterBodyMode);
1983 if (token->name() == htmlTag) { 1983 if (token->name() == htmlTag) {
1984 if (isParsingFragment()) { 1984 if (isParsingFragment()) {
1985 parseError(token); 1985 parseError(token);
1986 return; 1986 return;
1987 } 1987 }
1988 setInsertionMode(AfterAfterBodyMode); 1988 setInsertionMode(AfterAfterBodyMode);
1989 return; 1989 return;
1990 } 1990 }
1991 // Fall through. 1991 // Fall through.
1992 case AfterAfterBodyMode: 1992 case AfterAfterBodyMode:
1993 ASSERT(getInsertionMode() == AfterBodyMode || 1993 DCHECK(getInsertionMode() == AfterBodyMode ||
1994 getInsertionMode() == AfterAfterBodyMode); 1994 getInsertionMode() == AfterAfterBodyMode);
1995 parseError(token); 1995 parseError(token);
1996 setInsertionMode(InBodyMode); 1996 setInsertionMode(InBodyMode);
1997 processEndTag(token); 1997 processEndTag(token);
1998 break; 1998 break;
1999 case InHeadNoscriptMode: 1999 case InHeadNoscriptMode:
2000 ASSERT(getInsertionMode() == InHeadNoscriptMode); 2000 DCHECK_EQ(getInsertionMode(), InHeadNoscriptMode);
2001 if (token->name() == noscriptTag) { 2001 if (token->name() == noscriptTag) {
2002 ASSERT(m_tree.currentStackItem()->hasTagName(noscriptTag)); 2002 DCHECK(m_tree.currentStackItem()->hasTagName(noscriptTag));
2003 m_tree.openElements()->pop(); 2003 m_tree.openElements()->pop();
2004 ASSERT(m_tree.currentStackItem()->hasTagName(headTag)); 2004 DCHECK(m_tree.currentStackItem()->hasTagName(headTag));
2005 setInsertionMode(InHeadMode); 2005 setInsertionMode(InHeadMode);
2006 return; 2006 return;
2007 } 2007 }
2008 if (token->name() != brTag) { 2008 if (token->name() != brTag) {
2009 parseError(token); 2009 parseError(token);
2010 return; 2010 return;
2011 } 2011 }
2012 defaultForInHeadNoscript(); 2012 defaultForInHeadNoscript();
2013 processToken(token); 2013 processToken(token);
2014 break; 2014 break;
(...skipping 11 matching lines...) Expand all
2026 // We must set the tokenizer's state to DataState explicitly if the 2026 // We must set the tokenizer's state to DataState explicitly if the
2027 // tokenizer didn't have a chance to. 2027 // tokenizer didn't have a chance to.
2028 m_parser->tokenizer()->setState(HTMLTokenizer::DataState); 2028 m_parser->tokenizer()->setState(HTMLTokenizer::DataState);
2029 } 2029 }
2030 return; 2030 return;
2031 } 2031 }
2032 m_tree.openElements()->pop(); 2032 m_tree.openElements()->pop();
2033 setInsertionMode(m_originalInsertionMode); 2033 setInsertionMode(m_originalInsertionMode);
2034 break; 2034 break;
2035 case InFramesetMode: 2035 case InFramesetMode:
2036 ASSERT(getInsertionMode() == InFramesetMode); 2036 DCHECK_EQ(getInsertionMode(), InFramesetMode);
2037 if (token->name() == framesetTag) { 2037 if (token->name() == framesetTag) {
2038 bool ignoreFramesetForFragmentParsing = m_tree.currentIsRootNode(); 2038 bool ignoreFramesetForFragmentParsing = m_tree.currentIsRootNode();
2039 ignoreFramesetForFragmentParsing = 2039 ignoreFramesetForFragmentParsing =
2040 ignoreFramesetForFragmentParsing || 2040 ignoreFramesetForFragmentParsing ||
2041 m_tree.openElements()->hasTemplateInHTMLScope(); 2041 m_tree.openElements()->hasTemplateInHTMLScope();
2042 if (ignoreFramesetForFragmentParsing) { 2042 if (ignoreFramesetForFragmentParsing) {
2043 ASSERT(isParsingFragmentOrTemplateContents()); 2043 DCHECK(isParsingFragmentOrTemplateContents());
2044 parseError(token); 2044 parseError(token);
2045 return; 2045 return;
2046 } 2046 }
2047 m_tree.openElements()->pop(); 2047 m_tree.openElements()->pop();
2048 if (!isParsingFragment() && 2048 if (!isParsingFragment() &&
2049 !m_tree.currentStackItem()->hasTagName(framesetTag)) 2049 !m_tree.currentStackItem()->hasTagName(framesetTag))
2050 setInsertionMode(AfterFramesetMode); 2050 setInsertionMode(AfterFramesetMode);
2051 return; 2051 return;
2052 } 2052 }
2053 if (token->name() == templateTag) { 2053 if (token->name() == templateTag) {
2054 processTemplateEndTag(token); 2054 processTemplateEndTag(token);
2055 return; 2055 return;
2056 } 2056 }
2057 break; 2057 break;
2058 case AfterFramesetMode: 2058 case AfterFramesetMode:
2059 ASSERT(getInsertionMode() == AfterFramesetMode); 2059 DCHECK_EQ(getInsertionMode(), AfterFramesetMode);
2060 if (token->name() == htmlTag) { 2060 if (token->name() == htmlTag) {
2061 setInsertionMode(AfterAfterFramesetMode); 2061 setInsertionMode(AfterAfterFramesetMode);
2062 return; 2062 return;
2063 } 2063 }
2064 // Fall through. 2064 // Fall through.
2065 case AfterAfterFramesetMode: 2065 case AfterAfterFramesetMode:
2066 ASSERT(getInsertionMode() == AfterFramesetMode || 2066 DCHECK(getInsertionMode() == AfterFramesetMode ||
2067 getInsertionMode() == AfterAfterFramesetMode); 2067 getInsertionMode() == AfterAfterFramesetMode);
2068 parseError(token); 2068 parseError(token);
2069 break; 2069 break;
2070 case InSelectInTableMode: 2070 case InSelectInTableMode:
2071 ASSERT(getInsertionMode() == InSelectInTableMode); 2071 DCHECK(getInsertionMode() == InSelectInTableMode);
2072 if (token->name() == captionTag || token->name() == tableTag || 2072 if (token->name() == captionTag || token->name() == tableTag ||
2073 isTableBodyContextTag(token->name()) || token->name() == trTag || 2073 isTableBodyContextTag(token->name()) || token->name() == trTag ||
2074 isTableCellContextTag(token->name())) { 2074 isTableCellContextTag(token->name())) {
2075 parseError(token); 2075 parseError(token);
2076 if (m_tree.openElements()->inTableScope(token->name())) { 2076 if (m_tree.openElements()->inTableScope(token->name())) {
2077 AtomicHTMLToken endSelect(HTMLToken::EndTag, selectTag.localName()); 2077 AtomicHTMLToken endSelect(HTMLToken::EndTag, selectTag.localName());
2078 processEndTag(&endSelect); 2078 processEndTag(&endSelect);
2079 processEndTag(token); 2079 processEndTag(token);
2080 } 2080 }
2081 return; 2081 return;
2082 } 2082 }
2083 // Fall through. 2083 // Fall through.
2084 case InSelectMode: 2084 case InSelectMode:
2085 ASSERT(getInsertionMode() == InSelectMode || 2085 DCHECK(getInsertionMode() == InSelectMode ||
2086 getInsertionMode() == InSelectInTableMode); 2086 getInsertionMode() == InSelectInTableMode);
2087 if (token->name() == optgroupTag) { 2087 if (token->name() == optgroupTag) {
2088 if (m_tree.currentStackItem()->hasTagName(optionTag) && 2088 if (m_tree.currentStackItem()->hasTagName(optionTag) &&
2089 m_tree.oneBelowTop() && 2089 m_tree.oneBelowTop() &&
2090 m_tree.oneBelowTop()->hasTagName(optgroupTag)) 2090 m_tree.oneBelowTop()->hasTagName(optgroupTag))
2091 processFakeEndTag(optionTag); 2091 processFakeEndTag(optionTag);
2092 if (m_tree.currentStackItem()->hasTagName(optgroupTag)) { 2092 if (m_tree.currentStackItem()->hasTagName(optgroupTag)) {
2093 m_tree.openElements()->pop(); 2093 m_tree.openElements()->pop();
2094 return; 2094 return;
2095 } 2095 }
2096 parseError(token); 2096 parseError(token);
2097 return; 2097 return;
2098 } 2098 }
2099 if (token->name() == optionTag) { 2099 if (token->name() == optionTag) {
2100 if (m_tree.currentStackItem()->hasTagName(optionTag)) { 2100 if (m_tree.currentStackItem()->hasTagName(optionTag)) {
2101 m_tree.openElements()->pop(); 2101 m_tree.openElements()->pop();
2102 return; 2102 return;
2103 } 2103 }
2104 parseError(token); 2104 parseError(token);
2105 return; 2105 return;
2106 } 2106 }
2107 if (token->name() == selectTag) { 2107 if (token->name() == selectTag) {
2108 if (!m_tree.openElements()->inSelectScope(token->name())) { 2108 if (!m_tree.openElements()->inSelectScope(token->name())) {
2109 ASSERT(isParsingFragment()); 2109 DCHECK(isParsingFragment());
2110 parseError(token); 2110 parseError(token);
2111 return; 2111 return;
2112 } 2112 }
2113 m_tree.openElements()->popUntilPopped(selectTag.localName()); 2113 m_tree.openElements()->popUntilPopped(selectTag.localName());
2114 resetInsertionModeAppropriately(); 2114 resetInsertionModeAppropriately();
2115 return; 2115 return;
2116 } 2116 }
2117 if (token->name() == templateTag) { 2117 if (token->name() == templateTag) {
2118 processTemplateEndTag(token); 2118 processTemplateEndTag(token);
2119 return; 2119 return;
2120 } 2120 }
2121 break; 2121 break;
2122 case InTableTextMode: 2122 case InTableTextMode:
2123 defaultForInTableText(); 2123 defaultForInTableText();
2124 processEndTag(token); 2124 processEndTag(token);
2125 break; 2125 break;
2126 case TemplateContentsMode: 2126 case TemplateContentsMode:
2127 if (token->name() == templateTag) { 2127 if (token->name() == templateTag) {
2128 processTemplateEndTag(token); 2128 processTemplateEndTag(token);
2129 return; 2129 return;
2130 } 2130 }
2131 break; 2131 break;
2132 } 2132 }
2133 } 2133 }
2134 2134
2135 void HTMLTreeBuilder::processComment(AtomicHTMLToken* token) { 2135 void HTMLTreeBuilder::processComment(AtomicHTMLToken* token) {
2136 ASSERT(token->type() == HTMLToken::Comment); 2136 DCHECK_EQ(token->type(), HTMLToken::Comment);
2137 if (m_insertionMode == InitialMode || m_insertionMode == BeforeHTMLMode || 2137 if (m_insertionMode == InitialMode || m_insertionMode == BeforeHTMLMode ||
2138 m_insertionMode == AfterAfterBodyMode || 2138 m_insertionMode == AfterAfterBodyMode ||
2139 m_insertionMode == AfterAfterFramesetMode) { 2139 m_insertionMode == AfterAfterFramesetMode) {
2140 m_tree.insertCommentOnDocument(token); 2140 m_tree.insertCommentOnDocument(token);
2141 return; 2141 return;
2142 } 2142 }
2143 if (m_insertionMode == AfterBodyMode) { 2143 if (m_insertionMode == AfterBodyMode) {
2144 m_tree.insertCommentOnHTMLHtmlElement(token); 2144 m_tree.insertCommentOnHTMLHtmlElement(token);
2145 return; 2145 return;
2146 } 2146 }
2147 if (m_insertionMode == InTableTextMode) { 2147 if (m_insertionMode == InTableTextMode) {
2148 defaultForInTableText(); 2148 defaultForInTableText();
2149 processComment(token); 2149 processComment(token);
2150 return; 2150 return;
2151 } 2151 }
2152 m_tree.insertComment(token); 2152 m_tree.insertComment(token);
2153 } 2153 }
2154 2154
2155 void HTMLTreeBuilder::processCharacter(AtomicHTMLToken* token) { 2155 void HTMLTreeBuilder::processCharacter(AtomicHTMLToken* token) {
2156 ASSERT(token->type() == HTMLToken::Character); 2156 DCHECK_EQ(token->type(), HTMLToken::Character);
2157 CharacterTokenBuffer buffer(token); 2157 CharacterTokenBuffer buffer(token);
2158 processCharacterBuffer(buffer); 2158 processCharacterBuffer(buffer);
2159 } 2159 }
2160 2160
2161 void HTMLTreeBuilder::processCharacterBuffer(CharacterTokenBuffer& buffer) { 2161 void HTMLTreeBuilder::processCharacterBuffer(CharacterTokenBuffer& buffer) {
2162 ReprocessBuffer: 2162 ReprocessBuffer:
2163 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.ht ml#parsing-main-inbody 2163 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.ht ml#parsing-main-inbody
2164 // Note that this logic is different than the generic \r\n collapsing 2164 // Note that this logic is different than the generic \r\n collapsing
2165 // handled in the input stream preprocessor. This logic is here as an 2165 // handled in the input stream preprocessor. This logic is here as an
2166 // "authoring convenience" so folks can write: 2166 // "authoring convenience" so folks can write:
2167 // 2167 //
2168 // <pre> 2168 // <pre>
2169 // lorem ipsum 2169 // lorem ipsum
2170 // lorem ipsum 2170 // lorem ipsum
2171 // </pre> 2171 // </pre>
2172 // 2172 //
2173 // without getting an extra newline at the start of their <pre> element. 2173 // without getting an extra newline at the start of their <pre> element.
2174 if (m_shouldSkipLeadingNewline) { 2174 if (m_shouldSkipLeadingNewline) {
2175 m_shouldSkipLeadingNewline = false; 2175 m_shouldSkipLeadingNewline = false;
2176 buffer.skipAtMostOneLeadingNewline(); 2176 buffer.skipAtMostOneLeadingNewline();
2177 if (buffer.isEmpty()) 2177 if (buffer.isEmpty())
2178 return; 2178 return;
2179 } 2179 }
2180 2180
2181 switch (getInsertionMode()) { 2181 switch (getInsertionMode()) {
2182 case InitialMode: { 2182 case InitialMode: {
2183 ASSERT(getInsertionMode() == InitialMode); 2183 DCHECK_EQ(getInsertionMode(), InitialMode);
2184 buffer.skipLeadingWhitespace(); 2184 buffer.skipLeadingWhitespace();
2185 if (buffer.isEmpty()) 2185 if (buffer.isEmpty())
2186 return; 2186 return;
2187 defaultForInitial(); 2187 defaultForInitial();
2188 // Fall through. 2188 // Fall through.
2189 } 2189 }
2190 case BeforeHTMLMode: { 2190 case BeforeHTMLMode: {
2191 ASSERT(getInsertionMode() == BeforeHTMLMode); 2191 DCHECK_EQ(getInsertionMode(), BeforeHTMLMode);
2192 buffer.skipLeadingWhitespace(); 2192 buffer.skipLeadingWhitespace();
2193 if (buffer.isEmpty()) 2193 if (buffer.isEmpty())
2194 return; 2194 return;
2195 defaultForBeforeHTML(); 2195 defaultForBeforeHTML();
2196 if (m_parser->isStopped()) { 2196 if (m_parser->isStopped()) {
2197 buffer.skipRemaining(); 2197 buffer.skipRemaining();
2198 return; 2198 return;
2199 } 2199 }
2200 // Fall through. 2200 // Fall through.
2201 } 2201 }
2202 case BeforeHeadMode: { 2202 case BeforeHeadMode: {
2203 ASSERT(getInsertionMode() == BeforeHeadMode); 2203 DCHECK_EQ(getInsertionMode(), BeforeHeadMode);
2204 buffer.skipLeadingWhitespace(); 2204 buffer.skipLeadingWhitespace();
2205 if (buffer.isEmpty()) 2205 if (buffer.isEmpty())
2206 return; 2206 return;
2207 defaultForBeforeHead(); 2207 defaultForBeforeHead();
2208 // Fall through. 2208 // Fall through.
2209 } 2209 }
2210 case InHeadMode: { 2210 case InHeadMode: {
2211 ASSERT(getInsertionMode() == InHeadMode); 2211 DCHECK_EQ(getInsertionMode(), InHeadMode);
2212 StringView leadingWhitespace = buffer.takeLeadingWhitespace(); 2212 StringView leadingWhitespace = buffer.takeLeadingWhitespace();
2213 if (!leadingWhitespace.isEmpty()) 2213 if (!leadingWhitespace.isEmpty())
2214 m_tree.insertTextNode(leadingWhitespace, AllWhitespace); 2214 m_tree.insertTextNode(leadingWhitespace, AllWhitespace);
2215 if (buffer.isEmpty()) 2215 if (buffer.isEmpty())
2216 return; 2216 return;
2217 defaultForInHead(); 2217 defaultForInHead();
2218 // Fall through. 2218 // Fall through.
2219 } 2219 }
2220 case AfterHeadMode: { 2220 case AfterHeadMode: {
2221 ASSERT(getInsertionMode() == AfterHeadMode); 2221 DCHECK_EQ(getInsertionMode(), AfterHeadMode);
2222 StringView leadingWhitespace = buffer.takeLeadingWhitespace(); 2222 StringView leadingWhitespace = buffer.takeLeadingWhitespace();
2223 if (!leadingWhitespace.isEmpty()) 2223 if (!leadingWhitespace.isEmpty())
2224 m_tree.insertTextNode(leadingWhitespace, AllWhitespace); 2224 m_tree.insertTextNode(leadingWhitespace, AllWhitespace);
2225 if (buffer.isEmpty()) 2225 if (buffer.isEmpty())
2226 return; 2226 return;
2227 defaultForAfterHead(); 2227 defaultForAfterHead();
2228 // Fall through. 2228 // Fall through.
2229 } 2229 }
2230 case InBodyMode: 2230 case InBodyMode:
2231 case InCaptionMode: 2231 case InCaptionMode:
2232 case TemplateContentsMode: 2232 case TemplateContentsMode:
2233 case InCellMode: { 2233 case InCellMode: {
2234 ASSERT(getInsertionMode() == InBodyMode || 2234 DCHECK(getInsertionMode() == InBodyMode ||
2235 getInsertionMode() == InCaptionMode || 2235 getInsertionMode() == InCaptionMode ||
2236 getInsertionMode() == InCellMode || 2236 getInsertionMode() == InCellMode ||
2237 getInsertionMode() == TemplateContentsMode); 2237 getInsertionMode() == TemplateContentsMode);
2238 processCharacterBufferForInBody(buffer); 2238 processCharacterBufferForInBody(buffer);
2239 break; 2239 break;
2240 } 2240 }
2241 case InTableMode: 2241 case InTableMode:
2242 case InTableBodyMode: 2242 case InTableBodyMode:
2243 case InRowMode: { 2243 case InRowMode: {
2244 ASSERT(getInsertionMode() == InTableMode || 2244 DCHECK(getInsertionMode() == InTableMode ||
2245 getInsertionMode() == InTableBodyMode || 2245 getInsertionMode() == InTableBodyMode ||
2246 getInsertionMode() == InRowMode); 2246 getInsertionMode() == InRowMode);
2247 ASSERT(m_pendingTableCharacters.isEmpty()); 2247 DCHECK(m_pendingTableCharacters.isEmpty());
2248 if (m_tree.currentStackItem()->isElementNode() && 2248 if (m_tree.currentStackItem()->isElementNode() &&
2249 (m_tree.currentStackItem()->hasTagName(tableTag) || 2249 (m_tree.currentStackItem()->hasTagName(tableTag) ||
2250 m_tree.currentStackItem()->hasTagName(tbodyTag) || 2250 m_tree.currentStackItem()->hasTagName(tbodyTag) ||
2251 m_tree.currentStackItem()->hasTagName(tfootTag) || 2251 m_tree.currentStackItem()->hasTagName(tfootTag) ||
2252 m_tree.currentStackItem()->hasTagName(theadTag) || 2252 m_tree.currentStackItem()->hasTagName(theadTag) ||
2253 m_tree.currentStackItem()->hasTagName(trTag))) { 2253 m_tree.currentStackItem()->hasTagName(trTag))) {
2254 m_originalInsertionMode = m_insertionMode; 2254 m_originalInsertionMode = m_insertionMode;
2255 setInsertionMode(InTableTextMode); 2255 setInsertionMode(InTableTextMode);
2256 // Note that we fall through to the InTableTextMode case below. 2256 // Note that we fall through to the InTableTextMode case below.
2257 } else { 2257 } else {
2258 HTMLConstructionSite::RedirectToFosterParentGuard redirecter(m_tree); 2258 HTMLConstructionSite::RedirectToFosterParentGuard redirecter(m_tree);
2259 processCharacterBufferForInBody(buffer); 2259 processCharacterBufferForInBody(buffer);
2260 break; 2260 break;
2261 } 2261 }
2262 // Fall through. 2262 // Fall through.
2263 } 2263 }
2264 case InTableTextMode: { 2264 case InTableTextMode: {
2265 buffer.giveRemainingTo(m_pendingTableCharacters); 2265 buffer.giveRemainingTo(m_pendingTableCharacters);
2266 break; 2266 break;
2267 } 2267 }
2268 case InColumnGroupMode: { 2268 case InColumnGroupMode: {
2269 ASSERT(getInsertionMode() == InColumnGroupMode); 2269 DCHECK_EQ(getInsertionMode(), InColumnGroupMode);
2270 StringView leadingWhitespace = buffer.takeLeadingWhitespace(); 2270 StringView leadingWhitespace = buffer.takeLeadingWhitespace();
2271 if (!leadingWhitespace.isEmpty()) 2271 if (!leadingWhitespace.isEmpty())
2272 m_tree.insertTextNode(leadingWhitespace, AllWhitespace); 2272 m_tree.insertTextNode(leadingWhitespace, AllWhitespace);
2273 if (buffer.isEmpty()) 2273 if (buffer.isEmpty())
2274 return; 2274 return;
2275 if (!processColgroupEndTagForInColumnGroup()) { 2275 if (!processColgroupEndTagForInColumnGroup()) {
2276 ASSERT(isParsingFragmentOrTemplateContents()); 2276 DCHECK(isParsingFragmentOrTemplateContents());
2277 // The spec tells us to drop these characters on the floor. 2277 // The spec tells us to drop these characters on the floor.
2278 buffer.skipLeadingNonWhitespace(); 2278 buffer.skipLeadingNonWhitespace();
2279 if (buffer.isEmpty()) 2279 if (buffer.isEmpty())
2280 return; 2280 return;
2281 } 2281 }
2282 goto ReprocessBuffer; 2282 goto ReprocessBuffer;
2283 } 2283 }
2284 case AfterBodyMode: 2284 case AfterBodyMode:
2285 case AfterAfterBodyMode: { 2285 case AfterAfterBodyMode: {
2286 ASSERT(getInsertionMode() == AfterBodyMode || 2286 DCHECK(getInsertionMode() == AfterBodyMode ||
2287 getInsertionMode() == AfterAfterBodyMode); 2287 getInsertionMode() == AfterAfterBodyMode);
2288 // FIXME: parse error 2288 // FIXME: parse error
2289 setInsertionMode(InBodyMode); 2289 setInsertionMode(InBodyMode);
2290 goto ReprocessBuffer; 2290 goto ReprocessBuffer;
2291 } 2291 }
2292 case TextMode: { 2292 case TextMode: {
2293 ASSERT(getInsertionMode() == TextMode); 2293 DCHECK_EQ(getInsertionMode(), TextMode);
2294 m_tree.insertTextNode(buffer.takeRemaining()); 2294 m_tree.insertTextNode(buffer.takeRemaining());
2295 break; 2295 break;
2296 } 2296 }
2297 case InHeadNoscriptMode: { 2297 case InHeadNoscriptMode: {
2298 ASSERT(getInsertionMode() == InHeadNoscriptMode); 2298 DCHECK_EQ(getInsertionMode(), InHeadNoscriptMode);
2299 StringView leadingWhitespace = buffer.takeLeadingWhitespace(); 2299 StringView leadingWhitespace = buffer.takeLeadingWhitespace();
2300 if (!leadingWhitespace.isEmpty()) 2300 if (!leadingWhitespace.isEmpty())
2301 m_tree.insertTextNode(leadingWhitespace, AllWhitespace); 2301 m_tree.insertTextNode(leadingWhitespace, AllWhitespace);
2302 if (buffer.isEmpty()) 2302 if (buffer.isEmpty())
2303 return; 2303 return;
2304 defaultForInHeadNoscript(); 2304 defaultForInHeadNoscript();
2305 goto ReprocessBuffer; 2305 goto ReprocessBuffer;
2306 } 2306 }
2307 case InFramesetMode: 2307 case InFramesetMode:
2308 case AfterFramesetMode: { 2308 case AfterFramesetMode: {
2309 ASSERT(getInsertionMode() == InFramesetMode || 2309 DCHECK(getInsertionMode() == InFramesetMode ||
2310 getInsertionMode() == AfterFramesetMode || 2310 getInsertionMode() == AfterFramesetMode ||
2311 getInsertionMode() == AfterAfterFramesetMode); 2311 getInsertionMode() == AfterAfterFramesetMode);
2312 String leadingWhitespace = buffer.takeRemainingWhitespace(); 2312 String leadingWhitespace = buffer.takeRemainingWhitespace();
2313 if (!leadingWhitespace.isEmpty()) 2313 if (!leadingWhitespace.isEmpty())
2314 m_tree.insertTextNode(leadingWhitespace, AllWhitespace); 2314 m_tree.insertTextNode(leadingWhitespace, AllWhitespace);
2315 // FIXME: We should generate a parse error if we skipped over any 2315 // FIXME: We should generate a parse error if we skipped over any
2316 // non-whitespace characters. 2316 // non-whitespace characters.
2317 break; 2317 break;
2318 } 2318 }
2319 case InSelectInTableMode: 2319 case InSelectInTableMode:
2320 case InSelectMode: { 2320 case InSelectMode: {
2321 ASSERT(getInsertionMode() == InSelectMode || 2321 DCHECK(getInsertionMode() == InSelectMode ||
2322 getInsertionMode() == InSelectInTableMode); 2322 getInsertionMode() == InSelectInTableMode);
2323 m_tree.insertTextNode(buffer.takeRemaining()); 2323 m_tree.insertTextNode(buffer.takeRemaining());
2324 break; 2324 break;
2325 } 2325 }
2326 case AfterAfterFramesetMode: { 2326 case AfterAfterFramesetMode: {
2327 String leadingWhitespace = buffer.takeRemainingWhitespace(); 2327 String leadingWhitespace = buffer.takeRemainingWhitespace();
2328 if (!leadingWhitespace.isEmpty()) { 2328 if (!leadingWhitespace.isEmpty()) {
2329 m_tree.reconstructTheActiveFormattingElements(); 2329 m_tree.reconstructTheActiveFormattingElements();
2330 m_tree.insertTextNode(leadingWhitespace, AllWhitespace); 2330 m_tree.insertTextNode(leadingWhitespace, AllWhitespace);
2331 } 2331 }
2332 // FIXME: We should generate a parse error if we skipped over any 2332 // FIXME: We should generate a parse error if we skipped over any
2333 // non-whitespace characters. 2333 // non-whitespace characters.
2334 break; 2334 break;
2335 } 2335 }
2336 } 2336 }
2337 } 2337 }
2338 2338
2339 void HTMLTreeBuilder::processCharacterBufferForInBody( 2339 void HTMLTreeBuilder::processCharacterBufferForInBody(
2340 CharacterTokenBuffer& buffer) { 2340 CharacterTokenBuffer& buffer) {
2341 m_tree.reconstructTheActiveFormattingElements(); 2341 m_tree.reconstructTheActiveFormattingElements();
2342 StringView characters = buffer.takeRemaining(); 2342 StringView characters = buffer.takeRemaining();
2343 m_tree.insertTextNode(characters); 2343 m_tree.insertTextNode(characters);
2344 if (m_framesetOk && !isAllWhitespaceOrReplacementCharacters(characters)) 2344 if (m_framesetOk && !isAllWhitespaceOrReplacementCharacters(characters))
2345 m_framesetOk = false; 2345 m_framesetOk = false;
2346 } 2346 }
2347 2347
2348 void HTMLTreeBuilder::processEndOfFile(AtomicHTMLToken* token) { 2348 void HTMLTreeBuilder::processEndOfFile(AtomicHTMLToken* token) {
2349 ASSERT(token->type() == HTMLToken::EndOfFile); 2349 DCHECK_EQ(token->type(), HTMLToken::EndOfFile);
2350 switch (getInsertionMode()) { 2350 switch (getInsertionMode()) {
2351 case InitialMode: 2351 case InitialMode:
2352 ASSERT(getInsertionMode() == InitialMode); 2352 DCHECK_EQ(getInsertionMode(), InitialMode);
2353 defaultForInitial(); 2353 defaultForInitial();
2354 // Fall through. 2354 // Fall through.
2355 case BeforeHTMLMode: 2355 case BeforeHTMLMode:
2356 ASSERT(getInsertionMode() == BeforeHTMLMode); 2356 DCHECK_EQ(getInsertionMode(), BeforeHTMLMode);
2357 defaultForBeforeHTML(); 2357 defaultForBeforeHTML();
2358 // Fall through. 2358 // Fall through.
2359 case BeforeHeadMode: 2359 case BeforeHeadMode:
2360 ASSERT(getInsertionMode() == BeforeHeadMode); 2360 DCHECK_EQ(getInsertionMode(), BeforeHeadMode);
2361 defaultForBeforeHead(); 2361 defaultForBeforeHead();
2362 // Fall through. 2362 // Fall through.
2363 case InHeadMode: 2363 case InHeadMode:
2364 ASSERT(getInsertionMode() == InHeadMode); 2364 DCHECK_EQ(getInsertionMode(), InHeadMode);
2365 defaultForInHead(); 2365 defaultForInHead();
2366 // Fall through. 2366 // Fall through.
2367 case AfterHeadMode: 2367 case AfterHeadMode:
2368 ASSERT(getInsertionMode() == AfterHeadMode); 2368 DCHECK_EQ(getInsertionMode(), AfterHeadMode);
2369 defaultForAfterHead(); 2369 defaultForAfterHead();
2370 // Fall through 2370 // Fall through
2371 case InBodyMode: 2371 case InBodyMode:
2372 case InCellMode: 2372 case InCellMode:
2373 case InCaptionMode: 2373 case InCaptionMode:
2374 case InRowMode: 2374 case InRowMode:
2375 ASSERT(getInsertionMode() == InBodyMode || 2375 DCHECK(getInsertionMode() == InBodyMode ||
2376 getInsertionMode() == InCellMode || 2376 getInsertionMode() == InCellMode ||
2377 getInsertionMode() == InCaptionMode || 2377 getInsertionMode() == InCaptionMode ||
2378 getInsertionMode() == InRowMode || 2378 getInsertionMode() == InRowMode ||
2379 getInsertionMode() == TemplateContentsMode); 2379 getInsertionMode() == TemplateContentsMode);
2380 // Emit parse error based on what elements are still open. 2380 // Emit parse error based on what elements are still open.
2381 DVLOG(1) << "Not implemented."; 2381 DVLOG(1) << "Not implemented.";
2382 if (!m_templateInsertionModes.isEmpty() && 2382 if (!m_templateInsertionModes.isEmpty() &&
2383 processEndOfFileForInTemplateContents(token)) 2383 processEndOfFileForInTemplateContents(token))
2384 return; 2384 return;
2385 break; 2385 break;
2386 case AfterBodyMode: 2386 case AfterBodyMode:
2387 case AfterAfterBodyMode: 2387 case AfterAfterBodyMode:
2388 ASSERT(getInsertionMode() == AfterBodyMode || 2388 DCHECK(getInsertionMode() == AfterBodyMode ||
2389 getInsertionMode() == AfterAfterBodyMode); 2389 getInsertionMode() == AfterAfterBodyMode);
2390 break; 2390 break;
2391 case InHeadNoscriptMode: 2391 case InHeadNoscriptMode:
2392 ASSERT(getInsertionMode() == InHeadNoscriptMode); 2392 DCHECK_EQ(getInsertionMode(), InHeadNoscriptMode);
2393 defaultForInHeadNoscript(); 2393 defaultForInHeadNoscript();
2394 processEndOfFile(token); 2394 processEndOfFile(token);
2395 return; 2395 return;
2396 case AfterFramesetMode: 2396 case AfterFramesetMode:
2397 case AfterAfterFramesetMode: 2397 case AfterAfterFramesetMode:
2398 ASSERT(getInsertionMode() == AfterFramesetMode || 2398 DCHECK(getInsertionMode() == AfterFramesetMode ||
2399 getInsertionMode() == AfterAfterFramesetMode); 2399 getInsertionMode() == AfterAfterFramesetMode);
2400 break; 2400 break;
2401 case InColumnGroupMode: 2401 case InColumnGroupMode:
2402 if (m_tree.currentIsRootNode()) { 2402 if (m_tree.currentIsRootNode()) {
2403 ASSERT(isParsingFragment()); 2403 DCHECK(isParsingFragment());
2404 return; // FIXME: Should we break here instead of returning? 2404 return; // FIXME: Should we break here instead of returning?
2405 } 2405 }
2406 ASSERT(m_tree.currentNode()->hasTagName(colgroupTag) || 2406 DCHECK(m_tree.currentNode()->hasTagName(colgroupTag) ||
2407 isHTMLTemplateElement(m_tree.currentNode())); 2407 isHTMLTemplateElement(m_tree.currentNode()));
2408 processColgroupEndTagForInColumnGroup(); 2408 processColgroupEndTagForInColumnGroup();
2409 // Fall through 2409 // Fall through
2410 case InFramesetMode: 2410 case InFramesetMode:
2411 case InTableMode: 2411 case InTableMode:
2412 case InTableBodyMode: 2412 case InTableBodyMode:
2413 case InSelectInTableMode: 2413 case InSelectInTableMode:
2414 case InSelectMode: 2414 case InSelectMode:
2415 ASSERT(getInsertionMode() == InSelectMode || 2415 DCHECK(getInsertionMode() == InSelectMode ||
2416 getInsertionMode() == InSelectInTableMode || 2416 getInsertionMode() == InSelectInTableMode ||
2417 getInsertionMode() == InTableMode || 2417 getInsertionMode() == InTableMode ||
2418 getInsertionMode() == InFramesetMode || 2418 getInsertionMode() == InFramesetMode ||
2419 getInsertionMode() == InTableBodyMode || 2419 getInsertionMode() == InTableBodyMode ||
2420 getInsertionMode() == InColumnGroupMode); 2420 getInsertionMode() == InColumnGroupMode);
2421 if (m_tree.currentNode() != m_tree.openElements()->rootNode()) 2421 if (m_tree.currentNode() != m_tree.openElements()->rootNode())
2422 parseError(token); 2422 parseError(token);
2423 if (!m_templateInsertionModes.isEmpty() && 2423 if (!m_templateInsertionModes.isEmpty() &&
2424 processEndOfFileForInTemplateContents(token)) 2424 processEndOfFileForInTemplateContents(token))
2425 return; 2425 return;
2426 break; 2426 break;
2427 case InTableTextMode: 2427 case InTableTextMode:
2428 defaultForInTableText(); 2428 defaultForInTableText();
2429 processEndOfFile(token); 2429 processEndOfFile(token);
2430 return; 2430 return;
2431 case TextMode: { 2431 case TextMode: {
2432 parseError(token); 2432 parseError(token);
2433 if (m_tree.currentStackItem()->hasTagName(scriptTag)) { 2433 if (m_tree.currentStackItem()->hasTagName(scriptTag)) {
2434 // Mark the script element as "already started". 2434 // Mark the script element as "already started".
2435 DVLOG(1) << "Not implemented."; 2435 DVLOG(1) << "Not implemented.";
2436 } 2436 }
2437 Element* el = m_tree.openElements()->top(); 2437 Element* el = m_tree.openElements()->top();
2438 if (isHTMLTextAreaElement(el)) 2438 if (isHTMLTextAreaElement(el))
2439 toHTMLFormControlElement(el)->setBlocksFormSubmission(true); 2439 toHTMLFormControlElement(el)->setBlocksFormSubmission(true);
2440 m_tree.openElements()->pop(); 2440 m_tree.openElements()->pop();
2441 ASSERT(m_originalInsertionMode != TextMode); 2441 DCHECK_NE(m_originalInsertionMode, TextMode);
2442 setInsertionMode(m_originalInsertionMode); 2442 setInsertionMode(m_originalInsertionMode);
2443 processEndOfFile(token); 2443 processEndOfFile(token);
2444 return; 2444 return;
2445 } 2445 }
2446 case TemplateContentsMode: 2446 case TemplateContentsMode:
2447 if (processEndOfFileForInTemplateContents(token)) 2447 if (processEndOfFileForInTemplateContents(token))
2448 return; 2448 return;
2449 break; 2449 break;
2450 } 2450 }
2451 m_tree.processEndOfFile(); 2451 m_tree.processEndOfFile();
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
2495 m_tree.insertTextNode(characters, NotAllWhitespace); 2495 m_tree.insertTextNode(characters, NotAllWhitespace);
2496 m_framesetOk = false; 2496 m_framesetOk = false;
2497 setInsertionMode(m_originalInsertionMode); 2497 setInsertionMode(m_originalInsertionMode);
2498 return; 2498 return;
2499 } 2499 }
2500 m_tree.insertTextNode(characters); 2500 m_tree.insertTextNode(characters);
2501 setInsertionMode(m_originalInsertionMode); 2501 setInsertionMode(m_originalInsertionMode);
2502 } 2502 }
2503 2503
2504 bool HTMLTreeBuilder::processStartTagForInHead(AtomicHTMLToken* token) { 2504 bool HTMLTreeBuilder::processStartTagForInHead(AtomicHTMLToken* token) {
2505 ASSERT(token->type() == HTMLToken::StartTag); 2505 DCHECK_EQ(token->type(), HTMLToken::StartTag);
2506 if (token->name() == htmlTag) { 2506 if (token->name() == htmlTag) {
2507 processHtmlStartTagForInBody(token); 2507 processHtmlStartTagForInBody(token);
2508 return true; 2508 return true;
2509 } 2509 }
2510 if (token->name() == baseTag || token->name() == basefontTag || 2510 if (token->name() == baseTag || token->name() == basefontTag ||
2511 token->name() == bgsoundTag || token->name() == commandTag || 2511 token->name() == bgsoundTag || token->name() == commandTag ||
2512 token->name() == linkTag || token->name() == metaTag) { 2512 token->name() == linkTag || token->name() == metaTag) {
2513 m_tree.insertSelfClosingHTMLElementDestroyingToken(token); 2513 m_tree.insertSelfClosingHTMLElementDestroyingToken(token);
2514 // Note: The custom processing for the <meta> tag is done in 2514 // Note: The custom processing for the <meta> tag is done in
2515 // HTMLMetaElement::process(). 2515 // HTMLMetaElement::process().
(...skipping 25 matching lines...) Expand all
2541 return true; 2541 return true;
2542 } 2542 }
2543 if (token->name() == headTag) { 2543 if (token->name() == headTag) {
2544 parseError(token); 2544 parseError(token);
2545 return true; 2545 return true;
2546 } 2546 }
2547 return false; 2547 return false;
2548 } 2548 }
2549 2549
2550 void HTMLTreeBuilder::processGenericRCDATAStartTag(AtomicHTMLToken* token) { 2550 void HTMLTreeBuilder::processGenericRCDATAStartTag(AtomicHTMLToken* token) {
2551 ASSERT(token->type() == HTMLToken::StartTag); 2551 DCHECK_EQ(token->type(), HTMLToken::StartTag);
2552 m_tree.insertHTMLElement(token); 2552 m_tree.insertHTMLElement(token);
2553 if (m_parser->tokenizer()) 2553 if (m_parser->tokenizer())
2554 m_parser->tokenizer()->setState(HTMLTokenizer::RCDATAState); 2554 m_parser->tokenizer()->setState(HTMLTokenizer::RCDATAState);
2555 m_originalInsertionMode = m_insertionMode; 2555 m_originalInsertionMode = m_insertionMode;
2556 setInsertionMode(TextMode); 2556 setInsertionMode(TextMode);
2557 } 2557 }
2558 2558
2559 void HTMLTreeBuilder::processGenericRawTextStartTag(AtomicHTMLToken* token) { 2559 void HTMLTreeBuilder::processGenericRawTextStartTag(AtomicHTMLToken* token) {
2560 ASSERT(token->type() == HTMLToken::StartTag); 2560 DCHECK_EQ(token->type(), HTMLToken::StartTag);
2561 m_tree.insertHTMLElement(token); 2561 m_tree.insertHTMLElement(token);
2562 if (m_parser->tokenizer()) 2562 if (m_parser->tokenizer())
2563 m_parser->tokenizer()->setState(HTMLTokenizer::RAWTEXTState); 2563 m_parser->tokenizer()->setState(HTMLTokenizer::RAWTEXTState);
2564 m_originalInsertionMode = m_insertionMode; 2564 m_originalInsertionMode = m_insertionMode;
2565 setInsertionMode(TextMode); 2565 setInsertionMode(TextMode);
2566 } 2566 }
2567 2567
2568 void HTMLTreeBuilder::processScriptStartTag(AtomicHTMLToken* token) { 2568 void HTMLTreeBuilder::processScriptStartTag(AtomicHTMLToken* token) {
2569 ASSERT(token->type() == HTMLToken::StartTag); 2569 DCHECK_EQ(token->type(), HTMLToken::StartTag);
2570 m_tree.insertScriptElement(token); 2570 m_tree.insertScriptElement(token);
2571 if (m_parser->tokenizer()) 2571 if (m_parser->tokenizer())
2572 m_parser->tokenizer()->setState(HTMLTokenizer::ScriptDataState); 2572 m_parser->tokenizer()->setState(HTMLTokenizer::ScriptDataState);
2573 m_originalInsertionMode = m_insertionMode; 2573 m_originalInsertionMode = m_insertionMode;
2574 2574
2575 TextPosition position = m_parser->textPosition(); 2575 TextPosition position = m_parser->textPosition();
2576 2576
2577 m_scriptToProcessStartPosition = position; 2577 m_scriptToProcessStartPosition = position;
2578 2578
2579 setInsertionMode(TextMode); 2579 setInsertionMode(TextMode);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
2617 if (m_framesetOk && !isAllWhitespaceOrReplacementCharacters(characters)) 2617 if (m_framesetOk && !isAllWhitespaceOrReplacementCharacters(characters))
2618 m_framesetOk = false; 2618 m_framesetOk = false;
2619 return; 2619 return;
2620 } 2620 }
2621 2621
2622 m_tree.flush(FlushAlways); 2622 m_tree.flush(FlushAlways);
2623 HTMLStackItem* adjustedCurrentNode = adjustedCurrentStackItem(); 2623 HTMLStackItem* adjustedCurrentNode = adjustedCurrentStackItem();
2624 2624
2625 switch (token->type()) { 2625 switch (token->type()) {
2626 case HTMLToken::Uninitialized: 2626 case HTMLToken::Uninitialized:
2627 ASSERT_NOT_REACHED(); 2627 NOTREACHED();
2628 break; 2628 break;
2629 case HTMLToken::DOCTYPE: 2629 case HTMLToken::DOCTYPE:
2630 parseError(token); 2630 parseError(token);
2631 break; 2631 break;
2632 case HTMLToken::StartTag: { 2632 case HTMLToken::StartTag: {
2633 if (token->name() == bTag || token->name() == bigTag || 2633 if (token->name() == bTag || token->name() == bigTag ||
2634 token->name() == blockquoteTag || token->name() == bodyTag || 2634 token->name() == blockquoteTag || token->name() == bodyTag ||
2635 token->name() == brTag || token->name() == centerTag || 2635 token->name() == brTag || token->name() == centerTag ||
2636 token->name() == codeTag || token->name() == ddTag || 2636 token->name() == codeTag || token->name() == ddTag ||
2637 token->name() == divTag || token->name() == dlTag || 2637 token->name() == divTag || token->name() == dlTag ||
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
2702 // Otherwise, process the token according to the rules given in the 2702 // Otherwise, process the token according to the rules given in the
2703 // section corresponding to the current insertion mode in HTML content. 2703 // section corresponding to the current insertion mode in HTML content.
2704 processEndTag(token); 2704 processEndTag(token);
2705 break; 2705 break;
2706 } 2706 }
2707 case HTMLToken::Comment: 2707 case HTMLToken::Comment:
2708 m_tree.insertComment(token); 2708 m_tree.insertComment(token);
2709 break; 2709 break;
2710 case HTMLToken::Character: 2710 case HTMLToken::Character:
2711 case HTMLToken::EndOfFile: 2711 case HTMLToken::EndOfFile:
2712 ASSERT_NOT_REACHED(); 2712 NOTREACHED();
2713 break; 2713 break;
2714 } 2714 }
2715 } 2715 }
2716 2716
2717 void HTMLTreeBuilder::finished() { 2717 void HTMLTreeBuilder::finished() {
2718 if (isParsingFragment()) 2718 if (isParsingFragment())
2719 return; 2719 return;
2720 2720
2721 ASSERT(m_templateInsertionModes.isEmpty()); 2721 DCHECK(m_templateInsertionModes.isEmpty());
2722 ASSERT(m_isAttached); 2722 #if DCHECK_IS_ON()
2723 DCHECK(m_isAttached);
2724 #endif
2723 // Warning, this may detach the parser. Do not do anything else after this. 2725 // Warning, this may detach the parser. Do not do anything else after this.
2724 m_tree.finishedParsing(); 2726 m_tree.finishedParsing();
2725 } 2727 }
2726 2728
2727 void HTMLTreeBuilder::parseError(AtomicHTMLToken*) {} 2729 void HTMLTreeBuilder::parseError(AtomicHTMLToken*) {}
2728 2730
2729 #ifndef NDEBUG 2731 #ifndef NDEBUG
2730 const char* HTMLTreeBuilder::toString(HTMLTreeBuilder::InsertionMode mode) { 2732 const char* HTMLTreeBuilder::toString(HTMLTreeBuilder::InsertionMode mode) {
2731 switch (mode) { 2733 switch (mode) {
2732 #define DEFINE_STRINGIFY(mode) \ 2734 #define DEFINE_STRINGIFY(mode) \
(...skipping 22 matching lines...) Expand all
2755 DEFINE_STRINGIFY(AfterFramesetMode) 2757 DEFINE_STRINGIFY(AfterFramesetMode)
2756 DEFINE_STRINGIFY(AfterAfterBodyMode) 2758 DEFINE_STRINGIFY(AfterAfterBodyMode)
2757 DEFINE_STRINGIFY(AfterAfterFramesetMode) 2759 DEFINE_STRINGIFY(AfterAfterFramesetMode)
2758 #undef DEFINE_STRINGIFY 2760 #undef DEFINE_STRINGIFY
2759 } 2761 }
2760 return "<unknown>"; 2762 return "<unknown>";
2761 } 2763 }
2762 #endif 2764 #endif
2763 2765
2764 } // namespace blink 2766 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698