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");
286 void JSWidget::finalize(JSObjectRef object)
289 JSWidgetPrivateObject* priv =
290 static_cast<JSWidgetPrivateObject*>(JSObjectGetPrivate(object));
292 JSValueUnprotect(priv->getContext(),
293 priv->getObject()->preferencesObject);
296 LogDebug("private object is released");
299 void JSWidget::acquireGlobalContext(java_script_context_t global_context,
300 js_object_instance_t iframe,
301 js_object_instance_t object)
303 IFrameSupport::RegisterWidget(global_context, iframe, 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,
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);
511 LogError("Preferences object is NULL");
512 return JSValueMakeUndefined(context);
516 LogError("Property NOT supported: " << propertyName);
517 return JSValueMakeUndefined(context);
520 CATCH_EXCEPTION_CONVERSION
521 CATCH_EXCEPTION_NULL_PTR
522 CATCH_EXCEPTION_INVALID_ARG
525 bool JSWidget::setProperty(JSContextRef context,
527 JSStringRef propertyName,
529 JSValueRef* exception)
534 Converter converter(context);
536 std::string key = converter.toString(propertyName);
537 if (key == "preferences"){
538 LogError("Object is read only");
542 CATCH_EXCEPTION_INVALID_ARG
543 CATCH_EXCEPTION_CONVERSION
544 CATCH_EXCEPTION_NULL_PTR
549 JSObjectRef JSWidget::callAsConstructor(JSContextRef context,
550 JSObjectRef constructor,
551 size_t argumentCount,
552 const JSValueRef arguments[],
553 JSValueRef* exception)
555 LogDebug("widget constructor");
556 if (!m_globalContext) {
557 LogError("Global context not set. Creating 'widget' object with "
559 return JSObjectMake(context, JSWidget::getClassRef(), NULL);
561 return JSObjectMake(m_globalContext, JSWidget::getClassRef(), NULL);
564 #undef CATCH_EXCEPTION_NO_MODIFABLE
565 #undef CATCH_EXCEPTION_CONVERSION
566 #undef CATCH_EXCEPTION_NULL_PTR
567 #undef CATCH_EXCEPTION_PLATFORM_ERROR
568 #undef CATCH_EXCEPTION_SECURITY
569 #undef CATCH_EXCEPTION_OUT_OF_RANGE
570 #undef CATCH_EXCEPTION_INVALID_ARG