summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoraa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-19 00:52:44 +0000
committeraa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-19 00:52:44 +0000
commit13c977e698996af379fad9a1b5015c6783d3465c (patch)
treec6bc716445370f32f5a708ff8963bc61802026a2
parent40e16762b22d3015ec00b51ff0072d0cbbf5fa43 (diff)
downloadchromium_src-13c977e698996af379fad9a1b5015c6783d3465c.zip
chromium_src-13c977e698996af379fad9a1b5015c6783d3465c.tar.gz
chromium_src-13c977e698996af379fad9a1b5015c6783d3465c.tar.bz2
Add support for wrapping classes indirectly inherited from gin::Wrappable<T>
This is needed for: https://codereview.chromium.org/116163008/ Review URL: https://codereview.chromium.org/118423004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@241730 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--content/renderer/stats_collection_controller.cc21
-rw-r--r--content/renderer/stats_collection_controller.h5
-rw-r--r--gin/wrappable.cc25
-rw-r--r--gin/wrappable.h21
-rw-r--r--gin/wrappable_unittest.cc63
-rw-r--r--mojo/apps/js/bindings/gl/context.cc19
-rw-r--r--mojo/apps/js/bindings/gl/context.h5
7 files changed, 96 insertions, 63 deletions
diff --git a/content/renderer/stats_collection_controller.cc b/content/renderer/stats_collection_controller.cc
index 0f5230e..cbbdc40 100644
--- a/content/renderer/stats_collection_controller.cc
+++ b/content/renderer/stats_collection_controller.cc
@@ -75,17 +75,6 @@ gin::WrapperInfo StatsCollectionController::kWrapperInfo = {
};
// static
-v8::Local<v8::ObjectTemplate> StatsCollectionController::GetObjectTemplate(
- v8::Isolate* isolate) {
- return gin::ObjectTemplateBuilder(isolate)
- .SetMethod("getHistogram", &StatsCollectionController::GetHistogram)
- .SetMethod("getBrowserHistogram",
- &StatsCollectionController::GetBrowserHistogram)
- .SetMethod("tabLoadTiming", &StatsCollectionController::GetTabLoadTiming)
- .Build();
-}
-
-// static
void StatsCollectionController::Install(blink::WebFrame* frame) {
v8::Isolate* isolate = blink::mainThreadIsolate();
v8::HandleScope handle_scope(isolate);
@@ -106,6 +95,16 @@ StatsCollectionController::StatsCollectionController() {}
StatsCollectionController::~StatsCollectionController() {}
+gin::ObjectTemplateBuilder StatsCollectionController::GetObjectTemplateBuilder(
+ v8::Isolate* isolate) {
+ return gin::Wrappable<StatsCollectionController>::GetObjectTemplateBuilder(
+ isolate)
+ .SetMethod("getHistogram", &StatsCollectionController::GetHistogram)
+ .SetMethod("getBrowserHistogram",
+ &StatsCollectionController::GetBrowserHistogram)
+ .SetMethod("tabLoadTiming", &StatsCollectionController::GetTabLoadTiming);
+}
+
std::string StatsCollectionController::GetHistogram(
const std::string& histogram_name) {
base::HistogramBase* histogram =
diff --git a/content/renderer/stats_collection_controller.h b/content/renderer/stats_collection_controller.h
index 91b3748..279fed7 100644
--- a/content/renderer/stats_collection_controller.h
+++ b/content/renderer/stats_collection_controller.h
@@ -22,7 +22,6 @@ class StatsCollectionController
: public gin::Wrappable<StatsCollectionController> {
public:
static gin::WrapperInfo kWrapperInfo;
- static v8::Local<v8::ObjectTemplate> GetObjectTemplate(v8::Isolate* isolate);
static void Install(blink::WebFrame* frame);
@@ -30,6 +29,10 @@ class StatsCollectionController
StatsCollectionController();
virtual ~StatsCollectionController();
+ // gin::WrappableBase
+ virtual gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
+ v8::Isolate* isolate) OVERRIDE;
+
// Retrieves a histogram and returns a JSON representation of it.
std::string GetHistogram(const std::string& histogram_name);
diff --git a/gin/wrappable.cc b/gin/wrappable.cc
index 3446f4f..8d41ce0 100644
--- a/gin/wrappable.cc
+++ b/gin/wrappable.cc
@@ -17,18 +17,9 @@ WrappableBase::~WrappableBase() {
wrapper_.Reset();
}
-v8::Handle<v8::Object> WrappableBase::GetWrapperImpl(
- v8::Isolate* isolate,
- WrapperInfo* wrapper_info,
- GetObjectTemplateFunction template_getter) {
- if (wrapper_.IsEmpty())
- CreateWrapper(isolate, wrapper_info, template_getter);
- return v8::Local<v8::Object>::New(isolate, wrapper_);
-}
-
-v8::Local<v8::ObjectTemplate> WrappableBase::GetObjectTemplate(
+ObjectTemplateBuilder WrappableBase::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
- return ObjectTemplateBuilder(isolate).Build();
+ return ObjectTemplateBuilder(isolate);
}
void WrappableBase::WeakCallback(
@@ -38,14 +29,16 @@ void WrappableBase::WeakCallback(
delete wrappable;
}
-v8::Handle<v8::Object> WrappableBase::CreateWrapper(
- v8::Isolate* isolate,
- WrapperInfo* info,
- GetObjectTemplateFunction template_getter) {
+v8::Handle<v8::Object> WrappableBase::GetWrapperImpl(v8::Isolate* isolate,
+ WrapperInfo* info) {
+ if (!wrapper_.IsEmpty()) {
+ return v8::Local<v8::Object>::New(isolate, wrapper_);
+ }
+
PerIsolateData* data = PerIsolateData::From(isolate);
v8::Local<v8::ObjectTemplate> templ = data->GetObjectTemplate(info);
if (templ.IsEmpty()) {
- templ = template_getter(isolate);
+ templ = GetObjectTemplateBuilder(isolate).Build();
CHECK(!templ.IsEmpty());
data->SetObjectTemplate(info, templ);
}
diff --git a/gin/wrappable.h b/gin/wrappable.h
index fccca1a..e20c7f1 100644
--- a/gin/wrappable.h
+++ b/gin/wrappable.h
@@ -53,32 +53,23 @@ GIN_EXPORT void* FromV8Impl(v8::Isolate* isolate,
template<typename T>
class Wrappable;
+class ObjectTemplateBuilder;
// Non-template base class to share code between templates instances.
class GIN_EXPORT WrappableBase {
protected:
- typedef v8::Local<v8::ObjectTemplate>(*GetObjectTemplateFunction)(
- v8::Isolate*);
-
WrappableBase();
virtual ~WrappableBase();
- v8::Handle<v8::Object> GetWrapperImpl(
- v8::Isolate* isolate,
- WrapperInfo* wrapper_info,
- GetObjectTemplateFunction template_getter);
+ virtual ObjectTemplateBuilder GetObjectTemplateBuilder(v8::Isolate* isolate);
- static v8::Local<v8::ObjectTemplate> GetObjectTemplate(v8::Isolate* isolate);
+ v8::Handle<v8::Object> GetWrapperImpl(v8::Isolate* isolate,
+ WrapperInfo* wrapper_info);
private:
static void WeakCallback(
const v8::WeakCallbackData<v8::Object, WrappableBase>& data);
- v8::Handle<v8::Object> CreateWrapper(
- v8::Isolate* isolate,
- WrapperInfo* wrapper_info,
- GetObjectTemplateFunction template_getter);
-
v8::Persistent<v8::Object> wrapper_; // Weak
DISALLOW_COPY_AND_ASSIGN(WrappableBase);
@@ -92,7 +83,7 @@ class Wrappable : public WrappableBase {
// To customize the wrapper created for a subclass, override GetWrapperInfo()
// instead of overriding this function.
v8::Handle<v8::Object> GetWrapper(v8::Isolate* isolate) {
- return GetWrapperImpl(isolate, &T::kWrapperInfo, &T::GetObjectTemplate);
+ return GetWrapperImpl(isolate, &T::kWrapperInfo);
}
protected:
@@ -107,7 +98,7 @@ class Wrappable : public WrappableBase {
// This converter handles any subclass of Wrappable.
template<typename T>
struct Converter<T*, typename base::enable_if<
- base::is_convertible<T*, Wrappable<T>*>::value>::type> {
+ base::is_convertible<T*, WrappableBase*>::value>::type> {
static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate, T* val) {
return val->GetWrapper(isolate);
}
diff --git a/gin/wrappable_unittest.cc b/gin/wrappable_unittest.cc
index 35035ce..ad8b6b7 100644
--- a/gin/wrappable_unittest.cc
+++ b/gin/wrappable_unittest.cc
@@ -19,8 +19,6 @@ class MyObject : public Wrappable<MyObject> {
public:
static WrapperInfo kWrapperInfo;
- static v8::Local<v8::ObjectTemplate> GetObjectTemplate(v8::Isolate* isolate);
-
static gin::Handle<MyObject> Create(v8::Isolate* isolate) {
return CreateHandle(isolate, new MyObject());
}
@@ -28,13 +26,42 @@ class MyObject : public Wrappable<MyObject> {
int value() const { return value_; }
void set_value(int value) { value_ = value; }
- private:
+ protected:
MyObject() : value_(0) {}
+ virtual ObjectTemplateBuilder GetObjectTemplateBuilder(
+ v8::Isolate* isolate) OVERRIDE;
virtual ~MyObject() {}
+ private:
int value_;
};
+class MyObjectSubclass : public MyObject {
+ public:
+ static gin::Handle<MyObjectSubclass> Create(v8::Isolate* isolate) {
+ return CreateHandle(isolate, new MyObjectSubclass());
+ }
+
+ void SayHello(const std::string& name) {
+ result = std::string("Hello, ") + name;
+ }
+
+ std::string result;
+
+ private:
+ virtual ObjectTemplateBuilder GetObjectTemplateBuilder(
+ v8::Isolate* isolate) OVERRIDE {
+ return MyObject::GetObjectTemplateBuilder(isolate)
+ .SetMethod("sayHello", &MyObjectSubclass::SayHello);
+ }
+
+ MyObjectSubclass() {
+ }
+
+ virtual ~MyObjectSubclass() {
+ }
+};
+
class MyObject2 : public Wrappable<MyObject2> {
public:
static WrapperInfo kWrapperInfo;
@@ -46,11 +73,9 @@ class MyObjectBlink : public Wrappable<MyObjectBlink> {
};
WrapperInfo MyObject::kWrapperInfo = { kEmbedderNativeGin };
-v8::Local<v8::ObjectTemplate> MyObject::GetObjectTemplate(
- v8::Isolate* isolate) {
- return ObjectTemplateBuilder(isolate)
- .SetProperty("value", &MyObject::value, &MyObject::set_value)
- .Build();
+ObjectTemplateBuilder MyObject::GetObjectTemplateBuilder(v8::Isolate* isolate) {
+ return Wrappable<MyObject>::GetObjectTemplateBuilder(isolate)
+ .SetProperty("value", &MyObject::value, &MyObject::set_value);
}
WrapperInfo MyObject2::kWrapperInfo = { kEmbedderNativeGin };
@@ -132,4 +157,26 @@ TEST_F(WrappableTest, GetAndSetProperty) {
EXPECT_EQ(191, obj->value());
}
+TEST_F(WrappableTest, WrappableSubclass) {
+ v8::Isolate* isolate = instance_->isolate();
+ v8::HandleScope handle_scope(isolate);
+
+ gin::Handle<MyObjectSubclass> object(MyObjectSubclass::Create(isolate));
+ v8::Handle<v8::String> source = StringToV8(isolate,
+ "(function(obj) {"
+ "obj.sayHello('Lily');"
+ "})");
+ gin::TryCatch try_catch;
+ v8::Handle<v8::Script> script = v8::Script::New(source);
+ v8::Handle<v8::Value> val = script->Run();
+ v8::Handle<v8::Function> func;
+ EXPECT_TRUE(ConvertFromV8(isolate, val, &func));
+ v8::Handle<v8::Value> argv[] = {
+ ConvertToV8(isolate, object.get())
+ };
+ func->Call(v8::Undefined(isolate), 1, argv);
+ EXPECT_FALSE(try_catch.HasCaught());
+ EXPECT_EQ("Hello, Lily", object->result);
+}
+
} // namespace gin
diff --git a/mojo/apps/js/bindings/gl/context.cc b/mojo/apps/js/bindings/gl/context.cc
index efba8e5..c0bb74a 100644
--- a/mojo/apps/js/bindings/gl/context.cc
+++ b/mojo/apps/js/bindings/gl/context.cc
@@ -21,16 +21,6 @@ gin::Handle<Context> Context::Create(v8::Isolate* isolate, uint64_t encoded,
return gin::CreateHandle(isolate, new Context(encoded, width, height));
}
-v8::Local<v8::ObjectTemplate> Context::GetObjectTemplate(
- v8::Isolate* isolate) {
- return gin::ObjectTemplateBuilder(isolate)
- .SetValue("VERTEX_SHADER", GL_VERTEX_SHADER)
- .SetMethod("createShader", CreateShader)
- .SetMethod("shaderSource", ShaderSource)
- .SetMethod("compileShader", CompileShader)
- .Build();
-}
-
gin::Handle<Shader> Context::CreateShader(const gin::Arguments& args,
GLenum type) {
gin::Handle<Shader> result;
@@ -60,6 +50,15 @@ void Context::CompileShader(const gin::Arguments& args,
}
}
+gin::ObjectTemplateBuilder Context::GetObjectTemplateBuilder(
+ v8::Isolate* isolate) {
+ return gin::Wrappable<Context>::GetObjectTemplateBuilder(isolate)
+ .SetValue("VERTEX_SHADER", GL_VERTEX_SHADER)
+ .SetMethod("createShader", CreateShader)
+ .SetMethod("shaderSource", ShaderSource)
+ .SetMethod("compileShader", CompileShader);
+}
+
Context::Context(uint64_t encoded, int width, int height)
: encoded_(encoded) {
// TODO(aa): When we want to support multiple contexts, we should add
diff --git a/mojo/apps/js/bindings/gl/context.h b/mojo/apps/js/bindings/gl/context.h
index 11f1753..a5a3ca1 100644
--- a/mojo/apps/js/bindings/gl/context.h
+++ b/mojo/apps/js/bindings/gl/context.h
@@ -28,8 +28,6 @@ class Context : public gin::Wrappable<Context> {
public:
static gin::WrapperInfo kWrapperInfo;
- static v8::Local<v8::ObjectTemplate> GetObjectTemplate(v8::Isolate* isolate);
-
static gin::Handle<Context> Create(v8::Isolate* isolate, uint64_t encoded,
int width, int height);
static gin::Handle<Shader> CreateShader(const gin::Arguments& arguments,
@@ -40,6 +38,9 @@ class Context : public gin::Wrappable<Context> {
gin::Handle<Shader> shader);
private:
+ virtual gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
+ v8::Isolate* isolate) OVERRIDE;
+
Context(uint64_t encoded, int width, int height);
uint64_t encoded_;