accessible/src/base/AccEvent.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     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/. */
     6 #ifndef _AccEvent_H_
     7 #define _AccEvent_H_
     9 #include "nsIAccessibleEvent.h"
    11 #include "mozilla/a11y/Accessible.h"
    13 namespace mozilla {
    15 namespace dom {
    16 class Selection;
    17 }
    19 namespace a11y {
    21 class DocAccessible;
    23 // Constants used to point whether the event is from user input.
    24 enum EIsFromUserInput
    25 {
    26   // eNoUserInput: event is not from user input
    27   eNoUserInput = 0,
    28   // eFromUserInput: event is from user input
    29   eFromUserInput = 1,
    30   // eAutoDetect: the value should be obtained from event state manager
    31   eAutoDetect = -1
    32 };
    34 /**
    35  * Generic accessible event.
    36  */
    37 class AccEvent
    38 {
    39 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,
    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,
    53      // eCoalesceMutationTextChange : coalesce text change events caused by
    54      // tree mutations of the same tree level.
    55     eCoalesceMutationTextChange,
    57     // eCoalesceOfSameType : For events of the same type, only the newest event
    58     // will be processed.
    59     eCoalesceOfSameType,
    61     // eCoalesceSelectionChange: coalescence of selection change events.
    62     eCoalesceSelectionChange,
    64     // eCoalesceStateChange: coalesce state change events.
    65     eCoalesceStateChange,
    67     // eCoalesceTextSelChange: coalescence of text selection change events.
    68     eCoalesceTextSelChange,
    70      // eRemoveDupes : For repeat events, only the newest event in queue
    71      //    will be emitted.
    72     eRemoveDupes,
    74      // eDoNotEmit : This event is confirmed as a duplicate, do not emit it.
    75     eDoNotEmit
    76   };
    78   // Initialize with an nsIAccessible
    79   AccEvent(uint32_t aEventType, Accessible* aAccessible,
    80            EIsFromUserInput aIsFromUserInput = eAutoDetect,
    81            EEventRule aEventRule = eRemoveDupes);
    82   virtual ~AccEvent() {}
    84   // AccEvent
    85   uint32_t GetEventType() const { return mEventType; }
    86   EEventRule GetEventRule() const { return mEventRule; }
    87   bool IsFromUserInput() const { return mIsFromUserInput; }
    88   EIsFromUserInput FromUserInput() const
    89     { return static_cast<EIsFromUserInput>(mIsFromUserInput); }
    91   Accessible* GetAccessible() const { return mAccessible; }
    92   DocAccessible* GetDocAccessible() const { return mAccessible->Document(); }
    94   /**
    95    * Down casting.
    96    */
    97   enum EventGroup {
    98     eGenericEvent,
    99     eStateChangeEvent,
   100     eTextChangeEvent,
   101     eMutationEvent,
   102     eReorderEvent,
   103     eHideEvent,
   104     eShowEvent,
   105     eCaretMoveEvent,
   106     eTextSelChangeEvent,
   107     eSelectionChangeEvent,
   108     eTableChangeEvent,
   109     eVirtualCursorChangeEvent
   110   };
   112   static const EventGroup kEventGroup = eGenericEvent;
   113   virtual unsigned int GetEventGroups() const
   114   {
   115     return 1U << eGenericEvent;
   116   }
   118   /**
   119    * Reference counting and cycle collection.
   120    */
   121   NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(AccEvent)
   122   NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(AccEvent)
   124 protected:
   125   bool mIsFromUserInput;
   126   uint32_t mEventType;
   127   EEventRule mEventRule;
   128   nsRefPtr<Accessible> mAccessible;
   130   friend class EventQueue;
   131   friend class AccReorderEvent;
   132 };
   135 /**
   136  * Accessible state change event.
   137  */
   138 class AccStateChangeEvent: public AccEvent
   139 {
   140 public:
   141   AccStateChangeEvent(Accessible* aAccessible, uint64_t aState,
   142                       bool aIsEnabled,
   143                       EIsFromUserInput aIsFromUserInput = eAutoDetect) :
   144     AccEvent(nsIAccessibleEvent::EVENT_STATE_CHANGE, aAccessible,
   145              aIsFromUserInput, eCoalesceStateChange),
   146              mState(aState), mIsEnabled(aIsEnabled) { }
   148   AccStateChangeEvent(Accessible* aAccessible, uint64_t aState) :
   149     AccEvent(::nsIAccessibleEvent::EVENT_STATE_CHANGE, aAccessible,
   150              eAutoDetect, eCoalesceStateChange), mState(aState)
   151     { mIsEnabled = (mAccessible->State() & mState) != 0; }
   153   // AccEvent
   154   static const EventGroup kEventGroup = eStateChangeEvent;
   155   virtual unsigned int GetEventGroups() const
   156   {
   157     return AccEvent::GetEventGroups() | (1U << eStateChangeEvent);
   158   }
   160   // AccStateChangeEvent
   161   uint64_t GetState() const { return mState; }
   162   bool IsStateEnabled() const { return mIsEnabled; }
   164 private:
   165   uint64_t mState;
   166   bool mIsEnabled;
   168   friend class EventQueue;
   169 };
   172 /**
   173  * Accessible text change event.
   174  */
   175 class AccTextChangeEvent: public AccEvent
   176 {
   177 public:
   178   AccTextChangeEvent(Accessible* aAccessible, int32_t aStart,
   179                      const nsAString& aModifiedText, bool aIsInserted,
   180                      EIsFromUserInput aIsFromUserInput = eAutoDetect);
   182   // AccEvent
   183   static const EventGroup kEventGroup = eTextChangeEvent;
   184   virtual unsigned int GetEventGroups() const
   185   {
   186     return AccEvent::GetEventGroups() | (1U << eTextChangeEvent);
   187   }
   189   // AccTextChangeEvent
   190   int32_t GetStartOffset() const { return mStart; }
   191   uint32_t GetLength() const { return mModifiedText.Length(); }
   192   bool IsTextInserted() const { return mIsInserted; }
   193   void GetModifiedText(nsAString& aModifiedText)
   194     { aModifiedText = mModifiedText; }
   196 private:
   197   int32_t mStart;
   198   bool mIsInserted;
   199   nsString mModifiedText;
   201   friend class EventQueue;
   202   friend class AccReorderEvent;
   203 };
   206 /**
   207  * Base class for show and hide accessible events.
   208  */
   209 class AccMutationEvent: public AccEvent
   210 {
   211 public:
   212   AccMutationEvent(uint32_t aEventType, Accessible* aTarget,
   213                    nsINode* aTargetNode) :
   214     AccEvent(aEventType, aTarget, eAutoDetect, eCoalesceMutationTextChange)
   215   {
   216     // Don't coalesce these since they are coalesced by reorder event. Coalesce
   217     // contained text change events.
   218     mParent = mAccessible->Parent();
   219   }
   220   virtual ~AccMutationEvent() { }
   222   // Event
   223   static const EventGroup kEventGroup = eMutationEvent;
   224   virtual unsigned int GetEventGroups() const
   225   {
   226     return AccEvent::GetEventGroups() | (1U << eMutationEvent);
   227   }
   229   // MutationEvent
   230   bool IsShow() const { return mEventType == nsIAccessibleEvent::EVENT_SHOW; }
   231   bool IsHide() const { return mEventType == nsIAccessibleEvent::EVENT_HIDE; }
   233 protected:
   234   nsCOMPtr<nsINode> mNode;
   235   nsRefPtr<Accessible> mParent;
   236   nsRefPtr<AccTextChangeEvent> mTextChangeEvent;
   238   friend class EventQueue;
   239 };
   242 /**
   243  * Accessible hide event.
   244  */
   245 class AccHideEvent: public AccMutationEvent
   246 {
   247 public:
   248   AccHideEvent(Accessible* aTarget, nsINode* aTargetNode);
   250   // Event
   251   static const EventGroup kEventGroup = eHideEvent;
   252   virtual unsigned int GetEventGroups() const
   253   {
   254     return AccMutationEvent::GetEventGroups() | (1U << eHideEvent);
   255   }
   257   // AccHideEvent
   258   Accessible* TargetParent() const { return mParent; }
   259   Accessible* TargetNextSibling() const { return mNextSibling; }
   260   Accessible* TargetPrevSibling() const { return mPrevSibling; }
   262 protected:
   263   nsRefPtr<Accessible> mNextSibling;
   264   nsRefPtr<Accessible> mPrevSibling;
   266   friend class EventQueue;
   267 };
   270 /**
   271  * Accessible show event.
   272  */
   273 class AccShowEvent: public AccMutationEvent
   274 {
   275 public:
   276   AccShowEvent(Accessible* aTarget, nsINode* aTargetNode);
   278   // Event
   279   static const EventGroup kEventGroup = eShowEvent;
   280   virtual unsigned int GetEventGroups() const
   281   {
   282     return AccMutationEvent::GetEventGroups() | (1U << eShowEvent);
   283   }
   284 };
   287 /**
   288  * Class for reorder accessible event. Takes care about
   289  */
   290 class AccReorderEvent : public AccEvent
   291 {
   292 public:
   293   AccReorderEvent(Accessible* aTarget) :
   294     AccEvent(::nsIAccessibleEvent::EVENT_REORDER, aTarget,
   295              eAutoDetect, eCoalesceReorder) { }
   296   virtual ~AccReorderEvent() { }
   298   // Event
   299   static const EventGroup kEventGroup = eReorderEvent;
   300   virtual unsigned int GetEventGroups() const
   301   {
   302     return AccEvent::GetEventGroups() | (1U << eReorderEvent);
   303   }
   305   /**
   306    * Get connected with mutation event.
   307    */
   308   void AddSubMutationEvent(AccMutationEvent* aEvent)
   309     { mDependentEvents.AppendElement(aEvent); }
   311   /**
   312    * Do not emit the reorder event and its connected mutation events.
   313    */
   314   void DoNotEmitAll()
   315   {
   316     mEventRule = AccEvent::eDoNotEmit;
   317     uint32_t eventsCount = mDependentEvents.Length();
   318     for (uint32_t idx = 0; idx < eventsCount; idx++)
   319       mDependentEvents[idx]->mEventRule = AccEvent::eDoNotEmit;
   320   }
   322   /**
   323    * Return true if the given accessible is a target of connected mutation
   324    * event.
   325    */
   326   uint32_t IsShowHideEventTarget(const Accessible* aTarget) const;
   328 protected:
   329   /**
   330    * Show and hide events causing this reorder event.
   331    */
   332   nsTArray<AccMutationEvent*> mDependentEvents;
   334   friend class EventQueue;
   335 };
   338 /**
   339  * Accessible caret move event.
   340  */
   341 class AccCaretMoveEvent: public AccEvent
   342 {
   343 public:
   344   AccCaretMoveEvent(Accessible* aAccessible, int32_t aCaretOffset,
   345                     EIsFromUserInput aIsFromUserInput = eAutoDetect) :
   346     AccEvent(::nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED, aAccessible,
   347              aIsFromUserInput),
   348     mCaretOffset(aCaretOffset) { }
   349   virtual ~AccCaretMoveEvent() { }
   351   // AccEvent
   352   static const EventGroup kEventGroup = eCaretMoveEvent;
   353   virtual unsigned int GetEventGroups() const
   354   {
   355     return AccEvent::GetEventGroups() | (1U << eCaretMoveEvent);
   356   }
   358   // AccCaretMoveEvent
   359   int32_t GetCaretOffset() const { return mCaretOffset; }
   361 private:
   362   int32_t mCaretOffset;
   363 };
   366 /**
   367  * Accessible text selection change event.
   368  */
   369 class AccTextSelChangeEvent : public AccEvent
   370 {
   371 public:
   372   AccTextSelChangeEvent(HyperTextAccessible* aTarget,
   373                         dom::Selection* aSelection,
   374                         int32_t aReason);
   375   virtual ~AccTextSelChangeEvent();
   377   // AccEvent
   378   static const EventGroup kEventGroup = eTextSelChangeEvent;
   379   virtual unsigned int GetEventGroups() const
   380   {
   381     return AccEvent::GetEventGroups() | (1U << eTextSelChangeEvent);
   382   }
   384   // AccTextSelChangeEvent
   386   /**
   387    * Return true if the text selection change wasn't caused by pure caret move.
   388    */
   389   bool IsCaretMoveOnly() const;
   391 private:
   392   nsRefPtr<dom::Selection> mSel;
   393   int32_t mReason;
   395   friend class EventQueue;
   396   friend class SelectionManager;
   397 };
   400 /**
   401  * Accessible widget selection change event.
   402  */
   403 class AccSelChangeEvent : public AccEvent
   404 {
   405 public:
   406   enum SelChangeType {
   407     eSelectionAdd,
   408     eSelectionRemove
   409   };
   411   AccSelChangeEvent(Accessible* aWidget, Accessible* aItem,
   412                     SelChangeType aSelChangeType);
   414   virtual ~AccSelChangeEvent() { }
   416   // AccEvent
   417   static const EventGroup kEventGroup = eSelectionChangeEvent;
   418   virtual unsigned int GetEventGroups() const
   419   {
   420     return AccEvent::GetEventGroups() | (1U << eSelectionChangeEvent);
   421   }
   423   // AccSelChangeEvent
   424   Accessible* Widget() const { return mWidget; }
   426 private:
   427   nsRefPtr<Accessible> mWidget;
   428   nsRefPtr<Accessible> mItem;
   429   SelChangeType mSelChangeType;
   430   uint32_t mPreceedingCount;
   431   AccSelChangeEvent* mPackedEvent;
   433   friend class EventQueue;
   434 };
   437 /**
   438  * Accessible table change event.
   439  */
   440 class AccTableChangeEvent : public AccEvent
   441 {
   442 public:
   443   AccTableChangeEvent(Accessible* aAccessible, uint32_t aEventType,
   444                       int32_t aRowOrColIndex, int32_t aNumRowsOrCols);
   446   // AccEvent
   447   static const EventGroup kEventGroup = eTableChangeEvent;
   448   virtual unsigned int GetEventGroups() const
   449   {
   450     return AccEvent::GetEventGroups() | (1U << eTableChangeEvent);
   451   }
   453   // AccTableChangeEvent
   454   uint32_t GetIndex() const { return mRowOrColIndex; }
   455   uint32_t GetCount() const { return mNumRowsOrCols; }
   457 private:
   458   uint32_t mRowOrColIndex;   // the start row/column after which the rows are inserted/deleted.
   459   uint32_t mNumRowsOrCols;   // the number of inserted/deleted rows/columns
   460 };
   462 /**
   463  * Accessible virtual cursor change event.
   464  */
   465 class AccVCChangeEvent : public AccEvent
   466 {
   467 public:
   468   AccVCChangeEvent(Accessible* aAccessible,
   469                    nsIAccessible* aOldAccessible,
   470                    int32_t aOldStart, int32_t aOldEnd,
   471                    int16_t aReason);
   473   virtual ~AccVCChangeEvent() { }
   475   // AccEvent
   476   static const EventGroup kEventGroup = eVirtualCursorChangeEvent;
   477   virtual unsigned int GetEventGroups() const
   478   {
   479     return AccEvent::GetEventGroups() | (1U << eVirtualCursorChangeEvent);
   480   }
   482   // AccTableChangeEvent
   483   nsIAccessible* OldAccessible() const { return mOldAccessible; }
   484   int32_t OldStartOffset() const { return mOldStart; }
   485   int32_t OldEndOffset() const { return mOldEnd; }
   486   int32_t Reason() const { return mReason; }
   488 private:
   489   nsRefPtr<nsIAccessible> mOldAccessible;
   490   int32_t mOldStart;
   491   int32_t mOldEnd;
   492   int16_t mReason;
   493 };
   495 /**
   496  * Downcast the generic accessible event object to derived type.
   497  */
   498 class downcast_accEvent
   499 {
   500 public:
   501   downcast_accEvent(AccEvent* e) : mRawPtr(e) { }
   503   template<class Destination>
   504   operator Destination*() {
   505     if (!mRawPtr)
   506       return nullptr;
   508     return mRawPtr->GetEventGroups() & (1U << Destination::kEventGroup) ?
   509       static_cast<Destination*>(mRawPtr) : nullptr;
   510   }
   512 private:
   513   AccEvent* mRawPtr;
   514 };
   516 /**
   517  * Return a new xpcom accessible event for the given internal one.
   518  */
   519 already_AddRefed<nsIAccessibleEvent>
   520 MakeXPCEvent(AccEvent* aEvent);
   522 } // namespace a11y
   523 } // namespace mozilla
   525 #endif

mercurial