| 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 Apple Inc. All rights reserved. | 3 * Copyright (C) 2011 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 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 333 // DocumentParser expects detach() to always be called before it's destroyed
. | 333 // DocumentParser expects detach() to always be called before it's destroyed
. |
| 334 m_isAttached = false; | 334 m_isAttached = false; |
| 335 #endif | 335 #endif |
| 336 // HTMLConstructionSite might be on the callstack when detach() is called | 336 // HTMLConstructionSite might be on the callstack when detach() is called |
| 337 // otherwise we'd just call m_tree.clear() here instead. | 337 // otherwise we'd just call m_tree.clear() here instead. |
| 338 m_tree.detach(); | 338 m_tree.detach(); |
| 339 } | 339 } |
| 340 | 340 |
| 341 HTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext() | 341 HTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext() |
| 342 : m_fragment(0) | 342 : m_fragment(0) |
| 343 , m_contextElement(0) | |
| 344 { | 343 { |
| 345 } | 344 } |
| 346 | 345 |
| 347 HTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext(DocumentFragment
* fragment, Element* contextElement) | 346 HTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext(DocumentFragment
* fragment, Element* contextElement) |
| 348 : m_fragment(fragment) | 347 : m_fragment(fragment) |
| 349 , m_contextElement(contextElement) | |
| 350 { | 348 { |
| 351 ASSERT(!fragment->hasChildNodes()); | 349 ASSERT(!fragment->hasChildNodes()); |
| 350 m_contextElementStackItem = HTMLStackItem::create(contextElement, HTMLStackI
tem::ItemForContextElement); |
| 352 } | 351 } |
| 353 | 352 |
| 354 HTMLTreeBuilder::FragmentParsingContext::~FragmentParsingContext() | 353 HTMLTreeBuilder::FragmentParsingContext::~FragmentParsingContext() |
| 355 { | 354 { |
| 356 } | 355 } |
| 357 | 356 |
| 358 PassRefPtr<Element> HTMLTreeBuilder::takeScriptToProcess(TextPosition& scriptSta
rtPosition) | 357 PassRefPtr<Element> HTMLTreeBuilder::takeScriptToProcess(TextPosition& scriptSta
rtPosition) |
| 359 { | 358 { |
| 360 ASSERT(m_scriptToProcess); | 359 ASSERT(m_scriptToProcess); |
| 361 ASSERT(!m_tree.hasPendingTasks()); | 360 ASSERT(!m_tree.hasPendingTasks()); |
| 362 // Unpause ourselves, callers may pause us again when processing the script. | 361 // Unpause ourselves, callers may pause us again when processing the script. |
| 363 // The HTML5 spec is written as though scripts are executed inside the tree | 362 // The HTML5 spec is written as though scripts are executed inside the tree |
| 364 // builder. We pause the parser to exit the tree builder, and then resume | 363 // builder. We pause the parser to exit the tree builder, and then resume |
| 365 // before running scripts. | 364 // before running scripts. |
| 366 scriptStartPosition = m_scriptToProcessStartPosition; | 365 scriptStartPosition = m_scriptToProcessStartPosition; |
| 367 m_scriptToProcessStartPosition = uninitializedPositionValue1(); | 366 m_scriptToProcessStartPosition = uninitializedPositionValue1(); |
| 368 return m_scriptToProcess.release(); | 367 return m_scriptToProcess.release(); |
| 369 } | 368 } |
| 370 | 369 |
| 371 void HTMLTreeBuilder::constructTree(AtomicHTMLToken* token) | 370 void HTMLTreeBuilder::constructTree(AtomicHTMLToken* token) |
| 372 { | 371 { |
| 373 if (shouldProcessTokenInForeignContent(token)) | 372 if (shouldProcessTokenInForeignContent(token)) |
| 374 processTokenInForeignContent(token); | 373 processTokenInForeignContent(token); |
| 375 else | 374 else |
| 376 processToken(token); | 375 processToken(token); |
| 377 | 376 |
| 378 if (m_parser->tokenizer()) { | 377 if (m_parser->tokenizer()) { |
| 379 bool inForeignContent = false; | 378 bool inForeignContent = false; |
| 380 if (!m_tree.isEmpty()) { | 379 if (!m_tree.isEmpty()) { |
| 381 RefPtr<HTMLStackItem> adjustedCurrentNode = adjustedCurrentStackItem
(); | 380 HTMLStackItem* adjustedCurrentNode = adjustedCurrentStackItem(); |
| 382 inForeignContent = !adjustedCurrentNode->isInHTMLNamespace() | 381 inForeignContent = !adjustedCurrentNode->isInHTMLNamespace() |
| 383 && !HTMLElementStack::isHTMLIntegrationPoint(adjustedCurrentNode
.get()) | 382 && !HTMLElementStack::isHTMLIntegrationPoint(adjustedCurrentNode
) |
| 384 && !HTMLElementStack::isMathMLTextIntegrationPoint(adjustedCurre
ntNode.get()); | 383 && !HTMLElementStack::isMathMLTextIntegrationPoint(adjustedCurre
ntNode); |
| 385 } | 384 } |
| 386 | 385 |
| 387 m_parser->tokenizer()->setForceNullCharacterReplacement(m_insertionMode
== TextMode || inForeignContent); | 386 m_parser->tokenizer()->setForceNullCharacterReplacement(m_insertionMode
== TextMode || inForeignContent); |
| 388 m_parser->tokenizer()->setShouldAllowCDATA(inForeignContent); | 387 m_parser->tokenizer()->setShouldAllowCDATA(inForeignContent); |
| 389 } | 388 } |
| 390 | 389 |
| 391 m_tree.executeQueuedTasks(); | 390 m_tree.executeQueuedTasks(); |
| 392 // We might be detached now. | 391 // We might be detached now. |
| 393 } | 392 } |
| 394 | 393 |
| (...skipping 601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 996 ASSERT(isParsingFragmentOrTemplateContents()); | 995 ASSERT(isParsingFragmentOrTemplateContents()); |
| 997 // FIXME: parse error | 996 // FIXME: parse error |
| 998 return false; | 997 return false; |
| 999 } | 998 } |
| 1000 m_tree.openElements()->pop(); | 999 m_tree.openElements()->pop(); |
| 1001 setInsertionMode(InTableMode); | 1000 setInsertionMode(InTableMode); |
| 1002 return true; | 1001 return true; |
| 1003 } | 1002 } |
| 1004 | 1003 |
| 1005 // http://www.whatwg.org/specs/web-apps/current-work/#adjusted-current-node | 1004 // http://www.whatwg.org/specs/web-apps/current-work/#adjusted-current-node |
| 1006 PassRefPtr<HTMLStackItem> HTMLTreeBuilder::adjustedCurrentStackItem() const | 1005 HTMLStackItem* HTMLTreeBuilder::adjustedCurrentStackItem() const |
| 1007 { | 1006 { |
| 1008 ASSERT(!m_tree.isEmpty()); | 1007 ASSERT(!m_tree.isEmpty()); |
| 1009 if (isParsingFragment() && m_tree.openElements()->hasOnlyOneElement()) | 1008 if (isParsingFragment() && m_tree.openElements()->hasOnlyOneElement()) |
| 1010 return HTMLStackItem::create(m_fragmentContext.contextElement(), HTMLSta
ckItem::ItemForContextElement); | 1009 return m_fragmentContext.contextElementStackItem(); |
| 1011 | 1010 |
| 1012 return m_tree.currentStackItem(); | 1011 return m_tree.currentStackItem(); |
| 1013 } | 1012 } |
| 1014 | 1013 |
| 1015 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html
#close-the-cell | 1014 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html
#close-the-cell |
| 1016 void HTMLTreeBuilder::closeTheCell() | 1015 void HTMLTreeBuilder::closeTheCell() |
| 1017 { | 1016 { |
| 1018 ASSERT(insertionMode() == InCellMode); | 1017 ASSERT(insertionMode() == InCellMode); |
| 1019 if (m_tree.openElements()->inTableScope(tdTag)) { | 1018 if (m_tree.openElements()->inTableScope(tdTag)) { |
| 1020 ASSERT(!m_tree.openElements()->inTableScope(thTag)); | 1019 ASSERT(!m_tree.openElements()->inTableScope(thTag)); |
| (...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1617 void HTMLTreeBuilder::resetInsertionModeAppropriately() | 1616 void HTMLTreeBuilder::resetInsertionModeAppropriately() |
| 1618 { | 1617 { |
| 1619 // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#
reset-the-insertion-mode-appropriately | 1618 // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#
reset-the-insertion-mode-appropriately |
| 1620 bool last = false; | 1619 bool last = false; |
| 1621 HTMLElementStack::ElementRecord* nodeRecord = m_tree.openElements()->topReco
rd(); | 1620 HTMLElementStack::ElementRecord* nodeRecord = m_tree.openElements()->topReco
rd(); |
| 1622 while (1) { | 1621 while (1) { |
| 1623 RefPtr<HTMLStackItem> item = nodeRecord->stackItem(); | 1622 RefPtr<HTMLStackItem> item = nodeRecord->stackItem(); |
| 1624 if (item->node() == m_tree.openElements()->rootNode()) { | 1623 if (item->node() == m_tree.openElements()->rootNode()) { |
| 1625 last = true; | 1624 last = true; |
| 1626 if (isParsingFragment()) | 1625 if (isParsingFragment()) |
| 1627 item = HTMLStackItem::create(m_fragmentContext.contextElement(),
HTMLStackItem::ItemForContextElement); | 1626 item = m_fragmentContext.contextElementStackItem(); |
| 1628 } | 1627 } |
| 1629 if (item->hasTagName(templateTag)) | 1628 if (item->hasTagName(templateTag)) |
| 1630 return setInsertionMode(m_templateInsertionModes.last()); | 1629 return setInsertionMode(m_templateInsertionModes.last()); |
| 1631 if (item->hasTagName(selectTag)) { | 1630 if (item->hasTagName(selectTag)) { |
| 1632 if (!last) { | 1631 if (!last) { |
| 1633 while (item->node() != m_tree.openElements()->rootNode() && !ite
m->hasTagName(templateTag)) { | 1632 while (item->node() != m_tree.openElements()->rootNode() && !ite
m->hasTagName(templateTag)) { |
| 1634 nodeRecord = nodeRecord->next(); | 1633 nodeRecord = nodeRecord->next(); |
| 1635 item = nodeRecord->stackItem(); | 1634 item = nodeRecord->stackItem(); |
| 1636 if (isHTMLTableElement(item->node())) | 1635 if (isHTMLTableElement(item->node())) |
| 1637 return setInsertionMode(InSelectInTableMode); | 1636 return setInsertionMode(InSelectInTableMode); |
| (...skipping 1047 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2685 m_scriptToProcessStartPosition = position; | 2684 m_scriptToProcessStartPosition = position; |
| 2686 | 2685 |
| 2687 setInsertionMode(TextMode); | 2686 setInsertionMode(TextMode); |
| 2688 } | 2687 } |
| 2689 | 2688 |
| 2690 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tree-construction
.html#tree-construction | 2689 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tree-construction
.html#tree-construction |
| 2691 bool HTMLTreeBuilder::shouldProcessTokenInForeignContent(AtomicHTMLToken* token) | 2690 bool HTMLTreeBuilder::shouldProcessTokenInForeignContent(AtomicHTMLToken* token) |
| 2692 { | 2691 { |
| 2693 if (m_tree.isEmpty()) | 2692 if (m_tree.isEmpty()) |
| 2694 return false; | 2693 return false; |
| 2695 RefPtr<HTMLStackItem> adjustedCurrentNode = adjustedCurrentStackItem(); | 2694 HTMLStackItem* adjustedCurrentNode = adjustedCurrentStackItem(); |
| 2696 | 2695 |
| 2697 if (adjustedCurrentNode->isInHTMLNamespace()) | 2696 if (adjustedCurrentNode->isInHTMLNamespace()) |
| 2698 return false; | 2697 return false; |
| 2699 if (HTMLElementStack::isMathMLTextIntegrationPoint(adjustedCurrentNode.get()
)) { | 2698 if (HTMLElementStack::isMathMLTextIntegrationPoint(adjustedCurrentNode)) { |
| 2700 if (token->type() == HTMLToken::StartTag | 2699 if (token->type() == HTMLToken::StartTag |
| 2701 && token->name() != MathMLNames::mglyphTag | 2700 && token->name() != MathMLNames::mglyphTag |
| 2702 && token->name() != MathMLNames::malignmarkTag) | 2701 && token->name() != MathMLNames::malignmarkTag) |
| 2703 return false; | 2702 return false; |
| 2704 if (token->type() == HTMLToken::Character) | 2703 if (token->type() == HTMLToken::Character) |
| 2705 return false; | 2704 return false; |
| 2706 } | 2705 } |
| 2707 if (adjustedCurrentNode->hasTagName(MathMLNames::annotation_xmlTag) | 2706 if (adjustedCurrentNode->hasTagName(MathMLNames::annotation_xmlTag) |
| 2708 && token->type() == HTMLToken::StartTag | 2707 && token->type() == HTMLToken::StartTag |
| 2709 && token->name() == SVGNames::svgTag) | 2708 && token->name() == SVGNames::svgTag) |
| 2710 return false; | 2709 return false; |
| 2711 if (HTMLElementStack::isHTMLIntegrationPoint(adjustedCurrentNode.get())) { | 2710 if (HTMLElementStack::isHTMLIntegrationPoint(adjustedCurrentNode)) { |
| 2712 if (token->type() == HTMLToken::StartTag) | 2711 if (token->type() == HTMLToken::StartTag) |
| 2713 return false; | 2712 return false; |
| 2714 if (token->type() == HTMLToken::Character) | 2713 if (token->type() == HTMLToken::Character) |
| 2715 return false; | 2714 return false; |
| 2716 } | 2715 } |
| 2717 if (token->type() == HTMLToken::EndOfFile) | 2716 if (token->type() == HTMLToken::EndOfFile) |
| 2718 return false; | 2717 return false; |
| 2719 return true; | 2718 return true; |
| 2720 } | 2719 } |
| 2721 | 2720 |
| 2722 void HTMLTreeBuilder::processTokenInForeignContent(AtomicHTMLToken* token) | 2721 void HTMLTreeBuilder::processTokenInForeignContent(AtomicHTMLToken* token) |
| 2723 { | 2722 { |
| 2724 if (token->type() == HTMLToken::Character) { | 2723 if (token->type() == HTMLToken::Character) { |
| 2725 const String& characters = token->characters(); | 2724 const String& characters = token->characters(); |
| 2726 m_tree.insertTextNode(characters); | 2725 m_tree.insertTextNode(characters); |
| 2727 if (m_framesetOk && !isAllWhitespaceOrReplacementCharacters(characters)) | 2726 if (m_framesetOk && !isAllWhitespaceOrReplacementCharacters(characters)) |
| 2728 m_framesetOk = false; | 2727 m_framesetOk = false; |
| 2729 return; | 2728 return; |
| 2730 } | 2729 } |
| 2731 | 2730 |
| 2732 m_tree.flush(); | 2731 m_tree.flush(); |
| 2733 RefPtr<HTMLStackItem> adjustedCurrentNode = adjustedCurrentStackItem(); | 2732 HTMLStackItem* adjustedCurrentNode = adjustedCurrentStackItem(); |
| 2734 | 2733 |
| 2735 switch (token->type()) { | 2734 switch (token->type()) { |
| 2736 case HTMLToken::Uninitialized: | 2735 case HTMLToken::Uninitialized: |
| 2737 ASSERT_NOT_REACHED(); | 2736 ASSERT_NOT_REACHED(); |
| 2738 break; | 2737 break; |
| 2739 case HTMLToken::DOCTYPE: | 2738 case HTMLToken::DOCTYPE: |
| 2740 parseError(token); | 2739 parseError(token); |
| 2741 break; | 2740 break; |
| 2742 case HTMLToken::StartTag: { | 2741 case HTMLToken::StartTag: { |
| 2743 if (token->name() == bTag | 2742 if (token->name() == bTag |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2845 ASSERT(m_isAttached); | 2844 ASSERT(m_isAttached); |
| 2846 // Warning, this may detach the parser. Do not do anything else after this. | 2845 // Warning, this may detach the parser. Do not do anything else after this. |
| 2847 m_tree.finishedParsing(); | 2846 m_tree.finishedParsing(); |
| 2848 } | 2847 } |
| 2849 | 2848 |
| 2850 void HTMLTreeBuilder::parseError(AtomicHTMLToken*) | 2849 void HTMLTreeBuilder::parseError(AtomicHTMLToken*) |
| 2851 { | 2850 { |
| 2852 } | 2851 } |
| 2853 | 2852 |
| 2854 } // namespace WebCore | 2853 } // namespace WebCore |
| OLD | NEW |