Initialize Tizen 2.3
[framework/web/wrt-plugins-common.git] / src_wearable / js-overlay / deprecated / js_overlay_addEventListener.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  *
18  * @file       AddEventListenerSupport.cpp
19  * @author     Grzegorz Krawczyk (g.krawczyk@samsung.com)
20  * @author     Yunchan Cho (yunchan.cho@samsung.com)
21  * @version    0.1
22  * @brief
23  */
24
25 #include <string>
26 #include <dpl/log/log.h>
27 #include <dpl/foreach.h>
28 #include <CommonsJavaScript/Converter.h>
29 #include <js_overlay_addEventListener.h>
30 #include <js_overlay_types.h>
31 #include <JSStorageEvent.h>
32
33 namespace WrtPlugins {
34 namespace W3C {
35
36 const std::string storageEventName = "storage";
37 const std::string appServiceEventName = "appservice";
38 const std::string softKeyboardChangeEventName = "softkeyboardchange";
39
40 AddEventListenerSupport::IFramesListeners
41 AddEventListenerSupport::m_listeners =
42     AddEventListenerSupport::IFramesListeners();
43
44 JSValueRef AddEventListenerSupport::AddEventListener(
45         JSContextRef context,
46         JSObjectRef object,
47         JSObjectRef thisObject,
48         size_t argumentCount,
49         const JSValueRef arguments[],
50         JSValueRef* /*exception*/)
51 {
52     LogDebug("Add event listener invoked");
53     LogDebug("This(iframe?):" << thisObject);
54     LogDebug("object:" << object);
55
56     JSContextRef global_context = JSContextGetGlobalContext(context);
57     LogDebug("context:" << context << "(global:" << global_context << ")");
58
59     if (argumentCount < 2 || !JSValueIsString(context, arguments[0])) {
60         LogError("Wrong arguments");
61         return JSValueMakeUndefined(context);
62     }
63
64     std::string eventName = WrtDeviceApis::CommonsJavaScript::
65             Converter(context).toString(arguments[0]);
66     LogDebug("Event name: " << eventName);
67
68     if (eventName != storageEventName &&
69         eventName != appServiceEventName &&
70         eventName != softKeyboardChangeEventName)
71     {
72         LogDebug("Event type not supported");
73         return JSValueMakeUndefined(context);
74     }
75
76     JSObjectRef objectCb = JSValueToObject(context, arguments[1], NULL);
77     if (!JSObjectIsFunction(context, objectCb)) {
78         LogError("JS object is not a function");
79         return JSValueMakeUndefined(context);
80     }
81     JSValueProtect(global_context, arguments[1]);
82     //add object to Listeners
83     //set event information according to each event type
84     CallbackData data;
85     data.object = objectCb;
86     data.thisObject = thisObject;
87     data.context = global_context;
88
89     if (eventName == storageEventName) {
90         data.eventType = StorageCustomEvent;
91     } else if (eventName == appServiceEventName) {
92         data.eventType = ServiceCustomEvent;
93     } else if (eventName == softKeyboardChangeEventName) {
94         data.eventType = SoftKeyboardChangeCustomEvent;
95     }
96
97     getIFrameListeners(thisObject)->push_back(data);
98
99     return JSValueMakeUndefined(context);
100 }
101
102 void AddEventListenerSupport::RemoveIFrame(JSObjectPtr iframe)
103 {
104     auto it = m_listeners.find(iframe->getObject());
105     if (it == m_listeners.end()) {
106         LogWarning("Iframe not registered");
107         return;
108     }
109
110     FOREACH(listener, *it->second)
111     {
112         JSValueUnprotect(listener->context, listener->object);
113     }
114     m_listeners.erase(it);
115     LogDebug("Iframe removed from add event listener object");
116 }
117
118 void AddEventListenerSupport::CallStorageListenersFromDifferentIFrames(
119         JSObjectRef iframe,
120         const WrtDeviceApis::StorageEvent::Api::IStorageEventPtr& event)
121 {
122     LogDebug("Invoked callbacks");
123
124     FOREACH(it, m_listeners)
125     {
126         if (it->first == iframe) {
127             continue;
128         }
129
130         FOREACH(listener, *it->second)
131         {
132             LogDebug("Call");
133
134             auto eventPriv =
135                 new JSStorageEventPrivateObject(listener->context, event);
136
137             JSObjectRef eventObject =
138                 JSObjectMake(listener->context, JSStorageEvent::getClassRef(), eventPriv);
139             const size_t argc = 1;
140             JSValueRef argv[argc] = { eventObject };
141
142             JSValueProtect(listener->context, eventObject);
143
144             if (listener->eventType == StorageCustomEvent)
145             {
146                 JSObjectCallAsFunction(
147                     listener->context,
148                     listener->object,
149                     NULL,
150                     argc,
151                     argv,
152                     NULL);
153             }
154
155             JSValueUnprotect(listener->context, eventObject);
156         }
157     }
158
159     LogDebug("Done");
160 }
161
162 void AddEventListenerSupport::CallCustomEventListenersFromIFrame(
163         JSObjectRef iframe,
164         CustomEventType eventType,
165         JSObjectRef eventObject)
166 {
167     LogDebug("Invoked callbacks");
168
169     IFramesListeners::iterator it = m_listeners.find(iframe);
170     if (it == m_listeners.end()) {
171         LogDebug("This frame object not existed");
172         return;
173     }
174
175     const size_t argc = 1;
176     JSValueRef argv[argc] = { eventObject };
177
178     FOREACH(listener, *it->second)
179     {
180         if (listener->eventType == eventType) {
181             LogDebug("Call");
182             JSObjectCallAsFunction(
183                 listener->context,
184                 listener->object,
185                 iframe,
186                 argc,
187                 argv,
188                 NULL);
189         }
190     }
191     LogDebug("Done");
192 }
193
194 AddEventListenerSupport::ListenersPtr
195 AddEventListenerSupport::getIFrameListeners(JSObjectRef iframe)
196 {
197     auto it = m_listeners.find(iframe);
198     if (it != m_listeners.end()) {
199         return it->second;
200     }
201
202     return m_listeners[iframe] = ListenersPtr(new Listeners());
203 }
204 }
205 }