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/. */
9 #include "nsIAccessibleEvent.h"
11 #include "mozilla/a11y/LocalAccessible.h"
26 // Constants used to point whether the event is from user input.
27 enum EIsFromUserInput
{
28 // eNoUserInput: event is not from user input
30 // eFromUserInput: event is from user input
32 // eAutoDetect: the value should be obtained from event state manager
37 * Generic accessible event.
41 // Rule for accessible events.
42 // The rule will be applied when flushing pending events.
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.
49 // eCoalesceReorder : For reorder events from the same subtree or the same
50 // node, only the umbrella event on the ancestor will be emitted.
53 // eCoalesceOfSameType : For events of the same type, only the newest event
57 // eCoalesceSelectionChange: coalescence of selection change events.
58 eCoalesceSelectionChange
,
60 // eCoalesceStateChange: coalesce state change events.
63 // eCoalesceTextSelChange: coalescence of text selection change events.
64 eCoalesceTextSelChange
,
66 // eRemoveDupes : For repeat events, only the newest event in queue
70 // eDoNotEmit : This event is confirmed as a duplicate, do not emit it.
74 // Initialize with an accessible.
75 AccEvent(uint32_t aEventType
, LocalAccessible
* aAccessible
,
76 EIsFromUserInput aIsFromUserInput
= eAutoDetect
,
77 EEventRule aEventRule
= eRemoveDupes
);
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
);
87 LocalAccessible
* GetAccessible() const { return mAccessible
; }
88 DocAccessible
* Document() const { return mAccessible
->Document(); }
104 eSelectionChangeEvent
,
106 eVirtualCursorChangeEvent
,
107 eObjectAttrChangedEvent
,
112 static const EventGroup kEventGroup
= eGenericEvent
;
113 virtual unsigned int GetEventGroups() const { return 1U << eGenericEvent
; }
116 * Reference counting and cycle collection.
118 NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(AccEvent
)
119 NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(AccEvent
)
122 virtual ~AccEvent() {}
124 bool mIsFromUserInput
;
126 EEventRule mEventRule
;
127 RefPtr
<LocalAccessible
> mAccessible
;
129 friend class EventQueue
;
130 friend class EventTree
;
131 friend class ::nsEventShell
;
132 friend class NotificationController
;
136 * Accessible state change event.
138 class AccStateChangeEvent
: public AccEvent
{
140 AccStateChangeEvent(LocalAccessible
* aAccessible
, uint64_t aState
,
142 EIsFromUserInput aIsFromUserInput
= eAutoDetect
)
143 : AccEvent(nsIAccessibleEvent::EVENT_STATE_CHANGE
, aAccessible
,
144 aIsFromUserInput
, eCoalesceStateChange
),
146 mIsEnabled(aIsEnabled
) {}
148 AccStateChangeEvent(LocalAccessible
* aAccessible
, uint64_t aState
)
149 : AccEvent(::nsIAccessibleEvent::EVENT_STATE_CHANGE
, aAccessible
,
150 eAutoDetect
, eCoalesceStateChange
),
152 mIsEnabled
= (mAccessible
->State() & mState
) != 0;
156 static const EventGroup kEventGroup
= eStateChangeEvent
;
157 virtual unsigned int GetEventGroups() const override
{
158 return AccEvent::GetEventGroups() | (1U << eStateChangeEvent
);
161 // AccStateChangeEvent
162 uint64_t GetState() const { return mState
; }
163 bool IsStateEnabled() const { return mIsEnabled
; }
169 friend class EventQueue
;
173 * Accessible text change event.
175 class AccTextChangeEvent
: public AccEvent
{
177 AccTextChangeEvent(LocalAccessible
* aAccessible
, int32_t aStart
,
178 const nsAString
& aModifiedText
, bool aIsInserted
,
179 EIsFromUserInput aIsFromUserInput
= eAutoDetect
);
182 static const EventGroup kEventGroup
= eTextChangeEvent
;
183 virtual unsigned int GetEventGroups() const override
{
184 return AccEvent::GetEventGroups() | (1U << eTextChangeEvent
);
187 // AccTextChangeEvent
188 int32_t GetStartOffset() const { return mStart
; }
189 uint32_t GetLength() const { return mModifiedText
.Length(); }
190 bool IsTextInserted() const { return mIsInserted
; }
191 void GetModifiedText(nsAString
& aModifiedText
) {
192 aModifiedText
= mModifiedText
;
194 const nsString
& ModifiedText() const { return mModifiedText
; }
199 nsString mModifiedText
;
201 friend class EventTree
;
202 friend class NotificationController
;
206 * A base class for events related to tree mutation, either an AccMutation
207 * event, or an AccReorderEvent.
209 class AccTreeMutationEvent
: public AccEvent
{
211 AccTreeMutationEvent(uint32_t aEventType
, LocalAccessible
* aTarget
)
212 : AccEvent(aEventType
, aTarget
, eAutoDetect
, eCoalesceReorder
),
216 static const EventGroup kEventGroup
= eTreeMutationEvent
;
217 virtual unsigned int GetEventGroups() const override
{
218 return AccEvent::GetEventGroups() | (1U << eTreeMutationEvent
);
221 void SetNextEvent(AccTreeMutationEvent
* aNext
) { mNextEvent
= aNext
; }
222 void SetPrevEvent(AccTreeMutationEvent
* aPrev
) { mPrevEvent
= aPrev
; }
223 AccTreeMutationEvent
* NextEvent() const { return mNextEvent
; }
224 AccTreeMutationEvent
* PrevEvent() const { return mPrevEvent
; }
227 * A sequence number to know when this event was fired.
229 uint32_t EventGeneration() const { return mGeneration
; }
230 void SetEventGeneration(uint32_t aGeneration
) { mGeneration
= aGeneration
; }
233 RefPtr
<AccTreeMutationEvent
> mNextEvent
;
234 RefPtr
<AccTreeMutationEvent
> mPrevEvent
;
235 uint32_t mGeneration
;
239 * Base class for show and hide accessible events.
241 class AccMutationEvent
: public AccTreeMutationEvent
{
243 AccMutationEvent(uint32_t aEventType
, LocalAccessible
* aTarget
)
244 : AccTreeMutationEvent(aEventType
, aTarget
) {
245 // Don't coalesce these since they are coalesced by reorder event. Coalesce
246 // contained text change events.
247 mParent
= mAccessible
->LocalParent();
249 virtual ~AccMutationEvent() {}
252 static const EventGroup kEventGroup
= eMutationEvent
;
253 virtual unsigned int GetEventGroups() const override
{
254 return AccTreeMutationEvent::GetEventGroups() | (1U << eMutationEvent
);
258 bool IsShow() const { return mEventType
== nsIAccessibleEvent::EVENT_SHOW
; }
259 bool IsHide() const { return mEventType
== nsIAccessibleEvent::EVENT_HIDE
; }
261 LocalAccessible
* LocalParent() const { return mParent
; }
264 nsCOMPtr
<nsINode
> mNode
;
265 RefPtr
<LocalAccessible
> mParent
;
266 RefPtr
<AccTextChangeEvent
> mTextChangeEvent
;
268 friend class EventTree
;
269 friend class NotificationController
;
273 * Accessible hide event.
275 class AccHideEvent
: public AccMutationEvent
{
277 explicit AccHideEvent(LocalAccessible
* aTarget
, bool aNeedsShutdown
= true);
280 static const EventGroup kEventGroup
= eHideEvent
;
281 virtual unsigned int GetEventGroups() const override
{
282 return AccMutationEvent::GetEventGroups() | (1U << eHideEvent
);
286 LocalAccessible
* TargetParent() const { return mParent
; }
287 LocalAccessible
* TargetNextSibling() const { return mNextSibling
; }
288 LocalAccessible
* TargetPrevSibling() const { return mPrevSibling
; }
289 bool NeedsShutdown() const { return mNeedsShutdown
; }
293 RefPtr
<LocalAccessible
> mNextSibling
;
294 RefPtr
<LocalAccessible
> mPrevSibling
;
296 friend class EventTree
;
297 friend class NotificationController
;
301 * Accessible show event.
303 class AccShowEvent
: public AccMutationEvent
{
305 explicit AccShowEvent(LocalAccessible
* aTarget
);
308 static const EventGroup kEventGroup
= eShowEvent
;
309 virtual unsigned int GetEventGroups() const override
{
310 return AccMutationEvent::GetEventGroups() | (1U << eShowEvent
);
313 uint32_t InsertionIndex() const { return mInsertionIndex
; }
316 nsTArray
<RefPtr
<AccHideEvent
>> mPrecedingEvents
;
317 uint32_t mInsertionIndex
;
319 friend class EventTree
;
323 * Class for reorder accessible event. Takes care about
325 class AccReorderEvent
: public AccTreeMutationEvent
{
327 explicit AccReorderEvent(LocalAccessible
* aTarget
)
328 : AccTreeMutationEvent(::nsIAccessibleEvent::EVENT_REORDER
, aTarget
) {}
329 virtual ~AccReorderEvent() {}
332 static const EventGroup kEventGroup
= eReorderEvent
;
333 virtual unsigned int GetEventGroups() const override
{
334 return AccTreeMutationEvent::GetEventGroups() | (1U << eReorderEvent
);
339 * Accessible caret move event.
341 class AccCaretMoveEvent
: public AccEvent
{
343 AccCaretMoveEvent(LocalAccessible
* aAccessible
, int32_t aCaretOffset
,
344 bool aIsSelectionCollapsed
,
345 EIsFromUserInput aIsFromUserInput
= eAutoDetect
)
346 : AccEvent(::nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED
, aAccessible
,
348 mCaretOffset(aCaretOffset
),
349 mIsSelectionCollapsed(aIsSelectionCollapsed
) {}
350 virtual ~AccCaretMoveEvent() {}
353 static const EventGroup kEventGroup
= eCaretMoveEvent
;
354 virtual unsigned int GetEventGroups() const override
{
355 return AccEvent::GetEventGroups() | (1U << eCaretMoveEvent
);
359 int32_t GetCaretOffset() const { return mCaretOffset
; }
361 bool IsSelectionCollapsed() const { return mIsSelectionCollapsed
; }
364 int32_t mCaretOffset
;
366 bool mIsSelectionCollapsed
;
370 * Accessible text selection change event.
372 class AccTextSelChangeEvent
: public AccEvent
{
374 AccTextSelChangeEvent(HyperTextAccessible
* aTarget
,
375 dom::Selection
* aSelection
, int32_t aReason
);
376 virtual ~AccTextSelChangeEvent();
379 static const EventGroup kEventGroup
= eTextSelChangeEvent
;
380 virtual unsigned int GetEventGroups() const override
{
381 return AccEvent::GetEventGroups() | (1U << eTextSelChangeEvent
);
384 // AccTextSelChangeEvent
387 * Return true if the text selection change wasn't caused by pure caret move.
389 bool IsCaretMoveOnly() const;
392 * Return selection ranges in document/control.
394 void SelectionRanges(nsTArray
<a11y::TextRange
>* aRanges
) const;
397 RefPtr
<dom::Selection
> mSel
;
400 friend class EventQueue
;
401 friend class SelectionManager
;
405 * Accessible widget selection change event.
407 class AccSelChangeEvent
: public AccEvent
{
409 enum SelChangeType
{ eSelectionAdd
, eSelectionRemove
};
411 AccSelChangeEvent(LocalAccessible
* aWidget
, LocalAccessible
* aItem
,
412 SelChangeType aSelChangeType
);
414 virtual ~AccSelChangeEvent() {}
417 static const EventGroup kEventGroup
= eSelectionChangeEvent
;
418 virtual unsigned int GetEventGroups() const override
{
419 return AccEvent::GetEventGroups() | (1U << eSelectionChangeEvent
);
423 LocalAccessible
* Widget() const { return mWidget
; }
426 RefPtr
<LocalAccessible
> mWidget
;
427 RefPtr
<LocalAccessible
> mItem
;
428 SelChangeType mSelChangeType
;
429 uint32_t mPreceedingCount
;
430 AccSelChangeEvent
* mPackedEvent
;
432 friend class EventQueue
;
436 * Accessible table change event.
438 class AccTableChangeEvent
: public AccEvent
{
440 AccTableChangeEvent(LocalAccessible
* aAccessible
, uint32_t aEventType
,
441 int32_t aRowOrColIndex
, int32_t aNumRowsOrCols
);
444 static const EventGroup kEventGroup
= eTableChangeEvent
;
445 virtual unsigned int GetEventGroups() const override
{
446 return AccEvent::GetEventGroups() | (1U << eTableChangeEvent
);
449 // AccTableChangeEvent
450 uint32_t GetIndex() const { return mRowOrColIndex
; }
451 uint32_t GetCount() const { return mNumRowsOrCols
; }
454 uint32_t mRowOrColIndex
; // the start row/column after which the rows are
456 uint32_t mNumRowsOrCols
; // the number of inserted/deleted rows/columns
460 * Accessible virtual cursor change event.
462 class AccVCChangeEvent
: public AccEvent
{
464 AccVCChangeEvent(LocalAccessible
* aAccessible
,
465 LocalAccessible
* aOldAccessible
, int32_t aOldStart
,
466 int32_t aOldEnd
, LocalAccessible
* aNewAccessible
,
467 int32_t aNewStart
, int32_t aNewEnd
, int16_t aReason
,
468 int16_t aBoundaryType
,
469 EIsFromUserInput aIsFromUserInput
= eFromUserInput
);
471 virtual ~AccVCChangeEvent() {}
474 static const EventGroup kEventGroup
= eVirtualCursorChangeEvent
;
475 virtual unsigned int GetEventGroups() const override
{
476 return AccEvent::GetEventGroups() | (1U << eVirtualCursorChangeEvent
);
480 LocalAccessible
* OldAccessible() const { return mOldAccessible
; }
481 int32_t OldStartOffset() const { return mOldStart
; }
482 int32_t OldEndOffset() const { return mOldEnd
; }
483 LocalAccessible
* NewAccessible() const { return mNewAccessible
; }
484 int32_t NewStartOffset() const { return mNewStart
; }
485 int32_t NewEndOffset() const { return mNewEnd
; }
486 int32_t Reason() const { return mReason
; }
487 int32_t BoundaryType() const { return mBoundaryType
; }
490 RefPtr
<LocalAccessible
> mOldAccessible
;
491 RefPtr
<LocalAccessible
> mNewAccessible
;
497 int16_t mBoundaryType
;
501 * Accessible object attribute changed event.
503 class AccObjectAttrChangedEvent
: public AccEvent
{
505 AccObjectAttrChangedEvent(LocalAccessible
* aAccessible
, nsAtom
* aAttribute
)
506 : AccEvent(::nsIAccessibleEvent::EVENT_OBJECT_ATTRIBUTE_CHANGED
,
508 mAttribute(aAttribute
) {}
511 static const EventGroup kEventGroup
= eObjectAttrChangedEvent
;
512 virtual unsigned int GetEventGroups() const override
{
513 return AccEvent::GetEventGroups() | (1U << eObjectAttrChangedEvent
);
516 // AccObjectAttrChangedEvent
517 nsAtom
* GetAttribute() const { return mAttribute
; }
520 RefPtr
<nsAtom
> mAttribute
;
522 virtual ~AccObjectAttrChangedEvent() {}
526 * Accessible scroll event.
528 class AccScrollingEvent
: public AccEvent
{
530 AccScrollingEvent(uint32_t aEventType
, LocalAccessible
* aAccessible
,
531 uint32_t aScrollX
, uint32_t aScrollY
, uint32_t aMaxScrollX
,
532 uint32_t aMaxScrollY
)
533 : AccEvent(aEventType
, aAccessible
),
536 mMaxScrollX(aMaxScrollX
),
537 mMaxScrollY(aMaxScrollY
) {}
539 virtual ~AccScrollingEvent() {}
542 static const EventGroup kEventGroup
= eScrollingEvent
;
543 virtual unsigned int GetEventGroups() const override
{
544 return AccEvent::GetEventGroups() | (1U << eScrollingEvent
);
547 // The X scrolling offset of the container when the event was fired.
548 uint32_t ScrollX() { return mScrollX
; }
549 // The Y scrolling offset of the container when the event was fired.
550 uint32_t ScrollY() { return mScrollY
; }
551 // The max X offset of the container.
552 uint32_t MaxScrollX() { return mMaxScrollX
; }
553 // The max Y offset of the container.
554 uint32_t MaxScrollY() { return mMaxScrollY
; }
559 uint32_t mMaxScrollX
;
560 uint32_t mMaxScrollY
;
564 * Accessible announcement event.
566 class AccAnnouncementEvent
: public AccEvent
{
568 AccAnnouncementEvent(LocalAccessible
* aAccessible
,
569 const nsAString
& aAnnouncement
, uint16_t aPriority
)
570 : AccEvent(nsIAccessibleEvent::EVENT_ANNOUNCEMENT
, aAccessible
),
571 mAnnouncement(aAnnouncement
),
572 mPriority(aPriority
) {}
574 virtual ~AccAnnouncementEvent() {}
577 static const EventGroup kEventGroup
= eAnnouncementEvent
;
578 virtual unsigned int GetEventGroups() const override
{
579 return AccEvent::GetEventGroups() | (1U << eAnnouncementEvent
);
582 const nsString
& Announcement() const { return mAnnouncement
; }
584 uint16_t Priority() { return mPriority
; }
587 nsString mAnnouncement
;
592 * Downcast the generic accessible event object to derived type.
594 class downcast_accEvent
{
596 explicit downcast_accEvent(AccEvent
* e
) : mRawPtr(e
) {}
598 template <class Destination
>
599 operator Destination
*() {
600 if (!mRawPtr
) return nullptr;
602 return mRawPtr
->GetEventGroups() & (1U << Destination::kEventGroup
)
603 ? static_cast<Destination
*>(mRawPtr
)
612 * Return a new xpcom accessible event for the given internal one.
614 already_AddRefed
<nsIAccessibleEvent
> MakeXPCEvent(AccEvent
* aEvent
);
617 } // namespace mozilla