| 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, 2014 Apple Inc. All rights reserved. | 3 * Copyright (C) 2011, 2014 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 17 matching lines...) Expand all Loading... |
| 28 #include "core/html/parser/HTMLTreeBuilder.h" | 28 #include "core/html/parser/HTMLTreeBuilder.h" |
| 29 | 29 |
| 30 #include "bindings/core/v8/ExceptionStatePlaceholder.h" | 30 #include "bindings/core/v8/ExceptionStatePlaceholder.h" |
| 31 #include "core/HTMLNames.h" | 31 #include "core/HTMLNames.h" |
| 32 #include "core/dom/DocumentFragment.h" | 32 #include "core/dom/DocumentFragment.h" |
| 33 #include "core/html/HTMLDocument.h" | 33 #include "core/html/HTMLDocument.h" |
| 34 #include "core/html/HTMLTemplateElement.h" | 34 #include "core/html/HTMLTemplateElement.h" |
| 35 #include "core/html/parser/AtomicHTMLToken.h" | 35 #include "core/html/parser/AtomicHTMLToken.h" |
| 36 #include "core/html/parser/HTMLDocumentParser.h" | 36 #include "core/html/parser/HTMLDocumentParser.h" |
| 37 #include "core/html/parser/HTMLParserIdioms.h" | 37 #include "core/html/parser/HTMLParserIdioms.h" |
| 38 #include "core/html/parser/HTMLStackItem.h" | |
| 39 #include "core/html/parser/HTMLToken.h" | 38 #include "core/html/parser/HTMLToken.h" |
| 40 #include "core/html/parser/HTMLTokenizer.h" | 39 #include "core/html/parser/HTMLTokenizer.h" |
| 41 | 40 |
| 42 namespace blink { | 41 namespace blink { |
| 43 | 42 |
| 44 static TextPosition uninitializedPositionValue1() | 43 static TextPosition uninitializedPositionValue1() |
| 45 { | 44 { |
| 46 return TextPosition(OrdinalNumber::fromOneBasedInt(-1), OrdinalNumber::first
()); | 45 return TextPosition(OrdinalNumber::fromOneBasedInt(-1), OrdinalNumber::first
()); |
| 47 } | 46 } |
| 48 | 47 |
| 49 HTMLTreeBuilder::HTMLTreeBuilder(HTMLDocumentParser* parser, HTMLDocument* docum
ent, ParserContentPolicy parserContentPolicy, bool, const HTMLParserOptions& opt
ions) | 48 HTMLTreeBuilder::HTMLTreeBuilder(HTMLDocumentParser* parser, HTMLDocument* docum
ent, ParserContentPolicy parserContentPolicy, bool, const HTMLParserOptions& opt
ions) |
| 50 : | 49 : |
| 51 #if ENABLE(ASSERT) | 50 #if ENABLE(ASSERT) |
| 52 m_isAttached(true), | 51 m_isAttached(true), |
| 53 #endif | 52 #endif |
| 54 m_tree(document, parserContentPolicy) | 53 m_tree(document, parserContentPolicy) |
| 55 , m_insertionMode(HTMLMode) | 54 , m_insertionMode(HTMLMode) |
| 56 , m_originalInsertionMode(HTMLMode) | 55 , m_originalInsertionMode(HTMLMode) |
| 57 , m_parser(parser) | 56 , m_parser(parser) |
| 58 , m_scriptToProcessStartPosition(uninitializedPositionValue1()) | 57 , m_scriptToProcessStartPosition(uninitializedPositionValue1()) |
| 59 , m_options(options) | 58 , m_options(options) |
| 60 { | 59 { |
| 61 m_tree.openElements()->pushRootNode(HTMLStackItem::create(document, HTMLStac
kItem::ItemForContextElement)); | 60 m_tree.openElements()->pushRootNode(document); |
| 62 } | 61 } |
| 63 | 62 |
| 64 // FIXME: Member variables should be grouped into self-initializing structs to | 63 // FIXME: Member variables should be grouped into self-initializing structs to |
| 65 // minimize code duplication between these constructors. | 64 // minimize code duplication between these constructors. |
| 66 HTMLTreeBuilder::HTMLTreeBuilder(HTMLDocumentParser* parser, DocumentFragment* f
ragment, Element* contextElement, ParserContentPolicy parserContentPolicy, const
HTMLParserOptions& options) | 65 HTMLTreeBuilder::HTMLTreeBuilder(HTMLDocumentParser* parser, DocumentFragment* f
ragment, Element* contextElement, ParserContentPolicy parserContentPolicy, const
HTMLParserOptions& options) |
| 67 : | 66 : |
| 68 #if ENABLE(ASSERT) | 67 #if ENABLE(ASSERT) |
| 69 m_isAttached(true), | 68 m_isAttached(true), |
| 70 #endif | 69 #endif |
| 71 m_fragmentContext(fragment, contextElement) | 70 m_fragmentContext(fragment, contextElement) |
| 72 , m_tree(fragment, parserContentPolicy) | 71 , m_tree(fragment, parserContentPolicy) |
| 73 , m_insertionMode(HTMLMode) | 72 , m_insertionMode(HTMLMode) |
| 74 , m_originalInsertionMode(HTMLMode) | 73 , m_originalInsertionMode(HTMLMode) |
| 75 , m_parser(parser) | 74 , m_parser(parser) |
| 76 , m_scriptToProcessStartPosition(uninitializedPositionValue1()) | 75 , m_scriptToProcessStartPosition(uninitializedPositionValue1()) |
| 77 , m_options(options) | 76 , m_options(options) |
| 78 { | 77 { |
| 79 ASSERT(isMainThread()); | 78 ASSERT(isMainThread()); |
| 80 ASSERT(contextElement); | 79 ASSERT(contextElement); |
| 81 | 80 |
| 82 // Steps 4.2-4.6 of the HTML5 Fragment Case parsing algorithm: | 81 // Steps 4.2-4.6 of the HTML5 Fragment Case parsing algorithm: |
| 83 // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#
fragment-case | 82 // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#
fragment-case |
| 84 // For efficiency, we skip step 4.2 ("Let root be a new html element with no
attributes") | 83 // For efficiency, we skip step 4.2 ("Let root be a new html element with no
attributes") |
| 85 // and instead use the DocumentFragment as a root node. | 84 // and instead use the DocumentFragment as a root node. |
| 86 m_tree.openElements()->pushRootNode(HTMLStackItem::create(fragment, HTMLStac
kItem::ItemForDocumentFragmentNode)); | 85 m_tree.openElements()->pushRootNode(fragment); |
| 87 } | 86 } |
| 88 | 87 |
| 89 HTMLTreeBuilder::~HTMLTreeBuilder() | 88 HTMLTreeBuilder::~HTMLTreeBuilder() |
| 90 { | 89 { |
| 91 } | 90 } |
| 92 | 91 |
| 93 void HTMLTreeBuilder::trace(Visitor* visitor) | 92 void HTMLTreeBuilder::trace(Visitor* visitor) |
| 94 { | 93 { |
| 95 visitor->trace(m_fragmentContext); | 94 visitor->trace(m_fragmentContext); |
| 96 visitor->trace(m_tree); | 95 visitor->trace(m_tree); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 112 | 111 |
| 113 HTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext() | 112 HTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext() |
| 114 : m_fragment(nullptr) | 113 : m_fragment(nullptr) |
| 115 { | 114 { |
| 116 } | 115 } |
| 117 | 116 |
| 118 HTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext(DocumentFragment
* fragment, Element* contextElement) | 117 HTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext(DocumentFragment
* fragment, Element* contextElement) |
| 119 : m_fragment(fragment) | 118 : m_fragment(fragment) |
| 120 { | 119 { |
| 121 ASSERT(!fragment->hasChildren()); | 120 ASSERT(!fragment->hasChildren()); |
| 122 m_contextElementStackItem = HTMLStackItem::create(contextElement, HTMLStackI
tem::ItemForContextElement); | |
| 123 } | 121 } |
| 124 | 122 |
| 125 HTMLTreeBuilder::FragmentParsingContext::~FragmentParsingContext() | 123 HTMLTreeBuilder::FragmentParsingContext::~FragmentParsingContext() |
| 126 { | 124 { |
| 127 } | 125 } |
| 128 | 126 |
| 129 void HTMLTreeBuilder::FragmentParsingContext::trace(Visitor* visitor) | 127 void HTMLTreeBuilder::FragmentParsingContext::trace(Visitor* visitor) |
| 130 { | 128 { |
| 131 visitor->trace(m_fragment); | 129 visitor->trace(m_fragment); |
| 132 visitor->trace(m_contextElementStackItem); | |
| 133 } | 130 } |
| 134 | 131 |
| 135 PassRefPtrWillBeRawPtr<Element> HTMLTreeBuilder::takeScriptToProcess(TextPositio
n& scriptStartPosition) | 132 PassRefPtrWillBeRawPtr<Element> HTMLTreeBuilder::takeScriptToProcess(TextPositio
n& scriptStartPosition) |
| 136 { | 133 { |
| 137 ASSERT(m_scriptToProcess); | 134 ASSERT(m_scriptToProcess); |
| 138 ASSERT(!m_tree.hasPendingTasks()); | 135 ASSERT(!m_tree.hasPendingTasks()); |
| 139 // Unpause ourselves, callers may pause us again when processing the script. | 136 // Unpause ourselves, callers may pause us again when processing the script. |
| 140 // The HTML5 spec is written as though scripts are executed inside the tree | 137 // The HTML5 spec is written as though scripts are executed inside the tree |
| 141 // builder. We pause the parser to exit the tree builder, and then resume | 138 // builder. We pause the parser to exit the tree builder, and then resume |
| 142 // before running scripts. | 139 // before running scripts. |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 190 } | 187 } |
| 191 | 188 |
| 192 void HTMLTreeBuilder::processEndTag(AtomicHTMLToken* token) | 189 void HTMLTreeBuilder::processEndTag(AtomicHTMLToken* token) |
| 193 { | 190 { |
| 194 ASSERT(token->type() == HTMLToken::EndTag); | 191 ASSERT(token->type() == HTMLToken::EndTag); |
| 195 | 192 |
| 196 const InsertionMode mode = insertionMode(); | 193 const InsertionMode mode = insertionMode(); |
| 197 if (mode == HTMLMode) { | 194 if (mode == HTMLMode) { |
| 198 HTMLElementStack::ElementRecord* record = m_tree.openElements()->topReco
rd(); | 195 HTMLElementStack::ElementRecord* record = m_tree.openElements()->topReco
rd(); |
| 199 while (record->next()) { | 196 while (record->next()) { |
| 200 RefPtrWillBeRawPtr<HTMLStackItem> item = record->stackItem(); | 197 RefPtrWillBeRawPtr<Element> element = record->element(); |
| 201 if (item->hasLocalName(token->name())) { | 198 if (element->hasLocalName(token->name())) { |
| 202 m_tree.openElements()->popUntilPopped(item->element()); | 199 m_tree.openElements()->popUntilPopped(element.get()); |
| 203 ASSERT(m_tree.openElements()->topNode()); | 200 ASSERT(m_tree.openElements()->topNode()); |
| 204 return; | 201 return; |
| 205 } | 202 } |
| 206 record = record->next(); | 203 record = record->next(); |
| 207 } | 204 } |
| 208 return; | 205 return; |
| 209 } | 206 } |
| 210 | 207 |
| 211 ASSERT(mode == TextMode); | 208 ASSERT(mode == TextMode); |
| 212 if (token->name() == HTMLNames::scriptTag) { | 209 if (token->name() == HTMLNames::scriptTag) { |
| 213 // Pause ourselves so that parsing stops until the script can be process
ed by the caller. | 210 // Pause ourselves so that parsing stops until the script can be process
ed by the caller. |
| 214 ASSERT(m_tree.currentStackItem()->hasLocalName(HTMLNames::scriptTag.loca
lName())); | 211 ASSERT(m_tree.currentElement()->hasLocalName(HTMLNames::scriptTag.localN
ame())); |
| 215 if (scriptingContentIsAllowed(m_tree.parserContentPolicy())) | 212 if (scriptingContentIsAllowed(m_tree.parserContentPolicy())) |
| 216 m_scriptToProcess = m_tree.currentElement(); | 213 m_scriptToProcess = m_tree.currentElement(); |
| 217 m_tree.openElements()->pop(); | 214 m_tree.openElements()->pop(); |
| 218 setInsertionMode(m_originalInsertionMode); | 215 setInsertionMode(m_originalInsertionMode); |
| 219 | 216 |
| 220 if (m_parser->tokenizer()) { | 217 if (m_parser->tokenizer()) { |
| 221 // We must set the tokenizer's state to | 218 // We must set the tokenizer's state to |
| 222 // DataState explicitly if the tokenizer didn't have a chance to. | 219 // DataState explicitly if the tokenizer didn't have a chance to. |
| 223 ASSERT(m_parser->tokenizer()->state() == HTMLTokenizer::DataState ||
m_options.useThreading); | 220 ASSERT(m_parser->tokenizer()->state() == HTMLTokenizer::DataState ||
m_options.useThreading); |
| 224 m_parser->tokenizer()->setState(HTMLTokenizer::DataState); | 221 m_parser->tokenizer()->setState(HTMLTokenizer::DataState); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 266 void HTMLTreeBuilder::finished() | 263 void HTMLTreeBuilder::finished() |
| 267 { | 264 { |
| 268 if (isParsingFragment()) | 265 if (isParsingFragment()) |
| 269 return; | 266 return; |
| 270 ASSERT(m_isAttached); | 267 ASSERT(m_isAttached); |
| 271 // Warning, this may detach the parser. Do not do anything else after this. | 268 // Warning, this may detach the parser. Do not do anything else after this. |
| 272 m_tree.finishedParsing(); | 269 m_tree.finishedParsing(); |
| 273 } | 270 } |
| 274 | 271 |
| 275 } // namespace blink | 272 } // namespace blink |
| OLD | NEW |