LCOV - code coverage report
Current view: top level - layout/base - AccessibleCaretEventHub.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 370 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 92 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "AccessibleCaretEventHub.h"
       8             : 
       9             : #include "AccessibleCaretLogger.h"
      10             : #include "AccessibleCaretManager.h"
      11             : #include "Layers.h"
      12             : #include "gfxPrefs.h"
      13             : #include "mozilla/AutoRestore.h"
      14             : #include "mozilla/MouseEvents.h"
      15             : #include "mozilla/TextEvents.h"
      16             : #include "mozilla/TouchEvents.h"
      17             : #include "mozilla/Preferences.h"
      18             : #include "nsCanvasFrame.h"
      19             : #include "nsDocShell.h"
      20             : #include "nsFocusManager.h"
      21             : #include "nsFrameSelection.h"
      22             : #include "nsITimer.h"
      23             : #include "nsPresContext.h"
      24             : 
      25             : namespace mozilla {
      26             : 
      27             : #undef AC_LOG
      28             : #define AC_LOG(message, ...)                                                   \
      29             :   AC_LOG_BASE("AccessibleCaretEventHub (%p): " message, this, ##__VA_ARGS__);
      30             : 
      31             : #undef AC_LOGV
      32             : #define AC_LOGV(message, ...)                                                  \
      33             :   AC_LOGV_BASE("AccessibleCaretEventHub (%p): " message, this, ##__VA_ARGS__);
      34             : 
      35           0 : NS_IMPL_ISUPPORTS(AccessibleCaretEventHub, nsIReflowObserver, nsIScrollObserver,
      36             :                   nsISelectionListener, nsISupportsWeakReference);
      37             : 
      38             : // -----------------------------------------------------------------------------
      39             : // NoActionState
      40             : //
      41           0 : class AccessibleCaretEventHub::NoActionState
      42             :   : public AccessibleCaretEventHub::State
      43             : {
      44             : public:
      45           0 :   virtual const char* Name() const override { return "NoActionState"; }
      46             : 
      47           0 :   virtual nsEventStatus OnPress(AccessibleCaretEventHub* aContext,
      48             :                                 const nsPoint& aPoint, int32_t aTouchId,
      49             :                                 EventClassID aEventClass) override
      50             :   {
      51           0 :     nsEventStatus rv = nsEventStatus_eIgnore;
      52             : 
      53           0 :     if (NS_SUCCEEDED(aContext->mManager->PressCaret(aPoint, aEventClass))) {
      54           0 :       aContext->SetState(aContext->PressCaretState());
      55           0 :       rv = nsEventStatus_eConsumeNoDefault;
      56             :     } else {
      57           0 :       aContext->SetState(aContext->PressNoCaretState());
      58             :     }
      59             : 
      60           0 :     aContext->mPressPoint = aPoint;
      61           0 :     aContext->mActiveTouchId = aTouchId;
      62             : 
      63           0 :     return rv;
      64             :   }
      65             : 
      66           0 :   virtual void OnScrollStart(AccessibleCaretEventHub* aContext) override
      67             :   {
      68           0 :     aContext->mManager->OnScrollStart();
      69           0 :     aContext->SetState(aContext->ScrollState());
      70           0 :   }
      71             : 
      72           0 :   virtual void OnScrollPositionChanged(
      73             :     AccessibleCaretEventHub* aContext) override
      74             :   {
      75           0 :     aContext->mManager->OnScrollPositionChanged();
      76           0 :   }
      77             : 
      78           0 :   virtual void OnSelectionChanged(AccessibleCaretEventHub* aContext,
      79             :                                   nsIDOMDocument* aDoc, nsISelection* aSel,
      80             :                                   int16_t aReason) override
      81             :   {
      82           0 :     aContext->mManager->OnSelectionChanged(aDoc, aSel, aReason);
      83           0 :   }
      84             : 
      85           0 :   virtual void OnBlur(AccessibleCaretEventHub* aContext,
      86             :                       bool aIsLeavingDocument) override
      87             :   {
      88           0 :     aContext->mManager->OnBlur();
      89           0 :   }
      90             : 
      91           0 :   virtual void OnReflow(AccessibleCaretEventHub* aContext) override
      92             :   {
      93           0 :     aContext->mManager->OnReflow();
      94           0 :   }
      95             : 
      96           0 :   virtual void Enter(AccessibleCaretEventHub* aContext) override
      97             :   {
      98           0 :     aContext->mPressPoint = nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
      99           0 :     aContext->mActiveTouchId = kInvalidTouchId;
     100           0 :   }
     101             : };
     102             : 
     103             : // -----------------------------------------------------------------------------
     104             : // PressCaretState: Always consume the event since we've pressed on the caret.
     105             : //
     106           0 : class AccessibleCaretEventHub::PressCaretState
     107             :   : public AccessibleCaretEventHub::State
     108             : {
     109             : public:
     110           0 :   virtual const char* Name() const override { return "PressCaretState"; }
     111             : 
     112           0 :   virtual nsEventStatus OnMove(AccessibleCaretEventHub* aContext,
     113             :                                const nsPoint& aPoint) override
     114             :   {
     115           0 :     if (aContext->MoveDistanceIsLarge(aPoint)) {
     116           0 :       if (NS_SUCCEEDED(aContext->mManager->DragCaret(aPoint))) {
     117           0 :         aContext->SetState(aContext->DragCaretState());
     118             :       }
     119             :     }
     120             : 
     121           0 :     return nsEventStatus_eConsumeNoDefault;
     122             :   }
     123             : 
     124           0 :   virtual nsEventStatus OnRelease(AccessibleCaretEventHub* aContext) override
     125             :   {
     126           0 :     aContext->mManager->ReleaseCaret();
     127           0 :     aContext->mManager->TapCaret(aContext->mPressPoint);
     128           0 :     aContext->SetState(aContext->NoActionState());
     129             : 
     130           0 :     return nsEventStatus_eConsumeNoDefault;
     131             :   }
     132             : 
     133           0 :   virtual nsEventStatus OnLongTap(AccessibleCaretEventHub* aContext,
     134             :                                   const nsPoint& aPoint) override
     135             :   {
     136           0 :     return nsEventStatus_eConsumeNoDefault;
     137             :   }
     138             : };
     139             : 
     140             : // -----------------------------------------------------------------------------
     141             : // DragCaretState: Always consume the event since we've pressed on the caret.
     142             : //
     143           0 : class AccessibleCaretEventHub::DragCaretState
     144             :   : public AccessibleCaretEventHub::State
     145             : {
     146             : public:
     147           0 :   virtual const char* Name() const override { return "DragCaretState"; }
     148             : 
     149           0 :   virtual nsEventStatus OnMove(AccessibleCaretEventHub* aContext,
     150             :                                const nsPoint& aPoint) override
     151             :   {
     152           0 :     aContext->mManager->DragCaret(aPoint);
     153             : 
     154           0 :     return nsEventStatus_eConsumeNoDefault;
     155             :   }
     156             : 
     157           0 :   virtual nsEventStatus OnRelease(AccessibleCaretEventHub* aContext) override
     158             :   {
     159           0 :     aContext->mManager->ReleaseCaret();
     160           0 :     aContext->SetState(aContext->NoActionState());
     161             : 
     162           0 :     return nsEventStatus_eConsumeNoDefault;
     163             :   }
     164             : };
     165             : 
     166             : // -----------------------------------------------------------------------------
     167             : // PressNoCaretState
     168             : //
     169           0 : class AccessibleCaretEventHub::PressNoCaretState
     170             :   : public AccessibleCaretEventHub::State
     171             : {
     172             : public:
     173           0 :   virtual const char* Name() const override { return "PressNoCaretState"; }
     174             : 
     175           0 :   virtual nsEventStatus OnMove(AccessibleCaretEventHub* aContext,
     176             :                                const nsPoint& aPoint) override
     177             :   {
     178           0 :     if (aContext->MoveDistanceIsLarge(aPoint)) {
     179           0 :       aContext->SetState(aContext->NoActionState());
     180             :     }
     181             : 
     182           0 :     return nsEventStatus_eIgnore;
     183             :   }
     184             : 
     185           0 :   virtual nsEventStatus OnRelease(AccessibleCaretEventHub* aContext) override
     186             :   {
     187           0 :     aContext->SetState(aContext->NoActionState());
     188             : 
     189           0 :     return nsEventStatus_eIgnore;
     190             :   }
     191             : 
     192           0 :   virtual nsEventStatus OnLongTap(AccessibleCaretEventHub* aContext,
     193             :                                   const nsPoint& aPoint) override
     194             :   {
     195           0 :     aContext->SetState(aContext->LongTapState());
     196             : 
     197           0 :     return aContext->GetState()->OnLongTap(aContext, aPoint);
     198             :   }
     199             : 
     200           0 :   virtual void OnScrollStart(AccessibleCaretEventHub* aContext) override
     201             :   {
     202           0 :     aContext->mManager->OnScrollStart();
     203           0 :     aContext->SetState(aContext->ScrollState());
     204           0 :   }
     205             : 
     206           0 :   virtual void OnBlur(AccessibleCaretEventHub* aContext,
     207             :                       bool aIsLeavingDocument) override
     208             :   {
     209           0 :     aContext->mManager->OnBlur();
     210           0 :     if (aIsLeavingDocument) {
     211           0 :       aContext->SetState(aContext->NoActionState());
     212             :     }
     213           0 :   }
     214             : 
     215           0 :   virtual void OnSelectionChanged(AccessibleCaretEventHub* aContext,
     216             :                                   nsIDOMDocument* aDoc, nsISelection* aSel,
     217             :                                   int16_t aReason) override
     218             :   {
     219           0 :     aContext->mManager->OnSelectionChanged(aDoc, aSel, aReason);
     220           0 :   }
     221             : 
     222           0 :   virtual void OnReflow(AccessibleCaretEventHub* aContext) override
     223             :   {
     224           0 :     aContext->mManager->OnReflow();
     225           0 :   }
     226             : 
     227           0 :   virtual void Enter(AccessibleCaretEventHub* aContext) override
     228             :   {
     229           0 :     aContext->LaunchLongTapInjector();
     230           0 :   }
     231             : 
     232           0 :   virtual void Leave(AccessibleCaretEventHub* aContext) override
     233             :   {
     234           0 :     aContext->CancelLongTapInjector();
     235           0 :   }
     236             : };
     237             : 
     238             : // -----------------------------------------------------------------------------
     239             : // ScrollState
     240             : //
     241           0 : class AccessibleCaretEventHub::ScrollState
     242             :   : public AccessibleCaretEventHub::State
     243             : {
     244             : public:
     245           0 :   virtual const char* Name() const override { return "ScrollState"; }
     246             : 
     247           0 :   virtual void OnScrollEnd(AccessibleCaretEventHub* aContext) override
     248             :   {
     249           0 :     aContext->SetState(aContext->PostScrollState());
     250           0 :   }
     251             : 
     252           0 :   virtual void OnScrollPositionChanged(
     253             :     AccessibleCaretEventHub* aContext) override
     254             :   {
     255           0 :     aContext->mManager->OnScrollPositionChanged();
     256           0 :   }
     257             : 
     258           0 :   virtual void OnBlur(AccessibleCaretEventHub* aContext,
     259             :                       bool aIsLeavingDocument) override
     260             :   {
     261           0 :     aContext->mManager->OnBlur();
     262           0 :     if (aIsLeavingDocument) {
     263           0 :       aContext->SetState(aContext->NoActionState());
     264             :     }
     265           0 :   }
     266             : };
     267             : 
     268             : // -----------------------------------------------------------------------------
     269             : // PostScrollState: In this state, we are waiting for another APZ start or press
     270             : // event.
     271             : //
     272           0 : class AccessibleCaretEventHub::PostScrollState
     273             :   : public AccessibleCaretEventHub::State
     274             : {
     275             : public:
     276           0 :   virtual const char* Name() const override { return "PostScrollState"; }
     277             : 
     278           0 :   virtual nsEventStatus OnPress(AccessibleCaretEventHub* aContext,
     279             :                                 const nsPoint& aPoint, int32_t aTouchId,
     280             :                                 EventClassID aEventClass) override
     281             :   {
     282           0 :     aContext->mManager->OnScrollEnd();
     283           0 :     aContext->SetState(aContext->NoActionState());
     284             : 
     285           0 :     return aContext->GetState()->OnPress(aContext, aPoint, aTouchId,
     286           0 :                                          aEventClass);
     287             :   }
     288             : 
     289           0 :   virtual void OnScrollStart(AccessibleCaretEventHub* aContext) override
     290             :   {
     291           0 :     aContext->SetState(aContext->ScrollState());
     292           0 :   }
     293             : 
     294           0 :   virtual void OnScrollEnd(AccessibleCaretEventHub* aContext) override
     295             :   {
     296           0 :     aContext->mManager->OnScrollEnd();
     297           0 :     aContext->SetState(aContext->NoActionState());
     298           0 :   }
     299             : 
     300           0 :   virtual void OnBlur(AccessibleCaretEventHub* aContext,
     301             :                       bool aIsLeavingDocument) override
     302             :   {
     303           0 :     aContext->mManager->OnBlur();
     304           0 :     if (aIsLeavingDocument) {
     305           0 :       aContext->SetState(aContext->NoActionState());
     306             :     }
     307           0 :   }
     308             : 
     309           0 :   virtual void Enter(AccessibleCaretEventHub* aContext) override
     310             :   {
     311             :     // Launch the injector to leave PostScrollState.
     312           0 :     aContext->LaunchScrollEndInjector();
     313           0 :   }
     314             : 
     315           0 :   virtual void Leave(AccessibleCaretEventHub* aContext) override
     316             :   {
     317           0 :     aContext->CancelScrollEndInjector();
     318           0 :   }
     319             : };
     320             : 
     321             : // -----------------------------------------------------------------------------
     322             : // LongTapState
     323             : //
     324           0 : class AccessibleCaretEventHub::LongTapState
     325             :   : public AccessibleCaretEventHub::State
     326             : {
     327             : public:
     328           0 :   virtual const char* Name() const override { return "LongTapState"; }
     329             : 
     330           0 :   virtual nsEventStatus OnLongTap(AccessibleCaretEventHub* aContext,
     331             :                                   const nsPoint& aPoint) override
     332             :   {
     333             :     // In general text selection is lower-priority than the context menu. If
     334             :     // we consume this long-press event, then it prevents the context menu from
     335             :     // showing up on desktop Firefox (because that happens on long-tap-up, if
     336             :     // the long-tap was not cancelled). So we return eIgnore instead.
     337           0 :     aContext->mManager->SelectWordOrShortcut(aPoint);
     338           0 :     return nsEventStatus_eIgnore;
     339             :   }
     340             : 
     341           0 :   virtual nsEventStatus OnRelease(AccessibleCaretEventHub* aContext) override
     342             :   {
     343           0 :     aContext->SetState(aContext->NoActionState());
     344             : 
     345             :     // Do not consume the release since the press is not consumed in
     346             :     // PressNoCaretState either.
     347           0 :     return nsEventStatus_eIgnore;
     348             :   }
     349             : 
     350           0 :   virtual void OnScrollStart(AccessibleCaretEventHub* aContext) override
     351             :   {
     352           0 :     aContext->mManager->OnScrollStart();
     353           0 :     aContext->SetState(aContext->ScrollState());
     354           0 :   }
     355             : 
     356           0 :   virtual void OnReflow(AccessibleCaretEventHub* aContext) override
     357             :   {
     358           0 :     aContext->mManager->OnReflow();
     359           0 :   }
     360             : };
     361             : 
     362             : // -----------------------------------------------------------------------------
     363             : // Implementation of AccessibleCaretEventHub methods
     364             : //
     365             : AccessibleCaretEventHub::State*
     366           0 : AccessibleCaretEventHub::GetState() const
     367             : {
     368           0 :   return mState;
     369             : }
     370             : 
     371             : void
     372           0 : AccessibleCaretEventHub::SetState(State* aState)
     373             : {
     374           0 :   MOZ_ASSERT(aState);
     375             : 
     376           0 :   AC_LOG("%s -> %s", mState->Name(), aState->Name());
     377             : 
     378           0 :   mState->Leave(this);
     379           0 :   mState = aState;
     380           0 :   mState->Enter(this);
     381           0 : }
     382             : 
     383           0 : MOZ_IMPL_STATE_CLASS_GETTER(NoActionState)
     384           0 : MOZ_IMPL_STATE_CLASS_GETTER(PressCaretState)
     385           0 : MOZ_IMPL_STATE_CLASS_GETTER(DragCaretState)
     386           0 : MOZ_IMPL_STATE_CLASS_GETTER(PressNoCaretState)
     387           0 : MOZ_IMPL_STATE_CLASS_GETTER(ScrollState)
     388           0 : MOZ_IMPL_STATE_CLASS_GETTER(PostScrollState)
     389           0 : MOZ_IMPL_STATE_CLASS_GETTER(LongTapState)
     390             : 
     391             : bool AccessibleCaretEventHub::sUseLongTapInjector = false;
     392             : 
     393           0 : AccessibleCaretEventHub::AccessibleCaretEventHub(nsIPresShell* aPresShell)
     394           0 :   : mPresShell(aPresShell)
     395             : {
     396             :   static bool prefsAdded = false;
     397           0 :   if (!prefsAdded) {
     398             :     Preferences::AddBoolVarCache(
     399           0 :       &sUseLongTapInjector, "layout.accessiblecaret.use_long_tap_injector");
     400           0 :     prefsAdded = true;
     401             :   }
     402           0 : }
     403             : 
     404           0 : AccessibleCaretEventHub::~AccessibleCaretEventHub()
     405             : {
     406           0 : }
     407             : 
     408             : void
     409           0 : AccessibleCaretEventHub::Init()
     410             : {
     411           0 :   if (mInitialized && mManager) {
     412           0 :     mManager->OnFrameReconstruction();
     413             :   }
     414             : 
     415           0 :   if (mInitialized || !mPresShell || !mPresShell->GetCanvasFrame() ||
     416           0 :       !mPresShell->GetCanvasFrame()->GetCustomContentContainer()) {
     417           0 :     return;
     418             :   }
     419             : 
     420             :   // Without nsAutoScriptBlocker, the script might be run after constructing
     421             :   // mFirstCaret in AccessibleCaretManager's constructor, which might destructs
     422             :   // the whole frame tree. Therefore we'll fail to construct mSecondCaret
     423             :   // because we cannot get root frame or canvas frame from mPresShell to inject
     424             :   // anonymous content. To avoid that, we protect Init() by nsAutoScriptBlocker.
     425             :   // To reproduce, run "./mach crashtest layout/base/crashtests/897852.html"
     426             :   // without the following scriptBlocker.
     427           0 :   nsAutoScriptBlocker scriptBlocker;
     428             : 
     429           0 :   nsPresContext* presContext = mPresShell->GetPresContext();
     430           0 :   MOZ_ASSERT(presContext, "PresContext should be given in PresShell::Init()");
     431             : 
     432           0 :   nsIDocShell* docShell = presContext->GetDocShell();
     433           0 :   if (!docShell) {
     434           0 :     return;
     435             :   }
     436             : 
     437           0 :   docShell->AddWeakReflowObserver(this);
     438           0 :   docShell->AddWeakScrollObserver(this);
     439             : 
     440           0 :   mDocShell = static_cast<nsDocShell*>(docShell);
     441             : 
     442           0 :   if (sUseLongTapInjector) {
     443           0 :     mLongTapInjectorTimer = do_CreateInstance("@mozilla.org/timer;1");
     444             :   }
     445             : 
     446           0 :   mScrollEndInjectorTimer = do_CreateInstance("@mozilla.org/timer;1");
     447             : 
     448           0 :   mManager = MakeUnique<AccessibleCaretManager>(mPresShell);
     449             : 
     450           0 :   mInitialized = true;
     451             : }
     452             : 
     453             : void
     454           0 : AccessibleCaretEventHub::Terminate()
     455             : {
     456           0 :   if (!mInitialized) {
     457           0 :     return;
     458             :   }
     459             : 
     460           0 :   RefPtr<nsDocShell> docShell(mDocShell.get());
     461           0 :   if (docShell) {
     462           0 :     docShell->RemoveWeakReflowObserver(this);
     463           0 :     docShell->RemoveWeakScrollObserver(this);
     464             :   }
     465             : 
     466           0 :   if (mLongTapInjectorTimer) {
     467           0 :     mLongTapInjectorTimer->Cancel();
     468             :   }
     469             : 
     470           0 :   if (mScrollEndInjectorTimer) {
     471           0 :     mScrollEndInjectorTimer->Cancel();
     472             :   }
     473             : 
     474           0 :   mManager->Terminate();
     475           0 :   mPresShell = nullptr;
     476           0 :   mInitialized = false;
     477             : }
     478             : 
     479             : nsEventStatus
     480           0 : AccessibleCaretEventHub::HandleEvent(WidgetEvent* aEvent)
     481             : {
     482           0 :   nsEventStatus status = nsEventStatus_eIgnore;
     483             : 
     484           0 :   if (!mInitialized) {
     485           0 :     return status;
     486             :   }
     487             : 
     488           0 :   MOZ_ASSERT(mRefCnt.get() > 1, "Expect caller holds us as well!");
     489             : 
     490           0 :   switch (aEvent->mClass) {
     491             :     case eMouseEventClass:
     492           0 :       status = HandleMouseEvent(aEvent->AsMouseEvent());
     493           0 :       break;
     494             : 
     495             :     case eTouchEventClass:
     496           0 :       status = HandleTouchEvent(aEvent->AsTouchEvent());
     497           0 :       break;
     498             : 
     499             :     case eKeyboardEventClass:
     500           0 :       status = HandleKeyboardEvent(aEvent->AsKeyboardEvent());
     501           0 :       break;
     502             : 
     503             :     default:
     504           0 :       break;
     505             :   }
     506             : 
     507           0 :   return status;
     508             : }
     509             : 
     510             : nsEventStatus
     511           0 : AccessibleCaretEventHub::HandleMouseEvent(WidgetMouseEvent* aEvent)
     512             : {
     513           0 :   nsEventStatus rv = nsEventStatus_eIgnore;
     514             : 
     515           0 :   if (aEvent->button != WidgetMouseEvent::eLeftButton) {
     516           0 :     return rv;
     517             :   }
     518             : 
     519             :   int32_t id =
     520           0 :     (mActiveTouchId == kInvalidTouchId ? kDefaultTouchId : mActiveTouchId);
     521           0 :   nsPoint point = GetMouseEventPosition(aEvent);
     522             : 
     523           0 :   if (aEvent->mMessage == eMouseDown ||
     524           0 :       aEvent->mMessage == eMouseUp ||
     525           0 :       aEvent->mMessage == eMouseClick ||
     526           0 :       aEvent->mMessage == eMouseDoubleClick ||
     527           0 :       aEvent->mMessage == eMouseLongTap) {
     528             :     // Don't reset the source on mouse movement since that can
     529             :     // happen anytime, even randomly during a touch sequence.
     530           0 :     mManager->SetLastInputSource(aEvent->inputSource);
     531             :   }
     532             : 
     533           0 :   switch (aEvent->mMessage) {
     534             :     case eMouseDown:
     535           0 :       AC_LOGV("Before eMouseDown, state: %s", mState->Name());
     536           0 :       rv = mState->OnPress(this, point, id, eMouseEventClass);
     537           0 :       AC_LOGV("After eMouseDown, state: %s, consume: %d", mState->Name(), rv);
     538           0 :       break;
     539             : 
     540             :     case eMouseMove:
     541           0 :       AC_LOGV("Before eMouseMove, state: %s", mState->Name());
     542           0 :       rv = mState->OnMove(this, point);
     543           0 :       AC_LOGV("After eMouseMove, state: %s, consume: %d", mState->Name(), rv);
     544           0 :       break;
     545             : 
     546             :     case eMouseUp:
     547           0 :       AC_LOGV("Before eMouseUp, state: %s", mState->Name());
     548           0 :       rv = mState->OnRelease(this);
     549           0 :       AC_LOGV("After eMouseUp, state: %s, consume: %d", mState->Name(), rv);
     550           0 :       break;
     551             : 
     552             :     case eMouseLongTap:
     553           0 :       AC_LOGV("Before eMouseLongTap, state: %s", mState->Name());
     554           0 :       rv = mState->OnLongTap(this, point);
     555           0 :       AC_LOGV("After eMouseLongTap, state: %s, consume: %d", mState->Name(),
     556             :               rv);
     557           0 :       break;
     558             : 
     559             :     default:
     560           0 :       break;
     561             :   }
     562             : 
     563           0 :   return rv;
     564             : }
     565             : 
     566             : nsEventStatus
     567           0 : AccessibleCaretEventHub::HandleTouchEvent(WidgetTouchEvent* aEvent)
     568             : {
     569           0 :   if (aEvent->mTouches.IsEmpty()) {
     570           0 :     AC_LOG("%s: Receive a touch event without any touch data!", __FUNCTION__);
     571           0 :     return nsEventStatus_eIgnore;
     572             :   }
     573             : 
     574           0 :   nsEventStatus rv = nsEventStatus_eIgnore;
     575             : 
     576             :   int32_t id =
     577           0 :     (mActiveTouchId == kInvalidTouchId ? aEvent->mTouches[0]->Identifier()
     578           0 :                                        : mActiveTouchId);
     579           0 :   nsPoint point = GetTouchEventPosition(aEvent, id);
     580             : 
     581           0 :   mManager->SetLastInputSource(nsIDOMMouseEvent::MOZ_SOURCE_TOUCH);
     582             : 
     583           0 :   switch (aEvent->mMessage) {
     584             :     case eTouchStart:
     585           0 :       AC_LOGV("Before eTouchStart, state: %s", mState->Name());
     586           0 :       rv = mState->OnPress(this, point, id, eTouchEventClass);
     587           0 :       AC_LOGV("After eTouchStart, state: %s, consume: %d", mState->Name(), rv);
     588           0 :       break;
     589             : 
     590             :     case eTouchMove:
     591           0 :       AC_LOGV("Before eTouchMove, state: %s", mState->Name());
     592           0 :       rv = mState->OnMove(this, point);
     593           0 :       AC_LOGV("After eTouchMove, state: %s, consume: %d", mState->Name(), rv);
     594           0 :       break;
     595             : 
     596             :     case eTouchEnd:
     597           0 :       AC_LOGV("Before eTouchEnd, state: %s", mState->Name());
     598           0 :       rv = mState->OnRelease(this);
     599           0 :       AC_LOGV("After eTouchEnd, state: %s, consume: %d", mState->Name(), rv);
     600           0 :       break;
     601             : 
     602             :     case eTouchCancel:
     603           0 :       AC_LOGV("Got eTouchCancel, state: %s", mState->Name());
     604             :       // Do nothing since we don't really care eTouchCancel anyway.
     605           0 :       break;
     606             : 
     607             :     default:
     608           0 :       break;
     609             :   }
     610             : 
     611           0 :   return rv;
     612             : }
     613             : 
     614             : nsEventStatus
     615           0 : AccessibleCaretEventHub::HandleKeyboardEvent(WidgetKeyboardEvent* aEvent)
     616             : {
     617           0 :   mManager->SetLastInputSource(nsIDOMMouseEvent::MOZ_SOURCE_KEYBOARD);
     618             : 
     619           0 :   switch (aEvent->mMessage) {
     620             :     case eKeyUp:
     621           0 :       AC_LOGV("eKeyUp, state: %s", mState->Name());
     622           0 :       mManager->OnKeyboardEvent();
     623           0 :       break;
     624             : 
     625             :     case eKeyDown:
     626           0 :       AC_LOGV("eKeyDown, state: %s", mState->Name());
     627           0 :       mManager->OnKeyboardEvent();
     628           0 :       break;
     629             : 
     630             :     case eKeyPress:
     631           0 :       AC_LOGV("eKeyPress, state: %s", mState->Name());
     632           0 :       mManager->OnKeyboardEvent();
     633           0 :       break;
     634             : 
     635             :     default:
     636           0 :       break;
     637             :   }
     638             : 
     639           0 :   return nsEventStatus_eIgnore;
     640             : }
     641             : 
     642             : bool
     643           0 : AccessibleCaretEventHub::MoveDistanceIsLarge(const nsPoint& aPoint) const
     644             : {
     645           0 :   nsPoint delta = aPoint - mPressPoint;
     646           0 :   return NS_hypot(delta.x, delta.y) >
     647           0 :          nsPresContext::AppUnitsPerCSSPixel() * kMoveStartToleranceInPixel;
     648             : }
     649             : 
     650             : void
     651           0 : AccessibleCaretEventHub::LaunchLongTapInjector()
     652             : {
     653           0 :   if (!mLongTapInjectorTimer) {
     654           0 :     return;
     655             :   }
     656             : 
     657           0 :   int32_t longTapDelay = gfxPrefs::UiClickHoldContextMenusDelay();
     658           0 :   mLongTapInjectorTimer->InitWithNamedFuncCallback(
     659             :     FireLongTap,
     660             :     this,
     661             :     longTapDelay,
     662             :     nsITimer::TYPE_ONE_SHOT,
     663           0 :     "AccessibleCaretEventHub::LaunchLongTapInjector");
     664             : }
     665             : 
     666             : void
     667           0 : AccessibleCaretEventHub::CancelLongTapInjector()
     668             : {
     669           0 :   if (!mLongTapInjectorTimer) {
     670           0 :     return;
     671             :   }
     672             : 
     673           0 :   mLongTapInjectorTimer->Cancel();
     674             : }
     675             : 
     676             : /* static */ void
     677           0 : AccessibleCaretEventHub::FireLongTap(nsITimer* aTimer,
     678             :                                      void* aAccessibleCaretEventHub)
     679             : {
     680           0 :   auto* self = static_cast<AccessibleCaretEventHub*>(aAccessibleCaretEventHub);
     681           0 :   self->mState->OnLongTap(self, self->mPressPoint);
     682           0 : }
     683             : 
     684             : NS_IMETHODIMP
     685           0 : AccessibleCaretEventHub::Reflow(DOMHighResTimeStamp aStart,
     686             :                                 DOMHighResTimeStamp aEnd)
     687             : {
     688           0 :   if (!mInitialized) {
     689           0 :     return NS_OK;
     690             :   }
     691             : 
     692           0 :   MOZ_ASSERT(mRefCnt.get() > 1, "Expect caller holds us as well!");
     693             : 
     694           0 :   if (mIsInReflowCallback) {
     695           0 :     return NS_OK;
     696             :   }
     697             : 
     698           0 :   AutoRestore<bool> autoRestoreIsInReflowCallback(mIsInReflowCallback);
     699           0 :   mIsInReflowCallback = true;
     700             : 
     701           0 :   AC_LOG("%s, state: %s", __FUNCTION__, mState->Name());
     702           0 :   mState->OnReflow(this);
     703           0 :   return NS_OK;
     704             : }
     705             : 
     706             : NS_IMETHODIMP
     707           0 : AccessibleCaretEventHub::ReflowInterruptible(DOMHighResTimeStamp aStart,
     708             :                                              DOMHighResTimeStamp aEnd)
     709             : {
     710             :   // Defer the error checking to Reflow().
     711           0 :   return Reflow(aStart, aEnd);
     712             : }
     713             : 
     714             : void
     715           0 : AccessibleCaretEventHub::AsyncPanZoomStarted()
     716             : {
     717           0 :   if (!mInitialized) {
     718           0 :     return;
     719             :   }
     720             : 
     721           0 :   MOZ_ASSERT(mRefCnt.get() > 1, "Expect caller holds us as well!");
     722             : 
     723           0 :   AC_LOG("%s, state: %s", __FUNCTION__, mState->Name());
     724           0 :   mState->OnScrollStart(this);
     725             : }
     726             : 
     727             : void
     728           0 : AccessibleCaretEventHub::AsyncPanZoomStopped()
     729             : {
     730           0 :   if (!mInitialized) {
     731           0 :     return;
     732             :   }
     733             : 
     734           0 :   MOZ_ASSERT(mRefCnt.get() > 1, "Expect caller holds us as well!");
     735             : 
     736           0 :   AC_LOG("%s, state: %s", __FUNCTION__, mState->Name());
     737           0 :   mState->OnScrollEnd(this);
     738             : }
     739             : 
     740             : void
     741           0 : AccessibleCaretEventHub::ScrollPositionChanged()
     742             : {
     743           0 :   if (!mInitialized) {
     744           0 :     return;
     745             :   }
     746             : 
     747           0 :   MOZ_ASSERT(mRefCnt.get() > 1, "Expect caller holds us as well!");
     748             : 
     749           0 :   AC_LOG("%s, state: %s", __FUNCTION__, mState->Name());
     750           0 :   mState->OnScrollPositionChanged(this);
     751             : }
     752             : 
     753             : void
     754           0 : AccessibleCaretEventHub::LaunchScrollEndInjector()
     755             : {
     756           0 :   if (!mScrollEndInjectorTimer) {
     757           0 :     return;
     758             :   }
     759             : 
     760           0 :   mScrollEndInjectorTimer->InitWithNamedFuncCallback(
     761             :     FireScrollEnd,
     762             :     this,
     763             :     kScrollEndTimerDelay,
     764             :     nsITimer::TYPE_ONE_SHOT,
     765           0 :     "AccessibleCaretEventHub::LaunchScrollEndInjector");
     766             : }
     767             : 
     768             : void
     769           0 : AccessibleCaretEventHub::CancelScrollEndInjector()
     770             : {
     771           0 :   if (!mScrollEndInjectorTimer) {
     772           0 :     return;
     773             :   }
     774             : 
     775           0 :   mScrollEndInjectorTimer->Cancel();
     776             : }
     777             : 
     778             : /* static */ void
     779           0 : AccessibleCaretEventHub::FireScrollEnd(nsITimer* aTimer,
     780             :                                        void* aAccessibleCaretEventHub)
     781             : {
     782           0 :   auto* self = static_cast<AccessibleCaretEventHub*>(aAccessibleCaretEventHub);
     783           0 :   self->mState->OnScrollEnd(self);
     784           0 : }
     785             : 
     786             : nsresult
     787           0 : AccessibleCaretEventHub::NotifySelectionChanged(nsIDOMDocument* aDoc,
     788             :                                                 nsISelection* aSel,
     789             :                                                 int16_t aReason)
     790             : {
     791           0 :   if (!mInitialized) {
     792           0 :     return NS_OK;
     793             :   }
     794             : 
     795           0 :   MOZ_ASSERT(mRefCnt.get() > 1, "Expect caller holds us as well!");
     796             : 
     797           0 :   AC_LOG("%s, state: %s, reason: %d", __FUNCTION__, mState->Name(), aReason);
     798           0 :   mState->OnSelectionChanged(this, aDoc, aSel, aReason);
     799           0 :   return NS_OK;
     800             : }
     801             : 
     802             : void
     803           0 : AccessibleCaretEventHub::NotifyBlur(bool aIsLeavingDocument)
     804             : {
     805           0 :   if (!mInitialized) {
     806           0 :     return;
     807             :   }
     808             : 
     809           0 :   MOZ_ASSERT(mRefCnt.get() > 1, "Expect caller holds us as well!");
     810             : 
     811           0 :   AC_LOG("%s, state: %s", __FUNCTION__, mState->Name());
     812           0 :   mState->OnBlur(this, aIsLeavingDocument);
     813             : }
     814             : 
     815             : nsPoint
     816           0 : AccessibleCaretEventHub::GetTouchEventPosition(WidgetTouchEvent* aEvent,
     817             :                                                int32_t aIdentifier) const
     818             : {
     819           0 :   for (dom::Touch* touch : aEvent->mTouches) {
     820           0 :     if (touch->Identifier() == aIdentifier) {
     821           0 :       LayoutDeviceIntPoint touchIntPoint = touch->mRefPoint;
     822             : 
     823             :       // Get event coordinate relative to root frame.
     824           0 :       nsIFrame* rootFrame = mPresShell->GetRootFrame();
     825             :       return nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, touchIntPoint,
     826           0 :                                                           rootFrame);
     827             :     }
     828             :   }
     829           0 :   return nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
     830             : }
     831             : 
     832             : nsPoint
     833           0 : AccessibleCaretEventHub::GetMouseEventPosition(WidgetMouseEvent* aEvent) const
     834             : {
     835           0 :   LayoutDeviceIntPoint mouseIntPoint = aEvent->AsGUIEvent()->mRefPoint;
     836             : 
     837             :   // Get event coordinate relative to root frame.
     838           0 :   nsIFrame* rootFrame = mPresShell->GetRootFrame();
     839             :   return nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, mouseIntPoint,
     840           0 :                                                       rootFrame);
     841             : }
     842             : 
     843             : } // namespace mozilla

Generated by: LCOV version 1.13