Merge to XFA: Make the vast majority of JS headers private to src/javascript.

(cherry picked from commit 5b3d0208723f21c50b9922bdc500c9d78c359a25)
Original Review URL: https://codereview.chromium.org/1389783002 .

New changes to fix IWYU in:
  fpdfsdk/include/fpdfxfa/fpdfxfa_app.h
  xfa/include/fxfa/fxfa.h
  xfa/include/fxfa/fxfa_objectacc.h

R=thestig@chromium.org

Review URL: https://codereview.chromium.org/1388023003 .
diff --git a/fpdfsdk/src/javascript/Consts.cpp b/fpdfsdk/src/javascript/Consts.cpp
index fcdc5ea..3381978 100644
--- a/fpdfsdk/src/javascript/Consts.cpp
+++ b/fpdfsdk/src/javascript/Consts.cpp
@@ -4,11 +4,12 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
+#include "Consts.h"
+
 #include "../../include/javascript/IJavaScript.h"
-#include "../../include/javascript/JS_Define.h"
-#include "../../include/javascript/JS_Object.h"
-#include "../../include/javascript/JS_Value.h"
-#include "../../include/javascript/Consts.h"
+#include "JS_Define.h"
+#include "JS_Object.h"
+#include "JS_Value.h"
 
 /* ------------------------------ border ------------------------------ */
 
diff --git a/fpdfsdk/src/javascript/Consts.h b/fpdfsdk/src/javascript/Consts.h
new file mode 100644
index 0000000..a1d36f8
--- /dev/null
+++ b/fpdfsdk/src/javascript/Consts.h
@@ -0,0 +1,116 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FPDFSDK_SRC_JAVASCRIPT_CONSTS_H_
+#define FPDFSDK_SRC_JAVASCRIPT_CONSTS_H_
+
+#include "JS_Define.h"
+
+/* ------------------------------ border ------------------------------ */
+
+class CJS_Border : public CJS_Object {
+ public:
+  explicit CJS_Border(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
+  ~CJS_Border() override {}
+
+  DECLARE_JS_CLASS_CONST();
+};
+
+/* ------------------------------ display ------------------------------ */
+
+class CJS_Display : public CJS_Object {
+ public:
+  explicit CJS_Display(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
+  ~CJS_Display() override {}
+
+  DECLARE_JS_CLASS_CONST();
+};
+
+/* ------------------------------ font ------------------------------ */
+
+class CJS_Font : public CJS_Object {
+ public:
+  explicit CJS_Font(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
+  ~CJS_Font() override {}
+
+  DECLARE_JS_CLASS_CONST();
+};
+
+/* ------------------------------ highlight ------------------------------ */
+
+class CJS_Highlight : public CJS_Object {
+ public:
+  explicit CJS_Highlight(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
+  ~CJS_Highlight() override {}
+
+  DECLARE_JS_CLASS_CONST();
+};
+
+/* ------------------------------ position ------------------------------ */
+
+class CJS_Position : public CJS_Object {
+ public:
+  explicit CJS_Position(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
+  ~CJS_Position() override {}
+
+  DECLARE_JS_CLASS_CONST();
+};
+
+/* ------------------------------ scaleHow ------------------------------ */
+
+class CJS_ScaleHow : public CJS_Object {
+ public:
+  explicit CJS_ScaleHow(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
+  ~CJS_ScaleHow() override {}
+
+  DECLARE_JS_CLASS_CONST();
+};
+
+/* ------------------------------ scaleWhen ------------------------------ */
+
+class CJS_ScaleWhen : public CJS_Object {
+ public:
+  explicit CJS_ScaleWhen(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
+  ~CJS_ScaleWhen() override {}
+
+  DECLARE_JS_CLASS_CONST();
+};
+
+/* ------------------------------ style ------------------------------ */
+
+class CJS_Style : public CJS_Object {
+ public:
+  explicit CJS_Style(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
+  ~CJS_Style() override {}
+
+  DECLARE_JS_CLASS_CONST();
+};
+
+/* ------------------------------ zoomtype ------------------------------ */
+
+class CJS_Zoomtype : public CJS_Object {
+ public:
+  explicit CJS_Zoomtype(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
+  ~CJS_Zoomtype() override {}
+
+  DECLARE_JS_CLASS_CONST();
+};
+
+/* ------------------------------ CJS_GlobalConsts -------------------------- */
+
+class CJS_GlobalConsts : public CJS_Object {
+ public:
+  static void DefineJSObjects(v8::Isolate* pIsolate);
+};
+
+/* ------------------------------ CJS_GlobalArrays -------------------------- */
+
+class CJS_GlobalArrays : public CJS_Object {
+ public:
+  static void DefineJSObjects(v8::Isolate* pIsolate);
+};
+
+#endif  // FPDFSDK_SRC_JAVASCRIPT_CONSTS_H_
diff --git a/fpdfsdk/src/javascript/Document.cpp b/fpdfsdk/src/javascript/Document.cpp
index 599d27f..9a569af 100644
--- a/fpdfsdk/src/javascript/Document.cpp
+++ b/fpdfsdk/src/javascript/Document.cpp
@@ -4,20 +4,21 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
-#include "../../include/javascript/IJavaScript.h"
-#include "../../include/javascript/JS_Define.h"
-#include "../../include/javascript/JS_Object.h"
-#include "../../include/javascript/JS_Value.h"
-#include "../../include/javascript/Document.h"
-#include "../../include/javascript/JS_EventHandler.h"
-#include "../../include/javascript/JS_Context.h"
-#include "../../include/javascript/JS_Runtime.h"
-#include "../../include/javascript/app.h"
-#include "../../include/javascript/Field.h"
-#include "../../include/javascript/Icon.h"
-#include "../../include/javascript/resource.h"
+#include "Document.h"
 
 #include "../../../third_party/base/numerics/safe_math.h"
+#include "../../include/fsdk_mgr.h"  // For CPDFDoc_Environment.
+#include "../../include/javascript/IJavaScript.h"
+#include "Field.h"
+#include "Icon.h"
+#include "JS_Context.h"
+#include "JS_Define.h"
+#include "JS_EventHandler.h"
+#include "JS_Object.h"
+#include "JS_Runtime.h"
+#include "JS_Value.h"
+#include "app.h"
+#include "resource.h"
 
 static v8::Isolate* GetIsolate(IFXJS_Context* cc) {
   CJS_Context* pContext = (CJS_Context*)cc;
diff --git a/fpdfsdk/src/javascript/Document.h b/fpdfsdk/src/javascript/Document.h
new file mode 100644
index 0000000..65b2764
--- /dev/null
+++ b/fpdfsdk/src/javascript/Document.h
@@ -0,0 +1,407 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FPDFSDK_SRC_JAVASCRIPT_DOCUMENT_H_
+#define FPDFSDK_SRC_JAVASCRIPT_DOCUMENT_H_
+
+#include "JS_Define.h"
+
+class PrintParamsObj : public CJS_EmbedObj {
+ public:
+  PrintParamsObj(CJS_Object* pJSObject);
+  ~PrintParamsObj() override {}
+
+ public:
+  FX_BOOL bUI;
+  int nStart;
+  int nEnd;
+  FX_BOOL bSilent;
+  FX_BOOL bShrinkToFit;
+  FX_BOOL bPrintAsImage;
+  FX_BOOL bReverse;
+  FX_BOOL bAnnotations;
+};
+
+class CJS_PrintParamsObj : public CJS_Object {
+ public:
+  CJS_PrintParamsObj(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
+  ~CJS_PrintParamsObj() override {}
+
+  DECLARE_JS_CLASS(CJS_PrintParamsObj);
+};
+
+class Icon;
+class Field;
+
+struct IconElement {
+  IconElement() : IconName(L""), NextIcon(NULL), IconStream(NULL) {}
+  virtual ~IconElement() {}
+  CFX_WideString IconName;
+  IconElement* NextIcon;
+  Icon* IconStream;
+};
+
+class IconTree {
+ public:
+  IconTree() : m_pHead(NULL), m_pEnd(NULL), m_iLength(0) {}
+
+  virtual ~IconTree() {}
+
+ public:
+  void InsertIconElement(IconElement* pNewIcon);
+  void DeleteIconElement(CFX_WideString swIconName);
+  void DeleteIconTree();
+  int GetLength();
+  IconElement* operator[](int iIndex);
+
+ private:
+  IconElement* m_pHead;
+  IconElement* m_pEnd;
+  int m_iLength;
+};
+
+struct CJS_DelayData;
+struct CJS_DelayAnnot;
+struct CJS_AnnotObj;
+
+class Document : public CJS_EmbedObj {
+ public:
+  Document(CJS_Object* pJSObject);
+  ~Document() override;
+
+ public:
+  FX_BOOL ADBE(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL author(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL baseURL(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL bookmarkRoot(IFXJS_Context* cc,
+                       CJS_PropValue& vp,
+                       CFX_WideString& sError);
+  FX_BOOL calculate(IFXJS_Context* cc,
+                    CJS_PropValue& vp,
+                    CFX_WideString& sError);
+  FX_BOOL Collab(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL creationDate(IFXJS_Context* cc,
+                       CJS_PropValue& vp,
+                       CFX_WideString& sError);
+  FX_BOOL creator(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL delay(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL dirty(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL documentFileName(IFXJS_Context* cc,
+                           CJS_PropValue& vp,
+                           CFX_WideString& sError);
+  FX_BOOL external(IFXJS_Context* cc,
+                   CJS_PropValue& vp,
+                   CFX_WideString& sError);
+  FX_BOOL filesize(IFXJS_Context* cc,
+                   CJS_PropValue& vp,
+                   CFX_WideString& sError);
+  FX_BOOL icons(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL info(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL keywords(IFXJS_Context* cc,
+                   CJS_PropValue& vp,
+                   CFX_WideString& sError);
+  FX_BOOL layout(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL media(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL modDate(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL mouseX(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL mouseY(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL numFields(IFXJS_Context* cc,
+                    CJS_PropValue& vp,
+                    CFX_WideString& sError);
+  FX_BOOL numPages(IFXJS_Context* cc,
+                   CJS_PropValue& vp,
+                   CFX_WideString& sError);
+  FX_BOOL pageNum(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL pageWindowRect(IFXJS_Context* cc,
+                         CJS_PropValue& vp,
+                         CFX_WideString& sError);
+  FX_BOOL path(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL producer(IFXJS_Context* cc,
+                   CJS_PropValue& vp,
+                   CFX_WideString& sError);
+  FX_BOOL subject(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL title(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL zoom(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL zoomType(IFXJS_Context* cc,
+                   CJS_PropValue& vp,
+                   CFX_WideString& sError);
+
+  FX_BOOL addAnnot(IFXJS_Context* cc,
+                   const CJS_Parameters& params,
+                   CJS_Value& vRet,
+                   CFX_WideString& sError);
+  FX_BOOL addField(IFXJS_Context* cc,
+                   const CJS_Parameters& params,
+                   CJS_Value& vRet,
+                   CFX_WideString& sError);
+  FX_BOOL addLink(IFXJS_Context* cc,
+                  const CJS_Parameters& params,
+                  CJS_Value& vRet,
+                  CFX_WideString& sError);
+  FX_BOOL addIcon(IFXJS_Context* cc,
+                  const CJS_Parameters& params,
+                  CJS_Value& vRet,
+                  CFX_WideString& sError);
+  FX_BOOL calculateNow(IFXJS_Context* cc,
+                       const CJS_Parameters& params,
+                       CJS_Value& vRet,
+                       CFX_WideString& sError);
+  FX_BOOL closeDoc(IFXJS_Context* cc,
+                   const CJS_Parameters& params,
+                   CJS_Value& vRet,
+                   CFX_WideString& sError);
+  FX_BOOL createDataObject(IFXJS_Context* cc,
+                           const CJS_Parameters& params,
+                           CJS_Value& vRet,
+                           CFX_WideString& sError);
+  FX_BOOL deletePages(IFXJS_Context* cc,
+                      const CJS_Parameters& params,
+                      CJS_Value& vRet,
+                      CFX_WideString& sError);
+  FX_BOOL exportAsText(IFXJS_Context* cc,
+                       const CJS_Parameters& params,
+                       CJS_Value& vRet,
+                       CFX_WideString& sError);
+  FX_BOOL exportAsFDF(IFXJS_Context* cc,
+                      const CJS_Parameters& params,
+                      CJS_Value& vRet,
+                      CFX_WideString& sError);
+  FX_BOOL exportAsXFDF(IFXJS_Context* cc,
+                       const CJS_Parameters& params,
+                       CJS_Value& vRet,
+                       CFX_WideString& sError);
+  FX_BOOL extractPages(IFXJS_Context* cc,
+                       const CJS_Parameters& params,
+                       CJS_Value& vRet,
+                       CFX_WideString& sError);
+  FX_BOOL getAnnot(IFXJS_Context* cc,
+                   const CJS_Parameters& params,
+                   CJS_Value& vRet,
+                   CFX_WideString& sError);
+  FX_BOOL getAnnots(IFXJS_Context* cc,
+                    const CJS_Parameters& params,
+                    CJS_Value& vRet,
+                    CFX_WideString& sError);
+  FX_BOOL getAnnot3D(IFXJS_Context* cc,
+                     const CJS_Parameters& params,
+                     CJS_Value& vRet,
+                     CFX_WideString& sError);
+  FX_BOOL getAnnots3D(IFXJS_Context* cc,
+                      const CJS_Parameters& params,
+                      CJS_Value& vRet,
+                      CFX_WideString& sError);
+  FX_BOOL getField(IFXJS_Context* cc,
+                   const CJS_Parameters& params,
+                   CJS_Value& vRet,
+                   CFX_WideString& sError);
+  FX_BOOL getIcon(IFXJS_Context* cc,
+                  const CJS_Parameters& params,
+                  CJS_Value& vRet,
+                  CFX_WideString& sError);
+  FX_BOOL getLinks(IFXJS_Context* cc,
+                   const CJS_Parameters& params,
+                   CJS_Value& vRet,
+                   CFX_WideString& sError);
+  FX_BOOL getNthFieldName(IFXJS_Context* cc,
+                          const CJS_Parameters& params,
+                          CJS_Value& vRet,
+                          CFX_WideString& sError);
+  FX_BOOL getOCGs(IFXJS_Context* cc,
+                  const CJS_Parameters& params,
+                  CJS_Value& vRet,
+                  CFX_WideString& sError);
+  FX_BOOL getPageBox(IFXJS_Context* cc,
+                     const CJS_Parameters& params,
+                     CJS_Value& vRet,
+                     CFX_WideString& sError);
+  FX_BOOL getPageNthWord(IFXJS_Context* cc,
+                         const CJS_Parameters& params,
+                         CJS_Value& vRet,
+                         CFX_WideString& sError);
+  FX_BOOL getPageNthWordQuads(IFXJS_Context* cc,
+                              const CJS_Parameters& params,
+                              CJS_Value& vRet,
+                              CFX_WideString& sError);
+  FX_BOOL getPageNumWords(IFXJS_Context* cc,
+                          const CJS_Parameters& params,
+                          CJS_Value& vRet,
+                          CFX_WideString& sError);
+  FX_BOOL getPrintParams(IFXJS_Context* cc,
+                         const CJS_Parameters& params,
+                         CJS_Value& vRet,
+                         CFX_WideString& sError);
+  FX_BOOL getURL(IFXJS_Context* cc,
+                 const CJS_Parameters& params,
+                 CJS_Value& vRet,
+                 CFX_WideString& sError);
+  FX_BOOL importAnFDF(IFXJS_Context* cc,
+                      const CJS_Parameters& params,
+                      CJS_Value& vRet,
+                      CFX_WideString& sError);
+  FX_BOOL importAnXFDF(IFXJS_Context* cc,
+                       const CJS_Parameters& params,
+                       CJS_Value& vRet,
+                       CFX_WideString& sError);
+  FX_BOOL importTextData(IFXJS_Context* cc,
+                         const CJS_Parameters& params,
+                         CJS_Value& vRet,
+                         CFX_WideString& sError);
+  FX_BOOL insertPages(IFXJS_Context* cc,
+                      const CJS_Parameters& params,
+                      CJS_Value& vRet,
+                      CFX_WideString& sError);
+  FX_BOOL mailForm(IFXJS_Context* cc,
+                   const CJS_Parameters& params,
+                   CJS_Value& vRet,
+                   CFX_WideString& sError);
+  FX_BOOL print(IFXJS_Context* cc,
+                const CJS_Parameters& params,
+                CJS_Value& vRet,
+                CFX_WideString& sError);
+  FX_BOOL removeField(IFXJS_Context* cc,
+                      const CJS_Parameters& params,
+                      CJS_Value& vRet,
+                      CFX_WideString& sError);
+  FX_BOOL replacePages(IFXJS_Context* cc,
+                       const CJS_Parameters& params,
+                       CJS_Value& vRet,
+                       CFX_WideString& sError);
+  FX_BOOL resetForm(IFXJS_Context* cc,
+                    const CJS_Parameters& params,
+                    CJS_Value& vRet,
+                    CFX_WideString& sError);
+  FX_BOOL saveAs(IFXJS_Context* cc,
+                 const CJS_Parameters& params,
+                 CJS_Value& vRet,
+                 CFX_WideString& sError);
+  FX_BOOL submitForm(IFXJS_Context* cc,
+                     const CJS_Parameters& params,
+                     CJS_Value& vRet,
+                     CFX_WideString& sError);
+  FX_BOOL mailDoc(IFXJS_Context* cc,
+                  const CJS_Parameters& params,
+                  CJS_Value& vRet,
+                  CFX_WideString& sError);
+  FX_BOOL removeIcon(IFXJS_Context* cc,
+                     const CJS_Parameters& params,
+                     CJS_Value& vRet,
+                     CFX_WideString& sError);
+
+ public:
+  void AttachDoc(CPDFSDK_Document* pDoc);
+  CPDFSDK_Document* GetReaderDoc();
+  static FX_BOOL ExtractFileName(CPDFSDK_Document* pDoc,
+                                 CFX_ByteString& strFileName);
+  static FX_BOOL ExtractFolderName(CPDFSDK_Document* pDoc,
+                                   CFX_ByteString& strFolderName);
+  void AddDelayData(CJS_DelayData* pData);
+  void DoFieldDelay(const CFX_WideString& sFieldName, int nControlIndex);
+  void AddDelayAnnotData(CJS_AnnotObj* pData);
+  void DoAnnotDelay();
+  void SetIsolate(v8::Isolate* isolate) { m_isolate = isolate; }
+  CJS_Document* GetCJSDoc() const;
+
+ private:
+  CFX_WideString ReversalStr(CFX_WideString cbFrom);
+  CFX_WideString CutString(CFX_WideString cbFrom);
+  bool IsEnclosedInRect(CFX_FloatRect rect, CFX_FloatRect LinkRect);
+  int CountWords(CPDF_TextObject* pTextObj);
+  CFX_WideString GetObjWordStr(CPDF_TextObject* pTextObj, int nWordIndex);
+
+  v8::Isolate* m_isolate;
+  IconTree* m_pIconTree;
+  CPDFSDK_Document* m_pDocument;
+  CFX_WideString m_cwBaseURL;
+  bool m_bDelay;
+  CFX_ArrayTemplate<CJS_DelayData*> m_DelayData;
+  CFX_ArrayTemplate<CJS_AnnotObj*> m_DelayAnnotData;
+};
+
+class CJS_Document : public CJS_Object {
+ public:
+  explicit CJS_Document(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
+  ~CJS_Document() override {}
+
+  // CJS_Object
+  FX_BOOL InitInstance(IFXJS_Context* cc) override;
+
+  DECLARE_JS_CLASS(CJS_Document);
+
+  JS_STATIC_PROP(ADBE, Document);
+  JS_STATIC_PROP(author, Document);
+  JS_STATIC_PROP(baseURL, Document);
+  JS_STATIC_PROP(bookmarkRoot, Document);
+  JS_STATIC_PROP(calculate, Document);
+  JS_STATIC_PROP(Collab, Document);
+  JS_STATIC_PROP(creationDate, Document);
+  JS_STATIC_PROP(creator, Document);
+  JS_STATIC_PROP(delay, Document);
+  JS_STATIC_PROP(dirty, Document);
+  JS_STATIC_PROP(documentFileName, Document);
+  JS_STATIC_PROP(external, Document);
+  JS_STATIC_PROP(filesize, Document);
+  JS_STATIC_PROP(icons, Document);
+  JS_STATIC_PROP(info, Document);
+  JS_STATIC_PROP(keywords, Document);
+  JS_STATIC_PROP(layout, Document);
+  JS_STATIC_PROP(media, Document);
+  JS_STATIC_PROP(modDate, Document);
+  JS_STATIC_PROP(mouseX, Document);
+  JS_STATIC_PROP(mouseY, Document);
+  JS_STATIC_PROP(numFields, Document);
+  JS_STATIC_PROP(numPages, Document);
+  JS_STATIC_PROP(pageNum, Document);
+  JS_STATIC_PROP(pageWindowRect, Document);
+  JS_STATIC_PROP(path, Document);
+  JS_STATIC_PROP(producer, Document);
+  JS_STATIC_PROP(subject, Document);
+  JS_STATIC_PROP(title, Document);
+  JS_STATIC_PROP(zoom, Document);
+  JS_STATIC_PROP(zoomType, Document);
+
+  JS_STATIC_METHOD(addAnnot, Document);
+  JS_STATIC_METHOD(addField, Document);
+  JS_STATIC_METHOD(addLink, Document);
+  JS_STATIC_METHOD(addIcon, Document);
+  JS_STATIC_METHOD(calculateNow, Document);
+  JS_STATIC_METHOD(closeDoc, Document);
+  JS_STATIC_METHOD(createDataObject, Document);
+  JS_STATIC_METHOD(deletePages, Document);
+  JS_STATIC_METHOD(exportAsText, Document);
+  JS_STATIC_METHOD(exportAsFDF, Document);
+  JS_STATIC_METHOD(exportAsXFDF, Document);
+  JS_STATIC_METHOD(extractPages, Document);
+  JS_STATIC_METHOD(getAnnot, Document);
+  JS_STATIC_METHOD(getAnnots, Document);
+  JS_STATIC_METHOD(getAnnot3D, Document);
+  JS_STATIC_METHOD(getAnnots3D, Document);
+  JS_STATIC_METHOD(getField, Document);
+  JS_STATIC_METHOD(getIcon, Document);
+  JS_STATIC_METHOD(getLinks, Document);
+  JS_STATIC_METHOD(getNthFieldName, Document);
+  JS_STATIC_METHOD(getOCGs, Document);
+  JS_STATIC_METHOD(getPageBox, Document);
+  JS_STATIC_METHOD(getPageNthWord, Document);
+  JS_STATIC_METHOD(getPageNthWordQuads, Document);
+  JS_STATIC_METHOD(getPageNumWords, Document);
+  JS_STATIC_METHOD(getPrintParams, Document);
+  JS_STATIC_METHOD(getURL, Document);
+  JS_STATIC_METHOD(importAnFDF, Document);
+  JS_STATIC_METHOD(importAnXFDF, Document);
+  JS_STATIC_METHOD(importTextData, Document);
+  JS_STATIC_METHOD(insertPages, Document);
+  JS_STATIC_METHOD(mailForm, Document);
+  JS_STATIC_METHOD(print, Document);
+  JS_STATIC_METHOD(removeField, Document);
+  JS_STATIC_METHOD(replacePages, Document);
+  JS_STATIC_METHOD(removeIcon, Document);
+  JS_STATIC_METHOD(resetForm, Document);
+  JS_STATIC_METHOD(saveAs, Document);
+  JS_STATIC_METHOD(submitForm, Document);
+  JS_STATIC_METHOD(mailDoc, Document);
+};
+
+#endif  // FPDFSDK_SRC_JAVASCRIPT_DOCUMENT_H_
diff --git a/fpdfsdk/src/javascript/Field.cpp b/fpdfsdk/src/javascript/Field.cpp
index 7d2c769..2a631dc 100644
--- a/fpdfsdk/src/javascript/Field.cpp
+++ b/fpdfsdk/src/javascript/Field.cpp
@@ -4,18 +4,20 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
+#include "Field.h"
+
+#include "../../include/fsdk_mgr.h"  // For CPDFDoc_Environment.
 #include "../../include/javascript/IJavaScript.h"
-#include "../../include/javascript/JS_Define.h"
-#include "../../include/javascript/JS_Object.h"
-#include "../../include/javascript/JS_Value.h"
-#include "../../include/javascript/Field.h"
-#include "../../include/javascript/JS_EventHandler.h"
-#include "../../include/javascript/JS_Context.h"
-#include "../../include/javascript/JS_Runtime.h"
-#include "../../include/javascript/Document.h"
-#include "../../include/javascript/color.h"
-#include "../../include/javascript/PublicMethods.h"
-#include "../../include/javascript/Icon.h"
+#include "Document.h"
+#include "Icon.h"
+#include "JS_Context.h"
+#include "JS_Define.h"
+#include "JS_EventHandler.h"
+#include "JS_Object.h"
+#include "JS_Runtime.h"
+#include "JS_Value.h"
+#include "PublicMethods.h"
+#include "color.h"
 
 /* ---------------------- Field ---------------------- */
 
diff --git a/fpdfsdk/src/javascript/Field.h b/fpdfsdk/src/javascript/Field.h
new file mode 100644
index 0000000..a62bf39
--- /dev/null
+++ b/fpdfsdk/src/javascript/Field.h
@@ -0,0 +1,625 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FPDFSDK_SRC_JAVASCRIPT_FIELD_H_
+#define FPDFSDK_SRC_JAVASCRIPT_FIELD_H_
+
+#include <string>  // For std::wstring.
+
+#include "../../include/pdfwindow/PWL_Wnd.h"  // For CPWL_Color.
+#include "JS_Define.h"
+
+class CPDFSDK_Widget;
+class Document;
+
+enum FIELD_PROP {
+  FP_ALIGNMENT,
+  FP_BORDERSTYLE,
+  FP_BUTTONALIGNX,
+  FP_BUTTONALIGNY,
+  FP_BUTTONFITBOUNDS,
+  FP_BUTTONPOSITION,
+  FP_BUTTONSCALEHOW,
+  FP_BUTTONSCALEWHEN,
+  FP_CALCORDERINDEX,
+  FP_CHARLIMIT,
+  FP_COMB,
+  FP_COMMITONSELCHANGE,
+  FP_CURRENTVALUEINDICES,
+  FP_DEFAULTVALUE,
+  FP_DONOTSCROLL,
+  FP_DISPLAY,
+  FP_FILLCOLOR,
+  FP_HIDDEN,
+  FP_HIGHLIGHT,
+  FP_LINEWIDTH,
+  FP_MULTILINE,
+  FP_MULTIPLESELECTION,
+  FP_PASSWORD,
+  FP_RECT,
+  FP_RICHTEXT,
+  FP_RICHVALUE,
+  FP_ROTATION,
+  FP_STROKECOLOR,
+  FP_STYLE,
+  FP_TEXTCOLOR,
+  FP_TEXTFONT,
+  FP_TEXTSIZE,
+  FP_USERNAME,
+  FP_VALUE
+};
+
+class CJS_WideStringArray {
+ public:
+  CJS_WideStringArray() {}
+  virtual ~CJS_WideStringArray() {
+    for (int i = 0, sz = m_Data.GetSize(); i < sz; i++)
+      delete m_Data.GetAt(i);
+    m_Data.RemoveAll();
+  }
+
+  void Add(const CFX_WideString& string) {
+    m_Data.Add(new CFX_WideString(string));
+  }
+
+  int GetSize() const { return m_Data.GetSize(); }
+
+  CFX_WideString GetAt(int i) const { return *m_Data.GetAt(i); }
+
+ private:
+  CFX_ArrayTemplate<CFX_WideString*> m_Data;
+};
+
+struct CJS_DelayData {
+  CFX_WideString sFieldName;
+  int nControlIndex;
+  enum FIELD_PROP eProp;
+  int32_t num;
+  bool b;
+  CFX_ByteString string;
+  CFX_WideString widestring;
+  CPDF_Rect rect;
+  CPWL_Color color;
+  CFX_DWordArray wordarray;
+  CJS_WideStringArray widestringarray;
+};
+
+class Field : public CJS_EmbedObj {
+ public:
+  Field(CJS_Object* pJSObject);
+  ~Field() override;
+
+  FX_BOOL alignment(IFXJS_Context* cc,
+                    CJS_PropValue& vp,
+                    CFX_WideString& sError);
+  FX_BOOL borderStyle(IFXJS_Context* cc,
+                      CJS_PropValue& vp,
+                      CFX_WideString& sError);
+  FX_BOOL buttonAlignX(IFXJS_Context* cc,
+                       CJS_PropValue& vp,
+                       CFX_WideString& sError);
+  FX_BOOL buttonAlignY(IFXJS_Context* cc,
+                       CJS_PropValue& vp,
+                       CFX_WideString& sError);
+  FX_BOOL buttonFitBounds(IFXJS_Context* cc,
+                          CJS_PropValue& vp,
+                          CFX_WideString& sError);
+  FX_BOOL buttonPosition(IFXJS_Context* cc,
+                         CJS_PropValue& vp,
+                         CFX_WideString& sError);
+  FX_BOOL buttonScaleHow(IFXJS_Context* cc,
+                         CJS_PropValue& vp,
+                         CFX_WideString& sError);
+  FX_BOOL buttonScaleWhen(IFXJS_Context* cc,
+                          CJS_PropValue& vp,
+                          CFX_WideString& sError);
+  FX_BOOL calcOrderIndex(IFXJS_Context* cc,
+                         CJS_PropValue& vp,
+                         CFX_WideString& sError);
+  FX_BOOL charLimit(IFXJS_Context* cc,
+                    CJS_PropValue& vp,
+                    CFX_WideString& sError);
+  FX_BOOL comb(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL commitOnSelChange(IFXJS_Context* cc,
+                            CJS_PropValue& vp,
+                            CFX_WideString& sError);
+  FX_BOOL currentValueIndices(IFXJS_Context* cc,
+                              CJS_PropValue& vp,
+                              CFX_WideString& sError);
+  FX_BOOL defaultStyle(IFXJS_Context* cc,
+                       CJS_PropValue& vp,
+                       CFX_WideString& sError);
+  FX_BOOL defaultValue(IFXJS_Context* cc,
+                       CJS_PropValue& vp,
+                       CFX_WideString& sError);
+  FX_BOOL doNotScroll(IFXJS_Context* cc,
+                      CJS_PropValue& vp,
+                      CFX_WideString& sError);
+  FX_BOOL doNotSpellCheck(IFXJS_Context* cc,
+                          CJS_PropValue& vp,
+                          CFX_WideString& sError);
+  FX_BOOL delay(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL display(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL doc(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL editable(IFXJS_Context* cc,
+                   CJS_PropValue& vp,
+                   CFX_WideString& sError);
+  FX_BOOL exportValues(IFXJS_Context* cc,
+                       CJS_PropValue& vp,
+                       CFX_WideString& sError);
+  FX_BOOL fileSelect(IFXJS_Context* cc,
+                     CJS_PropValue& vp,
+                     CFX_WideString& sError);
+  FX_BOOL fillColor(IFXJS_Context* cc,
+                    CJS_PropValue& vp,
+                    CFX_WideString& sError);
+  FX_BOOL hidden(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL highlight(IFXJS_Context* cc,
+                    CJS_PropValue& vp,
+                    CFX_WideString& sError);
+  FX_BOOL lineWidth(IFXJS_Context* cc,
+                    CJS_PropValue& vp,
+                    CFX_WideString& sError);
+  FX_BOOL multiline(IFXJS_Context* cc,
+                    CJS_PropValue& vp,
+                    CFX_WideString& sError);
+  FX_BOOL multipleSelection(IFXJS_Context* cc,
+                            CJS_PropValue& vp,
+                            CFX_WideString& sError);
+  FX_BOOL name(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL numItems(IFXJS_Context* cc,
+                   CJS_PropValue& vp,
+                   CFX_WideString& sError);
+  FX_BOOL page(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL password(IFXJS_Context* cc,
+                   CJS_PropValue& vp,
+                   CFX_WideString& sError);
+  FX_BOOL print(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL radiosInUnison(IFXJS_Context* cc,
+                         CJS_PropValue& vp,
+                         CFX_WideString& sError);
+  FX_BOOL readonly(IFXJS_Context* cc,
+                   CJS_PropValue& vp,
+                   CFX_WideString& sError);
+  FX_BOOL rect(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL required(IFXJS_Context* cc,
+                   CJS_PropValue& vp,
+                   CFX_WideString& sError);
+  FX_BOOL richText(IFXJS_Context* cc,
+                   CJS_PropValue& vp,
+                   CFX_WideString& sError);
+  FX_BOOL richValue(IFXJS_Context* cc,
+                    CJS_PropValue& vp,
+                    CFX_WideString& sError);
+  FX_BOOL rotation(IFXJS_Context* cc,
+                   CJS_PropValue& vp,
+                   CFX_WideString& sError);
+  FX_BOOL strokeColor(IFXJS_Context* cc,
+                      CJS_PropValue& vp,
+                      CFX_WideString& sError);
+  FX_BOOL style(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL submitName(IFXJS_Context* cc,
+                     CJS_PropValue& vp,
+                     CFX_WideString& sError);
+  FX_BOOL textColor(IFXJS_Context* cc,
+                    CJS_PropValue& vp,
+                    CFX_WideString& sError);
+  FX_BOOL textFont(IFXJS_Context* cc,
+                   CJS_PropValue& vp,
+                   CFX_WideString& sError);
+  FX_BOOL textSize(IFXJS_Context* cc,
+                   CJS_PropValue& vp,
+                   CFX_WideString& sError);
+  FX_BOOL type(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL userName(IFXJS_Context* cc,
+                   CJS_PropValue& vp,
+                   CFX_WideString& sError);
+  FX_BOOL value(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL valueAsString(IFXJS_Context* cc,
+                        CJS_PropValue& vp,
+                        CFX_WideString& sError);
+  FX_BOOL source(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+
+  FX_BOOL browseForFileToSubmit(IFXJS_Context* cc,
+                                const CJS_Parameters& params,
+                                CJS_Value& vRet,
+                                CFX_WideString& sError);
+  FX_BOOL buttonGetCaption(IFXJS_Context* cc,
+                           const CJS_Parameters& params,
+                           CJS_Value& vRet,
+                           CFX_WideString& sError);
+  FX_BOOL buttonGetIcon(IFXJS_Context* cc,
+                        const CJS_Parameters& params,
+                        CJS_Value& vRet,
+                        CFX_WideString& sError);
+  FX_BOOL buttonImportIcon(IFXJS_Context* cc,
+                           const CJS_Parameters& params,
+                           CJS_Value& vRet,
+                           CFX_WideString& sError);
+  FX_BOOL buttonSetCaption(IFXJS_Context* cc,
+                           const CJS_Parameters& params,
+                           CJS_Value& vRet,
+                           CFX_WideString& sError);
+  FX_BOOL buttonSetIcon(IFXJS_Context* cc,
+                        const CJS_Parameters& params,
+                        CJS_Value& vRet,
+                        CFX_WideString& sError);
+  FX_BOOL checkThisBox(IFXJS_Context* cc,
+                       const CJS_Parameters& params,
+                       CJS_Value& vRet,
+                       CFX_WideString& sError);
+  FX_BOOL clearItems(IFXJS_Context* cc,
+                     const CJS_Parameters& params,
+                     CJS_Value& vRet,
+                     CFX_WideString& sError);
+  FX_BOOL defaultIsChecked(IFXJS_Context* cc,
+                           const CJS_Parameters& params,
+                           CJS_Value& vRet,
+                           CFX_WideString& sError);
+  FX_BOOL deleteItemAt(IFXJS_Context* cc,
+                       const CJS_Parameters& params,
+                       CJS_Value& vRet,
+                       CFX_WideString& sError);
+  FX_BOOL getArray(IFXJS_Context* cc,
+                   const CJS_Parameters& params,
+                   CJS_Value& vRet,
+                   CFX_WideString& sError);
+  FX_BOOL getItemAt(IFXJS_Context* cc,
+                    const CJS_Parameters& params,
+                    CJS_Value& vRet,
+                    CFX_WideString& sError);
+  FX_BOOL getLock(IFXJS_Context* cc,
+                  const CJS_Parameters& params,
+                  CJS_Value& vRet,
+                  CFX_WideString& sError);
+  FX_BOOL insertItemAt(IFXJS_Context* cc,
+                       const CJS_Parameters& params,
+                       CJS_Value& vRet,
+                       CFX_WideString& sError);
+  FX_BOOL isBoxChecked(IFXJS_Context* cc,
+                       const CJS_Parameters& params,
+                       CJS_Value& vRet,
+                       CFX_WideString& sError);
+  FX_BOOL isDefaultChecked(IFXJS_Context* cc,
+                           const CJS_Parameters& params,
+                           CJS_Value& vRet,
+                           CFX_WideString& sError);
+  FX_BOOL setAction(IFXJS_Context* cc,
+                    const CJS_Parameters& params,
+                    CJS_Value& vRet,
+                    CFX_WideString& sError);
+  FX_BOOL setFocus(IFXJS_Context* cc,
+                   const CJS_Parameters& params,
+                   CJS_Value& vRet,
+                   CFX_WideString& sError);
+  FX_BOOL setItems(IFXJS_Context* cc,
+                   const CJS_Parameters& params,
+                   CJS_Value& vRet,
+                   CFX_WideString& sError);
+  FX_BOOL setLock(IFXJS_Context* cc,
+                  const CJS_Parameters& params,
+                  CJS_Value& vRet,
+                  CFX_WideString& sError);
+  FX_BOOL signatureGetModifications(IFXJS_Context* cc,
+                                    const CJS_Parameters& params,
+                                    CJS_Value& vRet,
+                                    CFX_WideString& sError);
+  FX_BOOL signatureGetSeedValue(IFXJS_Context* cc,
+                                const CJS_Parameters& params,
+                                CJS_Value& vRet,
+                                CFX_WideString& sError);
+  FX_BOOL signatureInfo(IFXJS_Context* cc,
+                        const CJS_Parameters& params,
+                        CJS_Value& vRet,
+                        CFX_WideString& sError);
+  FX_BOOL signatureSetSeedValue(IFXJS_Context* cc,
+                                const CJS_Parameters& params,
+                                CJS_Value& vRet,
+                                CFX_WideString& sError);
+  FX_BOOL signatureSign(IFXJS_Context* cc,
+                        const CJS_Parameters& params,
+                        CJS_Value& vRet,
+                        CFX_WideString& sError);
+  FX_BOOL signatureValidate(IFXJS_Context* cc,
+                            const CJS_Parameters& params,
+                            CJS_Value& vRet,
+                            CFX_WideString& sError);
+
+ public:
+  static void SetAlignment(CPDFSDK_Document* pDocument,
+                           const CFX_WideString& swFieldName,
+                           int nControlIndex,
+                           const CFX_ByteString& string);
+  static void SetBorderStyle(CPDFSDK_Document* pDocument,
+                             const CFX_WideString& swFieldName,
+                             int nControlIndex,
+                             const CFX_ByteString& string);
+  static void SetButtonAlignX(CPDFSDK_Document* pDocument,
+                              const CFX_WideString& swFieldName,
+                              int nControlIndex,
+                              int number);
+  static void SetButtonAlignY(CPDFSDK_Document* pDocument,
+                              const CFX_WideString& swFieldName,
+                              int nControlIndex,
+                              int number);
+  static void SetButtonFitBounds(CPDFSDK_Document* pDocument,
+                                 const CFX_WideString& swFieldName,
+                                 int nControlIndex,
+                                 bool b);
+  static void SetButtonPosition(CPDFSDK_Document* pDocument,
+                                const CFX_WideString& swFieldName,
+                                int nControlIndex,
+                                int number);
+  static void SetButtonScaleHow(CPDFSDK_Document* pDocument,
+                                const CFX_WideString& swFieldName,
+                                int nControlIndex,
+                                int number);
+  static void SetButtonScaleWhen(CPDFSDK_Document* pDocument,
+                                 const CFX_WideString& swFieldName,
+                                 int nControlIndex,
+                                 int number);
+  static void SetCalcOrderIndex(CPDFSDK_Document* pDocument,
+                                const CFX_WideString& swFieldName,
+                                int nControlIndex,
+                                int number);
+  static void SetCharLimit(CPDFSDK_Document* pDocument,
+                           const CFX_WideString& swFieldName,
+                           int nControlIndex,
+                           int number);
+  static void SetComb(CPDFSDK_Document* pDocument,
+                      const CFX_WideString& swFieldName,
+                      int nControlIndex,
+                      bool b);
+  static void SetCommitOnSelChange(CPDFSDK_Document* pDocument,
+                                   const CFX_WideString& swFieldName,
+                                   int nControlIndex,
+                                   bool b);
+  static void SetCurrentValueIndices(CPDFSDK_Document* pDocument,
+                                     const CFX_WideString& swFieldName,
+                                     int nControlIndex,
+                                     const CFX_DWordArray& array);
+  static void SetDefaultStyle(CPDFSDK_Document* pDocument,
+                              const CFX_WideString& swFieldName,
+                              int nControlIndex);
+  static void SetDefaultValue(CPDFSDK_Document* pDocument,
+                              const CFX_WideString& swFieldName,
+                              int nControlIndex,
+                              const CFX_WideString& string);
+  static void SetDoNotScroll(CPDFSDK_Document* pDocument,
+                             const CFX_WideString& swFieldName,
+                             int nControlIndex,
+                             bool b);
+  static void SetDisplay(CPDFSDK_Document* pDocument,
+                         const CFX_WideString& swFieldName,
+                         int nControlIndex,
+                         int number);
+  static void SetFillColor(CPDFSDK_Document* pDocument,
+                           const CFX_WideString& swFieldName,
+                           int nControlIndex,
+                           const CPWL_Color& color);
+  static void SetHidden(CPDFSDK_Document* pDocument,
+                        const CFX_WideString& swFieldName,
+                        int nControlIndex,
+                        bool b);
+  static void SetHighlight(CPDFSDK_Document* pDocument,
+                           const CFX_WideString& swFieldName,
+                           int nControlIndex,
+                           const CFX_ByteString& string);
+  static void SetLineWidth(CPDFSDK_Document* pDocument,
+                           const CFX_WideString& swFieldName,
+                           int nControlIndex,
+                           int number);
+  static void SetMultiline(CPDFSDK_Document* pDocument,
+                           const CFX_WideString& swFieldName,
+                           int nControlIndex,
+                           bool b);
+  static void SetMultipleSelection(CPDFSDK_Document* pDocument,
+                                   const CFX_WideString& swFieldName,
+                                   int nControlIndex,
+                                   bool b);
+  static void SetPassword(CPDFSDK_Document* pDocument,
+                          const CFX_WideString& swFieldName,
+                          int nControlIndex,
+                          bool b);
+  static void SetRect(CPDFSDK_Document* pDocument,
+                      const CFX_WideString& swFieldName,
+                      int nControlIndex,
+                      const CPDF_Rect& rect);
+  static void SetRichText(CPDFSDK_Document* pDocument,
+                          const CFX_WideString& swFieldName,
+                          int nControlIndex,
+                          bool b);
+  static void SetRichValue(CPDFSDK_Document* pDocument,
+                           const CFX_WideString& swFieldName,
+                           int nControlIndex);
+  static void SetRotation(CPDFSDK_Document* pDocument,
+                          const CFX_WideString& swFieldName,
+                          int nControlIndex,
+                          int number);
+  static void SetStrokeColor(CPDFSDK_Document* pDocument,
+                             const CFX_WideString& swFieldName,
+                             int nControlIndex,
+                             const CPWL_Color& color);
+  static void SetStyle(CPDFSDK_Document* pDocument,
+                       const CFX_WideString& swFieldName,
+                       int nControlIndex,
+                       const CFX_ByteString& string);
+  static void SetTextColor(CPDFSDK_Document* pDocument,
+                           const CFX_WideString& swFieldName,
+                           int nControlIndex,
+                           const CPWL_Color& color);
+  static void SetTextFont(CPDFSDK_Document* pDocument,
+                          const CFX_WideString& swFieldName,
+                          int nControlIndex,
+                          const CFX_ByteString& string);
+  static void SetTextSize(CPDFSDK_Document* pDocument,
+                          const CFX_WideString& swFieldName,
+                          int nControlIndex,
+                          int number);
+  static void SetUserName(CPDFSDK_Document* pDocument,
+                          const CFX_WideString& swFieldName,
+                          int nControlIndex,
+                          const CFX_WideString& string);
+  static void SetValue(CPDFSDK_Document* pDocument,
+                       const CFX_WideString& swFieldName,
+                       int nControlIndex,
+                       const CJS_WideStringArray& strArray);
+
+ public:
+  static void AddField(CPDFSDK_Document* pDocument,
+                       int nPageIndex,
+                       int nFieldType,
+                       const CFX_WideString& sName,
+                       const CPDF_Rect& rcCoords);
+
+ public:
+  static void UpdateFormField(CPDFSDK_Document* pDocument,
+                              CPDF_FormField* pFormField,
+                              FX_BOOL bChangeMark,
+                              FX_BOOL bResetAP,
+                              FX_BOOL bRefresh);
+  static void UpdateFormControl(CPDFSDK_Document* pDocument,
+                                CPDF_FormControl* pFormControl,
+                                FX_BOOL bChangeMark,
+                                FX_BOOL bResetAP,
+                                FX_BOOL bRefresh);
+
+  static CPDFSDK_Widget* GetWidget(CPDFSDK_Document* pDocument,
+                                   CPDF_FormControl* pFormControl);
+  static void GetFormFields(CPDFSDK_Document* pDocument,
+                            const CFX_WideString& csFieldName,
+                            CFX_PtrArray& FieldsArray);
+
+  static void DoDelay(CPDFSDK_Document* pDocument, CJS_DelayData* pData);
+
+ public:
+  FX_BOOL AttachField(Document* pDocument, const CFX_WideString& csFieldName);
+  void SetDelay(FX_BOOL bDelay);
+  void SetIsolate(v8::Isolate* isolate) { m_isolate = isolate; }
+
+ protected:
+  void ParseFieldName(const std::wstring& strFieldNameParsed,
+                      std::wstring& strFieldName,
+                      int& iControlNo);
+  void GetFormFields(const CFX_WideString& csFieldName,
+                     CFX_PtrArray& FieldsArray);
+  CPDF_FormControl* GetSmartFieldControl(CPDF_FormField* pFormField);
+  FX_BOOL ValueIsOccur(CPDF_FormField* pFormField, CFX_WideString csOptLabel);
+
+  void AddDelay_Int(enum FIELD_PROP prop, int32_t n);
+  void AddDelay_Bool(enum FIELD_PROP prop, bool b);
+  void AddDelay_String(enum FIELD_PROP prop, const CFX_ByteString& string);
+  void AddDelay_WideString(enum FIELD_PROP prop, const CFX_WideString& string);
+  void AddDelay_Rect(enum FIELD_PROP prop, const CPDF_Rect& rect);
+  void AddDelay_Color(enum FIELD_PROP prop, const CPWL_Color& color);
+  void AddDelay_WordArray(enum FIELD_PROP prop, const CFX_DWordArray& array);
+  void AddDelay_WideStringArray(enum FIELD_PROP prop,
+                                const CJS_WideStringArray& array);
+
+  void DoDelay();
+
+ public:
+  Document* m_pJSDoc;
+  CPDFSDK_Document* m_pDocument;
+  CFX_WideString m_FieldName;
+  int m_nFormControlIndex;
+  FX_BOOL m_bCanSet;
+
+  FX_BOOL m_bDelay;
+  v8::Isolate* m_isolate;
+};
+
+class CJS_Field : public CJS_Object {
+ public:
+  CJS_Field(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
+  ~CJS_Field(void) override {}
+
+  FX_BOOL InitInstance(IFXJS_Context* cc) override;
+
+  DECLARE_JS_CLASS(CJS_Field);
+
+  JS_STATIC_PROP(alignment, Field);
+  JS_STATIC_PROP(borderStyle, Field);
+  JS_STATIC_PROP(buttonAlignX, Field);
+  JS_STATIC_PROP(buttonAlignY, Field);
+  JS_STATIC_PROP(buttonFitBounds, Field);
+  JS_STATIC_PROP(buttonPosition, Field);
+  JS_STATIC_PROP(buttonScaleHow, Field);
+  JS_STATIC_PROP(buttonScaleWhen, Field);
+  JS_STATIC_PROP(calcOrderIndex, Field);
+  JS_STATIC_PROP(charLimit, Field);
+  JS_STATIC_PROP(comb, Field);
+  JS_STATIC_PROP(commitOnSelChange, Field);
+  JS_STATIC_PROP(currentValueIndices, Field);
+  JS_STATIC_PROP(defaultStyle, Field);
+  JS_STATIC_PROP(defaultValue, Field);
+  JS_STATIC_PROP(doNotScroll, Field);
+  JS_STATIC_PROP(doNotSpellCheck, Field);
+  JS_STATIC_PROP(delay, Field);
+  JS_STATIC_PROP(display, Field);
+  JS_STATIC_PROP(doc, Field);
+  JS_STATIC_PROP(editable, Field);
+  JS_STATIC_PROP(exportValues, Field);
+  JS_STATIC_PROP(fileSelect, Field);
+  JS_STATIC_PROP(fillColor, Field);
+  JS_STATIC_PROP(hidden, Field);
+  JS_STATIC_PROP(highlight, Field);
+  JS_STATIC_PROP(lineWidth, Field);
+  JS_STATIC_PROP(multiline, Field);
+  JS_STATIC_PROP(multipleSelection, Field);
+  JS_STATIC_PROP(name, Field);
+  JS_STATIC_PROP(numItems, Field);
+  JS_STATIC_PROP(page, Field);
+  JS_STATIC_PROP(password, Field);
+  JS_STATIC_PROP(print, Field);
+  JS_STATIC_PROP(radiosInUnison, Field);
+  JS_STATIC_PROP(readonly, Field);
+  JS_STATIC_PROP(rect, Field);
+  JS_STATIC_PROP(required, Field);
+  JS_STATIC_PROP(richText, Field);
+  JS_STATIC_PROP(richValue, Field);
+  JS_STATIC_PROP(rotation, Field);
+  JS_STATIC_PROP(strokeColor, Field);
+  JS_STATIC_PROP(style, Field);
+  JS_STATIC_PROP(submitName, Field);
+  JS_STATIC_PROP(textColor, Field);
+  JS_STATIC_PROP(textFont, Field);
+  JS_STATIC_PROP(textSize, Field);
+  JS_STATIC_PROP(type, Field);
+  JS_STATIC_PROP(userName, Field);
+  JS_STATIC_PROP(value, Field);
+  JS_STATIC_PROP(valueAsString, Field);
+  JS_STATIC_PROP(source, Field);
+
+  JS_STATIC_METHOD(browseForFileToSubmit, Field);
+  JS_STATIC_METHOD(buttonGetCaption, Field);
+  JS_STATIC_METHOD(buttonGetIcon, Field);
+  JS_STATIC_METHOD(buttonImportIcon, Field);
+  JS_STATIC_METHOD(buttonSetCaption, Field);
+  JS_STATIC_METHOD(buttonSetIcon, Field);
+  JS_STATIC_METHOD(checkThisBox, Field);
+  JS_STATIC_METHOD(clearItems, Field);
+  JS_STATIC_METHOD(defaultIsChecked, Field);
+  JS_STATIC_METHOD(deleteItemAt, Field);
+  JS_STATIC_METHOD(getArray, Field);
+  JS_STATIC_METHOD(getItemAt, Field);
+  JS_STATIC_METHOD(getLock, Field);
+  JS_STATIC_METHOD(insertItemAt, Field);
+  JS_STATIC_METHOD(isBoxChecked, Field);
+  JS_STATIC_METHOD(isDefaultChecked, Field);
+  JS_STATIC_METHOD(setAction, Field);
+  JS_STATIC_METHOD(setFocus, Field);
+  JS_STATIC_METHOD(setItems, Field);
+  JS_STATIC_METHOD(setLock, Field);
+  JS_STATIC_METHOD(signatureGetModifications, Field);
+  JS_STATIC_METHOD(signatureGetSeedValue, Field);
+  JS_STATIC_METHOD(signatureInfo, Field);
+  JS_STATIC_METHOD(signatureSetSeedValue, Field);
+  JS_STATIC_METHOD(signatureSign, Field);
+  JS_STATIC_METHOD(signatureValidate, Field);
+};
+
+#endif  // FPDFSDK_SRC_JAVASCRIPT_FIELD_H_
diff --git a/fpdfsdk/src/javascript/Icon.cpp b/fpdfsdk/src/javascript/Icon.cpp
index 4468fac..044a38e 100644
--- a/fpdfsdk/src/javascript/Icon.cpp
+++ b/fpdfsdk/src/javascript/Icon.cpp
@@ -4,11 +4,12 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
+#include "Icon.h"
+
 #include "../../include/javascript/IJavaScript.h"
-#include "../../include/javascript/JS_Define.h"
-#include "../../include/javascript/JS_Object.h"
-#include "../../include/javascript/JS_Value.h"
-#include "../../include/javascript/Icon.h"
+#include "JS_Define.h"
+#include "JS_Object.h"
+#include "JS_Value.h"
 
 /* ---------------------- Icon ---------------------- */
 
diff --git a/fpdfsdk/src/javascript/Icon.h b/fpdfsdk/src/javascript/Icon.h
new file mode 100644
index 0000000..b03048b
--- /dev/null
+++ b/fpdfsdk/src/javascript/Icon.h
@@ -0,0 +1,39 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FPDFSDK_SRC_JAVASCRIPT_ICON_H_
+#define FPDFSDK_SRC_JAVASCRIPT_ICON_H_
+
+#include "JS_Define.h"
+
+class Icon : public CJS_EmbedObj {
+ public:
+  Icon(CJS_Object* pJSObject);
+  ~Icon() override;
+
+  FX_BOOL name(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  void SetStream(CPDF_Stream* pIconStream);
+  CPDF_Stream* GetStream();
+  void SetIconName(CFX_WideString name);
+  CFX_WideString GetIconName();
+
+ private:
+  CPDF_Stream* m_pIconStream;
+  CFX_WideString m_swIconName;
+};
+
+class CJS_Icon : public CJS_Object {
+ public:
+  CJS_Icon(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
+  ~CJS_Icon() override {}
+
+ public:
+  DECLARE_JS_CLASS(CJS_Icon);
+
+  JS_STATIC_PROP(name, Icon);
+};
+
+#endif  // FPDFSDK_SRC_JAVASCRIPT_ICON_H_
diff --git a/fpdfsdk/src/javascript/JS_Context.cpp b/fpdfsdk/src/javascript/JS_Context.cpp
index 44756b6..4769dac 100644
--- a/fpdfsdk/src/javascript/JS_Context.cpp
+++ b/fpdfsdk/src/javascript/JS_Context.cpp
@@ -4,11 +4,12 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
+#include "JS_Context.h"
+
 #include "../../include/javascript/IJavaScript.h"
-#include "../../include/javascript/JS_Context.h"
-#include "../../include/javascript/JS_EventHandler.h"
-#include "../../include/javascript/JS_Runtime.h"
-#include "../../include/javascript/resource.h"
+#include "JS_EventHandler.h"
+#include "JS_Runtime.h"
+#include "resource.h"
 
 /* -------------------------- CJS_Context -------------------------- */
 
diff --git a/fpdfsdk/src/javascript/JS_Context.h b/fpdfsdk/src/javascript/JS_Context.h
new file mode 100644
index 0000000..b1e1bce
--- /dev/null
+++ b/fpdfsdk/src/javascript/JS_Context.h
@@ -0,0 +1,137 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FPDFSDK_SRC_JAVASCRIPT_JS_CONTEXT_H_
+#define FPDFSDK_SRC_JAVASCRIPT_JS_CONTEXT_H_
+
+#include "../../../core/include/fxcrt/fx_system.h"
+#include "../../../core/include/fxcrt/fx_string.h"
+#include "../../include/javascript/IJavaScript.h"
+
+class CJS_EventHandler;
+class CJS_Runtime;
+
+class CJS_Context : public IFXJS_Context {
+ public:
+  explicit CJS_Context(CJS_Runtime* pRuntime);
+  ~CJS_Context() override;
+
+  // IFXJS_Context
+  FX_BOOL RunScript(const CFX_WideString& script,
+                    CFX_WideString& info) override;
+  void OnApp_Init() override;
+  void OnDoc_Open(CPDFSDK_Document* pDoc,
+                  const CFX_WideString& strTargetName) override;
+  void OnDoc_WillPrint(CPDFSDK_Document* pDoc) override;
+  void OnDoc_DidPrint(CPDFSDK_Document* pDoc) override;
+  void OnDoc_WillSave(CPDFSDK_Document* pDoc) override;
+  void OnDoc_DidSave(CPDFSDK_Document* pDoc) override;
+  void OnDoc_WillClose(CPDFSDK_Document* pDoc) override;
+  void OnPage_Open(CPDFSDK_Document* pTarget) override;
+  void OnPage_Close(CPDFSDK_Document* pTarget) override;
+  void OnPage_InView(CPDFSDK_Document* pTarget) override;
+  void OnPage_OutView(CPDFSDK_Document* pTarget) override;
+  void OnField_MouseDown(FX_BOOL bModifier,
+                         FX_BOOL bShift,
+                         CPDF_FormField* pTarget) override;
+  void OnField_MouseEnter(FX_BOOL bModifier,
+                          FX_BOOL bShift,
+                          CPDF_FormField* pTarget) override;
+  void OnField_MouseExit(FX_BOOL bModifier,
+                         FX_BOOL bShift,
+                         CPDF_FormField* pTarget) override;
+  void OnField_MouseUp(FX_BOOL bModifier,
+                       FX_BOOL bShift,
+                       CPDF_FormField* pTarget) override;
+  void OnField_Focus(FX_BOOL bModifier,
+                     FX_BOOL bShift,
+                     CPDF_FormField* pTarget,
+                     const CFX_WideString& Value) override;
+  void OnField_Blur(FX_BOOL bModifier,
+                    FX_BOOL bShift,
+                    CPDF_FormField* pTarget,
+                    const CFX_WideString& Value) override;
+  void OnField_Calculate(CPDF_FormField* pSource,
+                         CPDF_FormField* pTarget,
+                         CFX_WideString& Value,
+                         FX_BOOL& bRc) override;
+  void OnField_Format(CPDF_FormField* pTarget,
+                      CFX_WideString& Value,
+                      FX_BOOL bWillCommit) override;
+  void OnField_Keystroke(CFX_WideString& strChange,
+                         const CFX_WideString& strChangeEx,
+                         FX_BOOL bKeyDown,
+                         FX_BOOL bModifier,
+                         int& nSelEnd,
+                         int& nSelStart,
+                         FX_BOOL bShift,
+                         CPDF_FormField* pTarget,
+                         CFX_WideString& Value,
+                         FX_BOOL bWillCommit,
+                         FX_BOOL bFieldFull,
+                         FX_BOOL& bRc) override;
+  void OnField_Validate(CFX_WideString& strChange,
+                        const CFX_WideString& strChangeEx,
+                        FX_BOOL bKeyDown,
+                        FX_BOOL bModifier,
+                        FX_BOOL bShift,
+                        CPDF_FormField* pTarget,
+                        CFX_WideString& Value,
+                        FX_BOOL& bRc) override;
+  void OnScreen_Focus(FX_BOOL bModifier,
+                      FX_BOOL bShift,
+                      CPDFSDK_Annot* pScreen) override;
+  void OnScreen_Blur(FX_BOOL bModifier,
+                     FX_BOOL bShift,
+                     CPDFSDK_Annot* pScreen) override;
+  void OnScreen_Open(FX_BOOL bModifier,
+                     FX_BOOL bShift,
+                     CPDFSDK_Annot* pScreen) override;
+  void OnScreen_Close(FX_BOOL bModifier,
+                      FX_BOOL bShift,
+                      CPDFSDK_Annot* pScreen) override;
+  void OnScreen_MouseDown(FX_BOOL bModifier,
+                          FX_BOOL bShift,
+                          CPDFSDK_Annot* pScreen) override;
+  void OnScreen_MouseUp(FX_BOOL bModifier,
+                        FX_BOOL bShift,
+                        CPDFSDK_Annot* pScreen) override;
+  void OnScreen_MouseEnter(FX_BOOL bModifier,
+                           FX_BOOL bShift,
+                           CPDFSDK_Annot* pScreen) override;
+  void OnScreen_MouseExit(FX_BOOL bModifier,
+                          FX_BOOL bShift,
+                          CPDFSDK_Annot* pScreen) override;
+  void OnScreen_InView(FX_BOOL bModifier,
+                       FX_BOOL bShift,
+                       CPDFSDK_Annot* pScreen) override;
+  void OnScreen_OutView(FX_BOOL bModifier,
+                        FX_BOOL bShift,
+                        CPDFSDK_Annot* pScreen) override;
+  void OnBookmark_MouseUp(CPDF_Bookmark* pBookMark) override;
+  void OnLink_MouseUp(CPDFSDK_Document* pTarget) override;
+  void OnMenu_Exec(CPDFSDK_Document* pTarget,
+                   const CFX_WideString& strTargetName) override;
+  void OnBatchExec(CPDFSDK_Document* pTarget) override;
+  void OnConsole_Exec() override;
+  void OnExternal_Exec() override;
+  void EnableMessageBox(FX_BOOL bEnable) override { m_bMsgBoxEnable = bEnable; }
+
+  FX_BOOL IsMsgBoxEnabled() const { return m_bMsgBoxEnable; }
+
+  CPDFDoc_Environment* GetReaderApp();
+  CJS_Runtime* GetJSRuntime() const { return m_pRuntime; }
+  CJS_EventHandler* GetEventHandler() const { return m_pEventHandler; }
+  CPDFSDK_Document* GetReaderDocument();
+
+ private:
+  CJS_Runtime* m_pRuntime;
+  CJS_EventHandler* m_pEventHandler;
+  FX_BOOL m_bBusy;
+  FX_BOOL m_bMsgBoxEnable;
+};
+
+#endif  // FPDFSDK_SRC_JAVASCRIPT_JS_CONTEXT_H_
diff --git a/fpdfsdk/src/javascript/JS_Define.h b/fpdfsdk/src/javascript/JS_Define.h
new file mode 100644
index 0000000..8c00ba5
--- /dev/null
+++ b/fpdfsdk/src/javascript/JS_Define.h
@@ -0,0 +1,479 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FPDFSDK_SRC_JAVASCRIPT_JS_DEFINE_H_
+#define FPDFSDK_SRC_JAVASCRIPT_JS_DEFINE_H_
+
+#include "../../include/jsapi/fxjs_v8.h"
+#include "resource.h"
+#include "JS_Object.h"
+#include "JS_Value.h"
+
+struct JSConstSpec {
+  const wchar_t* pName;
+  double number;
+  const wchar_t* string;
+  uint8_t t;  // 0:double 1:str
+};
+
+struct JSPropertySpec {
+  const wchar_t* pName;
+  v8::AccessorGetterCallback pPropGet;
+  v8::AccessorSetterCallback pPropPut;
+};
+
+struct JSMethodSpec {
+  const wchar_t* pName;
+  v8::FunctionCallback pMethodCall;
+};
+
+/* ====================================== PUBLIC DEFINE SPEC
+ * ============================================== */
+#define JS_WIDESTRING(widestring) L## #widestring
+
+#define BEGIN_JS_STATIC_CONST(js_class_name) \
+  JSConstSpec js_class_name::JS_Class_Consts[] = {
+#define JS_STATIC_CONST_ENTRY_NUMBER(const_name, pValue) \
+  { const_name, pValue, L"", 0 }                         \
+  ,
+#define JS_STATIC_CONST_ENTRY_STRING(const_name, pValue) \
+  { const_name, 0, pValue, 1 }                           \
+  ,
+#define END_JS_STATIC_CONST() \
+  { 0, 0, 0, 0 }              \
+  }                           \
+  ;
+
+#define BEGIN_JS_STATIC_PROP(js_class_name) \
+  JSPropertySpec js_class_name::JS_Class_Properties[] = {
+#define JS_STATIC_PROP_ENTRY(prop_name)                 \
+  {                                                     \
+    JS_WIDESTRING(prop_name), get_##prop_name##_static, \
+        set_##prop_name##_static                        \
+  }                                                     \
+  ,
+#define END_JS_STATIC_PROP() \
+  { 0, 0, 0 }                \
+  }                          \
+  ;
+
+#define BEGIN_JS_STATIC_METHOD(js_class_name) \
+  JSMethodSpec js_class_name::JS_Class_Methods[] = {
+#define JS_STATIC_METHOD_ENTRY(method_name)            \
+  { JS_WIDESTRING(method_name), method_name##_static } \
+  ,
+#define END_JS_STATIC_METHOD() \
+  { 0, 0 }                     \
+  }                            \
+  ;
+
+/* ======================================== PROP CALLBACK
+ * ============================================ */
+
+template <class C,
+          FX_BOOL (C::*M)(IFXJS_Context*, CJS_PropValue&, CFX_WideString&)>
+void JSPropGetter(const char* prop_name_string,
+                  const char* class_name_string,
+                  v8::Local<v8::String> property,
+                  const v8::PropertyCallbackInfo<v8::Value>& info) {
+  v8::Isolate* isolate = info.GetIsolate();
+  IFXJS_Runtime* pRuntime = FXJS_GetRuntimeFromIsolate(isolate);
+  if (!pRuntime)
+    return;
+  IFXJS_Context* pRuntimeContext = pRuntime->GetCurrentContext();
+  CJS_Object* pJSObj = (CJS_Object*)FXJS_GetPrivate(isolate, info.Holder());
+  C* pObj = reinterpret_cast<C*>(pJSObj->GetEmbedObject());
+  CFX_WideString sError;
+  CJS_PropValue value(isolate);
+  value.StartGetting();
+  if (!(pObj->*M)(pRuntimeContext, value, sError)) {
+    FXJS_Error(isolate, JSFormatErrorString(class_name_string, prop_name_string,
+                                            sError));
+    return;
+  }
+  info.GetReturnValue().Set((v8::Local<v8::Value>)value);
+}
+
+template <class C,
+          FX_BOOL (C::*M)(IFXJS_Context*, CJS_PropValue&, CFX_WideString&)>
+void JSPropSetter(const char* prop_name_string,
+                  const char* class_name_string,
+                  v8::Local<v8::String> property,
+                  v8::Local<v8::Value> value,
+                  const v8::PropertyCallbackInfo<void>& info) {
+  v8::Isolate* isolate = info.GetIsolate();
+  IFXJS_Runtime* pRuntime = FXJS_GetRuntimeFromIsolate(isolate);
+  if (!pRuntime)
+    return;
+  IFXJS_Context* pRuntimeContext = pRuntime->GetCurrentContext();
+  CJS_Object* pJSObj = (CJS_Object*)FXJS_GetPrivate(isolate, info.Holder());
+  C* pObj = reinterpret_cast<C*>(pJSObj->GetEmbedObject());
+  CFX_WideString sError;
+  CJS_PropValue propValue(CJS_Value(isolate, value, CJS_Value::VT_unknown));
+  propValue.StartSetting();
+  if (!(pObj->*M)(pRuntimeContext, propValue, sError)) {
+    FXJS_Error(isolate, JSFormatErrorString(class_name_string, prop_name_string,
+                                            sError));
+  }
+}
+
+#define JS_STATIC_PROP(prop_name, class_name)                                 \
+  static void get_##prop_name##_static(                                       \
+      v8::Local<v8::String> property,                                         \
+      const v8::PropertyCallbackInfo<v8::Value>& info) {                      \
+    JSPropGetter<class_name, &class_name::prop_name>(#prop_name, #class_name, \
+                                                     property, info);         \
+  }                                                                           \
+  static void set_##prop_name##_static(                                       \
+      v8::Local<v8::String> property, v8::Local<v8::Value> value,             \
+      const v8::PropertyCallbackInfo<void>& info) {                           \
+    JSPropSetter<class_name, &class_name::prop_name>(#prop_name, #class_name, \
+                                                     property, value, info);  \
+  }
+
+/* ========================================= METHOD CALLBACK
+ * =========================================== */
+
+template <class C,
+          FX_BOOL (C::*M)(IFXJS_Context*,
+                          const CJS_Parameters&,
+                          CJS_Value&,
+                          CFX_WideString&)>
+void JSMethod(const char* method_name_string,
+              const char* class_name_string,
+              const v8::FunctionCallbackInfo<v8::Value>& info) {
+  v8::Isolate* isolate = info.GetIsolate();
+  IFXJS_Runtime* pRuntime = FXJS_GetRuntimeFromIsolate(isolate);
+  if (!pRuntime)
+    return;
+  IFXJS_Context* pRuntimeContext = pRuntime->GetCurrentContext();
+  CJS_Parameters parameters;
+  for (unsigned int i = 0; i < (unsigned int)info.Length(); i++) {
+    parameters.push_back(CJS_Value(isolate, info[i], CJS_Value::VT_unknown));
+  }
+  CJS_Value valueRes(isolate);
+  CJS_Object* pJSObj = (CJS_Object*)FXJS_GetPrivate(isolate, info.Holder());
+  C* pObj = reinterpret_cast<C*>(pJSObj->GetEmbedObject());
+  CFX_WideString sError;
+  if (!(pObj->*M)(pRuntimeContext, parameters, valueRes, sError)) {
+    FXJS_Error(isolate, JSFormatErrorString(class_name_string,
+                                            method_name_string, sError));
+    return;
+  }
+  info.GetReturnValue().Set(valueRes.ToV8Value());
+}
+
+#define JS_STATIC_METHOD(method_name, class_name)                             \
+  static void method_name##_static(                                           \
+      const v8::FunctionCallbackInfo<v8::Value>& info) {                      \
+    JSMethod<class_name, &class_name::method_name>(#method_name, #class_name, \
+                                                   info);                     \
+  }
+
+#define JS_SPECIAL_STATIC_METHOD(method_name, class_alternate, class_name) \
+  static void method_name##_static(                                        \
+      const v8::FunctionCallbackInfo<v8::Value>& info) {                   \
+    JSMethod<class_alternate, &class_alternate::method_name>(              \
+        #method_name, #class_name, info);                                  \
+  }
+
+/* ===================================== JS CLASS
+ * =============================================== */
+
+#define DECLARE_JS_CLASS(js_class_name)                                     \
+  static void JSConstructor(IFXJS_Context* cc, v8::Local<v8::Object> obj,   \
+                            v8::Local<v8::Object> global);                  \
+  static void JSDestructor(v8::Local<v8::Object> obj);                      \
+  static void DefineJSObjects(v8::Isolate* pIsolate, FXJSOBJTYPE eObjType); \
+  static JSConstSpec JS_Class_Consts[];                                     \
+  static JSPropertySpec JS_Class_Properties[];                              \
+  static JSMethodSpec JS_Class_Methods[];                                   \
+  static const wchar_t* m_pClassName
+
+#define IMPLEMENT_JS_CLASS_RICH(js_class_name, class_alternate, class_name)  \
+  const wchar_t* js_class_name::m_pClassName = JS_WIDESTRING(class_name);    \
+  void js_class_name::JSConstructor(IFXJS_Context* cc,                       \
+                                    v8::Local<v8::Object> obj,               \
+                                    v8::Local<v8::Object> global) {          \
+    CJS_Object* pObj = new js_class_name(obj);                               \
+    pObj->SetEmbedObject(new class_alternate(pObj));                         \
+    FXJS_SetPrivate(NULL, obj, (void*)pObj);                                 \
+    pObj->InitInstance(cc);                                                  \
+  }                                                                          \
+                                                                             \
+  void js_class_name::JSDestructor(v8::Local<v8::Object> obj) {              \
+    js_class_name* pObj = (js_class_name*)FXJS_GetPrivate(NULL, obj);        \
+    pObj->ExitInstance();                                                    \
+    delete pObj;                                                             \
+  }                                                                          \
+                                                                             \
+  void js_class_name::DefineJSObjects(v8::Isolate* pIsolate,                 \
+                                      FXJSOBJTYPE eObjType) {                \
+    int nObjDefnID = FXJS_DefineObj(pIsolate, js_class_name::m_pClassName,   \
+                                    eObjType, JSConstructor, JSDestructor);  \
+    for (int i = 0; i < FX_ArraySize(JS_Class_Properties) - 1; ++i) {        \
+      FXJS_DefineObjProperty(                                                \
+          pIsolate, nObjDefnID, JS_Class_Properties[i].pName,                \
+          JS_Class_Properties[i].pPropGet, JS_Class_Properties[i].pPropPut); \
+    }                                                                        \
+    for (int i = 0; i < FX_ArraySize(JS_Class_Methods) - 1; ++i) {           \
+      FXJS_DefineObjMethod(pIsolate, nObjDefnID, JS_Class_Methods[i].pName,  \
+                           JS_Class_Methods[i].pMethodCall);                 \
+    }                                                                        \
+  }
+
+#define IMPLEMENT_JS_CLASS(js_class_name, class_name) \
+  IMPLEMENT_JS_CLASS_RICH(js_class_name, class_name, class_name)
+
+/* ======================================== CONST CLASS
+ * ============================================ */
+
+#define DECLARE_JS_CLASS_CONST()                                            \
+  static void DefineJSObjects(v8::Isolate* pIsolate, FXJSOBJTYPE eObjType); \
+  static JSConstSpec JS_Class_Consts[];                                     \
+  static const wchar_t* m_pClassName
+
+#define IMPLEMENT_JS_CLASS_CONST(js_class_name, class_name)                \
+  const wchar_t* js_class_name::m_pClassName = JS_WIDESTRING(class_name);  \
+  void js_class_name::DefineJSObjects(v8::Isolate* pIsolate,               \
+                                      FXJSOBJTYPE eObjType) {              \
+    int nObjDefnID = FXJS_DefineObj(pIsolate, js_class_name::m_pClassName, \
+                                    eObjType, NULL, NULL);                 \
+    for (int i = 0; i < FX_ArraySize(JS_Class_Consts) - 1; ++i) {          \
+      FXJS_DefineObjConst(                                                 \
+          pIsolate, nObjDefnID, JS_Class_Consts[i].pName,                  \
+          JS_Class_Consts[i].t == 0                                        \
+              ? FXJS_NewNumber(pIsolate, JS_Class_Consts[i].number)        \
+              : FXJS_NewString(pIsolate, JS_Class_Consts[i].string));      \
+    }                                                                      \
+  }
+
+/* ===================================== SPECIAL JS CLASS
+ * =============================================== */
+
+template <class Alt>
+void JSSpecialPropQuery(const char*,
+                        v8::Local<v8::String> property,
+                        const v8::PropertyCallbackInfo<v8::Integer>& info) {
+  v8::Isolate* isolate = info.GetIsolate();
+  v8::String::Utf8Value utf8_value(property);
+  CFX_WideString propname =
+      CFX_WideString::FromUTF8(*utf8_value, utf8_value.length());
+  CJS_Object* pJSObj =
+      reinterpret_cast<CJS_Object*>(FXJS_GetPrivate(isolate, info.Holder()));
+  Alt* pObj = reinterpret_cast<Alt*>(pJSObj->GetEmbedObject());
+  FX_BOOL bRet = pObj->QueryProperty(propname.c_str());
+  info.GetReturnValue().Set(bRet ? 4 : 0);
+}
+
+template <class Alt>
+void JSSpecialPropGet(const char* class_name,
+                      v8::Local<v8::String> property,
+                      const v8::PropertyCallbackInfo<v8::Value>& info) {
+  v8::Isolate* isolate = info.GetIsolate();
+  IFXJS_Runtime* pRuntime = FXJS_GetRuntimeFromIsolate(isolate);
+  if (!pRuntime)
+    return;
+  IFXJS_Context* pRuntimeContext = pRuntime->GetCurrentContext();
+  CJS_Object* pJSObj =
+      reinterpret_cast<CJS_Object*>(FXJS_GetPrivate(isolate, info.Holder()));
+  Alt* pObj = reinterpret_cast<Alt*>(pJSObj->GetEmbedObject());
+  v8::String::Utf8Value utf8_value(property);
+  CFX_WideString propname =
+      CFX_WideString::FromUTF8(*utf8_value, utf8_value.length());
+  CFX_WideString sError;
+  CJS_PropValue value(isolate);
+  value.StartGetting();
+  if (!pObj->DoProperty(pRuntimeContext, propname.c_str(), value, sError)) {
+    FXJS_Error(isolate, JSFormatErrorString(class_name, "GetProperty", sError));
+    return;
+  }
+  info.GetReturnValue().Set((v8::Local<v8::Value>)value);
+}
+
+template <class Alt>
+void JSSpecialPropPut(const char* class_name,
+                      v8::Local<v8::String> property,
+                      v8::Local<v8::Value> value,
+                      const v8::PropertyCallbackInfo<v8::Value>& info) {
+  v8::Isolate* isolate = info.GetIsolate();
+  IFXJS_Runtime* pRuntime = FXJS_GetRuntimeFromIsolate(isolate);
+  if (!pRuntime)
+    return;
+  IFXJS_Context* pRuntimeContext = pRuntime->GetCurrentContext();
+  CJS_Object* pJSObj =
+      reinterpret_cast<CJS_Object*>(FXJS_GetPrivate(isolate, info.Holder()));
+  Alt* pObj = reinterpret_cast<Alt*>(pJSObj->GetEmbedObject());
+  v8::String::Utf8Value utf8_value(property);
+  CFX_WideString propname =
+      CFX_WideString::FromUTF8(*utf8_value, utf8_value.length());
+  CFX_WideString sError;
+  CJS_PropValue PropValue(CJS_Value(isolate, value, CJS_Value::VT_unknown));
+  PropValue.StartSetting();
+  if (!pObj->DoProperty(pRuntimeContext, propname.c_str(), PropValue, sError)) {
+    FXJS_Error(isolate, JSFormatErrorString(class_name, "PutProperty", sError));
+  }
+}
+
+template <class Alt>
+void JSSpecialPropDel(const char* class_name,
+                      v8::Local<v8::String> property,
+                      const v8::PropertyCallbackInfo<v8::Boolean>& info) {
+  v8::Isolate* isolate = info.GetIsolate();
+  IFXJS_Runtime* pRuntime = FXJS_GetRuntimeFromIsolate(isolate);
+  if (!pRuntime)
+    return;
+  IFXJS_Context* pRuntimeContext = pRuntime->GetCurrentContext();
+  CJS_Object* pJSObj =
+      reinterpret_cast<CJS_Object*>(FXJS_GetPrivate(isolate, info.Holder()));
+  Alt* pObj = reinterpret_cast<Alt*>(pJSObj->GetEmbedObject());
+  v8::String::Utf8Value utf8_value(property);
+  CFX_WideString propname =
+      CFX_WideString::FromUTF8(*utf8_value, utf8_value.length());
+  CFX_WideString sError;
+  if (!pObj->DelProperty(pRuntimeContext, propname.c_str(), sError)) {
+    CFX_ByteString cbName;
+    cbName.Format("%s.%s", class_name, "DelProperty");
+    // Probably a missing call to JSFX_Error().
+  }
+}
+
+#define DECLARE_SPECIAL_JS_CLASS(js_class_name)                             \
+  static void JSConstructor(IFXJS_Context* cc, v8::Local<v8::Object> obj,   \
+                            v8::Local<v8::Object> global);                  \
+  static void JSDestructor(v8::Local<v8::Object> obj);                      \
+  static JSConstSpec JS_Class_Consts[];                                     \
+  static JSPropertySpec JS_Class_Properties[];                              \
+  static JSMethodSpec JS_Class_Methods[];                                   \
+  static void DefineJSObjects(v8::Isolate* pIsolate, FXJSOBJTYPE eObjType); \
+  static const wchar_t* m_pClassName;                                       \
+  static void queryprop_##js_class_name##_static(                           \
+      v8::Local<v8::String> property,                                       \
+      const v8::PropertyCallbackInfo<v8::Integer>& info);                   \
+  static void getprop_##js_class_name##_static(                             \
+      v8::Local<v8::String> property,                                       \
+      const v8::PropertyCallbackInfo<v8::Value>& info);                     \
+  static void putprop_##js_class_name##_static(                             \
+      v8::Local<v8::String> property, v8::Local<v8::Value> value,           \
+      const v8::PropertyCallbackInfo<v8::Value>& info);                     \
+  static void delprop_##js_class_name##_static(                             \
+      v8::Local<v8::String> property,                                       \
+      const v8::PropertyCallbackInfo<v8::Boolean>& info)
+
+#define IMPLEMENT_SPECIAL_JS_CLASS(js_class_name, class_alternate, class_name) \
+  const wchar_t* js_class_name::m_pClassName = JS_WIDESTRING(class_name);      \
+  void js_class_name::queryprop_##js_class_name##_static(                      \
+      v8::Local<v8::String> property,                                          \
+      const v8::PropertyCallbackInfo<v8::Integer>& info) {                     \
+    JSSpecialPropQuery<class_alternate>(#class_name, property, info);          \
+  }                                                                            \
+  void js_class_name::getprop_##js_class_name##_static(                        \
+      v8::Local<v8::String> property,                                          \
+      const v8::PropertyCallbackInfo<v8::Value>& info) {                       \
+    JSSpecialPropGet<class_alternate>(#class_name, property, info);            \
+  }                                                                            \
+  void js_class_name::putprop_##js_class_name##_static(                        \
+      v8::Local<v8::String> property, v8::Local<v8::Value> value,              \
+      const v8::PropertyCallbackInfo<v8::Value>& info) {                       \
+    JSSpecialPropPut<class_alternate>(#class_name, property, value, info);     \
+  }                                                                            \
+  void js_class_name::delprop_##js_class_name##_static(                        \
+      v8::Local<v8::String> property,                                          \
+      const v8::PropertyCallbackInfo<v8::Boolean>& info) {                     \
+    JSSpecialPropDel<class_alternate>(#class_name, property, info);            \
+  }                                                                            \
+  void js_class_name::JSConstructor(IFXJS_Context* cc,                         \
+                                    v8::Local<v8::Object> obj,                 \
+                                    v8::Local<v8::Object> global) {            \
+    CJS_Object* pObj = new js_class_name(obj);                                 \
+    pObj->SetEmbedObject(new class_alternate(pObj));                           \
+    FXJS_SetPrivate(NULL, obj, (void*)pObj);                                   \
+    pObj->InitInstance(cc);                                                    \
+  }                                                                            \
+                                                                               \
+  void js_class_name::JSDestructor(v8::Local<v8::Object> obj) {                \
+    js_class_name* pObj = (js_class_name*)FXJS_GetPrivate(NULL, obj);          \
+    ASSERT(pObj != NULL);                                                      \
+    pObj->ExitInstance();                                                      \
+    delete pObj;                                                               \
+  }                                                                            \
+                                                                               \
+  void js_class_name::DefineJSObjects(v8::Isolate* pIsolate,                   \
+                                      FXJSOBJTYPE eObjType) {                  \
+    int nObjDefnID = FXJS_DefineObj(pIsolate, js_class_name::m_pClassName,     \
+                                    eObjType, JSConstructor, JSDestructor);    \
+    for (int i = 0; i < FX_ArraySize(JS_Class_Properties) - 1; ++i) {          \
+      FXJS_DefineObjProperty(                                                  \
+          pIsolate, nObjDefnID, JS_Class_Properties[i].pName,                  \
+          JS_Class_Properties[i].pPropGet, JS_Class_Properties[i].pPropPut);   \
+    }                                                                          \
+                                                                               \
+    for (int i = 0; i < FX_ArraySize(JS_Class_Methods) - 1; ++i) {             \
+      FXJS_DefineObjMethod(pIsolate, nObjDefnID, JS_Class_Methods[i].pName,    \
+                           JS_Class_Methods[i].pMethodCall);                   \
+    }                                                                          \
+    FXJS_DefineObjAllProperties(                                               \
+        pIsolate, nObjDefnID,                                                  \
+        js_class_name::queryprop_##js_class_name##_static,                     \
+        js_class_name::getprop_##js_class_name##_static,                       \
+        js_class_name::putprop_##js_class_name##_static,                       \
+        js_class_name::delprop_##js_class_name##_static);                      \
+  }
+
+/* ======================================== GLOBAL METHODS
+ * ============================================ */
+
+template <FX_BOOL (
+    *F)(IFXJS_Context*, const CJS_Parameters&, CJS_Value&, CFX_WideString&)>
+void JSGlobalFunc(const char* func_name_string,
+                  const v8::FunctionCallbackInfo<v8::Value>& info) {
+  v8::Isolate* isolate = info.GetIsolate();
+  IFXJS_Runtime* pRuntime = FXJS_GetRuntimeFromIsolate(isolate);
+  if (!pRuntime)
+    return;
+  IFXJS_Context* pRuntimeContext = pRuntime->GetCurrentContext();
+  CJS_Parameters parameters;
+  for (unsigned int i = 0; i < (unsigned int)info.Length(); i++) {
+    parameters.push_back(CJS_Value(isolate, info[i], CJS_Value::VT_unknown));
+  }
+  CJS_Value valueRes(isolate);
+  CFX_WideString sError;
+  if (!(*F)(pRuntimeContext, parameters, valueRes, sError)) {
+    FXJS_Error(isolate, JSFormatErrorString(func_name_string, nullptr, sError));
+    return;
+  }
+  info.GetReturnValue().Set(valueRes.ToV8Value());
+}
+
+#define JS_STATIC_GLOBAL_FUN(fun_name)                   \
+  static void fun_name##_static(                         \
+      const v8::FunctionCallbackInfo<v8::Value>& info) { \
+    JSGlobalFunc<fun_name>(#fun_name, info);             \
+  }
+
+#define JS_STATIC_DECLARE_GLOBAL_FUN()  \
+  static JSMethodSpec global_methods[]; \
+  static void DefineJSObjects(v8::Isolate* pIsolate)
+
+#define BEGIN_JS_STATIC_GLOBAL_FUN(js_class_name) \
+  JSMethodSpec js_class_name::global_methods[] = {
+#define JS_STATIC_GLOBAL_FUN_ENTRY(method_name) \
+  JS_STATIC_METHOD_ENTRY(method_name)
+
+#define END_JS_STATIC_GLOBAL_FUN() END_JS_STATIC_METHOD()
+
+#define IMPLEMENT_JS_STATIC_GLOBAL_FUN(js_class_name)                        \
+  void js_class_name::DefineJSObjects(v8::Isolate* pIsolate) {               \
+    for (int i = 0; i < FX_ArraySize(global_methods) - 1; ++i) {             \
+      FXJS_DefineGlobalMethod(pIsolate,                                      \
+                              js_class_name::global_methods[i].pName,        \
+                              js_class_name::global_methods[i].pMethodCall); \
+    }                                                                        \
+  }
+
+CJS_Value::Type GET_VALUE_TYPE(v8::Local<v8::Value> p);
+
+#endif  // FPDFSDK_SRC_JAVASCRIPT_JS_DEFINE_H_
diff --git a/fpdfsdk/src/javascript/JS_EventHandler.cpp b/fpdfsdk/src/javascript/JS_EventHandler.cpp
index 64a6168..42d61f4 100644
--- a/fpdfsdk/src/javascript/JS_EventHandler.cpp
+++ b/fpdfsdk/src/javascript/JS_EventHandler.cpp
@@ -4,15 +4,16 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
+#include "JS_EventHandler.h"
+
 #include "../../include/javascript/IJavaScript.h"
-#include "../../include/javascript/JS_EventHandler.h"
-#include "../../include/javascript/JS_Context.h"
-#include "../../include/javascript/JS_Runtime.h"
-#include "../../include/javascript/JS_Define.h"
-#include "../../include/javascript/JS_Object.h"
-#include "../../include/javascript/JS_Value.h"
-#include "../../include/javascript/Document.h"
-#include "../../include/javascript/Field.h"
+#include "Document.h"
+#include "Field.h"
+#include "JS_Context.h"
+#include "JS_Define.h"
+#include "JS_Object.h"
+#include "JS_Runtime.h"
+#include "JS_Value.h"
 
 /* ---------------------------- CJS_EventHandler ---------------------------- */
 
diff --git a/fpdfsdk/src/javascript/JS_EventHandler.h b/fpdfsdk/src/javascript/JS_EventHandler.h
new file mode 100644
index 0000000..5b67ec4
--- /dev/null
+++ b/fpdfsdk/src/javascript/JS_EventHandler.h
@@ -0,0 +1,220 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FPDFSDK_SRC_JAVASCRIPT_JS_EVENTHANDLER_H_
+#define FPDFSDK_SRC_JAVASCRIPT_JS_EVENTHANDLER_H_
+
+#include "../../../core/include/fxcrt/fx_string.h"
+#include "../../../core/include/fxcrt/fx_system.h"
+
+class CJS_Context;
+class CPDFSDK_Annot;
+class CPDFSDK_Document;
+class CPDF_Bookmark;
+class CPDF_FormField;
+class Field;
+
+enum JS_EVENT_T {
+  JET_UNKNOWN,
+  JET_APP_INIT,
+  JET_DOC_OPEN,
+  JET_DOC_WILLPRINT,
+  JET_DOC_DIDPRINT,
+  JET_DOC_WILLSAVE,
+  JET_DOC_DIDSAVE,
+  JET_DOC_WILLCLOSE,
+  JET_PAGE_OPEN,
+  JET_PAGE_CLOSE,
+  JET_PAGE_INVIEW,
+  JET_PAGE_OUTVIEW,
+  JET_FIELD_MOUSEDOWN,
+  JET_FIELD_MOUSEUP,
+  JET_FIELD_MOUSEENTER,
+  JET_FIELD_MOUSEEXIT,
+  JET_FIELD_FOCUS,
+  JET_FIELD_BLUR,
+  JET_FIELD_KEYSTROKE,
+  JET_FIELD_VALIDATE,
+  JET_FIELD_CALCULATE,
+  JET_FIELD_FORMAT,
+  JET_SCREEN_FOCUS,
+  JET_SCREEN_BLUR,
+  JET_SCREEN_OPEN,
+  JET_SCREEN_CLOSE,
+  JET_SCREEN_MOUSEDOWN,
+  JET_SCREEN_MOUSEUP,
+  JET_SCREEN_MOUSEENTER,
+  JET_SCREEN_MOUSEEXIT,
+  JET_SCREEN_INVIEW,
+  JET_SCREEN_OUTVIEW,
+  JET_BATCH_EXEC,
+  JET_MENU_EXEC,
+  JET_CONSOLE_EXEC,
+  JET_EXTERNAL_EXEC,
+  JET_BOOKMARK_MOUSEUP,
+  JET_LINK_MOUSEUP
+};
+
+class CJS_EventHandler {
+ public:
+  CJS_EventHandler(CJS_Context* pContext);
+  virtual ~CJS_EventHandler();
+
+  void OnApp_Init();
+
+  void OnDoc_Open(CPDFSDK_Document* pDoc, const CFX_WideString& strTargetName);
+  void OnDoc_WillPrint(CPDFSDK_Document* pDoc);
+  void OnDoc_DidPrint(CPDFSDK_Document* pDoc);
+  void OnDoc_WillSave(CPDFSDK_Document* pDoc);
+  void OnDoc_DidSave(CPDFSDK_Document* pDoc);
+  void OnDoc_WillClose(CPDFSDK_Document* pDoc);
+
+  void OnPage_Open(CPDFSDK_Document* pDoc);
+  void OnPage_Close(CPDFSDK_Document* pDoc);
+  void OnPage_InView(CPDFSDK_Document* pTarget);
+  void OnPage_OutView(CPDFSDK_Document* pTarget);
+
+  void OnField_Calculate(CPDF_FormField* pSource,
+                         CPDF_FormField* pTarget,
+                         CFX_WideString& Value,
+                         FX_BOOL& bRc);
+  void OnField_Format(CPDF_FormField* pTarget,
+                      CFX_WideString& Value,
+                      FX_BOOL bWillCommit);
+  void OnField_Keystroke(CFX_WideString& strChange,
+                         const CFX_WideString& strChangeEx,
+                         FX_BOOL KeyDown,
+                         FX_BOOL bModifier,
+                         int& nSelEnd,
+                         int& nSelStart,
+                         FX_BOOL bShift,
+                         CPDF_FormField* pTarget,
+                         CFX_WideString& Value,
+                         FX_BOOL bWillCommit,
+                         FX_BOOL bFieldFull,
+                         FX_BOOL& bRc);
+  void OnField_Validate(CFX_WideString& strChange,
+                        const CFX_WideString& strChangeEx,
+                        FX_BOOL bKeyDown,
+                        FX_BOOL bModifier,
+                        FX_BOOL bShift,
+                        CPDF_FormField* pTarget,
+                        CFX_WideString& Value,
+                        FX_BOOL& bRc);
+
+  void OnField_MouseDown(FX_BOOL bModifier,
+                         FX_BOOL bShift,
+                         CPDF_FormField* pTarget);
+  void OnField_MouseEnter(FX_BOOL bModifier,
+                          FX_BOOL bShift,
+                          CPDF_FormField* pTarget);
+  void OnField_MouseExit(FX_BOOL bModifier,
+                         FX_BOOL bShift,
+                         CPDF_FormField* pTarget);
+  void OnField_MouseUp(FX_BOOL bModifier,
+                       FX_BOOL bShift,
+                       CPDF_FormField* pTarget);
+  void OnField_Blur(FX_BOOL bModifier,
+                    FX_BOOL bShift,
+                    CPDF_FormField* pTarget,
+                    const CFX_WideString& Value);
+  void OnField_Focus(FX_BOOL bModifier,
+                     FX_BOOL bShift,
+                     CPDF_FormField* pTarget,
+                     const CFX_WideString& Value);
+
+  void OnScreen_Focus(FX_BOOL bModifier,
+                      FX_BOOL bShift,
+                      CPDFSDK_Annot* pScreen);
+  void OnScreen_Blur(FX_BOOL bModifier, FX_BOOL bShift, CPDFSDK_Annot* pScreen);
+  void OnScreen_Open(FX_BOOL bModifier, FX_BOOL bShift, CPDFSDK_Annot* pScreen);
+  void OnScreen_Close(FX_BOOL bModifier,
+                      FX_BOOL bShift,
+                      CPDFSDK_Annot* pScreen);
+  void OnScreen_MouseDown(FX_BOOL bModifier,
+                          FX_BOOL bShift,
+                          CPDFSDK_Annot* pScreen);
+  void OnScreen_MouseUp(FX_BOOL bModifier,
+                        FX_BOOL bShift,
+                        CPDFSDK_Annot* pScreen);
+  void OnScreen_MouseEnter(FX_BOOL bModifier,
+                           FX_BOOL bShift,
+                           CPDFSDK_Annot* pScreen);
+  void OnScreen_MouseExit(FX_BOOL bModifier,
+                          FX_BOOL bShift,
+                          CPDFSDK_Annot* pScreen);
+  void OnScreen_InView(FX_BOOL bModifier,
+                       FX_BOOL bShift,
+                       CPDFSDK_Annot* pScreen);
+  void OnScreen_OutView(FX_BOOL bModifier,
+                        FX_BOOL bShift,
+                        CPDFSDK_Annot* pScreen);
+
+  void OnBookmark_MouseUp(CPDF_Bookmark* pBookMark);
+  void OnLink_MouseUp(CPDFSDK_Document* pTarget);
+
+  void OnMenu_Exec(CPDFSDK_Document* pTarget,
+                   const CFX_WideString& strTargetName);
+  void OnBatchExec(CPDFSDK_Document* pTarget);
+  void OnConsole_Exec();
+  void OnExternal_Exec();
+
+ public:
+  void Initial(JS_EVENT_T type);
+  void Destroy();
+  FX_BOOL IsValid();
+
+  CFX_WideString& Change();
+  CFX_WideString ChangeEx();
+  int CommitKey();
+  FX_BOOL FieldFull();
+  FX_BOOL KeyDown();
+  FX_BOOL Modifier();
+  const FX_WCHAR* Name();
+  const FX_WCHAR* Type();
+  FX_BOOL& Rc();
+  int& SelEnd();
+  int& SelStart();
+  FX_BOOL Shift();
+  Field* Source();
+  Field* Target_Field();
+  CFX_WideString& Value();
+  FX_BOOL WillCommit();
+  CFX_WideString TargetName();
+
+  JS_EVENT_T EventType() { return m_eEventType; }
+
+ public:
+  CJS_Context* m_pJSContext;
+  JS_EVENT_T m_eEventType;
+  FX_BOOL m_bValid;
+
+  CFX_WideString m_strTargetName;
+  CFX_WideString m_strSourceName;
+  CFX_WideString* m_pWideStrChange;
+  CFX_WideString m_WideStrChangeDu;
+  CFX_WideString m_WideStrChangeEx;
+  int m_nCommitKey;
+  FX_BOOL m_bKeyDown;
+  FX_BOOL m_bModifier;
+  FX_BOOL m_bShift;
+  int* m_pISelEnd;
+  int m_nSelEndDu;
+  int* m_pISelStart;
+  int m_nSelStartDu;
+  FX_BOOL m_bWillCommit;
+  CFX_WideString* m_pValue;
+  FX_BOOL m_bFieldFull;
+  FX_BOOL* m_pbRc;
+  FX_BOOL m_bRcDu;
+
+  CPDFSDK_Document* m_pSourceDoc;
+  CPDF_Bookmark* m_pTargetBookMark;
+  CPDFSDK_Document* m_pTargetDoc;
+  CPDFSDK_Annot* m_pTargetAnnot;
+};
+
+#endif  // FPDFSDK_SRC_JAVASCRIPT_JS_EVENTHANDLER_H_
diff --git a/fpdfsdk/src/javascript/JS_GlobalData.cpp b/fpdfsdk/src/javascript/JS_GlobalData.cpp
index e6d21e2..e13b50f 100644
--- a/fpdfsdk/src/javascript/JS_GlobalData.cpp
+++ b/fpdfsdk/src/javascript/JS_GlobalData.cpp
@@ -4,9 +4,10 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
+#include "JS_GlobalData.h"
+
 #include "../../../core/include/fdrm/fx_crypt.h"
 #include "../../include/javascript/IJavaScript.h"
-#include "../../include/javascript/JS_GlobalData.h"
 
 #define JS_MAXGLOBALDATA (1024 * 4 - 8)
 
diff --git a/fpdfsdk/src/javascript/JS_GlobalData.h b/fpdfsdk/src/javascript/JS_GlobalData.h
new file mode 100644
index 0000000..b174a8d
--- /dev/null
+++ b/fpdfsdk/src/javascript/JS_GlobalData.h
@@ -0,0 +1,108 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FPDFSDK_SRC_JAVASCRIPT_JS_GLOBALDATA_H_
+#define FPDFSDK_SRC_JAVASCRIPT_JS_GLOBALDATA_H_
+
+#include "../../../core/include/fxcrt/fx_basic.h"
+
+#define JS_GLOBALDATA_TYPE_NUMBER 0
+#define JS_GLOBALDATA_TYPE_BOOLEAN 1
+#define JS_GLOBALDATA_TYPE_STRING 2
+#define JS_GLOBALDATA_TYPE_OBJECT 3
+#define JS_GLOBALDATA_TYPE_NULL 4
+
+class CJS_KeyValue;
+class CPDFDoc_Environment;
+
+class CJS_GlobalVariableArray {
+ public:
+  CJS_GlobalVariableArray();
+  virtual ~CJS_GlobalVariableArray();
+
+  void Add(CJS_KeyValue* p);
+  int Count() const;
+  CJS_KeyValue* GetAt(int index) const;
+  void Copy(const CJS_GlobalVariableArray& array);
+
+  void Empty();
+
+ private:
+  CFX_ArrayTemplate<CJS_KeyValue*> array;
+};
+
+class CJS_KeyValue {
+ public:
+  CJS_KeyValue() {}
+  virtual ~CJS_KeyValue() {}
+
+  CFX_ByteString sKey;
+  int nType;  // 0:int 1:bool 2:string 3:obj
+  double dData;
+  bool bData;
+  CFX_ByteString sData;
+  CJS_GlobalVariableArray objData;
+};
+
+class CJS_GlobalData_Element {
+ public:
+  CJS_GlobalData_Element() {}
+  virtual ~CJS_GlobalData_Element() {}
+
+  CJS_KeyValue data;
+  FX_BOOL bPersistent;
+};
+
+class CJS_GlobalData {
+ public:
+  static CJS_GlobalData* GetRetainedInstance(CPDFDoc_Environment* pApp);
+  void Release();
+
+  void SetGlobalVariableNumber(const FX_CHAR* propname, double dData);
+  void SetGlobalVariableBoolean(const FX_CHAR* propname, bool bData);
+  void SetGlobalVariableString(const FX_CHAR* propname,
+                               const CFX_ByteString& sData);
+  void SetGlobalVariableObject(const FX_CHAR* propname,
+                               const CJS_GlobalVariableArray& array);
+  void SetGlobalVariableNull(const FX_CHAR* propname);
+
+  FX_BOOL SetGlobalVariablePersistent(const FX_CHAR* propname,
+                                      FX_BOOL bPersistent);
+  FX_BOOL DeleteGlobalVariable(const FX_CHAR* propname);
+
+  int32_t GetSize() const;
+  CJS_GlobalData_Element* GetAt(int index) const;
+
+ private:
+  static CJS_GlobalData* g_Instance;
+
+  CJS_GlobalData(CPDFDoc_Environment* pApp);
+  ~CJS_GlobalData();
+
+  void LoadGlobalPersistentVariables();
+  void SaveGlobalPersisitentVariables();
+
+  CJS_GlobalData_Element* GetGlobalVariable(const FX_CHAR* propname);
+  int FindGlobalVariable(const FX_CHAR* propname);
+
+  void LoadFileBuffer(const FX_WCHAR* sFilePath,
+                      uint8_t*& pBuffer,
+                      int32_t& nLength);
+  void WriteFileBuffer(const FX_WCHAR* sFilePath,
+                       const FX_CHAR* pBuffer,
+                       int32_t nLength);
+  void MakeByteString(const CFX_ByteString& name,
+                      CJS_KeyValue* pData,
+                      CFX_BinaryBuf& sData);
+
+ private:
+  size_t m_RefCount;
+  CFX_ArrayTemplate<CJS_GlobalData_Element*> m_arrayGlobalData;
+  CFX_WideString m_sFilePath;
+  CPDFDoc_Environment* m_pApp;
+};
+
+#endif  // FPDFSDK_SRC_JAVASCRIPT_JS_GLOBALDATA_H_
diff --git a/fpdfsdk/src/javascript/JS_Object.cpp b/fpdfsdk/src/javascript/JS_Object.cpp
index 7898f48..0556c4e 100644
--- a/fpdfsdk/src/javascript/JS_Object.cpp
+++ b/fpdfsdk/src/javascript/JS_Object.cpp
@@ -4,10 +4,12 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
+#include "JS_Object.h"
+
+#include "../../include/fsdk_mgr.h"  // For CPDFDoc_Environment.
 #include "../../include/javascript/IJavaScript.h"
-#include "../../include/javascript/JS_Context.h"
-#include "../../include/javascript/JS_Define.h"
-#include "../../include/javascript/JS_Object.h"
+#include "JS_Context.h"
+#include "JS_Define.h"
 
 namespace {
 
diff --git a/fpdfsdk/src/javascript/JS_Object.h b/fpdfsdk/src/javascript/JS_Object.h
new file mode 100644
index 0000000..82d1da9
--- /dev/null
+++ b/fpdfsdk/src/javascript/JS_Object.h
@@ -0,0 +1,116 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FPDFSDK_SRC_JAVASCRIPT_JS_OBJECT_H_
+#define FPDFSDK_SRC_JAVASCRIPT_JS_OBJECT_H_
+
+#include <map>
+
+#include "../../../third_party/base/nonstd_unique_ptr.h"
+#include "../../include/fsdk_define.h"  // For FX_UINT
+#include "../../include/jsapi/fxjs_v8.h"
+#include "JS_Runtime.h"
+
+class CJS_Context;
+class CJS_Object;
+class CJS_Timer;
+class CPDFDoc_Environment;
+class CJS_EmbedObj {
+ public:
+  explicit CJS_EmbedObj(CJS_Object* pJSObject);
+  virtual ~CJS_EmbedObj();
+
+  virtual void TimerProc(CJS_Timer* pTimer) {}
+
+  CJS_Object* GetJSObject() const { return m_pJSObject; }
+
+  int MsgBox(CPDFDoc_Environment* pApp,
+             const FX_WCHAR* swMsg,
+             const FX_WCHAR* swTitle,
+             FX_UINT nType,
+             FX_UINT nIcon);
+  void Alert(CJS_Context* pContext, const FX_WCHAR* swMsg);
+
+ protected:
+  CJS_Object* m_pJSObject;
+};
+
+class CJS_Object {
+ public:
+  explicit CJS_Object(v8::Local<v8::Object> pObject);
+  virtual ~CJS_Object();
+
+  void MakeWeak();
+  void Dispose();
+
+  virtual FX_BOOL IsType(const FX_CHAR* sClassName) { return TRUE; }
+  virtual CFX_ByteString GetClassName() { return ""; }
+
+  virtual FX_BOOL InitInstance(IFXJS_Context* cc) { return TRUE; }
+  virtual FX_BOOL ExitInstance() { return TRUE; }
+
+  v8::Local<v8::Object> ToV8Object() { return m_pV8Object.Get(m_pIsolate); }
+
+  // Takes ownership of |pObj|.
+  void SetEmbedObject(CJS_EmbedObj* pObj) { m_pEmbedObj.reset(pObj); }
+  CJS_EmbedObj* GetEmbedObject() const { return m_pEmbedObj.get(); }
+
+  static int MsgBox(CPDFDoc_Environment* pApp,
+                    const FX_WCHAR* swMsg,
+                    const FX_WCHAR* swTitle,
+                    FX_UINT nType,
+                    FX_UINT nIcon);
+  static void Alert(CJS_Context* pContext, const FX_WCHAR* swMsg);
+
+  v8::Isolate* GetIsolate() { return m_pIsolate; }
+
+ protected:
+  nonstd::unique_ptr<CJS_EmbedObj> m_pEmbedObj;
+  v8::Global<v8::Object> m_pV8Object;
+  v8::Isolate* m_pIsolate;
+};
+
+class CJS_Timer : public CJS_Runtime::Observer {
+ public:
+  CJS_Timer(CJS_EmbedObj* pObj,
+            CPDFDoc_Environment* pApp,
+            CJS_Runtime* pRuntime,
+            int nType,
+            const CFX_WideString& script,
+            FX_DWORD dwElapse,
+            FX_DWORD dwTimeOut);
+  ~CJS_Timer() override;
+
+  void KillJSTimer();
+
+  int GetType() const { return m_nType; }
+  FX_DWORD GetTimeOut() const { return m_dwTimeOut; }
+  CJS_Runtime* GetRuntime() const { return m_bValid ? m_pRuntime : nullptr; }
+  CFX_WideString GetJScript() const { return m_swJScript; }
+
+  static void TimerProc(int idEvent);
+
+ private:
+  using TimerMap = std::map<FX_UINT, CJS_Timer*>;
+  static TimerMap* GetGlobalTimerMap();
+
+  // CJS_Runtime::Observer
+  void OnDestroyed() override;
+
+  FX_DWORD m_nTimerID;
+  CJS_EmbedObj* const m_pEmbedObj;
+  bool m_bProcessing;
+  bool m_bValid;
+
+  // data
+  const int m_nType;  // 0:Interval; 1:TimeOut
+  const FX_DWORD m_dwTimeOut;
+  const CFX_WideString m_swJScript;
+  CJS_Runtime* const m_pRuntime;
+  CPDFDoc_Environment* const m_pApp;
+};
+
+#endif  // FPDFSDK_SRC_JAVASCRIPT_JS_OBJECT_H_
diff --git a/fpdfsdk/src/javascript/JS_Runtime.cpp b/fpdfsdk/src/javascript/JS_Runtime.cpp
index 49d235c..563576a 100644
--- a/fpdfsdk/src/javascript/JS_Runtime.cpp
+++ b/fpdfsdk/src/javascript/JS_Runtime.cpp
@@ -4,32 +4,38 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
-#include "../../include/javascript/IJavaScript.h"
-#include "../../include/javascript/JS_EventHandler.h"
-#include "../../include/javascript/JS_Runtime.h"
-#include "../../include/javascript/JS_Context.h"
-#include "../../include/javascript/JS_Define.h"
-#include "../../include/javascript/JS_Object.h"
-#include "../../include/javascript/JS_Value.h"
-#include "../../include/javascript/app.h"
-#include "../../include/javascript/color.h"
-#include "../../include/javascript/Consts.h"
-#include "../../include/javascript/Document.h"
-#include "../../include/javascript/event.h"
-#include "../../include/javascript/Field.h"
-#include "../../include/javascript/Icon.h"
-#include "../../include/javascript/PublicMethods.h"
-#include "../../include/javascript/report.h"
-#include "../../include/javascript/util.h"
-#include "../../include/javascript/JS_GlobalData.h"
-#include "../../include/javascript/global.h"
-#include "../../include/javascript/console.h"
-#include "../../include/fpdfxfa/fpdfxfa_app.h"
+#include "JS_Runtime.h"
+
 #include "../../../xfa/src/fxjse/src/value.h"
+#include "../../include/fpdfxfa/fpdfxfa_app.h"
+#include "../../include/fsdk_mgr.h"  // For CPDFDoc_Environment.
+#include "../../include/javascript/IJavaScript.h"
+#include "Consts.h"
+#include "Document.h"
+#include "Field.h"
+#include "Icon.h"
+#include "JS_Context.h"
+#include "JS_Define.h"
+#include "JS_EventHandler.h"
+#include "JS_GlobalData.h"
+#include "JS_Object.h"
+#include "JS_Value.h"
+#include "PublicMethods.h"
+#include "app.h"
+#include "color.h"
+#include "console.h"
+#include "event.h"
+#include "global.h"
+#include "report.h"
+#include "util.h"
 
 /* ------------------------------ CJS_Runtime ------------------------------ */
 v8::Global<v8::ObjectTemplate>& _getGlobalObjectTemplate(v8::Isolate* pIsolate);
 
+IFXJS_Runtime* IFXJS_Runtime::Create(CPDFDoc_Environment* pEnv) {
+  return new CJS_Runtime(pEnv);
+}
+
 CJS_Runtime::CJS_Runtime(CPDFDoc_Environment* pApp)
     : m_pApp(pApp),
       m_pDocument(NULL),
diff --git a/fpdfsdk/src/javascript/JS_Runtime.h b/fpdfsdk/src/javascript/JS_Runtime.h
new file mode 100644
index 0000000..0576980
--- /dev/null
+++ b/fpdfsdk/src/javascript/JS_Runtime.h
@@ -0,0 +1,79 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FPDFSDK_SRC_JAVASCRIPT_JS_RUNTIME_H_
+#define FPDFSDK_SRC_JAVASCRIPT_JS_RUNTIME_H_
+
+#include <set>
+#include <utility>
+
+#include "../../../third_party/base/nonstd_unique_ptr.h"
+#include "../../../core/include/fxcrt/fx_basic.h"
+#include "../../include/javascript/IJavaScript.h"
+#include "../../include/jsapi/fxjs_v8.h"
+#include "JS_EventHandler.h"
+
+class CJS_Context;
+
+class CJS_Runtime : public IFXJS_Runtime {
+ public:
+  class Observer {
+   public:
+    virtual void OnDestroyed() = 0;
+
+   protected:
+    virtual ~Observer() {}
+  };
+
+  using FieldEvent = std::pair<CFX_WideString, JS_EVENT_T>;
+
+  explicit CJS_Runtime(CPDFDoc_Environment* pApp);
+  ~CJS_Runtime() override;
+
+  // IFXJS_Runtime
+  IFXJS_Context* NewContext() override;
+  void ReleaseContext(IFXJS_Context* pContext) override;
+  IFXJS_Context* GetCurrentContext() override;
+  void SetReaderDocument(CPDFSDK_Document* pReaderDoc) override;
+  CPDFSDK_Document* GetReaderDocument() override { return m_pDocument; }
+
+  CPDFDoc_Environment* GetReaderApp() const { return m_pApp; }
+
+  // Returns true if the event isn't already found in the set.
+  bool AddEventToSet(const FieldEvent& event);
+  void RemoveEventFromSet(const FieldEvent& event);
+
+  void BeginBlock() { m_bBlocking = TRUE; }
+  void EndBlock() { m_bBlocking = FALSE; }
+  FX_BOOL IsBlocking() const { return m_bBlocking; }
+
+  v8::Isolate* GetIsolate() const { return m_isolate; }
+  v8::Local<v8::Context> NewJSContext();
+
+  virtual FX_BOOL GetHValueByName(const CFX_ByteStringC& utf8Name,
+                                  FXJSE_HVALUE hValue);
+  virtual FX_BOOL SetHValueByName(const CFX_ByteStringC& utf8Name,
+                                  FXJSE_HVALUE hValue);
+
+  void AddObserver(Observer* observer);
+  void RemoveObserver(Observer* observer);
+
+ private:
+  void DefineJSObjects();
+
+  CFX_ArrayTemplate<CJS_Context*> m_ContextArray;
+  CPDFDoc_Environment* m_pApp;
+  CPDFSDK_Document* m_pDocument;
+  FX_BOOL m_bBlocking;
+  std::set<FieldEvent> m_FieldEventSet;
+  v8::Isolate* m_isolate;
+  bool m_isolateManaged;
+  nonstd::unique_ptr<FXJS_ArrayBufferAllocator> m_pArrayBufferAllocator;
+  v8::Global<v8::Context> m_context;
+  std::set<Observer*> m_observers;
+};
+
+#endif  // FPDFSDK_SRC_JAVASCRIPT_JS_RUNTIME_H_
diff --git a/fpdfsdk/src/javascript/JS_Value.cpp b/fpdfsdk/src/javascript/JS_Value.cpp
index f4aecba..94b5ff6 100644
--- a/fpdfsdk/src/javascript/JS_Value.cpp
+++ b/fpdfsdk/src/javascript/JS_Value.cpp
@@ -4,14 +4,15 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
+#include "JS_Value.h"
+
 #include <time.h>
 #include <cmath>
 #include <limits>
 
-#include "../../include/javascript/JS_Define.h"
-#include "../../include/javascript/JS_Object.h"
-#include "../../include/javascript/JS_Value.h"
-#include "../../include/javascript/Document.h"
+#include "Document.h"
+#include "JS_Define.h"
+#include "JS_Object.h"
 
 static const FX_DWORD g_nan[2] = {0, 0x7FF80000};
 static double GetNan() {
diff --git a/fpdfsdk/src/javascript/JS_Value.h b/fpdfsdk/src/javascript/JS_Value.h
new file mode 100644
index 0000000..fdcc662
--- /dev/null
+++ b/fpdfsdk/src/javascript/JS_Value.h
@@ -0,0 +1,218 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FPDFSDK_SRC_JAVASCRIPT_JS_VALUE_H_
+#define FPDFSDK_SRC_JAVASCRIPT_JS_VALUE_H_
+
+#include "../../../core/include/fxcrt/fx_basic.h"
+#include "../../include/jsapi/fxjs_v8.h"
+
+class CJS_Array;
+class CJS_Date;
+class CJS_Document;
+class CJS_Object;
+
+class CJS_Value {
+ public:
+  enum Type {
+    VT_unknown,
+    VT_string,
+    VT_number,
+    VT_boolean,
+    VT_date,
+    VT_object,
+    VT_fxobject,
+    VT_null,
+    VT_undefined
+  };
+
+  CJS_Value(v8::Isolate* isolate);
+  CJS_Value(v8::Isolate* isolate, v8::Local<v8::Value> pValue, Type t);
+  CJS_Value(v8::Isolate* isolate, const int& iValue);
+  CJS_Value(v8::Isolate* isolate, const double& dValue);
+  CJS_Value(v8::Isolate* isolate, const float& fValue);
+  CJS_Value(v8::Isolate* isolate, const bool& bValue);
+  CJS_Value(v8::Isolate* isolate, v8::Local<v8::Object>);
+  CJS_Value(v8::Isolate* isolate, CJS_Object*);
+  CJS_Value(v8::Isolate* isolate, CJS_Document*);
+  CJS_Value(v8::Isolate* isolate, const FX_CHAR* pStr);
+  CJS_Value(v8::Isolate* isolate, const FX_WCHAR* pWstr);
+  CJS_Value(v8::Isolate* isolate, CJS_Array& array);
+
+  ~CJS_Value();
+
+  void SetNull();
+  void Attach(v8::Local<v8::Value> pValue, Type t);
+  void Attach(CJS_Value* pValue);
+  void Detach();
+
+  Type GetType() const;
+  int ToInt() const;
+  bool ToBool() const;
+  double ToDouble() const;
+  float ToFloat() const;
+  CJS_Object* ToCJSObject() const;
+  CFX_WideString ToCFXWideString() const;
+  CFX_ByteString ToCFXByteString() const;
+  v8::Local<v8::Object> ToV8Object() const;
+  v8::Local<v8::Array> ToV8Array() const;
+  v8::Local<v8::Value> ToV8Value() const;
+
+  void operator=(int iValue);
+  void operator=(bool bValue);
+  void operator=(double);
+  void operator=(float);
+  void operator=(CJS_Object*);
+  void operator=(CJS_Document*);
+  void operator=(v8::Local<v8::Object>);
+  void operator=(CJS_Array&);
+  void operator=(CJS_Date&);
+  void operator=(const FX_WCHAR* pWstr);
+  void operator=(const FX_CHAR* pStr);
+  void operator=(CJS_Value value);
+
+  FX_BOOL IsArrayObject() const;
+  FX_BOOL IsDateObject() const;
+  FX_BOOL ConvertToArray(CJS_Array&) const;
+  FX_BOOL ConvertToDate(CJS_Date&) const;
+
+  v8::Isolate* GetIsolate() { return m_isolate; }
+
+ protected:
+  Type m_eType;
+  v8::Local<v8::Value> m_pValue;
+  v8::Isolate* m_isolate;
+};
+
+class CJS_Parameters : public CFX_ArrayTemplate<CJS_Value> {
+ public:
+  void push_back(const CJS_Value& newElement) {
+    CFX_ArrayTemplate<CJS_Value>::Add(newElement);
+  }
+  int size() const { return CFX_ArrayTemplate<CJS_Value>::GetSize(); }
+};
+
+class CJS_PropValue : public CJS_Value {
+ public:
+  CJS_PropValue(const CJS_Value&);
+  CJS_PropValue(v8::Isolate* isolate);
+  ~CJS_PropValue();
+
+ public:
+  FX_BOOL IsSetting();
+  FX_BOOL IsGetting();
+  void operator<<(int);
+  void operator>>(int&) const;
+  void operator<<(bool);
+  void operator>>(bool&) const;
+  void operator<<(double);
+  void operator>>(double&) const;
+  void operator<<(CJS_Object* pObj);
+  void operator>>(CJS_Object*& ppObj) const;
+  void operator<<(CJS_Document* pJsDoc);
+  void operator>>(CJS_Document*& ppJsDoc) const;
+  void operator<<(CFX_ByteString);
+  void operator>>(CFX_ByteString&) const;
+  void operator<<(CFX_WideString);
+  void operator>>(CFX_WideString&) const;
+  void operator<<(const FX_WCHAR* c_string);
+  void operator<<(v8::Local<v8::Object>);
+  void operator>>(v8::Local<v8::Object>&) const;
+  void operator>>(CJS_Array& array) const;
+  void operator<<(CJS_Array& array);
+  void operator<<(CJS_Date& date);
+  void operator>>(CJS_Date& date) const;
+  operator v8::Local<v8::Value>() const;
+  void StartSetting();
+  void StartGetting();
+
+ private:
+  FX_BOOL m_bIsSetting;
+};
+
+class CJS_Array {
+ public:
+  CJS_Array(v8::Isolate* isolate);
+  virtual ~CJS_Array();
+
+  void Attach(v8::Local<v8::Array> pArray);
+  void GetElement(unsigned index, CJS_Value& value);
+  void SetElement(unsigned index, CJS_Value value);
+  int GetLength();
+  FX_BOOL IsAttached();
+  operator v8::Local<v8::Array>();
+
+  v8::Isolate* GetIsolate() { return m_isolate; }
+
+ private:
+  v8::Local<v8::Array> m_pArray;
+  v8::Isolate* m_isolate;
+};
+
+class CJS_Date {
+  friend class CJS_Value;
+
+ public:
+  CJS_Date(v8::Isolate* isolate);
+  CJS_Date(v8::Isolate* isolate, double dMsec_time);
+  CJS_Date(v8::Isolate* isolate,
+           int year,
+           int mon,
+           int day,
+           int hour,
+           int min,
+           int sec);
+  virtual ~CJS_Date();
+  void Attach(v8::Local<v8::Value> pDate);
+
+  int GetYear();
+  void SetYear(int iYear);
+
+  int GetMonth();
+  void SetMonth(int iMonth);
+
+  int GetDay();
+  void SetDay(int iDay);
+
+  int GetHours();
+  void SetHours(int iHours);
+
+  int GetMinutes();
+  void SetMinutes(int minutes);
+
+  int GetSeconds();
+  void SetSeconds(int seconds);
+
+  operator v8::Local<v8::Value>();
+  operator double() const;
+
+  CFX_WideString ToString() const;
+
+  static double
+  MakeDate(int year, int mon, int mday, int hour, int min, int sec, int ms);
+
+  FX_BOOL IsValidDate();
+
+ protected:
+  v8::Local<v8::Value> m_pDate;
+  v8::Isolate* m_isolate;
+};
+
+double JS_GetDateTime();
+int JS_GetYearFromTime(double dt);
+int JS_GetMonthFromTime(double dt);
+int JS_GetDayFromTime(double dt);
+int JS_GetHourFromTime(double dt);
+int JS_GetMinFromTime(double dt);
+int JS_GetSecFromTime(double dt);
+double JS_DateParse(const wchar_t* string);
+double JS_MakeDay(int nYear, int nMonth, int nDay);
+double JS_MakeTime(int nHour, int nMin, int nSec, int nMs);
+double JS_MakeDate(double day, double time);
+bool JS_PortIsNan(double d);
+double JS_LocalTime(double d);
+
+#endif  // FPDFSDK_SRC_JAVASCRIPT_JS_VALUE_H_
diff --git a/fpdfsdk/src/javascript/PublicMethods.cpp b/fpdfsdk/src/javascript/PublicMethods.cpp
index 490c9e3..f5686a7 100644
--- a/fpdfsdk/src/javascript/PublicMethods.cpp
+++ b/fpdfsdk/src/javascript/PublicMethods.cpp
@@ -4,19 +4,20 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
+#include "PublicMethods.h"
+
+#include "../../include/fsdk_mgr.h"  // For CPDFDoc_Environment.
 #include "../../include/javascript/IJavaScript.h"
-#include "../../include/javascript/JS_Define.h"
-#include "../../include/javascript/JS_Object.h"
-#include "../../include/javascript/JS_Value.h"
-#include "../../include/javascript/PublicMethods.h"
-#include "../../include/javascript/JS_EventHandler.h"
-#include "../../include/javascript/resource.h"
-#include "../../include/javascript/JS_Context.h"
-#include "../../include/javascript/JS_Value.h"
-#include "../../include/javascript/util.h"
-#include "../../include/javascript/Field.h"
-#include "../../include/javascript/color.h"
-#include "../../include/javascript/JS_Runtime.h"
+#include "Field.h"
+#include "JS_Context.h"
+#include "JS_Define.h"
+#include "JS_EventHandler.h"
+#include "JS_Object.h"
+#include "JS_Runtime.h"
+#include "JS_Value.h"
+#include "color.h"
+#include "resource.h"
+#include "util.h"
 
 static v8::Isolate* GetIsolate(IFXJS_Context* cc) {
   CJS_Context* pContext = (CJS_Context*)cc;
diff --git a/fpdfsdk/src/javascript/PublicMethods.h b/fpdfsdk/src/javascript/PublicMethods.h
new file mode 100644
index 0000000..47885b4
--- /dev/null
+++ b/fpdfsdk/src/javascript/PublicMethods.h
@@ -0,0 +1,185 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FPDFSDK_SRC_JAVASCRIPT_PUBLICMETHODS_H_
+#define FPDFSDK_SRC_JAVASCRIPT_PUBLICMETHODS_H_
+
+#include "JS_Define.h"
+
+class CJS_PublicMethods : public CJS_Object {
+ public:
+  CJS_PublicMethods(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
+  ~CJS_PublicMethods() override {}
+
+ public:
+  static FX_BOOL AFNumber_Format(IFXJS_Context* cc,
+                                 const CJS_Parameters& params,
+                                 CJS_Value& vRet,
+                                 CFX_WideString& sError);
+  static FX_BOOL AFNumber_Keystroke(IFXJS_Context* cc,
+                                    const CJS_Parameters& params,
+                                    CJS_Value& vRet,
+                                    CFX_WideString& sError);
+  static FX_BOOL AFPercent_Format(IFXJS_Context* cc,
+                                  const CJS_Parameters& params,
+                                  CJS_Value& vRet,
+                                  CFX_WideString& sError);
+  static FX_BOOL AFPercent_Keystroke(IFXJS_Context* cc,
+                                     const CJS_Parameters& params,
+                                     CJS_Value& vRet,
+                                     CFX_WideString& sError);
+  static FX_BOOL AFDate_FormatEx(IFXJS_Context* cc,
+                                 const CJS_Parameters& params,
+                                 CJS_Value& vRet,
+                                 CFX_WideString& sError);
+  static FX_BOOL AFDate_KeystrokeEx(IFXJS_Context* cc,
+                                    const CJS_Parameters& params,
+                                    CJS_Value& vRet,
+                                    CFX_WideString& sError);
+  static FX_BOOL AFDate_Format(IFXJS_Context* cc,
+                               const CJS_Parameters& params,
+                               CJS_Value& vRet,
+                               CFX_WideString& sError);
+  static FX_BOOL AFDate_Keystroke(IFXJS_Context* cc,
+                                  const CJS_Parameters& params,
+                                  CJS_Value& vRet,
+                                  CFX_WideString& sError);
+  static FX_BOOL AFTime_FormatEx(IFXJS_Context* cc,
+                                 const CJS_Parameters& params,
+                                 CJS_Value& vRet,
+                                 CFX_WideString& sError);  //
+  static FX_BOOL AFTime_KeystrokeEx(IFXJS_Context* cc,
+                                    const CJS_Parameters& params,
+                                    CJS_Value& vRet,
+                                    CFX_WideString& sError);
+  static FX_BOOL AFTime_Format(IFXJS_Context* cc,
+                               const CJS_Parameters& params,
+                               CJS_Value& vRet,
+                               CFX_WideString& sError);
+  static FX_BOOL AFTime_Keystroke(IFXJS_Context* cc,
+                                  const CJS_Parameters& params,
+                                  CJS_Value& vRet,
+                                  CFX_WideString& sError);
+  static FX_BOOL AFSpecial_Format(IFXJS_Context* cc,
+                                  const CJS_Parameters& params,
+                                  CJS_Value& vRet,
+                                  CFX_WideString& sError);
+  static FX_BOOL AFSpecial_Keystroke(IFXJS_Context* cc,
+                                     const CJS_Parameters& params,
+                                     CJS_Value& vRet,
+                                     CFX_WideString& sError);
+  static FX_BOOL AFSpecial_KeystrokeEx(IFXJS_Context* cc,
+                                       const CJS_Parameters& params,
+                                       CJS_Value& vRet,
+                                       CFX_WideString& sError);  //
+  static FX_BOOL AFSimple(IFXJS_Context* cc,
+                          const CJS_Parameters& params,
+                          CJS_Value& vRet,
+                          CFX_WideString& sError);
+  static FX_BOOL AFMakeNumber(IFXJS_Context* cc,
+                              const CJS_Parameters& params,
+                              CJS_Value& vRet,
+                              CFX_WideString& sError);
+  static FX_BOOL AFSimple_Calculate(IFXJS_Context* cc,
+                                    const CJS_Parameters& params,
+                                    CJS_Value& vRet,
+                                    CFX_WideString& sError);
+  static FX_BOOL AFRange_Validate(IFXJS_Context* cc,
+                                  const CJS_Parameters& params,
+                                  CJS_Value& vRet,
+                                  CFX_WideString& sError);
+  static FX_BOOL AFMergeChange(IFXJS_Context* cc,
+                               const CJS_Parameters& params,
+                               CJS_Value& vRet,
+                               CFX_WideString& sError);
+  static FX_BOOL AFParseDateEx(IFXJS_Context* cc,
+                               const CJS_Parameters& params,
+                               CJS_Value& vRet,
+                               CFX_WideString& sError);
+  static FX_BOOL AFExtractNums(IFXJS_Context* cc,
+                               const CJS_Parameters& params,
+                               CJS_Value& vRet,
+                               CFX_WideString& sError);
+
+ public:
+  JS_STATIC_GLOBAL_FUN(AFNumber_Format);
+  JS_STATIC_GLOBAL_FUN(AFNumber_Keystroke);
+  JS_STATIC_GLOBAL_FUN(AFPercent_Format);
+  JS_STATIC_GLOBAL_FUN(AFPercent_Keystroke);
+  JS_STATIC_GLOBAL_FUN(AFDate_FormatEx);
+  JS_STATIC_GLOBAL_FUN(AFDate_KeystrokeEx);
+  JS_STATIC_GLOBAL_FUN(AFDate_Format);
+  JS_STATIC_GLOBAL_FUN(AFDate_Keystroke);
+  JS_STATIC_GLOBAL_FUN(AFTime_FormatEx);
+  JS_STATIC_GLOBAL_FUN(AFTime_KeystrokeEx);
+  JS_STATIC_GLOBAL_FUN(AFTime_Format);
+  JS_STATIC_GLOBAL_FUN(AFTime_Keystroke);
+  JS_STATIC_GLOBAL_FUN(AFSpecial_Format);
+  JS_STATIC_GLOBAL_FUN(AFSpecial_Keystroke);
+  JS_STATIC_GLOBAL_FUN(AFSpecial_KeystrokeEx);
+  JS_STATIC_GLOBAL_FUN(AFSimple);
+  JS_STATIC_GLOBAL_FUN(AFMakeNumber);
+  JS_STATIC_GLOBAL_FUN(AFSimple_Calculate);
+  JS_STATIC_GLOBAL_FUN(AFRange_Validate);
+  JS_STATIC_GLOBAL_FUN(AFMergeChange);
+  JS_STATIC_GLOBAL_FUN(AFParseDateEx);
+  JS_STATIC_GLOBAL_FUN(AFExtractNums);
+
+  JS_STATIC_DECLARE_GLOBAL_FUN();
+
+ public:
+  static int ParseStringInteger(const CFX_WideString& string,
+                                int nStart,
+                                int& nSkip,
+                                int nMaxStep);
+  static CFX_WideString ParseStringString(const CFX_WideString& string,
+                                          int nStart,
+                                          int& nSkip);
+  static double MakeRegularDate(const CFX_WideString& value,
+                                const CFX_WideString& format,
+                                FX_BOOL& bWrongFormat);
+  static CFX_WideString MakeFormatDate(double dDate,
+                                       const CFX_WideString& format);
+  static FX_BOOL ConvertStringToNumber(const FX_WCHAR* swSource,
+                                       double& dRet,
+                                       FX_BOOL& bDot);
+  static double ParseStringToNumber(const FX_WCHAR* swSource);
+  static double ParseNormalDate(const CFX_WideString& value,
+                                FX_BOOL& bWrongFormat);
+  static double MakeInterDate(CFX_WideString strValue);
+  static double ParseNumber(const FX_WCHAR* swSource,
+                            FX_BOOL& bAllDigits,
+                            FX_BOOL& bDot,
+                            FX_BOOL& bSign,
+                            FX_BOOL& bKXJS);
+
+ public:
+  static CFX_WideString StrLTrim(const FX_WCHAR* pStr);
+  static CFX_WideString StrRTrim(const FX_WCHAR* pStr);
+  static CFX_WideString StrTrim(const FX_WCHAR* pStr);
+
+  static CFX_ByteString StrLTrim(const FX_CHAR* pStr);
+  static CFX_ByteString StrRTrim(const FX_CHAR* pStr);
+  static CFX_ByteString StrTrim(const FX_CHAR* pStr);
+
+  static FX_BOOL IsNumber(const FX_CHAR* string);
+  static FX_BOOL IsNumber(const FX_WCHAR* string);
+
+  static FX_BOOL IsDigit(char ch);
+  static FX_BOOL IsDigit(wchar_t ch);
+  static FX_BOOL IsAlphabetic(wchar_t ch);
+  static FX_BOOL IsAlphaNumeric(wchar_t ch);
+
+  static FX_BOOL maskSatisfied(wchar_t c_Change, wchar_t c_Mask);
+  static FX_BOOL isReservedMaskChar(wchar_t ch);
+
+  static double AF_Simple(const FX_WCHAR* sFuction,
+                          double dValue1,
+                          double dValue2);
+  static CJS_Array AF_MakeArrayFromList(v8::Isolate* isolate, CJS_Value val);
+};
+
+#endif  // FPDFSDK_SRC_JAVASCRIPT_PUBLICMETHODS_H_
diff --git a/fpdfsdk/src/javascript/app.cpp b/fpdfsdk/src/javascript/app.cpp
index fcaffa4..8927122 100644
--- a/fpdfsdk/src/javascript/app.cpp
+++ b/fpdfsdk/src/javascript/app.cpp
@@ -4,17 +4,19 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
+#include "app.h"
+
 #include "../../../third_party/base/nonstd_unique_ptr.h"
+#include "../../include/fsdk_mgr.h"  // For CPDFDoc_Environment.
 #include "../../include/javascript/IJavaScript.h"
-#include "../../include/javascript/JS_Define.h"
-#include "../../include/javascript/JS_Object.h"
-#include "../../include/javascript/JS_Value.h"
-#include "../../include/javascript/app.h"
-#include "../../include/javascript/JS_EventHandler.h"
-#include "../../include/javascript/resource.h"
-#include "../../include/javascript/JS_Context.h"
-#include "../../include/javascript/JS_Runtime.h"
-#include "../../include/javascript/Document.h"
+#include "Document.h"
+#include "JS_Context.h"
+#include "JS_Define.h"
+#include "JS_EventHandler.h"
+#include "JS_Object.h"
+#include "JS_Runtime.h"
+#include "JS_Value.h"
+#include "resource.h"
 
 static v8::Isolate* GetIsolate(IFXJS_Context* cc) {
   CJS_Context* pContext = (CJS_Context*)cc;
diff --git a/fpdfsdk/src/javascript/app.h b/fpdfsdk/src/javascript/app.h
new file mode 100644
index 0000000..7824a1e
--- /dev/null
+++ b/fpdfsdk/src/javascript/app.h
@@ -0,0 +1,218 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FPDFSDK_SRC_JAVASCRIPT_APP_H_
+#define FPDFSDK_SRC_JAVASCRIPT_APP_H_
+
+#include "JS_Define.h"
+
+class CJS_Runtime;
+
+/* ---------------------------- TimerObj ---------------------------- */
+
+class CJS_Timer;
+
+class TimerObj : public CJS_EmbedObj {
+ public:
+  TimerObj(CJS_Object* pJSObject);
+  ~TimerObj() override;
+
+ public:
+  void SetTimer(CJS_Timer* pTimer);
+  CJS_Timer* GetTimer() const;
+
+ private:
+  CJS_Timer* m_pTimer;
+};
+
+class CJS_TimerObj : public CJS_Object {
+ public:
+  CJS_TimerObj(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
+  ~CJS_TimerObj() override {}
+
+  DECLARE_JS_CLASS(CJS_TimerObj);
+};
+
+class app : public CJS_EmbedObj {
+ public:
+  app(CJS_Object* pJSObject);
+  ~app() override;
+
+ public:
+  FX_BOOL activeDocs(IFXJS_Context* cc,
+                     CJS_PropValue& vp,
+                     CFX_WideString& sError);
+  FX_BOOL calculate(IFXJS_Context* cc,
+                    CJS_PropValue& vp,
+                    CFX_WideString& sError);
+  FX_BOOL formsVersion(IFXJS_Context* cc,
+                       CJS_PropValue& vp,
+                       CFX_WideString& sError);
+  FX_BOOL fs(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL fullscreen(IFXJS_Context* cc,
+                     CJS_PropValue& vp,
+                     CFX_WideString& sError);
+  FX_BOOL language(IFXJS_Context* cc,
+                   CJS_PropValue& vp,
+                   CFX_WideString& sError);
+  FX_BOOL media(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL platform(IFXJS_Context* cc,
+                   CJS_PropValue& vp,
+                   CFX_WideString& sError);
+  FX_BOOL runtimeHighlight(IFXJS_Context* cc,
+                           CJS_PropValue& vp,
+                           CFX_WideString& sError);
+  FX_BOOL viewerType(IFXJS_Context* cc,
+                     CJS_PropValue& vp,
+                     CFX_WideString& sError);
+  FX_BOOL viewerVariation(IFXJS_Context* cc,
+                          CJS_PropValue& vp,
+                          CFX_WideString& sError);
+  FX_BOOL viewerVersion(IFXJS_Context* cc,
+                        CJS_PropValue& vp,
+                        CFX_WideString& sError);
+
+  FX_BOOL alert(IFXJS_Context* cc,
+                const CJS_Parameters& params,
+                CJS_Value& vRet,
+                CFX_WideString& sError);
+  FX_BOOL beep(IFXJS_Context* cc,
+               const CJS_Parameters& params,
+               CJS_Value& vRet,
+               CFX_WideString& sError);
+  FX_BOOL browseForDoc(IFXJS_Context* cc,
+                       const CJS_Parameters& params,
+                       CJS_Value& vRet,
+                       CFX_WideString& sError);
+  FX_BOOL clearInterval(IFXJS_Context* cc,
+                        const CJS_Parameters& params,
+                        CJS_Value& vRet,
+                        CFX_WideString& sError);
+  FX_BOOL clearTimeOut(IFXJS_Context* cc,
+                       const CJS_Parameters& params,
+                       CJS_Value& vRet,
+                       CFX_WideString& sError);
+  FX_BOOL execDialog(IFXJS_Context* cc,
+                     const CJS_Parameters& params,
+                     CJS_Value& vRet,
+                     CFX_WideString& sError);
+  FX_BOOL execMenuItem(IFXJS_Context* cc,
+                       const CJS_Parameters& params,
+                       CJS_Value& vRet,
+                       CFX_WideString& sError);
+  FX_BOOL findComponent(IFXJS_Context* cc,
+                        const CJS_Parameters& params,
+                        CJS_Value& vRet,
+                        CFX_WideString& sError);
+  FX_BOOL goBack(IFXJS_Context* cc,
+                 const CJS_Parameters& params,
+                 CJS_Value& vRet,
+                 CFX_WideString& sError);
+  FX_BOOL goForward(IFXJS_Context* cc,
+                    const CJS_Parameters& params,
+                    CJS_Value& vRet,
+                    CFX_WideString& sError);
+  FX_BOOL launchURL(IFXJS_Context* cc,
+                    const CJS_Parameters& params,
+                    CJS_Value& vRet,
+                    CFX_WideString& sError);
+  FX_BOOL mailMsg(IFXJS_Context* cc,
+                  const CJS_Parameters& params,
+                  CJS_Value& vRet,
+                  CFX_WideString& sError);
+  FX_BOOL newFDF(IFXJS_Context* cc,
+                 const CJS_Parameters& params,
+                 CJS_Value& vRet,
+                 CFX_WideString& sError);
+  FX_BOOL newDoc(IFXJS_Context* cc,
+                 const CJS_Parameters& params,
+                 CJS_Value& vRet,
+                 CFX_WideString& sError);
+  FX_BOOL openDoc(IFXJS_Context* cc,
+                  const CJS_Parameters& params,
+                  CJS_Value& vRet,
+                  CFX_WideString& sError);
+  FX_BOOL openFDF(IFXJS_Context* cc,
+                  const CJS_Parameters& params,
+                  CJS_Value& vRet,
+                  CFX_WideString& sError);
+  FX_BOOL popUpMenuEx(IFXJS_Context* cc,
+                      const CJS_Parameters& params,
+                      CJS_Value& vRet,
+                      CFX_WideString& sError);
+  FX_BOOL popUpMenu(IFXJS_Context* cc,
+                    const CJS_Parameters& params,
+                    CJS_Value& vRet,
+                    CFX_WideString& sError);
+  FX_BOOL response(IFXJS_Context* cc,
+                   const CJS_Parameters& params,
+                   CJS_Value& vRet,
+                   CFX_WideString& sError);
+  FX_BOOL setInterval(IFXJS_Context* cc,
+                      const CJS_Parameters& params,
+                      CJS_Value& vRet,
+                      CFX_WideString& sError);
+  FX_BOOL setTimeOut(IFXJS_Context* cc,
+                     const CJS_Parameters& params,
+                     CJS_Value& vRet,
+                     CFX_WideString& sError);
+
+  static CFX_WideString SysPathToPDFPath(const CFX_WideString& sOldPath);
+
+ private:
+  // CJS_EmbedObj
+  void TimerProc(CJS_Timer* pTimer) override;
+  void RunJsScript(CJS_Runtime* pRuntime, const CFX_WideString& wsScript);
+
+  bool m_bCalculate;
+  bool m_bRuntimeHighLight;
+  CFX_ArrayTemplate<CJS_Timer*> m_aTimer;
+};
+
+class CJS_App : public CJS_Object {
+ public:
+  explicit CJS_App(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
+  ~CJS_App() override {}
+
+  DECLARE_JS_CLASS(CJS_App);
+
+  JS_STATIC_PROP(activeDocs, app);
+  JS_STATIC_PROP(calculate, app);
+  JS_STATIC_PROP(formsVersion, app);
+  JS_STATIC_PROP(fs, app);
+  JS_STATIC_PROP(fullscreen, app);
+  JS_STATIC_PROP(language, app);
+  JS_STATIC_PROP(media, app);
+  JS_STATIC_PROP(platform, app);
+  JS_STATIC_PROP(runtimeHighlight, app);
+  JS_STATIC_PROP(viewerType, app);
+  JS_STATIC_PROP(viewerVariation, app);
+  JS_STATIC_PROP(viewerVersion, app);
+
+  JS_STATIC_METHOD(alert, app);
+  JS_STATIC_METHOD(beep, app);
+  JS_STATIC_METHOD(browseForDoc, app);
+  JS_STATIC_METHOD(clearInterval, app);
+  JS_STATIC_METHOD(clearTimeOut, app);
+  JS_STATIC_METHOD(execDialog, app);
+  JS_STATIC_METHOD(execMenuItem, app);
+  JS_STATIC_METHOD(findComponent, app);
+  JS_STATIC_METHOD(goBack, app);
+  JS_STATIC_METHOD(goForward, app);
+  JS_STATIC_METHOD(launchURL, app);
+  JS_STATIC_METHOD(mailMsg, app);
+  JS_STATIC_METHOD(newFDF, app);
+  JS_STATIC_METHOD(newDoc, app);
+  JS_STATIC_METHOD(openDoc, app);
+  JS_STATIC_METHOD(openFDF, app);
+  JS_STATIC_METHOD(popUpMenuEx, app);
+  JS_STATIC_METHOD(popUpMenu, app);
+  JS_STATIC_METHOD(response, app);
+  JS_STATIC_METHOD(setInterval, app);
+  JS_STATIC_METHOD(setTimeOut, app);
+};
+
+#endif  // FPDFSDK_SRC_JAVASCRIPT_APP_H_
diff --git a/fpdfsdk/src/javascript/color.cpp b/fpdfsdk/src/javascript/color.cpp
index cac3907..da6fc60 100644
--- a/fpdfsdk/src/javascript/color.cpp
+++ b/fpdfsdk/src/javascript/color.cpp
@@ -4,15 +4,15 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
-#include "../../include/javascript/color.h"
+#include "color.h"
 
 #include "../../include/javascript/IJavaScript.h"
-#include "../../include/javascript/JS_Define.h"
-#include "../../include/javascript/JS_Object.h"
-#include "../../include/javascript/JS_Value.h"
-#include "../../include/javascript/JS_EventHandler.h"
-#include "../../include/javascript/JS_Context.h"
-#include "../../include/javascript/JS_Runtime.h"
+#include "JS_Define.h"
+#include "JS_Object.h"
+#include "JS_Value.h"
+#include "JS_EventHandler.h"
+#include "JS_Context.h"
+#include "JS_Runtime.h"
 
 static v8::Isolate* GetIsolate(IFXJS_Context* cc) {
   CJS_Context* pContext = (CJS_Context*)cc;
diff --git a/fpdfsdk/src/javascript/color.h b/fpdfsdk/src/javascript/color.h
new file mode 100644
index 0000000..9dec191
--- /dev/null
+++ b/fpdfsdk/src/javascript/color.h
@@ -0,0 +1,85 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FPDFSDK_SRC_JAVASCRIPT_COLOR_H_
+#define FPDFSDK_SRC_JAVASCRIPT_COLOR_H_
+
+#include "../../include/pdfwindow/PWL_Wnd.h"  // For CPWL_Color.
+#include "JS_Define.h"
+
+class color : public CJS_EmbedObj {
+ public:
+  color(CJS_Object* pJSObject);
+  ~color() override;
+
+  FX_BOOL black(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL blue(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL cyan(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL dkGray(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL gray(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL green(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL ltGray(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL magenta(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL red(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL transparent(IFXJS_Context* cc,
+                      CJS_PropValue& vp,
+                      CFX_WideString& sError);
+  FX_BOOL white(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL yellow(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+
+  FX_BOOL convert(IFXJS_Context* cc,
+                  const CJS_Parameters& params,
+                  CJS_Value& vRet,
+                  CFX_WideString& sError);
+  FX_BOOL equal(IFXJS_Context* cc,
+                const CJS_Parameters& params,
+                CJS_Value& vRet,
+                CFX_WideString& sError);
+
+ public:
+  static void ConvertPWLColorToArray(const CPWL_Color& color, CJS_Array& array);
+  static void ConvertArrayToPWLColor(CJS_Array& array, CPWL_Color& color);
+
+ private:
+  CPWL_Color m_crTransparent;
+  CPWL_Color m_crBlack;
+  CPWL_Color m_crWhite;
+  CPWL_Color m_crRed;
+  CPWL_Color m_crGreen;
+  CPWL_Color m_crBlue;
+  CPWL_Color m_crCyan;
+  CPWL_Color m_crMagenta;
+  CPWL_Color m_crYellow;
+  CPWL_Color m_crDKGray;
+  CPWL_Color m_crGray;
+  CPWL_Color m_crLTGray;
+};
+
+class CJS_Color : public CJS_Object {
+ public:
+  CJS_Color(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
+  ~CJS_Color() override {}
+
+  DECLARE_JS_CLASS(CJS_Color);
+
+  JS_STATIC_PROP(black, color);
+  JS_STATIC_PROP(blue, color);
+  JS_STATIC_PROP(cyan, color);
+  JS_STATIC_PROP(dkGray, color);
+  JS_STATIC_PROP(gray, color);
+  JS_STATIC_PROP(green, color);
+  JS_STATIC_PROP(ltGray, color);
+  JS_STATIC_PROP(magenta, color);
+  JS_STATIC_PROP(red, color);
+  JS_STATIC_PROP(transparent, color);
+  JS_STATIC_PROP(white, color);
+  JS_STATIC_PROP(yellow, color);
+
+  JS_STATIC_METHOD(convert, color);
+  JS_STATIC_METHOD(equal, color);
+};
+
+#endif  // FPDFSDK_SRC_JAVASCRIPT_COLOR_H_
diff --git a/fpdfsdk/src/javascript/console.cpp b/fpdfsdk/src/javascript/console.cpp
index 519cecc..a44d239 100644
--- a/fpdfsdk/src/javascript/console.cpp
+++ b/fpdfsdk/src/javascript/console.cpp
@@ -4,13 +4,14 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
+#include "console.h"
+
 #include "../../include/javascript/IJavaScript.h"
-#include "../../include/javascript/JS_Define.h"
-#include "../../include/javascript/JS_Object.h"
-#include "../../include/javascript/JS_Value.h"
-#include "../../include/javascript/console.h"
-#include "../../include/javascript/JS_EventHandler.h"
-#include "../../include/javascript/JS_Context.h"
+#include "JS_Define.h"
+#include "JS_Object.h"
+#include "JS_Value.h"
+#include "JS_EventHandler.h"
+#include "JS_Context.h"
 
 /* ------------------------ console ------------------------ */
 
diff --git a/fpdfsdk/src/javascript/console.h b/fpdfsdk/src/javascript/console.h
new file mode 100644
index 0000000..747bc15
--- /dev/null
+++ b/fpdfsdk/src/javascript/console.h
@@ -0,0 +1,49 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FPDFSDK_SRC_JAVASCRIPT_CONSOLE_H_
+#define FPDFSDK_SRC_JAVASCRIPT_CONSOLE_H_
+
+#include "JS_Define.h"
+
+class console : public CJS_EmbedObj {
+ public:
+  console(CJS_Object* pJSObject);
+  ~console() override;
+
+ public:
+  FX_BOOL clear(IFXJS_Context* cc,
+                const CJS_Parameters& params,
+                CJS_Value& vRet,
+                CFX_WideString& sError);
+  FX_BOOL hide(IFXJS_Context* cc,
+               const CJS_Parameters& params,
+               CJS_Value& vRet,
+               CFX_WideString& sError);
+  FX_BOOL println(IFXJS_Context* cc,
+                  const CJS_Parameters& params,
+                  CJS_Value& vRet,
+                  CFX_WideString& sError);
+  FX_BOOL show(IFXJS_Context* cc,
+               const CJS_Parameters& params,
+               CJS_Value& vRet,
+               CFX_WideString& sError);
+};
+
+class CJS_Console : public CJS_Object {
+ public:
+  CJS_Console(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
+  ~CJS_Console() override {}
+
+  DECLARE_JS_CLASS(CJS_Console);
+
+  JS_STATIC_METHOD(clear, console);
+  JS_STATIC_METHOD(hide, console);
+  JS_STATIC_METHOD(println, console);
+  JS_STATIC_METHOD(show, console);
+};
+
+#endif  // FPDFSDK_SRC_JAVASCRIPT_CONSOLE_H_
diff --git a/fpdfsdk/src/javascript/event.cpp b/fpdfsdk/src/javascript/event.cpp
index 7031be8..0d02503 100644
--- a/fpdfsdk/src/javascript/event.cpp
+++ b/fpdfsdk/src/javascript/event.cpp
@@ -4,14 +4,15 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
+#include "event.h"
+
 #include "../../include/javascript/IJavaScript.h"
-#include "../../include/javascript/JS_Define.h"
-#include "../../include/javascript/JS_Object.h"
-#include "../../include/javascript/JS_Value.h"
-#include "../../include/javascript/JS_EventHandler.h"
-#include "../../include/javascript/JS_Context.h"
-#include "../../include/javascript/event.h"
-#include "../../include/javascript/Field.h"
+#include "JS_Define.h"
+#include "JS_Object.h"
+#include "JS_Value.h"
+#include "JS_EventHandler.h"
+#include "JS_Context.h"
+#include "Field.h"
 
 /* -------------------------- event -------------------------- */
 
diff --git a/fpdfsdk/src/javascript/event.h b/fpdfsdk/src/javascript/event.h
new file mode 100644
index 0000000..29ff3bc
--- /dev/null
+++ b/fpdfsdk/src/javascript/event.h
@@ -0,0 +1,89 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FPDFSDK_SRC_JAVASCRIPT_EVENT_H_
+#define FPDFSDK_SRC_JAVASCRIPT_EVENT_H_
+
+#include "JS_Define.h"
+
+class event : public CJS_EmbedObj {
+ public:
+  event(CJS_Object* pJSObject);
+  ~event() override;
+
+ public:
+  FX_BOOL change(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL changeEx(IFXJS_Context* cc,
+                   CJS_PropValue& vp,
+                   CFX_WideString& sError);
+  FX_BOOL commitKey(IFXJS_Context* cc,
+                    CJS_PropValue& vp,
+                    CFX_WideString& sError);
+  FX_BOOL fieldFull(IFXJS_Context* cc,
+                    CJS_PropValue& vp,
+                    CFX_WideString& sError);
+  FX_BOOL keyDown(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL modifier(IFXJS_Context* cc,
+                   CJS_PropValue& vp,
+                   CFX_WideString& sError);
+  FX_BOOL name(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL rc(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL richChange(IFXJS_Context* cc,
+                     CJS_PropValue& vp,
+                     CFX_WideString& sError);
+  FX_BOOL richChangeEx(IFXJS_Context* cc,
+                       CJS_PropValue& vp,
+                       CFX_WideString& sError);
+  FX_BOOL richValue(IFXJS_Context* cc,
+                    CJS_PropValue& vp,
+                    CFX_WideString& sError);
+  FX_BOOL selEnd(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL selStart(IFXJS_Context* cc,
+                   CJS_PropValue& vp,
+                   CFX_WideString& sError);
+  FX_BOOL shift(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL source(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL target(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL targetName(IFXJS_Context* cc,
+                     CJS_PropValue& vp,
+                     CFX_WideString& sError);
+  FX_BOOL type(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL value(IFXJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError);
+  FX_BOOL willCommit(IFXJS_Context* cc,
+                     CJS_PropValue& vp,
+                     CFX_WideString& sError);
+};
+
+class CJS_Event : public CJS_Object {
+ public:
+  CJS_Event(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
+  ~CJS_Event() override {}
+
+  DECLARE_JS_CLASS(CJS_Event);
+
+  JS_STATIC_PROP(change, event);
+  JS_STATIC_PROP(changeEx, event);
+  JS_STATIC_PROP(commitKey, event);
+  JS_STATIC_PROP(fieldFull, event);
+  JS_STATIC_PROP(keyDown, event);
+  JS_STATIC_PROP(modifier, event);
+  JS_STATIC_PROP(name, event);
+  JS_STATIC_PROP(rc, event);
+  JS_STATIC_PROP(richChange, event);
+  JS_STATIC_PROP(richChangeEx, event);
+  JS_STATIC_PROP(richValue, event);
+  JS_STATIC_PROP(selEnd, event);
+  JS_STATIC_PROP(selStart, event);
+  JS_STATIC_PROP(shift, event);
+  JS_STATIC_PROP(source, event);
+  JS_STATIC_PROP(target, event);
+  JS_STATIC_PROP(targetName, event);
+  JS_STATIC_PROP(type, event);
+  JS_STATIC_PROP(value, event);
+  JS_STATIC_PROP(willCommit, event);
+};
+
+#endif  // FPDFSDK_SRC_JAVASCRIPT_EVENT_H_
diff --git a/fpdfsdk/src/javascript/global.cpp b/fpdfsdk/src/javascript/global.cpp
index c4f208f..cd4545d 100644
--- a/fpdfsdk/src/javascript/global.cpp
+++ b/fpdfsdk/src/javascript/global.cpp
@@ -4,17 +4,18 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
+#include "global.h"
+
 #include "../../../core/include/fxcrt/fx_ext.h"
-#include "../../include/javascript/IJavaScript.h"
-#include "../../include/javascript/JS_Context.h"
-#include "../../include/javascript/JS_Define.h"
-#include "../../include/javascript/JS_EventHandler.h"
-#include "../../include/javascript/JS_GlobalData.h"
-#include "../../include/javascript/JS_Object.h"
-#include "../../include/javascript/JS_Value.h"
-#include "../../include/javascript/global.h"
 #include "../../include/fpdfxfa/fpdfxfa_app.h"
-#include "../../include/javascript/resource.h"
+#include "../../include/javascript/IJavaScript.h"
+#include "JS_Context.h"
+#include "JS_Define.h"
+#include "JS_EventHandler.h"
+#include "JS_GlobalData.h"
+#include "JS_Object.h"
+#include "JS_Value.h"
+#include "resource.h"
 
 /* ---------------------------- global ---------------------------- */
 
diff --git a/fpdfsdk/src/javascript/global.h b/fpdfsdk/src/javascript/global.h
new file mode 100644
index 0000000..03b6e76
--- /dev/null
+++ b/fpdfsdk/src/javascript/global.h
@@ -0,0 +1,93 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FPDFSDK_SRC_JAVASCRIPT_GLOBAL_H_
+#define FPDFSDK_SRC_JAVASCRIPT_GLOBAL_H_
+
+#include <map>
+
+#include "JS_Define.h"
+
+class CJS_GlobalData;
+class CJS_GlobalVariableArray;
+class CJS_KeyValue;
+
+struct JSGlobalData {
+  JSGlobalData() {
+    nType = 0;
+    dData = 0;
+    bData = FALSE;
+    sData = "";
+    bPersistent = FALSE;
+    bDeleted = FALSE;
+  }
+
+  ~JSGlobalData() { pData.Reset(); }
+  int nType;  // 0:int 1:bool 2:string 3:obj
+  double dData;
+  bool bData;
+  CFX_ByteString sData;
+  v8::Global<v8::Object> pData;
+  bool bPersistent;
+  bool bDeleted;
+};
+
+class JSGlobalAlternate : public CJS_EmbedObj {
+ public:
+  JSGlobalAlternate(CJS_Object* pJSObject);
+  ~JSGlobalAlternate() override;
+
+  FX_BOOL setPersistent(IFXJS_Context* cc,
+                        const CJS_Parameters& params,
+                        CJS_Value& vRet,
+                        CFX_WideString& sError);
+  FX_BOOL QueryProperty(const FX_WCHAR* propname);
+  FX_BOOL DoProperty(IFXJS_Context* cc,
+                     const FX_WCHAR* propname,
+                     CJS_PropValue& vp,
+                     CFX_WideString& sError);
+  FX_BOOL DelProperty(IFXJS_Context* cc,
+                      const FX_WCHAR* propname,
+                      CFX_WideString& sError);
+  void Initial(CPDFDoc_Environment* pApp);
+
+ private:
+  void UpdateGlobalPersistentVariables();
+  void CommitGlobalPersisitentVariables();
+  void DestroyGlobalPersisitentVariables();
+  FX_BOOL SetGlobalVariables(const FX_CHAR* propname,
+                             int nType,
+                             double dData,
+                             bool bData,
+                             const CFX_ByteString& sData,
+                             v8::Local<v8::Object> pData,
+                             bool bDefaultPersistent);
+
+  void ObjectToArray(v8::Local<v8::Object> pObj,
+                     CJS_GlobalVariableArray& array);
+  void PutObjectProperty(v8::Local<v8::Object> obj, CJS_KeyValue* pData);
+
+ private:
+  std::map<CFX_ByteString, JSGlobalData*> m_mapGlobal;
+  CFX_WideString m_sFilePath;
+  CJS_GlobalData* m_pGlobalData;
+  CPDFDoc_Environment* m_pApp;
+};
+
+class CJS_Global : public CJS_Object {
+ public:
+  explicit CJS_Global(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
+  ~CJS_Global() override {}
+
+  // CJS_Object
+  FX_BOOL InitInstance(IFXJS_Context* cc) override;
+
+  DECLARE_SPECIAL_JS_CLASS(CJS_Global);
+
+  JS_SPECIAL_STATIC_METHOD(setPersistent, JSGlobalAlternate, global);
+};
+
+#endif  // FPDFSDK_SRC_JAVASCRIPT_GLOBAL_H_
diff --git a/fpdfsdk/src/javascript/report.cpp b/fpdfsdk/src/javascript/report.cpp
index d387792..629b749 100644
--- a/fpdfsdk/src/javascript/report.cpp
+++ b/fpdfsdk/src/javascript/report.cpp
@@ -4,11 +4,12 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
+#include "report.h"
+
 #include "../../include/javascript/IJavaScript.h"
-#include "../../include/javascript/JS_Define.h"
-#include "../../include/javascript/JS_Object.h"
-#include "../../include/javascript/JS_Value.h"
-#include "../../include/javascript/report.h"
+#include "JS_Define.h"
+#include "JS_Object.h"
+#include "JS_Value.h"
 
 /* ---------------------- report ---------------------- */
 
diff --git a/fpdfsdk/src/javascript/report.h b/fpdfsdk/src/javascript/report.h
new file mode 100644
index 0000000..0b4be6d
--- /dev/null
+++ b/fpdfsdk/src/javascript/report.h
@@ -0,0 +1,40 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FPDFSDK_SRC_JAVASCRIPT_REPORT_H_
+#define FPDFSDK_SRC_JAVASCRIPT_REPORT_H_
+
+#include "JS_Define.h"
+
+class Report : public CJS_EmbedObj {
+ public:
+  Report(CJS_Object* pJSObject);
+  ~Report() override;
+
+ public:
+  FX_BOOL save(IFXJS_Context* cc,
+               const CJS_Parameters& params,
+               CJS_Value& vRet,
+               CFX_WideString& sError);
+  FX_BOOL writeText(IFXJS_Context* cc,
+                    const CJS_Parameters& params,
+                    CJS_Value& vRet,
+                    CFX_WideString& sError);
+};
+
+class CJS_Report : public CJS_Object {
+ public:
+  CJS_Report(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
+  ~CJS_Report() override {}
+
+ public:
+  DECLARE_JS_CLASS(CJS_Report);
+
+  JS_STATIC_METHOD(save, Report)
+  JS_STATIC_METHOD(writeText, Report);
+};
+
+#endif  // FPDFSDK_SRC_JAVASCRIPT_REPORT_H_
diff --git a/fpdfsdk/src/javascript/resource.cpp b/fpdfsdk/src/javascript/resource.cpp
index 5b6bd48..d99e7ce 100644
--- a/fpdfsdk/src/javascript/resource.cpp
+++ b/fpdfsdk/src/javascript/resource.cpp
@@ -4,7 +4,7 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
-#include "../../include/javascript/resource.h"
+#include "resource.h"
 
 CFX_WideString JSGetStringFromID(CJS_Context* pContext, FX_UINT id) {
   switch (id) {
diff --git a/fpdfsdk/src/javascript/resource.h b/fpdfsdk/src/javascript/resource.h
new file mode 100644
index 0000000..fcefcd4
--- /dev/null
+++ b/fpdfsdk/src/javascript/resource.h
@@ -0,0 +1,39 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FPDFSDK_SRC_JAVASCRIPT_RESOURCE_H_
+#define FPDFSDK_SRC_JAVASCRIPT_RESOURCE_H_
+
+#include "../../../core/include/fxcrt/fx_string.h"  // For CFX_WideString.
+#include "../../include/fsdk_define.h"              // For FX_UINT.
+
+class CJS_Context;
+
+#define IDS_STRING_JSALERT 25613
+#define IDS_STRING_JSPARAMERROR 25614
+#define IDS_STRING_JSAFNUMBER_KEYSTROKE 25615
+#define IDS_STRING_JSPARAM_TOOLONG 25617
+#define IDS_STRING_JSPARSEDATE 25618
+#define IDS_STRING_JSRANGE1 25619
+#define IDS_STRING_JSRANGE2 25620
+#define IDS_STRING_JSRANGE3 25621
+#define IDS_STRING_NOTSUPPORT 25627
+#define IDS_STRING_JSBUSY 25628
+#define IDS_STRING_JSEVENT 25629
+#define IDS_STRING_RUN 25630
+#define IDS_STRING_JSPRINT1 25632
+#define IDS_STRING_JSPRINT2 25633
+#define IDS_STRING_JSNOGLOBAL 25635
+#define IDS_STRING_JSREADONLY 25636
+#define IDS_STRING_JSTYPEERROR 25637
+#define IDS_STRING_JSVALUEERROR 25638
+
+CFX_WideString JSGetStringFromID(CJS_Context* pContext, FX_UINT id);
+CFX_WideString JSFormatErrorString(const char* class_name,
+                                   const char* property_name,
+                                   const CFX_WideString& details);
+
+#endif  // FPDFSDK_SRC_JAVASCRIPT_RESOURCE_H_
diff --git a/fpdfsdk/src/javascript/util.cpp b/fpdfsdk/src/javascript/util.cpp
index 6afddf7..c83aa6f 100644
--- a/fpdfsdk/src/javascript/util.cpp
+++ b/fpdfsdk/src/javascript/util.cpp
@@ -4,16 +4,17 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
+#include "util.h"
+
 #include "../../include/javascript/IJavaScript.h"
-#include "../../include/javascript/JS_Define.h"
-#include "../../include/javascript/JS_Object.h"
-#include "../../include/javascript/JS_Value.h"
-#include "../../include/javascript/util.h"
-#include "../../include/javascript/PublicMethods.h"
-#include "../../include/javascript/resource.h"
-#include "../../include/javascript/JS_Context.h"
-#include "../../include/javascript/JS_EventHandler.h"
-#include "../../include/javascript/JS_Runtime.h"
+#include "JS_Context.h"
+#include "JS_Define.h"
+#include "JS_EventHandler.h"
+#include "JS_Object.h"
+#include "JS_Runtime.h"
+#include "JS_Value.h"
+#include "PublicMethods.h"
+#include "resource.h"
 
 #if _FX_OS_ == _FX_ANDROID_
 #include <ctype.h>
diff --git a/fpdfsdk/src/javascript/util.h b/fpdfsdk/src/javascript/util.h
new file mode 100644
index 0000000..c88462c
--- /dev/null
+++ b/fpdfsdk/src/javascript/util.h
@@ -0,0 +1,68 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FPDFSDK_SRC_JAVASCRIPT_UTIL_H_
+#define FPDFSDK_SRC_JAVASCRIPT_UTIL_H_
+
+#include <string>  // For std::wstring.
+
+#include "JS_Define.h"
+
+class util : public CJS_EmbedObj {
+ public:
+  util(CJS_Object* pJSObject);
+  ~util() override;
+
+ public:
+  FX_BOOL printd(IFXJS_Context* cc,
+                 const CJS_Parameters& params,
+                 CJS_Value& vRet,
+                 CFX_WideString& sError);
+  FX_BOOL printf(IFXJS_Context* cc,
+                 const CJS_Parameters& params,
+                 CJS_Value& vRet,
+                 CFX_WideString& sError);
+  FX_BOOL printx(IFXJS_Context* cc,
+                 const CJS_Parameters& params,
+                 CJS_Value& vRet,
+                 CFX_WideString& sError);
+  FX_BOOL scand(IFXJS_Context* cc,
+                const CJS_Parameters& params,
+                CJS_Value& vRet,
+                CFX_WideString& sError);
+  FX_BOOL byteToChar(IFXJS_Context* cc,
+                     const CJS_Parameters& params,
+                     CJS_Value& vRet,
+                     CFX_WideString& sError);
+
+ public:
+  static void printd(const std::wstring& cFormat,
+                     CJS_Date Date,
+                     bool bXFAPicture,
+                     std::wstring& cPurpose);
+  static void printx(const std::string& cFormat,
+                     const std::string& cSource,
+                     std::string& cPurpose);
+  static int ParstDataType(std::wstring* sFormat);
+};
+
+class CJS_Util : public CJS_Object {
+ public:
+  CJS_Util(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
+  ~CJS_Util() override {}
+
+  DECLARE_JS_CLASS(CJS_Util);
+
+  JS_STATIC_METHOD(printd, util);
+  JS_STATIC_METHOD(printf, util);
+  JS_STATIC_METHOD(printx, util);
+  JS_STATIC_METHOD(scand, util);
+  JS_STATIC_METHOD(byteToChar, util);
+};
+
+int64_t FX_atoi64(const char* nptr);
+
+#endif  // FPDFSDK_SRC_JAVASCRIPT_UTIL_H_