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>
43 //const char* SEPARATOR = ".";
44 const std::string GLOBAL_OBJECT_NAME = "GLOBAL_OBJECT";
48 using namespace PluginModule;
49 using namespace WrtPlugins::W3C;
51 Explorer::Explorer(JSGlobalContextRef context) :
55 LogError("Context is NULL");
60 JavaScriptInterfaceSingleton::Instance().getGlobalObject(context);
62 LogDebug("Register main frame");
63 //register main frame;
64 m_iframeSupport.registerIframe(m_globalObject);
66 m_propertySupport.reset(new WindowPropertySupport(m_context));
68 // initialization for use of custom event
69 if (!AddEventListenerSupport::isInitialized())
71 LogInfo("initialization for use of custom event");
72 AddEventListenerSupport::initialize(context);
78 // deinitialization for use of custom event
79 if (AddEventListenerSupport::isInitialized()) {
80 LogInfo("deinitialization for use of custom event");
81 AddEventListenerSupport::deinitialize();
85 JSObjectPtr Explorer::getJSObjectProperty(const std::string& propertyName,
88 LogDebug("Get object property " << propertyName);
89 return JavaScriptInterfaceSingleton::Instance().getJSObjectProperty(
90 m_context, object, propertyName);
93 JSObjectPtr Explorer::getProperty(
94 const string& requestedProperty,
95 JSObjectPtr providedObject)
97 LogDebug("Requested Property: " << requestedProperty);
101 LogError("Provided object is empty");
102 return JSObjectPtr();
105 std::string currentObjectName;
106 std::string currentPropertyRequested = requestedProperty;
107 JSObjectPtr currentObject = providedObject;
111 auto pos = currentPropertyRequested.find(".");
112 if (pos == string::npos)
114 return getJSObjectProperty(currentPropertyRequested, currentObject);
117 //check if requested object has child
118 currentObjectName = currentPropertyRequested.substr(0,pos);
120 if (currentPropertyRequested.size() <= pos+1)
122 LogError("Wrong name of requested property");
123 return JSObjectPtr();
125 currentPropertyRequested = currentPropertyRequested.substr(pos+1);
127 currentObject = getJSObjectProperty(currentObjectName, currentObject);
130 LogError("Failed to get property: " << currentObjectName);
131 return JSObjectPtr();
136 bool Explorer::registerObject(const JSObjectDeclarationPtr& declaration,
137 JSGlobalContextRef context)
139 LogDebug("Register to global object");
143 if (declaration->getParentName() == GLOBAL_OBJECT_NAME)
145 LogDebug("Connect to Global object");
146 retValue = register_(declaration, m_globalObject, context);
150 LogDebug("Connect to NOT global object");
151 //it should be master object name
152 string masterName = declaration->getParentName();
153 auto pos = masterName.find(".");
154 if (string::npos != pos)
156 LogError("ParentName not allowed");
159 auto masterObject = getJSObjectProperty(masterName, m_globalObject);
160 if (masterObject->getObject() == 0)
164 retValue = registerObject(declaration, masterName, masterObject, context);
167 if (declaration->checkIframesSupported()) {
168 LogDebug("Iframe supported");
169 m_iframeSupport.registerDeclaration(declaration);
170 // m_iframeSupport.invokeCallbackForMainFrame(m_context,
175 LogDebug("Iframe NOT supported");
182 bool Explorer::registerObject(const JSObjectDeclarationPtr& declaration,
183 const std::string& providedObjectName,
184 JSObjectPtr providedObject,
185 JSGlobalContextRef context)
187 LogDebug("Register object. Provided object name: '" << providedObjectName
188 << "', registration of: '" << declaration->getName() << "'");
190 std::string fullParentName = declaration->getParentName();
191 LogDebug("Parent name: " << declaration->getParentName());
193 if(fullParentName == providedObjectName)
195 LogDebug("Provided object match equaly to requested parent");
196 return register_(declaration, providedObject, context);
199 //check if object exists in fullParentName
200 auto pos = fullParentName.find(providedObjectName);
201 if(pos == string::npos)
203 LogError("Object: " << declaration->getName()
204 << " should be child of: " << declaration->getParentName()
205 << " but you provided object: " << providedObjectName);
210 if (fullParentName.size() <= pos+providedObjectName.size()+1)
212 LogError("Invalid object name");
216 auto currentRequesteProperty =
217 fullParentName.substr(pos+providedObjectName.size()+1);
220 JSObjectPtr jsObject = getProperty(
221 currentRequesteProperty, providedObject);
223 if(!jsObject->getObject())
225 LogError("Object: '" << declaration->getName()
226 << "' should be child of: '" << declaration->getParentName()
227 << "'. you provided object: '" << providedObjectName
228 << "' but object is null");
233 return register_(declaration, jsObject, context);
236 bool Explorer::register_(const JSObjectDeclarationPtr& declaration,
238 JSGlobalContextRef context)
240 LogInfo("Registration object: " << declaration->getParentName() <<
241 "<-" << declaration->getName());
243 Assert(parent && "parent object is NULL");
245 typedef JSObjectDeclaration::Options JO;
247 JSGlobalContextRef gContext = (context==NULL)?m_context:context;
248 JSObjectPtr newObject;
250 JSObjectPtr objectInstance = JavaScriptInterfaceSingleton::Instance().
251 createObject(gContext,declaration);
254 if (declaration->getOptions() &&
255 declaration->getOptions()->getType() == JO::ClassType::Function)
257 LogDebug("Loading function object " << declaration->getName());
259 auto type = declaration->getOptions()->getIframeOverlay();
260 if (JO::IFrameOverlay::OverlayedBeforeOriginal == type)
262 LogDebug("Create overlayed function");
263 JSObjectPtr original =
264 JavaScriptInterfaceSingleton::Instance().
265 getJSObjectProperty(gContext,
267 declaration->getName());
268 newObject = JSOverlaySupport::
269 createWrappedFunction(gContext,
272 declaration->getName());
276 LogDebug("create normal function");
277 newObject = objectInstance;
280 else //object creation
282 newObject = objectInstance;
285 JavaScriptInterfaceSingleton::Instance().setObjectProperty(
288 declaration->getName(),
292 if (declaration->getOptions() &&
293 (declaration->getOptions()->getIframeNotice() ==
294 JO::IFrameNotice::AlwaysNotice))
296 declaration->getOptions()->invokeCallback(gContext,
298 objectInstance->getObject());
305 void Explorer::registerObjectIntoIframe(const JSObjectDeclarationPtr& declaration,
306 JSObjectPtr frameObject,
307 JSGlobalContextRef context)
309 if (declaration->getParentName() == GLOBAL_OBJECT_NAME)
311 LogDebug("Connect to Global object of IFRAME");
312 register_(declaration, frameObject, context);
318 LogWarning("Connect to NOT global object of IFRAME");
319 //it should be master object name
320 string masterName = declaration->getParentName();
321 auto pos = masterName.find(".");
322 if (string::npos != pos)
324 LogError("ParentName not allowed");
327 auto masterObject = getJSObjectProperty(masterName, frameObject);
328 if (!masterObject->getObject())
330 LogError("Object not exist in frame");
333 register_(declaration, masterObject, context);
338 void Explorer::loadFrame(JSGlobalContextRef context)
340 LogDebug("Frame attached");
342 JSObjectPtr frameObject =
343 JavaScriptInterfaceSingleton::Instance().getGlobalObject(context);
345 LogDebug("Register main frame");
346 //register main frame;
348 if(frameObject->getObject() == m_globalObject->getObject())
350 // Main page was already loaded from constructor
351 LogDebug("Main page loaded");
355 m_iframeSupport.registerIframe(frameObject);
357 auto iframeObjects = m_iframeSupport.getIframeObjects();
359 FOREACH(object, iframeObjects)
361 LogDebug("Register object: " << (*object)->getName() );
363 registerObjectIntoIframe(*object, frameObject, context);
367 void Explorer::unloadFrame(JSGlobalContextRef context)
369 LogDebug("Frame detached");
371 JSObjectPtr frameObject =
372 JavaScriptInterfaceSingleton::Instance().getGlobalObject(context);
374 m_iframeSupport.unregisterIframe(frameObject);
377 void Explorer::removePluginsFromIframes()
379 LogDebug("Remove plugins from iframes");
381 if (m_iframeSupport.hasIframes())
383 LogDebug("Removing iframes");
384 JavaScriptInterfaceSingleton::Instance().removeIframes(m_context);
388 void Explorer::deregisterObject(const JSObjectDeclarationPtr& declaration)
390 LogDebug("Deregister object " << declaration->getName());
392 if (GLOBAL_OBJECT_NAME != declaration->getParentName())
394 LogWarning("Ignored remove property " << declaration->getName());
398 JavaScriptInterfaceSingleton::Instance().
399 removeObjectProperty(m_context,
401 declaration->getName());
404 void Explorer::cleanIframesData()
406 LogDebug("Clean iframes data");
407 m_iframeSupport.clean();
410 void Explorer::callEventListeners(CustomEventType eventType, void* data)
412 using namespace WrtPlugins::Tizen;
413 // get iframe objects from javascript global context
414 JavaScriptInterface::ObjectsListPtr frameLists =
415 JavaScriptInterfaceSingleton::Instance().getIframesList(m_context);
417 // get main frame object from javascript global context
418 JSObjectRef mainFrame = JSContextGetGlobalObject(m_context);
419 frameLists->push_back(JSObjectPtr(new JSObject(mainFrame)));
421 if (eventType == ServiceCustomEvent) {
422 using namespace WrtDeviceApis::TizenServiceEvent::Api;
423 // set user data of js callback function for 'appservice' js event
424 ITizenServiceEventPtr event = ITizenServiceEventPtr(new TizenServiceEvent());
425 event->setScale(m_propertySupport->getScale());
426 event->setBundle(m_propertySupport->getBundle());
428 // call js callback function for 'appservice' js event on each frame
429 FOREACH(it, *frameLists)
431 JSObjectRef frame = static_cast<JSObjectRef>((*it).Get()->getObject());
434 new JSTizenServiceEventPrivateObject(m_context, event);
435 JSObjectRef eventObject =
436 JSObjectMake(m_context, JSTizenServiceEvent::getClassRef(), eventPriv);
438 AddEventListenerSupport::CallCustomEventListenersFromIFrame(
439 frame, eventType, eventObject);
441 } else if (eventType == SoftKeyboardChangeCustomEvent) {
442 using namespace WrtDeviceApis::SoftKeyboardChangeEvent::Api;
444 LogDebug("no ime size");
448 // set user data of js callback function for 'softkeyboardchange' js event
449 SoftKeyboardChangeArgs* args = static_cast<SoftKeyboardChangeArgs *>(data);
450 ISoftKeyboardChangeEventPtr event =
451 ISoftKeyboardChangeEventPtr(
452 new SoftKeyboardChangeEvent(
456 LogInfo("softkeyboard event's state: " << args->state);
458 // call js callback function for 'softkeyboardchange' js event on each frame
459 FOREACH(it, *frameLists)
461 JSObjectRef frame = static_cast<JSObjectRef>((*it).Get()->getObject());
464 new JSSoftKeyboardChangeEventPrivateObject(m_context, event);
465 JSObjectRef eventObject =
468 JSSoftKeyboardChangeEvent::getClassRef(),
471 AddEventListenerSupport::CallCustomEventListenersFromIFrame(
472 frame, eventType, eventObject);
475 LogInfo("Not supported custom event type");
481 WindowPropertySupport* Explorer::getWindowPropertySupport()
483 return m_propertySupport.get();