Home | History | Annotate | Download | only in renderer
      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 WebKit {
     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:
     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(WebKit::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).
    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