Chromium Code Reviews| Index: sky/engine/core/html/parser/HTMLScriptRunner.cpp |
| diff --git a/sky/engine/core/html/parser/HTMLScriptRunner.cpp b/sky/engine/core/html/parser/HTMLScriptRunner.cpp |
| index b79a9008b631de3bb91d0840e9eab2d2ac97027f..e0bab6300dbe993013f914b7da15ae6703902889 100644 |
| --- a/sky/engine/core/html/parser/HTMLScriptRunner.cpp |
| +++ b/sky/engine/core/html/parser/HTMLScriptRunner.cpp |
| @@ -5,6 +5,7 @@ |
| #include "sky/engine/config.h" |
| #include "sky/engine/core/html/parser/HTMLScriptRunner.h" |
| +#include "base/bind.h" |
| #include "sky/engine/core/app/AbstractModule.h" |
| #include "sky/engine/core/dom/Document.h" |
| #include "sky/engine/core/dom/Microtask.h" |
| @@ -14,36 +15,111 @@ |
| namespace blink { |
| -HTMLScriptRunner::HTMLScriptRunner() |
| - : m_isExecutingScript(false) |
| -{ |
| +PassOwnPtr<HTMLScriptRunner> HTMLScriptRunner::createForScript( |
| + PassRefPtr<HTMLScriptElement> element, |
| + TextPosition position, |
| + HTMLScriptRunnerHost* host) { |
| + return adoptPtr(new HTMLScriptRunner(element, position, host)); |
| +} |
| + |
| +HTMLScriptRunner::HTMLScriptRunner(PassRefPtr<HTMLScriptElement> element, |
| + TextPosition position, |
| + HTMLScriptRunnerHost* host) |
| + : m_host(host), |
| + m_element(element), |
| + m_position(position), |
| + m_state(StateInitial), |
| + m_weakFactory(this) { |
| } |
| HTMLScriptRunner::~HTMLScriptRunner() |
| { |
| + // If we hit this ASSERT we failed to notify the ScriptRunnerHost! |
| + ASSERT(m_state == StateCompleted); |
| } |
| -void HTMLScriptRunner::runScript(PassRefPtr<HTMLScriptElement> element, TextPosition textPosition) |
| -{ |
| - ASSERT(element->document().haveImportsLoaded()); |
| - Microtask::performCheckpoint(); |
| +bool HTMLScriptRunner::isExecutingScript() const { |
| + return m_state == StateExecuting; |
| +} |
| - Document& sourceDocument = element->document(); |
| - String source = element->textContent(); |
| +void HTMLScriptRunner::advanceTo(State state, AdvanceType advanceType) { |
| + if (advanceType == ExecutionNormal) { |
| + switch (m_state) { |
| + case StateInitial: |
| + ASSERT(state == StateLoading); |
| + break; |
| + case StateLoading: |
| + ASSERT(state == StateExecuting); |
| + break; |
| + case StateExecuting: |
| + ASSERT(state == StateCompleted); |
| + break; |
| + case StateCompleted: |
| + ASSERT_NOT_REACHED(); |
| + } |
| + } |
| + m_state = state; |
| - RefPtr<Document> contextDocument = sourceDocument.contextDocument().get(); |
| + if (m_state == StateCompleted) |
| + m_host->scriptExecutionCompleted(); |
| + // We may be deleted by scriptExecutionCompleted(). |
| +} |
| + |
| +static LocalFrame* contextFrame(Element* element) { |
| + Document* contextDocument = element->document().contextDocument().get(); |
| if (!contextDocument) |
| - return; |
| + return nullptr; |
| LocalFrame* frame = contextDocument->frame(); |
| if (!frame) |
| - return; |
| + return nullptr; |
| + return frame; |
| +} |
| + |
| +void HTMLScriptRunner::scriptFailed() { |
| + advanceTo(StateCompleted, ExecutionFailure); |
| +} |
| - ASSERT(!m_isExecutingScript); |
| - TemporaryChange<bool> executingScript(m_isExecutingScript, true); |
| +void HTMLScriptRunner::start() { |
| + ASSERT(m_state == StateInitial); |
| + ASSERT(m_element->document().haveImportsLoaded()); |
| + |
| + Document& sourceDocument = m_element->document(); |
| + String source = m_element->textContent(); |
| + |
| + LocalFrame* frame = contextFrame(m_element.get()); |
| + if (!frame) |
| + return scriptFailed(); |
| + |
| + advanceTo(StateLoading); |
| ASSERT(sourceDocument.module()); |
| - frame->dart().LoadModule(sourceDocument.module(), source, textPosition); |
| + DartController::LoadFinishedCallback loadFinished = base::Bind( |
| + &HTMLScriptRunner::executeLibrary, m_weakFactory.GetWeakPtr()); |
| + frame->dart().LoadScriptInModule(sourceDocument.module(), source, |
| + m_position, loadFinished); |
|
abarth-chromium
2015/02/19 02:51:40
Normally we'd combine these two lines into one.
|
| +} |
| + |
| +// Enforce that the caller holds refs using RefPtr. |
| +// FIXME: Neither of these should need refs, the Script should hold onto the |
| +// library the document should keep the Module alive. |
| +void HTMLScriptRunner::executeLibrary(RefPtr<AbstractModule> module, |
| + RefPtr<DartValue> library) { |
| + if (!module) |
| + return scriptFailed(); |
| + |
| + advanceTo(StateExecuting); |
| + |
| + // Ian says we'll remove microtasks, but for now execute them right before |
| + // we "run" the script (call 'init'), not at dependency resolution |
| + // or script failures, etc. |
| + Microtask::performCheckpoint(); |
| + |
| + if (LocalFrame* frame = contextFrame(m_element.get())) |
| + frame->dart().ExecuteLibraryInModule(module.get(), library->dart_value()); |
| + |
| + advanceTo(StateCompleted); |
| + // We may be deleted at this point. |
| } |
| } |