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.
19 * @author Grzegorz Krawczyk (g.krawczyk@samsung.com)
25 #include <CommonsJavaScript/Converter.h>
26 #include <dpl/log/log.h>
27 #include <dpl/assert.h>
28 #include <Widget/WidgetFactory.h>
29 #include <CommonsJavaScript/JSDOMExceptionFactory.h>
30 #include "JSPreferences.h"
31 #include <Widget/IWidget.h>
32 #include <LocalStorage/LocalStorageMgr.h>
33 #include <Commons/WrtAccess/WrtAccess.h>
34 #include <js-overlay/js_iframe_support.h>
37 #define CATCH_EXCEPTION_NO_MODIFABLE \
38 Catch(Commons::LocalStorageValueNoModifableException) {\
39 LogError("The item is read only");\
40 return JSDOMExceptionFactory::\
41 NoModificationAllowedException.make(context, exception);\
44 #define CATCH_EXCEPTION_CONVERSION \
45 Catch(Commons::ConversionException) {\
46 LogError("Error on conversion");\
47 return JSDOMExceptionFactory::\
48 UnknownException.make(context, exception);\
51 #define CATCH_EXCEPTION_NULL_PTR \
52 Catch(Commons::NullPointerException) {\
53 LogError("Error on pointer, null value");\
54 return JSDOMExceptionFactory::\
55 UnknownException.make(context, exception);\
58 #define CATCH_EXCEPTION_PLATFORM_ERROR \
59 Catch(Commons::PlatformException){\
60 LogError("PlatformException occured");\
61 return JSDOMExceptionFactory::\
62 UnknownException.make(context, exception);\
65 #define CATCH_EXCEPTION_SECURITY \
66 Catch(Commons::SecurityException){\
67 LogError("Security exception occured");\
68 return JSDOMExceptionFactory::\
69 SecurityException.make(context, exception);\
72 #define CATCH_EXCEPTION_OUT_OF_RANGE \
73 Catch(Commons::OutOfRangeException) {\
74 LogError("OutOfRangeException");\
75 return JSDOMExceptionFactory::\
76 QuotaExceededException.make(context, exception);\
79 #define CATCH_EXCEPTION_INVALID_ARG \
80 Catch(Commons::InvalidArgumentException) {\
81 LogError("Pair for given key doesnt exist");\
82 return JSValueMakeNull(context);\
85 #define WIDGET_PLUGIN_NAME "Widget"
87 #define WRT_WIDGET_PROPERTY_AUTHOR "author"
88 #define WRT_WIDGET_PROPERTY_AUTHOR_EMAIL "authorEmail"
89 #define WRT_WIDGET_PROPERTY_AUTHOR_HREF "authorHref"
90 #define WRT_WIDGET_PROPERTY_DESCRIPTION "description"
91 #define WRT_WIDGET_PROPERTY_ID "id"
92 #define WRT_WIDGET_PROPERTY_NAME "name"
93 #define WRT_WIDGET_PROPERTY_SHORT_NAME "shortName"
94 #define WRT_WIDGET_PROPERTY_VERSION "version"
95 #define WRT_WIDGET_PROPERTY_HEIGHT "height"
96 #define WRT_WIDGET_PROPERTY_WIDTH "width"
98 namespace WrtPlugins {
101 using namespace WrtDeviceApis;
102 using namespace WrtDeviceApis::Commons;
103 using namespace WrtDeviceApis::CommonsJavaScript;
104 using namespace WrtDeviceApis::Widget;
107 struct WidgetPrivateObject
109 Widget::Api::IWidgetPtr iwidget;
110 JSObjectRef preferencesObject;
113 JSObjectRef widgetObject;
115 typedef std::shared_ptr<WidgetPrivateObject> WidgetPrivateObjectPtr;
117 typedef WrtDeviceApis::CommonsJavaScript::PrivateObjectT
118 <WidgetPrivateObjectPtr>::Type JSWidgetPrivateObject;
120 WrtDeviceApis::Widget::Api::IWidgetPtr getIWidget(JSObjectRef arg)
122 JSWidgetPrivateObject* priv =
123 static_cast<JSWidgetPrivateObject*>(JSObjectGetPrivate(arg));
126 LogError("Private object not initialized");
127 ThrowMsg(Commons::NullPointerException,
128 "Private object not initialized");
131 return priv->getObject()->iwidget;
135 LocalStorage::Api::ILocalStoragePtr getLocalStorage(int widgetId)
137 LocalStorage::Api::ILocalStoragePtr storage(
138 LocalStorage::Api::getLocalStorage(widgetId));
143 JSObjectRef getPreferences(JSObjectRef arg)
145 JSWidgetPrivateObject* priv =
146 static_cast<JSWidgetPrivateObject*>(JSObjectGetPrivate(arg));
149 LogError("Private object not initialized");
153 return priv->getObject()->preferencesObject;
156 JSObjectRef createPreferencesObject(JSContextRef context,
157 JSObjectRef widgetObject,
160 Assert(widgetObject && "Widget Object can'n be null");
161 //delete is invoked in JSPreferences::finalize
162 LocalStoragePrivateData* priv = new LocalStoragePrivateData;
163 Assert(priv && "Private data is null");
164 priv->istorage = getLocalStorage(widgetId);
165 priv->widgetObject = widgetObject;
167 JSObjectRef preferences = JSObjectMake(context,
168 JSPreferences::getClassRef(),
172 LogError("Preferences object is null");
175 //Unprotect is called in JSWidget::finalize
176 JSValueProtect(context, preferences);
182 JSClassDefinition JSWidget::m_classInfo = {
184 kJSClassAttributeNone,
194 NULL, //DeleteProperty,
195 NULL, //GetPropertyNames,
196 NULL, //CallAsFunction,
199 NULL, //ConvertToType,
202 JSStaticValue JSWidget::m_property[] = {
203 { WRT_WIDGET_PROPERTY_AUTHOR, JSWidget::getAuthor,
204 0, kJSPropertyAttributeReadOnly },
205 { WRT_WIDGET_PROPERTY_AUTHOR_EMAIL, JSWidget::getAuthorEmail,
206 0, kJSPropertyAttributeReadOnly },
207 { WRT_WIDGET_PROPERTY_AUTHOR_HREF, JSWidget::getAuthorHref,
208 0, kJSPropertyAttributeReadOnly },
209 { WRT_WIDGET_PROPERTY_DESCRIPTION, JSWidget::getDescription,
210 0, kJSPropertyAttributeReadOnly },
211 { WRT_WIDGET_PROPERTY_ID, JSWidget::getId,
212 0, kJSPropertyAttributeReadOnly },
213 { WRT_WIDGET_PROPERTY_NAME, JSWidget::getName,
214 0, kJSPropertyAttributeReadOnly },
215 { WRT_WIDGET_PROPERTY_SHORT_NAME, JSWidget::getShortName,
216 0, kJSPropertyAttributeReadOnly },
217 { WRT_WIDGET_PROPERTY_VERSION, JSWidget::getVersion,
218 0, kJSPropertyAttributeReadOnly },
219 { WRT_WIDGET_PROPERTY_HEIGHT, JSWidget::getHeight,
220 0, kJSPropertyAttributeReadOnly },
221 { WRT_WIDGET_PROPERTY_WIDTH, JSWidget::getWidth,
222 0, kJSPropertyAttributeReadOnly },
226 const JSClassRef JSWidget::getClassRef()
229 m_jsClassRef = JSClassCreate(&m_classInfo);
234 const JSClassDefinition* JSWidget::getClassInfo()
239 JSClassRef JSWidget::m_jsClassRef = JSClassCreate(JSWidget::getClassInfo());
241 JSContextRef JSWidget::m_globalContext = NULL;
243 void JSWidget::initialize(JSContextRef context,
246 LogDebug("entered. Context : " << context);
247 LogDebug("Object: " << object);
249 JSWidgetPrivateObject* priv =
250 static_cast<JSWidgetPrivateObject*>(JSObjectGetPrivate(object));
253 LogDebug("creation private object");
256 using namespace WrtDeviceApis::Commons;
258 Widget::Api::IWidgetPtr widget =
259 Api::WidgetFactory::createWidget();
260 int widgetId = WrtAccessSingleton::Instance().getWidgetId();
261 JSObjectRef preferences =
262 createPreferencesObject(context,
266 LogError("Failed to create preferences object");
269 WidgetPrivateObjectPtr widgetPriv(new WidgetPrivateObject);
270 widgetPriv->iwidget = widget;
271 widgetPriv->preferencesObject = preferences;
273 priv = new JSWidgetPrivateObject(context, widgetPriv);
274 JSObjectSetPrivate(object, priv);
275 LogDebug("private object created");
278 Catch(Commons::InvalidArgumentException){
279 LogError("You should register widget id in ON_WIDGET_START");
282 Catch(DPL::Exception) {
283 LogError("Failed to create private object for JSWidget");
290 void JSWidget::finalize(JSObjectRef object)
293 LogDebug("Object: " << object);
294 JSWidgetPrivateObject* priv =
295 static_cast<JSWidgetPrivateObject*>(JSObjectGetPrivate(object));
298 JSValueUnprotect(priv->getContext(),
299 priv->getObject()->preferencesObject);
302 LogDebug("private object is released");
304 LogDebug("private object wasn't created");
308 void JSWidget::acquireGlobalContext(java_script_context_t global_context,
309 js_object_instance_t iframe,
310 js_object_instance_t object)
312 IFrameSupport::RegisterWidget(global_context, iframe, object);
313 if (!m_globalContext) {
314 m_globalContext = static_cast<JSContextRef>(global_context);
315 LogInfo("Global context acquired.");
317 LogInfo("Global context already set.");
321 JSValueRef JSWidget::getAuthor(JSContextRef context,
323 JSStringRef propertyName,
324 JSValueRef* exception)
329 Converter converter(context);
330 return converter.toJSValueRef(getIWidget(object)->getAuthor());
332 CATCH_EXCEPTION_CONVERSION
333 CATCH_EXCEPTION_NULL_PTR
334 CATCH_EXCEPTION_PLATFORM_ERROR
337 JSValueRef JSWidget::getAuthorEmail(JSContextRef context,
339 JSStringRef propertyName,
340 JSValueRef* exception)
343 Converter converter(context);
344 return converter.toJSValueRef(getIWidget(object)->getAuthorEmail());
346 CATCH_EXCEPTION_CONVERSION
347 CATCH_EXCEPTION_NULL_PTR
348 CATCH_EXCEPTION_PLATFORM_ERROR
351 JSValueRef JSWidget::getAuthorHref(JSContextRef context,
353 JSStringRef propertyName,
354 JSValueRef* exception)
357 Converter converter(context);
358 return converter.toJSValueRef(getIWidget(object)->getAuthorHref());
360 CATCH_EXCEPTION_CONVERSION
361 CATCH_EXCEPTION_NULL_PTR
362 CATCH_EXCEPTION_PLATFORM_ERROR
365 JSValueRef JSWidget::getDescription(JSContextRef context,
367 JSStringRef propertyName,
368 JSValueRef* exception)
371 Converter converter(context);
372 return converter.toJSValueRef(getIWidget(object)->getDescription());
374 CATCH_EXCEPTION_CONVERSION
375 CATCH_EXCEPTION_NULL_PTR
376 CATCH_EXCEPTION_PLATFORM_ERROR
379 JSValueRef JSWidget::getId(JSContextRef context,
381 JSStringRef propertyName,
382 JSValueRef* exception)
385 Converter converter(context);
386 return converter.toJSValueRef(getIWidget(object)->getId());
388 CATCH_EXCEPTION_CONVERSION
389 CATCH_EXCEPTION_NULL_PTR
390 CATCH_EXCEPTION_PLATFORM_ERROR
393 JSValueRef JSWidget::getName(JSContextRef context,
395 JSStringRef propertyName,
396 JSValueRef* exception)
399 Converter converter(context);
400 return converter.toJSValueRef(getIWidget(object)->getName());
402 CATCH_EXCEPTION_CONVERSION
403 CATCH_EXCEPTION_NULL_PTR
404 CATCH_EXCEPTION_PLATFORM_ERROR
407 JSValueRef JSWidget::getShortName(JSContextRef context,
409 JSStringRef propertyName,
410 JSValueRef* exception)
413 Converter converter(context);
414 return converter.toJSValueRef(getIWidget(object)->getShortName());
416 CATCH_EXCEPTION_CONVERSION
417 CATCH_EXCEPTION_NULL_PTR
418 CATCH_EXCEPTION_PLATFORM_ERROR
421 JSValueRef JSWidget::getVersion(JSContextRef context,
423 JSStringRef propertyName,
424 JSValueRef* exception)
427 Converter converter(context);
428 return converter.toJSValueRef(getIWidget(object)->getVersion());
430 CATCH_EXCEPTION_CONVERSION
431 CATCH_EXCEPTION_NULL_PTR
432 CATCH_EXCEPTION_PLATFORM_ERROR
435 JSValueRef JSWidget::getHeight(JSContextRef context,
437 JSStringRef propertyName,
438 JSValueRef* exception)
441 Converter converter(context);
442 unsigned int height = getIWidget(object)->getHeight();
446 return converter.toJSValueRef(height);
448 CATCH_EXCEPTION_CONVERSION
449 CATCH_EXCEPTION_NULL_PTR
450 CATCH_EXCEPTION_PLATFORM_ERROR
453 JSValueRef JSWidget::getWidth(JSContextRef context,
455 JSStringRef propertyName,
456 JSValueRef* exception)
459 Converter converter(context);
460 unsigned int width = getIWidget(object)->getWidth();
464 return converter.toJSValueRef(width);
466 CATCH_EXCEPTION_CONVERSION
467 CATCH_EXCEPTION_NULL_PTR
468 CATCH_EXCEPTION_PLATFORM_ERROR
471 bool JSWidget::hasProperty(JSContextRef context,
473 JSStringRef propertyName)
478 Converter converter(context);
480 std::string key = converter.toString(propertyName);
481 if (key == "preferences") {
485 Catch(Commons::InvalidArgumentException) {
486 LogDebug("Pair for given key doesnt exist");
489 Catch(Commons::ConversionException) {
490 LogError("Error on conversion");
493 Catch(Commons::NullPointerException) {
494 LogError("Error on pointer, null value");
497 Catch(Commons::PlatformException){
498 LogError("PlatformException occured");
503 JSValueRef JSWidget::getProperty(JSContextRef context,
505 JSStringRef propertyName,
506 JSValueRef* exception)
508 LogDebug("Object: " << object);
511 Converter converter(context);
513 std::string key = converter.toString(propertyName);
515 if (key=="preferences") {
516 Converter converter(context);
517 JSObjectRef pref = getPreferences(object);
520 LogError("Preferences object is NULL");
521 return JSValueMakeUndefined(context);
525 LogError("Property NOT supported: " << propertyName);
526 return JSValueMakeUndefined(context);
529 CATCH_EXCEPTION_CONVERSION
530 CATCH_EXCEPTION_NULL_PTR
531 CATCH_EXCEPTION_INVALID_ARG
534 bool JSWidget::setProperty(JSContextRef context,
536 JSStringRef propertyName,
538 JSValueRef* exception)
543 Converter converter(context);
545 std::string key = converter.toString(propertyName);
546 if (key == "preferences"){
547 LogError("Object is read only");
551 CATCH_EXCEPTION_INVALID_ARG
552 CATCH_EXCEPTION_CONVERSION
553 CATCH_EXCEPTION_NULL_PTR
558 JSObjectRef JSWidget::callAsConstructor(JSContextRef context,
559 JSObjectRef constructor,
560 size_t argumentCount,
561 const JSValueRef arguments[],
562 JSValueRef* exception)
564 LogDebug("widget constructor");
565 if (!m_globalContext) {
566 LogError("Global context not set. Creating 'widget' object with "
568 return JSObjectMake(context, JSWidget::getClassRef(), NULL);
570 return JSObjectMake(m_globalContext, JSWidget::getClassRef(), NULL);
573 #undef CATCH_EXCEPTION_NO_MODIFABLE
574 #undef CATCH_EXCEPTION_CONVERSION
575 #undef CATCH_EXCEPTION_NULL_PTR
576 #undef CATCH_EXCEPTION_PLATFORM_ERROR
577 #undef CATCH_EXCEPTION_SECURITY
578 #undef CATCH_EXCEPTION_OUT_OF_RANGE
579 #undef CATCH_EXCEPTION_INVALID_ARG