tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

AccEvent.h (16323B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* This Source Code Form is subject to the terms of the Mozilla Public
      3 * License, v. 2.0. If a copy of the MPL was not distributed with this
      4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      5 
      6 #ifndef _AccEvent_H_
      7 #define _AccEvent_H_
      8 
      9 #include "nsIAccessibleEvent.h"
     10 
     11 #include "mozilla/a11y/LocalAccessible.h"
     12 
     13 class nsEventShell;
     14 namespace mozilla {
     15 
     16 namespace dom {
     17 class Selection;
     18 }
     19 
     20 namespace a11y {
     21 
     22 class DocAccessible;
     23 class EventQueue;
     24 class TextRange;
     25 
     26 // Constants used to point whether the event is from user input.
     27 enum EIsFromUserInput {
     28  // eNoUserInput: event is not from user input
     29  eNoUserInput = 0,
     30  // eFromUserInput: event is from user input
     31  eFromUserInput = 1,
     32  // eAutoDetect: the value should be obtained from event state manager
     33  eAutoDetect = -1
     34 };
     35 
     36 /**
     37 * Generic accessible event.
     38 */
     39 class AccEvent {
     40 public:
     41  // Rule for accessible events.
     42  // The rule will be applied when flushing pending events.
     43  enum EEventRule {
     44    // eAllowDupes : More than one event of the same type is allowed.
     45    //    This event will always be emitted. This flag is used for events that
     46    //    don't support coalescence.
     47    eAllowDupes,
     48 
     49    // eCoalesceReorder : For reorder events from the same subtree or the same
     50    //    node, only the umbrella event on the ancestor will be emitted.
     51    eCoalesceReorder,
     52 
     53    // eCoalesceOfSameType : For events of the same type, only the newest event
     54    // will be processed.
     55    eCoalesceOfSameType,
     56 
     57    // eCoalesceSelectionChange: coalescence of selection change events.
     58    eCoalesceSelectionChange,
     59 
     60    // eCoalesceStateChange: coalesce state change events.
     61    eCoalesceStateChange,
     62 
     63    // eCoalesceTextSelChange: coalescence of text selection change events.
     64    eCoalesceTextSelChange,
     65 
     66    // eRemoveDupes : For repeat events, only the newest event in queue
     67    //    will be emitted.
     68    eRemoveDupes,
     69 
     70    // eDoNotEmit : This event is confirmed as a duplicate, do not emit it.
     71    eDoNotEmit
     72  };
     73 
     74  // Initialize with an accessible.
     75  AccEvent(uint32_t aEventType, LocalAccessible* aAccessible,
     76           EIsFromUserInput aIsFromUserInput = eAutoDetect,
     77           EEventRule aEventRule = eRemoveDupes);
     78 
     79  // AccEvent
     80  uint32_t GetEventType() const { return mEventType; }
     81  EEventRule GetEventRule() const { return mEventRule; }
     82  bool IsFromUserInput() const { return mIsFromUserInput; }
     83  EIsFromUserInput FromUserInput() const {
     84    return static_cast<EIsFromUserInput>(mIsFromUserInput);
     85  }
     86 
     87  LocalAccessible* GetAccessible() const { return mAccessible; }
     88  DocAccessible* Document() const { return mAccessible->Document(); }
     89 
     90  /**
     91   * Down casting.
     92   */
     93  enum EventGroup {
     94    eGenericEvent,
     95    eStateChangeEvent,
     96    eTextChangeEvent,
     97    eTreeMutationEvent,
     98    eMutationEvent,
     99    eReorderEvent,
    100    eHideEvent,
    101    eShowEvent,
    102    eCaretMoveEvent,
    103    eTextSelChangeEvent,
    104    eSelectionChangeEvent,
    105    eObjectAttrChangedEvent,
    106    eScrollingEvent,
    107    eAnnouncementEvent,
    108  };
    109 
    110  static const EventGroup kEventGroup = eGenericEvent;
    111  virtual unsigned int GetEventGroups() const { return 1U << eGenericEvent; }
    112 
    113  /**
    114   * Reference counting and cycle collection.
    115   */
    116  NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(AccEvent)
    117  NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(AccEvent)
    118 
    119 protected:
    120  virtual ~AccEvent() {}
    121 
    122  bool mIsFromUserInput;
    123  uint32_t mEventType;
    124  EEventRule mEventRule;
    125  RefPtr<LocalAccessible> mAccessible;
    126 
    127  friend class EventQueue;
    128  friend class EventTree;
    129  friend class ::nsEventShell;
    130  friend class NotificationController;
    131 };
    132 
    133 /**
    134 * Accessible state change event.
    135 */
    136 class AccStateChangeEvent : public AccEvent {
    137 public:
    138  AccStateChangeEvent(LocalAccessible* aAccessible, uint64_t aState,
    139                      bool aIsEnabled,
    140                      EIsFromUserInput aIsFromUserInput = eAutoDetect)
    141      : AccEvent(nsIAccessibleEvent::EVENT_STATE_CHANGE, aAccessible,
    142                 aIsFromUserInput, eCoalesceStateChange),
    143        mState(aState),
    144        mIsEnabled(aIsEnabled) {}
    145 
    146  AccStateChangeEvent(LocalAccessible* aAccessible, uint64_t aState)
    147      : AccEvent(::nsIAccessibleEvent::EVENT_STATE_CHANGE, aAccessible,
    148                 eAutoDetect, eCoalesceStateChange),
    149        mState(aState) {
    150    mIsEnabled = (mAccessible->State() & mState) != 0;
    151  }
    152 
    153  // AccEvent
    154  static const EventGroup kEventGroup = eStateChangeEvent;
    155  virtual unsigned int GetEventGroups() const override {
    156    return AccEvent::GetEventGroups() | (1U << eStateChangeEvent);
    157  }
    158 
    159  // AccStateChangeEvent
    160  uint64_t GetState() const { return mState; }
    161  bool IsStateEnabled() const { return mIsEnabled; }
    162 
    163 private:
    164  uint64_t mState;
    165  bool mIsEnabled;
    166 
    167  friend class EventQueue;
    168 };
    169 
    170 /**
    171 * Accessible text change event.
    172 */
    173 class AccTextChangeEvent : public AccEvent {
    174 public:
    175  AccTextChangeEvent(LocalAccessible* aAccessible, int32_t aStart,
    176                     const nsAString& aModifiedText, bool aIsInserted,
    177                     EIsFromUserInput aIsFromUserInput = eAutoDetect);
    178 
    179  // AccEvent
    180  static const EventGroup kEventGroup = eTextChangeEvent;
    181  virtual unsigned int GetEventGroups() const override {
    182    return AccEvent::GetEventGroups() | (1U << eTextChangeEvent);
    183  }
    184 
    185  // AccTextChangeEvent
    186  int32_t GetStartOffset() const { return mStart; }
    187  uint32_t GetLength() const { return mModifiedText.Length(); }
    188  bool IsTextInserted() const { return mIsInserted; }
    189  void GetModifiedText(nsAString& aModifiedText) {
    190    aModifiedText = mModifiedText;
    191  }
    192  const nsString& ModifiedText() const { return mModifiedText; }
    193 
    194 private:
    195  int32_t mStart;
    196  bool mIsInserted;
    197  nsString mModifiedText;
    198 
    199  friend class EventTree;
    200  friend class NotificationController;
    201 };
    202 
    203 /**
    204 * A base class for events related to tree mutation, either an AccMutation
    205 * event, or an AccReorderEvent.
    206 */
    207 class AccTreeMutationEvent : public AccEvent {
    208 public:
    209  AccTreeMutationEvent(uint32_t aEventType, LocalAccessible* aTarget)
    210      : AccEvent(aEventType, aTarget, eAutoDetect, eCoalesceReorder),
    211        mGeneration(0) {}
    212 
    213  // Event
    214  static const EventGroup kEventGroup = eTreeMutationEvent;
    215  virtual unsigned int GetEventGroups() const override {
    216    return AccEvent::GetEventGroups() | (1U << eTreeMutationEvent);
    217  }
    218 
    219  void SetNextEvent(AccTreeMutationEvent* aNext) { mNextEvent = aNext; }
    220  void SetPrevEvent(AccTreeMutationEvent* aPrev) { mPrevEvent = aPrev; }
    221  AccTreeMutationEvent* NextEvent() const { return mNextEvent; }
    222  AccTreeMutationEvent* PrevEvent() const { return mPrevEvent; }
    223 
    224  /**
    225   * A sequence number to know when this event was fired.
    226   */
    227  uint32_t EventGeneration() const { return mGeneration; }
    228  void SetEventGeneration(uint32_t aGeneration) { mGeneration = aGeneration; }
    229 
    230 private:
    231  RefPtr<AccTreeMutationEvent> mNextEvent;
    232  RefPtr<AccTreeMutationEvent> mPrevEvent;
    233  uint32_t mGeneration;
    234 };
    235 
    236 /**
    237 * Base class for show and hide accessible events.
    238 */
    239 class AccMutationEvent : public AccTreeMutationEvent {
    240 public:
    241  AccMutationEvent(uint32_t aEventType, LocalAccessible* aTarget)
    242      : AccTreeMutationEvent(aEventType, aTarget) {
    243    // Don't coalesce these since they are coalesced by reorder event. Coalesce
    244    // contained text change events.
    245    mParent = mAccessible->LocalParent();
    246  }
    247  virtual ~AccMutationEvent() {}
    248 
    249  // Event
    250  static const EventGroup kEventGroup = eMutationEvent;
    251  virtual unsigned int GetEventGroups() const override {
    252    return AccTreeMutationEvent::GetEventGroups() | (1U << eMutationEvent);
    253  }
    254 
    255  // MutationEvent
    256  bool IsShow() const { return mEventType == nsIAccessibleEvent::EVENT_SHOW; }
    257  bool IsHide() const { return mEventType == nsIAccessibleEvent::EVENT_HIDE; }
    258 
    259  LocalAccessible* LocalParent() const { return mParent; }
    260 
    261 protected:
    262  RefPtr<LocalAccessible> mParent;
    263  RefPtr<AccTextChangeEvent> mTextChangeEvent;
    264 
    265  friend class EventTree;
    266  friend class NotificationController;
    267 };
    268 
    269 /**
    270 * Accessible hide event.
    271 */
    272 class AccHideEvent : public AccMutationEvent {
    273 public:
    274  explicit AccHideEvent(LocalAccessible* aTarget, bool aNeedsShutdown = true);
    275 
    276  // Event
    277  static const EventGroup kEventGroup = eHideEvent;
    278  virtual unsigned int GetEventGroups() const override {
    279    return AccMutationEvent::GetEventGroups() | (1U << eHideEvent);
    280  }
    281 
    282  // AccHideEvent
    283  LocalAccessible* TargetParent() const { return mParent; }
    284  LocalAccessible* TargetNextSibling() const { return mNextSibling; }
    285  LocalAccessible* TargetPrevSibling() const { return mPrevSibling; }
    286  bool NeedsShutdown() const { return mNeedsShutdown; }
    287 
    288 protected:
    289  bool mNeedsShutdown;
    290  RefPtr<LocalAccessible> mNextSibling;
    291  RefPtr<LocalAccessible> mPrevSibling;
    292 
    293  friend class EventTree;
    294  friend class NotificationController;
    295 };
    296 
    297 /**
    298 * Accessible show event.
    299 */
    300 class AccShowEvent : public AccMutationEvent {
    301 public:
    302  explicit AccShowEvent(LocalAccessible* aTarget)
    303      : AccMutationEvent(::nsIAccessibleEvent::EVENT_SHOW, aTarget) {}
    304 
    305  // Event
    306  static const EventGroup kEventGroup = eShowEvent;
    307  virtual unsigned int GetEventGroups() const override {
    308    return AccMutationEvent::GetEventGroups() | (1U << eShowEvent);
    309  }
    310 };
    311 
    312 /**
    313 * Class for reorder accessible event. Takes care about
    314 */
    315 class AccReorderEvent : public AccTreeMutationEvent {
    316 public:
    317  explicit AccReorderEvent(LocalAccessible* aTarget)
    318      : AccTreeMutationEvent(::nsIAccessibleEvent::EVENT_REORDER, aTarget) {}
    319  virtual ~AccReorderEvent() {}
    320 
    321  // Event
    322  static const EventGroup kEventGroup = eReorderEvent;
    323  virtual unsigned int GetEventGroups() const override {
    324    return AccTreeMutationEvent::GetEventGroups() | (1U << eReorderEvent);
    325  }
    326 
    327  /*
    328   * Make this an inner reorder event that is coalesced into
    329   * a reorder event of an ancestor.
    330   */
    331  void SetInner() { mEventType = ::nsIAccessibleEvent::EVENT_INNER_REORDER; }
    332 };
    333 
    334 /**
    335 * Accessible caret move event.
    336 */
    337 class AccCaretMoveEvent : public AccEvent {
    338 public:
    339  AccCaretMoveEvent(LocalAccessible* aAccessible, int32_t aCaretOffset,
    340                    bool aIsSelectionCollapsed, bool aIsAtEndOfLine,
    341                    int32_t aGranularity,
    342                    EIsFromUserInput aIsFromUserInput = eAutoDetect)
    343      : AccEvent(::nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED, aAccessible,
    344                 aIsFromUserInput),
    345        mCaretOffset(aCaretOffset),
    346        mIsSelectionCollapsed(aIsSelectionCollapsed),
    347        mIsAtEndOfLine(aIsAtEndOfLine),
    348        mGranularity(aGranularity) {}
    349  virtual ~AccCaretMoveEvent() {}
    350 
    351  // AccEvent
    352  static const EventGroup kEventGroup = eCaretMoveEvent;
    353  virtual unsigned int GetEventGroups() const override {
    354    return AccEvent::GetEventGroups() | (1U << eCaretMoveEvent);
    355  }
    356 
    357  // AccCaretMoveEvent
    358  int32_t GetCaretOffset() const { return mCaretOffset; }
    359 
    360  bool IsSelectionCollapsed() const { return mIsSelectionCollapsed; }
    361  bool IsAtEndOfLine() { return mIsAtEndOfLine; }
    362 
    363  int32_t GetGranularity() const { return mGranularity; }
    364 
    365 private:
    366  int32_t mCaretOffset;
    367 
    368  bool mIsSelectionCollapsed;
    369  bool mIsAtEndOfLine;
    370  int32_t mGranularity;
    371 };
    372 
    373 /**
    374 * Accessible text selection change event.
    375 */
    376 class AccTextSelChangeEvent : public AccEvent {
    377 public:
    378  AccTextSelChangeEvent(HyperTextAccessible* aTarget,
    379                        dom::Selection* aSelection, int32_t aReason,
    380                        int32_t aGranularity);
    381  virtual ~AccTextSelChangeEvent();
    382 
    383  // AccEvent
    384  static const EventGroup kEventGroup = eTextSelChangeEvent;
    385  virtual unsigned int GetEventGroups() const override {
    386    return AccEvent::GetEventGroups() | (1U << eTextSelChangeEvent);
    387  }
    388 
    389  // AccTextSelChangeEvent
    390 
    391  /**
    392   * Return true if the text selection change wasn't caused by pure caret move.
    393   */
    394  bool IsCaretMoveOnly() const;
    395 
    396  int32_t GetGranularity() const { return mGranularity; }
    397 
    398  /**
    399   * Return selection ranges in document/control.
    400   */
    401  void SelectionRanges(nsTArray<a11y::TextRange>* aRanges) const;
    402 
    403 private:
    404  RefPtr<dom::Selection> mSel;
    405  int32_t mReason;
    406  int32_t mGranularity;
    407 
    408  friend class EventQueue;
    409  friend class SelectionManager;
    410 };
    411 
    412 /**
    413 * Accessible widget selection change event.
    414 */
    415 class AccSelChangeEvent : public AccEvent {
    416 public:
    417  enum SelChangeType { eSelectionAdd, eSelectionRemove };
    418 
    419  AccSelChangeEvent(LocalAccessible* aWidget, LocalAccessible* aItem,
    420                    SelChangeType aSelChangeType);
    421 
    422  virtual ~AccSelChangeEvent() {}
    423 
    424  // AccEvent
    425  static const EventGroup kEventGroup = eSelectionChangeEvent;
    426  virtual unsigned int GetEventGroups() const override {
    427    return AccEvent::GetEventGroups() | (1U << eSelectionChangeEvent);
    428  }
    429 
    430  // AccSelChangeEvent
    431  LocalAccessible* Widget() const { return mWidget; }
    432 
    433 private:
    434  RefPtr<LocalAccessible> mWidget;
    435  RefPtr<LocalAccessible> mItem;
    436  SelChangeType mSelChangeType;
    437  uint32_t mPreceedingCount;
    438  AccSelChangeEvent* mPackedEvent;
    439 
    440  friend class EventQueue;
    441 };
    442 
    443 /**
    444 * Accessible object attribute changed event.
    445 */
    446 class AccObjectAttrChangedEvent : public AccEvent {
    447 public:
    448  AccObjectAttrChangedEvent(LocalAccessible* aAccessible, nsAtom* aAttribute)
    449      : AccEvent(::nsIAccessibleEvent::EVENT_OBJECT_ATTRIBUTE_CHANGED,
    450                 aAccessible),
    451        mAttribute(aAttribute) {}
    452 
    453  // AccEvent
    454  static const EventGroup kEventGroup = eObjectAttrChangedEvent;
    455  virtual unsigned int GetEventGroups() const override {
    456    return AccEvent::GetEventGroups() | (1U << eObjectAttrChangedEvent);
    457  }
    458 
    459  // AccObjectAttrChangedEvent
    460  nsAtom* GetAttribute() const { return mAttribute; }
    461 
    462 private:
    463  RefPtr<nsAtom> mAttribute;
    464 
    465  virtual ~AccObjectAttrChangedEvent() {}
    466 };
    467 
    468 /**
    469 * Accessible scroll event.
    470 */
    471 class AccScrollingEvent : public AccEvent {
    472 public:
    473  AccScrollingEvent(uint32_t aEventType, LocalAccessible* aAccessible,
    474                    uint32_t aScrollX, uint32_t aScrollY, uint32_t aMaxScrollX,
    475                    uint32_t aMaxScrollY)
    476      : AccEvent(aEventType, aAccessible),
    477        mScrollX(aScrollX),
    478        mScrollY(aScrollY),
    479        mMaxScrollX(aMaxScrollX),
    480        mMaxScrollY(aMaxScrollY) {}
    481 
    482  virtual ~AccScrollingEvent() {}
    483 
    484  // AccEvent
    485  static const EventGroup kEventGroup = eScrollingEvent;
    486  virtual unsigned int GetEventGroups() const override {
    487    return AccEvent::GetEventGroups() | (1U << eScrollingEvent);
    488  }
    489 
    490  // The X scrolling offset of the container when the event was fired.
    491  uint32_t ScrollX() { return mScrollX; }
    492  // The Y scrolling offset of the container when the event was fired.
    493  uint32_t ScrollY() { return mScrollY; }
    494  // The max X offset of the container.
    495  uint32_t MaxScrollX() { return mMaxScrollX; }
    496  // The max Y offset of the container.
    497  uint32_t MaxScrollY() { return mMaxScrollY; }
    498 
    499 private:
    500  uint32_t mScrollX;
    501  uint32_t mScrollY;
    502  uint32_t mMaxScrollX;
    503  uint32_t mMaxScrollY;
    504 };
    505 
    506 /**
    507 * Accessible announcement event.
    508 */
    509 class AccAnnouncementEvent : public AccEvent {
    510 public:
    511  AccAnnouncementEvent(LocalAccessible* aAccessible,
    512                       const nsAString& aAnnouncement, uint16_t aPriority)
    513      : AccEvent(nsIAccessibleEvent::EVENT_ANNOUNCEMENT, aAccessible),
    514        mAnnouncement(aAnnouncement),
    515        mPriority(aPriority) {}
    516 
    517  virtual ~AccAnnouncementEvent() {}
    518 
    519  // AccEvent
    520  static const EventGroup kEventGroup = eAnnouncementEvent;
    521  virtual unsigned int GetEventGroups() const override {
    522    return AccEvent::GetEventGroups() | (1U << eAnnouncementEvent);
    523  }
    524 
    525  const nsString& Announcement() const { return mAnnouncement; }
    526 
    527  uint16_t Priority() { return mPriority; }
    528 
    529 private:
    530  nsString mAnnouncement;
    531  uint16_t mPriority;
    532 };
    533 
    534 /**
    535 * Downcast the generic accessible event object to derived type.
    536 */
    537 class downcast_accEvent {
    538 public:
    539  explicit downcast_accEvent(AccEvent* e) : mRawPtr(e) {}
    540 
    541  template <class Destination>
    542  operator Destination*() {
    543    if (!mRawPtr) return nullptr;
    544 
    545    return mRawPtr->GetEventGroups() & (1U << Destination::kEventGroup)
    546               ? static_cast<Destination*>(mRawPtr)
    547               : nullptr;
    548  }
    549 
    550 private:
    551  AccEvent* mRawPtr;
    552 };
    553 
    554 /**
    555 * Return a new xpcom accessible event for the given internal one.
    556 */
    557 already_AddRefed<nsIAccessibleEvent> MakeXPCEvent(AccEvent* aEvent);
    558 
    559 }  // namespace a11y
    560 }  // namespace mozilla
    561 
    562 #endif