| 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 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 260 if (start == m_current) | 260 if (start == m_current) |
| 261 return String(); | 261 return String(); |
| 262 return String(m_characters->substring(start, m_current - start)); | 262 return String(m_characters->substring(start, m_current - start)); |
| 263 } | 263 } |
| 264 | 264 |
| 265 RefPtr<StringImpl> m_characters; | 265 RefPtr<StringImpl> m_characters; |
| 266 unsigned m_current; | 266 unsigned m_current; |
| 267 unsigned m_end; | 267 unsigned m_end; |
| 268 }; | 268 }; |
| 269 | 269 |
| 270 HTMLTreeBuilder::HTMLTreeBuilder(HTMLDocumentParser* parser, HTMLDocument* docum
ent, ParserContentPolicy parserContentPolicy, const HTMLParserOptions& options) | 270 HTMLTreeBuilder::HTMLTreeBuilder(HTMLDocumentParser* parser, Document& document,
ParserContentPolicy parserContentPolicy, const HTMLParserOptions& options) |
| 271 : m_framesetOk(true) | 271 : m_framesetOk(true) |
| 272 #if ENABLE(ASSERT) | 272 #if ENABLE(ASSERT) |
| 273 , m_isAttached(true) | 273 , m_isAttached(true) |
| 274 #endif | 274 #endif |
| 275 , m_tree(document, parserContentPolicy) | 275 , m_tree(document, parserContentPolicy) |
| 276 , m_insertionMode(InitialMode) | 276 , m_insertionMode(InitialMode) |
| 277 , m_originalInsertionMode(InitialMode) | 277 , m_originalInsertionMode(InitialMode) |
| 278 , m_shouldSkipLeadingNewline(false) | 278 , m_shouldSkipLeadingNewline(false) |
| 279 , m_parser(parser) | 279 , m_parser(parser) |
| 280 , m_scriptToProcessStartPosition(uninitializedPositionValue1()) | 280 , m_scriptToProcessStartPosition(uninitializedPositionValue1()) |
| 281 , m_options(options) | 281 , m_options(options) |
| 282 { | 282 { |
| 283 } | 283 } |
| 284 | 284 |
| 285 // FIXME: Member variables should be grouped into self-initializing structs to | |
| 286 // minimize code duplication between these constructors. | |
| 287 HTMLTreeBuilder::HTMLTreeBuilder(HTMLDocumentParser* parser, DocumentFragment* f
ragment, Element* contextElement, ParserContentPolicy parserContentPolicy, const
HTMLParserOptions& options) | 285 HTMLTreeBuilder::HTMLTreeBuilder(HTMLDocumentParser* parser, DocumentFragment* f
ragment, Element* contextElement, ParserContentPolicy parserContentPolicy, const
HTMLParserOptions& options) |
| 288 : m_framesetOk(true) | 286 : HTMLTreeBuilder(parser, fragment->document(), parserContentPolicy, options
) |
| 289 #if ENABLE(ASSERT) | |
| 290 , m_isAttached(true) | |
| 291 #endif | |
| 292 , m_fragmentContext(fragment, contextElement) | |
| 293 , m_tree(fragment, parserContentPolicy) | |
| 294 , m_insertionMode(InitialMode) | |
| 295 , m_originalInsertionMode(InitialMode) | |
| 296 , m_shouldSkipLeadingNewline(false) | |
| 297 , m_parser(parser) | |
| 298 , m_scriptToProcessStartPosition(uninitializedPositionValue1()) | |
| 299 , m_options(options) | |
| 300 { | 287 { |
| 301 ASSERT(isMainThread()); | 288 ASSERT(isMainThread()); |
| 302 ASSERT(contextElement); | 289 ASSERT(contextElement); |
| 290 m_tree.initFragmentParsing(fragment); |
| 291 m_fragmentContext.init(fragment, contextElement); |
| 303 | 292 |
| 304 // Steps 4.2-4.6 of the HTML5 Fragment Case parsing algorithm: | 293 // Steps 4.2-4.6 of the HTML5 Fragment Case parsing algorithm: |
| 305 // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#
fragment-case | 294 // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#
fragment-case |
| 306 // For efficiency, we skip step 4.2 ("Let root be a new html element with no
attributes") | 295 // For efficiency, we skip step 4.2 ("Let root be a new html element with no
attributes") |
| 307 // and instead use the DocumentFragment as a root node. | 296 // and instead use the DocumentFragment as a root node. |
| 308 m_tree.openElements()->pushRootNode(HTMLStackItem::create(fragment, HTMLStac
kItem::ItemForDocumentFragmentNode)); | 297 m_tree.openElements()->pushRootNode(HTMLStackItem::create(fragment, HTMLStac
kItem::ItemForDocumentFragmentNode)); |
| 309 | 298 |
| 310 if (isHTMLTemplateElement(*contextElement)) | 299 if (isHTMLTemplateElement(*contextElement)) |
| 311 m_templateInsertionModes.append(TemplateContentsMode); | 300 m_templateInsertionModes.append(TemplateContentsMode); |
| 312 | 301 |
| 313 resetInsertionModeAppropriately(); | 302 resetInsertionModeAppropriately(); |
| 314 m_tree.setForm(closestFormAncestor(*contextElement)); | 303 m_tree.setForm(closestFormAncestor(*contextElement)); |
| 315 } | 304 } |
| 316 | 305 |
| 317 HTMLTreeBuilder::~HTMLTreeBuilder() | 306 HTMLTreeBuilder::~HTMLTreeBuilder() |
| 318 { | 307 { |
| 319 } | 308 } |
| 320 | 309 |
| 310 void HTMLTreeBuilder::FragmentParsingContext::init(DocumentFragment* fragment, E
lement* contextElement) |
| 311 { |
| 312 DCHECK(fragment); |
| 313 DCHECK(!fragment->hasChildren()); |
| 314 m_fragment = fragment; |
| 315 m_contextElementStackItem = HTMLStackItem::create(contextElement, HTMLStackI
tem::ItemForContextElement); |
| 316 } |
| 317 |
| 318 DEFINE_TRACE(HTMLTreeBuilder::FragmentParsingContext) |
| 319 { |
| 320 visitor->trace(m_fragment); |
| 321 visitor->trace(m_contextElementStackItem); |
| 322 } |
| 323 |
| 321 DEFINE_TRACE(HTMLTreeBuilder) | 324 DEFINE_TRACE(HTMLTreeBuilder) |
| 322 { | 325 { |
| 323 visitor->trace(m_fragmentContext); | 326 visitor->trace(m_fragmentContext); |
| 324 visitor->trace(m_tree); | 327 visitor->trace(m_tree); |
| 325 visitor->trace(m_parser); | 328 visitor->trace(m_parser); |
| 326 visitor->trace(m_scriptToProcess); | 329 visitor->trace(m_scriptToProcess); |
| 327 } | 330 } |
| 328 | 331 |
| 329 void HTMLTreeBuilder::detach() | 332 void HTMLTreeBuilder::detach() |
| 330 { | 333 { |
| 331 #if ENABLE(ASSERT) | 334 #if ENABLE(ASSERT) |
| 332 // This call makes little sense in fragment mode, but for consistency | 335 // This call makes little sense in fragment mode, but for consistency |
| 333 // DocumentParser expects detach() to always be called before it's destroyed
. | 336 // DocumentParser expects detach() to always be called before it's destroyed
. |
| 334 m_isAttached = false; | 337 m_isAttached = false; |
| 335 #endif | 338 #endif |
| 336 // HTMLConstructionSite might be on the callstack when detach() is called | 339 // HTMLConstructionSite might be on the callstack when detach() is called |
| 337 // otherwise we'd just call m_tree.clear() here instead. | 340 // otherwise we'd just call m_tree.clear() here instead. |
| 338 m_tree.detach(); | 341 m_tree.detach(); |
| 339 } | 342 } |
| 340 | 343 |
| 341 HTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext() | |
| 342 : m_fragment(nullptr) | |
| 343 { | |
| 344 } | |
| 345 | |
| 346 HTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext(DocumentFragment
* fragment, Element* contextElement) | |
| 347 : m_fragment(fragment) | |
| 348 { | |
| 349 ASSERT(!fragment->hasChildren()); | |
| 350 m_contextElementStackItem = HTMLStackItem::create(contextElement, HTMLStackI
tem::ItemForContextElement); | |
| 351 } | |
| 352 | |
| 353 HTMLTreeBuilder::FragmentParsingContext::~FragmentParsingContext() | |
| 354 { | |
| 355 } | |
| 356 | |
| 357 DEFINE_TRACE(HTMLTreeBuilder::FragmentParsingContext) | |
| 358 { | |
| 359 visitor->trace(m_fragment); | |
| 360 visitor->trace(m_contextElementStackItem); | |
| 361 } | |
| 362 | |
| 363 Element* HTMLTreeBuilder::takeScriptToProcess(TextPosition& scriptStartPosition) | 344 Element* HTMLTreeBuilder::takeScriptToProcess(TextPosition& scriptStartPosition) |
| 364 { | 345 { |
| 365 ASSERT(m_scriptToProcess); | 346 ASSERT(m_scriptToProcess); |
| 366 ASSERT(!m_tree.hasPendingTasks()); | 347 ASSERT(!m_tree.hasPendingTasks()); |
| 367 // Unpause ourselves, callers may pause us again when processing the script. | 348 // Unpause ourselves, callers may pause us again when processing the script. |
| 368 // The HTML5 spec is written as though scripts are executed inside the tree | 349 // The HTML5 spec is written as though scripts are executed inside the tree |
| 369 // builder. We pause the parser to exit the tree builder, and then resume | 350 // builder. We pause the parser to exit the tree builder, and then resume |
| 370 // before running scripts. | 351 // before running scripts. |
| 371 scriptStartPosition = m_scriptToProcessStartPosition; | 352 scriptStartPosition = m_scriptToProcessStartPosition; |
| 372 m_scriptToProcessStartPosition = uninitializedPositionValue1(); | 353 m_scriptToProcessStartPosition = uninitializedPositionValue1(); |
| (...skipping 1755 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2128 m_parser->tokenizer()->setState(HTMLTokenizer::DataState); | 2109 m_parser->tokenizer()->setState(HTMLTokenizer::DataState); |
| 2129 } | 2110 } |
| 2130 return; | 2111 return; |
| 2131 } | 2112 } |
| 2132 m_tree.openElements()->pop(); | 2113 m_tree.openElements()->pop(); |
| 2133 setInsertionMode(m_originalInsertionMode); | 2114 setInsertionMode(m_originalInsertionMode); |
| 2134 break; | 2115 break; |
| 2135 case InFramesetMode: | 2116 case InFramesetMode: |
| 2136 ASSERT(getInsertionMode() == InFramesetMode); | 2117 ASSERT(getInsertionMode() == InFramesetMode); |
| 2137 if (token->name() == framesetTag) { | 2118 if (token->name() == framesetTag) { |
| 2138 bool ignoreFramesetForFragmentParsing = m_tree.currentIsRootNode(); | 2119 bool ignoreFramesetForFragmentParsing = m_tree.currentIsRootNode(); |
| 2139 ignoreFramesetForFragmentParsing = ignoreFramesetForFragmentParsing
|| m_tree.openElements()->hasTemplateInHTMLScope(); | 2120 ignoreFramesetForFragmentParsing = ignoreFramesetForFragmentParsing
|| m_tree.openElements()->hasTemplateInHTMLScope(); |
| 2140 if (ignoreFramesetForFragmentParsing) { | 2121 if (ignoreFramesetForFragmentParsing) { |
| 2141 ASSERT(isParsingFragmentOrTemplateContents()); | 2122 ASSERT(isParsingFragmentOrTemplateContents()); |
| 2142 parseError(token); | 2123 parseError(token); |
| 2143 return; | 2124 return; |
| 2144 } | 2125 } |
| 2145 m_tree.openElements()->pop(); | 2126 m_tree.openElements()->pop(); |
| 2146 if (!isParsingFragment() && !m_tree.currentStackItem()->hasTagName(f
ramesetTag)) | 2127 if (!isParsingFragment() && !m_tree.currentStackItem()->hasTagName(f
ramesetTag)) |
| 2147 setInsertionMode(AfterFramesetMode); | 2128 setInsertionMode(AfterFramesetMode); |
| 2148 return; | 2129 return; |
| (...skipping 671 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2820 ASSERT(m_isAttached); | 2801 ASSERT(m_isAttached); |
| 2821 // Warning, this may detach the parser. Do not do anything else after this. | 2802 // Warning, this may detach the parser. Do not do anything else after this. |
| 2822 m_tree.finishedParsing(); | 2803 m_tree.finishedParsing(); |
| 2823 } | 2804 } |
| 2824 | 2805 |
| 2825 void HTMLTreeBuilder::parseError(AtomicHTMLToken*) | 2806 void HTMLTreeBuilder::parseError(AtomicHTMLToken*) |
| 2826 { | 2807 { |
| 2827 } | 2808 } |
| 2828 | 2809 |
| 2829 } // namespace blink | 2810 } // namespace blink |
| OLD | NEW |