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