Bug 1433671: Add MOZ_CAN_RUN_SCRIPT annotations to AccessibleCaret and other stuff. r=bz
authorEmilio Cobos Álvarez <emilio@crisal.io>
Mon, 29 Jan 2018 20:35:17 +0100
changeset 408257 69a882fbd02a50b9ac6ed917a96c42cf22f410e7
parent 408256 1ec0f839a905f165e0a9d6312fbd7aabf502dc8b
child 408258 dd1c00afe429fd961e7f7423a0eeb44619bc9f54
push id33630
push usershindli@mozilla.com
push dateThu, 15 Mar 2018 10:14:59 +0000
treeherdermozilla-central@fcb11e93adf5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs1433671
milestone61.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1433671: Add MOZ_CAN_RUN_SCRIPT annotations to AccessibleCaret and other stuff. r=bz MozReview-Commit-ID: Js0CF7WQM73
dom/base/nsContentUtils.h
dom/base/nsDOMWindowUtils.h
dom/base/nsFocusManager.h
dom/events/PointerEventHandler.h
dom/ipc/TabChild.h
gfx/layers/apz/util/APZCCallbackHelper.h
gfx/layers/apz/util/APZEventState.h
gfx/layers/apz/util/ChromeProcessController.h
layout/base/AccessibleCaretEventHub.cpp
layout/base/AccessibleCaretEventHub.h
layout/base/AccessibleCaretManager.cpp
layout/base/AccessibleCaretManager.h
layout/base/PresShell.cpp
layout/base/PresShell.h
layout/base/gtest/TestAccessibleCaretEventHub.cpp
layout/base/gtest/TestAccessibleCaretManager.cpp
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -2881,16 +2881,17 @@ public:
                                                      nsPresContext* aPresContext);
   static nsView* GetViewToDispatchEvent(nsPresContext* aPresContext,
                                         nsIPresShell** aPresShell);
 
   /**
    * Synthesize a mouse event to the given widget
    * (see nsIDOMWindowUtils.sendMouseEvent).
    */
+  MOZ_CAN_RUN_SCRIPT
   static nsresult SendMouseEvent(const nsCOMPtr<nsIPresShell>& aPresShell,
                                  const nsAString& aType,
                                  float aX,
                                  float aY,
                                  int32_t aButton,
                                  int32_t aButtons,
                                  int32_t aClickCount,
                                  int32_t aModifiers,
--- a/dom/base/nsDOMWindowUtils.h
+++ b/dom/base/nsDOMWindowUtils.h
@@ -79,16 +79,18 @@ protected:
   nsIWidget* GetWidgetForElement(nsIDOMElement* aElement);
 
   nsIPresShell* GetPresShell();
   nsPresContext* GetPresContext();
   nsIDocument* GetDocument();
   mozilla::layers::LayerTransactionChild* GetLayerTransaction();
   mozilla::layers::WebRenderBridgeChild* GetWebRenderBridge();
 
+  // Until callers are annotated.
+  MOZ_CAN_RUN_SCRIPT_BOUNDARY
   NS_IMETHOD SendMouseEventCommon(const nsAString& aType,
                                   float aX,
                                   float aY,
                                   int32_t aButton,
                                   int32_t aClickCount,
                                   int32_t aModifiers,
                                   bool aIgnoreRootScrollFrame,
                                   float aPressure,
--- a/dom/base/nsFocusManager.h
+++ b/dom/base/nsFocusManager.h
@@ -269,16 +269,18 @@ protected:
    * switching focus to a sibling window.
    *
    * aIsLeavingDocument should be set to true if the document/window is being
    * blurred as well. Document/window blur events will be fired. It should be
    * false if an element is the same document is about to be focused.
    *
    * If aAdjustWidget is false, don't change the widget focus state.
    */
+  // MOZ_CAN_RUN_SCRIPT_BOUNDARY for now, until we annotate callers.
+  MOZ_CAN_RUN_SCRIPT_BOUNDARY
   bool Blur(nsPIDOMWindowOuter* aWindowToClear,
             nsPIDOMWindowOuter* aAncestorWindowToFocus,
             bool aIsLeavingDocument,
             bool aAdjustWidget,
             nsIContent* aContentToFocus = nullptr);
 
   /**
    * Focus an element in the active window and child frame.
--- a/dom/events/PointerEventHandler.h
+++ b/dom/events/PointerEventHandler.h
@@ -133,16 +133,17 @@ public:
    * We add mPreventMouseEventByContent flag in PointerInfo to represent the
    * active pointer won't firing compatible mouse events. It's set to true when
    * content preventDefault on pointerdown
    */
   static void PostHandlePointerEventsPreventDefault(
                 WidgetPointerEvent* aPointerEvent,
                 WidgetGUIEvent* aMouseOrTouchEvent);
 
+  MOZ_CAN_RUN_SCRIPT
   static void DispatchPointerFromMouseOrTouch(PresShell* aShell,
                                               nsIFrame* aFrame,
                                               nsIContent* aContent,
                                               WidgetGUIEvent* aEvent,
                                               bool aDontRetargetEvents,
                                               nsEventStatus* aStatus,
                                               nsIContent** aTargetContent);
 
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -351,16 +351,17 @@ public:
   RecvUpdateDimensions(const mozilla::dom::DimensionInfo& aDimensionInfo) override;
   virtual mozilla::ipc::IPCResult
   RecvSizeModeChanged(const nsSizeMode& aSizeMode) override;
 
   mozilla::ipc::IPCResult RecvActivate();
 
   mozilla::ipc::IPCResult RecvDeactivate();
 
+  MOZ_CAN_RUN_SCRIPT
   virtual mozilla::ipc::IPCResult RecvMouseEvent(const nsString& aType,
                                                  const float& aX,
                                                  const float& aY,
                                                  const int32_t& aButton,
                                                  const int32_t& aClickCount,
                                                  const int32_t& aModifiers,
                                                  const bool& aIgnoreRootScrollFrame) override;
 
@@ -646,22 +647,24 @@ public:
                   PRenderFrameChild* aRenderFrame,
                   const ShowInfo& aShowInfo);
 
   void ContentReceivedInputBlock(const ScrollableLayerGuid& aGuid,
                                  uint64_t aInputBlockId,
                                  bool aPreventDefault) const;
   void SetTargetAPZC(uint64_t aInputBlockId,
                     const nsTArray<ScrollableLayerGuid>& aTargets) const;
+  MOZ_CAN_RUN_SCRIPT
   mozilla::ipc::IPCResult RecvHandleTap(const layers::GeckoContentController::TapType& aType,
                                         const LayoutDevicePoint& aPoint,
                                         const Modifiers& aModifiers,
                                         const ScrollableLayerGuid& aGuid,
                                         const uint64_t& aInputBlockId) override;
 
+  MOZ_CAN_RUN_SCRIPT
   mozilla::ipc::IPCResult
   RecvNormalPriorityHandleTap(const layers::GeckoContentController::TapType& aType,
                               const LayoutDevicePoint& aPoint,
                               const Modifiers& aModifiers,
                               const ScrollableLayerGuid& aGuid,
                               const uint64_t& aInputBlockId) override;
 
   void SetAllowedTouchBehavior(uint64_t aInputBlockId,
--- a/gfx/layers/apz/util/APZCCallbackHelper.h
+++ b/gfx/layers/apz/util/APZCCallbackHelper.h
@@ -109,16 +109,17 @@ public:
                                                        uint64_t aTime,
                                                        const LayoutDevicePoint& aRefPoint,
                                                        Modifiers aModifiers,
                                                        int32_t aClickCount,
                                                        nsIWidget* aWidget);
 
     /* Dispatch a mouse event with the given parameters.
      * Return whether or not any listeners have called preventDefault on the event. */
+    MOZ_CAN_RUN_SCRIPT
     static bool DispatchMouseEvent(const nsCOMPtr<nsIPresShell>& aPresShell,
                                    const nsString& aType,
                                    const CSSPoint& aPoint,
                                    int32_t aButton,
                                    int32_t aClickCount,
                                    int32_t aModifiers,
                                    bool aIgnoreRootScrollFrame,
                                    unsigned short aInputSourceArg,
--- a/gfx/layers/apz/util/APZEventState.h
+++ b/gfx/layers/apz/util/APZEventState.h
@@ -49,22 +49,24 @@ public:
 
   NS_INLINE_DECL_REFCOUNTING(APZEventState);
 
   void ProcessSingleTap(const CSSPoint& aPoint,
                         const CSSToLayoutDeviceScale& aScale,
                         Modifiers aModifiers,
                         const ScrollableLayerGuid& aGuid,
                         int32_t aClickCount);
+  MOZ_CAN_RUN_SCRIPT
   void ProcessLongTap(const nsCOMPtr<nsIPresShell>& aUtils,
                       const CSSPoint& aPoint,
                       const CSSToLayoutDeviceScale& aScale,
                       Modifiers aModifiers,
                       const ScrollableLayerGuid& aGuid,
                       uint64_t aInputBlockId);
+  MOZ_CAN_RUN_SCRIPT
   void ProcessLongTapUp(const nsCOMPtr<nsIPresShell>& aPresShell,
                         const CSSPoint& aPoint,
                         const CSSToLayoutDeviceScale& aScale,
                         Modifiers aModifiers);
   void ProcessTouchEvent(const WidgetTouchEvent& aEvent,
                          const ScrollableLayerGuid& aGuid,
                          uint64_t aInputBlockId,
                          nsEventStatus aApzResponse,
@@ -77,16 +79,17 @@ public:
                          uint64_t aInputBlockId);
   void ProcessAPZStateChange(ViewID aViewId,
                              APZStateChange aChange,
                              int aArg);
   void ProcessClusterHit();
 private:
   ~APZEventState();
   bool SendPendingTouchPreventedResponse(bool aPreventDefault);
+  MOZ_CAN_RUN_SCRIPT
   bool FireContextmenuEvents(const nsCOMPtr<nsIPresShell>& aPresShell,
                              const CSSPoint& aPoint,
                              const CSSToLayoutDeviceScale& aScale,
                              Modifiers aModifiers,
                              const nsCOMPtr<nsIWidget>& aWidget);
   already_AddRefed<nsIWidget> GetWidget() const;
   already_AddRefed<nsIContent> GetTouchRollup() const;
 private:
--- a/gfx/layers/apz/util/ChromeProcessController.h
+++ b/gfx/layers/apz/util/ChromeProcessController.h
@@ -44,16 +44,17 @@ public:
   ~ChromeProcessController();
   virtual void Destroy() override;
 
   // GeckoContentController interface
   virtual void RequestContentRepaint(const FrameMetrics& aFrameMetrics) override;
   virtual void PostDelayedTask(already_AddRefed<Runnable> aTask, int aDelayMs) override;
   virtual bool IsRepaintThread() override;
   virtual void DispatchToRepaintThread(already_AddRefed<Runnable> aTask) override;
+  MOZ_CAN_RUN_SCRIPT
   virtual void HandleTap(TapType aType,
                          const mozilla::LayoutDevicePoint& aPoint,
                          Modifiers aModifiers,
                          const ScrollableLayerGuid& aGuid,
                          uint64_t aInputBlockId) override;
   virtual void NotifyPinchGesture(PinchGestureInput::PinchGestureType aType,
                                   const ScrollableLayerGuid& aGuid,
                                   LayoutDeviceCoord aSpanChange,
--- a/layout/base/AccessibleCaretEventHub.cpp
+++ b/layout/base/AccessibleCaretEventHub.cpp
@@ -39,18 +39,20 @@ NS_IMPL_ISUPPORTS(AccessibleCaretEventHu
 // NoActionState
 //
 class AccessibleCaretEventHub::NoActionState
   : public AccessibleCaretEventHub::State
 {
 public:
   const char* Name() const override { return "NoActionState"; }
 
+  MOZ_CAN_RUN_SCRIPT
   nsEventStatus OnPress(AccessibleCaretEventHub* aContext,
-                        const nsPoint& aPoint, int32_t aTouchId,
+                        const nsPoint& aPoint,
+                        int32_t aTouchId,
                         EventClassID aEventClass) override
   {
     nsEventStatus rv = nsEventStatus_eIgnore;
 
     if (NS_SUCCEEDED(aContext->mManager->PressCaret(aPoint, aEventClass))) {
       aContext->SetState(aContext->PressCaretState());
       rv = nsEventStatus_eConsumeNoDefault;
     } else {
@@ -58,40 +60,46 @@ public:
     }
 
     aContext->mPressPoint = aPoint;
     aContext->mActiveTouchId = aTouchId;
 
     return rv;
   }
 
+  MOZ_CAN_RUN_SCRIPT
   void OnScrollStart(AccessibleCaretEventHub* aContext) override
   {
     aContext->mManager->OnScrollStart();
     aContext->SetState(aContext->ScrollState());
   }
 
+  MOZ_CAN_RUN_SCRIPT
   void OnScrollPositionChanged(AccessibleCaretEventHub* aContext) override
   {
     aContext->mManager->OnScrollPositionChanged();
   }
 
+  MOZ_CAN_RUN_SCRIPT
   void OnSelectionChanged(AccessibleCaretEventHub* aContext,
-                          nsIDOMDocument* aDoc, nsISelection* aSel,
+                          nsIDOMDocument* aDoc,
+                          nsISelection* aSel,
                           int16_t aReason) override
   {
     aContext->mManager->OnSelectionChanged(aDoc, aSel, aReason);
   }
 
+  MOZ_CAN_RUN_SCRIPT
   void OnBlur(AccessibleCaretEventHub* aContext,
               bool aIsLeavingDocument) override
   {
     aContext->mManager->OnBlur();
   }
 
+  MOZ_CAN_RUN_SCRIPT
   void OnReflow(AccessibleCaretEventHub* aContext) override
   {
     aContext->mManager->OnReflow();
   }
 
   void Enter(AccessibleCaretEventHub* aContext) override
   {
     aContext->mPressPoint = nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
@@ -103,28 +111,30 @@ public:
 // PressCaretState: Always consume the event since we've pressed on the caret.
 //
 class AccessibleCaretEventHub::PressCaretState
   : public AccessibleCaretEventHub::State
 {
 public:
   const char* Name() const override { return "PressCaretState"; }
 
+  MOZ_CAN_RUN_SCRIPT
   nsEventStatus OnMove(AccessibleCaretEventHub* aContext,
                        const nsPoint& aPoint) override
   {
     if (aContext->MoveDistanceIsLarge(aPoint)) {
       if (NS_SUCCEEDED(aContext->mManager->DragCaret(aPoint))) {
         aContext->SetState(aContext->DragCaretState());
       }
     }
 
     return nsEventStatus_eConsumeNoDefault;
   }
 
+  MOZ_CAN_RUN_SCRIPT
   nsEventStatus OnRelease(AccessibleCaretEventHub* aContext) override
   {
     aContext->mManager->ReleaseCaret();
     aContext->mManager->TapCaret(aContext->mPressPoint);
     aContext->SetState(aContext->NoActionState());
 
     return nsEventStatus_eConsumeNoDefault;
   }
@@ -140,24 +150,26 @@ public:
 // DragCaretState: Always consume the event since we've pressed on the caret.
 //
 class AccessibleCaretEventHub::DragCaretState
   : public AccessibleCaretEventHub::State
 {
 public:
   const char* Name() const override { return "DragCaretState"; }
 
+  MOZ_CAN_RUN_SCRIPT
   nsEventStatus OnMove(AccessibleCaretEventHub* aContext,
                        const nsPoint& aPoint) override
   {
     aContext->mManager->DragCaret(aPoint);
 
     return nsEventStatus_eConsumeNoDefault;
   }
 
+  MOZ_CAN_RUN_SCRIPT
   nsEventStatus OnRelease(AccessibleCaretEventHub* aContext) override
   {
     aContext->mManager->ReleaseCaret();
     aContext->SetState(aContext->NoActionState());
 
     return nsEventStatus_eConsumeNoDefault;
   }
 };
@@ -183,46 +195,52 @@ public:
 
   nsEventStatus OnRelease(AccessibleCaretEventHub* aContext) override
   {
     aContext->SetState(aContext->NoActionState());
 
     return nsEventStatus_eIgnore;
   }
 
+  MOZ_CAN_RUN_SCRIPT
   nsEventStatus OnLongTap(AccessibleCaretEventHub* aContext,
                           const nsPoint& aPoint) override
   {
     aContext->SetState(aContext->LongTapState());
 
     return aContext->GetState()->OnLongTap(aContext, aPoint);
   }
 
+  MOZ_CAN_RUN_SCRIPT
   void OnScrollStart(AccessibleCaretEventHub* aContext) override
   {
     aContext->mManager->OnScrollStart();
     aContext->SetState(aContext->ScrollState());
   }
 
+  MOZ_CAN_RUN_SCRIPT
   void OnBlur(AccessibleCaretEventHub* aContext,
               bool aIsLeavingDocument) override
   {
     aContext->mManager->OnBlur();
     if (aIsLeavingDocument) {
       aContext->SetState(aContext->NoActionState());
     }
   }
 
+  MOZ_CAN_RUN_SCRIPT
   void OnSelectionChanged(AccessibleCaretEventHub* aContext,
-                          nsIDOMDocument* aDoc, nsISelection* aSel,
+                          nsIDOMDocument* aDoc,
+                          nsISelection* aSel,
                           int16_t aReason) override
   {
     aContext->mManager->OnSelectionChanged(aDoc, aSel, aReason);
   }
 
+  MOZ_CAN_RUN_SCRIPT
   void OnReflow(AccessibleCaretEventHub* aContext) override
   {
     aContext->mManager->OnReflow();
   }
 
   void Enter(AccessibleCaretEventHub* aContext) override
   {
     aContext->LaunchLongTapInjector();
@@ -238,27 +256,30 @@ public:
 // ScrollState
 //
 class AccessibleCaretEventHub::ScrollState
   : public AccessibleCaretEventHub::State
 {
 public:
   const char* Name() const override { return "ScrollState"; }
 
+  MOZ_CAN_RUN_SCRIPT
   void OnScrollEnd(AccessibleCaretEventHub* aContext) override
   {
     aContext->mManager->OnScrollEnd();
     aContext->SetState(aContext->NoActionState());
   }
 
+  MOZ_CAN_RUN_SCRIPT
   void OnScrollPositionChanged(AccessibleCaretEventHub* aContext) override
   {
     aContext->mManager->OnScrollPositionChanged();
   }
 
+  MOZ_CAN_RUN_SCRIPT
   void OnBlur(AccessibleCaretEventHub* aContext,
               bool aIsLeavingDocument) override
   {
     aContext->mManager->OnBlur();
     if (aIsLeavingDocument) {
       aContext->SetState(aContext->NoActionState());
     }
   }
@@ -268,16 +289,17 @@ public:
 // LongTapState
 //
 class AccessibleCaretEventHub::LongTapState
   : public AccessibleCaretEventHub::State
 {
 public:
   const char* Name() const override { return "LongTapState"; }
 
+  MOZ_CAN_RUN_SCRIPT
   nsEventStatus OnLongTap(AccessibleCaretEventHub* aContext,
                           const nsPoint& aPoint) override
   {
     // In general text selection is lower-priority than the context menu. If
     // we consume this long-press event, then it prevents the context menu from
     // showing up on desktop Firefox (because that happens on long-tap-up, if
     // the long-tap was not cancelled). So we return eIgnore instead.
     aContext->mManager->SelectWordOrShortcut(aPoint);
@@ -288,22 +310,24 @@ public:
   {
     aContext->SetState(aContext->NoActionState());
 
     // Do not consume the release since the press is not consumed in
     // PressNoCaretState either.
     return nsEventStatus_eIgnore;
   }
 
+  MOZ_CAN_RUN_SCRIPT
   void OnScrollStart(AccessibleCaretEventHub* aContext) override
   {
     aContext->mManager->OnScrollStart();
     aContext->SetState(aContext->ScrollState());
   }
 
+  MOZ_CAN_RUN_SCRIPT
   void OnReflow(AccessibleCaretEventHub* aContext) override
   {
     aContext->mManager->OnReflow();
   }
 };
 
 // -----------------------------------------------------------------------------
 // Implementation of AccessibleCaretEventHub methods
--- a/layout/base/AccessibleCaretEventHub.h
+++ b/layout/base/AccessibleCaretEventHub.h
@@ -55,38 +55,56 @@ class WidgetTouchEvent;
 // State transition diagram:
 // https://hg.mozilla.org/mozilla-central/raw-file/default/layout/base/doc/AccessibleCaretEventHubStates.png
 // Source code of the diagram:
 // https://hg.mozilla.org/mozilla-central/file/default/layout/base/doc/AccessibleCaretEventHubStates.dot
 //
 // Please see the wiki page for more information.
 // https://wiki.mozilla.org/AccessibleCaret
 //
-class AccessibleCaretEventHub : public nsIReflowObserver,
-                                public nsIScrollObserver,
-                                public nsISelectionListener,
-                                public nsSupportsWeakReference
+class AccessibleCaretEventHub
+  : public nsIReflowObserver
+  , public nsIScrollObserver
+  , public nsISelectionListener
+  , public nsSupportsWeakReference
 {
 public:
   explicit AccessibleCaretEventHub(nsIPresShell* aPresShell);
   void Init();
   void Terminate();
 
+  MOZ_CAN_RUN_SCRIPT
   nsEventStatus HandleEvent(WidgetEvent* aEvent);
 
   // Call this function to notify the blur event happened.
+  MOZ_CAN_RUN_SCRIPT
   void NotifyBlur(bool aIsLeavingDocument);
 
   NS_DECL_ISUPPORTS
-  NS_DECL_NSIREFLOWOBSERVER
-  NS_DECL_NSISELECTIONLISTENER
+
+  // nsIReflowObserver
+  MOZ_CAN_RUN_SCRIPT
+  NS_IMETHOD Reflow(DOMHighResTimeStamp start,
+                    DOMHighResTimeStamp end) final;
+  MOZ_CAN_RUN_SCRIPT
+  NS_IMETHOD ReflowInterruptible(DOMHighResTimeStamp start,
+                                 DOMHighResTimeStamp end) final;
+
+  // nsISelectionListener
+  MOZ_CAN_RUN_SCRIPT
+  NS_IMETHOD NotifySelectionChanged(nsIDOMDocument* doc,
+                                    nsISelection* sel,
+                                    int16_t reason) final;
 
   // Override nsIScrollObserver methods.
+  MOZ_CAN_RUN_SCRIPT
   virtual void ScrollPositionChanged() override;
+  MOZ_CAN_RUN_SCRIPT
   virtual void AsyncPanZoomStarted() override;
+  MOZ_CAN_RUN_SCRIPT
   virtual void AsyncPanZoomStopped() override;
 
   // Base state
   class State;
   State* GetState() const;
 
 protected:
   virtual ~AccessibleCaretEventHub() = default;
@@ -107,32 +125,39 @@ protected:
   MOZ_DECL_STATE_CLASS_GETTER(PressCaretState)
   MOZ_DECL_STATE_CLASS_GETTER(DragCaretState)
   MOZ_DECL_STATE_CLASS_GETTER(PressNoCaretState)
   MOZ_DECL_STATE_CLASS_GETTER(ScrollState)
   MOZ_DECL_STATE_CLASS_GETTER(LongTapState)
 
   void SetState(State* aState);
 
+  MOZ_CAN_RUN_SCRIPT
   nsEventStatus HandleMouseEvent(WidgetMouseEvent* aEvent);
+  MOZ_CAN_RUN_SCRIPT
   nsEventStatus HandleTouchEvent(WidgetTouchEvent* aEvent);
+  MOZ_CAN_RUN_SCRIPT
   nsEventStatus HandleKeyboardEvent(WidgetKeyboardEvent* aEvent);
 
   virtual nsPoint GetTouchEventPosition(WidgetTouchEvent* aEvent,
                                         int32_t aIdentifier) const;
   virtual nsPoint GetMouseEventPosition(WidgetMouseEvent* aEvent) const;
 
   bool MoveDistanceIsLarge(const nsPoint& aPoint) const;
 
   void LaunchLongTapInjector();
   void CancelLongTapInjector();
+
+  MOZ_CAN_RUN_SCRIPT_BOUNDARY
   static void FireLongTap(nsITimer* aTimer, void* aAccessibleCaretEventHub);
 
   void LaunchScrollEndInjector();
   void CancelScrollEndInjector();
+
+  MOZ_CAN_RUN_SCRIPT_BOUNDARY
   static void FireScrollEnd(nsITimer* aTimer, void* aAccessibleCaretEventHub);
 
   // Member variables
   State* mState = NoActionState();
 
   // Will be set to nullptr in Terminate().
   nsIPresShell* MOZ_NON_OWNING_REF mPresShell = nullptr;
 
--- a/layout/base/AccessibleCaretManager.cpp
+++ b/layout/base/AccessibleCaretManager.cpp
@@ -543,28 +543,24 @@ AccessibleCaretManager::TapCaret(const n
   }
 
   return rv;
 }
 
 nsresult
 AccessibleCaretManager::SelectWordOrShortcut(const nsPoint& aPoint)
 {
-  auto UpdateCaretsWithHapticFeedback = [this] {
-    UpdateCarets();
-    ProvideHapticFeedback();
-  };
-
   // If the long-tap is landing on a pre-existing selection, don't replace
   // it with a new one. Instead just return and let the context menu pop up
   // on the pre-existing selection.
   if (GetCaretMode() == CaretMode::Selection &&
       GetSelection()->ContainsPoint(aPoint)) {
     AC_LOG("%s: UpdateCarets() for current selection", __FUNCTION__);
-    UpdateCaretsWithHapticFeedback();
+    UpdateCarets();
+    ProvideHapticFeedback();
     return NS_OK;
   }
 
   if (!mPresShell) {
     return NS_ERROR_UNEXPECTED;
   }
 
   nsIFrame* rootFrame = mPresShell->GetRootFrame();
@@ -602,17 +598,18 @@ AccessibleCaretManager::SelectWordOrShor
       !HasNonEmptyTextContent(newFocusEditingHost)) {
     ChangeFocusToOrClearOldFocus(focusableFrame);
 
     if (sCaretShownWhenLongTappingOnEmptyContent) {
       mFirstCaret->SetAppearance(Appearance::Normal);
     }
     // We need to update carets to get correct information before dispatching
     // CaretStateChangedEvent.
-    UpdateCaretsWithHapticFeedback();
+    UpdateCarets();
+    ProvideHapticFeedback();
     DispatchCaretStateChangedEvent(CaretChangedReason::Longpressonemptycontent);
     return NS_OK;
   }
 
   bool selectable = ptFrame->IsSelectable(nullptr);
 
 #ifdef DEBUG_FRAME_DUMP
   AC_LOG("%s: %s %s selectable.", __FUNCTION__, ptFrame->ListTag().get(),
@@ -636,17 +633,18 @@ AccessibleCaretManager::SelectWordOrShor
   ChangeFocusToOrClearOldFocus(focusableFrame);
   if (!ptFrame.IsAlive()) {
     // Cannot continue because ptFrame died.
     return NS_ERROR_FAILURE;
   }
 
   // Then try select a word under point.
   nsresult rv = SelectWord(ptFrame, ptInFrame);
-  UpdateCaretsWithHapticFeedback();
+  UpdateCarets();
+  ProvideHapticFeedback();
 
   return rv;
 }
 
 void
 AccessibleCaretManager::OnScrollStart()
 {
   AC_LOG("%s", __FUNCTION__);
--- a/layout/base/AccessibleCaretManager.h
+++ b/layout/base/AccessibleCaretManager.h
@@ -54,54 +54,67 @@ public:
   // Called by AccessibleCaretEventHub to inform us that PresShell is destroyed.
   void Terminate();
 
   // The aPoint in the following public methods should be relative to root
   // frame.
 
   // Press caret on the given point. Return NS_OK if the point is actually on
   // one of the carets.
-  virtual nsresult PressCaret(const nsPoint& aPoint, EventClassID aEventClass);
+  MOZ_CAN_RUN_SCRIPT
+  virtual nsresult PressCaret(const nsPoint& aPoint,
+                              EventClassID aEventClass);
 
   // Drag caret to the given point. It's required to call PressCaret()
   // beforehand.
+  MOZ_CAN_RUN_SCRIPT
   virtual nsresult DragCaret(const nsPoint& aPoint);
 
   // Release caret from he previous press action. It's required to call
   // PressCaret() beforehand.
+  MOZ_CAN_RUN_SCRIPT
   virtual nsresult ReleaseCaret();
 
   // A quick single tap on caret on given point without dragging.
+  MOZ_CAN_RUN_SCRIPT
   virtual nsresult TapCaret(const nsPoint& aPoint);
 
   // Select a word or bring up paste shortcut (if Gaia is listening) under the
   // given point.
+  MOZ_CAN_RUN_SCRIPT
   virtual nsresult SelectWordOrShortcut(const nsPoint& aPoint);
 
   // Handle scroll-start event.
+  MOZ_CAN_RUN_SCRIPT
   virtual void OnScrollStart();
 
   // Handle scroll-end event.
+  MOZ_CAN_RUN_SCRIPT
   virtual void OnScrollEnd();
 
   // Handle ScrollPositionChanged from nsIScrollObserver. This might be called
   // at anytime, not necessary between OnScrollStart and OnScrollEnd.
+  MOZ_CAN_RUN_SCRIPT
   virtual void OnScrollPositionChanged();
 
   // Handle reflow event from nsIReflowObserver.
+  MOZ_CAN_RUN_SCRIPT
   virtual void OnReflow();
 
   // Handle blur event from nsFocusManager.
+  MOZ_CAN_RUN_SCRIPT
   virtual void OnBlur();
 
   // Handle NotifySelectionChanged event from nsISelectionListener.
+  MOZ_CAN_RUN_SCRIPT
   virtual nsresult OnSelectionChanged(nsIDOMDocument* aDoc,
                                       nsISelection* aSel,
                                       int16_t aReason);
   // Handle key event.
+  MOZ_CAN_RUN_SCRIPT
   virtual void OnKeyboardEvent();
 
   // The canvas frame holding the accessible caret anonymous content elements
   // was reconstructed, resulting in the content elements getting cloned.
   virtual void OnFrameReconstruction();
 
   // Update the manager with the last input source that was observed. This
   // is used in part to determine if the carets should be shown or hidden.
@@ -140,22 +153,28 @@ protected:
   using UpdateCaretsHintSet = mozilla::EnumSet<UpdateCaretsHint>;
 
   friend std::ostream& operator<<(std::ostream& aStream,
                                   const UpdateCaretsHint& aResult);
 
   // Update carets based on current selection status. This function will flush
   // layout, so caller must ensure the PresShell is still valid after calling
   // this method.
-  void UpdateCarets(const UpdateCaretsHintSet& aHints = UpdateCaretsHint::Default);
+  MOZ_CAN_RUN_SCRIPT
+  void UpdateCarets(
+    const UpdateCaretsHintSet& aHints = UpdateCaretsHint::Default);
 
   // Force hiding all carets regardless of the current selection status.
+  MOZ_CAN_RUN_SCRIPT
   void HideCarets();
 
+  MOZ_CAN_RUN_SCRIPT
   void UpdateCaretsForCursorMode(const UpdateCaretsHintSet& aHints);
+
+  MOZ_CAN_RUN_SCRIPT
   void UpdateCaretsForSelectionMode(const UpdateCaretsHintSet& aHints);
 
   // Provide haptic / touch feedback, primarily for select on longpress.
   void ProvideHapticFeedback();
 
   // Get the nearest enclosing focusable frame of aFrame.
   // @return focusable frame if there is any; nullptr otherwise.
   nsIFrame* GetFocusableFrame(nsIFrame* aFrame) const;
@@ -200,17 +219,18 @@ protected:
   void ClearMaintainedSelection() const;
 
   // This method could kill the shell, so callers to methods that call
   // FlushLayout should ensure the event hub that owns us is still alive.
   //
   // See the mRefCnt assertions in AccessibleCaretEventHub.
   //
   // Returns whether mPresShell we're holding is still valid.
-  MOZ_MUST_USE bool FlushLayout();
+  MOZ_MUST_USE MOZ_CAN_RUN_SCRIPT
+  bool FlushLayout();
 
   dom::Element* GetEditingHostForFrame(nsIFrame* aFrame) const;
   dom::Selection* GetSelection() const;
   already_AddRefed<nsFrameSelection> GetFrameSelection() const;
   nsAutoString StringifiedSelection() const;
 
   // Get the union of all the child frame scrollable overflow rects for aFrame,
   // which is used as a helper function to restrict the area where the caret can
@@ -256,16 +276,17 @@ protected:
   // @param aOutOffset returns frame offset as well.
   virtual bool IsCaretDisplayableInCursorMode(nsIFrame** aOutFrame = nullptr,
                                               int32_t* aOutOffset = nullptr) const;
 
   virtual bool HasNonEmptyTextContent(nsINode* aNode) const;
 
   // This function will flush layout, so caller must ensure the PresShell is
   // still valid after calling this method.
+  MOZ_CAN_RUN_SCRIPT
   virtual void DispatchCaretStateChangedEvent(dom::CaretChangedReason aReason);
 
   // ---------------------------------------------------------------------------
   // Member variables
   //
   nscoord mOffsetYToCaretLogicalPosition = NS_UNCONSTRAINEDSIZE;
 
   // AccessibleCaretEventHub owns us by a UniquePtr. When it's destroyed, we'll
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -6989,43 +6989,40 @@ PresShell::HandleEvent(nsIFrame* aFrame,
       // Prevent application crashes, in case damaged frame.
       if (!frameKeeper.IsAlive()) {
         NS_WARNING("Nothing to handle this event!");
         return NS_OK;
       }
     }
 
     // Only capture mouse events and pointer events.
-    nsIContent* pointerCapturingContent =
+    nsCOMPtr<nsIContent> pointerCapturingContent =
       PointerEventHandler::GetPointerCapturingContent(aEvent);
 
     if (pointerCapturingContent) {
-      nsIFrame* pointerCapturingFrame =
-        pointerCapturingContent->GetPrimaryFrame();
-
-      if (!pointerCapturingFrame) {
+      frame = pointerCapturingContent->GetPrimaryFrame();
+
+      if (!frame) {
         // Dispatch events to the capturing content even it's frame is
         // destroyed.
         PointerEventHandler::DispatchPointerFromMouseOrTouch(
-          this, nullptr, pointerCapturingContent, aEvent, false, aEventStatus,
-          nullptr);
-
-        PresShell* shell = GetShellForEventTarget(nullptr,
-                                                  pointerCapturingContent);
+          this, nullptr, pointerCapturingContent, aEvent, false,
+          aEventStatus, nullptr);
+
+        RefPtr<PresShell> shell =
+          GetShellForEventTarget(nullptr, pointerCapturingContent);
 
         if (!shell) {
           // The capturing element could be changed when dispatch pointer
           // events.
           return NS_OK;
         }
         return shell->HandleEventWithTarget(aEvent, nullptr,
                                             pointerCapturingContent,
                                             aEventStatus, true);
-      } else {
-        frame = pointerCapturingFrame;
       }
     }
 
     WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent();
     bool isWindowLevelMouseExit = (aEvent->mMessage == eMouseExitFromWidget) &&
       (mouseEvent && mouseEvent->mExitFrom == WidgetMouseEvent::eTopLevel);
 
     // Get the frame at the event point. However, don't do this if we're
@@ -7090,17 +7087,17 @@ PresShell::HandleEvent(nsIFrame* aFrame,
       return NS_OK;
     }
 
     if (!frame) {
       NS_WARNING("Nothing to handle this event!");
       return NS_OK;
     }
 
-    PresShell* shell = static_cast<PresShell*>(frame->PresShell());
+    RefPtr<PresShell> shell = static_cast<PresShell*>(frame->PresShell());
     // Check if we have an active EventStateManager which isn't the
     // EventStateManager of the current PresContext.
     // If that is the case, and mouse is over some ancestor document,
     // forward event handling to the active document.
     // This way content can get mouse events even when
     // mouse is over the chrome or outside the window.
     //
     // Note, currently for backwards compatibility we don't forward mouse events
@@ -7193,27 +7190,25 @@ PresShell::HandleEvent(nsIFrame* aFrame,
     if (aEvent->mClass == eTouchEventClass) {
       if (aEvent->mMessage == eTouchStart) {
         WidgetTouchEvent* touchEvent = aEvent->AsTouchEvent();
         if (nsIFrame* newFrame =
               TouchManager::SuppressInvalidPointsAndGetTargetedFrame(
                 touchEvent)) {
           frame = newFrame;
           frame->GetContentForEvent(aEvent, getter_AddRefs(targetElement));
-          shell = static_cast<PresShell*>(frame->PresContext()->PresShell());
+          shell = static_cast<PresShell*>(frame->PresShell());
         }
       } else if (PresShell* newShell = GetShellForTouchEvent(aEvent)) {
         // Touch events (except touchstart) are dispatching to the captured
         // element. Get correct shell from it.
         shell = newShell;
       }
     }
 
-    // Prevent deletion until we're done with event handling (bug 336582)
-    nsCOMPtr<nsIPresShell> kungFuDeathGrip(shell);
     nsresult rv;
 
     // Handle the event in the correct shell.
     // We pass the subshell's root frame as the frame to start from. This is
     // the only correct alternative; if the event was captured then it
     // must have been captured by us or some ancestor shell and we
     // now ask the subshell to dispatch it normally.
     shell->PushCurrentEventInfo(frame, targetElement);
--- a/layout/base/PresShell.h
+++ b/layout/base/PresShell.h
@@ -221,20 +221,20 @@ public:
   float GetCumulativeNonRootScaleResolution() override;
   void SetRestoreResolution(float aResolution,
                             LayoutDeviceIntSize aDisplaySize) override;
 
   //nsIViewObserver interface
 
   void Paint(nsView* aViewToPaint, const nsRegion& aDirtyRegion,
              uint32_t aFlags) override;
-  nsresult HandleEvent(nsIFrame* aFrame,
-                       WidgetGUIEvent* aEvent,
-                       bool aDontRetargetEvents,
-                       nsEventStatus* aEventStatus) override;
+  MOZ_CAN_RUN_SCRIPT nsresult HandleEvent(nsIFrame* aFrame,
+                                          WidgetGUIEvent* aEvent,
+                                          bool aDontRetargetEvents,
+                                          nsEventStatus* aEventStatus) override;
   nsresult HandleDOMEventWithTarget(nsIContent* aTargetContent,
                                     WidgetEvent* aEvent,
                                     nsEventStatus* aStatus) override;
   nsresult HandleDOMEventWithTarget(nsIContent* aTargetContent,
                                     nsIDOMEvent* aEvent,
                                     nsEventStatus* aStatus) override;
   bool ShouldIgnoreInvalidation() override;
   void WillPaint() override;
@@ -661,18 +661,18 @@ private:
 
   void QueryIsActive();
   nsresult UpdateImageLockingState();
 
   bool InZombieDocument(nsIContent *aContent);
   already_AddRefed<nsIPresShell> GetParentPresShellForEventHandling();
   nsIContent* GetCurrentEventContent();
   nsIFrame* GetCurrentEventFrame();
-  nsresult RetargetEventToParent(WidgetGUIEvent* aEvent,
-                                 nsEventStatus* aEventStatus);
+  MOZ_CAN_RUN_SCRIPT nsresult
+  RetargetEventToParent(WidgetGUIEvent* aEvent, nsEventStatus* aEventStatus);
   void PushCurrentEventInfo(nsIFrame* aFrame, nsIContent* aContent);
   void PopCurrentEventInfo();
   /**
    * @param aIsHandlingNativeEvent      true when the caller (perhaps) handles
    *                                    an event which is caused by native
    *                                    event.  Otherwise, false.
    */
   nsresult HandleEventInternal(WidgetEvent* aEvent,
--- a/layout/base/gtest/TestAccessibleCaretEventHub.cpp
+++ b/layout/base/gtest/TestAccessibleCaretEventHub.cpp
@@ -190,77 +190,90 @@ public:
 
   static UniquePtr<WidgetEvent> CreateWheelEvent(EventMessage aMessage)
   {
     auto event = MakeUnique<WidgetWheelEvent>(true, aMessage, nullptr);
 
     return Move(event);
   }
 
+  MOZ_CAN_RUN_SCRIPT_BOUNDARY void TestAsyncPanZoomScroll();
+
+  MOZ_CAN_RUN_SCRIPT_BOUNDARY
   void HandleEventAndCheckState(UniquePtr<WidgetEvent> aEvent,
                                 MockAccessibleCaretEventHub::State* aExpectedState,
                                 nsEventStatus aExpectedEventStatus)
   {
     nsEventStatus rv = mHub->HandleEvent(aEvent.get());
     EXPECT_EQ(mHub->GetState(), aExpectedState);
     EXPECT_EQ(rv, aExpectedEventStatus);
   }
 
   void CheckState(MockAccessibleCaretEventHub::State* aExpectedState)
   {
     EXPECT_EQ(mHub->GetState(), aExpectedState);
   }
 
-  template <typename PressEventCreator, typename ReleaseEventCreator>
-  void TestPressReleaseOnNoCaret(PressEventCreator aPressEventCreator,
-                                 ReleaseEventCreator aReleaseEventCreator);
-
-  template <typename PressEventCreator, typename ReleaseEventCreator>
-  void TestPressReleaseOnCaret(PressEventCreator aPressEventCreator,
-                               ReleaseEventCreator aReleaseEventCreator);
+  template<typename PressEventCreator, typename ReleaseEventCreator>
+  MOZ_CAN_RUN_SCRIPT_BOUNDARY void TestPressReleaseOnNoCaret(
+    PressEventCreator aPressEventCreator,
+    ReleaseEventCreator aReleaseEventCreator);
 
-  template <typename PressEventCreator, typename MoveEventCreator,
-            typename ReleaseEventCreator>
-  void TestPressMoveReleaseOnNoCaret(PressEventCreator aPressEventCreator,
-                                     MoveEventCreator aMoveEventCreator,
-                                     ReleaseEventCreator aReleaseEventCreator);
-
-  template <typename PressEventCreator, typename MoveEventCreator,
-            typename ReleaseEventCreator>
-  void TestPressMoveReleaseOnCaret(PressEventCreator aPressEventCreator,
-                                   MoveEventCreator aMoveEventCreator,
-                                   ReleaseEventCreator aReleaseEventCreator);
-
-  template <typename PressEventCreator, typename ReleaseEventCreator>
-  void TestLongTapWithSelectWordSuccessful(
+  template<typename PressEventCreator, typename ReleaseEventCreator>
+  MOZ_CAN_RUN_SCRIPT_BOUNDARY void TestPressReleaseOnCaret(
     PressEventCreator aPressEventCreator,
     ReleaseEventCreator aReleaseEventCreator);
 
-  template <typename PressEventCreator, typename ReleaseEventCreator>
-  void TestLongTapWithSelectWordFailed(
+  template<typename PressEventCreator,
+           typename MoveEventCreator,
+           typename ReleaseEventCreator>
+  MOZ_CAN_RUN_SCRIPT_BOUNDARY void TestPressMoveReleaseOnNoCaret(
+    PressEventCreator aPressEventCreator,
+    MoveEventCreator aMoveEventCreator,
+    ReleaseEventCreator aReleaseEventCreator);
+
+  template<typename PressEventCreator,
+           typename MoveEventCreator,
+           typename ReleaseEventCreator>
+  MOZ_CAN_RUN_SCRIPT_BOUNDARY void TestPressMoveReleaseOnCaret(
+    PressEventCreator aPressEventCreator,
+    MoveEventCreator aMoveEventCreator,
+    ReleaseEventCreator aReleaseEventCreator);
+
+  template<typename PressEventCreator, typename ReleaseEventCreator>
+  MOZ_CAN_RUN_SCRIPT_BOUNDARY void TestLongTapWithSelectWordSuccessful(
     PressEventCreator aPressEventCreator,
     ReleaseEventCreator aReleaseEventCreator);
 
-  template <typename PressEventCreator, typename MoveEventCreator,
-            typename ReleaseEventCreator>
-  void TestEventDrivenAsyncPanZoomScroll(
-    PressEventCreator aPressEventCreator, MoveEventCreator aMoveEventCreator,
+  template<typename PressEventCreator, typename ReleaseEventCreator>
+  MOZ_CAN_RUN_SCRIPT_BOUNDARY void TestLongTapWithSelectWordFailed(
+    PressEventCreator aPressEventCreator,
+    ReleaseEventCreator aReleaseEventCreator);
+
+  template<typename PressEventCreator,
+           typename MoveEventCreator,
+           typename ReleaseEventCreator>
+  MOZ_CAN_RUN_SCRIPT_BOUNDARY void TestEventDrivenAsyncPanZoomScroll(
+    PressEventCreator aPressEventCreator,
+    MoveEventCreator aMoveEventCreator,
     ReleaseEventCreator aReleaseEventCreator);
 
   // Member variables
   RefPtr<MockAccessibleCaretEventHub> mHub{new MockAccessibleCaretEventHub()};
 
 }; // class AccessibleCaretEventHubTester
 
 TEST_F(AccessibleCaretEventHubTester, TestMousePressReleaseOnNoCaret)
+MOZ_CAN_RUN_SCRIPT
 {
   TestPressReleaseOnNoCaret(CreateMousePressEvent, CreateMouseReleaseEvent);
 }
 
 TEST_F(AccessibleCaretEventHubTester, TestTouchPressReleaseOnNoCaret)
+MOZ_CAN_RUN_SCRIPT
 {
   TestPressReleaseOnNoCaret(CreateTouchStartEvent, CreateTouchEndEvent);
 }
 
 template <typename PressEventCreator, typename ReleaseEventCreator>
 void
 AccessibleCaretEventHubTester::TestPressReleaseOnNoCaret(
   PressEventCreator aPressEventCreator,
@@ -278,21 +291,23 @@ AccessibleCaretEventHubTester::TestPress
                            nsEventStatus_eIgnore);
 
   HandleEventAndCheckState(aReleaseEventCreator(0, 0),
                            MockAccessibleCaretEventHub::NoActionState(),
                            nsEventStatus_eIgnore);
 }
 
 TEST_F(AccessibleCaretEventHubTester, TestMousePressReleaseOnCaret)
+MOZ_CAN_RUN_SCRIPT
 {
   TestPressReleaseOnCaret(CreateMousePressEvent, CreateMouseReleaseEvent);
 }
 
 TEST_F(AccessibleCaretEventHubTester, TestTouchPressReleaseOnCaret)
+MOZ_CAN_RUN_SCRIPT
 {
   TestPressReleaseOnCaret(CreateTouchStartEvent, CreateTouchEndEvent);
 }
 
 template <typename PressEventCreator, typename ReleaseEventCreator>
 void
 AccessibleCaretEventHubTester::TestPressReleaseOnCaret(
   PressEventCreator aPressEventCreator,
@@ -320,22 +335,24 @@ AccessibleCaretEventHubTester::TestPress
                            nsEventStatus_eConsumeNoDefault);
 
   HandleEventAndCheckState(aReleaseEventCreator(0, 0),
                            MockAccessibleCaretEventHub::NoActionState(),
                            nsEventStatus_eConsumeNoDefault);
 }
 
 TEST_F(AccessibleCaretEventHubTester, TestMousePressMoveReleaseOnNoCaret)
+MOZ_CAN_RUN_SCRIPT
 {
   TestPressMoveReleaseOnNoCaret(CreateMousePressEvent, CreateMouseMoveEvent,
                                 CreateMouseReleaseEvent);
 }
 
 TEST_F(AccessibleCaretEventHubTester, TestTouchPressMoveReleaseOnNoCaret)
+MOZ_CAN_RUN_SCRIPT
 {
   TestPressMoveReleaseOnNoCaret(CreateTouchStartEvent, CreateTouchMoveEvent,
                                 CreateTouchEndEvent);
 }
 
 template <typename PressEventCreator, typename MoveEventCreator,
           typename ReleaseEventCreator>
 void
@@ -374,22 +391,24 @@ AccessibleCaretEventHubTester::TestPress
                            nsEventStatus_eIgnore);
 
   HandleEventAndCheckState(aReleaseEventCreator(x3, y3),
                            MockAccessibleCaretEventHub::NoActionState(),
                            nsEventStatus_eIgnore);
 }
 
 TEST_F(AccessibleCaretEventHubTester, TestMousePressMoveReleaseOnCaret)
+MOZ_CAN_RUN_SCRIPT
 {
   TestPressMoveReleaseOnCaret(CreateMousePressEvent, CreateMouseMoveEvent,
                               CreateMouseReleaseEvent);
 }
 
 TEST_F(AccessibleCaretEventHubTester, TestTouchPressMoveReleaseOnCaret)
+MOZ_CAN_RUN_SCRIPT
 {
   TestPressMoveReleaseOnCaret(CreateTouchStartEvent, CreateTouchMoveEvent,
                               CreateTouchEndEvent);
 }
 
 template <typename PressEventCreator, typename MoveEventCreator,
           typename ReleaseEventCreator>
 void
@@ -441,16 +460,17 @@ AccessibleCaretEventHubTester::TestPress
 
   HandleEventAndCheckState(aReleaseEventCreator(x3, y3),
                            MockAccessibleCaretEventHub::NoActionState(),
                            nsEventStatus_eConsumeNoDefault);
 }
 
 TEST_F(AccessibleCaretEventHubTester,
        TestTouchStartMoveEndOnCaretWithTouchCancelIgnored)
+MOZ_CAN_RUN_SCRIPT
 {
   nscoord x0 = 0, y0 = 0;
   nscoord x1 = 100, y1 = 100;
   nscoord x2 = 300, y2 = 300;
   nscoord x3 = 400, y3 = 400;
 
   {
     InSequence dummy;
@@ -499,22 +519,24 @@ TEST_F(AccessibleCaretEventHubTester,
                            MockAccessibleCaretEventHub::NoActionState(),
                            nsEventStatus_eConsumeNoDefault);
 
   HandleEventAndCheckState(CreateTouchCancelEvent(x3, y3),
                            MockAccessibleCaretEventHub::NoActionState(),
                            nsEventStatus_eIgnore);}
 
 TEST_F(AccessibleCaretEventHubTester, TestMouseLongTapWithSelectWordSuccessful)
+MOZ_CAN_RUN_SCRIPT
 {
   TestLongTapWithSelectWordSuccessful(CreateMousePressEvent,
                                       CreateMouseReleaseEvent);
 }
 
 TEST_F(AccessibleCaretEventHubTester, TestTouchLongTapWithSelectWordSuccessful)
+MOZ_CAN_RUN_SCRIPT
 {
   TestLongTapWithSelectWordSuccessful(CreateTouchStartEvent,
                                       CreateTouchEndEvent);
 }
 
 template <typename PressEventCreator, typename ReleaseEventCreator>
 void
 AccessibleCaretEventHubTester::TestLongTapWithSelectWordSuccessful(
@@ -579,22 +601,24 @@ AccessibleCaretEventHubTester::TestLongT
   EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::NoActionState());
 
   HandleEventAndCheckState(aReleaseEventCreator(1, 1),
                            MockAccessibleCaretEventHub::NoActionState(),
                            nsEventStatus_eIgnore);
 }
 
 TEST_F(AccessibleCaretEventHubTester, TestMouseLongTapWithSelectWordFailed)
+MOZ_CAN_RUN_SCRIPT
 {
   TestLongTapWithSelectWordFailed(CreateMousePressEvent,
                                   CreateMouseReleaseEvent);
 }
 
 TEST_F(AccessibleCaretEventHubTester, TestTouchLongTapWithSelectWordFailed)
+MOZ_CAN_RUN_SCRIPT
 {
   TestLongTapWithSelectWordFailed(CreateTouchStartEvent,
                                   CreateTouchEndEvent);
 }
 
 template <typename PressEventCreator, typename ReleaseEventCreator>
 void
 AccessibleCaretEventHubTester::TestLongTapWithSelectWordFailed(
@@ -620,22 +644,24 @@ AccessibleCaretEventHubTester::TestLongT
                            nsEventStatus_eIgnore);
 
   HandleEventAndCheckState(aReleaseEventCreator(0, 0),
                            MockAccessibleCaretEventHub::NoActionState(),
                            nsEventStatus_eIgnore);
 }
 
 TEST_F(AccessibleCaretEventHubTester, TestTouchEventDrivenAsyncPanZoomScroll)
+MOZ_CAN_RUN_SCRIPT
 {
   TestEventDrivenAsyncPanZoomScroll(CreateTouchStartEvent, CreateTouchMoveEvent,
                                     CreateTouchEndEvent);
 }
 
 TEST_F(AccessibleCaretEventHubTester, TestMouseEventDrivenAsyncPanZoomScroll)
+MOZ_CAN_RUN_SCRIPT
 {
   TestEventDrivenAsyncPanZoomScroll(CreateMousePressEvent, CreateMouseMoveEvent,
                                     CreateMouseReleaseEvent);
 }
 
 template <typename PressEventCreator, typename MoveEventCreator,
           typename ReleaseEventCreator>
 void
@@ -719,17 +745,23 @@ AccessibleCaretEventHubTester::TestEvent
   mHub->AsyncPanZoomStopped();
   EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::NoActionState());
 
   HandleEventAndCheckState(aReleaseEventCreator(310, 310),
                            MockAccessibleCaretEventHub::NoActionState(),
                            nsEventStatus_eIgnore);
 }
 
-TEST_F(AccessibleCaretEventHubTester, TestAsyncPanZoomScroll)
+TEST_F(AccessibleCaretEventHubTester, TestAsyncPanZoomScroll) MOZ_CAN_RUN_SCRIPT
+{
+  TestAsyncPanZoomScroll();
+}
+
+void
+AccessibleCaretEventHubTester::TestAsyncPanZoomScroll()
 {
   MockFunction<void(::std::string aCheckPointName)> check;
   {
     InSequence dummy;
 
     EXPECT_CALL(check, Call("1"));
     EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollStart());
     EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(),
@@ -764,16 +796,17 @@ TEST_F(AccessibleCaretEventHubTester, Te
   mHub->ScrollPositionChanged();
   EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::ScrollState());
 
   mHub->AsyncPanZoomStopped();
   EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::NoActionState());
 }
 
 TEST_F(AccessibleCaretEventHubTester, TestAsyncPanZoomScrollStartedThenBlur)
+MOZ_CAN_RUN_SCRIPT
 {
   {
     InSequence dummy;
 
     EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollStart());
     EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollEnd()).Times(0);
     EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnBlur());
   }
@@ -784,16 +817,17 @@ TEST_F(AccessibleCaretEventHubTester, Te
   mHub->ScrollPositionChanged();
   EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::ScrollState());
 
   mHub->NotifyBlur(true);
   EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::NoActionState());
 }
 
 TEST_F(AccessibleCaretEventHubTester, TestAsyncPanZoomScrollEndedThenBlur)
+MOZ_CAN_RUN_SCRIPT
 {
   {
     InSequence dummy;
 
     EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollStart());
     EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollEnd());
     EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnBlur());
   }
--- a/layout/base/gtest/TestAccessibleCaretManager.cpp
+++ b/layout/base/gtest/TestAccessibleCaretManager.cpp
@@ -141,16 +141,17 @@ public:
   }
 
   // Member variables
   MockAccessibleCaretManager mManager;
 
 }; // class AccessibleCaretManagerTester
 
 TEST_F(AccessibleCaretManagerTester, TestUpdatesInSelectionMode)
+MOZ_CAN_RUN_SCRIPT
 {
   EXPECT_CALL(mManager, GetCaretMode())
     .WillRepeatedly(Return(CaretMode::Selection));
 
   EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
                 CaretChangedReason::Updateposition)).Times(3);
 
   mManager.UpdateCarets();
@@ -162,16 +163,17 @@ TEST_F(AccessibleCaretManagerTester, Tes
   EXPECT_EQ(SecondCaretAppearance(), Appearance::Normal);
 
   mManager.OnScrollPositionChanged();
   EXPECT_EQ(FirstCaretAppearance(), Appearance::Normal);
   EXPECT_EQ(SecondCaretAppearance(), Appearance::Normal);
 }
 
 TEST_F(AccessibleCaretManagerTester, TestSingleTapOnNonEmptyInput)
+MOZ_CAN_RUN_SCRIPT
 {
   EXPECT_CALL(mManager, GetCaretMode())
     .WillRepeatedly(Return(CaretMode::Cursor));
 
   EXPECT_CALL(mManager, HasNonEmptyTextContent(_))
     .WillRepeatedly(Return(true));
 
   MockFunction<void(std::string aCheckPointName)> check;
@@ -232,16 +234,17 @@ TEST_F(AccessibleCaretManagerTester, Tes
   EXPECT_EQ(FirstCaretAppearance(), Appearance::Normal);
   check.Call("reflow2");
 
   mManager.OnScrollPositionChanged();
   EXPECT_EQ(FirstCaretAppearance(), Appearance::Normal);
 }
 
 TEST_F(AccessibleCaretManagerTester, TestSingleTapOnEmptyInput)
+MOZ_CAN_RUN_SCRIPT
 {
   EXPECT_CALL(mManager, GetCaretMode())
     .WillRepeatedly(Return(CaretMode::Cursor));
 
   EXPECT_CALL(mManager, HasNonEmptyTextContent(_))
     .WillRepeatedly(Return(false));
 
   MockFunction<void(std::string aCheckPointName)> check;
@@ -301,17 +304,17 @@ TEST_F(AccessibleCaretManagerTester, Tes
   mManager.OnReflow();
   EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown);
   check.Call("reflow2");
 
   mManager.OnScrollPositionChanged();
   EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown);
 }
 
-TEST_F(AccessibleCaretManagerTester, TestTypingAtEndOfInput)
+TEST_F(AccessibleCaretManagerTester, TestTypingAtEndOfInput) MOZ_CAN_RUN_SCRIPT
 {
   EXPECT_CALL(mManager, GetCaretMode())
     .WillRepeatedly(Return(CaretMode::Cursor));
 
   EXPECT_CALL(mManager, HasNonEmptyTextContent(_))
     .WillRepeatedly(Return(true));
 
   MockFunction<void(std::string aCheckPointName)> check;
@@ -344,16 +347,17 @@ TEST_F(AccessibleCaretManagerTester, Tes
                               nsISelectionListener::NO_REASON);
   EXPECT_EQ(FirstCaretAppearance(), Appearance::None);
 
   mManager.OnScrollPositionChanged();
   EXPECT_EQ(FirstCaretAppearance(), Appearance::None);
 }
 
 TEST_F(AccessibleCaretManagerTester, TestScrollInSelectionMode)
+MOZ_CAN_RUN_SCRIPT
 {
   // Simulate caret hiding when scrolling.
   AutoRestore<bool> savesCaretsAlwaysShowWhenScrolling(
     MockAccessibleCaretManager::sCaretsAlwaysShowWhenScrolling);
   MockAccessibleCaretManager::sCaretsAlwaysShowWhenScrolling = false;
 
   EXPECT_CALL(mManager, GetCaretMode())
     .WillRepeatedly(Return(CaretMode::Selection));
@@ -422,17 +426,19 @@ TEST_F(AccessibleCaretManagerTester, Tes
   EXPECT_EQ(SecondCaretAppearance(), Appearance::None);
 
   mManager.OnScrollEnd();
   EXPECT_EQ(FirstCaretAppearance(), Appearance::Normal);
   EXPECT_EQ(SecondCaretAppearance(), Appearance::Normal);
   check.Call("scrollend2");
 }
 
-TEST_F(AccessibleCaretManagerTester, TestScrollInSelectionModeWithAlwaysTiltPref)
+TEST_F(AccessibleCaretManagerTester,
+       TestScrollInSelectionModeWithAlwaysTiltPref)
+MOZ_CAN_RUN_SCRIPT
 {
   // Simulate Firefox Android preference.
   AutoRestore<bool> saveCaretsAlwaysTilt(
     MockAccessibleCaretManager::sCaretsAlwaysTilt);
   MockAccessibleCaretManager::sCaretsAlwaysTilt = true;
 
   EXPECT_CALL(mManager, GetCaretMode())
     .WillRepeatedly(Return(CaretMode::Selection));
@@ -528,16 +534,17 @@ TEST_F(AccessibleCaretManagerTester, Tes
 
   mManager.OnScrollEnd();
   EXPECT_EQ(FirstCaretAppearance(), Appearance::Left);
   EXPECT_EQ(SecondCaretAppearance(), Appearance::Right);
   check.Call("scrollend2");
 }
 
 TEST_F(AccessibleCaretManagerTester, TestScrollInCursorModeWhenLogicallyVisible)
+MOZ_CAN_RUN_SCRIPT
 {
   // Simulate caret hiding when scrolling.
   AutoRestore<bool> savesCaretsAlwaysShowWhenScrolling(
     MockAccessibleCaretManager::sCaretsAlwaysShowWhenScrolling);
   MockAccessibleCaretManager::sCaretsAlwaysShowWhenScrolling = false;
 
   EXPECT_CALL(mManager, GetCaretMode())
     .WillRepeatedly(Return(CaretMode::Cursor));
@@ -593,16 +600,17 @@ TEST_F(AccessibleCaretManagerTester, Tes
   check.Call("scrollstart2");
 
   mManager.OnScrollEnd();
   EXPECT_EQ(FirstCaretAppearance(), Appearance::Normal);
   check.Call("scrollend2");
 }
 
 TEST_F(AccessibleCaretManagerTester, TestScrollInCursorModeWhenHidden)
+MOZ_CAN_RUN_SCRIPT
 {
   // Simulate caret hiding when scrolling.
   AutoRestore<bool> savesCaretsAlwaysShowWhenScrolling(
     MockAccessibleCaretManager::sCaretsAlwaysShowWhenScrolling);
   MockAccessibleCaretManager::sCaretsAlwaysShowWhenScrolling = false;
 
   EXPECT_CALL(mManager, GetCaretMode())
     .WillRepeatedly(Return(CaretMode::Cursor));
@@ -652,16 +660,17 @@ TEST_F(AccessibleCaretManagerTester, Tes
   EXPECT_EQ(FirstCaretAppearance(), Appearance::None);
 
   mManager.OnScrollEnd();
   EXPECT_EQ(FirstCaretAppearance(), Appearance::None);
   check.Call("scrollend2");
 }
 
 TEST_F(AccessibleCaretManagerTester, TestScrollInCursorModeOnEmptyContent)
+MOZ_CAN_RUN_SCRIPT
 {
   // Simulate caret hiding when scrolling.
   AutoRestore<bool> savesCaretsAlwaysShowWhenScrolling(
     MockAccessibleCaretManager::sCaretsAlwaysShowWhenScrolling);
   MockAccessibleCaretManager::sCaretsAlwaysShowWhenScrolling = false;
 
   EXPECT_CALL(mManager, GetCaretMode())
     .WillRepeatedly(Return(CaretMode::Cursor));
@@ -728,16 +737,17 @@ TEST_F(AccessibleCaretManagerTester, Tes
   check.Call("scrollstart3");
   mManager.OnScrollEnd();
   EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown);
   check.Call("scrollend3");
 }
 
 TEST_F(AccessibleCaretManagerTester,
        TestScrollInCursorModeWithCaretShownWhenLongTappingOnEmptyContentPref)
+MOZ_CAN_RUN_SCRIPT
 {
   // Simulate Firefox Android preference.
   AutoRestore<bool> savesCaretShownWhenLongTappingOnEmptyContent(
     MockAccessibleCaretManager::sCaretShownWhenLongTappingOnEmptyContent);
   MockAccessibleCaretManager::sCaretShownWhenLongTappingOnEmptyContent = true;
 
   EXPECT_CALL(mManager, GetCaretMode())
     .WillRepeatedly(Return(CaretMode::Cursor));