15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CppBoundClass class:
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  This base class serves as a parent for C++ classes designed to be bound to
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  JavaScript objects.
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Subclasses should define the constructor to build the property and method
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  lists needed to bind this class to a JS object.  They should also declare
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  and define member variables and methods to be exposed to JS through
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  that object.
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  See cpp_binding_example.{h|cc} for an example.
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#ifndef WEBKIT_RENDERER_CPP_BOUND_CLASS_H_
19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#define WEBKIT_RENDERER_CPP_BOUND_CLASS_H_
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map>
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h"
25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "webkit/renderer/cpp_variant.h"
26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "webkit/renderer/webkit_renderer_export.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace blink {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class WebFrame;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace webkit_glue {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef std::vector<CppVariant> CppArgumentList;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// CppBoundClass lets you map Javascript method calls and property accesses
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// directly to C++ method calls and CppVariant* variable access.
38868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class WEBKIT_RENDERER_EXPORT CppBoundClass {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class PropertyCallback {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual ~PropertyCallback() { }
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sets |value| to the value of the property. Returns false in case of
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // failure. |value| is always non-NULL.
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual bool GetValue(CppVariant* value) = 0;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // sets the property value to |value|. Returns false in case of failure.
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual bool SetValue(const CppVariant& value) = 0;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The constructor should call BindCallback, BindProperty, and
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // BindFallbackCallback as needed to set up the methods, properties, and
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fallback method.
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CppBoundClass();
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~CppBoundClass();
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Return a CppVariant representing this class, for use with BindProperty().
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The variant type is guaranteed to be NPVariantType_Object.
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CppVariant* GetAsCppVariant();
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Given a WebFrame, BindToJavascript builds the NPObject that will represent
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // this CppBoundClass object and binds it to the frame's window under the
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // given name.  This should generally be called from the WebView delegate's
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // WindowObjectCleared(). This CppBoundClass object will be accessible to
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // JavaScript as window.<classname>. The owner of this CppBoundClass object is
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // responsible for keeping it around while the frame is alive, and for
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // destroying it afterwards.
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void BindToJavascript(blink::WebFrame* frame, const std::string& classname);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The type of callbacks.
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef base::Callback<void(const CppArgumentList&, CppVariant*)> Callback;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef base::Callback<void(CppVariant*)> GetterCallback;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Used by a test.  Returns true if a method with name |name| exists,
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // regardless of whether a fallback is registered.
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsMethodRegistered(const std::string& name) const;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Bind the Javascript method called |name| to the C++ callback |callback|.
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void BindCallback(const std::string& name, const Callback& callback);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Bind Javascript property |name| to the C++ getter callback |callback|.
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This can be used to create read-only properties.
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void BindGetterCallback(const std::string& name,
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          const GetterCallback& callback);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Bind the Javascript property called |name| to a CppVariant |prop|.
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void BindProperty(const std::string& name, CppVariant* prop);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Bind Javascript property called |name| to a PropertyCallback |callback|.
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CppBoundClass assumes control over the life time of the |callback|.
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void BindProperty(const std::string& name, PropertyCallback* callback);
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set the fallback callback, which is called when when a callback is
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // invoked that isn't bound.
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If it is NULL (its default value), a JavaScript exception is thrown in
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that case (as normally expected). If non NULL, the fallback method is
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // invoked and the script continues its execution.
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Passing NULL for |callback| clears out any existing binding.
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It is used for tests and should probably only be used in such cases
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // as it may cause unexpected behaviors (a JavaScript object with a
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fallback always returns true when checked for a method's
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // existence).
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void BindFallbackCallback(const Callback& fallback_callback) {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fallback_callback_ = fallback_callback;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Some fields are protected because some tests depend on accessing them,
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // but otherwise they should be considered private.
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::map<NPIdentifier, PropertyCallback*> PropertyList;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::map<NPIdentifier, Callback> MethodList;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // These maps associate names with property and method pointers to be
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // exposed to JavaScript.
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PropertyList properties_;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MethodList methods_;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The callback gets invoked when a call is made to an nonexistent method.
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Callback fallback_callback_;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NPObject callbacks.
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend struct CppNPObject;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool HasMethod(NPIdentifier ident) const;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool Invoke(NPIdentifier ident, const NPVariant* args, size_t arg_count,
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              NPVariant* result);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool HasProperty(NPIdentifier ident) const;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool GetProperty(NPIdentifier ident, NPVariant* result) const;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool SetProperty(NPIdentifier ident, const NPVariant* value);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A lazily-initialized CppVariant representing this class.  We retain 1
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // reference to this object, and it is released on deletion.
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CppVariant self_variant_;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // TODO(wez): Remove once crrev.com/14019005 lands.
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool bound_to_frame_;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Dummy NPP to use to register as owner for NPObjects.
14090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<NPP_t> npp_;
14190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(CppBoundClass);
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace webkit_glue
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif  // WEBKIT_RENDERER_CPP_BOUND_CLASS_H_
148