Rename WebKitTools to Tools
[WebKit-https.git] / Tools / DumpRenderTree / chromium / CppBoundClass.h
1 /*
2  * Copyright (C) 2010 Google Inc. All rights reserved.
3  * Copyright (C) 2009 Pawel Hajdan (phajdan.jr@chromium.org)
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  *     * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *     * Redistributions in binary form must reproduce the above
12  * copyright notice, this list of conditions and the following disclaimer
13  * in the documentation and/or other materials provided with the
14  * distribution.
15  *     * Neither the name of Google Inc. nor the names of its
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31
32 /*
33   CppBoundClass class:
34   This base class serves as a parent for C++ classes designed to be bound to
35   JavaScript objects.
36
37   Subclasses should define the constructor to build the property and method
38   lists needed to bind this class to a JS object.  They should also declare
39   and define member variables and methods to be exposed to JS through
40   that object.
41 */
42
43 #ifndef CppBoundClass_h
44 #define CppBoundClass_h
45
46 #include "CppVariant.h"
47 #include <wtf/HashMap.h>
48 #include <wtf/Noncopyable.h>
49 #include <wtf/OwnPtr.h>
50 #include <wtf/Vector.h>
51
52 namespace WebKit {
53 class WebFrame;
54 class WebString;
55 }
56
57 typedef Vector<CppVariant> CppArgumentList;
58
59 // CppBoundClass lets you map Javascript method calls and property accesses
60 // directly to C++ method calls and CppVariant* variable access.
61 class CppBoundClass : public Noncopyable {
62 public:
63     class PropertyCallback {
64     public:
65         virtual ~PropertyCallback() { }
66
67         // Sets |value| to the value of the property. Returns false in case of
68         // failure. |value| is always non-0.
69         virtual bool getValue(CppVariant* result) = 0;
70
71         // sets the property value to |value|. Returns false in case of failure.
72         virtual bool setValue(const CppVariant&) = 0;
73     };
74
75     // Callback class for "void function(CppVariant*)"
76     class GetterCallback {
77     public:
78         virtual ~GetterCallback() {}
79         virtual void run(CppVariant*) = 0;
80     };
81
82     // The constructor should call BindMethod, BindProperty, and
83     // SetFallbackMethod as needed to set up the methods, properties, and
84     // fallback method.
85     CppBoundClass() : m_boundToFrame(false) {}
86     virtual ~CppBoundClass();
87
88     // Return a CppVariant representing this class, for use with BindProperty().
89     // The variant type is guaranteed to be NPVariantType_Object.
90     CppVariant* getAsCppVariant();
91
92     // Given a WebFrame, BindToJavascript builds the NPObject that will represent
93     // the class and binds it to the frame's window under the given name.  This
94     // should generally be called from the WebView delegate's
95     // WindowObjectCleared(). A class so bound will be accessible to JavaScript
96     // as window.<classname>. The owner of the CppBoundObject is responsible for
97     // keeping the object around while the frame is alive, and for destroying it
98     // afterwards.
99     void bindToJavascript(WebKit::WebFrame*, const WebKit::WebString& classname);
100
101     // Used by a test.  Returns true if a method with name |name| exists,
102     // regardless of whether a fallback is registered.
103     bool isMethodRegistered(const std::string&) const;
104
105 protected:
106     // Callback for "void function(const CppArguemntList&, CppVariant*)"
107     class Callback {
108     public:
109         virtual ~Callback() {}
110         virtual void run(const CppArgumentList&, CppVariant*) = 0;
111     };
112
113     // Callback for "void T::method(const CppArguemntList&, CppVariant*)"
114     template <class T> class MemberCallback : public Callback {
115     public:
116         typedef void (T::*MethodType)(const CppArgumentList&, CppVariant*);
117         MemberCallback(T* object, MethodType method)
118             : m_object(object)
119             , m_method(method) {}
120         virtual ~MemberCallback() {}
121
122         virtual void run(const CppArgumentList& arguments, CppVariant* result)
123         {
124             (m_object->*m_method)(arguments, result);
125         }
126     private:
127         T* m_object;
128         MethodType m_method;
129     };
130
131     // Callback class for "void T::method(CppVariant*)"
132     template <class T> class MemberGetterCallback : public GetterCallback {
133     public:
134         typedef void (T::*MethodType)(CppVariant*);
135         MemberGetterCallback(T* object, MethodType method)
136             : m_object(object)
137             , m_method(method) {}
138         virtual ~MemberGetterCallback() {}
139
140         virtual void run(CppVariant* result) { (m_object->*m_method)(result); }
141     private:
142         T* m_object;
143         MethodType m_method;
144     };
145
146     // Bind the Javascript method called the string parameter to the C++ method.
147     void bindCallback(const std::string&, Callback*);
148
149     // A wrapper for bindCallback, to simplify the common case of binding a
150     // method on the current object.  Though not verified here, |method|
151     // must be a method of this CppBoundClass subclass.
152     template<class T>
153     void bindMethod(const std::string& name, void (T::*method)(const CppArgumentList&, CppVariant*))
154     {
155         Callback* callback = new MemberCallback<T>(static_cast<T*>(this), method);
156         bindCallback(name, callback);
157     }
158
159     // Bind Javascript property |name| to the C++ getter callback |callback|.
160     // This can be used to create read-only properties.
161     void bindGetterCallback(const std::string&, GetterCallback*);
162
163     // A wrapper for BindGetterCallback, to simplify the common case of binding a
164     // property on the current object.  Though not verified here, |method|
165     // must be a method of this CppBoundClass subclass.
166     template<class T>
167     void bindProperty(const std::string& name, void (T::*method)(CppVariant*))
168     {
169         GetterCallback* callback = new MemberGetterCallback<T>(static_cast<T*>(this), method);
170         bindGetterCallback(name, callback);
171     }
172
173     // Bind the Javascript property called |name| to a CppVariant.
174     void bindProperty(const std::string&, CppVariant*);
175
176     // Bind Javascript property called |name| to a PropertyCallback.
177     // CppBoundClass assumes control over the life time of the callback.
178     void bindProperty(const std::string&, PropertyCallback*);
179
180     // Set the fallback callback, which is called when when a callback is
181     // invoked that isn't bound.
182     // If it is 0 (its default value), a JavaScript exception is thrown in
183     // that case (as normally expected). If non 0, the fallback method is
184     // invoked and the script continues its execution.
185     // Passing 0 clears out any existing binding.
186     // It is used for tests and should probably only be used in such cases
187     // as it may cause unexpected behaviors (a JavaScript object with a
188     // fallback always returns true when checked for a method's
189     // existence).
190     void bindFallbackCallback(Callback* fallbackCallback)
191     {
192         m_fallbackCallback.set(fallbackCallback);
193     }
194
195     // A wrapper for BindFallbackCallback, to simplify the common case of
196     // binding a method on the current object.  Though not verified here,
197     // |method| must be a method of this CppBoundClass subclass.
198     // Passing 0 for |method| clears out any existing binding.
199     template<class T>
200     void bindFallbackMethod(void (T::*method)(const CppArgumentList&, CppVariant*))
201     {
202         if (method) {
203             Callback* callback = new MemberCallback<T>(static_cast<T*>(this), method);
204             bindFallbackCallback(callback);
205         } else
206             bindFallbackCallback(0);
207     }
208
209     // Some fields are protected because some tests depend on accessing them,
210     // but otherwise they should be considered private.
211
212     typedef HashMap<NPIdentifier, PropertyCallback*> PropertyList;
213     typedef HashMap<NPIdentifier, Callback*> MethodList;
214     // These maps associate names with property and method pointers to be
215     // exposed to JavaScript.
216     PropertyList m_properties;
217     MethodList m_methods;
218
219     // The callback gets invoked when a call is made to an nonexistent method.
220     OwnPtr<Callback> m_fallbackCallback;
221
222 private:
223     // NPObject callbacks.
224     friend struct CppNPObject;
225     bool hasMethod(NPIdentifier) const;
226     bool invoke(NPIdentifier, const NPVariant* args, size_t argCount,
227                 NPVariant* result);
228     bool hasProperty(NPIdentifier) const;
229     bool getProperty(NPIdentifier, NPVariant* result) const;
230     bool setProperty(NPIdentifier, const NPVariant*);
231
232     // A lazily-initialized CppVariant representing this class.  We retain 1
233     // reference to this object, and it is released on deletion.
234     CppVariant m_selfVariant;
235
236     // True if our np_object has been bound to a WebFrame, in which case it must
237     // be unregistered with V8 when we delete it.
238     bool m_boundToFrame;
239 };
240
241 #endif // CppBoundClass_h