2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * @author Grzegorz Krawczyk (g.krawczyk@samgsung.com)
19 * @author Yunchan Cho (yunchan.cho@samgsung.com)
25 #include <dpl/foreach.h>
26 #include <dpl/log/log.h>
28 #include "plugin_property_support.h"
31 #include <js_overlay_support.h>
32 #include <js_overlay_types.h>
33 #include <js_overlay_addEventListener.h>
34 #include <TizenServiceEvent/ITizenServiceEvent.h>
35 #include <TizenServiceEvent/TizenServiceEvent.h>
36 #include <SoftKeyboardChangeEvent/ISoftKeyboardChangeEvent.h>
37 #include <SoftKeyboardChangeEvent/SoftKeyboardChangeEvent.h>
38 #include <JSClass/JSTizenServiceEvent.h>
39 #include <JSClass/JSSoftKeyboardChangeEvent.h>
42 //const char* SEPARATOR = ".";
43 const std::string GLOBAL_OBJECT_NAME = "GLOBAL_OBJECT";
47 using namespace PluginModule;
48 using namespace WrtPlugins::W3C;
50 Explorer::Explorer(JSGlobalContextRef context) :
54 LogError("Context is NULL");
59 JavaScriptInterfaceSingleton::Instance().getGlobalObject(context);
61 LogDebug("Register main frame");
62 //register main frame;
63 m_iframeSupport.registerIframe(m_globalObject);
65 m_propertySupport.reset(new WindowPropertySupport(m_context));
67 // initialization for use of custom event
68 if (!AddEventListenerSupport::isInitialized()) {
69 LogInfo("initialization for use of custom event");
70 AddEventListenerSupport::initialize(context);
76 // deinitialization for use of custom event
77 if (AddEventListenerSupport::isInitialized()) {
78 LogInfo("deinitialization for use of custom event");
79 AddEventListenerSupport::deinitialize();
83 JSObjectPtr Explorer::getJSObjectProperty(const std::string& propertyName,
86 LogDebug("Get object property " << propertyName);
87 return JavaScriptInterfaceSingleton::Instance().getJSObjectProperty(
88 m_context, object, propertyName);
91 JSObjectPtr Explorer::getProperty(
92 const string& requestedProperty,
93 JSObjectPtr providedObject)
95 LogDebug("Requested Property: " << requestedProperty);
97 if (!providedObject) {
98 LogError("Provided object is empty");
102 std::string currentObjectName;
103 std::string currentPropertyRequested = requestedProperty;
104 JSObjectPtr currentObject = providedObject;
107 auto pos = currentPropertyRequested.find(".");
108 if (pos == string::npos) {
109 return getJSObjectProperty(currentPropertyRequested, currentObject);
112 //check if requested object has child
113 currentObjectName = currentPropertyRequested.substr(0, pos);
115 if (currentPropertyRequested.size() <= pos + 1) {
116 LogError("Wrong name of requested property");
117 return JSObjectPtr();
119 currentPropertyRequested = currentPropertyRequested.substr(pos + 1);
121 currentObject = getJSObjectProperty(currentObjectName, currentObject);
122 if (!currentObject) {
123 LogError("Failed to get property: " << currentObjectName);
124 return JSObjectPtr();
129 bool Explorer::registerObject(const JSObjectDeclarationPtr& declaration,
130 JSGlobalContextRef context)
132 LogDebug("Register to global object");
136 if (declaration->getParentName() == GLOBAL_OBJECT_NAME) {
137 LogDebug("Connect to Global object");
138 retValue = register_(declaration, m_globalObject, context);
139 } else { //PIM support
140 LogDebug("Connect to NOT global object");
141 //it should be master object name
142 string masterName = declaration->getParentName();
143 auto pos = masterName.find(".");
144 if (string::npos != pos) {
145 LogError("ParentName not allowed");
148 auto masterObject = getJSObjectProperty(masterName, m_globalObject);
149 if (masterObject->getObject() == 0) {
152 retValue = registerObject(declaration,
158 if (declaration->checkIframesSupported()) {
159 LogDebug("Iframe supported");
160 m_iframeSupport.registerDeclaration(declaration);
161 // m_iframeSupport.invokeCallbackForMainFrame(m_context,
165 LogDebug("Iframe NOT supported");
171 bool Explorer::registerObject(const JSObjectDeclarationPtr& declaration,
172 const std::string& providedObjectName,
173 JSObjectPtr providedObject,
174 JSGlobalContextRef context)
177 "Register object. Provided object name: '" << providedObjectName
179 "', registration of: '" << declaration->getName() << "'");
181 std::string fullParentName = declaration->getParentName();
182 LogDebug("Parent name: " << declaration->getParentName());
184 if (fullParentName == providedObjectName) {
185 LogDebug("Provided object match equaly to requested parent");
186 return register_(declaration, providedObject, context);
189 //check if object exists in fullParentName
190 auto pos = fullParentName.find(providedObjectName);
191 if (pos == string::npos) {
193 "Object: " << declaration->getName()
194 << " should be child of: " <<
195 declaration->getParentName()
196 << " but you provided object: " <<
202 if (fullParentName.size() <= pos + providedObjectName.size() + 1) {
203 LogError("Invalid object name");
207 auto currentRequesteProperty =
208 fullParentName.substr(pos + providedObjectName.size() + 1);
210 JSObjectPtr jsObject = getProperty(
211 currentRequesteProperty, providedObject);
213 if (!jsObject->getObject()) {
215 "Object: '" << declaration->getName()
216 << "' should be child of: '" <<
217 declaration->getParentName()
218 << "'. you provided object: '" <<
220 << "' but object is null");
225 return register_(declaration, jsObject, context);
228 bool Explorer::register_(const JSObjectDeclarationPtr& declaration,
230 JSGlobalContextRef context)
232 LogInfo("Registration object: " << declaration->getParentName() <<
233 "<-" << declaration->getName());
235 Assert(parent && "parent object is NULL");
237 typedef JSObjectDeclaration::Options JO;
239 JSGlobalContextRef gContext = (context == NULL) ? m_context : context;
240 JSObjectPtr newObject;
242 JSObjectPtr objectInstance = JavaScriptInterfaceSingleton::Instance().
243 createObject(gContext, declaration);
246 if (declaration->getOptions() &&
247 declaration->getOptions()->getType() == JO::ClassType::Function)
249 LogDebug("Loading function object " << declaration->getName());
251 auto type = declaration->getOptions()->getIframeOverlay();
252 if (JO::IFrameOverlay::OverlayedBeforeOriginal == type) {
253 LogDebug("Create overlayed function");
254 JSObjectPtr original =
255 JavaScriptInterfaceSingleton::Instance().
256 getJSObjectProperty(gContext,
258 declaration->getName());
259 newObject = JSOverlaySupport::
260 createWrappedFunction(gContext,
263 declaration->getName());
265 LogDebug("create normal function");
266 newObject = objectInstance;
268 } else { //object creation
269 newObject = objectInstance;
272 JavaScriptInterfaceSingleton::Instance().setObjectProperty(
275 declaration->getName(),
279 if (declaration->getOptions() &&
280 (declaration->getOptions()->getIframeNotice() ==
281 JO::IFrameNotice::AlwaysNotice))
283 declaration->getOptions()->invokeCallback(gContext,
285 objectInstance->getObject());
291 void Explorer::registerObjectIntoIframe(
292 const JSObjectDeclarationPtr& declaration,
293 JSObjectPtr frameObject,
294 JSGlobalContextRef context)
296 if (declaration->getParentName() == GLOBAL_OBJECT_NAME) {
297 LogDebug("Connect to Global object of IFRAME");
298 register_(declaration, frameObject, context);
304 LogWarning("Connect to NOT global object of IFRAME");
305 //it should be master object name
306 string masterName = declaration->getParentName();
307 auto pos = masterName.find(".");
308 if (string::npos != pos) {
309 LogError("ParentName not allowed");
312 auto masterObject = getJSObjectProperty(masterName, frameObject);
313 if (!masterObject->getObject()) {
314 LogError("Object not exist in frame");
317 register_(declaration, masterObject, context);
321 void Explorer::loadFrame(JSGlobalContextRef context)
323 LogDebug("Frame attached");
325 JSObjectPtr frameObject =
326 JavaScriptInterfaceSingleton::Instance().getGlobalObject(context);
328 LogDebug("Register main frame");
329 //register main frame;
331 if (frameObject->getObject() == m_globalObject->getObject()) {
332 // Main page was already loaded from constructor
333 LogDebug("Main page loaded");
337 m_iframeSupport.registerIframe(frameObject);
339 auto iframeObjects = m_iframeSupport.getIframeObjects();
341 FOREACH(object, iframeObjects)
343 LogDebug("Register object: " << (*object)->getName() );
345 registerObjectIntoIframe(*object, frameObject, context);
349 void Explorer::unloadFrame(JSGlobalContextRef context)
351 LogDebug("Frame detached");
353 JSObjectPtr frameObject =
354 JavaScriptInterfaceSingleton::Instance().getGlobalObject(context);
356 m_iframeSupport.unregisterIframe(frameObject);
359 void Explorer::removePluginsFromIframes()
361 LogDebug("Remove plugins from iframes");
363 if (m_iframeSupport.hasIframes()) {
364 LogDebug("Removing iframes");
365 JavaScriptInterfaceSingleton::Instance().removeIframes(m_context);
369 void Explorer::deregisterObject(const JSObjectDeclarationPtr& declaration)
371 LogDebug("Deregister object " << declaration->getName());
373 if (GLOBAL_OBJECT_NAME != declaration->getParentName()) {
374 LogWarning("Ignored remove property " << declaration->getName());
378 JavaScriptInterfaceSingleton::Instance().
379 removeObjectProperty(m_context,
381 declaration->getName());
384 void Explorer::cleanIframesData()
386 LogDebug("Clean iframes data");
387 m_iframeSupport.clean();
390 void Explorer::callEventListeners(CustomEventType eventType, void* data)
392 using namespace WrtPlugins::Tizen;
393 // get iframe objects from javascript global context
394 JavaScriptInterface::ObjectsListPtr frameLists =
395 JavaScriptInterfaceSingleton::Instance().getIframesList(m_context);
397 // get main frame object from javascript global context
398 JSObjectRef mainFrame = JSContextGetGlobalObject(m_context);
399 frameLists->push_back(JSObjectPtr(new JSObject(mainFrame)));
401 if (eventType == ServiceCustomEvent) {
402 using namespace WrtDeviceApis::TizenServiceEvent::Api;
403 // set user data of js callback function for 'appservice' js event
404 ITizenServiceEventPtr event = ITizenServiceEventPtr(
405 new TizenServiceEvent());
406 event->setScale(m_propertySupport->getScale());
407 event->setBundle(m_propertySupport->getBundle());
409 // call js callback function for 'appservice' js event on each frame
410 FOREACH(it, *frameLists)
412 JSObjectRef frame = static_cast<JSObjectRef>((*it).Get()->getObject());
415 new JSTizenServiceEventPrivateObject(m_context, event);
416 JSObjectRef eventObject =
417 JSObjectMake(m_context,
418 JSTizenServiceEvent::getClassRef(), eventPriv);
420 AddEventListenerSupport::CallCustomEventListenersFromIFrame(
421 frame, eventType, eventObject);
423 } else if (eventType == SoftKeyboardChangeCustomEvent) {
424 using namespace WrtDeviceApis::SoftKeyboardChangeEvent::Api;
426 LogDebug("no ime size");
430 // set user data of js callback function for 'softkeyboardchange' js
432 SoftKeyboardChangeArgs* args =
433 static_cast<SoftKeyboardChangeArgs *>(data);
434 ISoftKeyboardChangeEventPtr event =
435 ISoftKeyboardChangeEventPtr(
436 new SoftKeyboardChangeEvent(
440 LogInfo("softkeyboard event's state: " << args->state);
442 // call js callback function for 'softkeyboardchange' js event on each
444 FOREACH(it, *frameLists)
446 JSObjectRef frame = static_cast<JSObjectRef>((*it).Get()->getObject());
449 new JSSoftKeyboardChangeEventPrivateObject(m_context, event);
450 JSObjectRef eventObject =
453 JSSoftKeyboardChangeEvent::getClassRef(),
456 AddEventListenerSupport::CallCustomEventListenersFromIFrame(
457 frame, eventType, eventObject);
460 LogInfo("Not supported custom event type");
465 WindowPropertySupport* Explorer::getWindowPropertySupport()
467 return m_propertySupport.get();