Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(131)

Unified Diff: third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp

Issue 1772853002: Block the HTML parser on external stylesheets (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp b/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp
index 0ed9b645e97913e65ae42861cfb2848a1a67024c..099c3fa1235415c7a63e185ede234b6ff0629141 100644
--- a/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp
+++ b/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp
@@ -31,6 +31,7 @@
#include "core/dom/DocumentFragment.h"
#include "core/dom/DocumentLifecycleObserver.h"
#include "core/dom/Element.h"
+#include "core/dom/StyleEngine.h"
#include "core/frame/LocalFrame.h"
#include "core/frame/Settings.h"
#include "core/html/HTMLDocument.h"
@@ -44,6 +45,7 @@
#include "core/inspector/InspectorTraceEvents.h"
#include "core/loader/DocumentLoader.h"
#include "core/loader/NavigationScheduler.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/SharedBuffer.h"
#include "platform/ThreadSafeFunctional.h"
#include "platform/TraceEvent.h"
@@ -266,7 +268,7 @@ bool HTMLDocumentParser::processingData() const
void HTMLDocumentParser::pumpTokenizerIfPossible()
{
- if (isStopped() || isWaitingForScripts())
+ if (isStopped() || isWaitingForScripts() || isWaitingForStyles())
return;
pumpTokenizer();
@@ -314,6 +316,9 @@ bool HTMLDocumentParser::canTakeNextToken()
return false;
}
+ if (isWaitingForStyles())
+ return false;
+
// FIXME: It's wrong for the HTMLDocumentParser to reach back to the
// LocalFrame, but this approach is how the old parser handled
// stopping when the page assigns window.location. What really
@@ -358,7 +363,7 @@ void HTMLDocumentParser::notifyPendingParsedChunks()
for (auto& chunk : pendingChunks)
m_speculations.append(chunk.release());
- if (!isWaitingForScripts() && !isScheduledForResume()) {
+ if (!isWaitingForScripts() && !isWaitingForStyles() && !isScheduledForResume()) {
if (m_tasksWereSuspended)
m_parserScheduler->forceResumeAfterYield();
else
@@ -437,6 +442,7 @@ size_t HTMLDocumentParser::processParsedChunkFromBackgroundParser(PassOwnPtr<Par
ASSERT_WITH_SECURITY_IMPLICATION(document()->activeParserCount() == 1);
ASSERT(!isParsingFragment());
ASSERT(!isWaitingForScripts());
+ ASSERT(!isWaitingForStyles());
ASSERT(!isStopped());
#if !ENABLE(OILPAN)
// ASSERT that this object is both attached to the Document and protected.
@@ -530,6 +536,7 @@ void HTMLDocumentParser::pumpPendingSpeculations()
ASSERT(!m_token);
ASSERT(!m_lastChunkBeforeScript);
ASSERT(!isWaitingForScripts());
+ ASSERT(!isWaitingForStyles());
ASSERT(!isStopped());
ASSERT(!isScheduledForResume());
ASSERT(!inPumpSession());
@@ -560,7 +567,7 @@ void HTMLDocumentParser::pumpPendingSpeculations()
// Surprisingly, isScheduledForResume() may be set here as a result of
// processParsedChunkFromBackgroundParser running arbitrary javascript
// which invokes nested event loops. (e.g. inspector breakpoints)
- if (!isParsing() || isWaitingForScripts() || isScheduledForResume())
+ if (!isParsing() || isWaitingForScripts() || isWaitingForStyles() || isScheduledForResume())
break;
if (m_speculations.isEmpty() || m_parserScheduler->yieldIfNeeded(session, m_speculations.first()->startingScript))
@@ -649,7 +656,7 @@ void HTMLDocumentParser::pumpTokenizer()
m_treeBuilder->flush(FlushAlways);
RELEASE_ASSERT(!isStopped());
- if (isWaitingForScripts()) {
+ if (isWaitingForScripts() || isWaitingForStyles()) {
ASSERT(m_tokenizer->getState() == HTMLTokenizer::DataState);
ASSERT(m_preloader);
@@ -739,7 +746,7 @@ void HTMLDocumentParser::insert(const SegmentedString& source)
m_input.insertAtCurrentInsertionPoint(excludedLineNumberSource);
pumpTokenizerIfPossible();
- if (isWaitingForScripts()) {
+ if (isWaitingForScripts() || isWaitingForStyles()) {
// Check the document.write() output with a separate preload scanner as
// the main scanner can't deal with insertions.
if (!m_insertionPreloadScanner) {
@@ -824,13 +831,13 @@ void HTMLDocumentParser::append(const String& inputSource)
const SegmentedString source(inputSource);
if (m_preloadScanner) {
- if (m_input.current().isEmpty() && !isWaitingForScripts()) {
+ if (m_input.current().isEmpty() && !isWaitingForScripts() && !isWaitingForStyles()) {
// We have parsed until the end of the current input and so are now moving ahead of the preload scanner.
// Clear the scanner so we know to scan starting from the current input point if we block again.
m_preloadScanner.clear();
} else {
m_preloadScanner->appendToEnd(source);
- if (isWaitingForScripts())
+ if (isWaitingForScripts() || isWaitingForStyles())
m_preloadScanner->scan(m_preloader.get(), document()->baseElementURL());
}
}
@@ -987,6 +994,11 @@ bool HTMLDocumentParser::isWaitingForScripts() const
return treeBuilderHasBlockingScript || scriptRunnerHasBlockingScript;
}
+bool HTMLDocumentParser::isWaitingForStyles() const
+{
+ 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
+}
+
void HTMLDocumentParser::resumeParsingAfterScriptExecution()
{
ASSERT(!isExecutingScript());
@@ -1042,18 +1054,17 @@ void HTMLDocumentParser::executeScriptsWaitingForResources()
// Document only calls this when the Document owns the DocumentParser
// so this will not be called in the DocumentFragment case.
ASSERT(m_scriptRunner);
- // Ignore calls unless we have a script blocking the parser waiting on a
- // stylesheet load. Otherwise we are currently parsing and this
- // is a re-entrant call from encountering a </ style> tag.
- if (!m_scriptRunner->hasScriptsWaitingForResources())
- return;
- // pumpTokenizer can cause this parser to be detached from the Document,
- // but we need to ensure it isn't deleted yet.
- RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this);
- m_scriptRunner->executeScriptsWaitingForResources();
- if (!isWaitingForScripts())
- resumeParsingAfterScriptExecution();
+ if (m_scriptRunner->hasScriptsWaitingForResources()) {
+ // pumpTokenizer can cause this parser to be detached from the Document,
+ // but we need to ensure it isn't deleted yet.
+ RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this);
+ m_scriptRunner->executeScriptsWaitingForResources();
+ if (!isWaitingForScripts())
+ resumeParsingAfterScriptExecution();
+ } else if (RuntimeEnabledFeatures::htmlParserBlocksOnCSSEnabled() && !inPumpSession() && !isScheduledForResume()) {
+ m_parserScheduler->scheduleForResume();
+ }
}
void HTMLDocumentParser::parseDocumentFragment(const String& source, DocumentFragment* fragment, Element* contextElement, ParserContentPolicy parserContentPolicy)

Powered by Google App Engine
This is Rietveld 408576698