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

Unified Diff: sky/engine/core/html/parser/HTMLDocumentParser.cpp

Issue 938623005: Allow multiple dart <script> tags in .sky files (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Update test results Created 5 years, 10 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
« no previous file with comments | « sky/engine/core/html/parser/HTMLDocumentParser.h ('k') | sky/engine/core/html/parser/HTMLScriptRunner.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sky/engine/core/html/parser/HTMLDocumentParser.cpp
diff --git a/sky/engine/core/html/parser/HTMLDocumentParser.cpp b/sky/engine/core/html/parser/HTMLDocumentParser.cpp
index 82db5d2e63cd55d8b52730f237230b7e6107648e..08087fcb885f615a81b516e92bc77d7ddff12cd4 100644
--- a/sky/engine/core/html/parser/HTMLDocumentParser.cpp
+++ b/sky/engine/core/html/parser/HTMLDocumentParser.cpp
@@ -159,7 +159,13 @@ void HTMLDocumentParser::runScriptsForPausedTreeBuilder()
return;
TextPosition scriptStartPosition = TextPosition::belowRangePosition();
RefPtr<Element> scriptToProcess = m_treeBuilder->takeScriptToProcess(scriptStartPosition);
- m_scriptRunner.runScript(toHTMLScriptElement(scriptToProcess.get()), scriptStartPosition);
+
+ // Sending the script to dart may find additional 'import' declarations
+ // which need to load before the script can execute. HTMLScriptRunner
+ // always calls scriptExecutionCompleted regardless of success/failure.
+ m_scriptRunner = HTMLScriptRunner::createForScript(
+ toHTMLScriptElement(scriptToProcess.get()), scriptStartPosition, this);
+ m_scriptRunner->start();
}
void HTMLDocumentParser::didReceiveParsedChunkFromBackgroundParser(PassOwnPtr<ParsedChunk> chunk)
@@ -168,7 +174,8 @@ void HTMLDocumentParser::didReceiveParsedChunkFromBackgroundParser(PassOwnPtr<Pa
// Sky should not need nested parsers.
ASSERT(document()->activeParserCount() == 0);
- if (isWaitingForScripts() || !m_pendingChunks.isEmpty() || document()->activeParserCount() > 0 || !document()->haveImportsLoaded()) {
+ if (isWaitingForScripts() || !m_pendingChunks.isEmpty() ||
+ document()->activeParserCount() > 0) {
m_pendingChunks.append(chunk);
return;
}
@@ -200,8 +207,12 @@ void HTMLDocumentParser::processParsedChunkFromBackgroundParser(PassOwnPtr<Parse
OwnPtr<ParsedChunk> chunk(popChunk);
OwnPtr<CompactHTMLTokenStream> tokens = chunk->tokens.release();
- for (Vector<CompactHTMLToken>::const_iterator it = tokens->begin(); it != tokens->end(); ++it) {
- ASSERT(!isWaitingForScripts());
+ Vector<CompactHTMLToken>::const_iterator it;
+ for (it = tokens->begin(); it != tokens->end(); ++it) {
+ // A chunk can issue import loads causing us to be isWaitingForScripts
+ // but we don't stop processing in that case.
+ ASSERT(!m_treeBuilder->hasParserBlockingScript());
+ ASSERT(!m_scriptRunner);
m_textPosition = it->textPosition();
@@ -210,20 +221,27 @@ void HTMLDocumentParser::processParsedChunkFromBackgroundParser(PassOwnPtr<Parse
if (isStopped())
break;
- if (isWaitingForScripts()) {
- ASSERT(it + 1 == tokens->end()); // The </script> is assumed to be the last token of this bunch.
+ if (m_treeBuilder->hasParserBlockingScript()) {
+ ++it; // Make it == end() during non-stopped termination.
+ ASSERT(it == tokens->end()); // The </script> is assumed to be the
+ // last token of this bunch.
runScriptsForPausedTreeBuilder();
break;
}
if (it->type() == HTMLToken::EndOfFile) {
- ASSERT(it + 1 == tokens->end()); // The EOF is assumed to be the last token of this bunch.
+ ++it; // Make it == end() during non-stopped termination.
+ ASSERT(it == tokens->end()); // The EOF is assumed to be the
+ // last token of this bunch.
ASSERT(m_pendingChunks.isEmpty()); // There should never be any chunks after the EOF.
prepareToStopParsing();
break;
}
}
+ // Either we aborted due to stopping or we processed all tokens.
+ ASSERT(isStopped() || it == tokens->end());
+
// Make sure any pending text nodes are emitted before returning.
if (!isStopped())
m_treeBuilder->flush();
@@ -238,7 +256,6 @@ void HTMLDocumentParser::pumpPendingChunks()
ASSERT(refCount() >= 2);
ASSERT(!isWaitingForScripts());
ASSERT(!isStopped());
- ASSERT(document()->haveImportsLoaded());
double startTime = currentTime();
@@ -246,7 +263,7 @@ void HTMLDocumentParser::pumpPendingChunks()
processParsedChunkFromBackgroundParser(m_pendingChunks.takeFirst());
// Always check isStopped first as m_document may be null.
- if (isStopped() || isWaitingForScripts() || !document()->haveImportsLoaded())
+ if (isStopped() || isWaitingForScripts())
break;
if (currentTime() - startTime > parserTimeLimit && !m_pendingChunks.isEmpty()) {
@@ -353,7 +370,8 @@ void HTMLDocumentParser::endIfDelayed()
bool HTMLDocumentParser::isExecutingScript() const
{
- return m_scriptRunner.isExecutingScript();
+ // TODO(eseidel): Callers may need updates now that scripts can be async.
+ return m_scriptRunner && m_scriptRunner->isExecutingScript();
}
OrdinalNumber HTMLDocumentParser::lineNumber() const
@@ -370,13 +388,13 @@ TextPosition HTMLDocumentParser::textPosition() const
bool HTMLDocumentParser::isWaitingForScripts() const
{
- return m_treeBuilder->hasParserBlockingScript();
+ return m_treeBuilder->hasParserBlockingScript() || m_scriptRunner ||
+ !document()->haveImportsLoaded();
}
void HTMLDocumentParser::resumeAfterWaitingForImports()
{
RefPtr<HTMLDocumentParser> protect(this);
- ASSERT(!isExecutingScript());
ASSERT(!isWaitingForScripts());
if (m_pendingChunks.isEmpty())
return;
@@ -384,4 +402,14 @@ void HTMLDocumentParser::resumeAfterWaitingForImports()
pumpPendingChunks();
}
+// HTMLScriptRunner has finished executing a script.
+// Just call resumeAfterWaitingForImports since it happens to do what we need.
+void HTMLDocumentParser::scriptExecutionCompleted() {
+ ASSERT(m_scriptRunner);
+ m_scriptRunner.clear();
+ // To avoid re-entering the parser for synchronous scripts, we use a postTask.
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE, base::Bind(&HTMLDocumentParser::resumeAfterWaitingForImports,
+ m_weakFactory.GetWeakPtr()));
+}
}
« no previous file with comments | « sky/engine/core/html/parser/HTMLDocumentParser.h ('k') | sky/engine/core/html/parser/HTMLScriptRunner.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698