Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(329)

Side by Side Diff: Source/core/html/parser/HTMLTreeBuilder.cpp

Issue 68893014: Allocate stack item for fragment context elements once (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Allocate stack item in fragment constructor Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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)
eseidel 2013/11/14 15:39:41 Oh, I love it.
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
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().get();
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
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
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
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
OLDNEW
« Source/core/html/parser/HTMLTreeBuilder.h ('K') | « Source/core/html/parser/HTMLTreeBuilder.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698