Garbage collect the FWL layer objects.

Bug: pdfium:1563
Change-Id: I639bda5247289b2cacae08f46ec1da671868e5a3
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/72913
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/xfa/DEPS b/xfa/DEPS
index dba1791..02cbbab 100644
--- a/xfa/DEPS
+++ b/xfa/DEPS
@@ -1,6 +1,8 @@
 include_rules = [
   '+core',
   '+fxbarcode',
+  '+fxjs/gc',
+  '+v8/include/cppgc',
 
   # xfa/fwl should be standalone. https://crbug.com/pdfium/507
   '-xfa/fwl',
diff --git a/xfa/fwl/BUILD.gn b/xfa/fwl/BUILD.gn
index 634237e..53cd213 100644
--- a/xfa/fwl/BUILD.gn
+++ b/xfa/fwl/BUILD.gn
@@ -110,9 +110,11 @@
     "../../core/fxcrt",
     "../../core/fxge",
     "../../fxbarcode",
+    "../../fxjs",
     "../fde",
     "../fgas",
     "../fxgraphics",
+    "//v8:cppgc",
   ]
   configs += [
     "../../:pdfium_core_config",
diff --git a/xfa/fwl/cfwl_barcode.h b/xfa/fwl/cfwl_barcode.h
index d2cd716..5f3c4c4 100644
--- a/xfa/fwl/cfwl_barcode.h
+++ b/xfa/fwl/cfwl_barcode.h
@@ -31,7 +31,7 @@
 
 class CFWL_Barcode final : public CFWL_Edit {
  public:
-  explicit CFWL_Barcode(const CFWL_App* pApp);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CFWL_Barcode() override;
 
   // CFWL_Widget
@@ -66,6 +66,8 @@
     kEncodeSuccess,
   };
 
+  explicit CFWL_Barcode(const CFWL_App* pApp);
+
   void GenerateBarcodeImageCache();
   void CreateBarcodeEngine();
 
diff --git a/xfa/fwl/cfwl_caret.h b/xfa/fwl/cfwl_caret.h
index f01eba8..8eae25d 100644
--- a/xfa/fwl/cfwl_caret.h
+++ b/xfa/fwl/cfwl_caret.h
@@ -15,9 +15,7 @@
 
 class CFWL_Caret final : public CFWL_Widget, public CFX_Timer::CallbackIface {
  public:
-  CFWL_Caret(const CFWL_App* app,
-             const Properties& properties,
-             CFWL_Widget* pOuter);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CFWL_Caret() override;
 
   // CFWL_Widget:
@@ -35,6 +33,10 @@
   void HideCaret();
 
  private:
+  CFWL_Caret(const CFWL_App* app,
+             const Properties& properties,
+             CFWL_Widget* pOuter);
+
   void DrawCaretBK(CXFA_Graphics* pGraphics, const CFX_Matrix* pMatrix);
 
   std::unique_ptr<CFX_Timer> m_pTimer;
diff --git a/xfa/fwl/cfwl_checkbox.h b/xfa/fwl/cfwl_checkbox.h
index ae301f3..4f417dd 100644
--- a/xfa/fwl/cfwl_checkbox.h
+++ b/xfa/fwl/cfwl_checkbox.h
@@ -30,7 +30,7 @@
 
 class CFWL_CheckBox final : public CFWL_Widget {
  public:
-  explicit CFWL_CheckBox(const CFWL_App* pApp);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CFWL_CheckBox() override;
 
   // CFWL_Widget
@@ -45,6 +45,8 @@
   void SetBoxSize(float fHeight);
 
  private:
+  explicit CFWL_CheckBox(const CFWL_App* pApp);
+
   void SetCheckState(int32_t iCheck);
   void Layout();
   uint32_t GetPartStates() const;
diff --git a/xfa/fwl/cfwl_combobox.cpp b/xfa/fwl/cfwl_combobox.cpp
index 4cace71..450368d 100644
--- a/xfa/fwl/cfwl_combobox.cpp
+++ b/xfa/fwl/cfwl_combobox.cpp
@@ -7,9 +7,9 @@
 #include "xfa/fwl/cfwl_combobox.h"
 
 #include <algorithm>
-#include <memory>
 #include <utility>
 
+#include "v8/include/cppgc/visitor.h"
 #include "xfa/fde/cfde_texteditengine.h"
 #include "xfa/fde/cfde_textout.h"
 #include "xfa/fwl/cfwl_app.h"
@@ -30,8 +30,13 @@
 
 CFWL_ComboBox::CFWL_ComboBox(const CFWL_App* app)
     : CFWL_Widget(app, Properties(), nullptr),
-      m_pEdit(std::make_unique<CFWL_ComboEdit>(app, Properties(), this)),
-      m_pListBox(std::make_unique<CFWL_ComboList>(
+      m_pEdit(cppgc::MakeGarbageCollected<CFWL_ComboEdit>(
+          app->GetHeap()->GetAllocationHandle(),
+          app,
+          Properties(),
+          this)),
+      m_pListBox(cppgc::MakeGarbageCollected<CFWL_ComboList>(
+          app->GetHeap()->GetAllocationHandle(),
           app,
           Properties{FWL_WGTSTYLE_Border | FWL_WGTSTYLE_VScroll, 0,
                      FWL_WGTSTATE_Invisible},
@@ -39,6 +44,12 @@
 
 CFWL_ComboBox::~CFWL_ComboBox() = default;
 
+void CFWL_ComboBox::Trace(cppgc::Visitor* visitor) const {
+  CFWL_Widget::Trace(visitor);
+  visitor->Trace(m_pEdit);
+  visitor->Trace(m_pListBox);
+}
+
 FWL_Type CFWL_ComboBox::GetClassID() const {
   return FWL_Type::ComboBox;
 }
@@ -123,8 +134,7 @@
 }
 
 WideString CFWL_ComboBox::GetTextByIndex(int32_t iIndex) const {
-  auto* pItem = static_cast<CFWL_ListBox::Item*>(
-      m_pListBox->GetItem(m_pListBox.get(), iIndex));
+  CFWL_ListBox::Item* pItem = m_pListBox->GetItem(m_pListBox, iIndex);
   return pItem ? pItem->GetText() : WideString();
 }
 
@@ -208,7 +218,7 @@
     if (!preEvent.GetSrcTarget())
       return;
 
-    CFWL_ComboList* pComboList = m_pListBox.get();
+    CFWL_ComboList* pComboList = m_pListBox;
     int32_t iItems = pComboList->CountItems(nullptr);
     if (iItems < 1)
       return;
@@ -290,7 +300,7 @@
 
   if (m_iCurSel >= 0) {
     CFWL_ListBox::Item* hItem = m_pListBox->GetItem(this, m_iCurSel);
-    ScopedUpdateLock update_lock(m_pEdit.get());
+    ScopedUpdateLock update_lock(m_pEdit);
     m_pEdit->SetText(hItem ? hItem->GetText() : WideString());
   }
   m_pEdit->Update();
@@ -474,13 +484,13 @@
   if (bSet) {
     m_Properties.m_dwStates |= FWL_WGTSTATE_Focused;
     if ((m_pEdit->GetStates() & FWL_WGTSTATE_Focused) == 0) {
-      CFWL_MessageSetFocus msg(nullptr, m_pEdit.get());
+      CFWL_MessageSetFocus msg(nullptr, m_pEdit);
       m_pEdit->GetDelegate()->OnProcessMessage(&msg);
     }
   } else {
     m_Properties.m_dwStates &= ~FWL_WGTSTATE_Focused;
     ShowDropList(false);
-    CFWL_MessageKillFocus msg(m_pEdit.get());
+    CFWL_MessageKillFocus msg(m_pEdit);
     m_pEdit->GetDelegate()->OnProcessMessage(&msg);
   }
 }
@@ -490,7 +500,7 @@
   const bool bUp = dwKeyCode == XFA_FWL_VKEY_Up;
   const bool bDown = dwKeyCode == XFA_FWL_VKEY_Down;
   if (bUp || bDown) {
-    CFWL_ComboList* pComboList = m_pListBox.get();
+    CFWL_ComboList* pComboList = m_pListBox;
     int32_t iCount = pComboList->CountItems(nullptr);
     if (iCount < 1)
       return;
diff --git a/xfa/fwl/cfwl_combobox.h b/xfa/fwl/cfwl_combobox.h
index 6f9293b..aa8d35e 100644
--- a/xfa/fwl/cfwl_combobox.h
+++ b/xfa/fwl/cfwl_combobox.h
@@ -7,8 +7,6 @@
 #ifndef XFA_FWL_CFWL_COMBOBOX_H_
 #define XFA_FWL_CFWL_COMBOBOX_H_
 
-#include <memory>
-
 #include "xfa/fwl/cfwl_comboedit.h"
 #include "xfa/fwl/cfwl_combolist.h"
 #include "xfa/fwl/cfwl_listbox.h"
@@ -36,10 +34,11 @@
 
 class CFWL_ComboBox final : public CFWL_Widget {
  public:
-  explicit CFWL_ComboBox(const CFWL_App* pApp);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CFWL_ComboBox() override;
 
   // CFWL_Widget
+  void Trace(cppgc::Visitor* visitor) const override;
   FWL_Type GetClassID() const override;
   void ModifyStylesEx(uint32_t dwStylesExAdded,
                       uint32_t dwStylesExRemoved) override;
@@ -88,12 +87,14 @@
   void EditModifyStylesEx(uint32_t dwStylesExAdded, uint32_t dwStylesExRemoved);
   void ShowDropList(bool bActivate);
 
-  CFWL_ComboEdit* GetComboEdit() const { return m_pEdit.get(); }
+  CFWL_ComboEdit* GetComboEdit() const { return m_pEdit; }
 
   void ProcessSelChanged(bool bLButtonUp);
   int32_t GetCurrentSelection() const { return m_iCurSel; }
 
  private:
+  explicit CFWL_ComboBox(const CFWL_App* pApp);
+
   bool IsDropDownStyle() const {
     return !!(m_Properties.m_dwStyleExes & FWL_STYLEEXT_CMB_DropDown);
   }
@@ -115,8 +116,8 @@
   CFX_RectF m_ClientRect;
   CFX_RectF m_ContentRect;
   CFX_RectF m_BtnRect;
-  std::unique_ptr<CFWL_ComboEdit> const m_pEdit;
-  std::unique_ptr<CFWL_ComboList> const m_pListBox;
+  cppgc::Member<CFWL_ComboEdit> const m_pEdit;
+  cppgc::Member<CFWL_ComboList> const m_pListBox;
   int32_t m_iCurSel = -1;
   int32_t m_iBtnState = CFWL_PartState_Normal;
 };
diff --git a/xfa/fwl/cfwl_comboedit.h b/xfa/fwl/cfwl_comboedit.h
index b6fd11a..8eb6712 100644
--- a/xfa/fwl/cfwl_comboedit.h
+++ b/xfa/fwl/cfwl_comboedit.h
@@ -12,9 +12,7 @@
 
 class CFWL_ComboEdit final : public CFWL_Edit {
  public:
-  CFWL_ComboEdit(const CFWL_App* app,
-                 const Properties& properties,
-                 CFWL_Widget* pOuter);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CFWL_ComboEdit() override;
 
   // CFWL_Edit:
@@ -23,6 +21,11 @@
   void ClearSelected();
   void SetSelected();
   void FlagFocus(bool bSet);
+
+ private:
+  CFWL_ComboEdit(const CFWL_App* app,
+                 const Properties& properties,
+                 CFWL_Widget* pOuter);
 };
 
 #endif  // XFA_FWL_CFWL_COMBOEDIT_H_
diff --git a/xfa/fwl/cfwl_combolist.cpp b/xfa/fwl/cfwl_combolist.cpp
index 6a34453..c7b59bd 100644
--- a/xfa/fwl/cfwl_combolist.cpp
+++ b/xfa/fwl/cfwl_combolist.cpp
@@ -23,6 +23,8 @@
   ASSERT(pOuter);
 }
 
+CFWL_ComboList::~CFWL_ComboList() = default;
+
 int32_t CFWL_ComboList::MatchItem(WideStringView wsMatch) {
   if (wsMatch.IsEmpty())
     return -1;
diff --git a/xfa/fwl/cfwl_combolist.h b/xfa/fwl/cfwl_combolist.h
index cb7f086..550a44b 100644
--- a/xfa/fwl/cfwl_combolist.h
+++ b/xfa/fwl/cfwl_combolist.h
@@ -12,9 +12,8 @@
 
 class CFWL_ComboList final : public CFWL_ListBox {
  public:
-  CFWL_ComboList(const CFWL_App* app,
-                 const Properties& properties,
-                 CFWL_Widget* pOuter);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
+  ~CFWL_ComboList() override;
 
   // CFWL_ListBox.
   void OnProcessMessage(CFWL_Message* pMessage) override;
@@ -24,6 +23,10 @@
   void SetNotifyOwner(bool notify) { m_bNotifyOwner = notify; }
 
  private:
+  CFWL_ComboList(const CFWL_App* app,
+                 const Properties& properties,
+                 CFWL_Widget* pOuter);
+
   CFX_PointF ClientToOuter(const CFX_PointF& point);
   void OnDropListFocusChanged(CFWL_Message* pMsg, bool bSet);
   void OnDropListMouseMove(CFWL_MessageMouse* pMsg);
diff --git a/xfa/fwl/cfwl_datetimeedit.h b/xfa/fwl/cfwl_datetimeedit.h
index 36e9af3..c89635e 100644
--- a/xfa/fwl/cfwl_datetimeedit.h
+++ b/xfa/fwl/cfwl_datetimeedit.h
@@ -12,13 +12,16 @@
 
 class CFWL_DateTimeEdit final : public CFWL_Edit {
  public:
-  CFWL_DateTimeEdit(const CFWL_App* app,
-                    const Properties& properties,
-                    CFWL_Widget* pOuter);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CFWL_DateTimeEdit() override;
 
   // CFWL_Edit:
   void OnProcessMessage(CFWL_Message* pMessage) override;
+
+ private:
+  CFWL_DateTimeEdit(const CFWL_App* app,
+                    const Properties& properties,
+                    CFWL_Widget* pOuter);
 };
 
 #endif  // XFA_FWL_CFWL_DATETIMEEDIT_H_
diff --git a/xfa/fwl/cfwl_datetimepicker.cpp b/xfa/fwl/cfwl_datetimepicker.cpp
index 8f121e3..3418f41 100644
--- a/xfa/fwl/cfwl_datetimepicker.cpp
+++ b/xfa/fwl/cfwl_datetimepicker.cpp
@@ -6,9 +6,10 @@
 
 #include "xfa/fwl/cfwl_datetimepicker.h"
 
-#include <memory>
 #include <utility>
 
+#include "v8/include/cppgc/visitor.h"
+#include "xfa/fwl/cfwl_app.h"
 #include "xfa/fwl/cfwl_event.h"
 #include "xfa/fwl/cfwl_eventselectchanged.h"
 #include "xfa/fwl/cfwl_messagemouse.h"
@@ -27,8 +28,13 @@
     : CFWL_Widget(app,
                   Properties{0, FWL_STYLEEXT_DTP_ShortDateFormat, 0},
                   nullptr),
-      m_pEdit(std::make_unique<CFWL_DateTimeEdit>(app, Properties(), this)),
-      m_pMonthCal(std::make_unique<CFWL_MonthCalendar>(
+      m_pEdit(cppgc::MakeGarbageCollected<CFWL_DateTimeEdit>(
+          app->GetHeap()->GetAllocationHandle(),
+          app,
+          Properties(),
+          this)),
+      m_pMonthCal(cppgc::MakeGarbageCollected<CFWL_MonthCalendar>(
+          app->GetHeap()->GetAllocationHandle(),
           app,
           Properties{FWL_WGTSTYLE_Popup | FWL_WGTSTYLE_Border, 0,
                      FWL_WGTSTATE_Invisible},
@@ -36,12 +42,21 @@
   m_pMonthCal->SetWidgetRect(
       CFX_RectF(0, 0, m_pMonthCal->GetAutosizedWidgetRect().Size()));
 
-  RegisterEventTarget(m_pMonthCal.get());
-  RegisterEventTarget(m_pEdit.get());
+  RegisterEventTarget(m_pMonthCal);
+  RegisterEventTarget(m_pEdit);
 }
 
-CFWL_DateTimePicker::~CFWL_DateTimePicker() {
+CFWL_DateTimePicker::~CFWL_DateTimePicker() = default;
+
+void CFWL_DateTimePicker::PreFinalize() {
   UnregisterEventTarget();
+  CFWL_Widget::PreFinalize();
+}
+
+void CFWL_DateTimePicker::Trace(cppgc::Visitor* visitor) const {
+  CFWL_Widget::Trace(visitor);
+  visitor->Trace(m_pEdit);
+  visitor->Trace(m_pMonthCal);
 }
 
 FWL_Type CFWL_DateTimePicker::GetClassID() const {
@@ -217,7 +232,7 @@
     m_pMonthCal->SetStates(FWL_WGTSTATE_Invisible);
 
   if (bActivate) {
-    CFWL_MessageSetFocus msg(m_pEdit.get(), m_pMonthCal.get());
+    CFWL_MessageSetFocus msg(m_pEdit, m_pMonthCal);
     m_pEdit->GetDelegate()->OnProcessMessage(&msg);
   }
 
@@ -362,7 +377,7 @@
           CFX_RectF(m_WidgetRect.width, 0, m_fBtn, m_WidgetRect.height - 1);
     }
     rtInvalidate = m_BtnRect;
-    pMsg->SetDstTarget(m_pEdit.get());
+    pMsg->SetDstTarget(m_pEdit);
     m_pEdit->GetDelegate()->OnProcessMessage(pMsg);
   } else {
     m_Properties.m_dwStates &= ~FWL_WGTSTATE_Focused;
@@ -370,7 +385,7 @@
     if (IsMonthCalendarVisible())
       ShowMonthCalendar(false);
     if (m_pEdit->GetStates() & FWL_WGTSTATE_Focused) {
-      pMsg->SetSrcTarget(m_pEdit.get());
+      pMsg->SetSrcTarget(m_pEdit);
       m_pEdit->GetDelegate()->OnProcessMessage(pMsg);
     }
   }
diff --git a/xfa/fwl/cfwl_datetimepicker.h b/xfa/fwl/cfwl_datetimepicker.h
index 83eeb88..e2263f7 100644
--- a/xfa/fwl/cfwl_datetimepicker.h
+++ b/xfa/fwl/cfwl_datetimepicker.h
@@ -7,9 +7,9 @@
 #ifndef XFA_FWL_CFWL_DATETIMEPICKER_H_
 #define XFA_FWL_CFWL_DATETIMEPICKER_H_
 
-#include <memory>
 #include <utility>
 
+#include "v8/include/cppgc/member.h"
 #include "xfa/fwl/cfwl_datetimeedit.h"
 #include "xfa/fwl/cfwl_event.h"
 #include "xfa/fwl/cfwl_monthcalendar.h"
@@ -30,10 +30,12 @@
 
 class CFWL_DateTimePicker final : public CFWL_Widget {
  public:
-  explicit CFWL_DateTimePicker(const CFWL_App* pApp);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CFWL_DateTimePicker() override;
 
-  // CFWL_Widget
+  // CFWL_Widget:
+  void PreFinalize() override;
+  void Trace(cppgc::Visitor* visitor) const override;
   FWL_Type GetClassID() const override;
   void Update() override;
   FWL_WidgetHit HitTest(const CFX_PointF& point) override;
@@ -74,6 +76,8 @@
   void ProcessSelChanged(int32_t iYear, int32_t iMonth, int32_t iDay);
 
  private:
+  explicit CFWL_DateTimePicker(const CFWL_App* pApp);
+
   void DrawDropDownButton(CXFA_Graphics* pGraphics, const CFX_Matrix* pMatrix);
   WideString FormatDateString(int32_t iYear, int32_t iMonth, int32_t iDay);
   void ResetEditAlignment();
@@ -86,7 +90,6 @@
   void OnLButtonUp(CFWL_MessageMouse* pMsg);
   void OnMouseMove(CFWL_MessageMouse* pMsg);
   void OnMouseLeave(CFWL_MessageMouse* pMsg);
-
   bool NeedsToShowButton() const;
 
   bool m_bLBtnDown = false;
@@ -97,8 +100,8 @@
   float m_fBtn = 0.0f;
   CFX_RectF m_BtnRect;
   CFX_RectF m_ClientRect;
-  std::unique_ptr<CFWL_DateTimeEdit> const m_pEdit;
-  std::unique_ptr<CFWL_MonthCalendar> const m_pMonthCal;
+  cppgc::Member<CFWL_DateTimeEdit> const m_pEdit;
+  cppgc::Member<CFWL_MonthCalendar> const m_pMonthCal;
 };
 
 #endif  // XFA_FWL_CFWL_DATETIMEPICKER_H_
diff --git a/xfa/fwl/cfwl_edit.cpp b/xfa/fwl/cfwl_edit.cpp
index 47a9bd6..f19b1fc 100644
--- a/xfa/fwl/cfwl_edit.cpp
+++ b/xfa/fwl/cfwl_edit.cpp
@@ -15,6 +15,7 @@
 #include "core/fxge/cfx_renderdevice.h"
 #include "core/fxge/text_char_pos.h"
 #include "third_party/base/stl_util.h"
+#include "v8/include/cppgc/visitor.h"
 #include "xfa/fde/cfde_textout.h"
 #include "xfa/fgas/font/cfgas_gefont.h"
 #include "xfa/fwl/cfwl_app.h"
@@ -52,10 +53,20 @@
   m_pEditEngine->SetDelegate(this);
 }
 
-CFWL_Edit::~CFWL_Edit() {
+CFWL_Edit::~CFWL_Edit() = default;
+
+void CFWL_Edit::PreFinalize() {
   m_pEditEngine->SetDelegate(nullptr);
   if (m_Properties.m_dwStates & FWL_WGTSTATE_Focused)
     HideCaret(nullptr);
+  CFWL_Widget::PreFinalize();
+}
+
+void CFWL_Edit::Trace(cppgc::Visitor* visitor) const {
+  CFWL_Widget::Trace(visitor);
+  visitor->Trace(m_pVertScrollBar);
+  visitor->Trace(m_pHorzScrollBar);
+  visitor->Trace(m_pCaret);
 }
 
 FWL_Type CFWL_Edit::GetClassID() const {
@@ -564,7 +575,7 @@
 }
 
 bool CFWL_Edit::UpdateOffset(CFWL_ScrollBar* pScrollBar, float fPosChanged) {
-  if (pScrollBar == m_pHorzScrollBar.get())
+  if (pScrollBar == m_pHorzScrollBar)
     m_fScrollOffsetX += fPosChanged;
   else
     m_fScrollOffsetY += fPosChanged;
@@ -631,7 +642,7 @@
     CFX_RectF rtScroll = m_pHorzScrollBar->GetWidgetRect();
     if (rtScroll.width < contents_bounds.width) {
       {
-        ScopedUpdateLock update_lock(m_pHorzScrollBar.get());
+        ScopedUpdateLock update_lock(m_pHorzScrollBar);
         float fRange = contents_bounds.width - rtScroll.width;
         m_pHorzScrollBar->SetRange(0.0f, fRange);
 
@@ -643,15 +654,15 @@
         m_pHorzScrollBar->RemoveStates(FWL_WGTSTATE_Disabled);
       }
       m_pHorzScrollBar->Update();
-      pRepaint = m_pHorzScrollBar.get();
+      pRepaint = m_pHorzScrollBar;
     } else if ((m_pHorzScrollBar->GetStates() & FWL_WGTSTATE_Disabled) == 0) {
       {
-        ScopedUpdateLock update_lock(m_pHorzScrollBar.get());
+        ScopedUpdateLock update_lock(m_pHorzScrollBar);
         m_pHorzScrollBar->SetRange(0, -1);
         m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Disabled);
       }
       m_pHorzScrollBar->Update();
-      pRepaint = m_pHorzScrollBar.get();
+      pRepaint = m_pHorzScrollBar;
     }
   }
 
@@ -659,7 +670,7 @@
     CFX_RectF rtScroll = m_pVertScrollBar->GetWidgetRect();
     if (rtScroll.height < contents_bounds.height) {
       {
-        ScopedUpdateLock update_lock(m_pHorzScrollBar.get());
+        ScopedUpdateLock update_lock(m_pHorzScrollBar);
         float fStep = m_pEditEngine->GetLineSpace();
         float fRange =
             std::max(contents_bounds.height - m_EngineRect.height, fStep);
@@ -673,15 +684,15 @@
         m_pVertScrollBar->RemoveStates(FWL_WGTSTATE_Disabled);
       }
       m_pVertScrollBar->Update();
-      pRepaint = m_pVertScrollBar.get();
+      pRepaint = m_pVertScrollBar;
     } else if ((m_pVertScrollBar->GetStates() & FWL_WGTSTATE_Disabled) == 0) {
       {
-        ScopedUpdateLock update_lock(m_pHorzScrollBar.get());
+        ScopedUpdateLock update_lock(m_pHorzScrollBar);
         m_pVertScrollBar->SetRange(0, -1);
         m_pVertScrollBar->SetStates(FWL_WGTSTATE_Disabled);
       }
       m_pVertScrollBar->Update();
-      pRepaint = m_pVertScrollBar.get();
+      pRepaint = m_pVertScrollBar;
     }
   }
   return pRepaint;
@@ -835,8 +846,8 @@
   if (m_pVertScrollBar)
     return;
 
-  m_pVertScrollBar = std::make_unique<CFWL_ScrollBar>(
-      GetFWLApp(),
+  m_pVertScrollBar = cppgc::MakeGarbageCollected<CFWL_ScrollBar>(
+      GetFWLApp()->GetHeap()->GetAllocationHandle(), GetFWLApp(),
       Properties{0, FWL_STYLEEXT_SCB_Vert,
                  FWL_WGTSTATE_Disabled | FWL_WGTSTATE_Invisible},
       this);
@@ -846,8 +857,8 @@
   if (m_pHorzScrollBar)
     return;
 
-  m_pHorzScrollBar = std::make_unique<CFWL_ScrollBar>(
-      GetFWLApp(),
+  m_pHorzScrollBar = cppgc::MakeGarbageCollected<CFWL_ScrollBar>(
+      GetFWLApp()->GetHeap()->GetAllocationHandle(), GetFWLApp(),
       Properties{0, FWL_STYLEEXT_SCB_Horz,
                  FWL_WGTSTATE_Disabled | FWL_WGTSTATE_Invisible},
       this);
@@ -920,7 +931,9 @@
   if (m_pCaret)
     return;
 
-  m_pCaret = std::make_unique<CFWL_Caret>(GetFWLApp(), Properties(), this);
+  m_pCaret = cppgc::MakeGarbageCollected<CFWL_Caret>(
+      GetFWLApp()->GetHeap()->GetAllocationHandle(), GetFWLApp(), Properties(),
+      this);
   m_pCaret->SetStates(m_Properties.m_dwStates);
   UpdateCursorRect();
 }
@@ -1006,8 +1019,8 @@
     return;
 
   CFWL_Widget* pSrcTarget = pEvent->GetSrcTarget();
-  if ((pSrcTarget == m_pVertScrollBar.get() && m_pVertScrollBar) ||
-      (pSrcTarget == m_pHorzScrollBar.get() && m_pHorzScrollBar)) {
+  if ((pSrcTarget == m_pVertScrollBar && m_pVertScrollBar) ||
+      (pSrcTarget == m_pHorzScrollBar && m_pHorzScrollBar)) {
     CFWL_EventScroll* pScrollEvent = static_cast<CFWL_EventScroll*>(pEvent);
     OnScroll(static_cast<CFWL_ScrollBar*>(pSrcTarget),
              pScrollEvent->m_iScrollCode, pScrollEvent->m_fPos);
diff --git a/xfa/fwl/cfwl_edit.h b/xfa/fwl/cfwl_edit.h
index 5e451ae..078ef34 100644
--- a/xfa/fwl/cfwl_edit.h
+++ b/xfa/fwl/cfwl_edit.h
@@ -44,12 +44,12 @@
 
 class CFWL_Edit : public CFWL_Widget, public CFDE_TextEditEngine::Delegate {
  public:
-  CFWL_Edit(const CFWL_App* app,
-            const Properties& properties,
-            CFWL_Widget* pOuter);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CFWL_Edit() override;
 
   // CFWL_Widget:
+  void PreFinalize() override;
+  void Trace(cppgc::Visitor* visitor) const override;
   FWL_Type GetClassID() const override;
   CFX_RectF GetAutosizedWidgetRect() override;
   CFX_RectF GetWidgetRect() override;
@@ -96,6 +96,10 @@
   void SetScrollOffset(float fScrollOffset) override;
 
  protected:
+  CFWL_Edit(const CFWL_App* app,
+            const Properties& properties,
+            CFWL_Widget* pOuter);
+
   void ShowCaret(CFX_RectF* pRect);
   void HideCaret(CFX_RectF* pRect);
   const CFX_RectF& GetRTClient() const { return m_ClientRect; }
@@ -157,9 +161,9 @@
   float m_fFontSize = 0.0f;
   size_t m_CursorPosition = 0;
   std::unique_ptr<CFDE_TextEditEngine> const m_pEditEngine;
-  std::unique_ptr<CFWL_ScrollBar> m_pVertScrollBar;
-  std::unique_ptr<CFWL_ScrollBar> m_pHorzScrollBar;
-  std::unique_ptr<CFWL_Caret> m_pCaret;
+  cppgc::Member<CFWL_ScrollBar> m_pVertScrollBar;
+  cppgc::Member<CFWL_ScrollBar> m_pHorzScrollBar;
+  cppgc::Member<CFWL_Caret> m_pCaret;
   WideString m_wsCache;
   WideString m_wsFont;
 };
diff --git a/xfa/fwl/cfwl_listbox.cpp b/xfa/fwl/cfwl_listbox.cpp
index 27f694e..a52c7d7 100644
--- a/xfa/fwl/cfwl_listbox.cpp
+++ b/xfa/fwl/cfwl_listbox.cpp
@@ -11,6 +11,7 @@
 #include <utility>
 
 #include "third_party/base/stl_util.h"
+#include "v8/include/cppgc/visitor.h"
 #include "xfa/fde/cfde_textout.h"
 #include "xfa/fwl/cfwl_app.h"
 #include "xfa/fwl/cfwl_messagekey.h"
@@ -35,6 +36,12 @@
 
 CFWL_ListBox::~CFWL_ListBox() = default;
 
+void CFWL_ListBox::Trace(cppgc::Visitor* visitor) const {
+  CFWL_Widget::Trace(visitor);
+  visitor->Trace(m_pHorzScrollBar);
+  visitor->Trace(m_pVertScrollBar);
+}
+
 FWL_Type CFWL_ListBox::GetClassID() const {
   return FWL_Type::ListBox;
 }
@@ -582,23 +589,22 @@
   if (m_pVertScrollBar)
     return;
 
-  m_pVertScrollBar = std::make_unique<CFWL_ScrollBar>(
-      GetFWLApp(), Properties{0, FWL_STYLEEXT_SCB_Vert, FWL_WGTSTATE_Invisible},
-      this);
+  m_pVertScrollBar = cppgc::MakeGarbageCollected<CFWL_ScrollBar>(
+      GetFWLApp()->GetHeap()->GetAllocationHandle(), GetFWLApp(),
+      Properties{0, FWL_STYLEEXT_SCB_Vert, FWL_WGTSTATE_Invisible}, this);
 }
 
 void CFWL_ListBox::InitHorizontalScrollBar() {
   if (m_pHorzScrollBar)
     return;
 
-  m_pHorzScrollBar = std::make_unique<CFWL_ScrollBar>(
-      GetFWLApp(), Properties{0, FWL_STYLEEXT_SCB_Horz, FWL_WGTSTATE_Invisible},
-      this);
+  m_pHorzScrollBar = cppgc::MakeGarbageCollected<CFWL_ScrollBar>(
+      GetFWLApp()->GetHeap()->GetAllocationHandle(), GetFWLApp(),
+      Properties{0, FWL_STYLEEXT_SCB_Horz, FWL_WGTSTATE_Invisible}, this);
 }
 
 bool CFWL_ListBox::IsShowScrollBar(bool bVert) {
-  CFWL_ScrollBar* pScrollbar =
-      bVert ? m_pVertScrollBar.get() : m_pHorzScrollBar.get();
+  CFWL_ScrollBar* pScrollbar = bVert ? m_pVertScrollBar : m_pHorzScrollBar;
   if (!pScrollbar || !pScrollbar->IsVisible())
     return false;
 
@@ -655,8 +661,8 @@
     return;
 
   CFWL_Widget* pSrcTarget = pEvent->GetSrcTarget();
-  if ((pSrcTarget == m_pVertScrollBar.get() && m_pVertScrollBar) ||
-      (pSrcTarget == m_pHorzScrollBar.get() && m_pHorzScrollBar)) {
+  if ((pSrcTarget == m_pVertScrollBar && m_pVertScrollBar) ||
+      (pSrcTarget == m_pHorzScrollBar && m_pHorzScrollBar)) {
     CFWL_EventScroll* pScrollEvent = static_cast<CFWL_EventScroll*>(pEvent);
     OnScroll(static_cast<CFWL_ScrollBar*>(pSrcTarget),
              pScrollEvent->m_iScrollCode, pScrollEvent->m_fPos);
diff --git a/xfa/fwl/cfwl_listbox.h b/xfa/fwl/cfwl_listbox.h
index cd36e94..28e2b06 100644
--- a/xfa/fwl/cfwl_listbox.h
+++ b/xfa/fwl/cfwl_listbox.h
@@ -48,12 +48,11 @@
     WideString m_wsText;
   };
 
-  CFWL_ListBox(const CFWL_App* pApp,
-               const Properties& properties,
-               CFWL_Widget* pOuter);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CFWL_ListBox() override;
 
-  // CFWL_Widget
+  // CFWL_Widget:
+  void Trace(cppgc::Visitor* visitor) const override;
   FWL_Type GetClassID() const override;
   void Update() override;
   FWL_WidgetHit HitTest(const CFX_PointF& point) override;
@@ -78,6 +77,10 @@
   float CalcItemHeight();
 
  protected:
+  CFWL_ListBox(const CFWL_App* pApp,
+               const Properties& properties,
+               CFWL_Widget* pOuter);
+
   Item* GetListItem(Item* hItem, uint32_t dwKeyCode);
   void SetSelection(Item* hStart, Item* hEnd, bool bSelected);
   Item* GetItemAtPoint(const CFX_PointF& point);
@@ -85,7 +88,7 @@
   void InitVerticalScrollBar();
   void InitHorizontalScrollBar();
   bool IsShowScrollBar(bool bVert);
-  CFWL_ScrollBar* GetVertScrollBar() const { return m_pVertScrollBar.get(); }
+  CFWL_ScrollBar* GetVertScrollBar() const { return m_pVertScrollBar; }
   const CFX_RectF& GetRTClient() const { return m_ClientRect; }
 
  private:
@@ -126,8 +129,8 @@
   CFX_RectF m_ClientRect;
   CFX_RectF m_StaticRect;
   CFX_RectF m_ContentRect;
-  std::unique_ptr<CFWL_ScrollBar> m_pHorzScrollBar;
-  std::unique_ptr<CFWL_ScrollBar> m_pVertScrollBar;
+  cppgc::Member<CFWL_ScrollBar> m_pHorzScrollBar;
+  cppgc::Member<CFWL_ScrollBar> m_pVertScrollBar;
   FDE_TextStyle m_TTOStyles;
   FDE_TextAlignment m_iTTOAligns = FDE_TextAlignment::kTopLeft;
   bool m_bLButtonDown = false;
diff --git a/xfa/fwl/cfwl_monthcalendar.h b/xfa/fwl/cfwl_monthcalendar.h
index 6488a02..83afae8 100644
--- a/xfa/fwl/cfwl_monthcalendar.h
+++ b/xfa/fwl/cfwl_monthcalendar.h
@@ -21,9 +21,7 @@
 
 class CFWL_MonthCalendar final : public CFWL_Widget {
  public:
-  CFWL_MonthCalendar(const CFWL_App* app,
-                     const Properties& properties,
-                     CFWL_Widget* pOuter);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CFWL_MonthCalendar() override;
 
   // FWL_WidgetImp
@@ -87,6 +85,10 @@
     WideString wsDay;
   };
 
+  CFWL_MonthCalendar(const CFWL_App* app,
+                     const Properties& properties,
+                     CFWL_Widget* pOuter);
+
   void DrawBackground(CXFA_Graphics* pGraphics,
                       const CFX_Matrix* pMatrix);
   void DrawHeadBK(CXFA_Graphics* pGraphics,
diff --git a/xfa/fwl/cfwl_picturebox.h b/xfa/fwl/cfwl_picturebox.h
index 967af73..7ede805 100644
--- a/xfa/fwl/cfwl_picturebox.h
+++ b/xfa/fwl/cfwl_picturebox.h
@@ -14,7 +14,7 @@
 
 class CFWL_PictureBox final : public CFWL_Widget {
  public:
-  explicit CFWL_PictureBox(const CFWL_App* pApp);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CFWL_PictureBox() override;
 
   // CFWL_Widget
@@ -25,6 +25,8 @@
                     const CFX_Matrix& matrix) override;
 
  private:
+  explicit CFWL_PictureBox(const CFWL_App* pApp);
+
   CFX_RectF m_ClientRect;
   CFX_RectF m_ImageRect;
   CFX_Matrix m_matrix;
diff --git a/xfa/fwl/cfwl_pushbutton.h b/xfa/fwl/cfwl_pushbutton.h
index 7f83a74..efd5412 100644
--- a/xfa/fwl/cfwl_pushbutton.h
+++ b/xfa/fwl/cfwl_pushbutton.h
@@ -18,7 +18,7 @@
 
 class CFWL_PushButton final : public CFWL_Widget {
  public:
-  explicit CFWL_PushButton(const CFWL_App*);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CFWL_PushButton() override;
 
   // CFWL_Widget
@@ -31,6 +31,8 @@
                     const CFX_Matrix& matrix) override;
 
  private:
+  explicit CFWL_PushButton(const CFWL_App*);
+
   void DrawBkground(CXFA_Graphics* pGraphics,
                     const CFX_Matrix* pMatrix);
   uint32_t GetPartStates();
diff --git a/xfa/fwl/cfwl_scrollbar.h b/xfa/fwl/cfwl_scrollbar.h
index da29b3d..4cacfc9 100644
--- a/xfa/fwl/cfwl_scrollbar.h
+++ b/xfa/fwl/cfwl_scrollbar.h
@@ -11,7 +11,6 @@
 
 #include "core/fxcrt/cfx_timer.h"
 #include "core/fxcrt/fx_system.h"
-#include "core/fxcrt/unowned_ptr.h"
 #include "xfa/fwl/cfwl_eventscroll.h"
 #include "xfa/fwl/cfwl_widget.h"
 
@@ -21,9 +20,7 @@
 class CFWL_ScrollBar final : public CFWL_Widget,
                              public CFX_Timer::CallbackIface {
  public:
-  CFWL_ScrollBar(const CFWL_App* app,
-                 const Properties& properties,
-                 CFWL_Widget* pOuter);
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CFWL_ScrollBar() override;
 
   // CFWL_Widget:
@@ -56,6 +53,10 @@
   void SetTrackPos(float fTrackPos);
 
  private:
+  CFWL_ScrollBar(const CFWL_App* app,
+                 const Properties& properties,
+                 CFWL_Widget* pOuter);
+
   bool IsVertical() const {
     return !!(m_Properties.m_dwStyleExes & FWL_STYLEEXT_SCB_Vert);
   }
diff --git a/xfa/fwl/cfwl_widget.cpp b/xfa/fwl/cfwl_widget.cpp
index 2d4de85..8b5aafe 100644
--- a/xfa/fwl/cfwl_widget.cpp
+++ b/xfa/fwl/cfwl_widget.cpp
@@ -11,6 +11,7 @@
 #include <vector>
 
 #include "third_party/base/stl_util.h"
+#include "v8/include/cppgc/visitor.h"
 #include "xfa/fde/cfde_textout.h"
 #include "xfa/fwl/cfwl_app.h"
 #include "xfa/fwl/cfwl_combobox.h"
@@ -42,12 +43,19 @@
   m_pWidgetMgr->InsertWidget(m_pOuter, this);
 }
 
-CFWL_Widget::~CFWL_Widget() {
+CFWL_Widget::~CFWL_Widget() = default;
+
+void CFWL_Widget::PreFinalize() {
   CHECK(!IsLocked());  // Prefer hard stop to UaF.
   NotifyDriver();
   m_pWidgetMgr->RemoveWidget(this);
 }
 
+void CFWL_Widget::Trace(cppgc::Visitor* visitor) const {
+  visitor->Trace(m_pOuter);
+  visitor->Trace(m_pDelegate);
+}
+
 bool CFWL_Widget::IsForm() const {
   return false;
 }
diff --git a/xfa/fwl/cfwl_widget.h b/xfa/fwl/cfwl_widget.h
index 1c504a6..f419ac2 100644
--- a/xfa/fwl/cfwl_widget.h
+++ b/xfa/fwl/cfwl_widget.h
@@ -11,6 +11,11 @@
 #include "core/fxcrt/fx_system.h"
 #include "core/fxcrt/observed_ptr.h"
 #include "core/fxcrt/unowned_ptr.h"
+#include "fxjs/gc/heap.h"
+#include "v8/include/cppgc/garbage-collected.h"
+#include "v8/include/cppgc/macros.h"
+#include "v8/include/cppgc/member.h"
+#include "v8/include/cppgc/prefinalizer.h"
 #include "xfa/fde/cfde_data.h"
 #include "xfa/fwl/cfwl_themepart.h"
 #include "xfa/fwl/cfwl_widgetmgr.h"
@@ -47,7 +52,11 @@
 };
 
 // NOTE: CFWL_Widget serves as its own delegate until replaced at runtime.
-class CFWL_Widget : public Observable, public IFWL_WidgetDelegate {
+class CFWL_Widget : public cppgc::GarbageCollected<CFWL_Widget>,
+                    public Observable,
+                    public IFWL_WidgetDelegate {
+  CPPGC_USING_PRE_FINALIZER(CFWL_Widget, PreFinalize);
+
  public:
   class AdapterIface {
    public:
@@ -65,6 +74,8 @@
   };
 
   class ScopedUpdateLock {
+    CPPGC_STACK_ALLOCATED();  // Allow raw/unowned pointers.
+
    public:
     explicit ScopedUpdateLock(CFWL_Widget* widget);
     ~ScopedUpdateLock();
@@ -73,8 +84,12 @@
     UnownedPtr<CFWL_Widget> const widget_;
   };
 
+  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CFWL_Widget() override;
 
+  virtual void PreFinalize();
+  void Trace(cppgc::Visitor* visitor) const override;
+
   virtual FWL_Type GetClassID() const = 0;
   virtual bool IsForm() const;
   virtual CFX_RectF GetAutosizedWidgetRect();
@@ -178,9 +193,9 @@
   uint64_t m_nEventKey = 0;
   UnownedPtr<const CFWL_App> const m_pFWLApp;
   UnownedPtr<CFWL_WidgetMgr> const m_pWidgetMgr;
-  CFWL_Widget* const m_pOuter;
+  cppgc::Member<CFWL_Widget> const m_pOuter;
   AdapterIface* m_pAdapterIface = nullptr;
-  UnownedPtr<IFWL_WidgetDelegate> m_pDelegate;
+  cppgc::Member<IFWL_WidgetDelegate> m_pDelegate;
 };
 
 #endif  // XFA_FWL_CFWL_WIDGET_H_
diff --git a/xfa/fwl/ifwl_widgetdelegate.h b/xfa/fwl/ifwl_widgetdelegate.h
index 17b8933..d6403c9 100644
--- a/xfa/fwl/ifwl_widgetdelegate.h
+++ b/xfa/fwl/ifwl_widgetdelegate.h
@@ -7,14 +7,14 @@
 #ifndef XFA_FWL_IFWL_WIDGETDELEGATE_H_
 #define XFA_FWL_IFWL_WIDGETDELEGATE_H_
 
-#include <stdint.h>
+#include "v8/include/cppgc/garbage-collected.h"
 
 class CFWL_Event;
 class CFWL_Message;
 class CXFA_Graphics;
 class CFX_Matrix;
 
-class IFWL_WidgetDelegate {
+class IFWL_WidgetDelegate : public cppgc::GarbageCollectedMixin {
  public:
   virtual ~IFWL_WidgetDelegate() = default;
 
diff --git a/xfa/fxfa/cxfa_ffbarcode.cpp b/xfa/fxfa/cxfa_ffbarcode.cpp
index be5c0e1..32811e7d 100644
--- a/xfa/fxfa/cxfa_ffbarcode.cpp
+++ b/xfa/fxfa/cxfa_ffbarcode.cpp
@@ -6,7 +6,6 @@
 
 #include "xfa/fxfa/cxfa_ffbarcode.h"
 
-#include <memory>
 #include <utility>
 
 #include "core/fxcrt/fx_extension.h"
@@ -146,9 +145,9 @@
 bool CXFA_FFBarcode::LoadWidget() {
   ASSERT(!IsLoaded());
 
-  auto pNew = std::make_unique<CFWL_Barcode>(GetFWLApp());
-  CFWL_Barcode* pFWLBarcode = pNew.get();
-  SetNormalWidget(std::move(pNew));
+  CFWL_Barcode* pFWLBarcode = cppgc::MakeGarbageCollected<CFWL_Barcode>(
+      GetFWLApp()->GetHeap()->GetAllocationHandle(), GetFWLApp());
+  SetNormalWidget(pFWLBarcode);
   pFWLBarcode->SetAdapterIface(this);
 
   CFWL_NoteDriver* pNoteDriver = pFWLBarcode->GetFWLApp()->GetNoteDriver();
diff --git a/xfa/fxfa/cxfa_ffcheckbutton.cpp b/xfa/fxfa/cxfa_ffcheckbutton.cpp
index 81c63af..d71335c 100644
--- a/xfa/fxfa/cxfa_ffcheckbutton.cpp
+++ b/xfa/fxfa/cxfa_ffcheckbutton.cpp
@@ -9,6 +9,7 @@
 #include <memory>
 #include <utility>
 
+#include "v8/include/cppgc/visitor.h"
 #include "xfa/fwl/cfwl_checkbox.h"
 #include "xfa/fwl/cfwl_messagemouse.h"
 #include "xfa/fwl/cfwl_notedriver.h"
@@ -33,15 +34,16 @@
 
 void CXFA_FFCheckButton::Trace(cppgc::Visitor* visitor) const {
   CXFA_FFField::Trace(visitor);
+  visitor->Trace(m_pOldDelegate);
   visitor->Trace(button_);
 }
 
 bool CXFA_FFCheckButton::LoadWidget() {
   ASSERT(!IsLoaded());
 
-  auto pNew = std::make_unique<CFWL_CheckBox>(GetFWLApp());
-  CFWL_CheckBox* pCheckBox = pNew.get();
-  SetNormalWidget(std::move(pNew));
+  CFWL_CheckBox* pCheckBox = cppgc::MakeGarbageCollected<CFWL_CheckBox>(
+      GetFWLApp()->GetHeap()->GetAllocationHandle(), GetFWLApp());
+  SetNormalWidget(pCheckBox);
   pCheckBox->SetAdapterIface(this);
 
   CFWL_NoteDriver* pNoteDriver = pCheckBox->GetFWLApp()->GetNoteDriver();
diff --git a/xfa/fxfa/cxfa_ffcheckbutton.h b/xfa/fxfa/cxfa_ffcheckbutton.h
index 35f8ba5..89d561e 100644
--- a/xfa/fxfa/cxfa_ffcheckbutton.h
+++ b/xfa/fxfa/cxfa_ffcheckbutton.h
@@ -7,9 +7,7 @@
 #ifndef XFA_FXFA_CXFA_FFCHECKBUTTON_H_
 #define XFA_FXFA_CXFA_FFCHECKBUTTON_H_
 
-#include "core/fxcrt/unowned_ptr.h"
 #include "v8/include/cppgc/member.h"
-#include "v8/include/cppgc/visitor.h"
 #include "xfa/fxfa/cxfa_fffield.h"
 #include "xfa/fxfa/cxfa_ffpageview.h"
 #include "xfa/fxfa/parser/cxfa_node.h"
@@ -50,7 +48,7 @@
   void AddUIMargin(XFA_AttributeValue iCapPlacement);
   XFA_CHECKSTATE FWLState2XFAState();
 
-  UnownedPtr<IFWL_WidgetDelegate> m_pOldDelegate;
+  cppgc::Member<IFWL_WidgetDelegate> m_pOldDelegate;
   cppgc::Member<CXFA_CheckButton> const button_;
   CFX_RectF m_CheckBoxRect;
 };
diff --git a/xfa/fxfa/cxfa_ffcombobox.cpp b/xfa/fxfa/cxfa_ffcombobox.cpp
index 6b17593..7477133 100644
--- a/xfa/fxfa/cxfa_ffcombobox.cpp
+++ b/xfa/fxfa/cxfa_ffcombobox.cpp
@@ -6,10 +6,10 @@
 
 #include "xfa/fxfa/cxfa_ffcombobox.h"
 
-#include <memory>
 #include <utility>
 #include <vector>
 
+#include "v8/include/cppgc/visitor.h"
 #include "xfa/fwl/cfwl_combobox.h"
 #include "xfa/fwl/cfwl_eventselectchanged.h"
 #include "xfa/fwl/cfwl_notedriver.h"
@@ -33,6 +33,11 @@
 
 CXFA_FFComboBox::~CXFA_FFComboBox() = default;
 
+void CXFA_FFComboBox::Trace(cppgc::Visitor* visitor) const {
+  CXFA_FFDropDown::Trace(visitor);
+  visitor->Trace(m_pOldDelegate);
+}
+
 CXFA_FFComboBox* CXFA_FFComboBox::AsComboBox() {
   return this;
 }
@@ -51,9 +56,9 @@
 bool CXFA_FFComboBox::LoadWidget() {
   ASSERT(!IsLoaded());
 
-  auto pNew = std::make_unique<CFWL_ComboBox>(GetFWLApp());
-  CFWL_ComboBox* pComboBox = pNew.get();
-  SetNormalWidget(std::move(pNew));
+  CFWL_ComboBox* pComboBox = cppgc::MakeGarbageCollected<CFWL_ComboBox>(
+      GetFWLApp()->GetHeap()->GetAllocationHandle(), GetFWLApp());
+  SetNormalWidget(pComboBox);
   pComboBox->SetAdapterIface(this);
 
   CFWL_NoteDriver* pNoteDriver = pComboBox->GetFWLApp()->GetNoteDriver();
diff --git a/xfa/fxfa/cxfa_ffcombobox.h b/xfa/fxfa/cxfa_ffcombobox.h
index d2f7d66..5711a92 100644
--- a/xfa/fxfa/cxfa_ffcombobox.h
+++ b/xfa/fxfa/cxfa_ffcombobox.h
@@ -7,7 +7,7 @@
 #ifndef XFA_FXFA_CXFA_FFCOMBOBOX_H_
 #define XFA_FXFA_CXFA_FFCOMBOBOX_H_
 
-#include "core/fxcrt/unowned_ptr.h"
+#include "v8/include/cppgc/member.h"
 #include "xfa/fxfa/cxfa_ffdropdown.h"
 
 class CXFA_EventParam;
@@ -17,6 +17,8 @@
   CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
   ~CXFA_FFComboBox() override;
 
+  void Trace(cppgc::Visitor* visitor) const override;
+
   // CXFA_FFDropDown:
   CXFA_FFComboBox* AsComboBox() override;
 
@@ -75,7 +77,7 @@
   WideString GetCurrentText() const;
 
   WideString m_wsNewValue;
-  UnownedPtr<IFWL_WidgetDelegate> m_pOldDelegate;
+  cppgc::Member<IFWL_WidgetDelegate> m_pOldDelegate;
 };
 
 #endif  // XFA_FXFA_CXFA_FFCOMBOBOX_H_
diff --git a/xfa/fxfa/cxfa_ffdatetimeedit.cpp b/xfa/fxfa/cxfa_ffdatetimeedit.cpp
index bb3209b..bb2d84a 100644
--- a/xfa/fxfa/cxfa_ffdatetimeedit.cpp
+++ b/xfa/fxfa/cxfa_ffdatetimeedit.cpp
@@ -6,7 +6,6 @@
 
 #include "xfa/fxfa/cxfa_ffdatetimeedit.h"
 
-#include <memory>
 #include <utility>
 
 #include "xfa/fwl/cfwl_datetimepicker.h"
@@ -44,9 +43,10 @@
 bool CXFA_FFDateTimeEdit::LoadWidget() {
   ASSERT(!IsLoaded());
 
-  auto pNewPicker = std::make_unique<CFWL_DateTimePicker>(GetFWLApp());
-  CFWL_DateTimePicker* pWidget = pNewPicker.get();
-  SetNormalWidget(std::move(pNewPicker));
+  CFWL_DateTimePicker* pWidget =
+      cppgc::MakeGarbageCollected<CFWL_DateTimePicker>(
+          GetFWLApp()->GetHeap()->GetAllocationHandle(), GetFWLApp());
+  SetNormalWidget(pWidget);
   pWidget->SetAdapterIface(this);
 
   CFWL_NoteDriver* pNoteDriver = pWidget->GetFWLApp()->GetNoteDriver();
diff --git a/xfa/fxfa/cxfa_fffield.cpp b/xfa/fxfa/cxfa_fffield.cpp
index 0997e95..8176090 100644
--- a/xfa/fxfa/cxfa_fffield.cpp
+++ b/xfa/fxfa/cxfa_fffield.cpp
@@ -48,6 +48,11 @@
   return this;
 }
 
+void CXFA_FFField::Trace(cppgc::Visitor* visitor) const {
+  CXFA_FFWidget::Trace(visitor);
+  visitor->Trace(m_pNormalWidget);
+}
+
 CFX_RectF CXFA_FFField::GetBBox(FocusOption focus) {
   if (focus == kDoNotDrawFocus)
     return CXFA_FFWidget::GetBBox(kDoNotDrawFocus);
@@ -123,15 +128,15 @@
 }
 
 CFWL_Widget* CXFA_FFField::GetNormalWidget() {
-  return m_pNormalWidget.get();
+  return m_pNormalWidget;
 }
 
 const CFWL_Widget* CXFA_FFField::GetNormalWidget() const {
-  return m_pNormalWidget.get();
+  return m_pNormalWidget;
 }
 
-void CXFA_FFField::SetNormalWidget(std::unique_ptr<CFWL_Widget> widget) {
-  m_pNormalWidget = std::move(widget);
+void CXFA_FFField::SetNormalWidget(CFWL_Widget* widget) {
+  m_pNormalWidget = widget;
 }
 
 bool CXFA_FFField::IsLoaded() {
diff --git a/xfa/fxfa/cxfa_fffield.h b/xfa/fxfa/cxfa_fffield.h
index 1906a32..08b4fa7 100644
--- a/xfa/fxfa/cxfa_fffield.h
+++ b/xfa/fxfa/cxfa_fffield.h
@@ -30,6 +30,7 @@
   virtual CXFA_FFDropDown* AsDropDown();
 
   // CXFA_FFWidget:
+  void Trace(cppgc::Visitor* visitor) const override;
   CXFA_FFField* AsField() override;
   CFX_RectF GetBBox(FocusOption focus) override;
   void RenderWidget(CXFA_Graphics* pGS,
@@ -80,7 +81,7 @@
 
   CFWL_Widget* GetNormalWidget();
   const CFWL_Widget* GetNormalWidget() const;
-  void SetNormalWidget(std::unique_ptr<CFWL_Widget> widget);
+  void SetNormalWidget(CFWL_Widget* widget);
   CFX_PointF FWLToClient(const CFX_PointF& point);
   void LayoutCaption();
   void RenderCaption(CXFA_Graphics* pGS, CFX_Matrix* pMatrix);
@@ -107,7 +108,7 @@
   CFX_RectF m_CaptionRect;
 
  private:
-  std::unique_ptr<CFWL_Widget> m_pNormalWidget;
+  cppgc::Member<CFWL_Widget> m_pNormalWidget;
 };
 
 inline CXFA_FFDropDown* ToDropDown(CXFA_FFField* field) {
diff --git a/xfa/fxfa/cxfa_ffimageedit.cpp b/xfa/fxfa/cxfa_ffimageedit.cpp
index c8e1961..1195549 100644
--- a/xfa/fxfa/cxfa_ffimageedit.cpp
+++ b/xfa/fxfa/cxfa_ffimageedit.cpp
@@ -10,6 +10,7 @@
 #include <utility>
 
 #include "core/fxge/dib/cfx_dibitmap.h"
+#include "v8/include/cppgc/visitor.h"
 #include "xfa/fwl/cfwl_app.h"
 #include "xfa/fwl/cfwl_messagemouse.h"
 #include "xfa/fwl/cfwl_notedriver.h"
@@ -33,12 +34,17 @@
   CXFA_FFField::PreFinalize();
 }
 
+void CXFA_FFImageEdit::Trace(cppgc::Visitor* visitor) const {
+  CXFA_FFField::Trace(visitor);
+  visitor->Trace(m_pOldDelegate);
+}
+
 bool CXFA_FFImageEdit::LoadWidget() {
   ASSERT(!IsLoaded());
 
-  auto pNew = std::make_unique<CFWL_PictureBox>(GetFWLApp());
-  CFWL_PictureBox* pPictureBox = pNew.get();
-  SetNormalWidget(std::move(pNew));
+  CFWL_PictureBox* pPictureBox = cppgc::MakeGarbageCollected<CFWL_PictureBox>(
+      GetFWLApp()->GetHeap()->GetAllocationHandle(), GetFWLApp());
+  SetNormalWidget(pPictureBox);
   pPictureBox->SetAdapterIface(this);
 
   CFWL_NoteDriver* pNoteDriver = pPictureBox->GetFWLApp()->GetNoteDriver();
diff --git a/xfa/fxfa/cxfa_ffimageedit.h b/xfa/fxfa/cxfa_ffimageedit.h
index dd3376c..92d2dc2 100644
--- a/xfa/fxfa/cxfa_ffimageedit.h
+++ b/xfa/fxfa/cxfa_ffimageedit.h
@@ -7,7 +7,7 @@
 #ifndef XFA_FXFA_CXFA_FFIMAGEEDIT_H_
 #define XFA_FXFA_CXFA_FFIMAGEEDIT_H_
 
-#include "core/fxcrt/unowned_ptr.h"
+#include "v8/include/cppgc/member.h"
 #include "xfa/fxfa/cxfa_fffield.h"
 
 class CXFA_FFImageEdit final : public CXFA_FFField {
@@ -17,6 +17,7 @@
 
   // CXFA_FFField:
   void PreFinalize() override;
+  void Trace(cppgc::Visitor* visitor) const override;
   void RenderWidget(CXFA_Graphics* pGS,
                     const CFX_Matrix& matrix,
                     HighlightOption highlight) override;
@@ -38,7 +39,7 @@
   bool UpdateFWLData() override;
   bool CommitData() override;
 
-  UnownedPtr<IFWL_WidgetDelegate> m_pOldDelegate;
+  cppgc::Member<IFWL_WidgetDelegate> m_pOldDelegate;
 };
 
 #endif  // XFA_FXFA_CXFA_FFIMAGEEDIT_H_
diff --git a/xfa/fxfa/cxfa_fflistbox.cpp b/xfa/fxfa/cxfa_fflistbox.cpp
index 4c0101b..5cd39ba 100644
--- a/xfa/fxfa/cxfa_fflistbox.cpp
+++ b/xfa/fxfa/cxfa_fflistbox.cpp
@@ -7,11 +7,11 @@
 #include "xfa/fxfa/cxfa_fflistbox.h"
 
 #include <algorithm>
-#include <memory>
 #include <utility>
 #include <vector>
 
 #include "third_party/base/stl_util.h"
+#include "v8/include/cppgc/visitor.h"
 #include "xfa/fwl/cfwl_listbox.h"
 #include "xfa/fwl/cfwl_notedriver.h"
 #include "xfa/fwl/cfwl_widget.h"
@@ -39,15 +39,20 @@
   CXFA_FFDropDown::PreFinalize();
 }
 
+void CXFA_FFListBox::Trace(cppgc::Visitor* visitor) const {
+  CXFA_FFDropDown::Trace(visitor);
+  visitor->Trace(m_pOldDelegate);
+}
+
 bool CXFA_FFListBox::LoadWidget() {
   ASSERT(!IsLoaded());
 
-  auto pNew = std::make_unique<CFWL_ListBox>(
-      GetFWLApp(), CFWL_Widget::Properties(), nullptr);
-  CFWL_ListBox* pListBox = pNew.get();
+  CFWL_ListBox* pListBox = cppgc::MakeGarbageCollected<CFWL_ListBox>(
+      GetFWLApp()->GetHeap()->GetAllocationHandle(), GetFWLApp(),
+      CFWL_Widget::Properties(), nullptr);
   pListBox->ModifyStyles(FWL_WGTSTYLE_VScroll | FWL_WGTSTYLE_NoBackground,
                          0xFFFFFFFF);
-  SetNormalWidget(std::move(pNew));
+  SetNormalWidget(pListBox);
   pListBox->SetAdapterIface(this);
 
   CFWL_NoteDriver* pNoteDriver = pListBox->GetFWLApp()->GetNoteDriver();
diff --git a/xfa/fxfa/cxfa_fflistbox.h b/xfa/fxfa/cxfa_fflistbox.h
index 581bbd8..ca967aa 100644
--- a/xfa/fxfa/cxfa_fflistbox.h
+++ b/xfa/fxfa/cxfa_fflistbox.h
@@ -7,7 +7,7 @@
 #ifndef XFA_FXFA_CXFA_FFLISTBOX_H_
 #define XFA_FXFA_CXFA_FFLISTBOX_H_
 
-#include "core/fxcrt/unowned_ptr.h"
+#include "v8/include/cppgc/member.h"
 #include "xfa/fxfa/cxfa_ffdropdown.h"
 
 class CXFA_FFListBox final : public CXFA_FFDropDown {
@@ -17,6 +17,7 @@
 
   // CXFA_FFField:
   void PreFinalize() override;
+  void Trace(cppgc::Visitor* visitor) const override;
   bool LoadWidget() override;
   bool OnKillFocus(CXFA_FFWidget* pNewWidget) override WARN_UNUSED_RESULT;
   void OnProcessMessage(CFWL_Message* pMessage) override;
@@ -41,7 +42,7 @@
 
   uint32_t GetAlignment();
 
-  UnownedPtr<IFWL_WidgetDelegate> m_pOldDelegate;
+  cppgc::Member<IFWL_WidgetDelegate> m_pOldDelegate;
 };
 
 #endif  // XFA_FXFA_CXFA_FFLISTBOX_H_
diff --git a/xfa/fxfa/cxfa_ffnumericedit.cpp b/xfa/fxfa/cxfa_ffnumericedit.cpp
index 81cc0d0..acd0121 100644
--- a/xfa/fxfa/cxfa_ffnumericedit.cpp
+++ b/xfa/fxfa/cxfa_ffnumericedit.cpp
@@ -6,7 +6,6 @@
 
 #include "xfa/fxfa/cxfa_ffnumericedit.h"
 
-#include <memory>
 #include <utility>
 
 #include "xfa/fwl/cfwl_edit.h"
@@ -25,10 +24,10 @@
 bool CXFA_FFNumericEdit::LoadWidget() {
   ASSERT(!IsLoaded());
 
-  auto pNewEdit = std::make_unique<CFWL_Edit>(
-      GetFWLApp(), CFWL_Widget::Properties(), nullptr);
-  CFWL_Edit* pWidget = pNewEdit.get();
-  SetNormalWidget(std::move(pNewEdit));
+  CFWL_Edit* pWidget = cppgc::MakeGarbageCollected<CFWL_Edit>(
+      GetFWLApp()->GetHeap()->GetAllocationHandle(), GetFWLApp(),
+      CFWL_Widget::Properties(), nullptr);
+  SetNormalWidget(pWidget);
   pWidget->SetAdapterIface(this);
 
   CFWL_NoteDriver* pNoteDriver = pWidget->GetFWLApp()->GetNoteDriver();
diff --git a/xfa/fxfa/cxfa_ffpasswordedit.cpp b/xfa/fxfa/cxfa_ffpasswordedit.cpp
index 87f17c9..daccc03 100644
--- a/xfa/fxfa/cxfa_ffpasswordedit.cpp
+++ b/xfa/fxfa/cxfa_ffpasswordedit.cpp
@@ -6,7 +6,6 @@
 
 #include "xfa/fxfa/cxfa_ffpasswordedit.h"
 
-#include <memory>
 #include <utility>
 
 #include "xfa/fwl/cfwl_edit.h"
@@ -29,10 +28,10 @@
 bool CXFA_FFPasswordEdit::LoadWidget() {
   ASSERT(!IsLoaded());
 
-  auto pNewEdit = std::make_unique<CFWL_Edit>(
-      GetFWLApp(), CFWL_Widget::Properties(), nullptr);
-  CFWL_Edit* pWidget = pNewEdit.get();
-  SetNormalWidget(std::move(pNewEdit));
+  CFWL_Edit* pWidget = cppgc::MakeGarbageCollected<CFWL_Edit>(
+      GetFWLApp()->GetHeap()->GetAllocationHandle(), GetFWLApp(),
+      CFWL_Widget::Properties(), nullptr);
+  SetNormalWidget(pWidget);
   pWidget->SetAdapterIface(this);
 
   CFWL_NoteDriver* pNoteDriver = pWidget->GetFWLApp()->GetNoteDriver();
diff --git a/xfa/fxfa/cxfa_ffpushbutton.cpp b/xfa/fxfa/cxfa_ffpushbutton.cpp
index 793eca2..3ade62b 100644
--- a/xfa/fxfa/cxfa_ffpushbutton.cpp
+++ b/xfa/fxfa/cxfa_ffpushbutton.cpp
@@ -8,6 +8,7 @@
 
 #include <utility>
 
+#include "v8/include/cppgc/visitor.h"
 #include "xfa/fwl/cfwl_notedriver.h"
 #include "xfa/fwl/cfwl_pushbutton.h"
 #include "xfa/fwl/cfwl_widgetmgr.h"
@@ -36,6 +37,7 @@
   visitor->Trace(m_pDownTextLayout);
   visitor->Trace(m_pRollProvider);
   visitor->Trace(m_pDownProvider);
+  visitor->Trace(m_pOldDelegate);
   visitor->Trace(button_);
 }
 
@@ -60,11 +62,11 @@
 bool CXFA_FFPushButton::LoadWidget() {
   ASSERT(!IsLoaded());
 
-  auto pNew = std::make_unique<CFWL_PushButton>(GetFWLApp());
-  CFWL_PushButton* pPushButton = pNew.get();
+  CFWL_PushButton* pPushButton = cppgc::MakeGarbageCollected<CFWL_PushButton>(
+      GetFWLApp()->GetHeap()->GetAllocationHandle(), GetFWLApp());
   m_pOldDelegate = pPushButton->GetDelegate();
   pPushButton->SetDelegate(this);
-  SetNormalWidget(std::move(pNew));
+  SetNormalWidget(pPushButton);
   pPushButton->SetAdapterIface(this);
 
   CFWL_NoteDriver* pNoteDriver = pPushButton->GetFWLApp()->GetNoteDriver();
diff --git a/xfa/fxfa/cxfa_ffpushbutton.h b/xfa/fxfa/cxfa_ffpushbutton.h
index 207c3dc..b1d0ce2 100644
--- a/xfa/fxfa/cxfa_ffpushbutton.h
+++ b/xfa/fxfa/cxfa_ffpushbutton.h
@@ -7,9 +7,7 @@
 #ifndef XFA_FXFA_CXFA_FFPUSHBUTTON_H_
 #define XFA_FXFA_CXFA_FFPUSHBUTTON_H_
 
-#include "core/fxcrt/unowned_ptr.h"
 #include "v8/include/cppgc/member.h"
-#include "v8/include/cppgc/visitor.h"
 #include "xfa/fxfa/cxfa_fffield.h"
 
 #define XFA_FWL_PSBSTYLEEXT_HiliteInverted (1L << 0)
@@ -54,7 +52,7 @@
   cppgc::Member<CXFA_TextLayout> m_pDownTextLayout;
   cppgc::Member<CXFA_TextProvider> m_pRollProvider;
   cppgc::Member<CXFA_TextProvider> m_pDownProvider;
-  UnownedPtr<IFWL_WidgetDelegate> m_pOldDelegate;
+  cppgc::Member<IFWL_WidgetDelegate> m_pOldDelegate;
   cppgc::Member<CXFA_Button> const button_;
 };
 
diff --git a/xfa/fxfa/cxfa_fftextedit.cpp b/xfa/fxfa/cxfa_fftextedit.cpp
index 1ee30c2..6d354c8 100644
--- a/xfa/fxfa/cxfa_fftextedit.cpp
+++ b/xfa/fxfa/cxfa_fftextedit.cpp
@@ -45,13 +45,18 @@
   CXFA_FFField::PreFinalize();
 }
 
+void CXFA_FFTextEdit::Trace(cppgc::Visitor* visitor) const {
+  CXFA_FFField::Trace(visitor);
+  visitor->Trace(m_pOldDelegate);
+}
+
 bool CXFA_FFTextEdit::LoadWidget() {
   ASSERT(!IsLoaded());
 
-  auto pNewWidget = std::make_unique<CFWL_Edit>(
-      GetFWLApp(), CFWL_Widget::Properties(), nullptr);
-  CFWL_Edit* pFWLEdit = pNewWidget.get();
-  SetNormalWidget(std::move(pNewWidget));
+  CFWL_Edit* pFWLEdit = cppgc::MakeGarbageCollected<CFWL_Edit>(
+      GetFWLApp()->GetHeap()->GetAllocationHandle(), GetFWLApp(),
+      CFWL_Widget::Properties(), nullptr);
+  SetNormalWidget(pFWLEdit);
   pFWLEdit->SetAdapterIface(this);
 
   CFWL_NoteDriver* pNoteDriver = pFWLEdit->GetFWLApp()->GetNoteDriver();
diff --git a/xfa/fxfa/cxfa_fftextedit.h b/xfa/fxfa/cxfa_fftextedit.h
index 5b4e298..23a4e54 100644
--- a/xfa/fxfa/cxfa_fftextedit.h
+++ b/xfa/fxfa/cxfa_fftextedit.h
@@ -9,7 +9,6 @@
 
 #include "core/fxcrt/fx_coordinates.h"
 #include "core/fxcrt/fx_string.h"
-#include "core/fxcrt/unowned_ptr.h"
 #include "xfa/fxfa/cxfa_fffield.h"
 
 class CFWL_Event;
@@ -25,6 +24,7 @@
   ~CXFA_FFTextEdit() override;
 
   void PreFinalize() override;
+  void Trace(cppgc::Visitor* visitor) const override;
 
   // CXFA_FFField
   bool LoadWidget() override;
@@ -67,7 +67,7 @@
   explicit CXFA_FFTextEdit(CXFA_Node* pNode);
   uint32_t GetAlignment();
 
-  UnownedPtr<IFWL_WidgetDelegate> m_pOldDelegate;
+  cppgc::Member<IFWL_WidgetDelegate> m_pOldDelegate;
 
  private:
   bool CommitData() override;