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 RefPtr
<LocalAccessible
> mParent
;
265 RefPtr
<AccTextChangeEvent
> mTextChangeEvent
;
267 friend class EventTree
;
268 friend class NotificationController
;
272 * Accessible hide event.
274 class AccHideEvent
: public AccMutationEvent
{
276 explicit AccHideEvent(LocalAccessible
* aTarget
, bool aNeedsShutdown
= true);
279 static const EventGroup kEventGroup
= eHideEvent
;
280 virtual unsigned int GetEventGroups() const override
{
281 return AccMutationEvent::GetEventGroups() | (1U << eHideEvent
);
285 LocalAccessible
* TargetParent() const { return mParent
; }
286 LocalAccessible
* TargetNextSibling() const { return mNextSibling
; }
287 LocalAccessible
* TargetPrevSibling() const { return mPrevSibling
; }
288 bool NeedsShutdown() const { return mNeedsShutdown
; }
292 RefPtr
<LocalAccessible
> mNextSibling
;
293 RefPtr
<LocalAccessible
> mPrevSibling
;
295 friend class EventTree
;
296 friend class NotificationController
;
300 * Accessible show event.
302 class AccShowEvent
: public AccMutationEvent
{
304 explicit AccShowEvent(LocalAccessible
* aTarget
)
305 : AccMutationEvent(::nsIAccessibleEvent::EVENT_SHOW
, aTarget
) {}
308 static const EventGroup kEventGroup
= eShowEvent
;
309 virtual unsigned int GetEventGroups() const override
{
310 return AccMutationEvent::GetEventGroups() | (1U << eShowEvent
);
315 * Class for reorder accessible event. Takes care about
317 class AccReorderEvent
: public AccTreeMutationEvent
{
319 explicit AccReorderEvent(LocalAccessible
* aTarget
)
320 : AccTreeMutationEvent(::nsIAccessibleEvent::EVENT_REORDER
, aTarget
) {}
321 virtual ~AccReorderEvent() {}
324 static const EventGroup kEventGroup
= eReorderEvent
;
325 virtual unsigned int GetEventGroups() const override
{
326 return AccTreeMutationEvent::GetEventGroups() | (1U << eReorderEvent
);
330 * Make this an inner reorder event that is coalesced into
331 * a reorder event of an ancestor.
333 void SetInner() { mEventType
= ::nsIAccessibleEvent::EVENT_INNER_REORDER
; }
337 * Accessible caret move event.
339 class AccCaretMoveEvent
: public AccEvent
{
341 AccCaretMoveEvent(LocalAccessible
* aAccessible
, int32_t aCaretOffset
,
342 bool aIsSelectionCollapsed
, bool aIsAtEndOfLine
,
343 int32_t aGranularity
,
344 EIsFromUserInput aIsFromUserInput
= eAutoDetect
)
345 : AccEvent(::nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED
, aAccessible
,
347 mCaretOffset(aCaretOffset
),
348 mIsSelectionCollapsed(aIsSelectionCollapsed
),
349 mIsAtEndOfLine(aIsAtEndOfLine
),
350 mGranularity(aGranularity
) {}
351 virtual ~AccCaretMoveEvent() {}
354 static const EventGroup kEventGroup
= eCaretMoveEvent
;
355 virtual unsigned int GetEventGroups() const override
{
356 return AccEvent::GetEventGroups() | (1U << eCaretMoveEvent
);
360 int32_t GetCaretOffset() const { return mCaretOffset
; }
362 bool IsSelectionCollapsed() const { return mIsSelectionCollapsed
; }
363 bool IsAtEndOfLine() { return mIsAtEndOfLine
; }
365 int32_t GetGranularity() const { return mGranularity
; }
368 int32_t mCaretOffset
;
370 bool mIsSelectionCollapsed
;
372 int32_t mGranularity
;
376 * Accessible text selection change event.
378 class AccTextSelChangeEvent
: public AccEvent
{
380 AccTextSelChangeEvent(HyperTextAccessible
* aTarget
,
381 dom::Selection
* aSelection
, int32_t aReason
,
382 int32_t aGranularity
);
383 virtual ~AccTextSelChangeEvent();
386 static const EventGroup kEventGroup
= eTextSelChangeEvent
;
387 virtual unsigned int GetEventGroups() const override
{
388 return AccEvent::GetEventGroups() | (1U << eTextSelChangeEvent
);
391 // AccTextSelChangeEvent
394 * Return true if the text selection change wasn't caused by pure caret move.
396 bool IsCaretMoveOnly() const;
398 int32_t GetGranularity() const { return mGranularity
; }
401 * Return selection ranges in document/control.
403 void SelectionRanges(nsTArray
<a11y::TextRange
>* aRanges
) const;
406 RefPtr
<dom::Selection
> mSel
;
408 int32_t mGranularity
;
410 friend class EventQueue
;
411 friend class SelectionManager
;
415 * Accessible widget selection change event.
417 class AccSelChangeEvent
: public AccEvent
{
419 enum SelChangeType
{ eSelectionAdd
, eSelectionRemove
};
421 AccSelChangeEvent(LocalAccessible
* aWidget
, LocalAccessible
* aItem
,
422 SelChangeType aSelChangeType
);
424 virtual ~AccSelChangeEvent() {}
427 static const EventGroup kEventGroup
= eSelectionChangeEvent
;
428 virtual unsigned int GetEventGroups() const override
{
429 return AccEvent::GetEventGroups() | (1U << eSelectionChangeEvent
);
433 LocalAccessible
* Widget() const { return mWidget
; }
436 RefPtr
<LocalAccessible
> mWidget
;
437 RefPtr
<LocalAccessible
> mItem
;
438 SelChangeType mSelChangeType
;
439 uint32_t mPreceedingCount
;
440 AccSelChangeEvent
* mPackedEvent
;
442 friend class EventQueue
;
446 * Accessible table change event.
448 class AccTableChangeEvent
: public AccEvent
{
450 AccTableChangeEvent(LocalAccessible
* aAccessible
, uint32_t aEventType
,
451 int32_t aRowOrColIndex
, int32_t aNumRowsOrCols
);
454 static const EventGroup kEventGroup
= eTableChangeEvent
;
455 virtual unsigned int GetEventGroups() const override
{
456 return AccEvent::GetEventGroups() | (1U << eTableChangeEvent
);
459 // AccTableChangeEvent
460 uint32_t GetIndex() const { return mRowOrColIndex
; }
461 uint32_t GetCount() const { return mNumRowsOrCols
; }
464 uint32_t mRowOrColIndex
; // the start row/column after which the rows are
466 uint32_t mNumRowsOrCols
; // the number of inserted/deleted rows/columns
470 * Accessible virtual cursor change event.
472 class AccVCChangeEvent
: public AccEvent
{
474 AccVCChangeEvent(LocalAccessible
* aAccessible
,
475 LocalAccessible
* aOldAccessible
,
476 LocalAccessible
* aNewAccessible
, int16_t aReason
,
477 EIsFromUserInput aIsFromUserInput
= eFromUserInput
);
479 virtual ~AccVCChangeEvent() {}
482 static const EventGroup kEventGroup
= eVirtualCursorChangeEvent
;
483 virtual unsigned int GetEventGroups() const override
{
484 return AccEvent::GetEventGroups() | (1U << eVirtualCursorChangeEvent
);
488 LocalAccessible
* OldAccessible() const { return mOldAccessible
; }
489 LocalAccessible
* NewAccessible() const { return mNewAccessible
; }
490 int32_t Reason() const { return mReason
; }
493 RefPtr
<LocalAccessible
> mOldAccessible
;
494 RefPtr
<LocalAccessible
> mNewAccessible
;
499 * Accessible object attribute changed event.
501 class AccObjectAttrChangedEvent
: public AccEvent
{
503 AccObjectAttrChangedEvent(LocalAccessible
* aAccessible
, nsAtom
* aAttribute
)
504 : AccEvent(::nsIAccessibleEvent::EVENT_OBJECT_ATTRIBUTE_CHANGED
,
506 mAttribute(aAttribute
) {}
509 static const EventGroup kEventGroup
= eObjectAttrChangedEvent
;
510 virtual unsigned int GetEventGroups() const override
{
511 return AccEvent::GetEventGroups() | (1U << eObjectAttrChangedEvent
);
514 // AccObjectAttrChangedEvent
515 nsAtom
* GetAttribute() const { return mAttribute
; }
518 RefPtr
<nsAtom
> mAttribute
;
520 virtual ~AccObjectAttrChangedEvent() {}
524 * Accessible scroll event.
526 class AccScrollingEvent
: public AccEvent
{
528 AccScrollingEvent(uint32_t aEventType
, LocalAccessible
* aAccessible
,
529 uint32_t aScrollX
, uint32_t aScrollY
, uint32_t aMaxScrollX
,
530 uint32_t aMaxScrollY
)
531 : AccEvent(aEventType
, aAccessible
),
534 mMaxScrollX(aMaxScrollX
),
535 mMaxScrollY(aMaxScrollY
) {}
537 virtual ~AccScrollingEvent() {}
540 static const EventGroup kEventGroup
= eScrollingEvent
;
541 virtual unsigned int GetEventGroups() const override
{
542 return AccEvent::GetEventGroups() | (1U << eScrollingEvent
);
545 // The X scrolling offset of the container when the event was fired.
546 uint32_t ScrollX() { return mScrollX
; }
547 // The Y scrolling offset of the container when the event was fired.
548 uint32_t ScrollY() { return mScrollY
; }
549 // The max X offset of the container.
550 uint32_t MaxScrollX() { return mMaxScrollX
; }
551 // The max Y offset of the container.
552 uint32_t MaxScrollY() { return mMaxScrollY
; }
557 uint32_t mMaxScrollX
;
558 uint32_t mMaxScrollY
;
562 * Accessible announcement event.
564 class AccAnnouncementEvent
: public AccEvent
{
566 AccAnnouncementEvent(LocalAccessible
* aAccessible
,
567 const nsAString
& aAnnouncement
, uint16_t aPriority
)
568 : AccEvent(nsIAccessibleEvent::EVENT_ANNOUNCEMENT
, aAccessible
),
569 mAnnouncement(aAnnouncement
),
570 mPriority(aPriority
) {}
572 virtual ~AccAnnouncementEvent() {}
575 static const EventGroup kEventGroup
= eAnnouncementEvent
;
576 virtual unsigned int GetEventGroups() const override
{
577 return AccEvent::GetEventGroups() | (1U << eAnnouncementEvent
);
580 const nsString
& Announcement() const { return mAnnouncement
; }
582 uint16_t Priority() { return mPriority
; }
585 nsString mAnnouncement
;
590 * Downcast the generic accessible event object to derived type.
592 class downcast_accEvent
{
594 explicit downcast_accEvent(AccEvent
* e
) : mRawPtr(e
) {}
596 template <class Destination
>
597 operator Destination
*() {
598 if (!mRawPtr
) return nullptr;
600 return mRawPtr
->GetEventGroups() & (1U << Destination::kEventGroup
)
601 ? static_cast<Destination
*>(mRawPtr
)
610 * Return a new xpcom accessible event for the given internal one.
612 already_AddRefed
<nsIAccessibleEvent
> MakeXPCEvent(AccEvent
* aEvent
);
615 } // namespace mozilla