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