| 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 |