1caf179f4d0f8294fcbe55e5d0f00eeb36da0e01
[platform/framework/web/wrt-plugins-common.git] / src / js-overlay / 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 const std::string storageEventName = "storage";
36 const std::string appServiceEventName = "appservice";
37 const std::string softKeyboardChangeEventName = "softkeyboardchange";
38
39 AddEventListenerSupport::IFramesListeners
40 AddEventListenerSupport::m_listeners =
41     AddEventListenerSupport::IFramesListeners();
42
43 JSContextRef AddEventListenerSupport::m_context = NULL;
44
45 void AddEventListenerSupport::initialize(JSContextRef context)
46 {
47     if (!m_context) {
48         m_context = context;
49     }
50 }
51
52 void AddEventListenerSupport::deinitialize()
53 {
54     if (!m_context) {
55         LogDebug("Not yet initialized");
56     }
57
58     m_listeners.clear();
59     m_context = NULL;
60 }
61
62 bool AddEventListenerSupport::isInitialized()
63 {
64     return m_context != NULL;
65 }
66
67 JSValueRef AddEventListenerSupport::
68     AddEventListener(JSContextRef context,
69                      JSObjectRef object,
70                      JSObjectRef thisObject,
71                      size_t argumentCount,
72                      const JSValueRef arguments[],
73                      JSValueRef* /*exception*/)
74 {
75     LogDebug("Add event listener invoked");
76     LogDebug("This(iframe?):" << thisObject);
77     LogDebug("object:" << object);
78
79     if (argumentCount < 2 || !JSValueIsString(context, arguments[0])) {
80         LogError("Wrong arguments");
81         return JSValueMakeUndefined(context);
82     }
83
84     std::string eventName = WrtDeviceApis::CommonsJavaScript::
85             Converter(context).toString(arguments[0]);
86     LogDebug("Event name: " << eventName);
87
88     if (eventName != storageEventName &&
89         eventName != appServiceEventName &&
90         eventName != softKeyboardChangeEventName)
91     {
92         LogDebug("Event type not supported");
93         return JSValueMakeUndefined(context);
94     }
95
96     JSValueProtect(m_context, arguments[1]);
97     JSObjectRef objectCb =
98         JSValueToObject(m_context,
99                         arguments[1],
100                         NULL);
101     if (!JSObjectIsFunction(m_context, objectCb)) {
102         LogError("JS object is not a function");
103         return JSValueMakeUndefined(context);
104     }
105     //add object to Listeners
106     //set event information according to each event type
107     CallbackData data;
108     data.object = objectCb;
109     data.thisObject = thisObject;
110
111     if (eventName == storageEventName) {
112         data.eventType = StorageCustomEvent;
113     } else if (eventName == appServiceEventName) {
114         data.eventType = ServiceCustomEvent;
115     } else if (eventName == softKeyboardChangeEventName) {
116         data.eventType = SoftKeyboardChangeCustomEvent;
117     }
118
119     getIFrameListeners(thisObject)->push_back(data);
120
121     return JSValueMakeUndefined(context);
122 }
123
124 void AddEventListenerSupport::
125     CallStorageListenersFromDifferentIFrames(
126     JSObjectRef iframe,
127     const WrtDeviceApis::StorageEvent::Api::IStorageEventPtr& event)
128 {
129     LogDebug("Invoked callbacks");
130     LogInfo("Context: " << m_context);
131
132     FOREACH(it, m_listeners)
133     {
134         if (it->first == iframe) {
135             continue;
136         }
137
138         auto eventPriv = new JSStorageEventPrivateObject(m_context,
139                                                          event);
140
141         JSObjectRef eventObject =
142             JSObjectMake(m_context, JSStorageEvent::getClassRef(), eventPriv);
143         const size_t argc = 1;
144         JSValueRef argv[argc] = { eventObject };
145
146         JSValueProtect(m_context, eventObject);
147
148         FOREACH(listener, *it->second)
149         {
150             LogDebug("Call");
151
152             if (listener->eventType ==
153                 StorageCustomEvent)
154             {
155                 JSObjectCallAsFunction(
156                     m_context,
157                     listener->object,
158                     NULL,
159                     argc,
160                     argv,
161                     NULL);
162             }
163         }
164
165         JSValueUnprotect(m_context, eventObject);
166     }
167
168     LogDebug("Done");
169 }
170
171 void AddEventListenerSupport::
172     CallCustomEventListenersFromIFrame(
173     JSObjectRef iframe,
174     CustomEventType eventType,
175     JSObjectRef eventObject)
176 {
177     LogDebug("Invoked callbacks");
178
179     IFramesListeners::iterator it = m_listeners.find(iframe);
180     if (it == m_listeners.end()) {
181         LogDebug("This frame object not existed");
182         return;
183     }
184
185     const size_t argc = 1;
186     JSValueRef argv[argc] = { eventObject };
187
188     JSValueProtect(m_context, eventObject);
189     FOREACH(listener, *it->second)
190     {
191         if (listener->eventType == eventType) {
192             LogDebug("Call");
193             JSObjectCallAsFunction(
194                 m_context,
195                 listener->object,
196                 iframe,
197                 argc,
198                 argv,
199                 NULL);
200         }
201     }
202     JSValueUnprotect(m_context, eventObject);
203     LogDebug("Done");
204 }
205
206 AddEventListenerSupport::ListenersPtr
207 AddEventListenerSupport::getIFrameListeners(JSObjectRef iframe)
208 {
209     auto it = m_listeners.find(iframe);
210     if (it != m_listeners.end()) {
211         return it->second;
212     }
213
214     return m_listeners[iframe] = ListenersPtr(new Listeners());
215 }
216 }
217 }