15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file contains definitions for CppBoundClass 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Here's the control flow of a JS method getting forwarded to a class. 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - Something calls our NPObject with a function like "Invoke". 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - CppNPObject's static invoke() function forwards it to its attached 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// CppBoundClass's Invoke() method. 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - CppBoundClass has then overridden Invoke() to look up the function 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// name in its internal map of methods, and then calls the appropriate 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// method. 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "webkit/renderer/cpp_bound_class.h" 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebBindings.h" 227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebFrame.h" 23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebString.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebBindings; 26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebFrame; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace webkit_glue { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CppVariantPropertyCallback : public CppBoundClass::PropertyCallback { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CppVariantPropertyCallback(CppVariant* value) : value_(value) { } 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool GetValue(CppVariant* value) OVERRIDE { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value->Set(*value_); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool SetValue(const CppVariant& value) OVERRIDE { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value_->Set(value); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CppVariant* value_; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GetterPropertyCallback : public CppBoundClass::PropertyCallback { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public: 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetterPropertyCallback(const CppBoundClass::GetterCallback& callback) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : callback_(callback) { } 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool GetValue(CppVariant* value) OVERRIDE { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_.Run(value); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool SetValue(const CppVariant& value) OVERRIDE { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)private: 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CppBoundClass::GetterCallback callback_; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Our special NPObject type. We extend an NPObject with a pointer to a 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// CppBoundClass, which is just a C++ interface that we forward all NPObject 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// callbacks to. 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct CppNPObject { 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPObject parent; // This must be the first field in the struct. 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CppBoundClass* bound_class; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // All following objects and functions are static, and just used to interface 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // with NPObject/NPClass. 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // An NPClass associates static functions of CppNPObject with the 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // function pointers used by the JS runtime. 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static NPClass np_class_; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Allocate a new NPObject with the specified class. 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static NPObject* allocate(NPP npp, NPClass* aClass); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Free an object. 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void deallocate(NPObject* obj); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if the C++ class associated with this NPObject exposes the 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // given property. Called by the JS runtime. 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool hasProperty(NPObject *obj, NPIdentifier ident); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if the C++ class associated with this NPObject exposes the 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // given method. Called by the JS runtime. 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool hasMethod(NPObject *obj, NPIdentifier ident); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the given method is exposed by the C++ class associated with this 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NPObject, invokes it with the given args and returns a result. Otherwise, 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // returns "undefined" (in the JavaScript sense). Called by the JS runtime. 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool invoke(NPObject *obj, NPIdentifier ident, 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NPVariant *args, uint32_t arg_count, 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPVariant *result); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the given property is exposed by the C++ class associated with this 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NPObject, returns its value. Otherwise, returns "undefined" (in the 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // JavaScript sense). Called by the JS runtime. 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool getProperty(NPObject *obj, NPIdentifier ident, 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPVariant *result); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the given property is exposed by the C++ class associated with this 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NPObject, sets its value. Otherwise, does nothing. Called by the JS 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // runtime. 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool setProperty(NPObject *obj, NPIdentifier ident, 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NPVariant *value); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Build CppNPObject's static function pointers into an NPClass, for use 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in constructing NPObjects for the C++ classes. 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NPClass CppNPObject::np_class_ = { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NP_CLASS_STRUCT_VERSION, 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CppNPObject::allocate, 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CppNPObject::deallocate, 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* NPInvalidateFunctionPtr */ NULL, 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CppNPObject::hasMethod, 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CppNPObject::invoke, 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* NPInvokeDefaultFunctionPtr */ NULL, 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CppNPObject::hasProperty, 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CppNPObject::getProperty, 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CppNPObject::setProperty, 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* NPRemovePropertyFunctionPtr */ NULL 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* static */ NPObject* CppNPObject::allocate(NPP npp, NPClass* aClass) { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CppNPObject* obj = new CppNPObject; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // obj->parent will be initialized by the NPObject code calling this. 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) obj->bound_class = NULL; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &obj->parent; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* static */ void CppNPObject::deallocate(NPObject* np_obj) { 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CppNPObject* obj = reinterpret_cast<CppNPObject*>(np_obj); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete obj; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* static */ bool CppNPObject::hasMethod(NPObject* np_obj, 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPIdentifier ident) { 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CppNPObject* obj = reinterpret_cast<CppNPObject*>(np_obj); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return obj->bound_class->HasMethod(ident); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* static */ bool CppNPObject::hasProperty(NPObject* np_obj, 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPIdentifier ident) { 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CppNPObject* obj = reinterpret_cast<CppNPObject*>(np_obj); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return obj->bound_class->HasProperty(ident); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* static */ bool CppNPObject::invoke(NPObject* np_obj, NPIdentifier ident, 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NPVariant* args, uint32_t arg_count, 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPVariant* result) { 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CppNPObject* obj = reinterpret_cast<CppNPObject*>(np_obj); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return obj->bound_class->Invoke(ident, args, arg_count, result); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* static */ bool CppNPObject::getProperty(NPObject* np_obj, 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPIdentifier ident, 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPVariant* result) { 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CppNPObject* obj = reinterpret_cast<CppNPObject*>(np_obj); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return obj->bound_class->GetProperty(ident, result); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* static */ bool CppNPObject::setProperty(NPObject* np_obj, 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPIdentifier ident, 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NPVariant* value) { 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CppNPObject* obj = reinterpret_cast<CppNPObject*>(np_obj); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return obj->bound_class->SetProperty(ident, value); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)CppBoundClass::CppBoundClass() : bound_to_frame_(false), npp_(new NPP_t) { 18190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) WebBindings::registerObjectOwner(npp_.get()); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CppBoundClass::~CppBoundClass() { 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STLDeleteValues(&properties_); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // TODO(wez): Remove once crrev.com/14019005 lands. 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bound_to_frame_) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebBindings::unregisterObject(NPVARIANT_TO_OBJECT(self_variant_)); 19090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 19190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) WebBindings::unregisterObjectOwner(npp_.get()); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CppBoundClass::HasMethod(NPIdentifier ident) const { 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (methods_.find(ident) != methods_.end()); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CppBoundClass::HasProperty(NPIdentifier ident) const { 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (properties_.find(ident) != properties_.end()); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CppBoundClass::Invoke(NPIdentifier ident, 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NPVariant* args, 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t arg_count, 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPVariant* result) { 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MethodList::const_iterator method = methods_.find(ident); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Callback callback; 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (method == methods_.end()) { 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!fallback_callback_.is_null()) { 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback = fallback_callback_; 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VOID_TO_NPVARIANT(*result); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback = method->second; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Build a CppArgumentList argument vector from the NPVariants coming in. 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CppArgumentList cpp_args(arg_count); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < arg_count; i++) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cpp_args[i].Set(args[i]); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CppVariant cpp_result; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.Run(cpp_args, &cpp_result); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cpp_result.CopyToNPVariant(result); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CppBoundClass::GetProperty(NPIdentifier ident, NPVariant* result) const { 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PropertyList::const_iterator callback = properties_.find(ident); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (callback == properties_.end()) { 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VOID_TO_NPVARIANT(*result); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CppVariant cpp_value; 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!callback->second->GetValue(&cpp_value)) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cpp_value.CopyToNPVariant(result); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CppBoundClass::SetProperty(NPIdentifier ident, 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NPVariant* value) { 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PropertyList::iterator callback = properties_.find(ident); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (callback == properties_.end()) 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CppVariant cpp_value; 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cpp_value.Set(*value); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (*callback).second->SetValue(cpp_value); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CppBoundClass::BindCallback(const std::string& name, 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Callback& callback) { 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPIdentifier ident = WebBindings::getStringIdentifier(name.c_str()); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (callback.is_null()) { 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) methods_.erase(ident); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) methods_[ident] = callback; 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CppBoundClass::BindGetterCallback(const std::string& name, 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GetterCallback& callback) { 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PropertyCallback* property_callback = callback.is_null() ? 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL : new GetterPropertyCallback(callback); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BindProperty(name, property_callback); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CppBoundClass::BindProperty(const std::string& name, CppVariant* prop) { 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PropertyCallback* property_callback = prop == NULL ? 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL : new CppVariantPropertyCallback(prop); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BindProperty(name, property_callback); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CppBoundClass::BindProperty(const std::string& name, 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PropertyCallback* callback) { 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPIdentifier ident = WebBindings::getStringIdentifier(name.c_str()); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PropertyList::iterator old_callback = properties_.find(ident); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (old_callback != properties_.end()) { 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete old_callback->second; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (callback == NULL) { 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) properties_.erase(old_callback); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) properties_[ident] = callback; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CppBoundClass::IsMethodRegistered(const std::string& name) const { 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPIdentifier ident = WebBindings::getStringIdentifier(name.c_str()); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MethodList::const_iterator callback = methods_.find(ident); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (callback != methods_.end()); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CppVariant* CppBoundClass::GetAsCppVariant() { 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!self_variant_.isObject()) { 30590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Create an NPObject using our static NPClass. The first argument has type 30690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // NPP, but is only used to track object ownership, so passing this is fine. 30790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) NPObject* np_obj = WebBindings::createObject( 30890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) npp_.get(), &CppNPObject::np_class_); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CppNPObject* obj = reinterpret_cast<CppNPObject*>(np_obj); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) obj->bound_class = this; 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self_variant_.Set(np_obj); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebBindings::releaseObject(np_obj); // CppVariant takes the reference. 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(self_variant_.isObject()); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &self_variant_; 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CppBoundClass::BindToJavascript(WebFrame* frame, 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& classname) { 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // BindToWindowObject will take its own reference to the NPObject, and clean 32190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // up after itself. It will also (indirectly) register the object with V8, 32290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // against an owner pointer we supply, so we must register that as an owner, 32390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // and unregister when we teardown. 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frame->bindToWindowObject(ASCIIToUTF16(classname), 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPVARIANT_TO_OBJECT(*GetAsCppVariant())); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bound_to_frame_ = true; 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace webkit_glue 330