LCOV - code coverage report
Current view: top level - layout/base - AccessibleCaretEventHub.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 21 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 15 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             : #ifndef AccessibleCaretEventHub_h
       8             : #define AccessibleCaretEventHub_h
       9             : 
      10             : #include "mozilla/EventForwards.h"
      11             : #include "mozilla/UniquePtr.h"
      12             : #include "mozilla/WeakPtr.h"
      13             : #include "nsCOMPtr.h"
      14             : #include "nsIFrame.h"
      15             : #include "nsIReflowObserver.h"
      16             : #include "nsIScrollObserver.h"
      17             : #include "nsISelectionListener.h"
      18             : #include "nsPoint.h"
      19             : #include "mozilla/RefPtr.h"
      20             : #include "nsWeakReference.h"
      21             : 
      22             : class nsDocShell;
      23             : class nsIPresShell;
      24             : class nsITimer;
      25             : 
      26             : namespace mozilla {
      27             : class AccessibleCaretManager;
      28             : class WidgetKeyboardEvent;
      29             : class WidgetMouseEvent;
      30             : class WidgetTouchEvent;
      31             : 
      32             : // -----------------------------------------------------------------------------
      33             : // Each PresShell holds a shared pointer to an AccessibleCaretEventHub; each
      34             : // AccessibleCaretEventHub holds a unique pointer to an AccessibleCaretManager.
      35             : // Thus, there's one AccessibleCaretManager per PresShell.
      36             : //
      37             : // AccessibleCaretEventHub implements a state pattern. It receives events from
      38             : // PresShell and callbacks by observers and listeners, and then relays them to
      39             : // the current concrete state which calls necessary event-handling methods in
      40             : // AccessibleCaretManager.
      41             : //
      42             : // We separate AccessibleCaretEventHub from AccessibleCaretManager to make the
      43             : // state transitions in AccessibleCaretEventHub testable. We put (nearly) all
      44             : // the operations involving PresShell, Selection, and AccessibleCaret
      45             : // manipulation in AccessibleCaretManager so that we can mock methods in
      46             : // AccessibleCaretManager in gtest. We test the correctness of the state
      47             : // transitions by giving events, callbacks, and the return values by mocked
      48             : // methods of AccessibleCaretEventHub. See TestAccessibleCaretEventHub.cpp.
      49             : //
      50             : // Besides dealing with real events, AccessibleCaretEventHub could also
      51             : // synthesize fake long-tap events and inject those events to itself on the
      52             : // platform lacks eMouseLongTap. Turn on this preference
      53             : // "layout.accessiblecaret.use_long_tap_injector" for the fake long-tap events.
      54             : //
      55             : // State transition diagram:
      56             : // https://hg.mozilla.org/mozilla-central/raw-file/default/layout/base/doc/AccessibleCaretEventHubStates.png
      57             : // Source code of the diagram:
      58             : // https://hg.mozilla.org/mozilla-central/file/default/layout/base/doc/AccessibleCaretEventHubStates.dot
      59             : //
      60             : // Please see the wiki page for more information.
      61             : // https://wiki.mozilla.org/AccessibleCaret
      62             : //
      63             : class AccessibleCaretEventHub : public nsIReflowObserver,
      64             :                                 public nsIScrollObserver,
      65             :                                 public nsISelectionListener,
      66             :                                 public nsSupportsWeakReference
      67             : {
      68             : public:
      69             :   explicit AccessibleCaretEventHub(nsIPresShell* aPresShell);
      70             :   void Init();
      71             :   void Terminate();
      72             : 
      73             :   nsEventStatus HandleEvent(WidgetEvent* aEvent);
      74             : 
      75             :   // Call this function to notify the blur event happened.
      76             :   void NotifyBlur(bool aIsLeavingDocument);
      77             : 
      78             :   NS_DECL_ISUPPORTS
      79             :   NS_DECL_NSIREFLOWOBSERVER
      80             :   NS_DECL_NSISELECTIONLISTENER
      81             : 
      82             :   // Override nsIScrollObserver methods.
      83             :   virtual void ScrollPositionChanged() override;
      84             :   virtual void AsyncPanZoomStarted() override;
      85             :   virtual void AsyncPanZoomStopped() override;
      86             : 
      87             :   // Base state
      88             :   class State;
      89             :   State* GetState() const;
      90             : 
      91             : protected:
      92             :   virtual ~AccessibleCaretEventHub();
      93             : 
      94             : #define MOZ_DECL_STATE_CLASS_GETTER(aClassName)                                \
      95             :   class aClassName;                                                            \
      96             :   static State* aClassName();
      97             : 
      98             : #define MOZ_IMPL_STATE_CLASS_GETTER(aClassName)                                \
      99             :   AccessibleCaretEventHub::State* AccessibleCaretEventHub::aClassName()        \
     100             :   {                                                                            \
     101             :     static class aClassName singleton;                                         \
     102             :     return &singleton;                                                         \
     103             :   }
     104             : 
     105             :   // Concrete state getters
     106             :   MOZ_DECL_STATE_CLASS_GETTER(NoActionState)
     107             :   MOZ_DECL_STATE_CLASS_GETTER(PressCaretState)
     108             :   MOZ_DECL_STATE_CLASS_GETTER(DragCaretState)
     109             :   MOZ_DECL_STATE_CLASS_GETTER(PressNoCaretState)
     110             :   MOZ_DECL_STATE_CLASS_GETTER(ScrollState)
     111             :   MOZ_DECL_STATE_CLASS_GETTER(PostScrollState)
     112             :   MOZ_DECL_STATE_CLASS_GETTER(LongTapState)
     113             : 
     114             :   void SetState(State* aState);
     115             : 
     116             :   nsEventStatus HandleMouseEvent(WidgetMouseEvent* aEvent);
     117             :   nsEventStatus HandleTouchEvent(WidgetTouchEvent* aEvent);
     118             :   nsEventStatus HandleKeyboardEvent(WidgetKeyboardEvent* aEvent);
     119             : 
     120             :   virtual nsPoint GetTouchEventPosition(WidgetTouchEvent* aEvent,
     121             :                                         int32_t aIdentifier) const;
     122             :   virtual nsPoint GetMouseEventPosition(WidgetMouseEvent* aEvent) const;
     123             : 
     124             :   bool MoveDistanceIsLarge(const nsPoint& aPoint) const;
     125             : 
     126             :   void LaunchLongTapInjector();
     127             :   void CancelLongTapInjector();
     128             :   static void FireLongTap(nsITimer* aTimer, void* aAccessibleCaretEventHub);
     129             : 
     130             :   void LaunchScrollEndInjector();
     131             :   void CancelScrollEndInjector();
     132             :   static void FireScrollEnd(nsITimer* aTimer, void* aAccessibleCaretEventHub);
     133             : 
     134             :   // Member variables
     135           0 :   State* mState = NoActionState();
     136             : 
     137             :   // Will be set to nullptr in Terminate().
     138             :   nsIPresShell* MOZ_NON_OWNING_REF mPresShell = nullptr;
     139             : 
     140             :   UniquePtr<AccessibleCaretManager> mManager;
     141             : 
     142             :   WeakPtr<nsDocShell> mDocShell;
     143             : 
     144             :   // Use this timer for injecting a long tap event when APZ is disabled. If APZ
     145             :   // is enabled, it will send long tap event to us.
     146             :   nsCOMPtr<nsITimer> mLongTapInjectorTimer;
     147             : 
     148             :   // Use this timer for injecting a simulated scroll end.
     149             :   nsCOMPtr<nsITimer> mScrollEndInjectorTimer;
     150             : 
     151             :   // Last mouse button down event or touch start event point.
     152             :   nsPoint mPressPoint{ NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE };
     153             : 
     154             :   // For filter multitouch event
     155             :   int32_t mActiveTouchId = kInvalidTouchId;
     156             : 
     157             :   // Flag to indicate the class has been initialized.
     158             :   bool mInitialized = false;
     159             : 
     160             :   // Flag to avoid calling Reflow() callback recursively.
     161             :   bool mIsInReflowCallback = false;
     162             : 
     163             :   // Simulate long tap if the platform does not support eMouseLongTap events.
     164             :   static bool sUseLongTapInjector;
     165             : 
     166             :   static const int32_t kScrollEndTimerDelay = 300;
     167             :   static const int32_t kMoveStartToleranceInPixel = 5;
     168             :   static const int32_t kInvalidTouchId = -1;
     169             :   static const int32_t kDefaultTouchId = 0; // For mouse event
     170             : };
     171             : 
     172             : // -----------------------------------------------------------------------------
     173             : // The base class for concrete states. A concrete state should inherit from this
     174             : // class, and override the methods to handle the events or callbacks. A concrete
     175             : // state is also responsible for transforming itself to the next concrete state.
     176             : //
     177             : class AccessibleCaretEventHub::State
     178             : {
     179             : public:
     180           0 :   virtual const char* Name() const { return ""; }
     181             : 
     182           0 :   virtual nsEventStatus OnPress(AccessibleCaretEventHub* aContext,
     183             :                                 const nsPoint& aPoint, int32_t aTouchId,
     184             :                                 EventClassID aEventClass)
     185             :   {
     186           0 :     return nsEventStatus_eIgnore;
     187             :   }
     188             : 
     189           0 :   virtual nsEventStatus OnMove(AccessibleCaretEventHub* aContext,
     190             :                                const nsPoint& aPoint)
     191             :   {
     192           0 :     return nsEventStatus_eIgnore;
     193             :   }
     194             : 
     195           0 :   virtual nsEventStatus OnRelease(AccessibleCaretEventHub* aContext)
     196             :   {
     197           0 :     return nsEventStatus_eIgnore;
     198             :   }
     199             : 
     200           0 :   virtual nsEventStatus OnLongTap(AccessibleCaretEventHub* aContext,
     201             :                                   const nsPoint& aPoint)
     202             :   {
     203           0 :     return nsEventStatus_eIgnore;
     204             :   }
     205             : 
     206           0 :   virtual void OnScrollStart(AccessibleCaretEventHub* aContext) {}
     207           0 :   virtual void OnScrollEnd(AccessibleCaretEventHub* aContext) {}
     208           0 :   virtual void OnScrollPositionChanged(AccessibleCaretEventHub* aContext) {}
     209           0 :   virtual void OnBlur(AccessibleCaretEventHub* aContext,
     210           0 :                       bool aIsLeavingDocument) {}
     211           0 :   virtual void OnSelectionChanged(AccessibleCaretEventHub* aContext,
     212             :                                   nsIDOMDocument* aDoc, nsISelection* aSel,
     213           0 :                                   int16_t aReason) {}
     214           0 :   virtual void OnReflow(AccessibleCaretEventHub* aContext) {}
     215           0 :   virtual void Enter(AccessibleCaretEventHub* aContext) {}
     216           0 :   virtual void Leave(AccessibleCaretEventHub* aContext) {}
     217             : 
     218             :   explicit State() = default;
     219           0 :   virtual ~State() = default;
     220             :   State(const State&) = delete;
     221             :   State& operator=(const State&) = delete;
     222             : };
     223             : 
     224             : } // namespace mozilla
     225             : 
     226             : #endif // AccessibleCaretEventHub_h

Generated by: LCOV version 1.13