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>
35 //const char* SEPARATOR = ".";
36 const std::string GLOBAL_OBJECT_NAME = "GLOBAL_OBJECT";
40 using namespace PluginModule;
41 using namespace WrtPlugins::W3C;
43 Explorer::Explorer(JSGlobalContextRef context) :
47 LogError("Context is NULL");
52 JavaScriptInterfaceSingleton::Instance().getGlobalObject(context);
54 LogDebug("Register main frame");
55 //register main frame;
56 m_iframeSupport.registerIframe(m_globalObject);
58 m_propertySupport.reset(new WindowPropertySupport(m_context));
65 JSObjectPtr Explorer::getJSObjectProperty(const std::string& propertyName,
68 LogDebug("Get object property " << propertyName);
69 return JavaScriptInterfaceSingleton::Instance().getJSObjectProperty(
70 m_context, object, propertyName);
73 JSObjectPtr Explorer::getProperty(
74 const string& requestedProperty,
75 JSObjectPtr providedObject)
77 LogDebug("Requested Property: " << requestedProperty);
79 if (!providedObject) {
80 LogError("Provided object is empty");
84 std::string currentObjectName;
85 std::string currentPropertyRequested = requestedProperty;
86 JSObjectPtr currentObject = providedObject;
89 auto pos = currentPropertyRequested.find(".");
90 if (pos == string::npos) {
91 return getJSObjectProperty(currentPropertyRequested, currentObject);
94 //check if requested object has child
95 currentObjectName = currentPropertyRequested.substr(0, pos);
97 if (currentPropertyRequested.size() <= pos + 1) {
98 LogError("Wrong name of requested property");
101 currentPropertyRequested = currentPropertyRequested.substr(pos + 1);
103 currentObject = getJSObjectProperty(currentObjectName, currentObject);
104 if (!currentObject) {
105 LogError("Failed to get property: " << currentObjectName);
106 return JSObjectPtr();
111 bool Explorer::registerObject(const JSObjectDeclarationPtr& declaration,
112 JSGlobalContextRef context)
114 LogDebug("Register to global object");
118 if (declaration->getParentName() == GLOBAL_OBJECT_NAME) {
119 LogDebug("Connect to Global object");
120 retValue = register_(declaration, m_globalObject, context);
121 } else { //PIM support
122 LogDebug("Connect to NOT global object");
123 //it should be master object name
124 string masterName = declaration->getParentName();
125 auto pos = masterName.find(".");
126 if (string::npos != pos) {
127 LogError("ParentName not allowed");
130 auto masterObject = getJSObjectProperty(masterName, m_globalObject);
131 if (masterObject->getObject() == 0) {
134 retValue = registerObject(declaration,
140 if (declaration->checkIframesSupported()) {
141 LogDebug("Iframe supported");
142 m_iframeSupport.registerDeclaration(declaration);
143 // m_iframeSupport.invokeCallbackForMainFrame(m_context,
147 LogDebug("Iframe NOT supported");
153 bool Explorer::registerObject(const JSObjectDeclarationPtr& declaration,
154 const std::string& providedObjectName,
155 JSObjectPtr providedObject,
156 JSGlobalContextRef context)
159 "Register object. Provided object name: '" << providedObjectName
161 "', registration of: '" << declaration->getName() << "'");
163 std::string fullParentName = declaration->getParentName();
164 LogDebug("Parent name: " << declaration->getParentName());
166 if (fullParentName == providedObjectName) {
167 LogDebug("Provided object match equaly to requested parent");
168 return register_(declaration, providedObject, context);
171 //check if object exists in fullParentName
172 auto pos = fullParentName.find(providedObjectName);
173 if (pos == string::npos) {
175 "Object: " << declaration->getName()
176 << " should be child of: " <<
177 declaration->getParentName()
178 << " but you provided object: " <<
184 if (fullParentName.size() <= pos + providedObjectName.size() + 1) {
185 LogError("Invalid object name");
189 auto currentRequesteProperty =
190 fullParentName.substr(pos + providedObjectName.size() + 1);
192 JSObjectPtr jsObject = getProperty(
193 currentRequesteProperty, providedObject);
195 if (!jsObject->getObject()) {
197 "Object: '" << declaration->getName()
198 << "' should be child of: '" <<
199 declaration->getParentName()
200 << "'. you provided object: '" <<
202 << "' but object is null");
207 return register_(declaration, jsObject, context);
210 bool Explorer::register_(const JSObjectDeclarationPtr& declaration,
212 JSGlobalContextRef context)
214 LogInfo("Registration object: " << declaration->getParentName() <<
215 "<-" << declaration->getName());
217 Assert(parent && "parent object is NULL");
219 typedef JSObjectDeclaration::Options JO;
221 JSGlobalContextRef gContext = (context == NULL) ? m_context : context;
222 JSObjectPtr newObject;
224 JSObjectPtr objectInstance = JavaScriptInterfaceSingleton::Instance().
225 createObject(gContext, declaration);
228 if (declaration->getOptions() &&
229 declaration->getOptions()->getType() == JO::ClassType::Function)
231 LogDebug("Loading function object " << declaration->getName());
233 auto type = declaration->getOptions()->getIframeOverlay();
234 if (JO::IFrameOverlay::OverlayedBeforeOriginal == type) {
235 LogDebug("Create overlayed function");
236 JSObjectPtr original =
237 JavaScriptInterfaceSingleton::Instance().
238 getJSObjectProperty(gContext,
240 declaration->getName());
241 newObject = JSOverlaySupport::
242 createWrappedFunction(gContext,
245 declaration->getName());
247 LogDebug("create normal function");
248 newObject = objectInstance;
250 } else { //object creation
251 newObject = objectInstance;
254 JavaScriptInterfaceSingleton::Instance().setObjectProperty(
257 declaration->getName(),
261 if (declaration->getOptions() &&
262 (declaration->getOptions()->getIframeNotice() ==
263 JO::IFrameNotice::AlwaysNotice))
265 declaration->getOptions()->invokeCallback(gContext,
267 objectInstance->getObject());
273 void Explorer::registerObjectIntoIframe(
274 const JSObjectDeclarationPtr& declaration,
275 JSObjectPtr frameObject,
276 JSGlobalContextRef context)
278 if (declaration->getParentName() == GLOBAL_OBJECT_NAME) {
279 LogDebug("Connect to Global object of IFRAME");
280 register_(declaration, frameObject, context);
286 LogWarning("Connect to NOT global object of IFRAME");
287 //it should be master object name
288 string masterName = declaration->getParentName();
289 auto pos = masterName.find(".");
290 if (string::npos != pos) {
291 LogError("ParentName not allowed");
294 auto masterObject = getJSObjectProperty(masterName, frameObject);
295 if (!masterObject->getObject()) {
296 LogError("Object not exist in frame");
299 register_(declaration, masterObject, context);
303 void Explorer::loadFrame(JSGlobalContextRef context)
305 LogDebug("Frame attached");
307 JSObjectPtr frameObject =
308 JavaScriptInterfaceSingleton::Instance().getGlobalObject(context);
310 LogDebug("Register main frame");
311 //register main frame;
313 if (frameObject->getObject() == m_globalObject->getObject()) {
314 // Main page was already loaded from constructor
315 LogDebug("Main page loaded");
319 m_iframeSupport.registerIframe(frameObject);
321 auto iframeObjects = m_iframeSupport.getIframeObjects();
323 FOREACH(object, iframeObjects)
325 LogDebug("Register object: " << (*object)->getName() );
327 registerObjectIntoIframe(*object, frameObject, context);
331 void Explorer::unloadFrame(JSGlobalContextRef context)
333 LogDebug("Frame detached");
335 JSObjectPtr frameObject =
336 JavaScriptInterfaceSingleton::Instance().getGlobalObject(context);
338 m_iframeSupport.unregisterIframe(frameObject);
341 void Explorer::removePluginsFromIframes()
343 LogDebug("Remove plugins from iframes");
345 if (m_iframeSupport.hasIframes()) {
346 LogDebug("Removing iframes");
347 JavaScriptInterfaceSingleton::Instance().removeIframes(m_context);
351 void Explorer::deregisterObject(const JSObjectDeclarationPtr& declaration)
353 LogDebug("Deregister object " << declaration->getName());
355 if (GLOBAL_OBJECT_NAME != declaration->getParentName()) {
356 LogWarning("Ignored remove property " << declaration->getName());
360 JavaScriptInterfaceSingleton::Instance().
361 removeObjectProperty(m_context,
363 declaration->getName());
366 void Explorer::cleanIframesData()
368 LogDebug("Clean iframes data");
369 m_iframeSupport.clean();
372 void Explorer::callEventListeners(CustomEventType eventType, void* data)
375 using namespace WrtPlugins::Tizen;
376 // get iframe objects from javascript global context
377 JavaScriptInterface::ObjectsListPtr frameLists =
378 JavaScriptInterfaceSingleton::Instance().getIframesList(m_context);
380 // get main frame object from javascript global context
381 JSObjectRef mainFrame = JSContextGetGlobalObject(m_context);
382 frameLists->push_back(JSObjectPtr(new JSObject(mainFrame)));
384 if (eventType == ServiceCustomEvent) {
385 using namespace WrtDeviceApis::TizenServiceEvent::Api;
386 // set user data of js callback function for 'appservice' js event
387 ITizenServiceEventPtr event = ITizenServiceEventPtr(
388 new TizenServiceEvent());
389 event->setScale(m_propertySupport->getScale());
390 event->setBundle(m_propertySupport->getBundle());
392 // call js callback function for 'appservice' js event on each frame
393 FOREACH(it, *frameLists)
395 JSObjectRef frame = static_cast<JSObjectRef>((*it).Get()->getObject());
398 new JSTizenServiceEventPrivateObject(m_context, event);
399 JSObjectRef eventObject =
400 JSObjectMake(m_context,
401 JSTizenServiceEvent::getClassRef(), eventPriv);
403 AddEventListenerSupport::CallCustomEventListenersFromIFrame(
404 frame, eventType, eventObject);
406 } else if (eventType == SoftKeyboardChangeCustomEvent) {
407 using namespace WrtDeviceApis::SoftKeyboardChangeEvent::Api;
409 LogDebug("no ime size");
413 // set user data of js callback function for 'softkeyboardchange' js
415 SoftKeyboardChangeArgs* args =
416 static_cast<SoftKeyboardChangeArgs *>(data);
417 ISoftKeyboardChangeEventPtr event =
418 ISoftKeyboardChangeEventPtr(
419 new SoftKeyboardChangeEvent(
423 LogInfo("softkeyboard event's state: " << args->state);
425 // call js callback function for 'softkeyboardchange' js event on each
427 FOREACH(it, *frameLists)
429 JSObjectRef frame = static_cast<JSObjectRef>((*it).Get()->getObject());
432 new JSSoftKeyboardChangeEventPrivateObject(m_context, event);
433 JSObjectRef eventObject =
436 JSSoftKeyboardChangeEvent::getClassRef(),
439 AddEventListenerSupport::CallCustomEventListenersFromIFrame(
440 frame, eventType, eventObject);
443 LogInfo("Not supported custom event type");
449 WindowPropertySupport* Explorer::getWindowPropertySupport()
451 return m_propertySupport.get();