RDK Documentation (Open Sourced RDK Components)
jsevent.cpp
Go to the documentation of this file.
1 /*
2  * If not stated otherwise in this file or this component's license file the
3  * following copyright and licenses apply:
4  *
5  * Copyright 2018 RDK Management
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 
20 /**
21  * @file jsevent.cpp
22  * @brief JavaScript Event Impl for AAMP_JSController and AAMPMediaPlayer_JS
23  */
24 
25 
26 #include "jsevent.h"
27 #include "jsutils.h"
28 #include <stdio.h>
29 
30 //#define _DEBUG
31 
32 static JSClassRef AAMPJSEvent_class_ref();
33 
34 #ifdef JSEVENT_WITH_NATIVE_MEMORY
35 
36 /**
37  * @brief AAMPJSEvent Constructor
38  */
39 AAMPJSEvent::AAMPJSEvent()
40  : _bubbles(false)
41  , _cancelable(false)
42  , _canceled(false)
43  , _currentTarget(NULL)
44  , _defaultPrevented(false)
45  , _phase(pAtTarget)
46  , _target(NULL)
47  , _timestamp(0)
48  , _typeName()
49  , _isTrusted(false)
50  , _ctx(NULL)
51  , _stopImmediatePropagation(false)
52  , _stopPropagation(false)
53 {
54 
55 }
56 
57 
58 /**
59  * @brief AAMPJSEvent Constructor
60  */
61 AAMPJSEvent::AAMPJSEvent(const char *type, bool bubble, bool cancelable)
62  : _bubbles(bubble)
63  , _cancelable(cancelable)
64  , _canceled(false)
65  , _currentTarget(NULL)
66  , _defaultPrevented(false)
67  , _phase(pAtTarget)
68  , _target(NULL)
69  , _timestamp(0)
70  , _typeName(type)
71  , _isTrusted(false)
72  , _ctx(NULL)
73  , _stopImmediatePropagation(false)
74  , _stopPropagation(false)
75 {
76 
77 }
78 
79 /**
80  * @brief AAMPJSEvent Destructor
81  */
82 AAMPJSEvent::~AAMPJSEvent()
83 {
84  if(_target != NULL)
85  {
86  JSValueUnprotect(_ctx, _target);
87  }
88 
89  if(_currentTarget != NULL)
90  {
91  JSValueUnprotect(_ctx, _currentTarget);
92  }
93 }
94 
95 /**
96  * @brief Initialize event's properties
97  */
98 void AAMPJSEvent::initEvent(const char *type, bool bubble, bool cancelable)
99 {
100  _typeName = type;
101  _bubbles = bubble;
102  _cancelable = cancelable;
103 }
104 
105 
106 
107 /**
108  * @brief Initialize event's properties based on args passed from JavaScript code.
109  * @param[in] context JS execution context
110  * @param[in] thisObj JSObject that is the 'this' variable in the function's scope.
111  * @param[in] argumentCount number of args
112  * @param[in] arguments[] JSValue array of args
113  * @param[out] exception pointer to a JSValueRef in which to return an exception, if any
114  */
115 static void initEvent(JSContextRef context, JSObjectRef thisObj, size_t argumentCount, const JSValueRef arguments[], JSValueRef *exception)
116 {
117  char* evType;
118  bool bubbles = false;
119  bool cancelable = false;
120 
121  if (argumentCount >= 1 && JSValueIsString(context, arguments[0]))
122  {
123  evType = aamp_JSValueToCString(context, arguments[0], NULL);
124 
125  if (argumentCount >= 2 && JSValueIsObject(context, arguments[1]))
126  {
127  JSObjectRef eventParams = JSValueToObject(context, arguments[1], NULL);
128 
129  JSStringRef bubblesProp = JSStringCreateWithUTF8CString("bubbles");
130  JSValueRef bubblesValue = JSObjectGetProperty(context, eventParams, bubblesProp, NULL);
131  if (JSValueIsBoolean(context, bubblesValue))
132  {
133  bubbles = JSValueToBoolean(context, bubblesValue);
134  }
135  JSStringRelease(bubblesProp);
136 
137  JSStringRef cancelableProp = JSStringCreateWithUTF8CString("cancelable");
138  JSValueRef cancelableValue = JSObjectGetProperty(context, eventParams, cancelableProp, NULL);
139  if (JSValueIsBoolean(context, cancelableValue))
140  {
141  cancelable = JSValueToBoolean(context, cancelableValue);
142  }
143  JSStringRelease(cancelableProp);
144  }
145 
146  AAMPJSEvent* ev = (AAMPJSEvent*) JSObjectGetPrivate(thisObj);
147 
148  if (ev && evType != NULL)
149  {
150  ev->initEvent(evType, bubbles, cancelable);
151  }
152  SAFE_DELETE_ARRAY(evType);
153  }
154 }
155 
156 
157 /**
158  * @brief Callback invoked from JS to initialize event's properties
159  * @param[in] context JS execution context
160  * @param[in] func JSObject that is the function being called
161  * @param[in] thisObj JSObject that is the 'this' variable in the function's scope
162  * @param[in] argumentCount number of args
163  * @param[in] arguments[] JSValue array of args
164  * @param[out] exception pointer to a JSValueRef in which to return an exception, if any
165  * @retval JSValue that is the function's return value.
166  */
167 static JSValueRef AAMPJSEvent_initEvent(JSContextRef context, JSObjectRef func, JSObjectRef thisObj, size_t argumentCount, const JSValueRef arguments[], JSValueRef *exception)
168 {
169  initEvent(context, thisObj, argumentCount, arguments, exception);
170 
171  return JSValueMakeUndefined(context);
172 }
173 
174 
175 /**
176  * @brief Callback invoked from JS to cancel the event's default action
177  * @param[in] context JS execution context
178  * @param[in] func JSObject that is the function being called
179  * @param[in] thisObj JSObject that is the 'this' variable in the function's scope
180  * @param[in] argumentCount number of args
181  * @param[in] arguments[] JSValue array of args
182  * @param[out] exception pointer to a JSValueRef in which to return an exception, if any
183  * @retval JSValue that is the function's return value.
184  */
185 static JSValueRef AAMPJSEvent_preventDefault(JSContextRef context, JSObjectRef func, JSObjectRef thisObj, size_t argumentCount, const JSValueRef arguments[], JSValueRef *exception)
186 {
187  AAMPJSEvent *eventObj = (AAMPJSEvent *) JSObjectGetPrivate(thisObj);
188 
189  if (eventObj != NULL)
190  {
191  eventObj->preventDefault();
192  }
193 
194  return JSValueMakeUndefined(context);
195 }
196 
197 
198 /**
199  * @brief Callback invoked from JS to prevent other listeners from being called
200  * @param[in] context JS execution context
201  * @param[in] func JSObject that is the function being called
202  * @param[in] thisObj JSObject that is the 'this' variable in the function's scope
203  * @param[in] argumentCount number of args
204  * @param[in] arguments[] JSValue array of args
205  * @param[out] exception pointer to a JSValueRef in which to return an exception, if any
206  * @retval JSValue that is the function's return value.
207  */
208 static JSValueRef AAMPJSEvent_stopImmediatePropagation(JSContextRef context, JSObjectRef func, JSObjectRef thisObj, size_t argumentCount, const JSValueRef arguments[], JSValueRef *exception)
209 {
210  AAMPJSEvent *eventObj = (AAMPJSEvent *) JSObjectGetPrivate(thisObj);
211 
212  if (eventObj != NULL)
213  {
214  eventObj->stopImmediatePropagation();
215  }
216 
217  return JSValueMakeUndefined(context);
218 }
219 
220 
221 /**
222  * @brief Callback invoked from JS to prevent further propagation of event during event flow
223  * @param[in] context JS execution context
224  * @param[in] func JSObject that is the function being called
225  * @param[in] thisObj JSObject that is the 'this' variable in the function's scope
226  * @param[in] argumentCount number of args
227  * @param[in] arguments[] JSValue array of args
228  * @param[out] exception pointer to a JSValueRef in which to return an exception, if any
229  * @retval JSValue that is the function's return value.
230  */
231 static JSValueRef AAMPJSEvent_stopPropagation(JSContextRef context, JSObjectRef func, JSObjectRef thisObj, size_t argumentCount, const JSValueRef arguments[], JSValueRef *exception)
232 {
233  AAMPJSEvent *eventObj = (AAMPJSEvent *) JSObjectGetPrivate(thisObj);
234 
235  if (eventObj != NULL)
236  {
237  eventObj->stopPropagation();
238  }
239 
240  return JSValueMakeUndefined(context);
241 }
242 
243 
244 /**
245  * @brief Callback invoked from JS to get the bubble property value
246  * @param[in] context JS execution context
247  * @param[in] thisObj JSObject to search for the property
248  * @param[in] propertyName JSString containing the name of the property to get
249  * @param[out] exception pointer to a JSValueRef in which to return an exception, if any
250  * @retval property's value if object has the property, otherwise NULL
251  */
252 static JSValueRef AAMPJSEvent_getproperty_bubbles(JSContextRef context, JSObjectRef thisObj, JSStringRef propertyName, JSValueRef* exception)
253 {
254  AAMPJSEvent *eventObj = (AAMPJSEvent *) JSObjectGetPrivate(thisObj);
255 
256  if (eventObj == NULL)
257  {
258  return JSValueMakeUndefined(context);
259  }
260 
261  return JSValueMakeBoolean(context, eventObj->getBubbles());
262 }
263 
264 
265 /**
266  * @brief Callback invoked from JS to get the cancelable property value
267  * @param[in] context JS execution context
268  * @param[in] thisObj JSObject to search for the property
269  * @param[in] propertyName JSString containing the name of the property to get
270  * @param[out] exception pointer to a JSValueRef in which to return an exception, if any
271  * @retval property's value if object has the property, otherwise NULL
272  */
273 static JSValueRef AAMPJSEvent_getproperty_cancelable(JSContextRef context, JSObjectRef thisObj, JSStringRef propertyName, JSValueRef* exception)
274 {
275  AAMPJSEvent *eventObj = (AAMPJSEvent *) JSObjectGetPrivate(thisObj);
276 
277  if (eventObj == NULL)
278  {
279  return JSValueMakeUndefined(context);
280  }
281 
282  return JSValueMakeBoolean(context, eventObj->getCancelable());
283 }
284 
285 
286 /**
287  * @brief Callback invoked from JS to get the default prevented value
288  * @param[in] context JS execution context
289  * @param[in] thisObj JSObject to search for the property
290  * @param[in] propertyName JSString containing the name of the property to get
291  * @param[out] exception pointer to a JSValueRef in which to return an exception, if any
292  * @retval property's value if object has the property, otherwise NULL
293  */
294 static JSValueRef AAMPJSEvent_getproperty_defaultPrevented(JSContextRef context, JSObjectRef thisObj, JSStringRef propertyName, JSValueRef* exception)
295 {
296  AAMPJSEvent *eventObj = (AAMPJSEvent *) JSObjectGetPrivate(thisObj);
297 
298  if (eventObj == NULL)
299  {
300  return JSValueMakeUndefined(context);
301  }
302 
303  return JSValueMakeBoolean(context, eventObj->getIsDefaultPrevented());
304 }
305 
306 
307 /**
308  * @brief Callback invoked from JS to get the event phase property value
309  * @param[in] context JS execution context
310  * @param[in] thisObj JSObject to search for the property
311  * @param[in] propertyName JSString containing the name of the property to get
312  * @param[out] exception pointer to a JSValueRef in which to return an exception, if any
313  * @retval property's value if object has the property, otherwise NULL
314  */
315 static JSValueRef AAMPJSEvent_getproperty_eventPhase(JSContextRef context, JSObjectRef thisObj, JSStringRef propertyName, JSValueRef* exception)
316 {
317  AAMPJSEvent *eventObj = (AAMPJSEvent *) JSObjectGetPrivate(thisObj);
318 
319  if (eventObj == NULL)
320  {
321  return JSValueMakeUndefined(context);
322  }
323 
324  return JSValueMakeNumber(context, eventObj->getEventPhase());
325 }
326 
327 
328 /**
329  * @brief Callback invoked from JS to get the target property value
330  * @param[in] context JS execution context
331  * @param[in] thisObj JSObject to search for the property
332  * @param[in] propertyName JSString containing the name of the property to get
333  * @param[out] exception pointer to a JSValueRef in which to return an exception, if any
334  * @retval property's value if object has the property, otherwise NULL
335  */
336 static JSValueRef AAMPJSEvent_getproperty_target(JSContextRef context, JSObjectRef thisObj, JSStringRef propertyName, JSValueRef* exception)
337 {
338  AAMPJSEvent *eventObj = (AAMPJSEvent *) JSObjectGetPrivate(thisObj);
339 
340  if (eventObj == NULL)
341  {
342  return JSValueMakeUndefined(context);
343  }
344 
345  return eventObj->getTarget();
346 }
347 
348 
349 /**
350  * @brief Callback invoked from JS to get the current target property value
351  * @param[in] context JS execution context
352  * @param[in] thisObj JSObject to search for the property
353  * @param[in] propertyName JSString containing the name of the property to get
354  * @param[out] exception pointer to a JSValueRef in which to return an exception, if any
355  * @retval property's value if object has the property, otherwise NULL
356  */
357 static JSValueRef AAMPJSEvent_getproperty_currentTarget(JSContextRef context, JSObjectRef thisObj, JSStringRef propertyName, JSValueRef* exception)
358 {
359  AAMPJSEvent *eventObj = (AAMPJSEvent *) JSObjectGetPrivate(thisObj);
360 
361  if (eventObj == NULL)
362  {
363  return JSValueMakeUndefined(context);
364  }
365 
366  return eventObj->getCurrentTarget();
367 }
368 
369 
370 /**
371  * @brief
372  * @param[in] context JS execution context
373  * @param[in] thisObj JSObject to search for the property
374  * @param[in] propertyName JSString containing the name of the property to get
375  * @param[out] exception pointer to a JSValueRef in which to return an exception, if any
376  * @retval property's value if object has the property, otherwise NULL
377  */
378 static JSValueRef AAMPJSEvent_getproperty_timestamp(JSContextRef context, JSObjectRef thisObj, JSStringRef propertyName, JSValueRef* exception)
379 {
380  AAMPJSEvent *eventObj = (AAMPJSEvent *) JSObjectGetPrivate(thisObj);
381 
382  if (eventObj == NULL)
383  {
384  return JSValueMakeUndefined(context);
385  }
386 
387  return JSValueMakeNumber(context, eventObj->getTimestamp());
388 }
389 
390 
391 /**
392  * @brief Callback invoked from JS to get the event type
393  * @param[in] context JS execution context
394  * @param[in] thisObj JSObject to search for the property
395  * @param[in] propertyName JSString containing the name of the property to get
396  * @param[out] exception pointer to a JSValueRef in which to return an exception, if any
397  * @retval property's value if object has the property, otherwise NULL
398  */
399 static JSValueRef AAMPJSEvent_getproperty_type(JSContextRef context, JSObjectRef thisObj, JSStringRef propertyName, JSValueRef* exception)
400 {
401  AAMPJSEvent *eventObj = (AAMPJSEvent *) JSObjectGetPrivate(thisObj);
402 
403  if (eventObj == NULL)
404  {
405  return JSValueMakeUndefined(context);
406  }
407 
408  return aamp_CStringToJSValue(context, eventObj->getType());
409 }
410 
411 
412 /**
413  * @brief Callback invoked from JS to get the isTrusted property value
414  * @param[in] context JS execution context
415  * @param[in] thisObj JSObject to search for the property
416  * @param[in] propertyName JSString containing the name of the property to get
417  * @param[out] exception pointer to a JSValueRef in which to return an exception, if any
418  * @retval property's value if object has the property, otherwise NULL
419  */
420 static JSValueRef AAMPJSEvent_getproperty_isTrusted(JSContextRef context, JSObjectRef thisObj, JSStringRef propertyName, JSValueRef* exception)
421 {
422  AAMPJSEvent *eventObj = (AAMPJSEvent *) JSObjectGetPrivate(thisObj);
423 
424  if (eventObj == NULL)
425  {
426  return JSValueMakeUndefined(context);
427  }
428 
429  return JSValueMakeBoolean(context, eventObj->getIsTrusted());
430 }
431 
432 
433 /**
434  * @brief Callback invoked from JS when an object is first created
435  * @param[in] ctx JS execution context
436  * @param[in] object JSObject being created
437  */
438 void AAMPJSEvent_initialize (JSContextRef ctx, JSObjectRef object)
439 {
440  AAMPJSEvent* ev = new AAMPJSEvent();
441  JSObjectSetPrivate(object, ev);
442 }
443 
444 
445 /**
446  * @brief Callback invoked from JS when an object is finalized
447  * @param[in] object JSObject being finalized
448  */
449 void AAMPJSEvent_finalize(JSObjectRef object)
450 {
451  AAMPJSEvent *ev = (AAMPJSEvent *) JSObjectGetPrivate(object);
452 
453  SAFE_DELETE(ev);
454 }
455 
456 /**
457  * @brief Array containing the class's statically declared function properties
458  */
459 static JSStaticFunction AAMPJSEvent_static_functions[] =
460 {
461  { "initEvent", AAMPJSEvent_initEvent, kJSPropertyAttributeReadOnly },
462  { "preventDefault", AAMPJSEvent_preventDefault, kJSPropertyAttributeReadOnly },
463  { "stopImmediatePropagation", AAMPJSEvent_stopImmediatePropagation, kJSPropertyAttributeReadOnly },
464  { "stopPropagation", AAMPJSEvent_stopPropagation, kJSPropertyAttributeReadOnly },
465  { NULL, NULL, 0 }
466 };
467 
468 /**
469  * @brief Array containing the class's statically declared value properties
470  */
471 static JSStaticValue AAMPJSEvent_static_values[] =
472 {
473  { "bubbles", AAMPJSEvent_getproperty_bubbles, NULL, kJSPropertyAttributeReadOnly },
474  { "cancelable", AAMPJSEvent_getproperty_cancelable, NULL, kJSPropertyAttributeReadOnly },
475  { "defaultPrevented", AAMPJSEvent_getproperty_defaultPrevented, NULL, kJSPropertyAttributeReadOnly },
476  { "eventPhase", AAMPJSEvent_getproperty_eventPhase, NULL, kJSPropertyAttributeReadOnly },
477  { "target", AAMPJSEvent_getproperty_target, NULL, kJSPropertyAttributeReadOnly },
478  { "currentTarget", AAMPJSEvent_getproperty_currentTarget, NULL, kJSPropertyAttributeReadOnly },
479  { "timestamp", AAMPJSEvent_getproperty_timestamp, NULL, kJSPropertyAttributeReadOnly },
480  { "type", AAMPJSEvent_getproperty_type, NULL, kJSPropertyAttributeReadOnly },
481  { "isTrusted", AAMPJSEvent_getproperty_isTrusted, NULL, kJSPropertyAttributeReadOnly },
482  { NULL, NULL, NULL, 0 }
483 };
484 #endif
485 
486 /**
487  * @brief Structure contains properties and callbacks of Event object of AAMP_JSController
488  */
489 static const JSClassDefinition AAMPJSEvent_object_def =
490 {
491  0,
492  kJSClassAttributeNone,
493  "__Event_AAMPJS",
494  NULL,
495 #ifdef JSEVENT_WITH_NATIVE_MEMORY
496  AAMPJSEvent_static_values,
497  AAMPJSEvent_static_functions,
498  AAMPJSEvent_initialize,
499  AAMPJSEvent_finalize,
500 #else
501  NULL,
502  NULL,
503  NULL,
504  NULL,
505 #endif
506  NULL,
507  NULL,
508  NULL,
509  NULL,
510  NULL,
511  NULL,
512  NULL,
513  NULL,
514  NULL
515 };
516 
517 
518 
519 JSObjectRef createNewAAMPJSEvent(JSGlobalContextRef ctx, const char *type, bool bubbles, bool cancelable)
520 {
521  JSObjectRef eventObj = JSObjectMake(ctx, AAMPJSEvent_class_ref(), NULL);
522 #ifdef JSEVENT_WITH_NATIVE_MEMORY
523  AAMPJSEvent *eventPriv = (AAMPJSEvent *) JSObjectGetPrivate(eventObj);
524  eventPriv->initEvent(type, bubbles, cancelable);
525 #endif
526 
527  return eventObj;
528 }
529 
530 static JSClassRef AAMPJSEvent_class_ref()
531 {
532  static JSClassRef classDef = NULL;
533  if (!classDef)
534  {
535  classDef = JSClassCreate(&AAMPJSEvent_object_def);
536  }
537 
538  return classDef;
539 }
jsutils.h
JavaScript util functions for AAMP.
AAMPJSEvent_object_def
static const JSClassDefinition AAMPJSEvent_object_def
Structure contains properties and callbacks of Event object of AAMP_JSController.
Definition: jsevent.cpp:489
aamp_JSValueToCString
char * aamp_JSValueToCString(JSContextRef context, JSValueRef value, JSValueRef *exception)
Convert JSString to C string.
Definition: jsutils.cpp:164
jsevent.h
JavaScript Event Impl for AAMP_JSController and AAMPMediaPlayer_JS.
createNewAAMPJSEvent
JSObjectRef createNewAAMPJSEvent(JSGlobalContextRef ctx, const char *type, bool bubbles, bool cancelable)
To create a new JS event instance.
Definition: jsevent.cpp:519
aamp_CStringToJSValue
JSValueRef aamp_CStringToJSValue(JSContextRef context, const char *sz)
Convert C string to JSString.
Definition: jsutils.cpp:152