| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2010 Google, Inc. All Rights Reserved. | 2 * Copyright (C) 2010 Google, Inc. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 24 */ | 24 */ |
| 25 | 25 |
| 26 #include "config.h" | 26 #include "config.h" |
| 27 #include "core/html/parser/HTMLDocumentParser.h" | 27 #include "core/html/parser/HTMLDocumentParser.h" |
| 28 | 28 |
| 29 #include "base/bind.h" | 29 #include "base/bind.h" |
| 30 #include "core/HTMLNames.h" | 30 #include "core/HTMLNames.h" |
| 31 #include "core/css/MediaValuesCached.h" | 31 #include "core/css/MediaValuesCached.h" |
| 32 #include "core/dom/DocumentFragment.h" | |
| 33 #include "core/dom/Element.h" | 32 #include "core/dom/Element.h" |
| 34 #include "core/frame/LocalFrame.h" | 33 #include "core/frame/LocalFrame.h" |
| 35 #include "core/html/HTMLDocument.h" | 34 #include "core/html/HTMLDocument.h" |
| 36 #include "core/html/HTMLScriptElement.h" | 35 #include "core/html/HTMLScriptElement.h" |
| 37 #include "core/html/parser/AtomicHTMLToken.h" | 36 #include "core/html/parser/AtomicHTMLToken.h" |
| 38 #include "core/html/parser/BackgroundHTMLParser.h" | 37 #include "core/html/parser/BackgroundHTMLParser.h" |
| 39 #include "core/html/parser/HTMLParserScheduler.h" | 38 #include "core/html/parser/HTMLParserScheduler.h" |
| 40 #include "core/html/parser/HTMLParserThread.h" | 39 #include "core/html/parser/HTMLParserThread.h" |
| 41 #include "core/html/parser/HTMLTreeBuilder.h" | 40 #include "core/html/parser/HTMLTreeBuilder.h" |
| 42 #include "core/inspector/InspectorTraceEvents.h" | 41 #include "core/inspector/InspectorTraceEvents.h" |
| 43 #include "platform/SharedBuffer.h" | 42 #include "platform/SharedBuffer.h" |
| 44 #include "platform/TraceEvent.h" | 43 #include "platform/TraceEvent.h" |
| 45 #include "wtf/Functional.h" | 44 #include "wtf/Functional.h" |
| 46 | 45 |
| 47 namespace blink { | 46 namespace blink { |
| 48 | 47 |
| 49 // This is a direct transcription of step 4 from: | |
| 50 // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#frag
ment-case | |
| 51 static HTMLTokenizer::State tokenizerStateForContextElement(Element* contextElem
ent, bool reportErrors, const HTMLParserOptions& options) | |
| 52 { | |
| 53 if (!contextElement) | |
| 54 return HTMLTokenizer::DataState; | |
| 55 | |
| 56 const QualifiedName& contextTag = contextElement->tagQName(); | |
| 57 | |
| 58 if (contextTag == HTMLNames::styleTag) | |
| 59 return HTMLTokenizer::RAWTEXTState; | |
| 60 if (contextTag == HTMLNames::scriptTag) | |
| 61 return HTMLTokenizer::ScriptDataState; | |
| 62 return HTMLTokenizer::DataState; | |
| 63 } | |
| 64 | |
| 65 HTMLDocumentParser::HTMLDocumentParser(HTMLDocument& document, bool reportErrors
) | 48 HTMLDocumentParser::HTMLDocumentParser(HTMLDocument& document, bool reportErrors
) |
| 66 : DecodedDataDocumentParser(document) | 49 : DecodedDataDocumentParser(document) |
| 67 , m_options(&document) | 50 , m_options(&document) |
| 68 , m_token(m_options.useThreading ? nullptr : adoptPtr(new HTMLToken)) | 51 , m_token(m_options.useThreading ? nullptr : adoptPtr(new HTMLToken)) |
| 69 , m_tokenizer(m_options.useThreading ? nullptr : HTMLTokenizer::create(m_opt
ions)) | 52 , m_tokenizer(m_options.useThreading ? nullptr : HTMLTokenizer::create(m_opt
ions)) |
| 70 , m_treeBuilder(HTMLTreeBuilder::create(this, &document, reportErrors, m_opt
ions)) | 53 , m_treeBuilder(HTMLTreeBuilder::create(this, &document, reportErrors, m_opt
ions)) |
| 71 , m_parserScheduler(HTMLParserScheduler::create(this)) | 54 , m_parserScheduler(HTMLParserScheduler::create(this)) |
| 72 , m_weakFactory(this) | 55 , m_weakFactory(this) |
| 73 , m_isFragment(false) | 56 , m_isFragment(false) |
| 74 , m_endWasDelayed(false) | 57 , m_endWasDelayed(false) |
| 75 , m_haveBackgroundParser(false) | 58 , m_haveBackgroundParser(false) |
| 76 , m_pumpSessionNestingLevel(0) | 59 , m_pumpSessionNestingLevel(0) |
| 77 { | 60 { |
| 78 ASSERT(shouldUseThreading() || (m_token && m_tokenizer)); | 61 ASSERT(shouldUseThreading() || (m_token && m_tokenizer)); |
| 79 } | 62 } |
| 80 | 63 |
| 81 // FIXME: Member variables should be grouped into self-initializing structs to | |
| 82 // minimize code duplication between these constructors. | |
| 83 HTMLDocumentParser::HTMLDocumentParser(DocumentFragment* fragment, Element* cont
extElement) | |
| 84 : DecodedDataDocumentParser(fragment->document()) | |
| 85 , m_options(&fragment->document()) | |
| 86 , m_token(adoptPtr(new HTMLToken)) | |
| 87 , m_tokenizer(HTMLTokenizer::create(m_options)) | |
| 88 , m_treeBuilder(HTMLTreeBuilder::create(this, fragment, contextElement, m_op
tions)) | |
| 89 , m_weakFactory(this) | |
| 90 , m_isFragment(true) | |
| 91 , m_endWasDelayed(false) | |
| 92 , m_haveBackgroundParser(false) | |
| 93 , m_pumpSessionNestingLevel(0) | |
| 94 { | |
| 95 ASSERT(!shouldUseThreading()); | |
| 96 bool reportErrors = false; // For now document fragment parsing never report
s errors. | |
| 97 m_tokenizer->setState(tokenizerStateForContextElement(contextElement, report
Errors, m_options)); | |
| 98 } | |
| 99 | |
| 100 HTMLDocumentParser::~HTMLDocumentParser() | 64 HTMLDocumentParser::~HTMLDocumentParser() |
| 101 { | 65 { |
| 102 #if ENABLE(OILPAN) | 66 #if ENABLE(OILPAN) |
| 103 if (m_haveBackgroundParser) | 67 if (m_haveBackgroundParser) |
| 104 stopBackgroundParser(); | 68 stopBackgroundParser(); |
| 105 // In Oilpan, HTMLDocumentParser can die together with Document, and | 69 // In Oilpan, HTMLDocumentParser can die together with Document, and |
| 106 // detach() is not called in this case. | 70 // detach() is not called in this case. |
| 107 #else | 71 #else |
| 108 ASSERT(!m_parserScheduler); | 72 ASSERT(!m_parserScheduler); |
| 109 ASSERT(!m_pumpSessionNestingLevel); | 73 ASSERT(!m_pumpSessionNestingLevel); |
| (...skipping 585 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 695 void HTMLDocumentParser::executeScriptsWaitingForResources() | 659 void HTMLDocumentParser::executeScriptsWaitingForResources() |
| 696 { | 660 { |
| 697 if (!m_scriptRunner.hasPendingScripts()) | 661 if (!m_scriptRunner.hasPendingScripts()) |
| 698 return; | 662 return; |
| 699 RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this); | 663 RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this); |
| 700 m_scriptRunner.executePendingScripts(); | 664 m_scriptRunner.executePendingScripts(); |
| 701 if (!isWaitingForScripts()) | 665 if (!isWaitingForScripts()) |
| 702 resumeParsingAfterScriptExecution(); | 666 resumeParsingAfterScriptExecution(); |
| 703 } | 667 } |
| 704 | 668 |
| 705 void HTMLDocumentParser::parseDocumentFragment(const String& source, DocumentFra
gment* fragment, Element* contextElement) | |
| 706 { | |
| 707 RefPtrWillBeRawPtr<HTMLDocumentParser> parser = HTMLDocumentParser::create(f
ragment, contextElement); | |
| 708 parser->insert(source); // Use insert() so that the parser will not yield. | |
| 709 parser->finish(); | |
| 710 ASSERT(!parser->processingData()); // Make sure we're done. <rdar://problem/
3963151> | |
| 711 parser->detach(); // Allows ~DocumentParser to assert it was detached before
destruction. | |
| 712 } | |
| 713 | |
| 714 void HTMLDocumentParser::appendBytes(const char* data, size_t length) | 669 void HTMLDocumentParser::appendBytes(const char* data, size_t length) |
| 715 { | 670 { |
| 716 if (!length || isStopped()) | 671 if (!length || isStopped()) |
| 717 return; | 672 return; |
| 718 | 673 |
| 719 if (shouldUseThreading()) { | 674 if (shouldUseThreading()) { |
| 720 if (!m_haveBackgroundParser) | 675 if (!m_haveBackgroundParser) |
| 721 startBackgroundParser(); | 676 startBackgroundParser(); |
| 722 | 677 |
| 723 OwnPtr<Vector<char> > buffer = adoptPtr(new Vector<char>(length)); | 678 OwnPtr<Vector<char> > buffer = adoptPtr(new Vector<char>(length)); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 740 | 695 |
| 741 if (m_haveBackgroundParser) { | 696 if (m_haveBackgroundParser) { |
| 742 HTMLParserThread::taskRunner()->PostTask(FROM_HERE, | 697 HTMLParserThread::taskRunner()->PostTask(FROM_HERE, |
| 743 base::Bind(&BackgroundHTMLParser::flush, m_backgroundParser)); | 698 base::Bind(&BackgroundHTMLParser::flush, m_backgroundParser)); |
| 744 } else { | 699 } else { |
| 745 DecodedDataDocumentParser::flush(); | 700 DecodedDataDocumentParser::flush(); |
| 746 } | 701 } |
| 747 } | 702 } |
| 748 | 703 |
| 749 } | 704 } |
| OLD | NEW |