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 static int id = widgetId;
138 Assert(id == widgetId && "SPA is not longer supported");
140 static LocalStorage::Api::ILocalStoragePtr storage(
141 LocalStorage::Api::getLocalStorage(widgetId));
146 JSObjectRef getPreferences(JSObjectRef arg)
148 JSWidgetPrivateObject* priv =
149 static_cast<JSWidgetPrivateObject*>(JSObjectGetPrivate(arg));
152 LogError("Private object not initialized");
156 return priv->getObject()->preferencesObject;
159 JSObjectRef createPreferencesObject(JSContextRef context,
160 JSObjectRef widgetObject,
163 Assert(widgetObject && "Widget Object can'n be null");
164 //delete is invoked in JSPreferences::finalize
165 LocalStoragePrivateData* priv = new LocalStoragePrivateData;
166 Assert(priv && "Private data is null");
167 priv->istorage = getLocalStorage(widgetId);
168 priv->widgetObject = widgetObject;
170 JSObjectRef preferences = JSObjectMake(context,
171 JSPreferences::getClassRef(),
175 LogError("Preferences object is null");
178 //Unprotect is called in JSWidget::finalize
179 JSValueProtect(context, preferences);
185 JSClassDefinition JSWidget::m_classInfo = {
187 kJSClassAttributeNone,
197 NULL, //DeleteProperty,
198 NULL, //GetPropertyNames,
199 NULL, //CallAsFunction,
202 NULL, //ConvertToType,
205 JSStaticValue JSWidget::m_property[] = {
206 { WRT_WIDGET_PROPERTY_AUTHOR, JSWidget::getAuthor,
207 0, kJSPropertyAttributeReadOnly },
208 { WRT_WIDGET_PROPERTY_AUTHOR_EMAIL, JSWidget::getAuthorEmail,
209 0, kJSPropertyAttributeReadOnly },
210 { WRT_WIDGET_PROPERTY_AUTHOR_HREF, JSWidget::getAuthorHref,
211 0, kJSPropertyAttributeReadOnly },
212 { WRT_WIDGET_PROPERTY_DESCRIPTION, JSWidget::getDescription,
213 0, kJSPropertyAttributeReadOnly },
214 { WRT_WIDGET_PROPERTY_ID, JSWidget::getId,
215 0, kJSPropertyAttributeReadOnly },
216 { WRT_WIDGET_PROPERTY_NAME, JSWidget::getName,
217 0, kJSPropertyAttributeReadOnly },
218 { WRT_WIDGET_PROPERTY_SHORT_NAME, JSWidget::getShortName,
219 0, kJSPropertyAttributeReadOnly },
220 { WRT_WIDGET_PROPERTY_VERSION, JSWidget::getVersion,
221 0, kJSPropertyAttributeReadOnly },
222 { WRT_WIDGET_PROPERTY_HEIGHT, JSWidget::getHeight,
223 0, kJSPropertyAttributeReadOnly },
224 { WRT_WIDGET_PROPERTY_WIDTH, JSWidget::getWidth,
225 0, kJSPropertyAttributeReadOnly },
229 const JSClassRef JSWidget::getClassRef()
232 m_jsClassRef = JSClassCreate(&m_classInfo);
237 const JSClassDefinition* JSWidget::getClassInfo()
242 JSClassRef JSWidget::m_jsClassRef = JSClassCreate(JSWidget::getClassInfo());
244 JSContextRef JSWidget::m_globalContext = NULL;
246 void JSWidget::initialize(JSContextRef context,
249 LogDebug("entered. Context : " << context);
250 LogDebug("Object: " << object);
252 JSWidgetPrivateObject* priv =
253 static_cast<JSWidgetPrivateObject*>(JSObjectGetPrivate(object));
256 LogDebug("creation private object");
259 using namespace WrtDeviceApis::Commons;
261 Widget::Api::IWidgetPtr widget =
262 Api::WidgetFactory::createWidget();
263 int widgetId = WrtAccessSingleton::Instance().getWidgetId();
264 JSObjectRef preferences =
265 createPreferencesObject(context,
269 LogError("Failed to create preferences object");
272 WidgetPrivateObjectPtr widgetPriv(new WidgetPrivateObject);
273 widgetPriv->iwidget = widget;
274 widgetPriv->preferencesObject = preferences;
276 priv = new JSWidgetPrivateObject(context, widgetPriv);
277 JSObjectSetPrivate(object, priv);
278 LogDebug("private object created");
281 Catch(Commons::InvalidArgumentException){
282 LogError("You should register widget id in ON_WIDGET_START");
289 void JSWidget::finalize(JSObjectRef object)
292 JSWidgetPrivateObject* priv =
293 static_cast<JSWidgetPrivateObject*>(JSObjectGetPrivate(object));
295 JSValueUnprotect(priv->getContext(),
296 priv->getObject()->preferencesObject);
299 LogDebug("private object is released");
302 void JSWidget::acquireGlobalContext(java_script_context_t global_context,
303 js_object_instance_t iframe,
304 js_object_instance_t object)
306 IFrameSupport::RegisterWidget(global_context, iframe, object);
307 if (!m_globalContext) {
308 m_globalContext = static_cast<JSContextRef>(global_context);
309 LogInfo("Global context acquired.");
311 LogInfo("Global context already set.");
315 JSValueRef JSWidget::getAuthor(JSContextRef context,
317 JSStringRef propertyName,
318 JSValueRef* exception)
323 Converter converter(context);
324 return converter.toJSValueRef(getIWidget(object)->getAuthor());
326 CATCH_EXCEPTION_CONVERSION
327 CATCH_EXCEPTION_NULL_PTR
328 CATCH_EXCEPTION_PLATFORM_ERROR
331 JSValueRef JSWidget::getAuthorEmail(JSContextRef context,
333 JSStringRef propertyName,
334 JSValueRef* exception)
337 Converter converter(context);
338 return converter.toJSValueRef(getIWidget(object)->getAuthorEmail());
340 CATCH_EXCEPTION_CONVERSION
341 CATCH_EXCEPTION_NULL_PTR
342 CATCH_EXCEPTION_PLATFORM_ERROR
345 JSValueRef JSWidget::getAuthorHref(JSContextRef context,
347 JSStringRef propertyName,
348 JSValueRef* exception)
351 Converter converter(context);
352 return converter.toJSValueRef(getIWidget(object)->getAuthorHref());
354 CATCH_EXCEPTION_CONVERSION
355 CATCH_EXCEPTION_NULL_PTR
356 CATCH_EXCEPTION_PLATFORM_ERROR
359 JSValueRef JSWidget::getDescription(JSContextRef context,
361 JSStringRef propertyName,
362 JSValueRef* exception)
365 Converter converter(context);
366 return converter.toJSValueRef(getIWidget(object)->getDescription());
368 CATCH_EXCEPTION_CONVERSION
369 CATCH_EXCEPTION_NULL_PTR
370 CATCH_EXCEPTION_PLATFORM_ERROR
373 JSValueRef JSWidget::getId(JSContextRef context,
375 JSStringRef propertyName,
376 JSValueRef* exception)
379 Converter converter(context);
380 return converter.toJSValueRef(getIWidget(object)->getId());
382 CATCH_EXCEPTION_CONVERSION
383 CATCH_EXCEPTION_NULL_PTR
384 CATCH_EXCEPTION_PLATFORM_ERROR
387 JSValueRef JSWidget::getName(JSContextRef context,
389 JSStringRef propertyName,
390 JSValueRef* exception)
393 Converter converter(context);
394 return converter.toJSValueRef(getIWidget(object)->getName());
396 CATCH_EXCEPTION_CONVERSION
397 CATCH_EXCEPTION_NULL_PTR
398 CATCH_EXCEPTION_PLATFORM_ERROR
401 JSValueRef JSWidget::getShortName(JSContextRef context,
403 JSStringRef propertyName,
404 JSValueRef* exception)
407 Converter converter(context);
408 return converter.toJSValueRef(getIWidget(object)->getShortName());
410 CATCH_EXCEPTION_CONVERSION
411 CATCH_EXCEPTION_NULL_PTR
412 CATCH_EXCEPTION_PLATFORM_ERROR
415 JSValueRef JSWidget::getVersion(JSContextRef context,
417 JSStringRef propertyName,
418 JSValueRef* exception)
421 Converter converter(context);
422 return converter.toJSValueRef(getIWidget(object)->getVersion());
424 CATCH_EXCEPTION_CONVERSION
425 CATCH_EXCEPTION_NULL_PTR
426 CATCH_EXCEPTION_PLATFORM_ERROR
429 JSValueRef JSWidget::getHeight(JSContextRef context,
431 JSStringRef propertyName,
432 JSValueRef* exception)
435 Converter converter(context);
436 unsigned int height = getIWidget(object)->getHeight();
440 return converter.toJSValueRef(height);
442 CATCH_EXCEPTION_CONVERSION
443 CATCH_EXCEPTION_NULL_PTR
444 CATCH_EXCEPTION_PLATFORM_ERROR
447 JSValueRef JSWidget::getWidth(JSContextRef context,
449 JSStringRef propertyName,
450 JSValueRef* exception)
453 Converter converter(context);
454 unsigned int width = getIWidget(object)->getWidth();
458 return converter.toJSValueRef(width);
460 CATCH_EXCEPTION_CONVERSION
461 CATCH_EXCEPTION_NULL_PTR
462 CATCH_EXCEPTION_PLATFORM_ERROR
465 bool JSWidget::hasProperty(JSContextRef context,
467 JSStringRef propertyName)
472 Converter converter(context);
474 std::string key = converter.toString(propertyName);
475 if (key == "preferences") {
479 Catch(Commons::InvalidArgumentException) {
480 LogDebug("Pair for given key doesnt exist");
483 Catch(Commons::ConversionException) {
484 LogError("Error on conversion");
487 Catch(Commons::NullPointerException) {
488 LogError("Error on pointer, null value");
491 Catch(Commons::PlatformException){
492 LogError("PlatformException occured");
497 JSValueRef JSWidget::getProperty(JSContextRef context,
499 JSStringRef propertyName,
500 JSValueRef* exception)
502 LogDebug("Object: " << object);
505 Converter converter(context);
507 std::string key = converter.toString(propertyName);
509 if (key=="preferences") {
510 Converter converter(context);
511 JSObjectRef pref = getPreferences(object);
514 LogError("Preferences object is NULL");
515 return JSValueMakeUndefined(context);
519 LogError("Property NOT supported: " << propertyName);
520 return JSValueMakeUndefined(context);
523 CATCH_EXCEPTION_CONVERSION
524 CATCH_EXCEPTION_NULL_PTR
525 CATCH_EXCEPTION_INVALID_ARG
528 bool JSWidget::setProperty(JSContextRef context,
530 JSStringRef propertyName,
532 JSValueRef* exception)
537 Converter converter(context);
539 std::string key = converter.toString(propertyName);
540 if (key == "preferences"){
541 LogError("Object is read only");
545 CATCH_EXCEPTION_INVALID_ARG
546 CATCH_EXCEPTION_CONVERSION
547 CATCH_EXCEPTION_NULL_PTR
552 JSObjectRef JSWidget::callAsConstructor(JSContextRef context,
553 JSObjectRef constructor,
554 size_t argumentCount,
555 const JSValueRef arguments[],
556 JSValueRef* exception)
558 LogDebug("widget constructor");
559 if (!m_globalContext) {
560 LogError("Global context not set. Creating 'widget' object with "
562 return JSObjectMake(context, JSWidget::getClassRef(), NULL);
564 return JSObjectMake(m_globalContext, JSWidget::getClassRef(), NULL);
567 #undef CATCH_EXCEPTION_NO_MODIFABLE
568 #undef CATCH_EXCEPTION_CONVERSION
569 #undef CATCH_EXCEPTION_NULL_PTR
570 #undef CATCH_EXCEPTION_PLATFORM_ERROR
571 #undef CATCH_EXCEPTION_SECURITY
572 #undef CATCH_EXCEPTION_OUT_OF_RANGE
573 #undef CATCH_EXCEPTION_INVALID_ARG