1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 /* 6 CppBoundClass class: 7 This base class serves as a parent for C++ classes designed to be bound to 8 JavaScript objects. 9 10 Subclasses should define the constructor to build the property and method 11 lists needed to bind this class to a JS object. They should also declare 12 and define member variables and methods to be exposed to JS through 13 that object. 14 15 See cpp_binding_example.{h|cc} for an example. 16 */ 17 18 #ifndef WEBKIT_RENDERER_CPP_BOUND_CLASS_H_ 19 #define WEBKIT_RENDERER_CPP_BOUND_CLASS_H_ 20 21 #include <map> 22 #include <vector> 23 24 #include "base/callback.h" 25 #include "webkit/renderer/cpp_variant.h" 26 #include "webkit/renderer/webkit_renderer_export.h" 27 28 namespace blink { 29 class WebFrame; 30 } 31 32 namespace webkit_glue { 33 34 typedef std::vector<CppVariant> CppArgumentList; 35 36 // CppBoundClass lets you map Javascript method calls and property accesses 37 // directly to C++ method calls and CppVariant* variable access. 38 class WEBKIT_RENDERER_EXPORT CppBoundClass { 39 public: 40 class PropertyCallback { 41 public: ~PropertyCallback()42 virtual ~PropertyCallback() { } 43 44 // Sets |value| to the value of the property. Returns false in case of 45 // failure. |value| is always non-NULL. 46 virtual bool GetValue(CppVariant* value) = 0; 47 48 // sets the property value to |value|. Returns false in case of failure. 49 virtual bool SetValue(const CppVariant& value) = 0; 50 }; 51 52 // The constructor should call BindCallback, BindProperty, and 53 // BindFallbackCallback as needed to set up the methods, properties, and 54 // fallback method. 55 CppBoundClass(); 56 virtual ~CppBoundClass(); 57 58 // Return a CppVariant representing this class, for use with BindProperty(). 59 // The variant type is guaranteed to be NPVariantType_Object. 60 CppVariant* GetAsCppVariant(); 61 62 // Given a WebFrame, BindToJavascript builds the NPObject that will represent 63 // this CppBoundClass object and binds it to the frame's window under the 64 // given name. This should generally be called from the WebView delegate's 65 // WindowObjectCleared(). This CppBoundClass object will be accessible to 66 // JavaScript as window.<classname>. The owner of this CppBoundClass object is 67 // responsible for keeping it around while the frame is alive, and for 68 // destroying it afterwards. 69 void BindToJavascript(blink::WebFrame* frame, const std::string& classname); 70 71 // The type of callbacks. 72 typedef base::Callback<void(const CppArgumentList&, CppVariant*)> Callback; 73 typedef base::Callback<void(CppVariant*)> GetterCallback; 74 75 // Used by a test. Returns true if a method with name |name| exists, 76 // regardless of whether a fallback is registered. 77 bool IsMethodRegistered(const std::string& name) const; 78 79 protected: 80 // Bind the Javascript method called |name| to the C++ callback |callback|. 81 void BindCallback(const std::string& name, const Callback& callback); 82 83 // Bind Javascript property |name| to the C++ getter callback |callback|. 84 // This can be used to create read-only properties. 85 void BindGetterCallback(const std::string& name, 86 const GetterCallback& callback); 87 88 // Bind the Javascript property called |name| to a CppVariant |prop|. 89 void BindProperty(const std::string& name, CppVariant* prop); 90 91 // Bind Javascript property called |name| to a PropertyCallback |callback|. 92 // CppBoundClass assumes control over the life time of the |callback|. 93 void BindProperty(const std::string& name, PropertyCallback* callback); 94 95 // Set the fallback callback, which is called when when a callback is 96 // invoked that isn't bound. 97 // If it is NULL (its default value), a JavaScript exception is thrown in 98 // that case (as normally expected). If non NULL, the fallback method is 99 // invoked and the script continues its execution. 100 // Passing NULL for |callback| clears out any existing binding. 101 // It is used for tests and should probably only be used in such cases 102 // as it may cause unexpected behaviors (a JavaScript object with a 103 // fallback always returns true when checked for a method's 104 // existence). BindFallbackCallback(const Callback & fallback_callback)105 void BindFallbackCallback(const Callback& fallback_callback) { 106 fallback_callback_ = fallback_callback; 107 } 108 109 // Some fields are protected because some tests depend on accessing them, 110 // but otherwise they should be considered private. 111 112 typedef std::map<NPIdentifier, PropertyCallback*> PropertyList; 113 typedef std::map<NPIdentifier, Callback> MethodList; 114 // These maps associate names with property and method pointers to be 115 // exposed to JavaScript. 116 PropertyList properties_; 117 MethodList methods_; 118 119 // The callback gets invoked when a call is made to an nonexistent method. 120 Callback fallback_callback_; 121 122 private: 123 // NPObject callbacks. 124 friend struct CppNPObject; 125 bool HasMethod(NPIdentifier ident) const; 126 bool Invoke(NPIdentifier ident, const NPVariant* args, size_t arg_count, 127 NPVariant* result); 128 bool HasProperty(NPIdentifier ident) const; 129 bool GetProperty(NPIdentifier ident, NPVariant* result) const; 130 bool SetProperty(NPIdentifier ident, const NPVariant* value); 131 132 // A lazily-initialized CppVariant representing this class. We retain 1 133 // reference to this object, and it is released on deletion. 134 CppVariant self_variant_; 135 136 // TODO(wez): Remove once crrev.com/14019005 lands. 137 bool bound_to_frame_; 138 139 // Dummy NPP to use to register as owner for NPObjects. 140 scoped_ptr<NPP_t> npp_; 141 142 DISALLOW_COPY_AND_ASSIGN(CppBoundClass); 143 }; 144 145 } // namespace webkit_glue 146 147 #endif // WEBKIT_RENDERER_CPP_BOUND_CLASS_H_ 148