OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |