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 13 matching lines...) Expand all Loading... | |
24 */ | 24 */ |
25 | 25 |
26 #include "core/html/parser/HTMLDocumentParser.h" | 26 #include "core/html/parser/HTMLDocumentParser.h" |
27 | 27 |
28 #include "core/HTMLNames.h" | 28 #include "core/HTMLNames.h" |
29 #include "core/css/MediaValuesCached.h" | 29 #include "core/css/MediaValuesCached.h" |
30 #include "core/css/resolver/StyleResolver.h" | 30 #include "core/css/resolver/StyleResolver.h" |
31 #include "core/dom/DocumentFragment.h" | 31 #include "core/dom/DocumentFragment.h" |
32 #include "core/dom/DocumentLifecycleObserver.h" | 32 #include "core/dom/DocumentLifecycleObserver.h" |
33 #include "core/dom/Element.h" | 33 #include "core/dom/Element.h" |
34 #include "core/dom/StyleEngine.h" | |
34 #include "core/frame/LocalFrame.h" | 35 #include "core/frame/LocalFrame.h" |
35 #include "core/frame/Settings.h" | 36 #include "core/frame/Settings.h" |
36 #include "core/html/HTMLDocument.h" | 37 #include "core/html/HTMLDocument.h" |
37 #include "core/html/parser/AtomicHTMLToken.h" | 38 #include "core/html/parser/AtomicHTMLToken.h" |
38 #include "core/html/parser/BackgroundHTMLParser.h" | 39 #include "core/html/parser/BackgroundHTMLParser.h" |
39 #include "core/html/parser/HTMLParserScheduler.h" | 40 #include "core/html/parser/HTMLParserScheduler.h" |
40 #include "core/html/parser/HTMLParserThread.h" | 41 #include "core/html/parser/HTMLParserThread.h" |
41 #include "core/html/parser/HTMLScriptRunner.h" | 42 #include "core/html/parser/HTMLScriptRunner.h" |
42 #include "core/html/parser/HTMLTreeBuilder.h" | 43 #include "core/html/parser/HTMLTreeBuilder.h" |
43 #include "core/inspector/InspectorInstrumentation.h" | 44 #include "core/inspector/InspectorInstrumentation.h" |
44 #include "core/inspector/InspectorTraceEvents.h" | 45 #include "core/inspector/InspectorTraceEvents.h" |
45 #include "core/loader/DocumentLoader.h" | 46 #include "core/loader/DocumentLoader.h" |
46 #include "core/loader/NavigationScheduler.h" | 47 #include "core/loader/NavigationScheduler.h" |
48 #include "platform/RuntimeEnabledFeatures.h" | |
47 #include "platform/SharedBuffer.h" | 49 #include "platform/SharedBuffer.h" |
48 #include "platform/ThreadSafeFunctional.h" | 50 #include "platform/ThreadSafeFunctional.h" |
49 #include "platform/TraceEvent.h" | 51 #include "platform/TraceEvent.h" |
50 #include "platform/heap/Handle.h" | 52 #include "platform/heap/Handle.h" |
51 #include "public/platform/Platform.h" | 53 #include "public/platform/Platform.h" |
52 #include "public/platform/WebFrameScheduler.h" | 54 #include "public/platform/WebFrameScheduler.h" |
53 #include "public/platform/WebScheduler.h" | 55 #include "public/platform/WebScheduler.h" |
54 #include "public/platform/WebThread.h" | 56 #include "public/platform/WebThread.h" |
55 #include "wtf/RefCounted.h" | 57 #include "wtf/RefCounted.h" |
56 #include "wtf/TemporaryChange.h" | 58 #include "wtf/TemporaryChange.h" |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
259 return m_treeBuilder->isParsingFragment(); | 261 return m_treeBuilder->isParsingFragment(); |
260 } | 262 } |
261 | 263 |
262 bool HTMLDocumentParser::processingData() const | 264 bool HTMLDocumentParser::processingData() const |
263 { | 265 { |
264 return isScheduledForResume() || inPumpSession() || m_haveBackgroundParser; | 266 return isScheduledForResume() || inPumpSession() || m_haveBackgroundParser; |
265 } | 267 } |
266 | 268 |
267 void HTMLDocumentParser::pumpTokenizerIfPossible() | 269 void HTMLDocumentParser::pumpTokenizerIfPossible() |
268 { | 270 { |
269 if (isStopped() || isWaitingForScripts()) | 271 if (isStopped() || isWaitingForScripts() || isWaitingForStyles()) |
270 return; | 272 return; |
271 | 273 |
272 pumpTokenizer(); | 274 pumpTokenizer(); |
273 } | 275 } |
274 | 276 |
275 bool HTMLDocumentParser::isScheduledForResume() const | 277 bool HTMLDocumentParser::isScheduledForResume() const |
276 { | 278 { |
277 return m_parserScheduler && m_parserScheduler->isScheduledForResume(); | 279 return m_parserScheduler && m_parserScheduler->isScheduledForResume(); |
278 } | 280 } |
279 | 281 |
(...skipping 27 matching lines...) Expand all Loading... | |
307 | 309 |
308 if (isWaitingForScripts()) { | 310 if (isWaitingForScripts()) { |
309 // If we're paused waiting for a script, we try to execute scripts befor e continuing. | 311 // If we're paused waiting for a script, we try to execute scripts befor e continuing. |
310 runScriptsForPausedTreeBuilder(); | 312 runScriptsForPausedTreeBuilder(); |
311 if (isStopped()) | 313 if (isStopped()) |
312 return false; | 314 return false; |
313 if (isWaitingForScripts()) | 315 if (isWaitingForScripts()) |
314 return false; | 316 return false; |
315 } | 317 } |
316 | 318 |
319 if (isWaitingForStyles()) | |
320 return false; | |
321 | |
317 // FIXME: It's wrong for the HTMLDocumentParser to reach back to the | 322 // FIXME: It's wrong for the HTMLDocumentParser to reach back to the |
318 // LocalFrame, but this approach is how the old parser handled | 323 // LocalFrame, but this approach is how the old parser handled |
319 // stopping when the page assigns window.location. What really | 324 // stopping when the page assigns window.location. What really |
320 // should happen is that assigning window.location causes the | 325 // should happen is that assigning window.location causes the |
321 // parser to stop parsing cleanly. The problem is we're not | 326 // parser to stop parsing cleanly. The problem is we're not |
322 // perpared to do that at every point where we run JavaScript. | 327 // perpared to do that at every point where we run JavaScript. |
323 if (!isParsingFragment() | 328 if (!isParsingFragment() |
324 && document()->frame() && document()->frame()->navigationScheduler().loc ationChangePending()) | 329 && document()->frame() && document()->frame()->navigationScheduler().loc ationChangePending()) |
325 return false; | 330 return false; |
326 | 331 |
(...skipping 24 matching lines...) Expand all Loading... | |
351 // the document element is available, as we empty the queue immediately | 356 // the document element is available, as we empty the queue immediately |
352 // after the document element is created in pumpPendingSpeculations(). | 357 // after the document element is created in pumpPendingSpeculations(). |
353 ASSERT(m_queuedPreloads.isEmpty()); | 358 ASSERT(m_queuedPreloads.isEmpty()); |
354 for (auto& chunk : pendingChunks) | 359 for (auto& chunk : pendingChunks) |
355 m_preloader->takeAndPreload(chunk->preloads); | 360 m_preloader->takeAndPreload(chunk->preloads); |
356 } | 361 } |
357 | 362 |
358 for (auto& chunk : pendingChunks) | 363 for (auto& chunk : pendingChunks) |
359 m_speculations.append(chunk.release()); | 364 m_speculations.append(chunk.release()); |
360 | 365 |
361 if (!isWaitingForScripts() && !isScheduledForResume()) { | 366 if (!isWaitingForScripts() && !isWaitingForStyles() && !isScheduledForResume ()) { |
362 if (m_tasksWereSuspended) | 367 if (m_tasksWereSuspended) |
363 m_parserScheduler->forceResumeAfterYield(); | 368 m_parserScheduler->forceResumeAfterYield(); |
364 else | 369 else |
365 m_parserScheduler->scheduleForResume(); | 370 m_parserScheduler->scheduleForResume(); |
366 } | 371 } |
367 } | 372 } |
368 | 373 |
369 void HTMLDocumentParser::didReceiveEncodingDataFromBackgroundParser(const Docume ntEncodingData& data) | 374 void HTMLDocumentParser::didReceiveEncodingDataFromBackgroundParser(const Docume ntEncodingData& data) |
370 { | 375 { |
371 document()->setEncodingData(data); | 376 document()->setEncodingData(data); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
430 } | 435 } |
431 | 436 |
432 size_t HTMLDocumentParser::processParsedChunkFromBackgroundParser(PassOwnPtr<Par sedChunk> popChunk) | 437 size_t HTMLDocumentParser::processParsedChunkFromBackgroundParser(PassOwnPtr<Par sedChunk> popChunk) |
433 { | 438 { |
434 TRACE_EVENT0("blink", "HTMLDocumentParser::processParsedChunkFromBackgroundP arser"); | 439 TRACE_EVENT0("blink", "HTMLDocumentParser::processParsedChunkFromBackgroundP arser"); |
435 TemporaryChange<bool> hasLineNumber(m_isParsingAtLineNumber, true); | 440 TemporaryChange<bool> hasLineNumber(m_isParsingAtLineNumber, true); |
436 | 441 |
437 ASSERT_WITH_SECURITY_IMPLICATION(document()->activeParserCount() == 1); | 442 ASSERT_WITH_SECURITY_IMPLICATION(document()->activeParserCount() == 1); |
438 ASSERT(!isParsingFragment()); | 443 ASSERT(!isParsingFragment()); |
439 ASSERT(!isWaitingForScripts()); | 444 ASSERT(!isWaitingForScripts()); |
445 ASSERT(!isWaitingForStyles()); | |
440 ASSERT(!isStopped()); | 446 ASSERT(!isStopped()); |
441 #if !ENABLE(OILPAN) | 447 #if !ENABLE(OILPAN) |
442 // ASSERT that this object is both attached to the Document and protected. | 448 // ASSERT that this object is both attached to the Document and protected. |
443 ASSERT(refCount() >= 2); | 449 ASSERT(refCount() >= 2); |
444 #endif | 450 #endif |
445 ASSERT(shouldUseThreading()); | 451 ASSERT(shouldUseThreading()); |
446 ASSERT(!m_tokenizer); | 452 ASSERT(!m_tokenizer); |
447 ASSERT(!m_token); | 453 ASSERT(!m_token); |
448 ASSERT(!m_lastChunkBeforeScript); | 454 ASSERT(!m_lastChunkBeforeScript); |
449 | 455 |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
523 #if !ENABLE(OILPAN) | 529 #if !ENABLE(OILPAN) |
524 // ASSERT that this object is both attached to the Document and protected. | 530 // ASSERT that this object is both attached to the Document and protected. |
525 ASSERT(refCount() >= 2); | 531 ASSERT(refCount() >= 2); |
526 #endif | 532 #endif |
527 // If this assert fails, you need to call validateSpeculations to make sure | 533 // If this assert fails, you need to call validateSpeculations to make sure |
528 // m_tokenizer and m_token don't have state that invalidates m_speculations. | 534 // m_tokenizer and m_token don't have state that invalidates m_speculations. |
529 ASSERT(!m_tokenizer); | 535 ASSERT(!m_tokenizer); |
530 ASSERT(!m_token); | 536 ASSERT(!m_token); |
531 ASSERT(!m_lastChunkBeforeScript); | 537 ASSERT(!m_lastChunkBeforeScript); |
532 ASSERT(!isWaitingForScripts()); | 538 ASSERT(!isWaitingForScripts()); |
539 ASSERT(!isWaitingForStyles()); | |
533 ASSERT(!isStopped()); | 540 ASSERT(!isStopped()); |
534 ASSERT(!isScheduledForResume()); | 541 ASSERT(!isScheduledForResume()); |
535 ASSERT(!inPumpSession()); | 542 ASSERT(!inPumpSession()); |
536 | 543 |
537 // FIXME: Here should never be reached when there is a blocking script, | 544 // FIXME: Here should never be reached when there is a blocking script, |
538 // but it happens in unknown scenarios. See https://crbug.com/440901 | 545 // but it happens in unknown scenarios. See https://crbug.com/440901 |
539 if (isWaitingForScripts()) { | 546 if (isWaitingForScripts()) { |
540 m_parserScheduler->scheduleForResume(); | 547 m_parserScheduler->scheduleForResume(); |
541 return; | 548 return; |
542 } | 549 } |
(...skipping 10 matching lines...) Expand all Loading... | |
553 SpeculationsPumpSession session(m_pumpSpeculationsSessionNestingLevel, conte xtForParsingSession()); | 560 SpeculationsPumpSession session(m_pumpSpeculationsSessionNestingLevel, conte xtForParsingSession()); |
554 while (!m_speculations.isEmpty()) { | 561 while (!m_speculations.isEmpty()) { |
555 ASSERT(!isScheduledForResume()); | 562 ASSERT(!isScheduledForResume()); |
556 size_t elementTokenCount = processParsedChunkFromBackgroundParser(m_spec ulations.takeFirst().release()); | 563 size_t elementTokenCount = processParsedChunkFromBackgroundParser(m_spec ulations.takeFirst().release()); |
557 session.addedElementTokens(elementTokenCount); | 564 session.addedElementTokens(elementTokenCount); |
558 | 565 |
559 // Always check isParsing first as m_document may be null. | 566 // Always check isParsing first as m_document may be null. |
560 // Surprisingly, isScheduledForResume() may be set here as a result of | 567 // Surprisingly, isScheduledForResume() may be set here as a result of |
561 // processParsedChunkFromBackgroundParser running arbitrary javascript | 568 // processParsedChunkFromBackgroundParser running arbitrary javascript |
562 // which invokes nested event loops. (e.g. inspector breakpoints) | 569 // which invokes nested event loops. (e.g. inspector breakpoints) |
563 if (!isParsing() || isWaitingForScripts() || isScheduledForResume()) | 570 if (!isParsing() || isWaitingForScripts() || isWaitingForStyles() || isS cheduledForResume()) |
564 break; | 571 break; |
565 | 572 |
566 if (m_speculations.isEmpty() || m_parserScheduler->yieldIfNeeded(session , m_speculations.first()->startingScript)) | 573 if (m_speculations.isEmpty() || m_parserScheduler->yieldIfNeeded(session , m_speculations.first()->startingScript)) |
567 break; | 574 break; |
568 } | 575 } |
569 | 576 |
570 TRACE_EVENT_END1("devtools.timeline", "ParseHTML", "endData", InspectorParse HtmlEvent::endData(lineNumber().zeroBasedInt() - 1)); | 577 TRACE_EVENT_END1("devtools.timeline", "ParseHTML", "endData", InspectorParse HtmlEvent::endData(lineNumber().zeroBasedInt() - 1)); |
571 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "Update Counters", TRACE_EVENT_SCOPE_THREAD, "data", InspectorUpdateCountersEvent::data( )); | 578 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "Update Counters", TRACE_EVENT_SCOPE_THREAD, "data", InspectorUpdateCountersEvent::data( )); |
572 } | 579 } |
573 | 580 |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
642 #endif | 649 #endif |
643 | 650 |
644 if (isStopped()) | 651 if (isStopped()) |
645 return; | 652 return; |
646 | 653 |
647 // There should only be PendingText left since the tree-builder always flush es | 654 // There should only be PendingText left since the tree-builder always flush es |
648 // the task queue before returning. In case that ever changes, crash. | 655 // the task queue before returning. In case that ever changes, crash. |
649 m_treeBuilder->flush(FlushAlways); | 656 m_treeBuilder->flush(FlushAlways); |
650 RELEASE_ASSERT(!isStopped()); | 657 RELEASE_ASSERT(!isStopped()); |
651 | 658 |
652 if (isWaitingForScripts()) { | 659 if (isWaitingForScripts() || isWaitingForStyles()) { |
653 ASSERT(m_tokenizer->getState() == HTMLTokenizer::DataState); | 660 ASSERT(m_tokenizer->getState() == HTMLTokenizer::DataState); |
654 | 661 |
655 ASSERT(m_preloader); | 662 ASSERT(m_preloader); |
656 // TODO(kouhei): m_preloader should be always available for synchronous parsing case, | 663 // TODO(kouhei): m_preloader should be always available for synchronous parsing case, |
657 // adding paranoia if for speculative crash fix for crbug.com/465478 | 664 // adding paranoia if for speculative crash fix for crbug.com/465478 |
658 if (m_preloader) { | 665 if (m_preloader) { |
659 if (!m_preloadScanner) { | 666 if (!m_preloadScanner) { |
660 m_preloadScanner = HTMLPreloadScanner::create( | 667 m_preloadScanner = HTMLPreloadScanner::create( |
661 m_options, | 668 m_options, |
662 document()->url(), | 669 document()->url(), |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
732 ASSERT(m_haveBackgroundParser || wasCreatedByScript()); | 739 ASSERT(m_haveBackgroundParser || wasCreatedByScript()); |
733 m_token = adoptPtr(new HTMLToken); | 740 m_token = adoptPtr(new HTMLToken); |
734 m_tokenizer = HTMLTokenizer::create(m_options); | 741 m_tokenizer = HTMLTokenizer::create(m_options); |
735 } | 742 } |
736 | 743 |
737 SegmentedString excludedLineNumberSource(source); | 744 SegmentedString excludedLineNumberSource(source); |
738 excludedLineNumberSource.setExcludeLineNumbers(); | 745 excludedLineNumberSource.setExcludeLineNumbers(); |
739 m_input.insertAtCurrentInsertionPoint(excludedLineNumberSource); | 746 m_input.insertAtCurrentInsertionPoint(excludedLineNumberSource); |
740 pumpTokenizerIfPossible(); | 747 pumpTokenizerIfPossible(); |
741 | 748 |
742 if (isWaitingForScripts()) { | 749 if (isWaitingForScripts() || isWaitingForStyles()) { |
743 // Check the document.write() output with a separate preload scanner as | 750 // Check the document.write() output with a separate preload scanner as |
744 // the main scanner can't deal with insertions. | 751 // the main scanner can't deal with insertions. |
745 if (!m_insertionPreloadScanner) { | 752 if (!m_insertionPreloadScanner) { |
746 m_insertionPreloadScanner = HTMLPreloadScanner::create( | 753 m_insertionPreloadScanner = HTMLPreloadScanner::create( |
747 m_options, | 754 m_options, |
748 document()->url(), | 755 document()->url(), |
749 CachedDocumentParameters::create(document()), | 756 CachedDocumentParameters::create(document()), |
750 MediaValuesCached::MediaValuesCachedData(*document())); | 757 MediaValuesCached::MediaValuesCachedData(*document())); |
751 } | 758 } |
752 | 759 |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
817 // as appendBytes() will directly ship the data to the thread. | 824 // as appendBytes() will directly ship the data to the thread. |
818 ASSERT(!shouldUseThreading()); | 825 ASSERT(!shouldUseThreading()); |
819 | 826 |
820 // pumpTokenizer can cause this parser to be detached from the Document, | 827 // pumpTokenizer can cause this parser to be detached from the Document, |
821 // but we need to ensure it isn't deleted yet. | 828 // but we need to ensure it isn't deleted yet. |
822 RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this); | 829 RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this); |
823 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("blink.debug"), "HTMLDocumentParser:: append", "size", inputSource.length()); | 830 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("blink.debug"), "HTMLDocumentParser:: append", "size", inputSource.length()); |
824 const SegmentedString source(inputSource); | 831 const SegmentedString source(inputSource); |
825 | 832 |
826 if (m_preloadScanner) { | 833 if (m_preloadScanner) { |
827 if (m_input.current().isEmpty() && !isWaitingForScripts()) { | 834 if (m_input.current().isEmpty() && !isWaitingForScripts() && !isWaitingF orStyles()) { |
828 // We have parsed until the end of the current input and so are now moving ahead of the preload scanner. | 835 // We have parsed until the end of the current input and so are now moving ahead of the preload scanner. |
829 // Clear the scanner so we know to scan starting from the current in put point if we block again. | 836 // Clear the scanner so we know to scan starting from the current in put point if we block again. |
830 m_preloadScanner.clear(); | 837 m_preloadScanner.clear(); |
831 } else { | 838 } else { |
832 m_preloadScanner->appendToEnd(source); | 839 m_preloadScanner->appendToEnd(source); |
833 if (isWaitingForScripts()) | 840 if (isWaitingForScripts() || isWaitingForStyles()) |
834 m_preloadScanner->scan(m_preloader.get(), document()->baseElemen tURL()); | 841 m_preloadScanner->scan(m_preloader.get(), document()->baseElemen tURL()); |
835 } | 842 } |
836 } | 843 } |
837 | 844 |
838 m_input.appendToEnd(source); | 845 m_input.appendToEnd(source); |
839 | 846 |
840 if (inPumpSession()) { | 847 if (inPumpSession()) { |
841 // We've gotten data off the network in a nested write. | 848 // We've gotten data off the network in a nested write. |
842 // We don't want to consume any more of the input stream now. Do | 849 // We don't want to consume any more of the input stream now. Do |
843 // not worry. We'll consume this data in a less-nested write(). | 850 // not worry. We'll consume this data in a less-nested write(). |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
980 // run the preload scanner, as well as delay completion of parsing. | 987 // run the preload scanner, as well as delay completion of parsing. |
981 bool treeBuilderHasBlockingScript = m_treeBuilder->hasParserBlockingScript() ; | 988 bool treeBuilderHasBlockingScript = m_treeBuilder->hasParserBlockingScript() ; |
982 bool scriptRunnerHasBlockingScript = m_scriptRunner && m_scriptRunner->hasPa rserBlockingScript(); | 989 bool scriptRunnerHasBlockingScript = m_scriptRunner && m_scriptRunner->hasPa rserBlockingScript(); |
983 // Since the parser is paused while a script runner has a blocking script, i t should | 990 // Since the parser is paused while a script runner has a blocking script, i t should |
984 // never be possible to end up with both objects holding a blocking script. | 991 // never be possible to end up with both objects holding a blocking script. |
985 ASSERT(!(treeBuilderHasBlockingScript && scriptRunnerHasBlockingScript)); | 992 ASSERT(!(treeBuilderHasBlockingScript && scriptRunnerHasBlockingScript)); |
986 // If either object has a blocking script, the parser should be paused. | 993 // If either object has a blocking script, the parser should be paused. |
987 return treeBuilderHasBlockingScript || scriptRunnerHasBlockingScript; | 994 return treeBuilderHasBlockingScript || scriptRunnerHasBlockingScript; |
988 } | 995 } |
989 | 996 |
997 bool HTMLDocumentParser::isWaitingForStyles() const | |
998 { | |
999 return RuntimeEnabledFeatures::htmlParserBlocksOnCSSEnabled() && document()- >styleEngine().hasPendingSheets(); | |
esprehn
2016/03/07 21:35:50
you need to block on imports too, does this do tha
Pat Meenan
2016/03/07 21:49:53
No, thanks. The chunks are set up so imports will
| |
1000 } | |
1001 | |
990 void HTMLDocumentParser::resumeParsingAfterScriptExecution() | 1002 void HTMLDocumentParser::resumeParsingAfterScriptExecution() |
991 { | 1003 { |
992 ASSERT(!isExecutingScript()); | 1004 ASSERT(!isExecutingScript()); |
993 ASSERT(!isWaitingForScripts()); | 1005 ASSERT(!isWaitingForScripts()); |
994 | 1006 |
995 if (m_haveBackgroundParser) { | 1007 if (m_haveBackgroundParser) { |
996 validateSpeculations(m_lastChunkBeforeScript.release()); | 1008 validateSpeculations(m_lastChunkBeforeScript.release()); |
997 ASSERT(!m_lastChunkBeforeScript); | 1009 ASSERT(!m_lastChunkBeforeScript); |
998 // processParsedChunkFromBackgroundParser can cause this parser to be de tached from the Document, | 1010 // processParsedChunkFromBackgroundParser can cause this parser to be de tached from the Document, |
999 // but we need to ensure it isn't deleted yet. | 1011 // but we need to ensure it isn't deleted yet. |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1035 m_scriptRunner->executeScriptsWaitingForLoad(cachedResource); | 1047 m_scriptRunner->executeScriptsWaitingForLoad(cachedResource); |
1036 if (!isWaitingForScripts()) | 1048 if (!isWaitingForScripts()) |
1037 resumeParsingAfterScriptExecution(); | 1049 resumeParsingAfterScriptExecution(); |
1038 } | 1050 } |
1039 | 1051 |
1040 void HTMLDocumentParser::executeScriptsWaitingForResources() | 1052 void HTMLDocumentParser::executeScriptsWaitingForResources() |
1041 { | 1053 { |
1042 // Document only calls this when the Document owns the DocumentParser | 1054 // Document only calls this when the Document owns the DocumentParser |
1043 // so this will not be called in the DocumentFragment case. | 1055 // so this will not be called in the DocumentFragment case. |
1044 ASSERT(m_scriptRunner); | 1056 ASSERT(m_scriptRunner); |
1045 // Ignore calls unless we have a script blocking the parser waiting on a | |
1046 // stylesheet load. Otherwise we are currently parsing and this | |
1047 // is a re-entrant call from encountering a </ style> tag. | |
1048 if (!m_scriptRunner->hasScriptsWaitingForResources()) | |
1049 return; | |
1050 | 1057 |
1051 // pumpTokenizer can cause this parser to be detached from the Document, | 1058 if (m_scriptRunner->hasScriptsWaitingForResources()) { |
1052 // but we need to ensure it isn't deleted yet. | 1059 // pumpTokenizer can cause this parser to be detached from the Document, |
1053 RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this); | 1060 // but we need to ensure it isn't deleted yet. |
1054 m_scriptRunner->executeScriptsWaitingForResources(); | 1061 RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this); |
1055 if (!isWaitingForScripts()) | 1062 m_scriptRunner->executeScriptsWaitingForResources(); |
1056 resumeParsingAfterScriptExecution(); | 1063 if (!isWaitingForScripts()) |
1064 resumeParsingAfterScriptExecution(); | |
1065 } else if (RuntimeEnabledFeatures::htmlParserBlocksOnCSSEnabled() && !inPump Session() && !isScheduledForResume()) { | |
1066 m_parserScheduler->scheduleForResume(); | |
1067 } | |
1057 } | 1068 } |
1058 | 1069 |
1059 void HTMLDocumentParser::parseDocumentFragment(const String& source, DocumentFra gment* fragment, Element* contextElement, ParserContentPolicy parserContentPolic y) | 1070 void HTMLDocumentParser::parseDocumentFragment(const String& source, DocumentFra gment* fragment, Element* contextElement, ParserContentPolicy parserContentPolic y) |
1060 { | 1071 { |
1061 RefPtrWillBeRawPtr<HTMLDocumentParser> parser = HTMLDocumentParser::create(f ragment, contextElement, parserContentPolicy); | 1072 RefPtrWillBeRawPtr<HTMLDocumentParser> parser = HTMLDocumentParser::create(f ragment, contextElement, parserContentPolicy); |
1062 parser->append(source); | 1073 parser->append(source); |
1063 parser->finish(); | 1074 parser->finish(); |
1064 ASSERT(!parser->processingData()); // Make sure we're done. <rdar://problem/ 3963151> | 1075 ASSERT(!parser->processingData()); // Make sure we're done. <rdar://problem/ 3963151> |
1065 parser->detach(); // Allows ~DocumentParser to assert it was detached before destruction. | 1076 parser->detach(); // Allows ~DocumentParser to assert it was detached before destruction. |
1066 } | 1077 } |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1127 void HTMLDocumentParser::setDecoder(PassOwnPtr<TextResourceDecoder> decoder) | 1138 void HTMLDocumentParser::setDecoder(PassOwnPtr<TextResourceDecoder> decoder) |
1128 { | 1139 { |
1129 ASSERT(decoder); | 1140 ASSERT(decoder); |
1130 DecodedDataDocumentParser::setDecoder(decoder); | 1141 DecodedDataDocumentParser::setDecoder(decoder); |
1131 | 1142 |
1132 if (m_haveBackgroundParser) | 1143 if (m_haveBackgroundParser) |
1133 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParse r::setDecoder, AllowCrossThreadAccess(m_backgroundParser), takeDecoder())); | 1144 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParse r::setDecoder, AllowCrossThreadAccess(m_backgroundParser), takeDecoder())); |
1134 } | 1145 } |
1135 | 1146 |
1136 } // namespace blink | 1147 } // namespace blink |
OLD | NEW |