Home | History | Annotate | Download | only in fxjs
      1 // Copyright 2014 PDFium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
      6 
      7 #ifndef FXJS_JS_DEFINE_H_
      8 #define FXJS_JS_DEFINE_H_
      9 
     10 #include <vector>
     11 
     12 #include "fxjs/cjs_object.h"
     13 #include "fxjs/cjs_return.h"
     14 #include "fxjs/fxjs_v8.h"
     15 #include "fxjs/js_resources.h"
     16 
     17 double JS_GetDateTime();
     18 int JS_GetYearFromTime(double dt);
     19 int JS_GetMonthFromTime(double dt);
     20 int JS_GetDayFromTime(double dt);
     21 int JS_GetHourFromTime(double dt);
     22 int JS_GetMinFromTime(double dt);
     23 int JS_GetSecFromTime(double dt);
     24 double JS_LocalTime(double d);
     25 double JS_DateParse(const WideString& str);
     26 double JS_MakeDay(int nYear, int nMonth, int nDay);
     27 double JS_MakeTime(int nHour, int nMin, int nSec, int nMs);
     28 double JS_MakeDate(double day, double time);
     29 
     30 // Some JS methods have the bizarre convention that they may also be called
     31 // with a single argument which is an object containing the actual arguments
     32 // as its properties. The varying arguments to this method are the property
     33 // names as wchar_t string literals corresponding to each positional argument.
     34 // The result will always contain |nKeywords| value, with unspecified ones
     35 // being set to type VT_unknown.
     36 std::vector<v8::Local<v8::Value>> ExpandKeywordParams(
     37     CJS_Runtime* pRuntime,
     38     const std::vector<v8::Local<v8::Value>>& originals,
     39     size_t nKeywords,
     40     ...);
     41 
     42 // All JS classes have a name, an object defintion ID, and the ability to
     43 // register themselves with FXJS_V8. We never make a BASE class on its own
     44 // because it can't really do anything.
     45 
     46 // Rich JS classes provide constants, methods, properties, and the ability
     47 // to construct native object state.
     48 
     49 template <class T, class A>
     50 static void JSConstructor(CFXJS_Engine* pEngine, v8::Local<v8::Object> obj) {
     51   CJS_Object* pObj = new T(obj);
     52   pObj->SetEmbedObject(new A(pObj));
     53   pEngine->SetObjectPrivate(obj, pObj);
     54   pObj->InitInstance(static_cast<CJS_Runtime*>(pEngine));
     55 }
     56 
     57 template <class T>
     58 static void JSDestructor(CFXJS_Engine* pEngine, v8::Local<v8::Object> obj) {
     59   delete static_cast<T*>(pEngine->GetObjectPrivate(obj));
     60 }
     61 
     62 template <class C, CJS_Return (C::*M)(CJS_Runtime*)>
     63 void JSPropGetter(const char* prop_name_string,
     64                   const char* class_name_string,
     65                   v8::Local<v8::String> property,
     66                   const v8::PropertyCallbackInfo<v8::Value>& info) {
     67   CJS_Runtime* pRuntime =
     68       CJS_Runtime::CurrentRuntimeFromIsolate(info.GetIsolate());
     69   if (!pRuntime)
     70     return;
     71 
     72   CJS_Object* pJSObj =
     73       static_cast<CJS_Object*>(pRuntime->GetObjectPrivate(info.Holder()));
     74   if (!pJSObj)
     75     return;
     76 
     77   C* pObj = reinterpret_cast<C*>(pJSObj->GetEmbedObject());
     78   CJS_Return result = (pObj->*M)(pRuntime);
     79   if (result.HasError()) {
     80     pRuntime->Error(JSFormatErrorString(class_name_string, prop_name_string,
     81                                         result.Error()));
     82     return;
     83   }
     84 
     85   if (result.HasReturn())
     86     info.GetReturnValue().Set(result.Return());
     87 }
     88 
     89 template <class C, CJS_Return (C::*M)(CJS_Runtime*, v8::Local<v8::Value>)>
     90 void JSPropSetter(const char* prop_name_string,
     91                   const char* class_name_string,
     92                   v8::Local<v8::String> property,
     93                   v8::Local<v8::Value> value,
     94                   const v8::PropertyCallbackInfo<void>& info) {
     95   CJS_Runtime* pRuntime =
     96       CJS_Runtime::CurrentRuntimeFromIsolate(info.GetIsolate());
     97   if (!pRuntime)
     98     return;
     99 
    100   CJS_Object* pJSObj =
    101       static_cast<CJS_Object*>(pRuntime->GetObjectPrivate(info.Holder()));
    102   if (!pJSObj)
    103     return;
    104 
    105   C* pObj = reinterpret_cast<C*>(pJSObj->GetEmbedObject());
    106   CJS_Return result = (pObj->*M)(pRuntime, value);
    107   if (result.HasError()) {
    108     pRuntime->Error(JSFormatErrorString(class_name_string, prop_name_string,
    109                                         result.Error()));
    110   }
    111 }
    112 
    113 template <class C,
    114           CJS_Return (C::*M)(CJS_Runtime*,
    115                              const std::vector<v8::Local<v8::Value>>&)>
    116 void JSMethod(const char* method_name_string,
    117               const char* class_name_string,
    118               const v8::FunctionCallbackInfo<v8::Value>& info) {
    119   CJS_Runtime* pRuntime =
    120       CJS_Runtime::CurrentRuntimeFromIsolate(info.GetIsolate());
    121   if (!pRuntime)
    122     return;
    123 
    124   CJS_Object* pJSObj =
    125       static_cast<CJS_Object*>(pRuntime->GetObjectPrivate(info.Holder()));
    126   if (!pJSObj)
    127     return;
    128 
    129   std::vector<v8::Local<v8::Value>> parameters;
    130   for (unsigned int i = 0; i < (unsigned int)info.Length(); i++)
    131     parameters.push_back(info[i]);
    132 
    133   C* pObj = reinterpret_cast<C*>(pJSObj->GetEmbedObject());
    134   CJS_Return result = (pObj->*M)(pRuntime, parameters);
    135   if (result.HasError()) {
    136     pRuntime->Error(JSFormatErrorString(class_name_string, method_name_string,
    137                                         result.Error()));
    138     return;
    139   }
    140 
    141   if (result.HasReturn())
    142     info.GetReturnValue().Set(result.Return());
    143 }
    144 
    145 #define JS_STATIC_PROP(err_name, prop_name, class_name)           \
    146   static void get_##prop_name##_static(                           \
    147       v8::Local<v8::String> property,                             \
    148       const v8::PropertyCallbackInfo<v8::Value>& info) {          \
    149     JSPropGetter<class_name, &class_name::get_##prop_name>(       \
    150         #err_name, #class_name, property, info);                  \
    151   }                                                               \
    152   static void set_##prop_name##_static(                           \
    153       v8::Local<v8::String> property, v8::Local<v8::Value> value, \
    154       const v8::PropertyCallbackInfo<void>& info) {               \
    155     JSPropSetter<class_name, &class_name::set_##prop_name>(       \
    156         #err_name, #class_name, property, value, info);           \
    157   }
    158 
    159 #define JS_STATIC_METHOD(method_name, class_name)                             \
    160   static void method_name##_static(                                           \
    161       const v8::FunctionCallbackInfo<v8::Value>& info) {                      \
    162     JSMethod<class_name, &class_name::method_name>(#method_name, #class_name, \
    163                                                    info);                     \
    164   }
    165 
    166 #endif  // FXJS_JS_DEFINE_H_
    167