7e2ca846f312a50ce9c6b48b634b2ad729645087
[platform/framework/web/wrt-plugins-common.git] / src / js-overlay / js_overlay_support.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16 /**
17  * @file        js_overlay_support.cpp
18  * @author
19  * @version     1.0
20  * @brief
21  */
22 #include <memory>
23 #include <dpl/log/log.h>
24 #include <dpl/foreach.h>
25 #include <JavaScriptCore/JavaScript.h>
26
27 #include <js_overlay_support.h>
28
29 namespace JSOverlaySupport
30 {
31
32 class JSFunctionDispatcher
33 {
34   public:
35     struct PrivateData
36     {
37         //required to unprotect object in destructor;
38         JSContextRef context;
39         JSObjectPtr originalFunction;
40         JSObjectPtr overlayFunction;
41     };
42
43     static JSClassRef getClassRef();
44
45   private:
46     static JSClassDefinition m_classInfo;
47
48   private:
49     static void initialize(JSContextRef context, JSObjectRef object);
50
51     static void finalize(JSObjectRef object);
52
53     static JSValueRef callAsFunction(JSContextRef ctx,
54                                      JSObjectRef function,
55                                      JSObjectRef thisObject,
56                                      size_t argumentCount,
57                                      const JSValueRef arguments[],
58                                      JSValueRef* exception);
59 };
60
61
62
63 JSObjectPtr createWrappedFunction(
64     JSGlobalContextRef ctx,
65     const JSObjectPtr& originalFunction,
66     const JSObjectPtr& overlayFunction,
67     const std::string& name)
68 {
69     LogDebug("Creation overlay for function: " << name);
70     JSStringRef name_js = JSStringCreateWithUTF8CString(name.c_str());
71
72     JSFunctionDispatcher::PrivateData* priv =
73         new JSFunctionDispatcher::PrivateData;
74     priv->context = ctx;
75     priv->overlayFunction = overlayFunction;
76     priv->originalFunction = originalFunction;
77
78     auto fun = JSObjectMake(ctx, JSFunctionDispatcher::getClassRef(), priv);
79
80     JSStringRelease(name_js);
81
82     LogDebug("JSValueProtect invoked for: "
83              << overlayFunction->getObject() << " "
84              << originalFunction->getObject() << " Wrapper:"
85              << fun);
86
87     //the value is unprotected in finalize of the JSFunctionDispatcher object
88     JSValueProtect(ctx,
89                    static_cast<JSObjectRef>(
90                        overlayFunction->getObject()));
91
92     return JSObjectPtr(new JSObject(fun));
93 }
94
95
96
97 JSClassDefinition JSFunctionDispatcher::m_classInfo = {
98     0,
99     kJSClassAttributeNone,
100     "IGNORED",
101     0,
102     0,
103     0,
104     initialize,
105     finalize,
106     NULL,
107     NULL,
108     NULL,
109     NULL,
110     NULL,
111     callAsFunction,
112     NULL,
113     NULL,
114     NULL
115 };
116
117 JSClassRef JSFunctionDispatcher::getClassRef()
118 {
119     static auto classRef = JSClassCreate(&m_classInfo);
120     return classRef;
121 }
122
123
124 void JSFunctionDispatcher::initialize(JSContextRef /*context*/,
125                                       JSObjectRef /*object*/)
126 {
127     LogDebug("Initialize");
128 }
129
130 void JSFunctionDispatcher::finalize(JSObjectRef object)
131 {
132     LogDebug("finalize");
133
134     PrivateData* priv = static_cast<PrivateData*> (JSObjectGetPrivate(object));
135     if(priv)
136     {
137         JSValueUnprotect(priv->context,
138                          static_cast<JSObjectRef>(
139                              priv->overlayFunction->getObject()));
140         delete priv;
141     }
142 }
143
144
145
146 JSValueRef JSFunctionDispatcher::callAsFunction(
147     JSContextRef context,
148     JSObjectRef object,
149     JSObjectRef thisObject,
150     size_t argumentCount,
151     const JSValueRef arguments[],
152     JSValueRef* exception)
153 {
154     LogDebug("Dispatcher invoked");
155
156     JSValueRef result = JSValueMakeUndefined(context);
157
158     JSFunctionDispatcher::PrivateData* priv =
159         static_cast<JSFunctionDispatcher::PrivateData*>
160             (JSObjectGetPrivate(object));
161
162     if(!priv)
163     {
164         LogError("Private object is NULL");
165         return result;
166     }
167
168     //call overlayed function
169     if (priv->overlayFunction->getObject())
170     {
171         LogDebug("Overlayed function will be invoked...");
172         result = JSObjectCallAsFunction(
173             context,
174             static_cast<JSObjectRef>(
175                 priv->overlayFunction->getObject()),
176             thisObject,
177             argumentCount,
178             arguments,
179             exception);
180     }
181
182     //call original function
183     if (priv->originalFunction->getObject())
184     {
185         LogDebug("Original function will be invoked..");
186         result = JSObjectCallAsFunction(
187             context,
188             static_cast<JSObjectRef>(
189                 priv->originalFunction->getObject()),
190             thisObject,
191             argumentCount,
192             arguments,
193             exception);
194     }
195
196     LogDebug("Done");
197     return result;
198 }
199
200
201
202
203 }