summaryrefslogtreecommitdiffstats
path: root/gin
diff options
context:
space:
mode:
authorsky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-06 10:28:14 +0000
committersky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-06 10:28:14 +0000
commit438f944e1f3ef46b6a7d9c0b99a85a78b45493e1 (patch)
tree5d68a23bf4dc1f304c3656f9df8c2469b3242850 /gin
parent441b50d7d8d8dfc848624c6d7edb778be4285f3a (diff)
downloadchromium_src-438f944e1f3ef46b6a7d9c0b99a85a78b45493e1.zip
chromium_src-438f944e1f3ef46b6a7d9c0b99a85a78b45493e1.tar.gz
chromium_src-438f944e1f3ef46b6a7d9c0b99a85a78b45493e1.tar.bz2
Adds ModuleRegistryObserver interface
This will be used to know when a module has been added so that I can download needed modules. BUG=none TEST=none R=abarth@chromium.org Review URL: https://codereview.chromium.org/187653004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@255291 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gin')
-rw-r--r--gin/gin.gyp1
-rw-r--r--gin/modules/module_registry.cc20
-rw-r--r--gin/modules/module_registry.h11
-rw-r--r--gin/modules/module_registry_observer.h31
-rw-r--r--gin/modules/module_registry_unittest.cc66
5 files changed, 129 insertions, 0 deletions
diff --git a/gin/gin.gyp b/gin/gin.gyp
index f87c2bc..8221ec2 100644
--- a/gin/gin.gyp
+++ b/gin/gin.gyp
@@ -42,6 +42,7 @@
'modules/file_module_provider.h',
'modules/module_registry.cc',
'modules/module_registry.h',
+ 'modules/module_registry_observer.h',
'modules/module_runner_delegate.cc',
'modules/module_runner_delegate.h',
'modules/timer.cc',
diff --git a/gin/modules/module_registry.cc b/gin/modules/module_registry.cc
index d4e3067..3712f1a 100644
--- a/gin/modules/module_registry.cc
+++ b/gin/modules/module_registry.cc
@@ -10,6 +10,7 @@
#include "base/logging.h"
#include "gin/arguments.h"
#include "gin/converter.h"
+#include "gin/modules/module_registry_observer.h"
#include "gin/per_context_data.h"
#include "gin/per_isolate_data.h"
#include "gin/public/wrapper_info.h"
@@ -112,6 +113,13 @@ void ModuleRegistry::RegisterGlobals(Isolate* isolate,
}
// static
+void ModuleRegistry::InstallGlobals(v8::Isolate* isolate,
+ v8::Handle<v8::Object> obj) {
+ obj->Set(StringToSymbol(isolate, "define"),
+ GetDefineTemplate(isolate)->GetFunction());
+}
+
+// static
ModuleRegistry* ModuleRegistry::From(v8::Handle<Context> context) {
PerContextData* data = PerContextData::From(context);
if (!data)
@@ -128,6 +136,14 @@ ModuleRegistry* ModuleRegistry::From(v8::Handle<Context> context) {
return registry_data->registry.get();
}
+void ModuleRegistry::AddObserver(ModuleRegistryObserver* observer) {
+ observer_list_.AddObserver(observer);
+}
+
+void ModuleRegistry::RemoveObserver(ModuleRegistryObserver* observer) {
+ observer_list_.RemoveObserver(observer);
+}
+
void ModuleRegistry::AddBuiltinModule(Isolate* isolate, const std::string& id,
v8::Handle<Value> module) {
DCHECK(!id.empty());
@@ -136,7 +152,11 @@ void ModuleRegistry::AddBuiltinModule(Isolate* isolate, const std::string& id,
void ModuleRegistry::AddPendingModule(Isolate* isolate,
scoped_ptr<PendingModule> pending) {
+ const std::string pending_id = pending->id;
+ const std::vector<std::string> pending_dependencies = pending->dependencies;
AttemptToLoad(isolate, pending.Pass());
+ FOR_EACH_OBSERVER(ModuleRegistryObserver, observer_list_,
+ OnDidAddPendingModule(pending_id, pending_dependencies));
}
void ModuleRegistry::LoadModule(Isolate* isolate,
diff --git a/gin/modules/module_registry.h b/gin/modules/module_registry.h
index 2270d31..5775a34 100644
--- a/gin/modules/module_registry.h
+++ b/gin/modules/module_registry.h
@@ -14,11 +14,13 @@
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
+#include "base/observer_list.h"
#include "gin/gin_export.h"
#include "v8/include/v8.h"
namespace gin {
+class ModuleRegistryObserver;
struct PendingModule;
// This class implements the Asynchronous Module Definition (AMD) API.
@@ -43,6 +45,13 @@ class GIN_EXPORT ModuleRegistry {
static void RegisterGlobals(v8::Isolate* isolate,
v8::Handle<v8::ObjectTemplate> templ);
+ // Installs the necessary functions needed for modules.
+ // WARNING: this may execute script in the page.
+ static void InstallGlobals(v8::Isolate* isolate, v8::Handle<v8::Object> obj);
+
+ void AddObserver(ModuleRegistryObserver* observer);
+ void RemoveObserver(ModuleRegistryObserver* observer);
+
// The caller must have already entered our context.
void AddBuiltinModule(v8::Isolate* isolate, const std::string& id,
v8::Handle<v8::Value> module);
@@ -90,6 +99,8 @@ class GIN_EXPORT ModuleRegistry {
PendingModuleVector pending_modules_;
v8::Persistent<v8::Object> modules_;
+ ObserverList<ModuleRegistryObserver> observer_list_;
+
DISALLOW_COPY_AND_ASSIGN(ModuleRegistry);
};
diff --git a/gin/modules/module_registry_observer.h b/gin/modules/module_registry_observer.h
new file mode 100644
index 0000000..68ee4ad
--- /dev/null
+++ b/gin/modules/module_registry_observer.h
@@ -0,0 +1,31 @@
+// Copyright 2014 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 GIN_MODULES_MODULE_REGISTRY_OBSERVER_H_
+#define GIN_MODULES_MODULE_REGISTRY_OBSERVER_H_
+
+#include <string>
+#include <vector>
+
+#include "gin/gin_export.h"
+
+namespace gin {
+
+// Notified of interesting events from ModuleRegistry.
+class GIN_EXPORT ModuleRegistryObserver {
+ public:
+ // Called from AddPendingModule(). |id| is the id/name of the module and
+ // |dependencies| this list of modules |id| depends upon.
+ virtual void OnDidAddPendingModule(
+ const std::string& id,
+ const std::vector<std::string>& dependencies) = 0;
+
+ protected:
+ virtual ~ModuleRegistryObserver() {}
+};
+
+} // namespace gin
+
+#endif // GIN_MODULES_MODULE_REGISTRY_OBSERVER_H_
+
diff --git a/gin/modules/module_registry_unittest.cc b/gin/modules/module_registry_unittest.cc
index af9dd00..0ffdc0c 100644
--- a/gin/modules/module_registry_unittest.cc
+++ b/gin/modules/module_registry_unittest.cc
@@ -4,13 +4,58 @@
#include "gin/modules/module_registry.h"
+#include "base/message_loop/message_loop.h"
+#include "gin/modules/module_registry_observer.h"
+#include "gin/modules/module_runner_delegate.h"
#include "gin/public/context_holder.h"
#include "gin/public/isolate_holder.h"
+#include "gin/shell_runner.h"
#include "gin/test/v8_test.h"
#include "v8/include/v8.h"
namespace gin {
+namespace {
+
+struct TestHelper {
+ TestHelper(v8::Isolate* isolate)
+ : delegate(std::vector<base::FilePath>()),
+ runner(new ShellRunner(&delegate, isolate)),
+ scope(runner.get()) {
+ }
+
+ base::MessageLoop message_loop;
+ ModuleRunnerDelegate delegate;
+ scoped_ptr<ShellRunner> runner;
+ Runner::Scope scope;
+};
+
+class ModuleRegistryObserverImpl : public ModuleRegistryObserver {
+ public:
+ ModuleRegistryObserverImpl() : did_add_count_(0) {}
+
+ virtual void OnDidAddPendingModule(
+ const std::string& id,
+ const std::vector<std::string>& dependencies) OVERRIDE {
+ did_add_count_++;
+ id_ = id;
+ dependencies_ = dependencies;
+ }
+
+ int did_add_count() { return did_add_count_; }
+ const std::string& id() const { return id_; }
+ const std::vector<std::string>& dependencies() const { return dependencies_; }
+
+ private:
+ int did_add_count_;
+ std::string id_;
+ std::vector<std::string> dependencies_;
+
+ DISALLOW_COPY_AND_ASSIGN(ModuleRegistryObserverImpl);
+};
+
+} // namespace
+
typedef V8Test ModuleRegistryTest;
// Verifies ModuleRegistry is not available after ContextHolder has been
@@ -30,4 +75,25 @@ TEST_F(ModuleRegistryTest, DestroyedWithContext) {
EXPECT_TRUE(registry == NULL);
}
+// Verifies ModuleRegistryObserver is notified appropriately.
+TEST_F(ModuleRegistryTest, ModuleRegistryObserverTest) {
+ TestHelper helper(instance_->isolate());
+ std::string source =
+ "define('id', ['dep1', 'dep2'], function() {"
+ " return function() {};"
+ "});";
+
+ ModuleRegistryObserverImpl observer;
+ ModuleRegistry::From(helper.runner->GetContextHolder()->context())->
+ AddObserver(&observer);
+ helper.runner->Run(source, "script");
+ ModuleRegistry::From(helper.runner->GetContextHolder()->context())->
+ RemoveObserver(&observer);
+ EXPECT_EQ(1, observer.did_add_count());
+ EXPECT_EQ("id", observer.id());
+ ASSERT_EQ(2u, observer.dependencies().size());
+ EXPECT_EQ("dep1", observer.dependencies()[0]);
+ EXPECT_EQ("dep2", observer.dependencies()[1]);
+}
+
} // namespace gin