| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // This file contains definitions for CppBoundClass | 5 // This file contains definitions for CppBoundClass |
| 6 | 6 |
| 7 // Here's the control flow of a JS method getting forwarded to a class. | 7 // Here's the control flow of a JS method getting forwarded to a class. |
| 8 // - Something calls our NPObject with a function like "Invoke". | 8 // - Something calls our NPObject with a function like "Invoke". |
| 9 // - CppNPObject's static invoke() function forwards it to its attached | 9 // - CppNPObject's static invoke() function forwards it to its attached |
| 10 // CppBoundClass's Invoke() method. | 10 // CppBoundClass's Invoke() method. |
| (...skipping 26 matching lines...) Expand all Loading... |
| 37 struct CppNPObject { | 37 struct CppNPObject { |
| 38 NPObject parent; // This must be the first field in the struct. | 38 NPObject parent; // This must be the first field in the struct. |
| 39 CppBoundClass* bound_class; | 39 CppBoundClass* bound_class; |
| 40 | 40 |
| 41 // | 41 // |
| 42 // All following objects and functions are static, and just used to interface | 42 // All following objects and functions are static, and just used to interface |
| 43 // with NPObject/NPClass. | 43 // with NPObject/NPClass. |
| 44 // | 44 // |
| 45 | 45 |
| 46 // An NPClass associates static functions of CppNPObject with the | 46 // An NPClass associates static functions of CppNPObject with the |
| 47 // function pointers used by the JS runtime. | 47 // function pointers used by the JS runtime. |
| 48 static NPClass np_class_; | 48 static NPClass np_class_; |
| 49 | 49 |
| 50 // Allocate a new NPObject with the specified class. | 50 // Allocate a new NPObject with the specified class. |
| 51 static NPObject* allocate(NPP npp, NPClass* aClass); | 51 static NPObject* allocate(NPP npp, NPClass* aClass); |
| 52 | 52 |
| 53 // Free an object. | 53 // Free an object. |
| 54 static void deallocate(NPObject* obj); | 54 static void deallocate(NPObject* obj); |
| 55 | 55 |
| 56 // Returns true if the C++ class associated with this NPObject exposes the | 56 // Returns true if the C++ class associated with this NPObject exposes the |
| 57 // given property. Called by the JS runtime. | 57 // given property. Called by the JS runtime. |
| 58 static bool hasProperty(NPObject *obj, NPIdentifier ident); | 58 static bool hasProperty(NPObject *obj, NPIdentifier ident); |
| 59 | 59 |
| 60 // Returns true if the C++ class associated with this NPObject exposes the | 60 // Returns true if the C++ class associated with this NPObject exposes the |
| 61 // given method. Called by the JS runtime. | 61 // given method. Called by the JS runtime. |
| 62 static bool hasMethod(NPObject *obj, NPIdentifier ident); | 62 static bool hasMethod(NPObject *obj, NPIdentifier ident); |
| 63 | 63 |
| 64 // If the given method is exposed by the C++ class associated with this | 64 // If the given method is exposed by the C++ class associated with this |
| 65 // NPObject, invokes it with the given args and returns a result. Otherwise, | 65 // NPObject, invokes it with the given args and returns a result. Otherwise, |
| 66 // returns "undefined" (in the JavaScript sense). Called by the JS runtime. | 66 // returns "undefined" (in the JavaScript sense). Called by the JS runtime. |
| 67 static bool invoke(NPObject *obj, NPIdentifier ident, | 67 static bool invoke(NPObject *obj, NPIdentifier ident, |
| 68 const NPVariant *args, uint32_t arg_count, | 68 const NPVariant *args, uint32_t arg_count, |
| 69 NPVariant *result); | 69 NPVariant *result); |
| 70 | 70 |
| 71 // If the given property is exposed by the C++ class associated with this | 71 // If the given property is exposed by the C++ class associated with this |
| 72 // NPObject, returns its value. Otherwise, returns "undefined" (in the | 72 // NPObject, returns its value. Otherwise, returns "undefined" (in the |
| 73 // JavaScript sense). Called by the JS runtime. | 73 // JavaScript sense). Called by the JS runtime. |
| 74 static bool getProperty(NPObject *obj, NPIdentifier ident, | 74 static bool getProperty(NPObject *obj, NPIdentifier ident, |
| 75 NPVariant *result); | 75 NPVariant *result); |
| 76 | 76 |
| 77 // If the given property is exposed by the C++ class associated with this | 77 // If the given property is exposed by the C++ class associated with this |
| 78 // NPObject, sets its value. Otherwise, does nothing. Called by the JS | 78 // NPObject, sets its value. Otherwise, does nothing. Called by the JS |
| 79 // runtime. | 79 // runtime. |
| 80 static bool setProperty(NPObject *obj, NPIdentifier ident, | 80 static bool setProperty(NPObject *obj, NPIdentifier ident, |
| 81 const NPVariant *value); | 81 const NPVariant *value); |
| 82 }; | 82 }; |
| 83 | 83 |
| 84 // Build CppNPObject's static function pointers into an NPClass, for use | 84 // Build CppNPObject's static function pointers into an NPClass, for use |
| 85 // in constructing NPObjects for the C++ classes. | 85 // in constructing NPObjects for the C++ classes. |
| 86 NPClass CppNPObject::np_class_ = { | 86 NPClass CppNPObject::np_class_ = { |
| 87 NP_CLASS_STRUCT_VERSION, | 87 NP_CLASS_STRUCT_VERSION, |
| 88 CppNPObject::allocate, | 88 CppNPObject::allocate, |
| 89 CppNPObject::deallocate, | 89 CppNPObject::deallocate, |
| 90 /* NPInvalidateFunctionPtr */ NULL, | 90 /* NPInvalidateFunctionPtr */ NULL, |
| 91 CppNPObject::hasMethod, | 91 CppNPObject::hasMethod, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 102 // obj->parent will be initialized by the NPObject code calling this. | 102 // obj->parent will be initialized by the NPObject code calling this. |
| 103 obj->bound_class = NULL; | 103 obj->bound_class = NULL; |
| 104 return &obj->parent; | 104 return &obj->parent; |
| 105 } | 105 } |
| 106 | 106 |
| 107 /* static */ void CppNPObject::deallocate(NPObject* np_obj) { | 107 /* static */ void CppNPObject::deallocate(NPObject* np_obj) { |
| 108 CppNPObject* obj = reinterpret_cast<CppNPObject*>(np_obj); | 108 CppNPObject* obj = reinterpret_cast<CppNPObject*>(np_obj); |
| 109 delete obj; | 109 delete obj; |
| 110 } | 110 } |
| 111 | 111 |
| 112 /* static */ bool CppNPObject::hasMethod(NPObject* np_obj, | 112 /* static */ bool CppNPObject::hasMethod(NPObject* np_obj, |
| 113 NPIdentifier ident) { | 113 NPIdentifier ident) { |
| 114 CppNPObject* obj = reinterpret_cast<CppNPObject*>(np_obj); | 114 CppNPObject* obj = reinterpret_cast<CppNPObject*>(np_obj); |
| 115 return obj->bound_class->HasMethod(ident); | 115 return obj->bound_class->HasMethod(ident); |
| 116 } | 116 } |
| 117 | 117 |
| 118 /* static */ bool CppNPObject::hasProperty(NPObject* np_obj, | 118 /* static */ bool CppNPObject::hasProperty(NPObject* np_obj, |
| 119 NPIdentifier ident) { | 119 NPIdentifier ident) { |
| 120 CppNPObject* obj = reinterpret_cast<CppNPObject*>(np_obj); | 120 CppNPObject* obj = reinterpret_cast<CppNPObject*>(np_obj); |
| 121 return obj->bound_class->HasProperty(ident); | 121 return obj->bound_class->HasProperty(ident); |
| 122 } | 122 } |
| 123 | 123 |
| 124 /* static */ bool CppNPObject::invoke(NPObject* np_obj, NPIdentifier ident, | 124 /* static */ bool CppNPObject::invoke(NPObject* np_obj, NPIdentifier ident, |
| 125 const NPVariant* args, uint32_t arg_count,
| 125 const NPVariant* args, uint32_t arg_count, |
| 126 NPVariant* result) { | 126 NPVariant* result) { |
| 127 CppNPObject* obj = reinterpret_cast<CppNPObject*>(np_obj); | 127 CppNPObject* obj = reinterpret_cast<CppNPObject*>(np_obj); |
| 128 return obj->bound_class->Invoke(ident, args, arg_count, result); | 128 return obj->bound_class->Invoke(ident, args, arg_count, result); |
| 129 } | 129 } |
| 130 | 130 |
| 131 /* static */ bool CppNPObject::getProperty(NPObject* np_obj, | 131 /* static */ bool CppNPObject::getProperty(NPObject* np_obj, |
| 132 NPIdentifier ident, | 132 NPIdentifier ident, |
| 133 NPVariant* result) { | 133 NPVariant* result) { |
| 134 CppNPObject* obj = reinterpret_cast<CppNPObject*>(np_obj); | 134 CppNPObject* obj = reinterpret_cast<CppNPObject*>(np_obj); |
| 135 return obj->bound_class->GetProperty(ident, result); | 135 return obj->bound_class->GetProperty(ident, result); |
| 136 } | 136 } |
| 137 | 137 |
| 138 /* static */ bool CppNPObject::setProperty(NPObject* np_obj, | 138 /* static */ bool CppNPObject::setProperty(NPObject* np_obj, |
| 139 NPIdentifier ident, | 139 NPIdentifier ident, |
| 140 const NPVariant* value) { | 140 const NPVariant* value) { |
| 141 CppNPObject* obj = reinterpret_cast<CppNPObject*>(np_obj); | 141 CppNPObject* obj = reinterpret_cast<CppNPObject*>(np_obj); |
| 142 return obj->bound_class->SetProperty(ident, value); | 142 return obj->bound_class->SetProperty(ident, value); |
| 143 } | 143 } |
| 144 | 144 |
| 145 CppBoundClass::~CppBoundClass() { | 145 CppBoundClass::~CppBoundClass() { |
| 146 for (MethodList::iterator i = methods_.begin(); i != methods_.end(); ++i) | 146 for (MethodList::iterator i = methods_.begin(); i != methods_.end(); ++i) |
| 147 delete i->second; | 147 delete i->second; |
| 148 | 148 |
| 149 // Unregister objects we created and bound to a frame. | 149 // Unregister objects we created and bound to a frame. |
| 150 for (BoundObjectList::iterator i = bound_objects_.begin(); | 150 for (BoundObjectList::iterator i = bound_objects_.begin(); |
| 151 i != bound_objects_.end(); ++i) { | 151 i != bound_objects_.end(); ++i) { |
| 152 #if USE(V8) | 152 #if USE(V8) |
| 153 _NPN_UnregisterObject(*i); | 153 _NPN_UnregisterObject(*i); |
| 154 #endif | 154 #endif |
| 155 NPN_ReleaseObject(*i); | 155 NPN_ReleaseObject(*i); |
| 156 } | 156 } |
| 157 } | 157 } |
| 158 | 158 |
| 159 bool CppBoundClass::HasMethod(NPIdentifier ident) { | 159 bool CppBoundClass::HasMethod(NPIdentifier ident) const { |
| 160 return (methods_.find(ident) != methods_.end()); | 160 return (methods_.find(ident) != methods_.end()); |
| 161 } | 161 } |
| 162 | 162 |
| 163 bool CppBoundClass::HasProperty(NPIdentifier ident) { | 163 bool CppBoundClass::HasProperty(NPIdentifier ident) const { |
| 164 return (properties_.find(ident) != properties_.end()); | 164 return (properties_.find(ident) != properties_.end()); |
| 165 } | 165 } |
| 166 | 166 |
| 167 bool CppBoundClass::Invoke(NPIdentifier ident, | 167 bool CppBoundClass::Invoke(NPIdentifier ident, |
| 168 const NPVariant* args, | 168 const NPVariant* args, |
| 169 size_t arg_count, | 169 size_t arg_count, |
| 170 NPVariant* result) { | 170 NPVariant* result) { |
| 171 MethodList::const_iterator method = methods_.find(ident); | 171 MethodList::const_iterator method = methods_.find(ident); |
| 172 Callback* callback; | 172 Callback* callback; |
| 173 if (method == methods_.end()) { | 173 if (method == methods_.end()) { |
| 174 if (fallback_callback_.get()) { | 174 if (fallback_callback_.get()) { |
| 175 callback = fallback_callback_.get(); | 175 callback = fallback_callback_.get(); |
| 176 } else { | 176 } else { |
| 177 VOID_TO_NPVARIANT(*result); | 177 VOID_TO_NPVARIANT(*result); |
| 178 return false; | 178 return false; |
| 179 } | 179 } |
| 180 } else { | 180 } else { |
| 181 callback = (*method).second; | 181 callback = (*method).second; |
| 182 } | 182 } |
| 183 | 183 |
| 184 // Build a CppArgumentList argument vector from the NPVariants coming in. | 184 // Build a CppArgumentList argument vector from the NPVariants coming in. |
| 185 CppArgumentList cpp_args(arg_count); | 185 CppArgumentList cpp_args(arg_count); |
| 186 for (size_t i = 0; i < arg_count; i++) | 186 for (size_t i = 0; i < arg_count; i++) |
| 187 cpp_args[i].Set(args[i]); | 187 cpp_args[i].Set(args[i]); |
| 188 | 188 |
| 189 CppVariant cpp_result; | 189 CppVariant cpp_result; |
| 190 callback->Run(cpp_args, &cpp_result); | 190 callback->Run(cpp_args, &cpp_result); |
| 191 | 191 |
| 192 cpp_result.CopyToNPVariant(result); | 192 cpp_result.CopyToNPVariant(result); |
| 193 return true; | 193 return true; |
| 194 } | 194 } |
| 195 | 195 |
| 196 bool CppBoundClass::GetProperty(NPIdentifier ident, NPVariant* result) { | 196 bool CppBoundClass::GetProperty(NPIdentifier ident, NPVariant* result) const { |
| 197 PropertyList::const_iterator prop = properties_.find(ident); | 197 PropertyList::const_iterator prop = properties_.find(ident); |
| 198 if (prop == properties_.end()) { | 198 if (prop == properties_.end()) { |
| 199 VOID_TO_NPVARIANT(*result); | 199 VOID_TO_NPVARIANT(*result); |
| 200 return false; | 200 return false; |
| 201 } | 201 } |
| 202 | 202 |
| 203 const CppVariant* cpp_value = (*prop).second; | 203 const CppVariant* cpp_value = (*prop).second; |
| 204 cpp_value->CopyToNPVariant(result); | 204 cpp_value->CopyToNPVariant(result); |
| 205 return true; | 205 return true; |
| 206 } | 206 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 223 delete old_callback->second; | 223 delete old_callback->second; |
| 224 methods_[ident] = callback; | 224 methods_[ident] = callback; |
| 225 } | 225 } |
| 226 | 226 |
| 227 void CppBoundClass::BindProperty(std::string name, CppVariant* prop) { | 227 void CppBoundClass::BindProperty(std::string name, CppVariant* prop) { |
| 228 // NPUTF8 is a typedef for char, so this cast is safe. | 228 // NPUTF8 is a typedef for char, so this cast is safe. |
| 229 NPIdentifier ident = NPN_GetStringIdentifier((const NPUTF8*)name.c_str()); | 229 NPIdentifier ident = NPN_GetStringIdentifier((const NPUTF8*)name.c_str()); |
| 230 properties_[ident] = prop; | 230 properties_[ident] = prop; |
| 231 } | 231 } |
| 232 | 232 |
| 233 bool CppBoundClass::IsMethodRegistered(std::string name) { | 233 bool CppBoundClass::IsMethodRegistered(std::string name) const { |
| 234 // NPUTF8 is a typedef for char, so this cast is safe. | 234 // NPUTF8 is a typedef for char, so this cast is safe. |
| 235 NPIdentifier ident = NPN_GetStringIdentifier((const NPUTF8*)name.c_str()); | 235 NPIdentifier ident = NPN_GetStringIdentifier((const NPUTF8*)name.c_str()); |
| 236 MethodList::iterator callback = methods_.find(ident); | 236 MethodList::const_iterator callback = methods_.find(ident); |
| 237 return (callback != methods_.end()); | 237 return (callback != methods_.end()); |
| 238 } | 238 } |
| 239 | 239 |
| 240 void CppBoundClass::BindToJavascript(WebFrame* frame, | 240 void CppBoundClass::BindToJavascript(WebFrame* frame, |
| 241 const std::wstring& classname) { | 241 const std::wstring& classname) { |
| 242 #if USE(JSC) | 242 #if USE(JSC) |
| 243 JSC::JSLock lock(false); | 243 JSC::JSLock lock(false); |
| 244 #endif | 244 #endif |
| 245 | 245 |
| 246 // Create an NPObject using our static NPClass. The first argument (a | 246 // Create an NPObject using our static NPClass. The first argument (a |
| 247 // plugin's instance handle) is passed through to the allocate function | 247 // plugin's instance handle) is passed through to the allocate function |
| 248 // directly, and we don't use it, so it's ok to be 0. | 248 // directly, and we don't use it, so it's ok to be 0. |
| 249 NPObject* np_obj = NPN_CreateObject(0, &CppNPObject::np_class_); | 249 NPObject* np_obj = NPN_CreateObject(0, &CppNPObject::np_class_); |
| 250 CppNPObject* obj = reinterpret_cast<CppNPObject*>(np_obj); | 250 CppNPObject* obj = reinterpret_cast<CppNPObject*>(np_obj); |
| 251 obj->bound_class = this; | 251 obj->bound_class = this; |
| 252 | 252 |
| 253 // BindToWindowObject will (indirectly) retain the np_object. We save it | 253 // BindToWindowObject will (indirectly) retain the np_object. We save it |
| 254 // so we can release it when we're destroyed. | 254 // so we can release it when we're destroyed. |
| 255 frame->BindToWindowObject(classname, np_obj); | 255 frame->BindToWindowObject(classname, np_obj); |
| 256 bound_objects_.push_back(np_obj); | 256 bound_objects_.push_back(np_obj); |
| 257 } | 257 } |
| 258 | 258 |
| OLD | NEW |