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
,
105 eObjectAttrChangedEvent
,
110 static const EventGroup kEventGroup
= eGenericEvent
;
111 virtual unsigned int GetEventGroups() const { return 1U << eGenericEvent
; }
114 * Reference counting and cycle collection.
116 NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(AccEvent
)
117 NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(AccEvent
)
120 virtual ~AccEvent() {}
122 bool mIsFromUserInput
;
124 EEventRule mEventRule
;
125 RefPtr
<LocalAccessible
> mAccessible
;
127 friend class EventQueue
;
128 friend class EventTree
;
129 friend class ::nsEventShell
;
130 friend class NotificationController
;
134 * Accessible state change event.
136 class AccStateChangeEvent
: public AccEvent
{
138 AccStateChangeEvent(LocalAccessible
* aAccessible
, uint64_t aState
,
140 EIsFromUserInput aIsFromUserInput
= eAutoDetect
)
141 : AccEvent(nsIAccessibleEvent::EVENT_STATE_CHANGE
, aAccessible
,
142 aIsFromUserInput
, eCoalesceStateChange
),
144 mIsEnabled(aIsEnabled
) {}
146 AccStateChangeEvent(LocalAccessible
* aAccessible
, uint64_t aState
)
147 : AccEvent(::nsIAccessibleEvent::EVENT_STATE_CHANGE
, aAccessible
,
148 eAutoDetect
, eCoalesceStateChange
),
150 mIsEnabled
= (mAccessible
->State() & mState
) != 0;
154 static const EventGroup kEventGroup
= eStateChangeEvent
;
155 virtual unsigned int GetEventGroups() const override
{
156 return AccEvent::GetEventGroups() | (1U << eStateChangeEvent
);
159 // AccStateChangeEvent
160 uint64_t GetState() const { return mState
; }
161 bool IsStateEnabled() const { return mIsEnabled
; }
167 friend class EventQueue
;
171 * Accessible text change event.
173 class AccTextChangeEvent
: public AccEvent
{
175 AccTextChangeEvent(LocalAccessible
* aAccessible
, int32_t aStart
,
176 const nsAString
& aModifiedText
, bool aIsInserted
,
177 EIsFromUserInput aIsFromUserInput
= eAutoDetect
);
180 static const EventGroup kEventGroup
= eTextChangeEvent
;
181 virtual unsigned int GetEventGroups() const override
{
182 return AccEvent::GetEventGroups() | (1U << eTextChangeEvent
);
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
;
192 const nsString
& ModifiedText() const { return mModifiedText
; }
197 nsString mModifiedText
;
199 friend class EventTree
;
200 friend class NotificationController
;
204 * A base class for events related to tree mutation, either an AccMutation
205 * event, or an AccReorderEvent.
207 class AccTreeMutationEvent
: public AccEvent
{
209 AccTreeMutationEvent(uint32_t aEventType
, LocalAccessible
* aTarget
)
210 : AccEvent(aEventType
, aTarget
, eAutoDetect
, eCoalesceReorder
),
214 static const EventGroup kEventGroup
= eTreeMutationEvent
;
215 virtual unsigned int GetEventGroups() const override
{
216 return AccEvent::GetEventGroups() | (1U << eTreeMutationEvent
);
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
; }
225 * A sequence number to know when this event was fired.
227 uint32_t EventGeneration() const { return mGeneration
; }
228 void SetEventGeneration(uint32_t aGeneration
) { mGeneration
= aGeneration
; }
231 RefPtr
<AccTreeMutationEvent
> mNextEvent
;
232 RefPtr
<AccTreeMutationEvent
> mPrevEvent
;
233 uint32_t mGeneration
;
237 * Base class for show and hide accessible events.
239 class AccMutationEvent
: public AccTreeMutationEvent
{
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();
247 virtual ~AccMutationEvent() {}
250 static const EventGroup kEventGroup
= eMutationEvent
;
251 virtual unsigned int GetEventGroups() const override
{
252 return AccTreeMutationEvent::GetEventGroups() | (1U << eMutationEvent
);
256 bool IsShow() const { return mEventType
== nsIAccessibleEvent::EVENT_SHOW
; }
257 bool IsHide() const { return mEventType
== nsIAccessibleEvent::EVENT_HIDE
; }
259 LocalAccessible
* LocalParent() const { return mParent
; }
262 RefPtr
<LocalAccessible
> mParent
;
263 RefPtr
<AccTextChangeEvent
> mTextChangeEvent
;
265 friend class EventTree
;
266 friend class NotificationController
;
270 * Accessible hide event.
272 class AccHideEvent
: public AccMutationEvent
{
274 explicit AccHideEvent(LocalAccessible
* aTarget
, bool aNeedsShutdown
= true);
277 static const EventGroup kEventGroup
= eHideEvent
;
278 virtual unsigned int GetEventGroups() const override
{
279 return AccMutationEvent::GetEventGroups() | (1U << eHideEvent
);
283 LocalAccessible
* TargetParent() const { return mParent
; }
284 LocalAccessible
* TargetNextSibling() const { return mNextSibling
; }
285 LocalAccessible
* TargetPrevSibling() const { return mPrevSibling
; }
286 bool NeedsShutdown() const { return mNeedsShutdown
; }
290 RefPtr
<LocalAccessible
> mNextSibling
;
291 RefPtr
<LocalAccessible
> mPrevSibling
;
293 friend class EventTree
;
294 friend class NotificationController
;
298 * Accessible show event.
300 class AccShowEvent
: public AccMutationEvent
{
302 explicit AccShowEvent(LocalAccessible
* aTarget
)
303 : AccMutationEvent(::nsIAccessibleEvent::EVENT_SHOW
, aTarget
) {}
306 static const EventGroup kEventGroup
= eShowEvent
;
307 virtual unsigned int GetEventGroups() const override
{
308 return AccMutationEvent::GetEventGroups() | (1U << eShowEvent
);
313 * Class for reorder accessible event. Takes care about
315 class AccReorderEvent
: public AccTreeMutationEvent
{
317 explicit AccReorderEvent(LocalAccessible
* aTarget
)
318 : AccTreeMutationEvent(::nsIAccessibleEvent::EVENT_REORDER
, aTarget
) {}
319 virtual ~AccReorderEvent() {}
322 static const EventGroup kEventGroup
= eReorderEvent
;
323 virtual unsigned int GetEventGroups() const override
{
324 return AccTreeMutationEvent::GetEventGroups() | (1U << eReorderEvent
);
328 * Make this an inner reorder event that is coalesced into
329 * a reorder event of an ancestor.
331 void SetInner() { mEventType
= ::nsIAccessibleEvent::EVENT_INNER_REORDER
; }
335 * Accessible caret move event.
337 class AccCaretMoveEvent
: public AccEvent
{
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
,
345 mCaretOffset(aCaretOffset
),
346 mIsSelectionCollapsed(aIsSelectionCollapsed
),
347 mIsAtEndOfLine(aIsAtEndOfLine
),
348 mGranularity(aGranularity
) {}
349 virtual ~AccCaretMoveEvent() {}
352 static const EventGroup kEventGroup
= eCaretMoveEvent
;
353 virtual unsigned int GetEventGroups() const override
{
354 return AccEvent::GetEventGroups() | (1U << eCaretMoveEvent
);
358 int32_t GetCaretOffset() const { return mCaretOffset
; }
360 bool IsSelectionCollapsed() const { return mIsSelectionCollapsed
; }
361 bool IsAtEndOfLine() { return mIsAtEndOfLine
; }
363 int32_t GetGranularity() const { return mGranularity
; }
366 int32_t mCaretOffset
;
368 bool mIsSelectionCollapsed
;
370 int32_t mGranularity
;
374 * Accessible text selection change event.
376 class AccTextSelChangeEvent
: public AccEvent
{
378 AccTextSelChangeEvent(HyperTextAccessible
* aTarget
,
379 dom::Selection
* aSelection
, int32_t aReason
,
380 int32_t aGranularity
);
381 virtual ~AccTextSelChangeEvent();
384 static const EventGroup kEventGroup
= eTextSelChangeEvent
;
385 virtual unsigned int GetEventGroups() const override
{
386 return AccEvent::GetEventGroups() | (1U << eTextSelChangeEvent
);
389 // AccTextSelChangeEvent
392 * Return true if the text selection change wasn't caused by pure caret move.
394 bool IsCaretMoveOnly() const;
396 int32_t GetGranularity() const { return mGranularity
; }
399 * Return selection ranges in document/control.
401 void SelectionRanges(nsTArray
<a11y::TextRange
>* aRanges
) const;
404 RefPtr
<dom::Selection
> mSel
;
406 int32_t mGranularity
;
408 friend class EventQueue
;
409 friend class SelectionManager
;
413 * Accessible widget selection change event.
415 class AccSelChangeEvent
: public AccEvent
{
417 enum SelChangeType
{ eSelectionAdd
, eSelectionRemove
};
419 AccSelChangeEvent(LocalAccessible
* aWidget
, LocalAccessible
* aItem
,
420 SelChangeType aSelChangeType
);
422 virtual ~AccSelChangeEvent() {}
425 static const EventGroup kEventGroup
= eSelectionChangeEvent
;
426 virtual unsigned int GetEventGroups() const override
{
427 return AccEvent::GetEventGroups() | (1U << eSelectionChangeEvent
);
431 LocalAccessible
* Widget() const { return mWidget
; }
434 RefPtr
<LocalAccessible
> mWidget
;
435 RefPtr
<LocalAccessible
> mItem
;
436 SelChangeType mSelChangeType
;
437 uint32_t mPreceedingCount
;
438 AccSelChangeEvent
* mPackedEvent
;
440 friend class EventQueue
;
444 * Accessible object attribute changed event.
446 class AccObjectAttrChangedEvent
: public AccEvent
{
448 AccObjectAttrChangedEvent(LocalAccessible
* aAccessible
, nsAtom
* aAttribute
)
449 : AccEvent(::nsIAccessibleEvent::EVENT_OBJECT_ATTRIBUTE_CHANGED
,
451 mAttribute(aAttribute
) {}
454 static const EventGroup kEventGroup
= eObjectAttrChangedEvent
;
455 virtual unsigned int GetEventGroups() const override
{
456 return AccEvent::GetEventGroups() | (1U << eObjectAttrChangedEvent
);
459 // AccObjectAttrChangedEvent
460 nsAtom
* GetAttribute() const { return mAttribute
; }
463 RefPtr
<nsAtom
> mAttribute
;
465 virtual ~AccObjectAttrChangedEvent() {}
469 * Accessible scroll event.
471 class AccScrollingEvent
: public AccEvent
{
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
),
479 mMaxScrollX(aMaxScrollX
),
480 mMaxScrollY(aMaxScrollY
) {}
482 virtual ~AccScrollingEvent() {}
485 static const EventGroup kEventGroup
= eScrollingEvent
;
486 virtual unsigned int GetEventGroups() const override
{
487 return AccEvent::GetEventGroups() | (1U << eScrollingEvent
);
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
; }
502 uint32_t mMaxScrollX
;
503 uint32_t mMaxScrollY
;
507 * Accessible announcement event.
509 class AccAnnouncementEvent
: public AccEvent
{
511 AccAnnouncementEvent(LocalAccessible
* aAccessible
,
512 const nsAString
& aAnnouncement
, uint16_t aPriority
)
513 : AccEvent(nsIAccessibleEvent::EVENT_ANNOUNCEMENT
, aAccessible
),
514 mAnnouncement(aAnnouncement
),
515 mPriority(aPriority
) {}
517 virtual ~AccAnnouncementEvent() {}
520 static const EventGroup kEventGroup
= eAnnouncementEvent
;
521 virtual unsigned int GetEventGroups() const override
{
522 return AccEvent::GetEventGroups() | (1U << eAnnouncementEvent
);
525 const nsString
& Announcement() const { return mAnnouncement
; }
527 uint16_t Priority() { return mPriority
; }
530 nsString mAnnouncement
;
535 * Downcast the generic accessible event object to derived type.
537 class downcast_accEvent
{
539 explicit downcast_accEvent(AccEvent
* e
) : mRawPtr(e
) {}
541 template <class Destination
>
542 operator Destination
*() {
543 if (!mRawPtr
) return nullptr;
545 return mRawPtr
->GetEventGroups() & (1U << Destination::kEventGroup
)
546 ? static_cast<Destination
*>(mRawPtr
)
555 * Return a new xpcom accessible event for the given internal one.
557 already_AddRefed
<nsIAccessibleEvent
> MakeXPCEvent(AccEvent
* aEvent
);
560 } // namespace mozilla