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 |