1ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann// Copyright 2014 PDFium Authors. All rights reserved.
2ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann// Use of this source code is governed by a BSD-style license that can be
3ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann// found in the LICENSE file.
4ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
5ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
74d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifndef FPDFSDK_JAVASCRIPT_JS_DEFINE_H_
84d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#define FPDFSDK_JAVASCRIPT_JS_DEFINE_H_
9ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include <vector>
114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "fpdfsdk/javascript/JS_Object.h"
134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "fpdfsdk/javascript/JS_Value.h"
144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "fpdfsdk/javascript/resource.h"
154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "fxjs/fxjs_v8.h"
16ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
17ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannstruct JSConstSpec {
1833357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  enum Type { Number = 0, String = 1 };
1933357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann
2033357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  const char* pName;
2133357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  Type eType;
22ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  double number;
2333357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  const char* pStr;
24ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann};
25ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
26ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannstruct JSPropertySpec {
2733357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  const char* pName;
28ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  v8::AccessorGetterCallback pPropGet;
29ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  v8::AccessorSetterCallback pPropPut;
30ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann};
31ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
32ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannstruct JSMethodSpec {
3333357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  const char* pName;
34ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  v8::FunctionCallback pMethodCall;
35ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann};
36ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
3733357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmanntemplate <class C, bool (C::*M)(CJS_Runtime*, CJS_PropValue&, CFX_WideString&)>
38ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannvoid JSPropGetter(const char* prop_name_string,
39ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann                  const char* class_name_string,
40ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann                  v8::Local<v8::String> property,
41ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann                  const v8::PropertyCallbackInfo<v8::Value>& info) {
42ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  CJS_Runtime* pRuntime =
434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      CJS_Runtime::CurrentRuntimeFromIsolate(info.GetIsolate());
44ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  if (!pRuntime)
45ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    return;
464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  CJS_Object* pJSObj =
474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      static_cast<CJS_Object*>(pRuntime->GetObjectPrivate(info.Holder()));
4833357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  if (!pJSObj)
4933357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
50ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  C* pObj = reinterpret_cast<C*>(pJSObj->GetEmbedObject());
51ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  CFX_WideString sError;
52ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  CJS_PropValue value(pRuntime);
53ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  value.StartGetting();
5433357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  if (!(pObj->*M)(pRuntime, value, sError)) {
554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    pRuntime->Error(
564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        JSFormatErrorString(class_name_string, prop_name_string, sError));
57ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    return;
58ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  }
594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  info.GetReturnValue().Set(value.GetJSValue()->ToV8Value(pRuntime));
60ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann}
61ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
6233357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmanntemplate <class C, bool (C::*M)(CJS_Runtime*, CJS_PropValue&, CFX_WideString&)>
63ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannvoid JSPropSetter(const char* prop_name_string,
64ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann                  const char* class_name_string,
65ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann                  v8::Local<v8::String> property,
66ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann                  v8::Local<v8::Value> value,
67ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann                  const v8::PropertyCallbackInfo<void>& info) {
68ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  CJS_Runtime* pRuntime =
694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      CJS_Runtime::CurrentRuntimeFromIsolate(info.GetIsolate());
70ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  if (!pRuntime)
71ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    return;
724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  CJS_Object* pJSObj =
734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      static_cast<CJS_Object*>(pRuntime->GetObjectPrivate(info.Holder()));
7433357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  if (!pJSObj)
7533357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
76ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  C* pObj = reinterpret_cast<C*>(pJSObj->GetEmbedObject());
77ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  CFX_WideString sError;
784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  CJS_PropValue propValue(pRuntime, CJS_Value(pRuntime, value));
79ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  propValue.StartSetting();
8033357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  if (!(pObj->*M)(pRuntime, propValue, sError)) {
814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    pRuntime->Error(
824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        JSFormatErrorString(class_name_string, prop_name_string, sError));
83ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  }
84ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann}
85ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
86ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#define JS_STATIC_PROP(prop_name, class_name)                                 \
87ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  static void get_##prop_name##_static(                                       \
88ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      v8::Local<v8::String> property,                                         \
89ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      const v8::PropertyCallbackInfo<v8::Value>& info) {                      \
90ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    JSPropGetter<class_name, &class_name::prop_name>(#prop_name, #class_name, \
91ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann                                                     property, info);         \
92ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  }                                                                           \
93ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  static void set_##prop_name##_static(                                       \
94ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      v8::Local<v8::String> property, v8::Local<v8::Value> value,             \
95ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      const v8::PropertyCallbackInfo<void>& info) {                           \
96ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    JSPropSetter<class_name, &class_name::prop_name>(#prop_name, #class_name, \
97ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann                                                     property, value, info);  \
98ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  }
99ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
100ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmanntemplate <class C,
10133357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann          bool (C::*M)(CJS_Runtime*,
1024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                       const std::vector<CJS_Value>&,
1034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                       CJS_Value&,
1044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                       CFX_WideString&)>
105ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannvoid JSMethod(const char* method_name_string,
106ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann              const char* class_name_string,
107ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann              const v8::FunctionCallbackInfo<v8::Value>& info) {
108ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  CJS_Runtime* pRuntime =
1094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      CJS_Runtime::CurrentRuntimeFromIsolate(info.GetIsolate());
110ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  if (!pRuntime)
111ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    return;
112ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  std::vector<CJS_Value> parameters;
113ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  for (unsigned int i = 0; i < (unsigned int)info.Length(); i++) {
1144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    parameters.push_back(CJS_Value(pRuntime, info[i]));
115ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  }
1164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  CJS_Object* pJSObj =
1174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      static_cast<CJS_Object*>(pRuntime->GetObjectPrivate(info.Holder()));
11833357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  if (!pJSObj)
11933357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
120ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  C* pObj = reinterpret_cast<C*>(pJSObj->GetEmbedObject());
121ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  CFX_WideString sError;
1224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  CJS_Value valueRes(pRuntime);
12333357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  if (!(pObj->*M)(pRuntime, parameters, valueRes, sError)) {
1244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    pRuntime->Error(
1254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        JSFormatErrorString(class_name_string, method_name_string, sError));
126ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    return;
127ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  }
1284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  info.GetReturnValue().Set(valueRes.ToV8Value(pRuntime));
129ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann}
130ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
131ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#define JS_STATIC_METHOD(method_name, class_name)                             \
132ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  static void method_name##_static(                                           \
133ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      const v8::FunctionCallbackInfo<v8::Value>& info) {                      \
134ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    JSMethod<class_name, &class_name::method_name>(#method_name, #class_name, \
135ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann                                                   info);                     \
136ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  }
137ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
138ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#define JS_SPECIAL_STATIC_METHOD(method_name, class_alternate, class_name) \
139ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  static void method_name##_static(                                        \
140ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      const v8::FunctionCallbackInfo<v8::Value>& info) {                   \
141ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    JSMethod<class_alternate, &class_alternate::method_name>(              \
142ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann        #method_name, #class_name, info);                                  \
143ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  }
144ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
145ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann// All JS classes have a name, an object defintion ID, and the ability to
146ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann// register themselves with FXJS_V8. We never make a BASE class on its own
147ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann// because it can't really do anything.
14833357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann#define DECLARE_JS_CLASS_BASE_PART() \
14933357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  static const char* g_pClassName;   \
15033357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  static int g_nObjDefnID;           \
1514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  static void DefineJSObjects(CFXJS_Engine* pEngine, FXJSOBJTYPE eObjType);
152ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
15333357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann#define IMPLEMENT_JS_CLASS_BASE_PART(js_class_name, class_name) \
15433357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  const char* js_class_name::g_pClassName = #class_name;        \
155ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  int js_class_name::g_nObjDefnID = -1;
156ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
157ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann// CONST classes provide constants, but not constructors, methods, or props.
158ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#define DECLARE_JS_CLASS_CONST() \
159ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  DECLARE_JS_CLASS_BASE_PART()   \
160ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  DECLARE_JS_CLASS_CONST_PART()
161ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
1624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#define IMPLEMENT_JS_CLASS_CONST(js_class_name, class_name)                  \
1634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  IMPLEMENT_JS_CLASS_BASE_PART(js_class_name, class_name)                    \
1644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  IMPLEMENT_JS_CLASS_CONST_PART(js_class_name, class_name)                   \
1654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  void js_class_name::DefineJSObjects(CFXJS_Engine* pEngine,                 \
1664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                      FXJSOBJTYPE eObjType) {                \
1674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    g_nObjDefnID = pEngine->DefineObj(js_class_name::g_pClassName, eObjType, \
1684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                      nullptr, nullptr);                     \
1694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    DefineConsts(pEngine);                                                   \
170ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  }
171ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
17233357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann#define DECLARE_JS_CLASS_CONST_PART() \
17333357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  static JSConstSpec ConstSpecs[];    \
1744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  static void DefineConsts(CFXJS_Engine* pEngine);
1754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17633357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann#define IMPLEMENT_JS_CLASS_CONST_PART(js_class_name, class_name)             \
17733357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  void js_class_name::DefineConsts(CFXJS_Engine* pEngine) {                  \
17833357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    for (size_t i = 0; i < FX_ArraySize(ConstSpecs) - 1; ++i) {              \
17933357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann      pEngine->DefineObjConst(g_nObjDefnID, ConstSpecs[i].pName,             \
18033357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann                              ConstSpecs[i].eType == JSConstSpec::Number     \
18133357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann                                  ? pEngine->NewNumber(ConstSpecs[i].number) \
18233357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann                                  : pEngine->NewString(ConstSpecs[i].pStr)); \
18333357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    }                                                                        \
184ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  }
185ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
186ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann// Convenience macros for declaring classes without an alternate.
187ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#define DECLARE_JS_CLASS() DECLARE_JS_CLASS_RICH()
188ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#define IMPLEMENT_JS_CLASS(js_class_name, class_name) \
189ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  IMPLEMENT_JS_CLASS_RICH(js_class_name, class_name, class_name)
190ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
191ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann// Rich JS classes provide constants, methods, properties, and the ability
192ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann// to construct native object state.
193ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#define DECLARE_JS_CLASS_RICH() \
194ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  DECLARE_JS_CLASS_BASE_PART()  \
195ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  DECLARE_JS_CLASS_CONST_PART() \
196ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  DECLARE_JS_CLASS_RICH_PART()
197ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
1984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#define IMPLEMENT_JS_CLASS_RICH(js_class_name, class_alternate, class_name)  \
1994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  IMPLEMENT_JS_CLASS_BASE_PART(js_class_name, class_name)                    \
2004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  IMPLEMENT_JS_CLASS_CONST_PART(js_class_name, class_name)                   \
2014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  IMPLEMENT_JS_CLASS_RICH_PART(js_class_name, class_alternate, class_name)   \
2024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  void js_class_name::DefineJSObjects(CFXJS_Engine* pEngine,                 \
2034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                      FXJSOBJTYPE eObjType) {                \
2044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    g_nObjDefnID = pEngine->DefineObj(js_class_name::g_pClassName, eObjType, \
2054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                      JSConstructor, JSDestructor);          \
2064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    DefineConsts(pEngine);                                                   \
2074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    DefineProps(pEngine);                                                    \
2084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    DefineMethods(pEngine);                                                  \
209ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  }
210ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
211ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#define DECLARE_JS_CLASS_RICH_PART()                                           \
2124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  static void JSConstructor(CFXJS_Engine* pEngine, v8::Local<v8::Object> obj); \
2134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  static void JSDestructor(CFXJS_Engine* pEngine, v8::Local<v8::Object> obj);  \
2144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  static void DefineProps(CFXJS_Engine* pEngine);                              \
2154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  static void DefineMethods(CFXJS_Engine* pEngine);                            \
21633357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  static JSPropertySpec PropertySpecs[];                                       \
21733357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  static JSMethodSpec MethodSpecs[];
21833357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann
21933357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann#define IMPLEMENT_JS_CLASS_RICH_PART(js_class_name, class_alternate,    \
22033357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann                                     class_name)                        \
22133357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  void js_class_name::JSConstructor(CFXJS_Engine* pEngine,              \
22233357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann                                    v8::Local<v8::Object> obj) {        \
22333357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    CJS_Object* pObj = new js_class_name(obj);                          \
22433357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    pObj->SetEmbedObject(new class_alternate(pObj));                    \
22533357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    pEngine->SetObjectPrivate(obj, (void*)pObj);                        \
22633357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    pObj->InitInstance(static_cast<CJS_Runtime*>(pEngine));             \
22733357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  }                                                                     \
22833357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  void js_class_name::JSDestructor(CFXJS_Engine* pEngine,               \
22933357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann                                   v8::Local<v8::Object> obj) {         \
23033357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    delete static_cast<js_class_name*>(pEngine->GetObjectPrivate(obj)); \
23133357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  }                                                                     \
23233357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  void js_class_name::DefineProps(CFXJS_Engine* pEngine) {              \
23333357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    for (size_t i = 0; i < FX_ArraySize(PropertySpecs) - 1; ++i) {      \
23433357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann      pEngine->DefineObjProperty(g_nObjDefnID, PropertySpecs[i].pName,  \
23533357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann                                 PropertySpecs[i].pPropGet,             \
23633357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann                                 PropertySpecs[i].pPropPut);            \
23733357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    }                                                                   \
23833357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  }                                                                     \
23933357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  void js_class_name::DefineMethods(CFXJS_Engine* pEngine) {            \
24033357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    for (size_t i = 0; i < FX_ArraySize(MethodSpecs) - 1; ++i) {        \
24133357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann      pEngine->DefineObjMethod(g_nObjDefnID, MethodSpecs[i].pName,      \
24233357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann                               MethodSpecs[i].pMethodCall);             \
24333357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    }                                                                   \
244ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  }
245ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
246ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann// Special JS classes implement methods, props, and queries, but not consts.
247ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#define DECLARE_SPECIAL_JS_CLASS() \
248ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  DECLARE_JS_CLASS_BASE_PART()     \
249ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  DECLARE_JS_CLASS_CONST_PART()    \
250ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  DECLARE_JS_CLASS_RICH_PART()     \
251ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  DECLARE_SPECIAL_JS_CLASS_PART()
252ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
253ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#define IMPLEMENT_SPECIAL_JS_CLASS(js_class_name, class_alternate, class_name) \
254ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  IMPLEMENT_JS_CLASS_BASE_PART(js_class_name, class_name)                      \
255ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  IMPLEMENT_JS_CLASS_CONST_PART(js_class_name, class_name)                     \
256ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  IMPLEMENT_JS_CLASS_RICH_PART(js_class_name, class_alternate, class_name)     \
257ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  IMPLEMENT_SPECIAL_JS_CLASS_PART(js_class_name, class_alternate, class_name)  \
2584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  void js_class_name::DefineJSObjects(CFXJS_Engine* pEngine,                   \
259ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann                                      FXJSOBJTYPE eObjType) {                  \
2604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    g_nObjDefnID = pEngine->DefineObj(js_class_name::g_pClassName, eObjType,   \
2614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                      JSConstructor, JSDestructor);            \
2624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    DefineConsts(pEngine);                                                     \
2634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    DefineProps(pEngine);                                                      \
2644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    DefineMethods(pEngine);                                                    \
2654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    DefineAllProperties(pEngine);                                              \
266ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  }
267ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
268ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#define DECLARE_SPECIAL_JS_CLASS_PART()                                        \
269ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  static void queryprop_static(                                                \
270ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      v8::Local<v8::String> property,                                          \
271ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      const v8::PropertyCallbackInfo<v8::Integer>& info);                      \
272ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  static void getprop_static(v8::Local<v8::String> property,                   \
273ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann                             const v8::PropertyCallbackInfo<v8::Value>& info); \
274ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  static void putprop_static(v8::Local<v8::String> property,                   \
275ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann                             v8::Local<v8::Value> value,                       \
276ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann                             const v8::PropertyCallbackInfo<v8::Value>& info); \
277ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  static void delprop_static(                                                  \
278ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      v8::Local<v8::String> property,                                          \
279ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      const v8::PropertyCallbackInfo<v8::Boolean>& info);                      \
2804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  static void DefineAllProperties(CFXJS_Engine* pEngine);
281ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
282ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#define IMPLEMENT_SPECIAL_JS_CLASS_PART(js_class_name, class_alternate,    \
283ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann                                        class_name)                        \
284ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  void js_class_name::queryprop_static(                                    \
285ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      v8::Local<v8::String> property,                                      \
286ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      const v8::PropertyCallbackInfo<v8::Integer>& info) {                 \
287ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    JSSpecialPropQuery<class_alternate>(#class_name, property, info);      \
288ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  }                                                                        \
289ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  void js_class_name::getprop_static(                                      \
290ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      v8::Local<v8::String> property,                                      \
291ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      const v8::PropertyCallbackInfo<v8::Value>& info) {                   \
292ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    JSSpecialPropGet<class_alternate>(#class_name, property, info);        \
293ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  }                                                                        \
294ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  void js_class_name::putprop_static(                                      \
295ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      v8::Local<v8::String> property, v8::Local<v8::Value> value,          \
296ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      const v8::PropertyCallbackInfo<v8::Value>& info) {                   \
297ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    JSSpecialPropPut<class_alternate>(#class_name, property, value, info); \
298ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  }                                                                        \
299ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  void js_class_name::delprop_static(                                      \
300ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      v8::Local<v8::String> property,                                      \
301ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      const v8::PropertyCallbackInfo<v8::Boolean>& info) {                 \
302ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    JSSpecialPropDel<class_alternate>(#class_name, property, info);        \
303ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  }                                                                        \
3044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  void js_class_name::DefineAllProperties(CFXJS_Engine* pEngine) {         \
3054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    pEngine->DefineObjAllProperties(                                       \
3064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        g_nObjDefnID, js_class_name::queryprop_static,                     \
307ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann        js_class_name::getprop_static, js_class_name::putprop_static,      \
308ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann        js_class_name::delprop_static);                                    \
309ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  }
310ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
311ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmanntemplate <class Alt>
312ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannvoid JSSpecialPropQuery(const char*,
313ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann                        v8::Local<v8::String> property,
314ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann                        const v8::PropertyCallbackInfo<v8::Integer>& info) {
3154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  CJS_Runtime* pRuntime =
3164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      CJS_Runtime::CurrentRuntimeFromIsolate(info.GetIsolate());
31733357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  if (!pRuntime)
31833357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
31933357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann
320ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  CJS_Object* pJSObj =
3214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      static_cast<CJS_Object*>(pRuntime->GetObjectPrivate(info.Holder()));
32233357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  if (!pJSObj)
32333357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
32433357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann
325ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  Alt* pObj = reinterpret_cast<Alt*>(pJSObj->GetEmbedObject());
32633357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  v8::String::Utf8Value utf8_value(property);
32733357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  CFX_WideString propname = CFX_WideString::FromUTF8(
32833357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann      CFX_ByteStringC(*utf8_value, utf8_value.length()));
3294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  bool bRet = pObj->QueryProperty(propname.c_str());
330ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  info.GetReturnValue().Set(bRet ? 4 : 0);
331ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann}
332ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
333ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmanntemplate <class Alt>
334ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannvoid JSSpecialPropGet(const char* class_name,
335ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann                      v8::Local<v8::String> property,
336ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann                      const v8::PropertyCallbackInfo<v8::Value>& info) {
337ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  CJS_Runtime* pRuntime =
3384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      CJS_Runtime::CurrentRuntimeFromIsolate(info.GetIsolate());
339ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  if (!pRuntime)
340ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    return;
34133357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann
342ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  CJS_Object* pJSObj =
3434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      static_cast<CJS_Object*>(pRuntime->GetObjectPrivate(info.Holder()));
34433357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  if (!pJSObj)
34533357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
34633357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann
347ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  Alt* pObj = reinterpret_cast<Alt*>(pJSObj->GetEmbedObject());
348ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  v8::String::Utf8Value utf8_value(property);
3494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  CFX_WideString propname = CFX_WideString::FromUTF8(
3504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      CFX_ByteStringC(*utf8_value, utf8_value.length()));
351ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  CFX_WideString sError;
352ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  CJS_PropValue value(pRuntime);
353ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  value.StartGetting();
35433357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  if (!pObj->DoProperty(pRuntime, propname.c_str(), value, sError)) {
3554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    pRuntime->Error(JSFormatErrorString(class_name, "GetProperty", sError));
356ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    return;
357ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  }
3584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  info.GetReturnValue().Set(value.GetJSValue()->ToV8Value(pRuntime));
359ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann}
360ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
361ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmanntemplate <class Alt>
362ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannvoid JSSpecialPropPut(const char* class_name,
363ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann                      v8::Local<v8::String> property,
364ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann                      v8::Local<v8::Value> value,
365ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann                      const v8::PropertyCallbackInfo<v8::Value>& info) {
366ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  CJS_Runtime* pRuntime =
3674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      CJS_Runtime::CurrentRuntimeFromIsolate(info.GetIsolate());
368ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  if (!pRuntime)
369ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    return;
37033357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann
371ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  CJS_Object* pJSObj =
3724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      static_cast<CJS_Object*>(pRuntime->GetObjectPrivate(info.Holder()));
37333357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  if (!pJSObj)
37433357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
37533357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann
376ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  Alt* pObj = reinterpret_cast<Alt*>(pJSObj->GetEmbedObject());
377ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  v8::String::Utf8Value utf8_value(property);
3784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  CFX_WideString propname = CFX_WideString::FromUTF8(
3794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      CFX_ByteStringC(*utf8_value, utf8_value.length()));
380ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  CFX_WideString sError;
3814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  CJS_PropValue PropValue(pRuntime, CJS_Value(pRuntime, value));
382ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  PropValue.StartSetting();
38333357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  if (!pObj->DoProperty(pRuntime, propname.c_str(), PropValue, sError)) {
3844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    pRuntime->Error(JSFormatErrorString(class_name, "PutProperty", sError));
385ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  }
386ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann}
387ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
388ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmanntemplate <class Alt>
389ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannvoid JSSpecialPropDel(const char* class_name,
390ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann                      v8::Local<v8::String> property,
391ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann                      const v8::PropertyCallbackInfo<v8::Boolean>& info) {
3924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  CJS_Runtime* pRuntime =
3934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      CJS_Runtime::CurrentRuntimeFromIsolate(info.GetIsolate());
394ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  if (!pRuntime)
395ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    return;
39633357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann
397ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  CJS_Object* pJSObj =
3984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      static_cast<CJS_Object*>(pRuntime->GetObjectPrivate(info.Holder()));
39933357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  if (!pJSObj)
40033357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
40133357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann
402ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  Alt* pObj = reinterpret_cast<Alt*>(pJSObj->GetEmbedObject());
403ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  v8::String::Utf8Value utf8_value(property);
4044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  CFX_WideString propname = CFX_WideString::FromUTF8(
4054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      CFX_ByteStringC(*utf8_value, utf8_value.length()));
406ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  CFX_WideString sError;
40733357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  if (!pObj->DelProperty(pRuntime, propname.c_str(), sError)) {
408ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    CFX_ByteString cbName;
409ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    cbName.Format("%s.%s", class_name, "DelProperty");
410ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    // Probably a missing call to JSFX_Error().
411ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  }
412ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann}
413ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
41433357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmanntemplate <bool (*F)(CJS_Runtime*,
4154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    const std::vector<CJS_Value>&,
4164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    CJS_Value&,
4174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                    CFX_WideString&)>
418ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannvoid JSGlobalFunc(const char* func_name_string,
419ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann                  const v8::FunctionCallbackInfo<v8::Value>& info) {
420ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  CJS_Runtime* pRuntime =
4214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      CJS_Runtime::CurrentRuntimeFromIsolate(info.GetIsolate());
422ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  if (!pRuntime)
423ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    return;
424ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  std::vector<CJS_Value> parameters;
425ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  for (unsigned int i = 0; i < (unsigned int)info.Length(); i++) {
4264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    parameters.push_back(CJS_Value(pRuntime, info[i]));
427ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  }
428ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  CJS_Value valueRes(pRuntime);
429ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  CFX_WideString sError;
43033357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  if (!(*F)(pRuntime, parameters, valueRes, sError)) {
4314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    pRuntime->Error(JSFormatErrorString(func_name_string, nullptr, sError));
432ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    return;
433ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  }
4344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  info.GetReturnValue().Set(valueRes.ToV8Value(pRuntime));
435ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann}
436ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
437ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#define JS_STATIC_GLOBAL_FUN(fun_name)                   \
438ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  static void fun_name##_static(                         \
439ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      const v8::FunctionCallbackInfo<v8::Value>& info) { \
440ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    JSGlobalFunc<fun_name>(#fun_name, info);             \
441ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  }
442ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
44333357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann#define JS_STATIC_DECLARE_GLOBAL_FUN()       \
44433357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  static JSMethodSpec GlobalFunctionSpecs[]; \
4454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  static void DefineJSObjects(CFXJS_Engine* pEngine)
446ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
44733357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann#define IMPLEMENT_JS_STATIC_GLOBAL_FUN(js_class_name)                    \
44833357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  void js_class_name::DefineJSObjects(CFXJS_Engine* pEngine) {           \
44933357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    for (size_t i = 0; i < FX_ArraySize(GlobalFunctionSpecs) - 1; ++i) { \
45033357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann      pEngine->DefineGlobalMethod(                                       \
45133357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann          js_class_name::GlobalFunctionSpecs[i].pName,                   \
45233357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann          js_class_name::GlobalFunctionSpecs[i].pMethodCall);            \
45333357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    }                                                                    \
454ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  }
455ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
4564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif  // FPDFSDK_JAVASCRIPT_JS_DEFINE_H_
457