Initialize Tizen 2.3
[framework/web/wrt-plugins-common.git] / src_mobile / js-overlay / deprecated / 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 class JSFunctionDispatcher
31 {
32   public:
33     struct PrivateData
34     {
35         //required to unprotect object in destructor;
36         JSContextRef context;
37         JSObjectPtr originalFunction;
38         JSObjectPtr overlayFunction;
39     };
40
41     static JSClassRef getClassRef();
42
43   private:
44     static JSClassDefinition m_classInfo;
45
46   private:
47     static void initialize(JSContextRef context, JSObjectRef object);
48
49     static void finalize(JSObjectRef object);
50
51     static JSValueRef callAsFunction(JSContextRef ctx,
52                                      JSObjectRef function,
53                                      JSObjectRef thisObject,
54                                      size_t argumentCount,
55                                      const JSValueRef arguments[],
56                                      JSValueRef* exception);
57 };
58
59 JSObjectPtr createWrappedFunction(
60     JSGlobalContextRef ctx,
61     const JSObjectPtr& originalFunction,
62     const JSObjectPtr& overlayFunction,
63     const std::string& name)
64 {
65     LogDebug("Creation overlay for function: " << name);
66     JSStringRef name_js = JSStringCreateWithUTF8CString(name.c_str());
67
68     JSFunctionDispatcher::PrivateData* priv =
69         new JSFunctionDispatcher::PrivateData;
70     priv->context = ctx;
71     priv->overlayFunction = overlayFunction;
72     priv->originalFunction = originalFunction;
73
74     auto fun = JSObjectMake(ctx, JSFunctionDispatcher::getClassRef(), priv);
75
76     JSStringRelease(name_js);
77
78     LogDebug("JSValueProtect invoked for: "
79              << overlayFunction->getObject() << " "
80              << originalFunction->getObject() << " Wrapper:"
81              << fun);
82
83     //the value is unprotected in finalize of the JSFunctionDispatcher object
84     JSValueProtect(ctx,
85                    static_cast<JSObjectRef>(
86                        overlayFunction->getObject()));
87
88     return JSObjectPtr(new JSObject(fun));
89 }
90
91 JSClassDefinition JSFunctionDispatcher::m_classInfo = {
92     0,
93     kJSClassAttributeNone,
94     "IGNORED",
95     0,
96     0,
97     0,
98     initialize,
99     finalize,
100     NULL,
101     NULL,
102     NULL,
103     NULL,
104     NULL,
105     callAsFunction,
106     NULL,
107     NULL,
108     NULL
109 };
110
111 JSClassRef JSFunctionDispatcher::getClassRef()
112 {
113     static auto classRef = JSClassCreate(&m_classInfo);
114     return classRef;
115 }
116
117 void JSFunctionDispatcher::initialize(JSContextRef /*context*/,
118                                       JSObjectRef /*object*/)
119 {
120     LogDebug("Initialize");
121 }
122
123 void JSFunctionDispatcher::finalize(JSObjectRef object)
124 {
125     LogDebug("finalize");
126
127     PrivateData* priv = static_cast<PrivateData*>(JSObjectGetPrivate(object));
128     if (priv) {
129         JSValueUnprotect(priv->context,
130                          static_cast<JSObjectRef>(
131                              priv->overlayFunction->getObject()));
132         delete priv;
133     }
134 }
135
136 JSValueRef JSFunctionDispatcher::callAsFunction(
137     JSContextRef context,
138     JSObjectRef object,
139     JSObjectRef thisObject,
140     size_t argumentCount,
141     const JSValueRef arguments[],
142     JSValueRef* exception)
143 {
144     LogDebug("Dispatcher invoked");
145
146     JSValueRef result = JSValueMakeUndefined(context);
147
148     JSFunctionDispatcher::PrivateData* priv =
149         static_cast<JSFunctionDispatcher::PrivateData*>
150         (JSObjectGetPrivate(object));
151
152     if (!priv) {
153         LogError("Private object is NULL");
154         return result;
155     }
156
157     //call overlayed function
158     if (priv->overlayFunction->getObject()) {
159         LogDebug("Overlayed function will be invoked...");
160         result = JSObjectCallAsFunction(
161                 priv->context,
162                 static_cast<JSObjectRef>(
163                     priv->overlayFunction->getObject()),
164                 thisObject,
165                 argumentCount,
166                 arguments,
167                 exception);
168     }
169
170     //call original function
171     if (priv->originalFunction->getObject()) {
172         LogDebug("Original function will be invoked..");
173         result = JSObjectCallAsFunction(
174                 context,
175                 static_cast<JSObjectRef>(
176                     priv->originalFunction->getObject()),
177                 thisObject,
178                 argumentCount,
179                 arguments,
180                 exception);
181     }
182
183     LogDebug("Done");
184     return result;
185 }
186 }