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));
72 JSObjectPtr Explorer::getJSObjectProperty(const std::string& propertyName,
75 LogDebug("Get object property " << propertyName);
76 return JavaScriptInterfaceSingleton::Instance().getJSObjectProperty(
77 m_context, object, propertyName);
80 JSObjectPtr Explorer::getProperty(
81 const string& requestedProperty,
82 JSObjectPtr providedObject)
84 LogDebug("Requested Property: " << requestedProperty);
86 if (!providedObject) {
87 LogError("Provided object is empty");
91 std::string currentObjectName;
92 std::string currentPropertyRequested = requestedProperty;
93 JSObjectPtr currentObject = providedObject;
96 auto pos = currentPropertyRequested.find(".");
97 if (pos == string::npos) {
98 return getJSObjectProperty(currentPropertyRequested, currentObject);
101 //check if requested object has child
102 currentObjectName = currentPropertyRequested.substr(0, pos);
104 if (currentPropertyRequested.size() <= pos + 1) {
105 LogError("Wrong name of requested property");
106 return JSObjectPtr();
108 currentPropertyRequested = currentPropertyRequested.substr(pos + 1);
110 currentObject = getJSObjectProperty(currentObjectName, currentObject);
111 if (!currentObject) {
112 LogError("Failed to get property: " << currentObjectName);
113 return JSObjectPtr();
118 bool Explorer::registerObject(const JSObjectDeclarationPtr& declaration,
119 JSGlobalContextRef context)
121 LogDebug("Register to global object");
125 if (declaration->getParentName() == GLOBAL_OBJECT_NAME) {
126 LogDebug("Connect to Global object");
127 retValue = register_(declaration, m_globalObject, context);
128 } else { //PIM support
129 LogDebug("Connect to NOT global object");
130 //it should be master object name
131 string masterName = declaration->getParentName();
132 auto pos = masterName.find(".");
133 if (string::npos != pos) {
134 LogError("ParentName not allowed");
137 auto masterObject = getJSObjectProperty(masterName, m_globalObject);
138 if (masterObject->getObject() == 0) {
141 retValue = registerObject(declaration,
147 if (declaration->checkIframesSupported()) {
148 LogDebug("Iframe supported");
149 m_iframeSupport.registerDeclaration(declaration);
150 // m_iframeSupport.invokeCallbackForMainFrame(m_context,
154 LogDebug("Iframe NOT supported");
160 bool Explorer::registerObject(const JSObjectDeclarationPtr& declaration,
161 const std::string& providedObjectName,
162 JSObjectPtr providedObject,
163 JSGlobalContextRef context)
166 "Register object. Provided object name: '" << providedObjectName
168 "', registration of: '" << declaration->getName() << "'");
170 std::string fullParentName = declaration->getParentName();
171 LogDebug("Parent name: " << declaration->getParentName());
173 if (fullParentName == providedObjectName) {
174 LogDebug("Provided object match equaly to requested parent");
175 return register_(declaration, providedObject, context);
178 //check if object exists in fullParentName
179 auto pos = fullParentName.find(providedObjectName);
180 if (pos == string::npos) {
182 "Object: " << declaration->getName()
183 << " should be child of: " <<
184 declaration->getParentName()
185 << " but you provided object: " <<
191 if (fullParentName.size() <= pos + providedObjectName.size() + 1) {
192 LogError("Invalid object name");
196 auto currentRequesteProperty =
197 fullParentName.substr(pos + providedObjectName.size() + 1);
199 JSObjectPtr jsObject = getProperty(
200 currentRequesteProperty, providedObject);
202 if (!jsObject->getObject()) {
204 "Object: '" << declaration->getName()
205 << "' should be child of: '" <<
206 declaration->getParentName()
207 << "'. you provided object: '" <<
209 << "' but object is null");
214 return register_(declaration, jsObject, context);
217 bool Explorer::register_(const JSObjectDeclarationPtr& declaration,
219 JSGlobalContextRef context)
221 LogInfo("Registration object: " << declaration->getParentName() <<
222 "<-" << declaration->getName());
224 Assert(parent && "parent object is NULL");
226 typedef JSObjectDeclaration::Options JO;
228 JSGlobalContextRef gContext = (context == NULL) ? m_context : context;
229 JSObjectPtr newObject;
231 JSObjectPtr objectInstance = JavaScriptInterfaceSingleton::Instance().
232 createObject(gContext, declaration);
235 if (declaration->getOptions() &&
236 declaration->getOptions()->getType() == JO::ClassType::Function)
238 LogDebug("Loading function object " << declaration->getName());
240 auto type = declaration->getOptions()->getIframeOverlay();
241 if (JO::IFrameOverlay::OverlayedBeforeOriginal == type) {
242 LogDebug("Create overlayed function");
243 JSObjectPtr original =
244 JavaScriptInterfaceSingleton::Instance().
245 getJSObjectProperty(gContext,
247 declaration->getName());
248 newObject = JSOverlaySupport::
249 createWrappedFunction(gContext,
252 declaration->getName());
254 LogDebug("create normal function");
255 newObject = objectInstance;
257 } else { //object creation
258 newObject = objectInstance;
261 JavaScriptInterfaceSingleton::Instance().setObjectProperty(
264 declaration->getName(),
268 if (declaration->getOptions() &&
269 (declaration->getOptions()->getIframeNotice() ==
270 JO::IFrameNotice::AlwaysNotice))
272 declaration->getOptions()->invokeCallback(gContext,
274 objectInstance->getObject());
280 void Explorer::registerObjectIntoIframe(
281 const JSObjectDeclarationPtr& declaration,
282 JSObjectPtr frameObject,
283 JSGlobalContextRef context)
285 if (declaration->getParentName() == GLOBAL_OBJECT_NAME) {
286 LogDebug("Connect to Global object of IFRAME");
287 register_(declaration, frameObject, context);
293 LogWarning("Connect to NOT global object of IFRAME");
294 //it should be master object name
295 string masterName = declaration->getParentName();
296 auto pos = masterName.find(".");
297 if (string::npos != pos) {
298 LogError("ParentName not allowed");
301 auto masterObject = getJSObjectProperty(masterName, frameObject);
302 if (!masterObject->getObject()) {
303 LogError("Object not exist in frame");
306 register_(declaration, masterObject, context);
310 void Explorer::loadFrame(JSGlobalContextRef context)
312 LogDebug("Frame attached");
314 JSObjectPtr frameObject =
315 JavaScriptInterfaceSingleton::Instance().getGlobalObject(context);
317 LogDebug("Register main frame");
318 //register main frame;
320 if (frameObject->getObject() == m_globalObject->getObject()) {
321 // Main page was already loaded from constructor
322 LogDebug("Main page loaded");
326 m_iframeSupport.registerIframe(frameObject);
328 auto iframeObjects = m_iframeSupport.getIframeObjects();
330 FOREACH(object, iframeObjects)
332 LogDebug("Register object: " << (*object)->getName() );
334 registerObjectIntoIframe(*object, frameObject, context);
338 void Explorer::unloadFrame(JSGlobalContextRef context)
340 LogDebug("Frame detached");
342 JSObjectPtr frameObject =
343 JavaScriptInterfaceSingleton::Instance().getGlobalObject(context);
345 AddEventListenerSupport::RemoveIFrame(frameObject);
346 m_iframeSupport.unregisterIframe(frameObject);
349 void Explorer::removePluginsFromIframes()
351 LogDebug("Remove plugins from iframes");
353 if (m_iframeSupport.hasIframes()) {
354 LogDebug("Removing iframes");
355 JavaScriptInterfaceSingleton::Instance().removeIframes(m_context);
359 void Explorer::deregisterObject(const JSObjectDeclarationPtr& declaration)
361 LogDebug("Deregister object " << declaration->getName());
363 if (GLOBAL_OBJECT_NAME != declaration->getParentName()) {
364 LogWarning("Ignored remove property " << declaration->getName());
368 JavaScriptInterfaceSingleton::Instance().
369 removeObjectProperty(m_context,
371 declaration->getName());
374 void Explorer::cleanIframesData()
376 LogDebug("Clean iframes data");
377 m_iframeSupport.clean();
380 void Explorer::callEventListeners(CustomEventType eventType, void* data)
382 using namespace WrtPlugins::Tizen;
383 // get iframe objects from javascript global context
384 JavaScriptInterface::ObjectsListPtr frameLists =
385 JavaScriptInterfaceSingleton::Instance().getIframesList(m_context);
387 // get main frame object from javascript global context
388 JSObjectRef mainFrame = JSContextGetGlobalObject(m_context);
389 frameLists->push_back(JSObjectPtr(new JSObject(mainFrame)));
391 if (eventType == ServiceCustomEvent) {
392 using namespace WrtDeviceApis::TizenServiceEvent::Api;
393 // set user data of js callback function for 'appservice' js event
394 ITizenServiceEventPtr event = ITizenServiceEventPtr(
395 new TizenServiceEvent());
396 event->setScale(m_propertySupport->getScale());
397 event->setBundle(m_propertySupport->getBundle());
399 // call js callback function for 'appservice' js event on each frame
400 FOREACH(it, *frameLists)
402 JSObjectRef frame = static_cast<JSObjectRef>((*it).Get()->getObject());
405 new JSTizenServiceEventPrivateObject(m_context, event);
406 JSObjectRef eventObject =
407 JSObjectMake(m_context,
408 JSTizenServiceEvent::getClassRef(), eventPriv);
410 AddEventListenerSupport::CallCustomEventListenersFromIFrame(
411 frame, eventType, eventObject);
413 } else if (eventType == SoftKeyboardChangeCustomEvent) {
414 using namespace WrtDeviceApis::SoftKeyboardChangeEvent::Api;
416 LogDebug("no ime size");
420 // set user data of js callback function for 'softkeyboardchange' js
422 SoftKeyboardChangeArgs* args =
423 static_cast<SoftKeyboardChangeArgs *>(data);
424 ISoftKeyboardChangeEventPtr event =
425 ISoftKeyboardChangeEventPtr(
426 new SoftKeyboardChangeEvent(
430 LogInfo("softkeyboard event's state: " << args->state);
432 // call js callback function for 'softkeyboardchange' js event on each
434 FOREACH(it, *frameLists)
436 JSObjectRef frame = static_cast<JSObjectRef>((*it).Get()->getObject());
439 new JSSoftKeyboardChangeEventPrivateObject(m_context, event);
440 JSObjectRef eventObject =
443 JSSoftKeyboardChangeEvent::getClassRef(),
446 AddEventListenerSupport::CallCustomEventListenersFromIFrame(
447 frame, eventType, eventObject);
450 LogInfo("Not supported custom event type");
455 WindowPropertySupport* Explorer::getWindowPropertySupport()
457 return m_propertySupport.get();