1dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block/*
2dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * Copyright (C) 2010 Google Inc. All rights reserved.
3dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * Copyright (C) 2009 Pawel Hajdan (phajdan.jr@chromium.org)
4dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block *
5dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * Redistribution and use in source and binary forms, with or without
6dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * modification, are permitted provided that the following conditions are
7dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * met:
8dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block *
9dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block *     * Redistributions of source code must retain the above copyright
10dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * notice, this list of conditions and the following disclaimer.
11dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block *     * Redistributions in binary form must reproduce the above
12dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * copyright notice, this list of conditions and the following disclaimer
13dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * in the documentation and/or other materials provided with the
14dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * distribution.
15dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block *     * Neither the name of Google Inc. nor the names of its
16dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * contributors may be used to endorse or promote products derived from
17dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * this software without specific prior written permission.
18dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block *
19dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block */
31dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
32dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block// This file contains definitions for CppBoundClass
33dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
34dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block// Here's the control flow of a JS method getting forwarded to a class.
35dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block// - Something calls our NPObject with a function like "Invoke".
36dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block// - CppNPObject's static invoke() function forwards it to its attached
37dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block//   CppBoundClass's invoke() method.
38dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block// - CppBoundClass has then overridden invoke() to look up the function
39dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block//   name in its internal map of methods, and then calls the appropriate
40dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block//   method.
41dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
42dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "config.h"
43dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "CppBoundClass.h"
44dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
45a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "WebBindings.h"
46a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "WebFrame.h"
47a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "WebString.h"
48dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include <wtf/Assertions.h>
49dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include <wtf/OwnPtr.h>
50dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
51dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockusing namespace WebKit;
52dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockusing namespace std;
53dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
54dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockclass CppVariantPropertyCallback : public CppBoundClass::PropertyCallback {
55dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockpublic:
56dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    CppVariantPropertyCallback(CppVariant* value) : m_value(value) { }
57dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
58dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    virtual bool getValue(CppVariant* value)
59dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
60dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        value->set(*m_value);
61dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return true;
62dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
63dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
64dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    virtual bool setValue(const CppVariant& value)
65dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
66dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        m_value->set(value);
67dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return true;
68dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
69dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
70dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockprivate:
71dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    CppVariant* m_value;
72dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block};
73dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
74dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockclass GetterPropertyCallback : public CppBoundClass::PropertyCallback {
75dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockpublic:
76dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    GetterPropertyCallback(CppBoundClass::GetterCallback* callback)
77dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        : m_callback(callback) { }
78dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
79dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    virtual bool getValue(CppVariant* value)
80dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
81dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        m_callback->run(value);
82dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return true;
83dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
84dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
85dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    virtual bool setValue(const CppVariant& value) { return false; }
86dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
87dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockprivate:
88dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    OwnPtr<CppBoundClass::GetterCallback> m_callback;
89dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block};
90dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
91dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block// Our special NPObject type.  We extend an NPObject with a pointer to a
92dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block// CppBoundClass, which is just a C++ interface that we forward all NPObject
93dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block// callbacks to.
94dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockstruct CppNPObject {
95dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    NPObject parent; // This must be the first field in the struct.
96dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    CppBoundClass* boundClass;
97dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
98dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    //
99dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // All following objects and functions are static, and just used to interface
100dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // with NPObject/NPClass.
101dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    //
102dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
103dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // An NPClass associates static functions of CppNPObject with the
104dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // function pointers used by the JS runtime.
105dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    static NPClass npClass;
106dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
107dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // Allocate a new NPObject with the specified class.
108dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    static NPObject* allocate(NPP, NPClass*);
109dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
110dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // Free an object.
111dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    static void deallocate(NPObject*);
112dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
113dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // Returns true if the C++ class associated with this NPObject exposes the
114dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // given property.  Called by the JS runtime.
115dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    static bool hasProperty(NPObject*, NPIdentifier);
116dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
117dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // Returns true if the C++ class associated with this NPObject exposes the
118dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // given method.  Called by the JS runtime.
119dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    static bool hasMethod(NPObject*, NPIdentifier);
120dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
121dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // If the given method is exposed by the C++ class associated with this
122dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // NPObject, invokes it with the given arguments and returns a result.  Otherwise,
123dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // returns "undefined" (in the JavaScript sense).  Called by the JS runtime.
124dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    static bool invoke(NPObject*, NPIdentifier,
125dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                       const NPVariant* arguments, uint32_t argumentCount,
126dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                       NPVariant* result);
127dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
128dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // If the given property is exposed by the C++ class associated with this
129dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // NPObject, returns its value.  Otherwise, returns "undefined" (in the
130dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // JavaScript sense).  Called by the JS runtime.
131dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    static bool getProperty(NPObject*, NPIdentifier, NPVariant* result);
132dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
133dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // If the given property is exposed by the C++ class associated with this
134dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // NPObject, sets its value.  Otherwise, does nothing. Called by the JS
135dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // runtime.
136dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    static bool setProperty(NPObject*, NPIdentifier, const NPVariant* value);
137dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block};
138dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
139dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block// Build CppNPObject's static function pointers into an NPClass, for use
140dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block// in constructing NPObjects for the C++ classes.
141dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockNPClass CppNPObject::npClass = {
142dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    NP_CLASS_STRUCT_VERSION,
143dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    CppNPObject::allocate,
144dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    CppNPObject::deallocate,
145dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    /* NPInvalidateFunctionPtr */ 0,
146dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    CppNPObject::hasMethod,
147dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    CppNPObject::invoke,
148dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    /* NPInvokeDefaultFunctionPtr */ 0,
149dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    CppNPObject::hasProperty,
150dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    CppNPObject::getProperty,
151dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    CppNPObject::setProperty,
152dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    /* NPRemovePropertyFunctionPtr */ 0
153dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block};
154dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
155dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockNPObject* CppNPObject::allocate(NPP npp, NPClass* aClass)
156dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
157dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    CppNPObject* obj = new CppNPObject;
158dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // obj->parent will be initialized by the NPObject code calling this.
159dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    obj->boundClass = 0;
160dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return &obj->parent;
161dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
162dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
163dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid CppNPObject::deallocate(NPObject* npObj)
164dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
165dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    CppNPObject* obj = reinterpret_cast<CppNPObject*>(npObj);
166dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    delete obj;
167dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
168dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
169dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockbool CppNPObject::hasMethod(NPObject* npObj, NPIdentifier ident)
170dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
171dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    CppNPObject* obj = reinterpret_cast<CppNPObject*>(npObj);
172dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return obj->boundClass->hasMethod(ident);
173dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
174dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
175dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockbool CppNPObject::hasProperty(NPObject* npObj, NPIdentifier ident)
176dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
177dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    CppNPObject* obj = reinterpret_cast<CppNPObject*>(npObj);
178dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return obj->boundClass->hasProperty(ident);
179dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
180dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
181dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockbool CppNPObject::invoke(NPObject* npObj, NPIdentifier ident,
182dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                         const NPVariant* arguments, uint32_t argumentCount,
183dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                         NPVariant* result)
184dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
185dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    CppNPObject* obj = reinterpret_cast<CppNPObject*>(npObj);
186dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return obj->boundClass->invoke(ident, arguments, argumentCount, result);
187dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
188dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
189dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockbool CppNPObject::getProperty(NPObject* npObj, NPIdentifier ident, NPVariant* result)
190dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
191dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    CppNPObject* obj = reinterpret_cast<CppNPObject*>(npObj);
192dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return obj->boundClass->getProperty(ident, result);
193dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
194dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
195dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockbool CppNPObject::setProperty(NPObject* npObj, NPIdentifier ident, const NPVariant* value)
196dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
197dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    CppNPObject* obj = reinterpret_cast<CppNPObject*>(npObj);
198dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return obj->boundClass->setProperty(ident, value);
199dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
200dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
201dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockCppBoundClass::~CppBoundClass()
202dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
203dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    for (MethodList::iterator i = m_methods.begin(); i != m_methods.end(); ++i)
204dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        delete i->second;
205dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
206dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    for (PropertyList::iterator i = m_properties.begin(); i != m_properties.end(); ++i)
207dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        delete i->second;
208dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
209dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // Unregister ourselves if we were bound to a frame.
210dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (m_boundToFrame)
211dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        WebBindings::unregisterObject(NPVARIANT_TO_OBJECT(m_selfVariant));
212dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
213dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
214dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockbool CppBoundClass::hasMethod(NPIdentifier ident) const
215dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
216dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return m_methods.find(ident) != m_methods.end();
217dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
218dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
219dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockbool CppBoundClass::hasProperty(NPIdentifier ident) const
220dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
221dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return m_properties.find(ident) != m_properties.end();
222dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
223dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
224dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockbool CppBoundClass::invoke(NPIdentifier ident,
225dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                           const NPVariant* arguments,
226dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                           size_t argumentCount,
227dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                           NPVariant* result) {
228dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    MethodList::const_iterator end = m_methods.end();
229dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    MethodList::const_iterator method = m_methods.find(ident);
230dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    Callback* callback;
231dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (method == end) {
232dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (!m_fallbackCallback.get()) {
233dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            VOID_TO_NPVARIANT(*result);
234dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return false;
235dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        }
236dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        callback = m_fallbackCallback.get();
237dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    } else
238dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        callback = (*method).second;
239dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
240dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // Build a CppArgumentList argument vector from the NPVariants coming in.
241dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    CppArgumentList cppArguments(argumentCount);
242dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    for (size_t i = 0; i < argumentCount; i++)
243dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        cppArguments[i].set(arguments[i]);
244dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
245dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    CppVariant cppResult;
246dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    callback->run(cppArguments, &cppResult);
247dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
248dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    cppResult.copyToNPVariant(result);
249dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return true;
250dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
251dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
252dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockbool CppBoundClass::getProperty(NPIdentifier ident, NPVariant* result) const
253dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
254dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    PropertyList::const_iterator callback = m_properties.find(ident);
255dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (callback == m_properties.end()) {
256dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        VOID_TO_NPVARIANT(*result);
257dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return false;
258dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
259dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
260dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    CppVariant cppValue;
261dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (!callback->second->getValue(&cppValue))
262dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return false;
263dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    cppValue.copyToNPVariant(result);
264dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return true;
265dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
266dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
267dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockbool CppBoundClass::setProperty(NPIdentifier ident, const NPVariant* value)
268dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
269dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    PropertyList::iterator callback = m_properties.find(ident);
270dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (callback == m_properties.end())
271dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return false;
272dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
273dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    CppVariant cppValue;
274dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    cppValue.set(*value);
275dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return (*callback).second->setValue(cppValue);
276dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
277dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
278dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid CppBoundClass::bindCallback(const string& name, Callback* callback)
279dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
280dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    NPIdentifier ident = WebBindings::getStringIdentifier(name.c_str());
281dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    MethodList::iterator oldCallback = m_methods.find(ident);
282dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (oldCallback != m_methods.end()) {
283dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        delete oldCallback->second;
284dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (!callback) {
285dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            m_methods.remove(oldCallback);
286dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return;
287dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        }
288dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
289dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
290dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    m_methods.set(ident, callback);
291dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
292dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
293dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid CppBoundClass::bindGetterCallback(const string& name, GetterCallback* callback)
294dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
295dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    PropertyCallback* propertyCallback = callback ? new GetterPropertyCallback(callback) : 0;
296dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    bindProperty(name, propertyCallback);
297dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
298dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
299dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid CppBoundClass::bindProperty(const string& name, CppVariant* prop)
300dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
301dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    PropertyCallback* propertyCallback = prop ? new CppVariantPropertyCallback(prop) : 0;
302dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    bindProperty(name, propertyCallback);
303dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
304dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
305dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid CppBoundClass::bindProperty(const string& name, PropertyCallback* callback)
306dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
307dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    NPIdentifier ident = WebBindings::getStringIdentifier(name.c_str());
308dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    PropertyList::iterator oldCallback = m_properties.find(ident);
309dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (oldCallback != m_properties.end()) {
310dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        delete oldCallback->second;
311dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (!callback) {
312dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            m_properties.remove(oldCallback);
313dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return;
314dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        }
315dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
316dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
317dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    m_properties.set(ident, callback);
318dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
319dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
320dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockbool CppBoundClass::isMethodRegistered(const string& name) const
321dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
322dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    NPIdentifier ident = WebBindings::getStringIdentifier(name.c_str());
323dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    MethodList::const_iterator callback = m_methods.find(ident);
324dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return callback != m_methods.end();
325dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
326dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
327dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockCppVariant* CppBoundClass::getAsCppVariant()
328dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
329dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (!m_selfVariant.isObject()) {
330dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        // Create an NPObject using our static NPClass.  The first argument (a
331dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        // plugin's instance handle) is passed through to the allocate function
332dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        // directly, and we don't use it, so it's ok to be 0.
333dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        NPObject* npObj = WebBindings::createObject(0, &CppNPObject::npClass);
334dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        CppNPObject* obj = reinterpret_cast<CppNPObject*>(npObj);
335dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        obj->boundClass = this;
336dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        m_selfVariant.set(npObj);
337dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        WebBindings::releaseObject(npObj); // CppVariant takes the reference.
338dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
339dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    ASSERT(m_selfVariant.isObject());
340dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return &m_selfVariant;
341dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
342dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
343dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid CppBoundClass::bindToJavascript(WebFrame* frame, const WebString& classname)
344dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
345dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // BindToWindowObject will take its own reference to the NPObject, and clean
346dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // up after itself.  It will also (indirectly) register the object with V8,
347dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // so we must remember this so we can unregister it when we're destroyed.
348dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    frame->bindToWindowObject(classname, NPVARIANT_TO_OBJECT(*getAsCppVariant()));
349dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    m_boundToFrame = true;
350dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
351