| 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);
|
| +}
|
| +
|
| +// 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.
|
| }
|
|
|
| }
|
|
|