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 |