summaryrefslogtreecommitdiffstats
path: root/gin
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 /gin
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
Diffstat (limited to 'gin')
-rw-r--r--gin/wrappable.cc25
-rw-r--r--gin/wrappable.h21
-rw-r--r--gin/wrappable_unittest.cc63
3 files changed, 70 insertions, 39 deletions
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