use std::vector in more places in JavaScript bindings code.
use unique_ptrs for app:m_Timers.

BUG=

Review URL: https://codereview.chromium.org/1834203002
diff --git a/fpdfsdk/javascript/Field.cpp b/fpdfsdk/javascript/Field.cpp
index 4ac7081..54b4f643 100644
--- a/fpdfsdk/javascript/Field.cpp
+++ b/fpdfsdk/javascript/Field.cpp
@@ -947,12 +947,11 @@
     if (!m_bCanSet)
       return FALSE;
 
-    CFX_ArrayTemplate<uint32_t> array;
-
+    std::vector<uint32_t> array;
     if (vp.GetType() == CJS_Value::VT_number) {
       int iSelecting = 0;
       vp >> iSelecting;
-      array.Add(iSelecting);
+      array.push_back(iSelecting);
     } else if (vp.IsArrayObject()) {
       CJS_Array SelArray(pRuntime);
       CJS_Value SelValue(pRuntime);
@@ -961,7 +960,7 @@
       for (int i = 0, sz = SelArray.GetLength(); i < sz; i++) {
         SelArray.GetElement(i, SelValue);
         iSelecting = SelValue.ToInt();
-        array.Add(iSelecting);
+        array.push_back(iSelecting);
       }
     }
 
@@ -1002,26 +1001,23 @@
 void Field::SetCurrentValueIndices(CPDFSDK_Document* pDocument,
                                    const CFX_WideString& swFieldName,
                                    int nControlIndex,
-                                   const CFX_ArrayTemplate<uint32_t>& array) {
+                                   const std::vector<uint32_t>& array) {
   ASSERT(pDocument);
-
   std::vector<CPDF_FormField*> FieldArray =
       GetFormFields(pDocument, swFieldName);
+
   for (CPDF_FormField* pFormField : FieldArray) {
     int nFieldType = pFormField->GetFieldType();
     if (nFieldType == FIELDTYPE_COMBOBOX || nFieldType == FIELDTYPE_LISTBOX) {
       uint32_t dwFieldFlags = pFormField->GetFieldFlags();
       pFormField->ClearSelection(TRUE);
-
-      for (int i = 0, sz = array.GetSize(); i < sz; i++) {
-        if (i > 0 && !(dwFieldFlags & (1 << 21))) {
+      for (size_t i = 0; i < array.size(); ++i) {
+        if (i != 0 && !(dwFieldFlags & (1 << 21)))
           break;
+        if (array[i] < pFormField->CountOptions() &&
+            !pFormField->IsItemSelected(array[i])) {
+          pFormField->SetItemSelection(array[i], TRUE);
         }
-
-        int iSelecting = (int32_t)array.GetAt(i);
-        if (iSelecting < pFormField->CountOptions() &&
-            !pFormField->IsItemSelected(iSelecting))
-          pFormField->SetItemSelection(iSelecting, TRUE);
       }
       UpdateFormField(pDocument, pFormField, TRUE, TRUE, TRUE);
     }
@@ -2712,20 +2708,19 @@
     if (!m_bCanSet)
       return FALSE;
 
-    CJS_WideStringArray strArray;
-
+    std::vector<CFX_WideString> strArray;
     if (vp.IsArrayObject()) {
       CJS_Array ValueArray(pRuntime);
       vp.ConvertToArray(ValueArray);
       for (int i = 0, sz = ValueArray.GetLength(); i < sz; i++) {
         CJS_Value ElementValue(pRuntime);
         ValueArray.GetElement(i, ElementValue);
-        strArray.Add(ElementValue.ToCFXWideString());
+        strArray.push_back(ElementValue.ToCFXWideString());
       }
     } else {
       CFX_WideString swValue;
       vp >> swValue;
-      strArray.Add(swValue);
+      strArray.push_back(swValue);
     }
 
     if (m_bDelay) {
@@ -2788,10 +2783,9 @@
 void Field::SetValue(CPDFSDK_Document* pDocument,
                      const CFX_WideString& swFieldName,
                      int nControlIndex,
-                     const CJS_WideStringArray& strArray) {
+                     const std::vector<CFX_WideString>& strArray) {
   ASSERT(pDocument);
-
-  if (strArray.GetSize() < 1)
+  if (strArray.empty())
     return;
 
   std::vector<CPDF_FormField*> FieldArray =
@@ -2804,38 +2798,33 @@
     switch (pFormField->GetFieldType()) {
       case FIELDTYPE_TEXTFIELD:
       case FIELDTYPE_COMBOBOX:
-        if (pFormField->GetValue() != strArray.GetAt(0)) {
-          CFX_WideString WideString = strArray.GetAt(0);
-          pFormField->SetValue(strArray.GetAt(0), TRUE);
+        if (pFormField->GetValue() != strArray[0]) {
+          pFormField->SetValue(strArray[0], TRUE);
           UpdateFormField(pDocument, pFormField, TRUE, FALSE, TRUE);
         }
         break;
-      case FIELDTYPE_CHECKBOX:  // mantis: 0004493
+      case FIELDTYPE_CHECKBOX:
       case FIELDTYPE_RADIOBUTTON: {
-        if (pFormField->GetValue() != strArray.GetAt(0)) {
-          pFormField->SetValue(strArray.GetAt(0), TRUE);
+        if (pFormField->GetValue() != strArray[0]) {
+          pFormField->SetValue(strArray[0], TRUE);
           UpdateFormField(pDocument, pFormField, TRUE, FALSE, TRUE);
         }
       } break;
       case FIELDTYPE_LISTBOX: {
         FX_BOOL bModified = FALSE;
-
-        for (int i = 0, sz = strArray.GetSize(); i < sz; i++) {
-          int iIndex = pFormField->FindOption(strArray.GetAt(i));
-
-          if (!pFormField->IsItemSelected(iIndex)) {
+        for (const auto& str : strArray) {
+          if (!pFormField->IsItemSelected(pFormField->FindOption(str))) {
             bModified = TRUE;
             break;
           }
         }
-
         if (bModified) {
           pFormField->ClearSelection(TRUE);
-          for (int i = 0, sz = strArray.GetSize(); i < sz; i++) {
-            int iIndex = pFormField->FindOption(strArray.GetAt(i));
-            pFormField->SetItemSelection(iIndex, TRUE, TRUE);
+          for (const auto& str : strArray) {
+            int index = pFormField->FindOption(str);
+            if (!pFormField->IsItemSelected(index))
+              pFormField->SetItemSelection(index, TRUE, TRUE);
           }
-
           UpdateFormField(pDocument, pFormField, TRUE, FALSE, TRUE);
         }
       } break;
@@ -3365,96 +3354,66 @@
   return TRUE;
 }
 
-void Field::AddDelay_Int(enum FIELD_PROP prop, int32_t n) {
-  CJS_DelayData* pNewData = new CJS_DelayData;
-  pNewData->sFieldName = m_FieldName;
-  pNewData->nControlIndex = m_nFormControlIndex;
-  pNewData->eProp = prop;
+void Field::AddDelay_Int(FIELD_PROP prop, int32_t n) {
+  CJS_DelayData* pNewData =
+      new CJS_DelayData(prop, m_nFormControlIndex, m_FieldName);
   pNewData->num = n;
-
   m_pJSDoc->AddDelayData(pNewData);
 }
 
-void Field::AddDelay_Bool(enum FIELD_PROP prop, bool b) {
-  CJS_DelayData* pNewData = new CJS_DelayData;
-  pNewData->sFieldName = m_FieldName;
-  pNewData->nControlIndex = m_nFormControlIndex;
-  pNewData->eProp = prop;
+void Field::AddDelay_Bool(FIELD_PROP prop, bool b) {
+  CJS_DelayData* pNewData =
+      new CJS_DelayData(prop, m_nFormControlIndex, m_FieldName);
   pNewData->b = b;
-
   m_pJSDoc->AddDelayData(pNewData);
 }
 
-void Field::AddDelay_String(enum FIELD_PROP prop,
-                            const CFX_ByteString& string) {
-  CJS_DelayData* pNewData = new CJS_DelayData;
-  pNewData->sFieldName = m_FieldName;
-  pNewData->nControlIndex = m_nFormControlIndex;
-  pNewData->eProp = prop;
+void Field::AddDelay_String(FIELD_PROP prop, const CFX_ByteString& string) {
+  CJS_DelayData* pNewData =
+      new CJS_DelayData(prop, m_nFormControlIndex, m_FieldName);
   pNewData->string = string;
-
   m_pJSDoc->AddDelayData(pNewData);
 }
 
-void Field::AddDelay_WideString(enum FIELD_PROP prop,
-                                const CFX_WideString& string) {
-  CJS_DelayData* pNewData = new CJS_DelayData;
-  pNewData->sFieldName = m_FieldName;
-  pNewData->nControlIndex = m_nFormControlIndex;
-  pNewData->eProp = prop;
+void Field::AddDelay_WideString(FIELD_PROP prop, const CFX_WideString& string) {
+  CJS_DelayData* pNewData =
+      new CJS_DelayData(prop, m_nFormControlIndex, m_FieldName);
   pNewData->widestring = string;
-
   m_pJSDoc->AddDelayData(pNewData);
 }
 
-void Field::AddDelay_Rect(enum FIELD_PROP prop, const CFX_FloatRect& rect) {
-  CJS_DelayData* pNewData = new CJS_DelayData;
-  pNewData->sFieldName = m_FieldName;
-  pNewData->nControlIndex = m_nFormControlIndex;
-  pNewData->eProp = prop;
+void Field::AddDelay_Rect(FIELD_PROP prop, const CFX_FloatRect& rect) {
+  CJS_DelayData* pNewData =
+      new CJS_DelayData(prop, m_nFormControlIndex, m_FieldName);
   pNewData->rect = rect;
-
   m_pJSDoc->AddDelayData(pNewData);
 }
 
-void Field::AddDelay_Color(enum FIELD_PROP prop, const CPWL_Color& color) {
-  CJS_DelayData* pNewData = new CJS_DelayData;
-  pNewData->sFieldName = m_FieldName;
-  pNewData->nControlIndex = m_nFormControlIndex;
-  pNewData->eProp = prop;
+void Field::AddDelay_Color(FIELD_PROP prop, const CPWL_Color& color) {
+  CJS_DelayData* pNewData =
+      new CJS_DelayData(prop, m_nFormControlIndex, m_FieldName);
   pNewData->color = color;
-
   m_pJSDoc->AddDelayData(pNewData);
 }
 
-void Field::AddDelay_WordArray(enum FIELD_PROP prop,
-                               const CFX_ArrayTemplate<uint32_t>& array) {
-  CJS_DelayData* pNewData = new CJS_DelayData;
-  pNewData->sFieldName = m_FieldName;
-  pNewData->nControlIndex = m_nFormControlIndex;
-  pNewData->eProp = prop;
-
-  for (int i = 0, sz = array.GetSize(); i < sz; i++)
-    pNewData->wordarray.Add(array.GetAt(i));
-
+void Field::AddDelay_WordArray(FIELD_PROP prop,
+                               const std::vector<uint32_t>& array) {
+  CJS_DelayData* pNewData =
+      new CJS_DelayData(prop, m_nFormControlIndex, m_FieldName);
+  pNewData->wordarray = array;
   m_pJSDoc->AddDelayData(pNewData);
 }
 
-void Field::AddDelay_WideStringArray(enum FIELD_PROP prop,
-                                     const CJS_WideStringArray& array) {
-  CJS_DelayData* pNewData = new CJS_DelayData;
-  pNewData->sFieldName = m_FieldName;
-  pNewData->nControlIndex = m_nFormControlIndex;
-  pNewData->eProp = prop;
-  for (int i = 0, sz = array.GetSize(); i < sz; i++)
-    pNewData->widestringarray.Add(array.GetAt(i));
-
+void Field::AddDelay_WideStringArray(FIELD_PROP prop,
+                                     const std::vector<CFX_WideString>& array) {
+  CJS_DelayData* pNewData =
+      new CJS_DelayData(prop, m_nFormControlIndex, m_FieldName);
+  pNewData->widestringarray = array;
   m_pJSDoc->AddDelayData(pNewData);
 }
 
 void Field::DoDelay(CPDFSDK_Document* pDocument, CJS_DelayData* pData) {
   ASSERT(pDocument);
-
   switch (pData->eProp) {
     case FP_ALIGNMENT:
       Field::SetAlignment(pDocument, pData->sFieldName, pData->nControlIndex,
diff --git a/fpdfsdk/javascript/Field.h b/fpdfsdk/javascript/Field.h
index 5f5be10..f5a7e1b 100644
--- a/fpdfsdk/javascript/Field.h
+++ b/fpdfsdk/javascript/Field.h
@@ -53,39 +53,21 @@
   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;
+  CJS_DelayData(FIELD_PROP prop, int idx, const CFX_WideString& name)
+      : eProp(prop), nControlIndex(idx), sFieldName(name) {}
+
+  FIELD_PROP eProp;
   int nControlIndex;
-  enum FIELD_PROP eProp;
+  CFX_WideString sFieldName;
   int32_t num;
   bool b;
   CFX_ByteString string;
   CFX_WideString widestring;
   CFX_FloatRect rect;
   CPWL_Color color;
-  CFX_ArrayTemplate<uint32_t> wordarray;
-  CJS_WideStringArray widestringarray;
+  std::vector<uint32_t> wordarray;
+  std::vector<CFX_WideString> widestringarray;
 };
 
 class Field : public CJS_EmbedObj {
@@ -344,7 +326,7 @@
   static void SetCurrentValueIndices(CPDFSDK_Document* pDocument,
                                      const CFX_WideString& swFieldName,
                                      int nControlIndex,
-                                     const CFX_ArrayTemplate<uint32_t>& array);
+                                     const std::vector<uint32_t>& array);
   static void SetDefaultStyle(CPDFSDK_Document* pDocument,
                               const CFX_WideString& swFieldName,
                               int nControlIndex);
@@ -430,7 +412,7 @@
   static void SetValue(CPDFSDK_Document* pDocument,
                        const CFX_WideString& swFieldName,
                        int nControlIndex,
-                       const CJS_WideStringArray& strArray);
+                       const std::vector<CFX_WideString>& strArray);
 
   static void AddField(CPDFSDK_Document* pDocument,
                        int nPageIndex,
@@ -470,16 +452,15 @@
   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 CFX_FloatRect& rect);
-  void AddDelay_Color(enum FIELD_PROP prop, const CPWL_Color& color);
-  void AddDelay_WordArray(enum FIELD_PROP prop,
-                          const CFX_ArrayTemplate<uint32_t>& array);
-  void AddDelay_WideStringArray(enum FIELD_PROP prop,
-                                const CJS_WideStringArray& array);
+  void AddDelay_Int(FIELD_PROP prop, int32_t n);
+  void AddDelay_Bool(FIELD_PROP prop, bool b);
+  void AddDelay_String(FIELD_PROP prop, const CFX_ByteString& string);
+  void AddDelay_WideString(FIELD_PROP prop, const CFX_WideString& string);
+  void AddDelay_Rect(FIELD_PROP prop, const CFX_FloatRect& rect);
+  void AddDelay_Color(FIELD_PROP prop, const CPWL_Color& color);
+  void AddDelay_WordArray(FIELD_PROP prop, const std::vector<uint32_t>& array);
+  void AddDelay_WideStringArray(FIELD_PROP prop,
+                                const std::vector<CFX_WideString>& array);
 
   void DoDelay();
 
diff --git a/fpdfsdk/javascript/JS_GlobalData.cpp b/fpdfsdk/javascript/JS_GlobalData.cpp
index 2c2ec1d..3a9e521 100644
--- a/fpdfsdk/javascript/JS_GlobalData.cpp
+++ b/fpdfsdk/javascript/JS_GlobalData.cpp
@@ -8,6 +8,7 @@
 
 #include "core/fdrm/crypto/include/fx_crypt.h"
 #include "fpdfsdk/include/javascript/IJavaScript.h"
+#include "third_party/base/stl_util.h"
 
 #define JS_MAXGLOBALDATA (1024 * 4 - 8)
 
@@ -97,6 +98,15 @@
     0x0e, 0xd0, 0x6b, 0xbb, 0xd5, 0x75, 0x55, 0x8b, 0x6e, 0x6b, 0x19, 0xa0,
     0xf8, 0x77, 0xd5, 0xa3};
 
+// Returns true if non-empty, setting sPropName
+static bool TrimPropName(const char* propname, CFX_ByteString* sPropName) {
+  ASSERT(propname);
+  *sPropName = propname;
+  sPropName->TrimLeft();
+  sPropName->TrimRight();
+  return sPropName->GetLength() != 0;
+}
+
 CJS_GlobalData* CJS_GlobalData::g_Instance = nullptr;
 
 // static
@@ -115,197 +125,164 @@
   }
 }
 
-CJS_GlobalData::CJS_GlobalData() : m_RefCount(0) {
-  m_sFilePath += SDK_JS_GLOBALDATA_FILENAME;
+CJS_GlobalData::CJS_GlobalData()
+    : m_RefCount(0), m_sFilePath(SDK_JS_GLOBALDATA_FILENAME) {
   LoadGlobalPersistentVariables();
 }
 
 CJS_GlobalData::~CJS_GlobalData() {
   SaveGlobalPersisitentVariables();
-  for (int i = 0, sz = m_arrayGlobalData.GetSize(); i < sz; i++)
-    delete m_arrayGlobalData.GetAt(i);
-
-  m_arrayGlobalData.RemoveAll();
 }
 
-int CJS_GlobalData::FindGlobalVariable(const FX_CHAR* propname) {
-  for (int i = 0, sz = m_arrayGlobalData.GetSize(); i < sz; i++) {
-    CJS_GlobalData_Element* pTemp = m_arrayGlobalData.GetAt(i);
-    if (pTemp->data.sKey[0] == *propname && pTemp->data.sKey == propname)
-      return i;
+CJS_GlobalData::iterator CJS_GlobalData::FindGlobalVariable(
+    const FX_CHAR* propname) {
+  for (auto it = m_arrayGlobalData.begin(); it != m_arrayGlobalData.end();
+       ++it) {
+    if ((*it)->data.sKey == propname)
+      return it;
   }
-  return -1;
+  return m_arrayGlobalData.end();
+}
+
+CJS_GlobalData::const_iterator CJS_GlobalData::FindGlobalVariable(
+    const FX_CHAR* propname) const {
+  for (auto it = m_arrayGlobalData.begin(); it != m_arrayGlobalData.end();
+       ++it) {
+    if ((*it)->data.sKey == propname)
+      return it;
+  }
+  return m_arrayGlobalData.end();
 }
 
 CJS_GlobalData_Element* CJS_GlobalData::GetGlobalVariable(
     const FX_CHAR* propname) {
-  ASSERT(propname);
-
-  int nFind = FindGlobalVariable(propname);
-  return nFind >= 0 ? m_arrayGlobalData.GetAt(nFind) : nullptr;
+  auto iter = FindGlobalVariable(propname);
+  return iter != m_arrayGlobalData.end() ? iter->get() : nullptr;
 }
 
 void CJS_GlobalData::SetGlobalVariableNumber(const FX_CHAR* propname,
                                              double dData) {
-  ASSERT(propname);
-  CFX_ByteString sPropName = propname;
-  sPropName.TrimLeft();
-  sPropName.TrimRight();
-  if (sPropName.GetLength() == 0)
+  CFX_ByteString sPropName;
+  if (!TrimPropName(propname, &sPropName))
     return;
 
   if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName)) {
     pData->data.nType = JS_GLOBALDATA_TYPE_NUMBER;
     pData->data.dData = dData;
-  } else {
-    CJS_GlobalData_Element* pNewData = new CJS_GlobalData_Element;
-    pNewData->data.sKey = sPropName;
-    pNewData->data.nType = JS_GLOBALDATA_TYPE_NUMBER;
-    pNewData->data.dData = dData;
-    m_arrayGlobalData.Add(pNewData);
+    return;
   }
+  std::unique_ptr<CJS_GlobalData_Element> pNewData(new CJS_GlobalData_Element);
+  pNewData->data.sKey = sPropName;
+  pNewData->data.nType = JS_GLOBALDATA_TYPE_NUMBER;
+  pNewData->data.dData = dData;
+  m_arrayGlobalData.push_back(std::move(pNewData));
 }
 
 void CJS_GlobalData::SetGlobalVariableBoolean(const FX_CHAR* propname,
                                               bool bData) {
-  ASSERT(propname);
-  CFX_ByteString sPropName = propname;
-
-  sPropName.TrimLeft();
-  sPropName.TrimRight();
-
-  if (sPropName.GetLength() == 0)
+  CFX_ByteString sPropName;
+  if (!TrimPropName(propname, &sPropName))
     return;
 
   if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName)) {
     pData->data.nType = JS_GLOBALDATA_TYPE_BOOLEAN;
     pData->data.bData = bData;
-  } else {
-    CJS_GlobalData_Element* pNewData = new CJS_GlobalData_Element;
-    pNewData->data.sKey = sPropName;
-    pNewData->data.nType = JS_GLOBALDATA_TYPE_BOOLEAN;
-    pNewData->data.bData = bData;
-
-    m_arrayGlobalData.Add(pNewData);
+    return;
   }
+  std::unique_ptr<CJS_GlobalData_Element> pNewData(new CJS_GlobalData_Element);
+  pNewData->data.sKey = sPropName;
+  pNewData->data.nType = JS_GLOBALDATA_TYPE_BOOLEAN;
+  pNewData->data.bData = bData;
+  m_arrayGlobalData.push_back(std::move(pNewData));
 }
 
 void CJS_GlobalData::SetGlobalVariableString(const FX_CHAR* propname,
                                              const CFX_ByteString& sData) {
-  ASSERT(propname);
-  CFX_ByteString sPropName = propname;
-
-  sPropName.TrimLeft();
-  sPropName.TrimRight();
-
-  if (sPropName.GetLength() == 0)
+  CFX_ByteString sPropName;
+  if (!TrimPropName(propname, &sPropName))
     return;
 
   if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName)) {
     pData->data.nType = JS_GLOBALDATA_TYPE_STRING;
     pData->data.sData = sData;
-  } else {
-    CJS_GlobalData_Element* pNewData = new CJS_GlobalData_Element;
-    pNewData->data.sKey = sPropName;
-    pNewData->data.nType = JS_GLOBALDATA_TYPE_STRING;
-    pNewData->data.sData = sData;
-
-    m_arrayGlobalData.Add(pNewData);
+    return;
   }
+  std::unique_ptr<CJS_GlobalData_Element> pNewData(new CJS_GlobalData_Element);
+  pNewData->data.sKey = sPropName;
+  pNewData->data.nType = JS_GLOBALDATA_TYPE_STRING;
+  pNewData->data.sData = sData;
+  m_arrayGlobalData.push_back(std::move(pNewData));
 }
 
 void CJS_GlobalData::SetGlobalVariableObject(
     const FX_CHAR* propname,
     const CJS_GlobalVariableArray& array) {
-  ASSERT(propname);
-  CFX_ByteString sPropName = propname;
-
-  sPropName.TrimLeft();
-  sPropName.TrimRight();
-
-  if (sPropName.GetLength() == 0)
+  CFX_ByteString sPropName;
+  if (!TrimPropName(propname, &sPropName))
     return;
 
   if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName)) {
     pData->data.nType = JS_GLOBALDATA_TYPE_OBJECT;
     pData->data.objData.Copy(array);
-  } else {
-    CJS_GlobalData_Element* pNewData = new CJS_GlobalData_Element;
-    pNewData->data.sKey = sPropName;
-    pNewData->data.nType = JS_GLOBALDATA_TYPE_OBJECT;
-    pNewData->data.objData.Copy(array);
-
-    m_arrayGlobalData.Add(pNewData);
+    return;
   }
+  std::unique_ptr<CJS_GlobalData_Element> pNewData(new CJS_GlobalData_Element);
+  pNewData->data.sKey = sPropName;
+  pNewData->data.nType = JS_GLOBALDATA_TYPE_OBJECT;
+  pNewData->data.objData.Copy(array);
+  m_arrayGlobalData.push_back(std::move(pNewData));
 }
 
 void CJS_GlobalData::SetGlobalVariableNull(const FX_CHAR* propname) {
-  ASSERT(propname);
-  CFX_ByteString sPropName = propname;
-
-  sPropName.TrimLeft();
-  sPropName.TrimRight();
-
-  if (sPropName.GetLength() == 0)
+  CFX_ByteString sPropName;
+  if (!TrimPropName(propname, &sPropName))
     return;
 
   if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName)) {
     pData->data.nType = JS_GLOBALDATA_TYPE_NULL;
-  } else {
-    CJS_GlobalData_Element* pNewData = new CJS_GlobalData_Element;
-    pNewData->data.sKey = sPropName;
-    pNewData->data.nType = JS_GLOBALDATA_TYPE_NULL;
-
-    m_arrayGlobalData.Add(pNewData);
+    return;
   }
+  std::unique_ptr<CJS_GlobalData_Element> pNewData(new CJS_GlobalData_Element);
+  pNewData->data.sKey = sPropName;
+  pNewData->data.nType = JS_GLOBALDATA_TYPE_NULL;
+  m_arrayGlobalData.push_back(std::move(pNewData));
 }
 
 FX_BOOL CJS_GlobalData::SetGlobalVariablePersistent(const FX_CHAR* propname,
                                                     FX_BOOL bPersistent) {
-  ASSERT(propname);
-  CFX_ByteString sPropName = propname;
-
-  sPropName.TrimLeft();
-  sPropName.TrimRight();
-
-  if (sPropName.GetLength() == 0)
+  CFX_ByteString sPropName;
+  if (!TrimPropName(propname, &sPropName))
     return FALSE;
 
-  if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName)) {
-    pData->bPersistent = bPersistent;
-    return TRUE;
-  }
+  CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName);
+  if (!pData)
+    return FALSE;
 
-  return FALSE;
+  pData->bPersistent = bPersistent;
+  return TRUE;
 }
 
 FX_BOOL CJS_GlobalData::DeleteGlobalVariable(const FX_CHAR* propname) {
-  ASSERT(propname);
-  CFX_ByteString sPropName = propname;
-
-  sPropName.TrimLeft();
-  sPropName.TrimRight();
-
-  if (sPropName.GetLength() == 0)
+  CFX_ByteString sPropName;
+  if (!TrimPropName(propname, &sPropName))
     return FALSE;
 
-  int nFind = FindGlobalVariable(sPropName);
+  auto iter = FindGlobalVariable(sPropName);
+  if (iter == m_arrayGlobalData.end())
+    return FALSE;
 
-  if (nFind >= 0) {
-    delete m_arrayGlobalData.GetAt(nFind);
-    m_arrayGlobalData.RemoveAt(nFind);
-    return TRUE;
-  }
-
-  return FALSE;
+  m_arrayGlobalData.erase(iter);
+  return TRUE;
 }
 
 int32_t CJS_GlobalData::GetSize() const {
-  return m_arrayGlobalData.GetSize();
+  return pdfium::CollectionSize<int32_t>(m_arrayGlobalData);
 }
 
 CJS_GlobalData_Element* CJS_GlobalData::GetAt(int index) const {
-  return m_arrayGlobalData.GetAt(index);
+  if (index < 0 || index >= GetSize())
+    return nullptr;
+  return m_arrayGlobalData[index].get();
 }
 
 void CJS_GlobalData::LoadGlobalPersistentVariables() {
@@ -400,13 +377,10 @@
 void CJS_GlobalData::SaveGlobalPersisitentVariables() {
   uint32_t nCount = 0;
   CFX_BinaryBuf sData;
-
-  for (int i = 0, sz = m_arrayGlobalData.GetSize(); i < sz; i++) {
-    CJS_GlobalData_Element* pElement = m_arrayGlobalData.GetAt(i);
+  for (const auto& pElement : m_arrayGlobalData) {
     if (pElement->bPersistent) {
       CFX_BinaryBuf sElement;
       MakeByteString(pElement->data.sKey, &pElement->data, sElement);
-
       if (sData.GetSize() + sElement.GetSize() > JS_MAXGLOBALDATA)
         break;
 
@@ -416,7 +390,6 @@
   }
 
   CFX_BinaryBuf sFile;
-
   uint16_t wType = (uint16_t)(('X' << 8) | 'F');
   sFile.AppendBlock(&wType, sizeof(uint16_t));
   uint16_t wVersion = 2;
diff --git a/fpdfsdk/javascript/JS_GlobalData.h b/fpdfsdk/javascript/JS_GlobalData.h
index 24c0abf..65bb921 100644
--- a/fpdfsdk/javascript/JS_GlobalData.h
+++ b/fpdfsdk/javascript/JS_GlobalData.h
@@ -7,6 +7,9 @@
 #ifndef FPDFSDK_JAVASCRIPT_JS_GLOBALDATA_H_
 #define FPDFSDK_JAVASCRIPT_JS_GLOBALDATA_H_
 
+#include <memory>
+#include <vector>
+
 #include "core/fxcrt/include/fx_basic.h"
 
 #define JS_GLOBALDATA_TYPE_NUMBER 0
@@ -77,6 +80,11 @@
   CJS_GlobalData_Element* GetAt(int index) const;
 
  private:
+  using iterator =
+      std::vector<std::unique_ptr<CJS_GlobalData_Element>>::iterator;
+  using const_iterator =
+      std::vector<std::unique_ptr<CJS_GlobalData_Element>>::const_iterator;
+
   static CJS_GlobalData* g_Instance;
 
   CJS_GlobalData();
@@ -86,7 +94,8 @@
   void SaveGlobalPersisitentVariables();
 
   CJS_GlobalData_Element* GetGlobalVariable(const FX_CHAR* propname);
-  int FindGlobalVariable(const FX_CHAR* propname);
+  iterator FindGlobalVariable(const FX_CHAR* propname);
+  const_iterator FindGlobalVariable(const FX_CHAR* propname) const;
 
   void LoadFileBuffer(const FX_WCHAR* sFilePath,
                       uint8_t*& pBuffer,
@@ -99,7 +108,7 @@
                       CFX_BinaryBuf& sData);
 
   size_t m_RefCount;
-  CFX_ArrayTemplate<CJS_GlobalData_Element*> m_arrayGlobalData;
+  std::vector<std::unique_ptr<CJS_GlobalData_Element>> m_arrayGlobalData;
   CFX_WideString m_sFilePath;
 };
 
diff --git a/fpdfsdk/javascript/JS_Runtime.cpp b/fpdfsdk/javascript/JS_Runtime.cpp
index 208348f..44fb340 100644
--- a/fpdfsdk/javascript/JS_Runtime.cpp
+++ b/fpdfsdk/javascript/JS_Runtime.cpp
@@ -6,6 +6,8 @@
 
 #include "fpdfsdk/javascript/JS_Runtime.h"
 
+#include <algorithm>
+
 #include "fpdfsdk/include/fsdk_mgr.h"  // For CPDFDoc_Environment.
 #include "fpdfsdk/include/javascript/IJavaScript.h"
 #include "fpdfsdk/javascript/Consts.h"
@@ -117,17 +119,10 @@
   for (auto* obs : m_observers)
     obs->OnDestroyed();
 
-  for (int i = 0, sz = m_ContextArray.GetSize(); i < sz; i++)
-    delete m_ContextArray.GetAt(i);
-
-  m_ContextArray.RemoveAll();
+  m_ContextArray.clear();
   m_ConstArrays.clear();
   FXJS_ReleaseRuntime(GetIsolate(), &m_context, &m_StaticObjects);
-
-  m_pApp = NULL;
-  m_pDocument = NULL;
   m_context.Reset();
-
   if (m_isolateManaged)
     m_isolate->Dispose();
 }
@@ -183,27 +178,21 @@
 }
 
 IJS_Context* CJS_Runtime::NewContext() {
-  CJS_Context* p = new CJS_Context(this);
-  m_ContextArray.Add(p);
-  return p;
+  m_ContextArray.push_back(std::unique_ptr<CJS_Context>(new CJS_Context(this)));
+  return m_ContextArray.back().get();
 }
 
 void CJS_Runtime::ReleaseContext(IJS_Context* pContext) {
-  CJS_Context* pJSContext = (CJS_Context*)pContext;
-
-  for (int i = 0, sz = m_ContextArray.GetSize(); i < sz; i++) {
-    if (pJSContext == m_ContextArray.GetAt(i)) {
-      delete pJSContext;
-      m_ContextArray.RemoveAt(i);
-      break;
+  for (auto it = m_ContextArray.begin(); it != m_ContextArray.end(); ++it) {
+    if (it->get() == static_cast<CJS_Context*>(pContext)) {
+      m_ContextArray.erase(it);
+      return;
     }
   }
 }
 
 IJS_Context* CJS_Runtime::GetCurrentContext() {
-  if (!m_ContextArray.GetSize())
-    return NULL;
-  return m_ContextArray.GetAt(m_ContextArray.GetSize() - 1);
+  return m_ContextArray.empty() ? nullptr : m_ContextArray.back().get();
 }
 
 void CJS_Runtime::SetReaderDocument(CPDFSDK_Document* pReaderDoc) {
diff --git a/fpdfsdk/javascript/JS_Runtime.h b/fpdfsdk/javascript/JS_Runtime.h
index fa13273..68dfb5b 100644
--- a/fpdfsdk/javascript/JS_Runtime.h
+++ b/fpdfsdk/javascript/JS_Runtime.h
@@ -8,6 +8,7 @@
 #define FPDFSDK_JAVASCRIPT_JS_RUNTIME_H_
 
 #include <map>
+#include <memory>
 #include <set>
 #include <utility>
 #include <vector>
@@ -75,8 +76,8 @@
  private:
   void DefineJSObjects();
 
-  CFX_ArrayTemplate<CJS_Context*> m_ContextArray;
-  CPDFDoc_Environment* m_pApp;
+  std::vector<std::unique_ptr<CJS_Context>> m_ContextArray;
+  CPDFDoc_Environment* const m_pApp;
   CPDFSDK_Document* m_pDocument;
   FX_BOOL m_bBlocking;
   std::set<FieldEvent> m_FieldEventSet;
diff --git a/fpdfsdk/javascript/app.cpp b/fpdfsdk/javascript/app.cpp
index 41fa152..8383675 100644
--- a/fpdfsdk/javascript/app.cpp
+++ b/fpdfsdk/javascript/app.cpp
@@ -32,7 +32,7 @@
 IMPLEMENT_JS_CLASS(CJS_TimerObj, TimerObj)
 
 TimerObj::TimerObj(CJS_Object* pJSObject)
-    : CJS_EmbedObj(pJSObject), m_pTimer(NULL) {}
+    : CJS_EmbedObj(pJSObject), m_pTimer(nullptr) {}
 
 TimerObj::~TimerObj() {}
 
@@ -102,10 +102,6 @@
     : CJS_EmbedObj(pJSObject), m_bCalculate(true), m_bRuntimeHighLight(false) {}
 
 app::~app() {
-  for (int i = 0, sz = m_aTimer.GetSize(); i < sz; i++)
-    delete m_aTimer[i];
-
-  m_aTimer.RemoveAll();
 }
 
 FX_BOOL app::activeDocs(IJS_Context* cc,
@@ -120,7 +116,7 @@
   CPDFSDK_Document* pCurDoc = pContext->GetReaderDocument();
   CJS_Array aDocs(pRuntime);
   if (CPDFSDK_Document* pDoc = pApp->GetSDKDocument()) {
-    CJS_Document* pJSDocument = NULL;
+    CJS_Document* pJSDocument = nullptr;
     if (pDoc == pCurDoc) {
       v8::Local<v8::Object> pObj = FXJS_GetThisObj(pRuntime->GetIsolate());
       if (FXJS_GetObjDefnID(pObj) == CJS_Document::g_nObjDefnID)
@@ -384,19 +380,16 @@
 
   CJS_Runtime* pRuntime = pContext->GetJSRuntime();
   uint32_t dwInterval = params.size() > 1 ? params[1].ToInt() : 1000;
-
   CPDFDoc_Environment* pApp = pRuntime->GetReaderApp();
-  ASSERT(pApp);
-  CJS_Timer* pTimer =
-      new CJS_Timer(this, pApp, pRuntime, 0, script, dwInterval, 0);
-  m_aTimer.Add(pTimer);
+  m_Timers.push_back(std::unique_ptr<CJS_Timer>(
+      new CJS_Timer(this, pApp, pRuntime, 0, script, dwInterval, 0)));
 
   v8::Local<v8::Object> pRetObj = FXJS_NewFxDynamicObj(
       pRuntime->GetIsolate(), pRuntime, CJS_TimerObj::g_nObjDefnID);
-  CJS_TimerObj* pJS_TimerObj =
-      (CJS_TimerObj*)FXJS_GetPrivate(pRuntime->GetIsolate(), pRetObj);
-  TimerObj* pTimerObj = (TimerObj*)pJS_TimerObj->GetEmbedObject();
-  pTimerObj->SetTimer(pTimer);
+  CJS_TimerObj* pJS_TimerObj = static_cast<CJS_TimerObj*>(
+      FXJS_GetPrivate(pRuntime->GetIsolate(), pRetObj));
+  TimerObj* pTimerObj = static_cast<TimerObj*>(pJS_TimerObj->GetEmbedObject());
+  pTimerObj->SetTimer(m_Timers.back().get());
 
   vRet = pRetObj;
   return TRUE;
@@ -406,36 +399,32 @@
                         const std::vector<CJS_Value>& params,
                         CJS_Value& vRet,
                         CFX_WideString& sError) {
+  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
   if (params.size() > 2 || params.size() == 0) {
-    sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPARAMERROR);
+    sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
     return FALSE;
   }
 
-  CJS_Context* pContext = (CJS_Context*)cc;
-  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
-
-  CFX_WideString script = params.size() > 0 ? params[0].ToCFXWideString() : L"";
+  CFX_WideString script = params[0].ToCFXWideString();
   if (script.IsEmpty()) {
-    sError =
-        JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSAFNUMBER_KEYSTROKE);
+    sError = JSGetStringFromID(pContext, IDS_STRING_JSAFNUMBER_KEYSTROKE);
     return TRUE;
   }
 
   uint32_t dwTimeOut = params.size() > 1 ? params[1].ToInt() : 1000;
-
+  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
   CPDFDoc_Environment* pApp = pRuntime->GetReaderApp();
-  ASSERT(pApp);
-
-  CJS_Timer* pTimer =
-      new CJS_Timer(this, pApp, pRuntime, 1, script, dwTimeOut, dwTimeOut);
-  m_aTimer.Add(pTimer);
+  m_Timers.push_back(std::unique_ptr<CJS_Timer>(
+      new CJS_Timer(this, pApp, pRuntime, 1, script, dwTimeOut, dwTimeOut)));
 
   v8::Local<v8::Object> pRetObj = FXJS_NewFxDynamicObj(
       pRuntime->GetIsolate(), pRuntime, CJS_TimerObj::g_nObjDefnID);
-  CJS_TimerObj* pJS_TimerObj =
-      (CJS_TimerObj*)FXJS_GetPrivate(pRuntime->GetIsolate(), pRetObj);
-  TimerObj* pTimerObj = (TimerObj*)pJS_TimerObj->GetEmbedObject();
-  pTimerObj->SetTimer(pTimer);
+
+  CJS_TimerObj* pJS_TimerObj = static_cast<CJS_TimerObj*>(
+      FXJS_GetPrivate(pRuntime->GetIsolate(), pRetObj));
+
+  TimerObj* pTimerObj = static_cast<TimerObj*>(pJS_TimerObj->GetEmbedObject());
+  pTimerObj->SetTimer(m_Timers.back().get());
 
   vRet = pRetObj;
   return TRUE;
@@ -451,29 +440,7 @@
     return FALSE;
   }
 
-  if (params[0].GetType() == CJS_Value::VT_fxobject) {
-    v8::Local<v8::Object> pObj = params[0].ToV8Object();
-    if (FXJS_GetObjDefnID(pObj) == CJS_TimerObj::g_nObjDefnID) {
-      if (CJS_Object* pJSObj = params[0].ToCJSObject()) {
-        if (TimerObj* pTimerObj = (TimerObj*)pJSObj->GetEmbedObject()) {
-          if (CJS_Timer* pTimer = pTimerObj->GetTimer()) {
-            pTimer->KillJSTimer();
-
-            for (int i = 0, sz = m_aTimer.GetSize(); i < sz; i++) {
-              if (m_aTimer[i] == pTimer) {
-                m_aTimer.RemoveAt(i);
-                break;
-              }
-            }
-
-            delete pTimer;
-            pTimerObj->SetTimer(NULL);
-          }
-        }
-      }
-    }
-  }
-
+  app::ClearTimerCommon(params[0]);
   return TRUE;
 }
 
@@ -487,32 +454,42 @@
     return FALSE;
   }
 
-  if (params[0].GetType() == CJS_Value::VT_fxobject) {
-    v8::Local<v8::Object> pObj = params[0].ToV8Object();
-    if (FXJS_GetObjDefnID(pObj) == CJS_TimerObj::g_nObjDefnID) {
-      if (CJS_Object* pJSObj = params[0].ToCJSObject()) {
-        if (TimerObj* pTimerObj = (TimerObj*)pJSObj->GetEmbedObject()) {
-          if (CJS_Timer* pTimer = pTimerObj->GetTimer()) {
-            pTimer->KillJSTimer();
-
-            for (int i = 0, sz = m_aTimer.GetSize(); i < sz; i++) {
-              if (m_aTimer[i] == pTimer) {
-                m_aTimer.RemoveAt(i);
-                break;
-              }
-            }
-
-            delete pTimer;
-            pTimerObj->SetTimer(NULL);
-          }
-        }
-      }
-    }
-  }
-
+  app::ClearTimerCommon(params[0]);
   return TRUE;
 }
 
+void app::ClearTimerCommon(const CJS_Value& param) {
+  if (param.GetType() != CJS_Value::VT_fxobject)
+    return;
+
+  v8::Local<v8::Object> pObj = param.ToV8Object();
+  if (FXJS_GetObjDefnID(pObj) != CJS_TimerObj::g_nObjDefnID)
+    return;
+
+  CJS_Object* pJSObj = param.ToCJSObject();
+  if (!pJSObj)
+    return;
+
+  TimerObj* pTimerObj = static_cast<TimerObj*>(pJSObj->GetEmbedObject());
+  if (!pTimerObj)
+    return;
+
+  CJS_Timer* pTimer = pTimerObj->GetTimer();
+  if (!pTimer)
+    return;
+
+  pTimer->KillJSTimer();
+  auto iter = std::find_if(m_Timers.begin(), m_Timers.end(),
+                           [pTimer](const std::unique_ptr<CJS_Timer>& that) {
+                             return pTimer == that.get();
+                           });
+
+  if (iter != m_Timers.end())
+    m_Timers.erase(iter);
+
+  pTimerObj->SetTimer(nullptr);
+}
+
 FX_BOOL app::execMenuItem(IJS_Context* cc,
                           const std::vector<CJS_Value>& params,
                           CJS_Value& vRet,
diff --git a/fpdfsdk/javascript/app.h b/fpdfsdk/javascript/app.h
index 764f73b..c6cda55 100644
--- a/fpdfsdk/javascript/app.h
+++ b/fpdfsdk/javascript/app.h
@@ -7,6 +7,7 @@
 #ifndef FPDFSDK_JAVASCRIPT_APP_H_
 #define FPDFSDK_JAVASCRIPT_APP_H_
 
+#include <memory>
 #include <vector>
 
 #include "fpdfsdk/javascript/JS_Define.h"
@@ -40,7 +41,6 @@
   app(CJS_Object* pJSObject);
   ~app() override;
 
- public:
   FX_BOOL activeDocs(IJS_Context* cc,
                      CJS_PropValue& vp,
                      CFX_WideString& sError);
@@ -160,9 +160,11 @@
   void TimerProc(CJS_Timer* pTimer) override;
   void RunJsScript(CJS_Runtime* pRuntime, const CFX_WideString& wsScript);
 
+  void ClearTimerCommon(const CJS_Value& param);
+
   bool m_bCalculate;
   bool m_bRuntimeHighLight;
-  CFX_ArrayTemplate<CJS_Timer*> m_aTimer;
+  std::vector<std::unique_ptr<CJS_Timer>> m_Timers;
 };
 
 class CJS_App : public CJS_Object {