Skip to content

Commit

Permalink
Introduce ModulePendingScript
Browse files Browse the repository at this point in the history
BUG=594639

Review-Url: https://codereview.chromium.org/2815453006
Cr-Commit-Position: refs/heads/master@{#464627}
  • Loading branch information
hiroshige-g authored and Commit bot committed Apr 14, 2017
1 parent 90a1c8c commit 2e5a5b8
Show file tree
Hide file tree
Showing 4 changed files with 189 additions and 0 deletions.
2 changes: 2 additions & 0 deletions third_party/WebKit/Source/core/dom/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@ blink_core_sources("dom") {
"Modulator.h",
"ModuleMap.cpp",
"ModuleMap.h",
"ModulePendingScript.cpp",
"ModulePendingScript.h",
"ModuleScript.cpp",
"ModuleScript.h",
"MutationCallback.h",
Expand Down
7 changes: 7 additions & 0 deletions third_party/WebKit/Source/core/dom/Modulator.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ class SingleModuleClient : public GarbageCollectedMixin {
virtual void NotifyModuleLoadFinished(ModuleScript*) = 0;
};

// A ModuleTreeClient is notified when a module script and its whole descendent
// tree load is complete.
class ModuleTreeClient : public GarbageCollectedMixin {
public:
virtual void NotifyModuleTreeLoadFinished(ModuleScript*) = 0;
};

// spec: "top-level module fetch flag"
// https://html.spec.whatwg.org/multipage/webappapis.html#fetching-scripts-is-top-level
enum class ModuleGraphLevel { kTopLevelModuleFetch, kDependentModuleFetch };
Expand Down
82 changes: 82 additions & 0 deletions third_party/WebKit/Source/core/dom/ModulePendingScript.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "core/dom/ModulePendingScript.h"

#include "core/dom/ScriptLoader.h"
#include "core/frame/LocalFrame.h"

namespace blink {

ModulePendingScriptTreeClient::ModulePendingScriptTreeClient()
: module_script_(nullptr), pending_script_(nullptr) {}

void ModulePendingScriptTreeClient::SetPendingScript(
ModulePendingScript* pending_script) {
DCHECK(!pending_script_);
pending_script_ = pending_script;

if (finished_) {
pending_script_->NotifyModuleTreeLoadFinished();
}
}

void ModulePendingScriptTreeClient::NotifyModuleTreeLoadFinished(
ModuleScript* module_script) {
DCHECK(!(module_script && module_script->InstantiationState() ==
ModuleInstantiationState::kUninstantiated));
DCHECK(!finished_);
finished_ = true;
module_script_ = module_script;

if (pending_script_)
pending_script_->NotifyModuleTreeLoadFinished();
}

DEFINE_TRACE(ModulePendingScriptTreeClient) {
visitor->Trace(module_script_);
visitor->Trace(pending_script_);
ModuleTreeClient::Trace(visitor);
}

ModulePendingScript::ModulePendingScript(ScriptElementBase* element,
ModulePendingScriptTreeClient* client)
: PendingScript(element, TextPosition()), module_tree_client_(client) {
CHECK(this->GetElement());
DCHECK(module_tree_client_);
client->SetPendingScript(this);
}

ModulePendingScript::~ModulePendingScript() {}

void ModulePendingScript::DisposeInternal() {
module_tree_client_ = nullptr;
}

DEFINE_TRACE(ModulePendingScript) {
visitor->Trace(module_tree_client_);
PendingScript::Trace(visitor);
}

void ModulePendingScript::NotifyModuleTreeLoadFinished() {
CHECK(!IsReady());
ready_ = true;

if (Client())
Client()->PendingScriptFinished(this);
}

Script* ModulePendingScript::GetSource(const KURL& document_url,
bool& error_occurred) const {
CHECK(IsReady());
error_occurred = ErrorOccurred();
return GetModuleScript();
}

bool ModulePendingScript::ErrorOccurred() const {
CHECK(IsReady());
return !GetModuleScript();
}

} // namespace blink
98 changes: 98 additions & 0 deletions third_party/WebKit/Source/core/dom/ModulePendingScript.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef ModulePendingScript_h
#define ModulePendingScript_h

#include "core/dom/Modulator.h"
#include "core/dom/ModuleScript.h"
#include "core/dom/PendingScript.h"

namespace blink {

class ModulePendingScript;

// ModulePendingScriptTreeClient is used to connect from Modulator::FetchTree()
// to ModulePendingScript. Because ModulePendingScript is created after
// Modulator::FetchTree() is called, ModulePendingScriptTreeClient is
// registered as ModuleTreeClient to FetchTree() first, and later
// ModulePendingScript is supplied to ModulePendingScriptTreeClient via
// SetPendingScript() and is notified of module tree load finish.
class ModulePendingScriptTreeClient final
: public GarbageCollectedFinalized<ModulePendingScriptTreeClient>,
public ModuleTreeClient {
USING_GARBAGE_COLLECTED_MIXIN(ModulePendingScriptTreeClient);

public:
static ModulePendingScriptTreeClient* Create() {
return new ModulePendingScriptTreeClient();
}
virtual ~ModulePendingScriptTreeClient() = default;

void SetPendingScript(ModulePendingScript* client);

ModuleScript* GetModuleScript() const { return module_script_; }

DECLARE_TRACE();

private:
ModulePendingScriptTreeClient();

// Implements ModuleTreeClient
void NotifyModuleTreeLoadFinished(ModuleScript*) override;

bool finished_ = false;
Member<ModuleScript> module_script_;
Member<ModulePendingScript> pending_script_;
};

// PendingScript for a module script
// https://html.spec.whatwg.org/#module-script.
class CORE_EXPORT ModulePendingScript : public PendingScript {
public:
static ModulePendingScript* Create(ScriptElementBase* element,
ModulePendingScriptTreeClient* client) {
return new ModulePendingScript(element, client);
}

~ModulePendingScript() override;

void NotifyModuleTreeLoadFinished();

ModuleScript* GetModuleScript() const {
return module_tree_client_->GetModuleScript();
}

DECLARE_TRACE();

private:
ModulePendingScript(ScriptElementBase*, ModulePendingScriptTreeClient*);

// PendingScript
ScriptType GetScriptType() const override { return ScriptType::kModule; }
Script* GetSource(const KURL& document_url,
bool& error_occurred) const override;
bool IsReady() const override { return ready_; }
bool IsExternal() const override { return true; }
bool ErrorOccurred() const override;
bool WasCanceled() const override { return false; }

void StartStreamingIfPossible(Document*, ScriptStreamer::Type) override {}
KURL UrlForClassicScript() const override {
NOTREACHED();
return KURL();
}
void RemoveFromMemoryCache() override { NOTREACHED(); }

void DisposeInternal() override;

void CheckState() const override {}

Member<ModulePendingScriptTreeClient> module_tree_client_;
bool ready_ = false;
};

} // namespace blink

#endif // ModulePendingScript_h

0 comments on commit 2e5a5b8

Please sign in to comment.