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>
35 #define CATCH_EXCEPTION_NO_MODIFABLE \
36 Catch(Commons::LocalStorageValueNoModifableException) { \
37 LogError("The item is read only"); \
38 return JSDOMExceptionFactory:: \
39 NoModificationAllowedException.make(context, exception); \
42 #define CATCH_EXCEPTION_CONVERSION \
43 Catch(Commons::ConversionException) { \
44 LogError("Error on conversion"); \
45 return JSDOMExceptionFactory:: \
46 UnknownException.make(context, exception); \
49 #define CATCH_EXCEPTION_NULL_PTR \
50 Catch(Commons::NullPointerException) { \
51 LogError("Error on pointer, null value"); \
52 return JSDOMExceptionFactory:: \
53 UnknownException.make(context, exception); \
56 #define CATCH_EXCEPTION_PLATFORM_ERROR \
57 Catch(Commons::PlatformException){ \
58 LogError("PlatformException occured"); \
59 return JSDOMExceptionFactory:: \
60 UnknownException.make(context, exception); \
63 #define CATCH_EXCEPTION_SECURITY \
64 Catch(Commons::SecurityException){ \
65 LogError("Security exception occured"); \
66 return JSDOMExceptionFactory:: \
67 SecurityException.make(context, exception); \
70 #define CATCH_EXCEPTION_OUT_OF_RANGE \
71 Catch(Commons::OutOfRangeException) { \
72 LogError("OutOfRangeException"); \
73 return JSDOMExceptionFactory:: \
74 QuotaExceededException.make(context, exception); \
77 #define CATCH_EXCEPTION_INVALID_ARG \
78 Catch(Commons::InvalidArgumentException) { \
79 LogError("Pair for given key doesnt exist"); \
80 return JSValueMakeNull(context); \
83 #define WIDGET_PLUGIN_NAME "Widget"
85 #define WRT_WIDGET_PROPERTY_AUTHOR "author"
86 #define WRT_WIDGET_PROPERTY_AUTHOR_EMAIL "authorEmail"
87 #define WRT_WIDGET_PROPERTY_AUTHOR_HREF "authorHref"
88 #define WRT_WIDGET_PROPERTY_DESCRIPTION "description"
89 #define WRT_WIDGET_PROPERTY_ID "id"
90 #define WRT_WIDGET_PROPERTY_NAME "name"
91 #define WRT_WIDGET_PROPERTY_SHORT_NAME "shortName"
92 #define WRT_WIDGET_PROPERTY_VERSION "version"
93 #define WRT_WIDGET_PROPERTY_HEIGHT "height"
94 #define WRT_WIDGET_PROPERTY_WIDTH "width"
96 namespace WrtPlugins {
98 using namespace WrtDeviceApis;
99 using namespace WrtDeviceApis::Commons;
100 using namespace WrtDeviceApis::CommonsJavaScript;
101 using namespace WrtDeviceApis::Widget;
103 struct WidgetPrivateObject
105 Widget::Api::IWidgetPtr iwidget;
106 JSObjectRef preferencesObject;
108 //int widgetId // TODO: check is it necessary (g.rynkowski)
109 JSObjectRef widgetObject;
111 typedef std::shared_ptr<WidgetPrivateObject> WidgetPrivateObjectPtr;
113 typedef WrtDeviceApis::CommonsJavaScript::PrivateObjectT
114 <WidgetPrivateObjectPtr>::Type JSWidgetPrivateObject;
116 WrtDeviceApis::Widget::Api::IWidgetPtr getIWidget(JSObjectRef arg)
118 JSWidgetPrivateObject* priv =
119 static_cast<JSWidgetPrivateObject*>(JSObjectGetPrivate(arg));
122 LogError("Private object not initialized");
123 ThrowMsg(Commons::NullPointerException,
124 "Private object not initialized");
127 return priv->getObject()->iwidget;
130 LocalStorage::Api::ILocalStoragePtr getLocalStorage(int widgetId)
132 LocalStorage::Api::ILocalStoragePtr storage(
133 LocalStorage::Api::getLocalStorage(widgetId));
138 JSObjectRef getPreferences(JSObjectRef arg)
140 JSWidgetPrivateObject* priv =
141 static_cast<JSWidgetPrivateObject*>(JSObjectGetPrivate(arg));
144 LogError("Private object not initialized");
148 return priv->getObject()->preferencesObject;
151 JSObjectRef createPreferencesObject(JSContextRef context,
152 JSObjectRef widgetObject,
155 Assert(widgetObject && "Widget Object can'n be null");
156 //delete is invoked in JSPreferences::finalize
157 LocalStoragePrivateData* priv = new LocalStoragePrivateData;
158 Assert(priv && "Private data is null");
159 priv->istorage = getLocalStorage(widgetId);
160 priv->widgetObject = widgetObject;
162 JSObjectRef preferences = JSObjectMake(context,
163 JSPreferences::getClassRef(),
167 LogError("Preferences object is null");
170 //Unprotect is called in JSWidget::finalize
171 JSValueProtect(context, preferences);
176 JSClassDefinition JSWidget::m_classInfo = {
178 kJSClassAttributeNone,
188 NULL, //DeleteProperty,
189 NULL, //GetPropertyNames,
190 NULL, //CallAsFunction,
193 NULL, //ConvertToType,
196 JSStaticValue JSWidget::m_property[] = {
197 { WRT_WIDGET_PROPERTY_AUTHOR, JSWidget::getAuthor,
198 0, kJSPropertyAttributeReadOnly },
199 { WRT_WIDGET_PROPERTY_AUTHOR_EMAIL, JSWidget::getAuthorEmail,
200 0, kJSPropertyAttributeReadOnly },
201 { WRT_WIDGET_PROPERTY_AUTHOR_HREF, JSWidget::getAuthorHref,
202 0, kJSPropertyAttributeReadOnly },
203 { WRT_WIDGET_PROPERTY_DESCRIPTION, JSWidget::getDescription,
204 0, kJSPropertyAttributeReadOnly },
205 { WRT_WIDGET_PROPERTY_ID, JSWidget::getId,
206 0, kJSPropertyAttributeReadOnly },
207 { WRT_WIDGET_PROPERTY_NAME, JSWidget::getName,
208 0, kJSPropertyAttributeReadOnly },
209 { WRT_WIDGET_PROPERTY_SHORT_NAME, JSWidget::getShortName,
210 0, kJSPropertyAttributeReadOnly },
211 { WRT_WIDGET_PROPERTY_VERSION, JSWidget::getVersion,
212 0, kJSPropertyAttributeReadOnly },
213 { WRT_WIDGET_PROPERTY_HEIGHT, JSWidget::getHeight,
214 0, kJSPropertyAttributeReadOnly },
215 { WRT_WIDGET_PROPERTY_WIDTH, JSWidget::getWidth,
216 0, kJSPropertyAttributeReadOnly },
220 JSClassRef JSWidget::getClassRef()
223 m_jsClassRef = JSClassCreate(&m_classInfo);
228 const JSClassDefinition* JSWidget::getClassInfo()
233 JSClassRef JSWidget::m_jsClassRef = JSClassCreate(JSWidget::getClassInfo());
235 JSContextRef JSWidget::m_globalContext = NULL;
237 void JSWidget::initialize(JSContextRef context,
240 LogDebug("entered. Context : " << context);
241 LogDebug("Object: " << object);
243 JSWidgetPrivateObject* priv =
244 static_cast<JSWidgetPrivateObject*>(JSObjectGetPrivate(object));
247 LogDebug("creation private object");
250 using namespace WrtDeviceApis::Commons;
252 Widget::Api::IWidgetPtr widget =
253 Api::WidgetFactory::createWidget();
254 int widgetId = WrtAccessSingleton::Instance().getWidgetId();
255 JSObjectRef preferences =
256 createPreferencesObject(context,
260 LogError("Failed to create preferences object");
263 WidgetPrivateObjectPtr widgetPriv(new WidgetPrivateObject);
264 widgetPriv->iwidget = widget;
265 widgetPriv->preferencesObject = preferences;
267 priv = new JSWidgetPrivateObject(context, widgetPriv);
268 JSObjectSetPrivate(object, priv);
269 LogDebug("private object created");
271 Catch(Commons::InvalidArgumentException){
272 LogError("You should register widget id in ON_WIDGET_START");
275 Catch(DPL::Exception) {
276 LogError("Failed to create private object for JSWidget");
282 void JSWidget::finalize(JSObjectRef object)
285 LogDebug("Object: " << object);
286 JSWidgetPrivateObject* priv =
287 static_cast<JSWidgetPrivateObject*>(JSObjectGetPrivate(object));
290 JSValueUnprotect(priv->getContext(),
291 priv->getObject()->preferencesObject);
294 LogDebug("private object is released");
296 LogDebug("private object wasn't created");
300 void JSWidget::acquireGlobalContext(java_script_context_t global_context,
301 js_object_instance_t iframe,
302 js_object_instance_t object)
304 if (!m_globalContext) {
305 m_globalContext = static_cast<JSContextRef>(global_context);
306 LogInfo("Global context acquired.");
308 LogInfo("Global context already set.");
312 JSValueRef JSWidget::getAuthor(JSContextRef context,
314 JSStringRef /*propertyName*/,
315 JSValueRef* exception)
320 Converter converter(context);
321 return converter.toJSValueRef(getIWidget(object)->getAuthor());
323 CATCH_EXCEPTION_CONVERSION
324 CATCH_EXCEPTION_NULL_PTR
325 CATCH_EXCEPTION_PLATFORM_ERROR
328 JSValueRef JSWidget::getAuthorEmail(JSContextRef context,
330 JSStringRef /*propertyName*/,
331 JSValueRef* exception)
334 Converter converter(context);
335 return converter.toJSValueRef(getIWidget(object)->getAuthorEmail());
337 CATCH_EXCEPTION_CONVERSION
338 CATCH_EXCEPTION_NULL_PTR
339 CATCH_EXCEPTION_PLATFORM_ERROR
342 JSValueRef JSWidget::getAuthorHref(JSContextRef context,
344 JSStringRef /*propertyName*/,
345 JSValueRef* exception)
348 Converter converter(context);
349 return converter.toJSValueRef(getIWidget(object)->getAuthorHref());
351 CATCH_EXCEPTION_CONVERSION
352 CATCH_EXCEPTION_NULL_PTR
353 CATCH_EXCEPTION_PLATFORM_ERROR
356 JSValueRef JSWidget::getDescription(JSContextRef context,
358 JSStringRef /*propertyName*/,
359 JSValueRef* exception)
362 Converter converter(context);
363 return converter.toJSValueRef(getIWidget(object)->getDescription());
365 CATCH_EXCEPTION_CONVERSION
366 CATCH_EXCEPTION_NULL_PTR
367 CATCH_EXCEPTION_PLATFORM_ERROR
370 JSValueRef JSWidget::getId(JSContextRef context,
372 JSStringRef /*propertyName*/,
373 JSValueRef* exception)
376 Converter converter(context);
377 return converter.toJSValueRef(getIWidget(object)->getId());
379 CATCH_EXCEPTION_CONVERSION
380 CATCH_EXCEPTION_NULL_PTR
381 CATCH_EXCEPTION_PLATFORM_ERROR
384 JSValueRef JSWidget::getName(JSContextRef context,
386 JSStringRef /*propertyName*/,
387 JSValueRef* exception)
390 Converter converter(context);
391 return converter.toJSValueRef(getIWidget(object)->getName());
393 CATCH_EXCEPTION_CONVERSION
394 CATCH_EXCEPTION_NULL_PTR
395 CATCH_EXCEPTION_PLATFORM_ERROR
398 JSValueRef JSWidget::getShortName(JSContextRef context,
400 JSStringRef /*propertyName*/,
401 JSValueRef* exception)
404 Converter converter(context);
405 return converter.toJSValueRef(getIWidget(object)->getShortName());
407 CATCH_EXCEPTION_CONVERSION
408 CATCH_EXCEPTION_NULL_PTR
409 CATCH_EXCEPTION_PLATFORM_ERROR
412 JSValueRef JSWidget::getVersion(JSContextRef context,
414 JSStringRef /*propertyName*/,
415 JSValueRef* exception)
418 Converter converter(context);
419 return converter.toJSValueRef(getIWidget(object)->getVersion());
421 CATCH_EXCEPTION_CONVERSION
422 CATCH_EXCEPTION_NULL_PTR
423 CATCH_EXCEPTION_PLATFORM_ERROR
426 JSValueRef JSWidget::getHeight(JSContextRef context,
428 JSStringRef /*propertyName*/,
429 JSValueRef* exception)
432 Converter converter(context);
433 unsigned int height = getIWidget(object)->getHeight();
437 return converter.toJSValueRef(height);
439 CATCH_EXCEPTION_CONVERSION
440 CATCH_EXCEPTION_NULL_PTR
441 CATCH_EXCEPTION_PLATFORM_ERROR
444 JSValueRef JSWidget::getWidth(JSContextRef context,
446 JSStringRef /*propertyName*/,
447 JSValueRef* exception)
450 Converter converter(context);
451 unsigned int width = getIWidget(object)->getWidth();
455 return converter.toJSValueRef(width);
457 CATCH_EXCEPTION_CONVERSION
458 CATCH_EXCEPTION_NULL_PTR
459 CATCH_EXCEPTION_PLATFORM_ERROR
462 bool JSWidget::hasProperty(JSContextRef context,
463 JSObjectRef /*object*/,
464 JSStringRef propertyName)
469 Converter converter(context);
471 std::string key = converter.toString(propertyName);
472 if (key == "preferences") {
476 Catch(Commons::InvalidArgumentException) {
477 LogDebug("Pair for given key doesnt exist");
480 Catch(Commons::ConversionException) {
481 LogError("Error on conversion");
484 Catch(Commons::NullPointerException) {
485 LogError("Error on pointer, null value");
488 Catch(Commons::PlatformException){
489 LogError("PlatformException occured");
494 JSValueRef JSWidget::getProperty(JSContextRef context,
496 JSStringRef propertyName,
497 JSValueRef* exception)
499 LogDebug("Object: " << object);
502 Converter converter(context);
504 std::string key = converter.toString(propertyName);
506 if (key == "preferences") {
507 Converter converter(context);
508 JSObjectRef pref = getPreferences(object);
510 LogError("Preferences object is NULL");
511 return JSValueMakeUndefined(context);
515 LogError("Property NOT supported: " << propertyName);
516 return JSValueMakeUndefined(context);
519 CATCH_EXCEPTION_CONVERSION
520 CATCH_EXCEPTION_NULL_PTR
521 CATCH_EXCEPTION_INVALID_ARG
524 bool JSWidget::setProperty(JSContextRef context,
525 JSObjectRef /*object*/,
526 JSStringRef propertyName,
527 JSValueRef /*jvalue*/,
528 JSValueRef* exception)
533 Converter converter(context);
535 std::string key = converter.toString(propertyName);
536 if (key == "preferences") {
537 LogError("Object is read only");
541 CATCH_EXCEPTION_INVALID_ARG
542 CATCH_EXCEPTION_CONVERSION
543 CATCH_EXCEPTION_NULL_PTR
548 JSObjectRef JSWidget::callAsConstructor(JSContextRef context,
549 JSObjectRef /*constructor*/,
550 size_t /*argumentCount*/,
551 const JSValueRef /*arguments*/[],
552 JSValueRef* /*exception*/)
554 LogDebug("widget constructor");
555 if (!m_globalContext) {
556 LogError("Global context not set. Creating 'widget' object with "
558 return JSObjectMake(context, JSWidget::getClassRef(), NULL);
560 return JSObjectMake(m_globalContext, JSWidget::getClassRef(), NULL);
563 #undef CATCH_EXCEPTION_NO_MODIFABLE
564 #undef CATCH_EXCEPTION_CONVERSION
565 #undef CATCH_EXCEPTION_NULL_PTR
566 #undef CATCH_EXCEPTION_PLATFORM_ERROR
567 #undef CATCH_EXCEPTION_SECURITY
568 #undef CATCH_EXCEPTION_OUT_OF_RANGE
569 #undef CATCH_EXCEPTION_INVALID_ARG