Index: content/shell/renderer/test_runner/CppBoundClass.h |
diff --git a/content/shell/renderer/test_runner/CppBoundClass.h b/content/shell/renderer/test_runner/CppBoundClass.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..f3870fd5804d15a0aa6b325283352d1fd8d29e8b |
--- /dev/null |
+++ b/content/shell/renderer/test_runner/CppBoundClass.h |
@@ -0,0 +1,251 @@ |
+// Copyright 2013 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+/* |
+ * Copyright (C) 2010 Google Inc. All rights reserved. |
+ * Copyright (C) 2009 Pawel Hajdan (phajdan.jr@chromium.org) |
+ * |
+ * Redistribution and use in source and binary forms, with or without |
+ * modification, are permitted provided that the following conditions are |
+ * met: |
+ * |
+ * * Redistributions of source code must retain the above copyright |
+ * notice, this list of conditions and the following disclaimer. |
+ * * Redistributions in binary form must reproduce the above |
+ * copyright notice, this list of conditions and the following disclaimer |
+ * in the documentation and/or other materials provided with the |
+ * distribution. |
+ * * Neither the name of Google Inc. nor the names of its |
+ * contributors may be used to endorse or promote products derived from |
+ * this software without specific prior written permission. |
+ * |
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
+ */ |
+ |
+/* |
+ CppBoundClass class: |
+ This base class serves as a parent for C++ classes designed to be bound to |
+ JavaScript objects. |
+ |
+ Subclasses should define the constructor to build the property and method |
+ lists needed to bind this class to a JS object. They should also declare |
+ and define member variables and methods to be exposed to JS through |
+ that object. |
+*/ |
+ |
+#ifndef CppBoundClass_h |
+#define CppBoundClass_h |
+ |
+#include <map> |
+#include <vector> |
+ |
+#include "content/shell/renderer/test_runner/CppVariant.h" |
+#include "content/shell/renderer/test_runner/WebScopedPtr.h" |
+#include "third_party/WebKit/public/platform/WebNonCopyable.h" |
+ |
+namespace blink { |
+class WebFrame; |
+class WebString; |
+} |
+ |
+namespace WebTestRunner { |
+ |
+typedef std::vector<CppVariant> CppArgumentList; |
+ |
+// CppBoundClass lets you map Javascript method calls and property accesses |
+// directly to C++ method calls and CppVariant* variable access. |
+class CppBoundClass : public blink::WebNonCopyable { |
+public: |
+ class PropertyCallback { |
+ public: |
+ virtual ~PropertyCallback() { } |
+ |
+ // Sets |value| to the value of the property. Returns false in case of |
+ // failure. |value| is always non-0. |
+ virtual bool getValue(CppVariant* result) = 0; |
+ |
+ // sets the property value to |value|. Returns false in case of failure. |
+ virtual bool setValue(const CppVariant&) = 0; |
+ }; |
+ |
+ // Callback class for "void function(CppVariant*)" |
+ class GetterCallback { |
+ public: |
+ virtual ~GetterCallback() { } |
+ virtual void run(CppVariant*) = 0; |
+ }; |
+ |
+ // The constructor should call BindMethod, BindProperty, and |
+ // SetFallbackMethod as needed to set up the methods, properties, and |
+ // fallback method. |
+ CppBoundClass() : m_boundToFrame(false) { } |
+ virtual ~CppBoundClass(); |
+ |
+ // Return a CppVariant representing this class, for use with BindProperty(). |
+ // The variant type is guaranteed to be NPVariantType_Object. |
+ CppVariant* getAsCppVariant(); |
+ |
+ // Given a WebFrame, BindToJavascript builds the NPObject that will represent |
+ // the class and binds it to the frame's window under the given name. This |
+ // should generally be called from the WebView delegate's |
+ // WindowObjectCleared(). A class so bound will be accessible to JavaScript |
+ // as window.<classname>. The owner of the CppBoundObject is responsible for |
+ // keeping the object around while the frame is alive, and for destroying it |
+ // afterwards. |
+ void bindToJavascript(blink::WebFrame*, const blink::WebString& classname); |
+ |
+ // Used by a test. Returns true if a method with the specified name exists, |
+ // regardless of whether a fallback is registered. |
+ bool isMethodRegistered(const std::string&) const; |
+ |
+protected: |
+ // Callback for "void function(const CppArguemntList&, CppVariant*)" |
+ class Callback { |
+ public: |
+ virtual ~Callback() { } |
+ virtual void run(const CppArgumentList&, CppVariant*) = 0; |
+ }; |
+ |
+ // Callback for "void T::method(const CppArguemntList&, CppVariant*)" |
+ template <class T> class MemberCallback : public Callback { |
+ public: |
+ typedef void (T::*MethodType)(const CppArgumentList&, CppVariant*); |
+ MemberCallback(T* object, MethodType method) |
+ : m_object(object) |
+ , m_method(method) { } |
+ virtual ~MemberCallback() { } |
+ |
+ virtual void run(const CppArgumentList& arguments, CppVariant* result) |
+ { |
+ (m_object->*m_method)(arguments, result); |
+ } |
+ |
+ private: |
+ T* m_object; |
+ MethodType m_method; |
+ }; |
+ |
+ // Callback class for "void T::method(CppVariant*)" |
+ template <class T> class MemberGetterCallback : public GetterCallback { |
+ public: |
+ typedef void (T::*MethodType)(CppVariant*); |
+ MemberGetterCallback(T* object, MethodType method) |
+ : m_object(object) |
+ , m_method(method) { } |
+ virtual ~MemberGetterCallback() { } |
+ |
+ virtual void run(CppVariant* result) { (m_object->*m_method)(result); } |
+ |
+ private: |
+ T* m_object; |
+ MethodType m_method; |
+ }; |
+ |
+ // Bind the Javascript method called the string parameter to the C++ method. |
+ void bindCallback(const std::string&, Callback*); |
+ |
+ // A wrapper for bindCallback, to simplify the common case of binding a |
+ // method on the current object. Though not verified here, the method parameter |
+ // must be a method of this CppBoundClass subclass. |
+ template<class T> |
+ void bindMethod(const std::string& name, void (T::*method)(const CppArgumentList&, CppVariant*)) |
+ { |
+ Callback* callback = new MemberCallback<T>(static_cast<T*>(this), method); |
+ bindCallback(name, callback); |
+ } |
+ |
+ // Bind Javascript property |name| to the C++ getter callback |callback|. |
+ // This can be used to create read-only properties. |
+ void bindGetterCallback(const std::string&, WebScopedPtr<GetterCallback>); |
+ |
+ // A wrapper for BindGetterCallback, to simplify the common case of binding a |
+ // property on the current object. Though not verified here, the method parameter |
+ // must be a method of this CppBoundClass subclass. |
+ template<class T> |
+ void bindProperty(const std::string& name, void (T::*method)(CppVariant*)) |
+ { |
+ WebScopedPtr<GetterCallback> callback(new MemberGetterCallback<T>(static_cast<T*>(this), method)); |
+ bindGetterCallback(name, callback); |
+ } |
+ |
+ // Bind the Javascript property called |name| to a CppVariant. |
+ void bindProperty(const std::string&, CppVariant*); |
+ |
+ // Bind Javascript property called |name| to a PropertyCallback. |
+ // CppBoundClass assumes control over the life time of the callback. |
+ void bindProperty(const std::string&, PropertyCallback*); |
+ |
+ // Set the fallback callback, which is called when when a callback is |
+ // invoked that isn't bound. |
+ // If it is 0 (its default value), a JavaScript exception is thrown in |
+ // that case (as normally expected). If non 0, the fallback method is |
+ // invoked and the script continues its execution. |
+ // Passing 0 clears out any existing binding. |
+ // It is used for tests and should probably only be used in such cases |
+ // as it may cause unexpected behaviors (a JavaScript object with a |
+ // fallback always returns true when checked for a method's |
+ // existence). |
+ void bindFallbackCallback(WebScopedPtr<Callback> fallbackCallback) |
+ { |
+ m_fallbackCallback = fallbackCallback; |
+ } |
+ |
+ // A wrapper for BindFallbackCallback, to simplify the common case of |
+ // binding a method on the current object. Though not verified here, |
+ // |method| must be a method of this CppBoundClass subclass. |
+ // Passing 0 for |method| clears out any existing binding. |
+ template<class T> |
+ void bindFallbackMethod(void (T::*method)(const CppArgumentList&, CppVariant*)) |
+ { |
+ if (method) |
+ bindFallbackCallback(WebScopedPtr<Callback>(new MemberCallback<T>(static_cast<T*>(this), method))); |
+ else |
+ bindFallbackCallback(WebScopedPtr<Callback>()); |
+ } |
+ |
+ // Some fields are protected because some tests depend on accessing them, |
+ // but otherwise they should be considered private. |
+ |
+ typedef std::map<NPIdentifier, PropertyCallback*> PropertyList; |
+ typedef std::map<NPIdentifier, Callback*> MethodList; |
+ // These maps associate names with property and method pointers to be |
+ // exposed to JavaScript. |
+ PropertyList m_properties; |
+ MethodList m_methods; |
+ |
+ // The callback gets invoked when a call is made to an nonexistent method. |
+ WebScopedPtr<Callback> m_fallbackCallback; |
+ |
+private: |
+ // NPObject callbacks. |
+ friend struct CppNPObject; |
+ bool hasMethod(NPIdentifier) const; |
+ bool invoke(NPIdentifier, const NPVariant* args, size_t argCount, |
+ NPVariant* result); |
+ bool hasProperty(NPIdentifier) const; |
+ bool getProperty(NPIdentifier, NPVariant* result) const; |
+ bool setProperty(NPIdentifier, const NPVariant*); |
+ |
+ // A lazily-initialized CppVariant representing this class. We retain 1 |
+ // reference to this object, and it is released on deletion. |
+ CppVariant m_selfVariant; |
+ |
+ // True if our np_object has been bound to a WebFrame, in which case it must |
+ // be unregistered with V8 when we delete it. |
+ bool m_boundToFrame; |
+}; |
+ |
+} |
+ |
+#endif // CppBoundClass_h |