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 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
369 } | 369 } |
370 | 370 |
371 void HTMLTreeBuilder::constructTree(AtomicHTMLToken* token) | 371 void HTMLTreeBuilder::constructTree(AtomicHTMLToken* token) |
372 { | 372 { |
373 if (shouldProcessTokenInForeignContent(token)) | 373 if (shouldProcessTokenInForeignContent(token)) |
374 processTokenInForeignContent(token); | 374 processTokenInForeignContent(token); |
375 else | 375 else |
376 processToken(token); | 376 processToken(token); |
377 | 377 |
378 if (m_parser->tokenizer()) { | 378 if (m_parser->tokenizer()) { |
379 bool inForeignContent = false; | 379 bool inForeignContent = !m_tree.isEmpty() |
380 if (!m_tree.isEmpty()) { | 380 && !m_tree.currentStackItem()->isInHTMLNamespace() |
381 RefPtr<HTMLStackItem> adjustedCurrentNode = adjustedCurrentStackItem
(); | 381 && !HTMLElementStack::isHTMLIntegrationPoint(m_tree.currentStackItem
()) |
382 inForeignContent = !adjustedCurrentNode->isInHTMLNamespace() | 382 && !HTMLElementStack::isMathMLTextIntegrationPoint(m_tree.currentSta
ckItem()); |
383 && !HTMLElementStack::isHTMLIntegrationPoint(adjustedCurrentNode
.get()) | |
384 && !HTMLElementStack::isMathMLTextIntegrationPoint(adjustedCurre
ntNode.get()); | |
385 } | |
386 | 383 |
387 m_parser->tokenizer()->setForceNullCharacterReplacement(m_insertionMode
== TextMode || inForeignContent); | 384 m_parser->tokenizer()->setForceNullCharacterReplacement(m_insertionMode
== TextMode || inForeignContent); |
388 m_parser->tokenizer()->setShouldAllowCDATA(inForeignContent); | 385 m_parser->tokenizer()->setShouldAllowCDATA(inForeignContent); |
389 } | 386 } |
390 | 387 |
391 m_tree.executeQueuedTasks(); | 388 m_tree.executeQueuedTasks(); |
392 // We might be detached now. | 389 // We might be detached now. |
393 } | 390 } |
394 | 391 |
395 void HTMLTreeBuilder::processToken(AtomicHTMLToken* token) | 392 void HTMLTreeBuilder::processToken(AtomicHTMLToken* token) |
(...skipping 599 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
995 if (m_tree.currentIsRootNode() || m_tree.currentNode()->hasTagName(templateT
ag)) { | 992 if (m_tree.currentIsRootNode() || m_tree.currentNode()->hasTagName(templateT
ag)) { |
996 ASSERT(isParsingFragmentOrTemplateContents()); | 993 ASSERT(isParsingFragmentOrTemplateContents()); |
997 // FIXME: parse error | 994 // FIXME: parse error |
998 return false; | 995 return false; |
999 } | 996 } |
1000 m_tree.openElements()->pop(); | 997 m_tree.openElements()->pop(); |
1001 setInsertionMode(InTableMode); | 998 setInsertionMode(InTableMode); |
1002 return true; | 999 return true; |
1003 } | 1000 } |
1004 | 1001 |
1005 // http://www.whatwg.org/specs/web-apps/current-work/#adjusted-current-node | |
1006 PassRefPtr<HTMLStackItem> HTMLTreeBuilder::adjustedCurrentStackItem() const | |
1007 { | |
1008 ASSERT(!m_tree.isEmpty()); | |
1009 if (isParsingFragment() && m_tree.openElements()->hasOnlyOneElement()) | |
1010 return HTMLStackItem::create(m_fragmentContext.contextElement(), HTMLSta
ckItem::ItemForContextElement); | |
1011 | |
1012 return m_tree.currentStackItem(); | |
1013 } | |
1014 | |
1015 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html
#close-the-cell | 1002 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html
#close-the-cell |
1016 void HTMLTreeBuilder::closeTheCell() | 1003 void HTMLTreeBuilder::closeTheCell() |
1017 { | 1004 { |
1018 ASSERT(insertionMode() == InCellMode); | 1005 ASSERT(insertionMode() == InCellMode); |
1019 if (m_tree.openElements()->inTableScope(tdTag)) { | 1006 if (m_tree.openElements()->inTableScope(tdTag)) { |
1020 ASSERT(!m_tree.openElements()->inTableScope(thTag)); | 1007 ASSERT(!m_tree.openElements()->inTableScope(thTag)); |
1021 processFakeEndTag(tdTag); | 1008 processFakeEndTag(tdTag); |
1022 return; | 1009 return; |
1023 } | 1010 } |
1024 ASSERT(m_tree.openElements()->inTableScope(thTag)); | 1011 ASSERT(m_tree.openElements()->inTableScope(thTag)); |
(...skipping 1660 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2685 m_scriptToProcessStartPosition = position; | 2672 m_scriptToProcessStartPosition = position; |
2686 | 2673 |
2687 setInsertionMode(TextMode); | 2674 setInsertionMode(TextMode); |
2688 } | 2675 } |
2689 | 2676 |
2690 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tree-construction
.html#tree-construction | 2677 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tree-construction
.html#tree-construction |
2691 bool HTMLTreeBuilder::shouldProcessTokenInForeignContent(AtomicHTMLToken* token) | 2678 bool HTMLTreeBuilder::shouldProcessTokenInForeignContent(AtomicHTMLToken* token) |
2692 { | 2679 { |
2693 if (m_tree.isEmpty()) | 2680 if (m_tree.isEmpty()) |
2694 return false; | 2681 return false; |
2695 RefPtr<HTMLStackItem> adjustedCurrentNode = adjustedCurrentStackItem(); | 2682 HTMLStackItem* item = m_tree.currentStackItem(); |
2696 | 2683 if (item->isInHTMLNamespace()) |
2697 if (adjustedCurrentNode->isInHTMLNamespace()) | |
2698 return false; | 2684 return false; |
2699 if (HTMLElementStack::isMathMLTextIntegrationPoint(adjustedCurrentNode.get()
)) { | 2685 if (HTMLElementStack::isMathMLTextIntegrationPoint(item)) { |
2700 if (token->type() == HTMLToken::StartTag | 2686 if (token->type() == HTMLToken::StartTag |
2701 && token->name() != MathMLNames::mglyphTag | 2687 && token->name() != MathMLNames::mglyphTag |
2702 && token->name() != MathMLNames::malignmarkTag) | 2688 && token->name() != MathMLNames::malignmarkTag) |
2703 return false; | 2689 return false; |
2704 if (token->type() == HTMLToken::Character) | 2690 if (token->type() == HTMLToken::Character) |
2705 return false; | 2691 return false; |
2706 } | 2692 } |
2707 if (adjustedCurrentNode->hasTagName(MathMLNames::annotation_xmlTag) | 2693 if (item->hasTagName(MathMLNames::annotation_xmlTag) |
2708 && token->type() == HTMLToken::StartTag | 2694 && token->type() == HTMLToken::StartTag |
2709 && token->name() == SVGNames::svgTag) | 2695 && token->name() == SVGNames::svgTag) |
2710 return false; | 2696 return false; |
2711 if (HTMLElementStack::isHTMLIntegrationPoint(adjustedCurrentNode.get())) { | 2697 if (HTMLElementStack::isHTMLIntegrationPoint(item)) { |
2712 if (token->type() == HTMLToken::StartTag) | 2698 if (token->type() == HTMLToken::StartTag) |
2713 return false; | 2699 return false; |
2714 if (token->type() == HTMLToken::Character) | 2700 if (token->type() == HTMLToken::Character) |
2715 return false; | 2701 return false; |
2716 } | 2702 } |
2717 if (token->type() == HTMLToken::EndOfFile) | 2703 if (token->type() == HTMLToken::EndOfFile) |
2718 return false; | 2704 return false; |
2719 return true; | 2705 return true; |
2720 } | 2706 } |
2721 | 2707 |
2722 void HTMLTreeBuilder::processTokenInForeignContent(AtomicHTMLToken* token) | 2708 void HTMLTreeBuilder::processTokenInForeignContent(AtomicHTMLToken* token) |
2723 { | 2709 { |
2724 if (token->type() == HTMLToken::Character) { | 2710 if (token->type() == HTMLToken::Character) { |
2725 const String& characters = token->characters(); | 2711 const String& characters = token->characters(); |
2726 m_tree.insertTextNode(characters); | 2712 m_tree.insertTextNode(characters); |
2727 if (m_framesetOk && !isAllWhitespaceOrReplacementCharacters(characters)) | 2713 if (m_framesetOk && !isAllWhitespaceOrReplacementCharacters(characters)) |
2728 m_framesetOk = false; | 2714 m_framesetOk = false; |
2729 return; | 2715 return; |
2730 } | 2716 } |
2731 | 2717 |
2732 m_tree.flush(); | 2718 m_tree.flush(); |
2733 RefPtr<HTMLStackItem> adjustedCurrentNode = adjustedCurrentStackItem(); | |
2734 | 2719 |
2735 switch (token->type()) { | 2720 switch (token->type()) { |
2736 case HTMLToken::Uninitialized: | 2721 case HTMLToken::Uninitialized: |
2737 ASSERT_NOT_REACHED(); | 2722 ASSERT_NOT_REACHED(); |
2738 break; | 2723 break; |
2739 case HTMLToken::DOCTYPE: | 2724 case HTMLToken::DOCTYPE: |
2740 parseError(token); | 2725 parseError(token); |
2741 break; | 2726 break; |
2742 case HTMLToken::StartTag: { | 2727 case HTMLToken::StartTag: { |
2743 if (token->name() == bTag | 2728 if (token->name() == bTag |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2778 || token->name() == ttTag | 2763 || token->name() == ttTag |
2779 || token->name() == uTag | 2764 || token->name() == uTag |
2780 || token->name() == ulTag | 2765 || token->name() == ulTag |
2781 || token->name() == varTag | 2766 || token->name() == varTag |
2782 || (token->name() == fontTag && (token->getAttributeItem(colorAttr)
|| token->getAttributeItem(faceAttr) || token->getAttributeItem(sizeAttr)))) { | 2767 || (token->name() == fontTag && (token->getAttributeItem(colorAttr)
|| token->getAttributeItem(faceAttr) || token->getAttributeItem(sizeAttr)))) { |
2783 parseError(token); | 2768 parseError(token); |
2784 m_tree.openElements()->popUntilForeignContentScopeMarker(); | 2769 m_tree.openElements()->popUntilForeignContentScopeMarker(); |
2785 processStartTag(token); | 2770 processStartTag(token); |
2786 return; | 2771 return; |
2787 } | 2772 } |
2788 const AtomicString& currentNamespace = adjustedCurrentNode->namespaceURI
(); | 2773 const AtomicString& currentNamespace = m_tree.currentStackItem()->namesp
aceURI(); |
2789 if (currentNamespace == MathMLNames::mathmlNamespaceURI) | 2774 if (currentNamespace == MathMLNames::mathmlNamespaceURI) |
2790 adjustMathMLAttributes(token); | 2775 adjustMathMLAttributes(token); |
2791 if (currentNamespace == SVGNames::svgNamespaceURI) { | 2776 if (currentNamespace == SVGNames::svgNamespaceURI) { |
2792 adjustSVGTagNameCase(token); | 2777 adjustSVGTagNameCase(token); |
2793 adjustSVGAttributes(token); | 2778 adjustSVGAttributes(token); |
2794 } | 2779 } |
2795 adjustForeignAttributes(token); | 2780 adjustForeignAttributes(token); |
2796 m_tree.insertForeignElement(token, currentNamespace); | 2781 m_tree.insertForeignElement(token, currentNamespace); |
2797 break; | 2782 break; |
2798 } | 2783 } |
2799 case HTMLToken::EndTag: { | 2784 case HTMLToken::EndTag: { |
2800 if (adjustedCurrentNode->namespaceURI() == SVGNames::svgNamespaceURI) | 2785 if (m_tree.currentStackItem()->namespaceURI() == SVGNames::svgNamespaceU
RI) |
2801 adjustSVGTagNameCase(token); | 2786 adjustSVGTagNameCase(token); |
2802 | 2787 |
2803 if (token->name() == SVGNames::scriptTag && m_tree.currentStackItem()->h
asTagName(SVGNames::scriptTag)) { | 2788 if (token->name() == SVGNames::scriptTag && m_tree.currentStackItem()->h
asTagName(SVGNames::scriptTag)) { |
2804 if (scriptingContentIsAllowed(m_tree.parserContentPolicy())) | 2789 if (scriptingContentIsAllowed(m_tree.parserContentPolicy())) |
2805 m_scriptToProcess = m_tree.currentElement(); | 2790 m_scriptToProcess = m_tree.currentElement(); |
2806 m_tree.openElements()->pop(); | 2791 m_tree.openElements()->pop(); |
2807 return; | 2792 return; |
2808 } | 2793 } |
2809 if (!m_tree.currentStackItem()->isInHTMLNamespace()) { | 2794 if (!m_tree.currentStackItem()->isInHTMLNamespace()) { |
2810 // FIXME: This code just wants an Element* iterator, instead of an E
lementRecord* | 2795 // FIXME: This code just wants an Element* iterator, instead of an E
lementRecord* |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2845 ASSERT(m_isAttached); | 2830 ASSERT(m_isAttached); |
2846 // Warning, this may detach the parser. Do not do anything else after this. | 2831 // Warning, this may detach the parser. Do not do anything else after this. |
2847 m_tree.finishedParsing(); | 2832 m_tree.finishedParsing(); |
2848 } | 2833 } |
2849 | 2834 |
2850 void HTMLTreeBuilder::parseError(AtomicHTMLToken*) | 2835 void HTMLTreeBuilder::parseError(AtomicHTMLToken*) |
2851 { | 2836 { |
2852 } | 2837 } |
2853 | 2838 |
2854 } // namespace WebCore | 2839 } // namespace WebCore |
OLD | NEW |