Merge CJS_EventRecorder into CJS_EventContext and remove.

-- fix IWYU encountered along the way.

Change-Id: I6eb1d21ec03aa00ebe0a0828637fd3187374a19a
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/84154
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/fxjs/BUILD.gn b/fxjs/BUILD.gn
index 4159d6e..f71c510 100644
--- a/fxjs/BUILD.gn
+++ b/fxjs/BUILD.gn
@@ -49,8 +49,6 @@
       "cjs_event.h",
       "cjs_event_context.cpp",
       "cjs_event_context.h",
-      "cjs_eventrecorder.cpp",
-      "cjs_eventrecorder.h",
       "cjs_field.cpp",
       "cjs_field.h",
       "cjs_font.cpp",
diff --git a/fxjs/cjs_app.cpp b/fxjs/cjs_app.cpp
index 4299e64..bacd8d2 100644
--- a/fxjs/cjs_app.cpp
+++ b/fxjs/cjs_app.cpp
@@ -9,6 +9,7 @@
 #include <utility>
 
 #include "core/fxcrt/stl_util.h"
+#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
 #include "fpdfsdk/cpdfsdk_interactiveform.h"
 #include "fxjs/cjs_document.h"
 #include "fxjs/cjs_timerobj.h"
diff --git a/fxjs/cjs_color.cpp b/fxjs/cjs_color.cpp
index b6ea5fe..d28bf3f 100644
--- a/fxjs/cjs_color.cpp
+++ b/fxjs/cjs_color.cpp
@@ -11,7 +11,6 @@
 
 #include "core/fxge/cfx_color.h"
 #include "fxjs/cjs_event_context.h"
-#include "fxjs/cjs_eventrecorder.h"
 #include "fxjs/cjs_object.h"
 #include "fxjs/cjs_runtime.h"
 #include "fxjs/fxv8.h"
diff --git a/fxjs/cjs_console.cpp b/fxjs/cjs_console.cpp
index 9cd0f36..12eff43 100644
--- a/fxjs/cjs_console.cpp
+++ b/fxjs/cjs_console.cpp
@@ -9,7 +9,6 @@
 #include <vector>
 
 #include "fxjs/cjs_event_context.h"
-#include "fxjs/cjs_eventrecorder.h"
 #include "fxjs/cjs_object.h"
 #include "fxjs/js_define.h"
 
diff --git a/fxjs/cjs_document.cpp b/fxjs/cjs_document.cpp
index d5d78e0..cd8b16c 100644
--- a/fxjs/cjs_document.cpp
+++ b/fxjs/cjs_document.cpp
@@ -20,6 +20,7 @@
 #include "core/fpdfdoc/cpdf_nametree.h"
 #include "core/fxcrt/fx_memory_wrappers.h"
 #include "fpdfsdk/cpdfsdk_annotiteration.h"
+#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
 #include "fpdfsdk/cpdfsdk_interactiveform.h"
 #include "fpdfsdk/cpdfsdk_pageview.h"
 #include "fxjs/cjs_annot.h"
diff --git a/fxjs/cjs_event.cpp b/fxjs/cjs_event.cpp
index 50760d3..5bcc43a 100644
--- a/fxjs/cjs_event.cpp
+++ b/fxjs/cjs_event.cpp
@@ -7,7 +7,6 @@
 #include "fxjs/cjs_event.h"
 
 #include "fxjs/cjs_event_context.h"
-#include "fxjs/cjs_eventrecorder.h"
 #include "fxjs/cjs_field.h"
 #include "fxjs/cjs_object.h"
 #include "fxjs/js_define.h"
diff --git a/fxjs/cjs_event_context.cpp b/fxjs/cjs_event_context.cpp
index c957d3c..0f28e9e 100644
--- a/fxjs/cjs_event_context.cpp
+++ b/fxjs/cjs_event_context.cpp
@@ -6,8 +6,9 @@
 
 #include "fxjs/cjs_event_context.h"
 
+#include "core/fpdfdoc/cpdf_formfield.h"
 #include "core/fxcrt/autorestorer.h"
-#include "fxjs/cjs_eventrecorder.h"
+#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
 #include "fxjs/cjs_field.h"
 #include "fxjs/cjs_runtime.h"
 #include "fxjs/js_define.h"
@@ -15,18 +16,10 @@
 #include "third_party/base/check.h"
 
 CJS_EventContext::CJS_EventContext(CJS_Runtime* pRuntime)
-    : m_pRuntime(pRuntime),
-      m_pEventRecorder(
-          std::make_unique<CJS_EventRecorder>(m_pRuntime->GetFormFillEnv())) {
-  DCHECK(pRuntime);
-}
+    : m_pRuntime(pRuntime), m_pFormFillEnv(pRuntime->GetFormFillEnv()) {}
 
 CJS_EventContext::~CJS_EventContext() = default;
 
-CPDFSDK_FormFillEnvironment* CJS_EventContext::GetFormFillEnv() {
-  return m_pRuntime->GetFormFillEnv();
-}
-
 Optional<IJS_Runtime::JS_Error> CJS_EventContext::RunScript(
     const WideString& script) {
   v8::Isolate::Scope isolate_scope(m_pRuntime->GetIsolate());
@@ -42,9 +35,8 @@
   AutoRestorer<bool> restorer(&m_bBusy);
   m_bBusy = true;
 
-  DCHECK(m_pEventRecorder->IsValid());
-  CJS_Runtime::FieldEvent event(m_pEventRecorder->TargetName(),
-                                m_pEventRecorder->EventType());
+  DCHECK(IsValid());
+  CJS_Runtime::FieldEvent event(TargetName(), EventType());
   if (!m_pRuntime->AddEventToSet(event)) {
     return IJS_Runtime::JS_Error(
         1, 1, JSGetStringFromID(JSMessage::kDuplicateEventError));
@@ -55,7 +47,7 @@
     err = m_pRuntime->ExecuteScript(script);
 
   m_pRuntime->RemoveEventFromSet(event);
-  m_pEventRecorder->Destroy();
+  Destroy();
   return err;
 }
 
@@ -70,7 +62,7 @@
   if (pFieldObj.IsEmpty())
     return nullptr;
 
-  auto* pFormFillEnv = m_pEventRecorder->GetFormFillEnvironment();
+  auto* pFormFillEnv = GetFormFillEnv();
   if (!pFormFillEnv)
     pFormFillEnv = GetFormFillEnv();
 
@@ -80,7 +72,7 @@
 
   auto* pJSField =
       static_cast<CJS_Field*>(CFXJS_Engine::GetObjectPrivate(pFieldObj));
-  pJSField->AttachField(pJSDocument, m_pEventRecorder->SourceName());
+  pJSField->AttachField(pJSDocument, SourceName());
   return pJSField;
 }
 
@@ -95,7 +87,7 @@
   if (pFieldObj.IsEmpty())
     return nullptr;
 
-  auto* pFormFillEnv = m_pEventRecorder->GetFormFillEnvironment();
+  auto* pFormFillEnv = GetFormFillEnv();
   if (!pFormFillEnv)
     pFormFillEnv = GetFormFillEnv();
 
@@ -105,119 +97,152 @@
 
   auto* pJSField =
       static_cast<CJS_Field*>(CFXJS_Engine::GetObjectPrivate(pFieldObj));
-  pJSField->AttachField(pJSDocument, m_pEventRecorder->TargetName());
+  pJSField->AttachField(pJSDocument, TargetName());
   return pJSField;
 }
 
 void CJS_EventContext::OnApp_Init() {
-  m_pEventRecorder->OnApp_Init();
+  Initialize(JET_APP_INIT);
 }
 
 void CJS_EventContext::OnDoc_Open(const WideString& strTargetName) {
-  m_pEventRecorder->OnDoc_Open(strTargetName);
+  Initialize(JET_DOC_OPEN);
+  m_strTargetName = strTargetName;
 }
 
 void CJS_EventContext::OnDoc_WillPrint() {
-  m_pEventRecorder->OnDoc_WillPrint();
+  Initialize(JET_DOC_WILLPRINT);
 }
 
 void CJS_EventContext::OnDoc_DidPrint() {
-  m_pEventRecorder->OnDoc_DidPrint();
+  Initialize(JET_DOC_DIDPRINT);
 }
 
 void CJS_EventContext::OnDoc_WillSave() {
-  m_pEventRecorder->OnDoc_WillSave();
+  Initialize(JET_DOC_WILLSAVE);
 }
 
 void CJS_EventContext::OnDoc_DidSave() {
-  m_pEventRecorder->OnDoc_DidSave();
+  Initialize(JET_DOC_DIDSAVE);
 }
 
 void CJS_EventContext::OnDoc_WillClose() {
-  m_pEventRecorder->OnDoc_WillClose();
+  Initialize(JET_DOC_WILLCLOSE);
 }
 
 void CJS_EventContext::OnPage_Open() {
-  m_pEventRecorder->OnPage_Open();
+  Initialize(JET_PAGE_OPEN);
 }
 
 void CJS_EventContext::OnPage_Close() {
-  m_pEventRecorder->OnPage_Close();
+  Initialize(JET_PAGE_CLOSE);
 }
 
 void CJS_EventContext::OnPage_InView() {
-  m_pEventRecorder->OnPage_InView();
+  Initialize(JET_PAGE_INVIEW);
 }
 
 void CJS_EventContext::OnPage_OutView() {
-  m_pEventRecorder->OnPage_OutView();
-}
-
-void CJS_EventContext::OnField_MouseDown(bool bModifier,
-                                         bool bShift,
-                                         CPDF_FormField* pTarget) {
-  m_pEventRecorder->OnField_MouseDown(bModifier, bShift, pTarget);
+  Initialize(JET_PAGE_OUTVIEW);
 }
 
 void CJS_EventContext::OnField_MouseEnter(bool bModifier,
                                           bool bShift,
                                           CPDF_FormField* pTarget) {
-  m_pEventRecorder->OnField_MouseEnter(bModifier, bShift, pTarget);
+  Initialize(JET_FIELD_MOUSEENTER);
+  m_bModifier = bModifier;
+  m_bShift = bShift;
+  m_strTargetName = pTarget->GetFullName();
 }
 
 void CJS_EventContext::OnField_MouseExit(bool bModifier,
                                          bool bShift,
                                          CPDF_FormField* pTarget) {
-  m_pEventRecorder->OnField_MouseExit(bModifier, bShift, pTarget);
+  Initialize(JET_FIELD_MOUSEEXIT);
+  m_bModifier = bModifier;
+  m_bShift = bShift;
+  m_strTargetName = pTarget->GetFullName();
+}
+
+void CJS_EventContext::OnField_MouseDown(bool bModifier,
+                                         bool bShift,
+                                         CPDF_FormField* pTarget) {
+  Initialize(JET_FIELD_MOUSEDOWN);
+  m_eEventType = JET_FIELD_MOUSEDOWN;
+
+  m_bModifier = bModifier;
+  m_bShift = bShift;
+  m_strTargetName = pTarget->GetFullName();
 }
 
 void CJS_EventContext::OnField_MouseUp(bool bModifier,
                                        bool bShift,
                                        CPDF_FormField* pTarget) {
-  m_pEventRecorder->OnField_MouseUp(bModifier, bShift, pTarget);
+  Initialize(JET_FIELD_MOUSEUP);
+
+  m_bModifier = bModifier;
+  m_bShift = bShift;
+  m_strTargetName = pTarget->GetFullName();
 }
 
 void CJS_EventContext::OnField_Focus(bool bModifier,
                                      bool bShift,
                                      CPDF_FormField* pTarget,
-                                     WideString* Value) {
-  m_pEventRecorder->OnField_Focus(bModifier, bShift, pTarget, Value);
+                                     WideString* pValue) {
+  DCHECK(pValue);
+  Initialize(JET_FIELD_FOCUS);
+
+  m_bModifier = bModifier;
+  m_bShift = bShift;
+  m_strTargetName = pTarget->GetFullName();
+  m_pValue = pValue;
 }
 
 void CJS_EventContext::OnField_Blur(bool bModifier,
                                     bool bShift,
                                     CPDF_FormField* pTarget,
-                                    WideString* Value) {
-  m_pEventRecorder->OnField_Blur(bModifier, bShift, pTarget, Value);
-}
+                                    WideString* pValue) {
+  DCHECK(pValue);
+  Initialize(JET_FIELD_BLUR);
 
-void CJS_EventContext::OnField_Calculate(CPDF_FormField* pSource,
-                                         CPDF_FormField* pTarget,
-                                         WideString* pValue,
-                                         bool* pRc) {
-  m_pEventRecorder->OnField_Calculate(pSource, pTarget, pValue, pRc);
-}
-
-void CJS_EventContext::OnField_Format(CPDF_FormField* pTarget,
-                                      WideString* Value) {
-  m_pEventRecorder->OnField_Format(pTarget, Value);
+  m_bModifier = bModifier;
+  m_bShift = bShift;
+  m_strTargetName = pTarget->GetFullName();
+  m_pValue = pValue;
 }
 
 void CJS_EventContext::OnField_Keystroke(WideString* strChange,
                                          const WideString& strChangeEx,
-                                         bool bKeyDown,
+                                         bool KeyDown,
                                          bool bModifier,
-                                         int* nSelEnd,
-                                         int* nSelStart,
+                                         int* pSelEnd,
+                                         int* pSelStart,
                                          bool bShift,
                                          CPDF_FormField* pTarget,
-                                         WideString* Value,
+                                         WideString* pValue,
                                          bool bWillCommit,
                                          bool bFieldFull,
-                                         bool* bRc) {
-  m_pEventRecorder->OnField_Keystroke(
-      strChange, strChangeEx, bKeyDown, bModifier, nSelEnd, nSelStart, bShift,
-      pTarget, Value, bWillCommit, bFieldFull, bRc);
+                                         bool* pbRc) {
+  DCHECK(pValue);
+  DCHECK(pbRc);
+  DCHECK(pSelStart);
+  DCHECK(pSelEnd);
+
+  Initialize(JET_FIELD_KEYSTROKE);
+
+  m_nCommitKey = 0;
+  m_pWideStrChange = strChange;
+  m_WideStrChangeEx = strChangeEx;
+  m_bKeyDown = KeyDown;
+  m_bModifier = bModifier;
+  m_pISelEnd = pSelEnd;
+  m_pISelStart = pSelStart;
+  m_bShift = bShift;
+  m_strTargetName = pTarget->GetFullName();
+  m_pValue = pValue;
+  m_bWillCommit = bWillCommit;
+  m_pbRc = pbRc;
+  m_bFieldFull = bFieldFull;
 }
 
 void CJS_EventContext::OnField_Validate(WideString* strChange,
@@ -226,92 +251,366 @@
                                         bool bModifier,
                                         bool bShift,
                                         CPDF_FormField* pTarget,
-                                        WideString* Value,
-                                        bool* bRc) {
-  m_pEventRecorder->OnField_Validate(strChange, strChangeEx, bKeyDown,
-                                     bModifier, bShift, pTarget, Value, bRc);
+                                        WideString* pValue,
+                                        bool* pbRc) {
+  DCHECK(pValue);
+  DCHECK(pbRc);
+
+  Initialize(JET_FIELD_VALIDATE);
+
+  m_pWideStrChange = strChange;
+  m_WideStrChangeEx = strChangeEx;
+  m_bKeyDown = bKeyDown;
+  m_bModifier = bModifier;
+  m_bShift = bShift;
+  m_strTargetName = pTarget->GetFullName();
+  m_pValue = pValue;
+  m_pbRc = pbRc;
+}
+
+void CJS_EventContext::OnField_Calculate(CPDF_FormField* pSource,
+                                         CPDF_FormField* pTarget,
+                                         WideString* pValue,
+                                         bool* pRc) {
+  DCHECK(pValue);
+  DCHECK(pRc);
+
+  Initialize(JET_FIELD_CALCULATE);
+
+  if (pSource)
+    m_strSourceName = pSource->GetFullName();
+  m_strTargetName = pTarget->GetFullName();
+  m_pValue = pValue;
+  m_pbRc = pRc;
+}
+
+void CJS_EventContext::OnField_Format(CPDF_FormField* pTarget,
+                                      WideString* pValue) {
+  DCHECK(pValue);
+  Initialize(JET_FIELD_FORMAT);
+
+  m_nCommitKey = 0;
+  m_strTargetName = pTarget->GetFullName();
+  m_pValue = pValue;
+  m_bWillCommit = true;
 }
 
 void CJS_EventContext::OnScreen_Focus(bool bModifier,
                                       bool bShift,
                                       CPDFSDK_Annot* pScreen) {
-  m_pEventRecorder->OnScreen_Focus(bModifier, bShift, pScreen);
+  Initialize(JET_SCREEN_FOCUS);
+
+  m_bModifier = bModifier;
+  m_bShift = bShift;
+  m_pTargetAnnot.Reset(pScreen);
 }
 
 void CJS_EventContext::OnScreen_Blur(bool bModifier,
                                      bool bShift,
                                      CPDFSDK_Annot* pScreen) {
-  m_pEventRecorder->OnScreen_Blur(bModifier, bShift, pScreen);
+  Initialize(JET_SCREEN_BLUR);
+
+  m_bModifier = bModifier;
+  m_bShift = bShift;
+  m_pTargetAnnot.Reset(pScreen);
 }
 
 void CJS_EventContext::OnScreen_Open(bool bModifier,
                                      bool bShift,
                                      CPDFSDK_Annot* pScreen) {
-  m_pEventRecorder->OnScreen_Open(bModifier, bShift, pScreen);
+  Initialize(JET_SCREEN_OPEN);
+
+  m_bModifier = bModifier;
+  m_bShift = bShift;
+  m_pTargetAnnot.Reset(pScreen);
 }
 
 void CJS_EventContext::OnScreen_Close(bool bModifier,
                                       bool bShift,
                                       CPDFSDK_Annot* pScreen) {
-  m_pEventRecorder->OnScreen_Close(bModifier, bShift, pScreen);
+  Initialize(JET_SCREEN_CLOSE);
+
+  m_bModifier = bModifier;
+  m_bShift = bShift;
+  m_pTargetAnnot.Reset(pScreen);
 }
 
 void CJS_EventContext::OnScreen_MouseDown(bool bModifier,
                                           bool bShift,
                                           CPDFSDK_Annot* pScreen) {
-  m_pEventRecorder->OnScreen_MouseDown(bModifier, bShift, pScreen);
+  Initialize(JET_SCREEN_MOUSEDOWN);
+
+  m_bModifier = bModifier;
+  m_bShift = bShift;
+  m_pTargetAnnot.Reset(pScreen);
 }
 
 void CJS_EventContext::OnScreen_MouseUp(bool bModifier,
                                         bool bShift,
                                         CPDFSDK_Annot* pScreen) {
-  m_pEventRecorder->OnScreen_MouseUp(bModifier, bShift, pScreen);
+  Initialize(JET_SCREEN_MOUSEUP);
+
+  m_bModifier = bModifier;
+  m_bShift = bShift;
+  m_pTargetAnnot.Reset(pScreen);
 }
 
 void CJS_EventContext::OnScreen_MouseEnter(bool bModifier,
                                            bool bShift,
                                            CPDFSDK_Annot* pScreen) {
-  m_pEventRecorder->OnScreen_MouseEnter(bModifier, bShift, pScreen);
+  Initialize(JET_SCREEN_MOUSEENTER);
+
+  m_bModifier = bModifier;
+  m_bShift = bShift;
+  m_pTargetAnnot.Reset(pScreen);
 }
 
 void CJS_EventContext::OnScreen_MouseExit(bool bModifier,
                                           bool bShift,
                                           CPDFSDK_Annot* pScreen) {
-  m_pEventRecorder->OnScreen_MouseExit(bModifier, bShift, pScreen);
+  Initialize(JET_SCREEN_MOUSEEXIT);
+
+  m_bModifier = bModifier;
+  m_bShift = bShift;
+  m_pTargetAnnot.Reset(pScreen);
 }
 
 void CJS_EventContext::OnScreen_InView(bool bModifier,
                                        bool bShift,
                                        CPDFSDK_Annot* pScreen) {
-  m_pEventRecorder->OnScreen_InView(bModifier, bShift, pScreen);
+  Initialize(JET_SCREEN_INVIEW);
+  m_bModifier = bModifier;
+  m_bShift = bShift;
+  m_pTargetAnnot.Reset(pScreen);
 }
 
 void CJS_EventContext::OnScreen_OutView(bool bModifier,
                                         bool bShift,
                                         CPDFSDK_Annot* pScreen) {
-  m_pEventRecorder->OnScreen_OutView(bModifier, bShift, pScreen);
-}
-
-void CJS_EventContext::OnBookmark_MouseUp(CPDF_Bookmark* pBookMark) {
-  m_pEventRecorder->OnBookmark_MouseUp(pBookMark);
+  Initialize(JET_SCREEN_OUTVIEW);
+  m_bModifier = bModifier;
+  m_bShift = bShift;
+  m_pTargetAnnot.Reset(pScreen);
 }
 
 void CJS_EventContext::OnLink_MouseUp() {
-  m_pEventRecorder->OnLink_MouseUp();
+  Initialize(JET_LINK_MOUSEUP);
 }
 
-void CJS_EventContext::OnConsole_Exec() {
-  m_pEventRecorder->OnConsole_Exec();
-}
-
-void CJS_EventContext::OnExternal_Exec() {
-  m_pEventRecorder->OnExternal_Exec();
-}
-
-void CJS_EventContext::OnBatch_Exec() {
-  m_pEventRecorder->OnBatchExec();
+void CJS_EventContext::OnBookmark_MouseUp(CPDF_Bookmark* pBookMark) {
+  Initialize(JET_BOOKMARK_MOUSEUP);
+  m_pTargetBookMark = pBookMark;
 }
 
 void CJS_EventContext::OnMenu_Exec(const WideString& strTargetName) {
-  m_pEventRecorder->OnMenu_Exec(strTargetName);
+  Initialize(JET_MENU_EXEC);
+  m_strTargetName = strTargetName;
+}
+
+void CJS_EventContext::OnExternal_Exec() {
+  Initialize(JET_EXTERNAL_EXEC);
+}
+
+void CJS_EventContext::OnBatch_Exec() {
+  Initialize(JET_BATCH_EXEC);
+}
+
+void CJS_EventContext::OnConsole_Exec() {
+  Initialize(JET_CONSOLE_EXEC);
+}
+
+void CJS_EventContext::Initialize(JS_EVENT_T type) {
+  m_eEventType = type;
+  m_strTargetName.clear();
+  m_strSourceName.clear();
+  m_pWideStrChange = nullptr;
+  m_WideStrChangeDu.clear();
+  m_WideStrChangeEx.clear();
+  m_nCommitKey = -1;
+  m_bKeyDown = false;
+  m_bModifier = false;
+  m_bShift = false;
+  m_pISelEnd = nullptr;
+  m_nSelEndDu = 0;
+  m_pISelStart = nullptr;
+  m_nSelStartDu = 0;
+  m_bWillCommit = false;
+  m_pValue = nullptr;
+  m_bFieldFull = false;
+  m_pbRc = nullptr;
+  m_bRcDu = false;
+  m_pTargetBookMark = nullptr;
+  m_pTargetAnnot.Reset();
+  m_bValid = true;
+}
+
+void CJS_EventContext::Destroy() {
+  m_bValid = false;
+}
+
+bool CJS_EventContext::IsUserGesture() const {
+  switch (m_eEventType) {
+    case JET_FIELD_MOUSEDOWN:
+    case JET_FIELD_MOUSEUP:
+    case JET_SCREEN_MOUSEDOWN:
+    case JET_SCREEN_MOUSEUP:
+    case JET_BOOKMARK_MOUSEUP:
+    case JET_LINK_MOUSEUP:
+    case JET_FIELD_KEYSTROKE:
+      return true;
+    default:
+      return false;
+  }
+}
+
+WideString& CJS_EventContext::Change() {
+  return m_pWideStrChange ? *m_pWideStrChange : m_WideStrChangeDu;
+}
+
+ByteStringView CJS_EventContext::Name() const {
+  switch (m_eEventType) {
+    case JET_APP_INIT:
+      return "Init";
+    case JET_BATCH_EXEC:
+      return "Exec";
+    case JET_BOOKMARK_MOUSEUP:
+      return "Mouse Up";
+    case JET_CONSOLE_EXEC:
+      return "Exec";
+    case JET_DOC_DIDPRINT:
+      return "DidPrint";
+    case JET_DOC_DIDSAVE:
+      return "DidSave";
+    case JET_DOC_OPEN:
+      return "Open";
+    case JET_DOC_WILLCLOSE:
+      return "WillClose";
+    case JET_DOC_WILLPRINT:
+      return "WillPrint";
+    case JET_DOC_WILLSAVE:
+      return "WillSave";
+    case JET_EXTERNAL_EXEC:
+      return "Exec";
+    case JET_FIELD_FOCUS:
+    case JET_SCREEN_FOCUS:
+      return "Focus";
+    case JET_FIELD_BLUR:
+    case JET_SCREEN_BLUR:
+      return "Blur";
+    case JET_FIELD_MOUSEDOWN:
+    case JET_SCREEN_MOUSEDOWN:
+      return "Mouse Down";
+    case JET_FIELD_MOUSEUP:
+    case JET_SCREEN_MOUSEUP:
+      return "Mouse Up";
+    case JET_FIELD_MOUSEENTER:
+    case JET_SCREEN_MOUSEENTER:
+      return "Mouse Enter";
+    case JET_FIELD_MOUSEEXIT:
+    case JET_SCREEN_MOUSEEXIT:
+      return "Mouse Exit";
+    case JET_FIELD_CALCULATE:
+      return "Calculate";
+    case JET_FIELD_FORMAT:
+      return "Format";
+    case JET_FIELD_KEYSTROKE:
+      return "Keystroke";
+    case JET_FIELD_VALIDATE:
+      return "Validate";
+    case JET_LINK_MOUSEUP:
+      return "Mouse Up";
+    case JET_MENU_EXEC:
+      return "Exec";
+    case JET_PAGE_OPEN:
+    case JET_SCREEN_OPEN:
+      return "Open";
+    case JET_PAGE_CLOSE:
+    case JET_SCREEN_CLOSE:
+      return "Close";
+    case JET_SCREEN_INVIEW:
+    case JET_PAGE_INVIEW:
+      return "InView";
+    case JET_PAGE_OUTVIEW:
+    case JET_SCREEN_OUTVIEW:
+      return "OutView";
+    default:
+      return "";
+  }
+}
+
+ByteStringView CJS_EventContext::Type() const {
+  switch (m_eEventType) {
+    case JET_APP_INIT:
+      return "App";
+    case JET_BATCH_EXEC:
+      return "Batch";
+    case JET_BOOKMARK_MOUSEUP:
+      return "BookMark";
+    case JET_CONSOLE_EXEC:
+      return "Console";
+    case JET_DOC_DIDPRINT:
+    case JET_DOC_DIDSAVE:
+    case JET_DOC_OPEN:
+    case JET_DOC_WILLCLOSE:
+    case JET_DOC_WILLPRINT:
+    case JET_DOC_WILLSAVE:
+      return "Doc";
+    case JET_EXTERNAL_EXEC:
+      return "External";
+    case JET_FIELD_BLUR:
+    case JET_FIELD_FOCUS:
+    case JET_FIELD_MOUSEDOWN:
+    case JET_FIELD_MOUSEENTER:
+    case JET_FIELD_MOUSEEXIT:
+    case JET_FIELD_MOUSEUP:
+    case JET_FIELD_CALCULATE:
+    case JET_FIELD_FORMAT:
+    case JET_FIELD_KEYSTROKE:
+    case JET_FIELD_VALIDATE:
+      return "Field";
+    case JET_SCREEN_FOCUS:
+    case JET_SCREEN_BLUR:
+    case JET_SCREEN_OPEN:
+    case JET_SCREEN_CLOSE:
+    case JET_SCREEN_MOUSEDOWN:
+    case JET_SCREEN_MOUSEUP:
+    case JET_SCREEN_MOUSEENTER:
+    case JET_SCREEN_MOUSEEXIT:
+    case JET_SCREEN_INVIEW:
+    case JET_SCREEN_OUTVIEW:
+      return "Screen";
+    case JET_LINK_MOUSEUP:
+      return "Link";
+    case JET_MENU_EXEC:
+      return "Menu";
+    case JET_PAGE_OPEN:
+    case JET_PAGE_CLOSE:
+    case JET_PAGE_INVIEW:
+    case JET_PAGE_OUTVIEW:
+      return "Page";
+    default:
+      return "";
+  }
+}
+
+bool& CJS_EventContext::Rc() {
+  return m_pbRc ? *m_pbRc : m_bRcDu;
+}
+
+int CJS_EventContext::SelEnd() const {
+  return m_pISelEnd ? *m_pISelEnd : m_nSelEndDu;
+}
+
+int CJS_EventContext::SelStart() const {
+  return m_pISelStart ? *m_pISelStart : m_nSelStartDu;
+}
+
+void CJS_EventContext::SetSelEnd(int value) {
+  int& target = m_pISelEnd ? *m_pISelEnd : m_nSelEndDu;
+  target = value;
+}
+
+void CJS_EventContext::SetSelStart(int value) {
+  int& target = m_pISelStart ? *m_pISelStart : m_nSelStartDu;
+  target = value;
 }
diff --git a/fxjs/cjs_event_context.h b/fxjs/cjs_event_context.h
index f0d260d..0a368ee 100644
--- a/fxjs/cjs_event_context.h
+++ b/fxjs/cjs_event_context.h
@@ -10,13 +10,55 @@
 #include <memory>
 
 #include "core/fxcrt/fx_string.h"
+#include "core/fxcrt/observed_ptr.h"
 #include "core/fxcrt/unowned_ptr.h"
-#include "fxjs/cjs_eventrecorder.h"
+#include "fpdfsdk/cpdfsdk_annot.h"
+#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
 #include "fxjs/ijs_event_context.h"
 
 class CJS_Field;
 class CJS_Runtime;
-class CPDFSDK_FormFillEnvironment;
+
+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_EventContext final : public IJS_EventContext {
  public:
@@ -119,42 +161,70 @@
   void OnExternal_Exec() override;
 
   CJS_Runtime* GetJSRuntime() const { return m_pRuntime.Get(); }
-  CPDFSDK_FormFillEnvironment* GetFormFillEnv();
+  CPDFSDK_FormFillEnvironment* GetFormFillEnv() const {
+    return m_pFormFillEnv.Get();
+  }
   CJS_Field* SourceField();
   CJS_Field* TargetField();
 
-  WideString& Change() { return m_pEventRecorder->Change(); }
-  WideString ChangeEx() const { return m_pEventRecorder->ChangeEx(); }
-  bool IsUserGesture() const { return m_pEventRecorder->IsUserGesture(); }
-  int CommitKey() const { return m_pEventRecorder->CommitKey(); }
-  ByteStringView Name() const { return m_pEventRecorder->Name(); }
-  ByteStringView Type() const { return m_pEventRecorder->Type(); }
-  bool FieldFull() const { return m_pEventRecorder->FieldFull(); }
-  bool KeyDown() const { return m_pEventRecorder->KeyDown(); }
-  bool Modifier() const { return m_pEventRecorder->Modifier(); }
-  bool& Rc() { return m_pEventRecorder->Rc(); }
-  int SelEnd() const { return m_pEventRecorder->SelEnd(); }
-  int SelStart() const { return m_pEventRecorder->SelStart(); }
-  void SetSelEnd(int value) { m_pEventRecorder->SetSelEnd(value); }
-  void SetSelStart(int value) { m_pEventRecorder->SetSelStart(value); }
-  bool Shift() const { return m_pEventRecorder->Shift(); }
-  bool HasValue() const { return m_pEventRecorder->HasValue(); }
-  WideString& Value() { return m_pEventRecorder->Value(); }
-  WideString TargetName() const { return m_pEventRecorder->TargetName(); }
-  bool WillCommit() const { return m_pEventRecorder->WillCommit(); }
+  JS_EVENT_T EventType() const { return m_eEventType; }
+  bool IsValid() const { return m_bValid; }
+  bool IsUserGesture() const;
+  WideString& Change();
+  WideString ChangeEx() const { return m_WideStrChangeEx; }
+  WideString SourceName() const { return m_strSourceName; }
+  WideString TargetName() const { return m_strTargetName; }
+  int CommitKey() const { return m_nCommitKey; }
+  bool FieldFull() const { return m_bFieldFull; }
+  bool KeyDown() const { return m_bKeyDown; }
+  bool Modifier() const { return m_bModifier; }
+  ByteStringView Name() const;
+  ByteStringView Type() const;
+  bool& Rc();
+  int SelEnd() const;
+  int SelStart() const;
+  void SetSelEnd(int value);
+  void SetSelStart(int value);
+  bool Shift() const { return m_bShift; }
+  bool HasValue() const { return !!m_pValue; }
+  WideString& Value() { return *m_pValue; }
+  bool WillCommit() const { return m_bWillCommit; }
 
-  void SetValueForTest(WideString* pStr) {
-    m_pEventRecorder->SetValueForTest(pStr);
-  }
-  void SetRCForTest(bool* pRC) { m_pEventRecorder->SetRCForTest(pRC); }
+  void SetValueForTest(WideString* pStr) { m_pValue = pStr; }
+  void SetRCForTest(bool* pRC) { m_pbRc = pRC; }
   void SetStrChangeForTest(WideString* pStrChange) {
-    m_pEventRecorder->SetStrChangeForTest(pStrChange);
+    m_pWideStrChange = pStrChange;
   }
-  void ResetWillCommitForTest() { m_pEventRecorder->ResetWillCommitForTest(); }
+  void ResetWillCommitForTest() { m_bWillCommit = false; }
 
  private:
+  void Initialize(JS_EVENT_T type);
+  void Destroy();
+
   UnownedPtr<CJS_Runtime> const m_pRuntime;
-  std::unique_ptr<CJS_EventRecorder> const m_pEventRecorder;
+  JS_EVENT_T m_eEventType = JET_UNKNOWN;
+  bool m_bValid = false;
+  UnownedPtr<WideString> m_pValue;
+  WideString m_strSourceName;
+  WideString m_strTargetName;
+  WideString m_WideStrChangeDu;
+  WideString m_WideStrChangeEx;
+  UnownedPtr<WideString> m_pWideStrChange;
+  int m_nCommitKey = -1;
+  bool m_bKeyDown = false;
+  bool m_bModifier = false;
+  bool m_bShift = false;
+  int m_nSelEndDu = 0;
+  int m_nSelStartDu = 0;
+  UnownedPtr<int> m_pISelEnd;
+  UnownedPtr<int> m_pISelStart;
+  bool m_bWillCommit = false;
+  bool m_bFieldFull = false;
+  bool m_bRcDu = false;
+  UnownedPtr<bool> m_pbRc;
+  UnownedPtr<const CPDF_Bookmark> m_pTargetBookMark;
+  ObservedPtr<CPDFSDK_FormFillEnvironment> m_pFormFillEnv;
+  ObservedPtr<CPDFSDK_Annot> m_pTargetAnnot;
   bool m_bBusy = false;
 };
 
diff --git a/fxjs/cjs_eventrecorder.cpp b/fxjs/cjs_eventrecorder.cpp
deleted file mode 100644
index dffbc06..0000000
--- a/fxjs/cjs_eventrecorder.cpp
+++ /dev/null
@@ -1,531 +0,0 @@
-// 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
-
-#include "fxjs/cjs_eventrecorder.h"
-
-#include "core/fpdfdoc/cpdf_bookmark.h"
-#include "core/fpdfdoc/cpdf_formfield.h"
-#include "third_party/base/check.h"
-
-CJS_EventRecorder::CJS_EventRecorder(CPDFSDK_FormFillEnvironment* pFormFillEnv)
-    : m_pFormFillEnv(pFormFillEnv) {}
-
-CJS_EventRecorder::~CJS_EventRecorder() = default;
-
-void CJS_EventRecorder::OnApp_Init() {
-  Initialize(JET_APP_INIT);
-}
-
-void CJS_EventRecorder::OnDoc_Open(const WideString& strTargetName) {
-  Initialize(JET_DOC_OPEN);
-  m_strTargetName = strTargetName;
-}
-
-void CJS_EventRecorder::OnDoc_WillPrint() {
-  Initialize(JET_DOC_WILLPRINT);
-}
-
-void CJS_EventRecorder::OnDoc_DidPrint() {
-  Initialize(JET_DOC_DIDPRINT);
-}
-
-void CJS_EventRecorder::OnDoc_WillSave() {
-  Initialize(JET_DOC_WILLSAVE);
-}
-
-void CJS_EventRecorder::OnDoc_DidSave() {
-  Initialize(JET_DOC_DIDSAVE);
-}
-
-void CJS_EventRecorder::OnDoc_WillClose() {
-  Initialize(JET_DOC_WILLCLOSE);
-}
-
-void CJS_EventRecorder::OnPage_Open() {
-  Initialize(JET_PAGE_OPEN);
-}
-
-void CJS_EventRecorder::OnPage_Close() {
-  Initialize(JET_PAGE_CLOSE);
-}
-
-void CJS_EventRecorder::OnPage_InView() {
-  Initialize(JET_PAGE_INVIEW);
-}
-
-void CJS_EventRecorder::OnPage_OutView() {
-  Initialize(JET_PAGE_OUTVIEW);
-}
-
-void CJS_EventRecorder::OnField_MouseEnter(bool bModifier,
-                                           bool bShift,
-                                           CPDF_FormField* pTarget) {
-  Initialize(JET_FIELD_MOUSEENTER);
-  m_bModifier = bModifier;
-  m_bShift = bShift;
-  m_strTargetName = pTarget->GetFullName();
-}
-
-void CJS_EventRecorder::OnField_MouseExit(bool bModifier,
-                                          bool bShift,
-                                          CPDF_FormField* pTarget) {
-  Initialize(JET_FIELD_MOUSEEXIT);
-  m_bModifier = bModifier;
-  m_bShift = bShift;
-  m_strTargetName = pTarget->GetFullName();
-}
-
-void CJS_EventRecorder::OnField_MouseDown(bool bModifier,
-                                          bool bShift,
-                                          CPDF_FormField* pTarget) {
-  Initialize(JET_FIELD_MOUSEDOWN);
-  m_eEventType = JET_FIELD_MOUSEDOWN;
-
-  m_bModifier = bModifier;
-  m_bShift = bShift;
-  m_strTargetName = pTarget->GetFullName();
-}
-
-void CJS_EventRecorder::OnField_MouseUp(bool bModifier,
-                                        bool bShift,
-                                        CPDF_FormField* pTarget) {
-  Initialize(JET_FIELD_MOUSEUP);
-
-  m_bModifier = bModifier;
-  m_bShift = bShift;
-  m_strTargetName = pTarget->GetFullName();
-}
-
-void CJS_EventRecorder::OnField_Focus(bool bModifier,
-                                      bool bShift,
-                                      CPDF_FormField* pTarget,
-                                      WideString* pValue) {
-  DCHECK(pValue);
-  Initialize(JET_FIELD_FOCUS);
-
-  m_bModifier = bModifier;
-  m_bShift = bShift;
-  m_strTargetName = pTarget->GetFullName();
-  m_pValue = pValue;
-}
-
-void CJS_EventRecorder::OnField_Blur(bool bModifier,
-                                     bool bShift,
-                                     CPDF_FormField* pTarget,
-                                     WideString* pValue) {
-  DCHECK(pValue);
-  Initialize(JET_FIELD_BLUR);
-
-  m_bModifier = bModifier;
-  m_bShift = bShift;
-  m_strTargetName = pTarget->GetFullName();
-  m_pValue = pValue;
-}
-
-void CJS_EventRecorder::OnField_Keystroke(WideString* strChange,
-                                          const WideString& strChangeEx,
-                                          bool KeyDown,
-                                          bool bModifier,
-                                          int* pSelEnd,
-                                          int* pSelStart,
-                                          bool bShift,
-                                          CPDF_FormField* pTarget,
-                                          WideString* pValue,
-                                          bool bWillCommit,
-                                          bool bFieldFull,
-                                          bool* pbRc) {
-  DCHECK(pValue);
-  DCHECK(pbRc);
-  DCHECK(pSelStart);
-  DCHECK(pSelEnd);
-
-  Initialize(JET_FIELD_KEYSTROKE);
-
-  m_nCommitKey = 0;
-  m_pWideStrChange = strChange;
-  m_WideStrChangeEx = strChangeEx;
-  m_bKeyDown = KeyDown;
-  m_bModifier = bModifier;
-  m_pISelEnd = pSelEnd;
-  m_pISelStart = pSelStart;
-  m_bShift = bShift;
-  m_strTargetName = pTarget->GetFullName();
-  m_pValue = pValue;
-  m_bWillCommit = bWillCommit;
-  m_pbRc = pbRc;
-  m_bFieldFull = bFieldFull;
-}
-
-void CJS_EventRecorder::OnField_Validate(WideString* strChange,
-                                         const WideString& strChangeEx,
-                                         bool bKeyDown,
-                                         bool bModifier,
-                                         bool bShift,
-                                         CPDF_FormField* pTarget,
-                                         WideString* pValue,
-                                         bool* pbRc) {
-  DCHECK(pValue);
-  DCHECK(pbRc);
-
-  Initialize(JET_FIELD_VALIDATE);
-
-  m_pWideStrChange = strChange;
-  m_WideStrChangeEx = strChangeEx;
-  m_bKeyDown = bKeyDown;
-  m_bModifier = bModifier;
-  m_bShift = bShift;
-  m_strTargetName = pTarget->GetFullName();
-  m_pValue = pValue;
-  m_pbRc = pbRc;
-}
-
-void CJS_EventRecorder::OnField_Calculate(CPDF_FormField* pSource,
-                                          CPDF_FormField* pTarget,
-                                          WideString* pValue,
-                                          bool* pRc) {
-  DCHECK(pValue);
-  DCHECK(pRc);
-
-  Initialize(JET_FIELD_CALCULATE);
-
-  if (pSource)
-    m_strSourceName = pSource->GetFullName();
-  m_strTargetName = pTarget->GetFullName();
-  m_pValue = pValue;
-  m_pbRc = pRc;
-}
-
-void CJS_EventRecorder::OnField_Format(CPDF_FormField* pTarget,
-                                       WideString* pValue) {
-  DCHECK(pValue);
-  Initialize(JET_FIELD_FORMAT);
-
-  m_nCommitKey = 0;
-  m_strTargetName = pTarget->GetFullName();
-  m_pValue = pValue;
-  m_bWillCommit = true;
-}
-
-void CJS_EventRecorder::OnScreen_Focus(bool bModifier,
-                                       bool bShift,
-                                       CPDFSDK_Annot* pScreen) {
-  Initialize(JET_SCREEN_FOCUS);
-
-  m_bModifier = bModifier;
-  m_bShift = bShift;
-  m_pTargetAnnot.Reset(pScreen);
-}
-
-void CJS_EventRecorder::OnScreen_Blur(bool bModifier,
-                                      bool bShift,
-                                      CPDFSDK_Annot* pScreen) {
-  Initialize(JET_SCREEN_BLUR);
-
-  m_bModifier = bModifier;
-  m_bShift = bShift;
-  m_pTargetAnnot.Reset(pScreen);
-}
-
-void CJS_EventRecorder::OnScreen_Open(bool bModifier,
-                                      bool bShift,
-                                      CPDFSDK_Annot* pScreen) {
-  Initialize(JET_SCREEN_OPEN);
-
-  m_bModifier = bModifier;
-  m_bShift = bShift;
-  m_pTargetAnnot.Reset(pScreen);
-}
-
-void CJS_EventRecorder::OnScreen_Close(bool bModifier,
-                                       bool bShift,
-                                       CPDFSDK_Annot* pScreen) {
-  Initialize(JET_SCREEN_CLOSE);
-
-  m_bModifier = bModifier;
-  m_bShift = bShift;
-  m_pTargetAnnot.Reset(pScreen);
-}
-
-void CJS_EventRecorder::OnScreen_MouseDown(bool bModifier,
-                                           bool bShift,
-                                           CPDFSDK_Annot* pScreen) {
-  Initialize(JET_SCREEN_MOUSEDOWN);
-
-  m_bModifier = bModifier;
-  m_bShift = bShift;
-  m_pTargetAnnot.Reset(pScreen);
-}
-
-void CJS_EventRecorder::OnScreen_MouseUp(bool bModifier,
-                                         bool bShift,
-                                         CPDFSDK_Annot* pScreen) {
-  Initialize(JET_SCREEN_MOUSEUP);
-
-  m_bModifier = bModifier;
-  m_bShift = bShift;
-  m_pTargetAnnot.Reset(pScreen);
-}
-
-void CJS_EventRecorder::OnScreen_MouseEnter(bool bModifier,
-                                            bool bShift,
-                                            CPDFSDK_Annot* pScreen) {
-  Initialize(JET_SCREEN_MOUSEENTER);
-
-  m_bModifier = bModifier;
-  m_bShift = bShift;
-  m_pTargetAnnot.Reset(pScreen);
-}
-
-void CJS_EventRecorder::OnScreen_MouseExit(bool bModifier,
-                                           bool bShift,
-                                           CPDFSDK_Annot* pScreen) {
-  Initialize(JET_SCREEN_MOUSEEXIT);
-
-  m_bModifier = bModifier;
-  m_bShift = bShift;
-  m_pTargetAnnot.Reset(pScreen);
-}
-
-void CJS_EventRecorder::OnScreen_InView(bool bModifier,
-                                        bool bShift,
-                                        CPDFSDK_Annot* pScreen) {
-  Initialize(JET_SCREEN_INVIEW);
-  m_bModifier = bModifier;
-  m_bShift = bShift;
-  m_pTargetAnnot.Reset(pScreen);
-}
-
-void CJS_EventRecorder::OnScreen_OutView(bool bModifier,
-                                         bool bShift,
-                                         CPDFSDK_Annot* pScreen) {
-  Initialize(JET_SCREEN_OUTVIEW);
-  m_bModifier = bModifier;
-  m_bShift = bShift;
-  m_pTargetAnnot.Reset(pScreen);
-}
-
-void CJS_EventRecorder::OnLink_MouseUp() {
-  Initialize(JET_LINK_MOUSEUP);
-}
-
-void CJS_EventRecorder::OnBookmark_MouseUp(const CPDF_Bookmark* pBookMark) {
-  Initialize(JET_BOOKMARK_MOUSEUP);
-  m_pTargetBookMark = pBookMark;
-}
-
-void CJS_EventRecorder::OnMenu_Exec(
-    const WideString& strTargetName) {
-  Initialize(JET_MENU_EXEC);
-  m_strTargetName = strTargetName;
-}
-
-void CJS_EventRecorder::OnExternal_Exec() {
-  Initialize(JET_EXTERNAL_EXEC);
-}
-
-void CJS_EventRecorder::OnBatchExec() {
-  Initialize(JET_BATCH_EXEC);
-}
-
-void CJS_EventRecorder::OnConsole_Exec() {
-  Initialize(JET_CONSOLE_EXEC);
-}
-
-void CJS_EventRecorder::Initialize(JS_EVENT_T type) {
-  m_eEventType = type;
-  m_strTargetName.clear();
-  m_strSourceName.clear();
-  m_pWideStrChange = nullptr;
-  m_WideStrChangeDu.clear();
-  m_WideStrChangeEx.clear();
-  m_nCommitKey = -1;
-  m_bKeyDown = false;
-  m_bModifier = false;
-  m_bShift = false;
-  m_pISelEnd = nullptr;
-  m_nSelEndDu = 0;
-  m_pISelStart = nullptr;
-  m_nSelStartDu = 0;
-  m_bWillCommit = false;
-  m_pValue = nullptr;
-  m_bFieldFull = false;
-  m_pbRc = nullptr;
-  m_bRcDu = false;
-  m_pTargetBookMark = nullptr;
-  m_pTargetAnnot.Reset();
-  m_bValid = true;
-}
-
-void CJS_EventRecorder::Destroy() {
-  m_bValid = false;
-}
-
-bool CJS_EventRecorder::IsUserGesture() const {
-  switch (m_eEventType) {
-    case JET_FIELD_MOUSEDOWN:
-    case JET_FIELD_MOUSEUP:
-    case JET_SCREEN_MOUSEDOWN:
-    case JET_SCREEN_MOUSEUP:
-    case JET_BOOKMARK_MOUSEUP:
-    case JET_LINK_MOUSEUP:
-    case JET_FIELD_KEYSTROKE:
-      return true;
-    default:
-      return false;
-  }
-}
-
-WideString& CJS_EventRecorder::Change() {
-  return m_pWideStrChange ? *m_pWideStrChange : m_WideStrChangeDu;
-}
-
-ByteStringView CJS_EventRecorder::Name() const {
-  switch (m_eEventType) {
-    case JET_APP_INIT:
-      return "Init";
-    case JET_BATCH_EXEC:
-      return "Exec";
-    case JET_BOOKMARK_MOUSEUP:
-      return "Mouse Up";
-    case JET_CONSOLE_EXEC:
-      return "Exec";
-    case JET_DOC_DIDPRINT:
-      return "DidPrint";
-    case JET_DOC_DIDSAVE:
-      return "DidSave";
-    case JET_DOC_OPEN:
-      return "Open";
-    case JET_DOC_WILLCLOSE:
-      return "WillClose";
-    case JET_DOC_WILLPRINT:
-      return "WillPrint";
-    case JET_DOC_WILLSAVE:
-      return "WillSave";
-    case JET_EXTERNAL_EXEC:
-      return "Exec";
-    case JET_FIELD_FOCUS:
-    case JET_SCREEN_FOCUS:
-      return "Focus";
-    case JET_FIELD_BLUR:
-    case JET_SCREEN_BLUR:
-      return "Blur";
-    case JET_FIELD_MOUSEDOWN:
-    case JET_SCREEN_MOUSEDOWN:
-      return "Mouse Down";
-    case JET_FIELD_MOUSEUP:
-    case JET_SCREEN_MOUSEUP:
-      return "Mouse Up";
-    case JET_FIELD_MOUSEENTER:
-    case JET_SCREEN_MOUSEENTER:
-      return "Mouse Enter";
-    case JET_FIELD_MOUSEEXIT:
-    case JET_SCREEN_MOUSEEXIT:
-      return "Mouse Exit";
-    case JET_FIELD_CALCULATE:
-      return "Calculate";
-    case JET_FIELD_FORMAT:
-      return "Format";
-    case JET_FIELD_KEYSTROKE:
-      return "Keystroke";
-    case JET_FIELD_VALIDATE:
-      return "Validate";
-    case JET_LINK_MOUSEUP:
-      return "Mouse Up";
-    case JET_MENU_EXEC:
-      return "Exec";
-    case JET_PAGE_OPEN:
-    case JET_SCREEN_OPEN:
-      return "Open";
-    case JET_PAGE_CLOSE:
-    case JET_SCREEN_CLOSE:
-      return "Close";
-    case JET_SCREEN_INVIEW:
-    case JET_PAGE_INVIEW:
-      return "InView";
-    case JET_PAGE_OUTVIEW:
-    case JET_SCREEN_OUTVIEW:
-      return "OutView";
-    default:
-      return "";
-  }
-}
-
-ByteStringView CJS_EventRecorder::Type() const {
-  switch (m_eEventType) {
-    case JET_APP_INIT:
-      return "App";
-    case JET_BATCH_EXEC:
-      return "Batch";
-    case JET_BOOKMARK_MOUSEUP:
-      return "BookMark";
-    case JET_CONSOLE_EXEC:
-      return "Console";
-    case JET_DOC_DIDPRINT:
-    case JET_DOC_DIDSAVE:
-    case JET_DOC_OPEN:
-    case JET_DOC_WILLCLOSE:
-    case JET_DOC_WILLPRINT:
-    case JET_DOC_WILLSAVE:
-      return "Doc";
-    case JET_EXTERNAL_EXEC:
-      return "External";
-    case JET_FIELD_BLUR:
-    case JET_FIELD_FOCUS:
-    case JET_FIELD_MOUSEDOWN:
-    case JET_FIELD_MOUSEENTER:
-    case JET_FIELD_MOUSEEXIT:
-    case JET_FIELD_MOUSEUP:
-    case JET_FIELD_CALCULATE:
-    case JET_FIELD_FORMAT:
-    case JET_FIELD_KEYSTROKE:
-    case JET_FIELD_VALIDATE:
-      return "Field";
-    case JET_SCREEN_FOCUS:
-    case JET_SCREEN_BLUR:
-    case JET_SCREEN_OPEN:
-    case JET_SCREEN_CLOSE:
-    case JET_SCREEN_MOUSEDOWN:
-    case JET_SCREEN_MOUSEUP:
-    case JET_SCREEN_MOUSEENTER:
-    case JET_SCREEN_MOUSEEXIT:
-    case JET_SCREEN_INVIEW:
-    case JET_SCREEN_OUTVIEW:
-      return "Screen";
-    case JET_LINK_MOUSEUP:
-      return "Link";
-    case JET_MENU_EXEC:
-      return "Menu";
-    case JET_PAGE_OPEN:
-    case JET_PAGE_CLOSE:
-    case JET_PAGE_INVIEW:
-    case JET_PAGE_OUTVIEW:
-      return "Page";
-    default:
-      return "";
-  }
-}
-
-bool& CJS_EventRecorder::Rc() {
-  return m_pbRc ? *m_pbRc : m_bRcDu;
-}
-
-int CJS_EventRecorder::SelEnd() const {
-  return m_pISelEnd ? *m_pISelEnd : m_nSelEndDu;
-}
-
-int CJS_EventRecorder::SelStart() const {
-  return m_pISelStart ? *m_pISelStart : m_nSelStartDu;
-}
-
-void CJS_EventRecorder::SetSelEnd(int value) {
-  int& target = m_pISelEnd ? *m_pISelEnd : m_nSelEndDu;
-  target = value;
-}
-
-void CJS_EventRecorder::SetSelStart(int value) {
-  int& target = m_pISelStart ? *m_pISelStart : m_nSelStartDu;
-  target = value;
-}
diff --git a/fxjs/cjs_eventrecorder.h b/fxjs/cjs_eventrecorder.h
deleted file mode 100644
index 399d1f0..0000000
--- a/fxjs/cjs_eventrecorder.h
+++ /dev/null
@@ -1,198 +0,0 @@
-// 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 FXJS_CJS_EVENTRECORDER_H_
-#define FXJS_CJS_EVENTRECORDER_H_
-
-#include "core/fxcrt/fx_string.h"
-#include "core/fxcrt/unowned_ptr.h"
-#include "fpdfsdk/cpdfsdk_annot.h"
-#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
-
-class CPDF_Bookmark;
-class CPDF_FormField;
-
-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_EventRecorder {
- public:
-  explicit CJS_EventRecorder(CPDFSDK_FormFillEnvironment* pFormFillEnv);
-  ~CJS_EventRecorder();
-
-  void OnApp_Init();
-
-  void OnDoc_Open(const WideString& strTargetName);
-  void OnDoc_WillPrint();
-  void OnDoc_DidPrint();
-  void OnDoc_WillSave();
-  void OnDoc_DidSave();
-  void OnDoc_WillClose();
-
-  void OnPage_Open();
-  void OnPage_Close();
-  void OnPage_InView();
-  void OnPage_OutView();
-
-  void OnField_Calculate(CPDF_FormField* pSource,
-                         CPDF_FormField* pTarget,
-                         WideString* Value,
-                         bool* pbRc);
-  void OnField_Format(CPDF_FormField* pTarget, WideString* Value);
-  void OnField_Keystroke(WideString* strChange,
-                         const WideString& strChangeEx,
-                         bool KeyDown,
-                         bool bModifier,
-                         int* nSelEnd,
-                         int* nSelStart,
-                         bool bShift,
-                         CPDF_FormField* pTarget,
-                         WideString* Value,
-                         bool bWillCommit,
-                         bool bFieldFull,
-                         bool* bRc);
-  void OnField_Validate(WideString* strChange,
-                        const WideString& strChangeEx,
-                        bool bKeyDown,
-                        bool bModifier,
-                        bool bShift,
-                        CPDF_FormField* pTarget,
-                        WideString* Value,
-                        bool* bRc);
-  void OnField_MouseDown(bool bModifier, bool bShift, CPDF_FormField* pTarget);
-  void OnField_MouseEnter(bool bModifier, bool bShift, CPDF_FormField* pTarget);
-  void OnField_MouseExit(bool bModifier, bool bShift, CPDF_FormField* pTarget);
-  void OnField_MouseUp(bool bModifier, bool bShift, CPDF_FormField* pTarget);
-  void OnField_Blur(bool bModifier,
-                    bool bShift,
-                    CPDF_FormField* pTarget,
-                    WideString* Value);
-  void OnField_Focus(bool bModifier,
-                     bool bShift,
-                     CPDF_FormField* pTarget,
-                     WideString* Value);
-
-  void OnScreen_Focus(bool bModifier, bool bShift, CPDFSDK_Annot* pScreen);
-  void OnScreen_Blur(bool bModifier, bool bShift, CPDFSDK_Annot* pScreen);
-  void OnScreen_Open(bool bModifier, bool bShift, CPDFSDK_Annot* pScreen);
-  void OnScreen_Close(bool bModifier, bool bShift, CPDFSDK_Annot* pScreen);
-  void OnScreen_MouseDown(bool bModifier, bool bShift, CPDFSDK_Annot* pScreen);
-  void OnScreen_MouseUp(bool bModifier, bool bShift, CPDFSDK_Annot* pScreen);
-  void OnScreen_MouseEnter(bool bModifier, bool bShift, CPDFSDK_Annot* pScreen);
-  void OnScreen_MouseExit(bool bModifier, bool bShift, CPDFSDK_Annot* pScreen);
-  void OnScreen_InView(bool bModifier, bool bShift, CPDFSDK_Annot* pScreen);
-  void OnScreen_OutView(bool bModifier, bool bShift, CPDFSDK_Annot* pScreen);
-
-  void OnBookmark_MouseUp(const CPDF_Bookmark* pBookMark);
-  void OnLink_MouseUp();
-
-  void OnMenu_Exec(const WideString& strTargetName);
-  void OnBatchExec();
-  void OnConsole_Exec();
-  void OnExternal_Exec();
-
-  void Destroy();
-
-  JS_EVENT_T EventType() const { return m_eEventType; }
-  bool IsValid() const { return m_bValid; }
-  bool IsUserGesture() const;
-  WideString& Change();
-  WideString ChangeEx() const { return m_WideStrChangeEx; }
-  WideString SourceName() const { return m_strSourceName; }
-  WideString TargetName() const { return m_strTargetName; }
-  int CommitKey() const { return m_nCommitKey; }
-  bool FieldFull() const { return m_bFieldFull; }
-  bool KeyDown() const { return m_bKeyDown; }
-  bool Modifier() const { return m_bModifier; }
-  ByteStringView Name() const;
-  ByteStringView Type() const;
-  bool& Rc();
-  int SelEnd() const;
-  int SelStart() const;
-  void SetSelEnd(int value);
-  void SetSelStart(int value);
-  bool Shift() const { return m_bShift; }
-  bool HasValue() const { return !!m_pValue; }
-  WideString& Value() { return *m_pValue; }
-  bool WillCommit() const { return m_bWillCommit; }
-  CPDFSDK_FormFillEnvironment* GetFormFillEnvironment() const {
-    return m_pFormFillEnv.Get();
-  }
-
-  void SetValueForTest(WideString* pStr) { m_pValue = pStr; }
-  void SetRCForTest(bool* pRC) { m_pbRc = pRC; }
-  void SetStrChangeForTest(WideString* pStrChange) {
-    m_pWideStrChange = pStrChange;
-  }
-  void ResetWillCommitForTest() { m_bWillCommit = false; }
-
- private:
-  void Initialize(JS_EVENT_T type);
-
-  JS_EVENT_T m_eEventType = JET_UNKNOWN;
-  bool m_bValid = false;
-  UnownedPtr<WideString> m_pValue;
-  WideString m_strSourceName;
-  WideString m_strTargetName;
-  WideString m_WideStrChangeDu;
-  WideString m_WideStrChangeEx;
-  UnownedPtr<WideString> m_pWideStrChange;
-  int m_nCommitKey = -1;
-  bool m_bKeyDown = false;
-  bool m_bModifier = false;
-  bool m_bShift = false;
-  int m_nSelEndDu = 0;
-  int m_nSelStartDu = 0;
-  UnownedPtr<int> m_pISelEnd;
-  UnownedPtr<int> m_pISelStart;
-  bool m_bWillCommit = false;
-  bool m_bFieldFull = false;
-  bool m_bRcDu = false;
-  UnownedPtr<bool> m_pbRc;
-  UnownedPtr<const CPDF_Bookmark> m_pTargetBookMark;
-  ObservedPtr<CPDFSDK_FormFillEnvironment> m_pFormFillEnv;
-  ObservedPtr<CPDFSDK_Annot> m_pTargetAnnot;
-};
-
-#endif  // FXJS_CJS_EVENTRECORDER_H_
diff --git a/fxjs/cjs_field.cpp b/fxjs/cjs_field.cpp
index b217d50..9bf542f 100644
--- a/fxjs/cjs_field.cpp
+++ b/fxjs/cjs_field.cpp
@@ -16,6 +16,7 @@
 #include "core/fpdfdoc/cpdf_formcontrol.h"
 #include "core/fpdfdoc/cpdf_formfield.h"
 #include "core/fpdfdoc/cpdf_interactiveform.h"
+#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
 #include "fpdfsdk/cpdfsdk_helpers.h"
 #include "fpdfsdk/cpdfsdk_interactiveform.h"
 #include "fpdfsdk/cpdfsdk_pageview.h"
diff --git a/fxjs/cjs_field.h b/fxjs/cjs_field.h
index fffb952..e21ba2b 100644
--- a/fxjs/cjs_field.h
+++ b/fxjs/cjs_field.h
@@ -13,6 +13,7 @@
 #include "fxjs/cjs_object.h"
 #include "fxjs/js_define.h"
 
+class CFX_FloatRect;
 class CPDF_FormControl;
 struct CJS_DelayData;
 
diff --git a/fxjs/cjs_global.cpp b/fxjs/cjs_global.cpp
index 19dcd20..0c44ad6 100644
--- a/fxjs/cjs_global.cpp
+++ b/fxjs/cjs_global.cpp
@@ -11,10 +11,10 @@
 #include <vector>
 
 #include "core/fxcrt/fx_extension.h"
+#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
 #include "fxjs/cfx_globaldata.h"
 #include "fxjs/cfx_keyvalue.h"
 #include "fxjs/cjs_event_context.h"
-#include "fxjs/cjs_eventrecorder.h"
 #include "fxjs/cjs_object.h"
 #include "fxjs/fxv8.h"
 #include "fxjs/js_define.h"
diff --git a/fxjs/cjs_publicmethods.cpp b/fxjs/cjs_publicmethods.cpp
index 611c11f..12e5427 100644
--- a/fxjs/cjs_publicmethods.cpp
+++ b/fxjs/cjs_publicmethods.cpp
@@ -26,7 +26,6 @@
 #include "fpdfsdk/cpdfsdk_interactiveform.h"
 #include "fxjs/cjs_color.h"
 #include "fxjs/cjs_event_context.h"
-#include "fxjs/cjs_eventrecorder.h"
 #include "fxjs/cjs_field.h"
 #include "fxjs/cjs_object.h"
 #include "fxjs/cjs_runtime.h"
diff --git a/fxjs/cjs_runtime.cpp b/fxjs/cjs_runtime.cpp
index 95909fb..a263280 100644
--- a/fxjs/cjs_runtime.cpp
+++ b/fxjs/cjs_runtime.cpp
@@ -21,7 +21,6 @@
 #include "fxjs/cjs_document.h"
 #include "fxjs/cjs_event.h"
 #include "fxjs/cjs_event_context.h"
-#include "fxjs/cjs_eventrecorder.h"
 #include "fxjs/cjs_field.h"
 #include "fxjs/cjs_font.h"
 #include "fxjs/cjs_global.h"
diff --git a/fxjs/cjs_runtime.h b/fxjs/cjs_runtime.h
index 5e4dfad..06465bd 100644
--- a/fxjs/cjs_runtime.h
+++ b/fxjs/cjs_runtime.h
@@ -15,10 +15,9 @@
 #include "core/fxcrt/cfx_timer.h"
 #include "core/fxcrt/observed_ptr.h"
 #include "fxjs/cfxjs_engine.h"
-#include "fxjs/cjs_eventrecorder.h"
+#include "fxjs/cjs_event_context.h"
 #include "fxjs/ijs_runtime.h"
 
-class CJS_EventContext;
 class CPDFSDK_FormFillEnvironment;
 
 class CJS_Runtime final : public IJS_Runtime,
diff --git a/fxjs/cjs_util.cpp b/fxjs/cjs_util.cpp
index f7b4742..c316e00 100644
--- a/fxjs/cjs_util.cpp
+++ b/fxjs/cjs_util.cpp
@@ -16,7 +16,6 @@
 #include "build/build_config.h"
 #include "core/fxcrt/fx_extension.h"
 #include "fxjs/cjs_event_context.h"
-#include "fxjs/cjs_eventrecorder.h"
 #include "fxjs/cjs_object.h"
 #include "fxjs/cjs_publicmethods.h"
 #include "fxjs/cjs_runtime.h"
diff --git a/fxjs/ijs_runtime.cpp b/fxjs/ijs_runtime.cpp
index 496d662..58a481d 100644
--- a/fxjs/ijs_runtime.cpp
+++ b/fxjs/ijs_runtime.cpp
@@ -4,6 +4,7 @@
 
 #include "fxjs/ijs_runtime.h"
 
+#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
 #include "fxjs/cjs_runtimestub.h"
 
 #ifdef PDF_ENABLE_V8