diff options
author | dglazkov@chromium.org <dglazkov@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-13 20:16:34 +0000 |
---|---|---|
committer | dglazkov@chromium.org <dglazkov@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-13 20:16:34 +0000 |
commit | 55a75d99c6609ed4f6dc7052fcf3d907efaf7137 (patch) | |
tree | 39a50ac51abdbee695ce494cfecefbbebfb38248 /webkit/glue/cpp_bound_class.cc | |
parent | 4eeb018cc6f4b3a1d6715facaa3a3c54a22b4951 (diff) | |
download | chromium_src-55a75d99c6609ed4f6dc7052fcf3d907efaf7137.zip chromium_src-55a75d99c6609ed4f6dc7052fcf3d907efaf7137.tar.gz chromium_src-55a75d99c6609ed4f6dc7052fcf3d907efaf7137.tar.bz2 |
Implement getter/setter-based bound properties for CppBoundClass.
This is necessary for AccessibilityController, which has non-trivial
property accessors.
R=darin
BUG=10322
TEST=CppBoundClassTest.SetAndGetPropertiesWithCallbacks
Review URL: http://codereview.chromium.org/243064
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@28872 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/glue/cpp_bound_class.cc')
-rw-r--r-- | webkit/glue/cpp_bound_class.cc | 115 |
1 files changed, 95 insertions, 20 deletions
diff --git a/webkit/glue/cpp_bound_class.cc b/webkit/glue/cpp_bound_class.cc index 3e5c1e7..f82b78e 100644 --- a/webkit/glue/cpp_bound_class.cc +++ b/webkit/glue/cpp_bound_class.cc @@ -23,6 +23,45 @@ using WebKit::WebBindings; using WebKit::WebFrame; +namespace { + +class CppVariantPropertyCallback : public CppBoundClass::PropertyCallback { + public: + CppVariantPropertyCallback(CppVariant* value) : value_(value) { } + + virtual bool GetValue(CppVariant* value) { + value->Set(*value_); + return true; + } + virtual bool SetValue(const CppVariant& value) { + value_->Set(value); + return true; + } + + private: + CppVariant* value_; +}; + +class GetterPropertyCallback : public CppBoundClass::PropertyCallback { +public: + GetterPropertyCallback(CppBoundClass::GetterCallback* callback) + : callback_(callback) { } + + virtual bool GetValue(CppVariant* value) { + callback_->Run(value); + return true; + } + + virtual bool SetValue(const CppVariant& value) { + return false; + } + +private: + scoped_ptr<CppBoundClass::GetterCallback> callback_; +}; + +} + // Our special NPObject type. We extend an NPObject with a pointer to a // CppBoundClass, which is just a C++ interface that we forward all NPObject // callbacks to. @@ -138,6 +177,11 @@ CppBoundClass::~CppBoundClass() { for (MethodList::iterator i = methods_.begin(); i != methods_.end(); ++i) delete i->second; + for (PropertyList::iterator i = properties_.begin(); i != properties_.end(); + ++i) { + delete i->second; + } + // Unregister ourselves if we were bound to a frame. if (bound_to_frame_) WebBindings::unregisterObject(NPVARIANT_TO_OBJECT(self_variant_)); @@ -181,45 +225,76 @@ bool CppBoundClass::Invoke(NPIdentifier ident, } bool CppBoundClass::GetProperty(NPIdentifier ident, NPVariant* result) const { - PropertyList::const_iterator prop = properties_.find(ident); - if (prop == properties_.end()) { + PropertyList::const_iterator callback = properties_.find(ident); + if (callback == properties_.end()) { VOID_TO_NPVARIANT(*result); return false; } - const CppVariant* cpp_value = (*prop).second; - cpp_value->CopyToNPVariant(result); + CppVariant cpp_value; + if (!callback->second->GetValue(&cpp_value)) + return false; + cpp_value.CopyToNPVariant(result); return true; } bool CppBoundClass::SetProperty(NPIdentifier ident, - const NPVariant* value) { - PropertyList::iterator prop = properties_.find(ident); - if (prop == properties_.end()) + const NPVariant* value) { + PropertyList::iterator callback = properties_.find(ident); + if (callback == properties_.end()) return false; - (*prop).second->Set(*value); - return true; + CppVariant cpp_value; + cpp_value.Set(*value); + return (*callback).second->SetValue(cpp_value); } -void CppBoundClass::BindCallback(std::string name, Callback* callback) { - // NPUTF8 is a typedef for char, so this cast is safe. - NPIdentifier ident = WebBindings::getStringIdentifier((const NPUTF8*)name.c_str()); +void CppBoundClass::BindCallback(const std::string& name, Callback* callback) { + NPIdentifier ident = WebBindings::getStringIdentifier(name.c_str()); MethodList::iterator old_callback = methods_.find(ident); - if (old_callback != methods_.end()) + if (old_callback != methods_.end()) { delete old_callback->second; + if (callback == NULL) { + methods_.erase(old_callback); + return; + } + } + methods_[ident] = callback; } -void CppBoundClass::BindProperty(std::string name, CppVariant* prop) { - // NPUTF8 is a typedef for char, so this cast is safe. - NPIdentifier ident = WebBindings::getStringIdentifier((const NPUTF8*)name.c_str()); - properties_[ident] = prop; +void CppBoundClass::BindGetterCallback(const std::string& name, + GetterCallback* callback) { + PropertyCallback* property_callback = callback == NULL ? + NULL : new GetterPropertyCallback(callback); + + BindProperty(name, property_callback); +} + +void CppBoundClass::BindProperty(const std::string& name, CppVariant* prop) { + PropertyCallback* property_callback = prop == NULL ? + NULL : new CppVariantPropertyCallback(prop); + + BindProperty(name, property_callback); +} + +void CppBoundClass::BindProperty(const std::string& name, + PropertyCallback* callback) { + NPIdentifier ident = WebBindings::getStringIdentifier(name.c_str()); + PropertyList::iterator old_callback = properties_.find(ident); + if (old_callback != properties_.end()) { + delete old_callback->second; + if (callback == NULL) { + properties_.erase(old_callback); + return; + } + } + + properties_[ident] = callback; } -bool CppBoundClass::IsMethodRegistered(std::string name) const { - // NPUTF8 is a typedef for char, so this cast is safe. - NPIdentifier ident = WebBindings::getStringIdentifier((const NPUTF8*)name.c_str()); +bool CppBoundClass::IsMethodRegistered(const std::string& name) const { + NPIdentifier ident = WebBindings::getStringIdentifier(name.c_str()); MethodList::const_iterator callback = methods_.find(ident); return (callback != methods_.end()); } |