Bug 1733869 [wpt PR 30916] - Add a note about counterintuitive send_keys() code point...
[gecko.git] / accessible / base / AccEvent.h
bloba57ab1b290c13f2ec6218c89bb4dd86a295527cf
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/LocalAccessible.h"
13 class nsEventShell;
14 namespace mozilla {
16 namespace dom {
17 class Selection;
20 namespace a11y {
22 class DocAccessible;
23 class EventQueue;
24 class TextRange;
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
36 /**
37 * Generic accessible event.
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,
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 // eCoalesceOfSameType : For events of the same type, only the newest event
54 // will be processed.
55 eCoalesceOfSameType,
57 // eCoalesceSelectionChange: coalescence of selection change events.
58 eCoalesceSelectionChange,
60 // eCoalesceStateChange: coalesce state change events.
61 eCoalesceStateChange,
63 // eCoalesceTextSelChange: coalescence of text selection change events.
64 eCoalesceTextSelChange,
66 // eRemoveDupes : For repeat events, only the newest event in queue
67 // will be emitted.
68 eRemoveDupes,
70 // eDoNotEmit : This event is confirmed as a duplicate, do not emit it.
71 eDoNotEmit
74 // Initialize with an accessible.
75 AccEvent(uint32_t aEventType, LocalAccessible* aAccessible,
76 EIsFromUserInput aIsFromUserInput = eAutoDetect,
77 EEventRule aEventRule = eRemoveDupes);
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);
87 LocalAccessible* GetAccessible() const { return mAccessible; }
88 DocAccessible* Document() const { return mAccessible->Document(); }
90 /**
91 * Down casting.
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 eTableChangeEvent,
106 eVirtualCursorChangeEvent,
107 eObjectAttrChangedEvent,
108 eScrollingEvent,
109 eAnnouncementEvent,
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)
121 protected:
122 virtual ~AccEvent() {}
124 bool mIsFromUserInput;
125 uint32_t mEventType;
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 {
139 public:
140 AccStateChangeEvent(LocalAccessible* aAccessible, uint64_t aState,
141 bool aIsEnabled,
142 EIsFromUserInput aIsFromUserInput = eAutoDetect)
143 : AccEvent(nsIAccessibleEvent::EVENT_STATE_CHANGE, aAccessible,
144 aIsFromUserInput, eCoalesceStateChange),
145 mState(aState),
146 mIsEnabled(aIsEnabled) {}
148 AccStateChangeEvent(LocalAccessible* aAccessible, uint64_t aState)
149 : AccEvent(::nsIAccessibleEvent::EVENT_STATE_CHANGE, aAccessible,
150 eAutoDetect, eCoalesceStateChange),
151 mState(aState) {
152 mIsEnabled = (mAccessible->State() & mState) != 0;
155 // AccEvent
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; }
165 private:
166 uint64_t mState;
167 bool mIsEnabled;
169 friend class EventQueue;
173 * Accessible text change event.
175 class AccTextChangeEvent : public AccEvent {
176 public:
177 AccTextChangeEvent(LocalAccessible* aAccessible, int32_t aStart,
178 const nsAString& aModifiedText, bool aIsInserted,
179 EIsFromUserInput aIsFromUserInput = eAutoDetect);
181 // AccEvent
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; }
196 private:
197 int32_t mStart;
198 bool mIsInserted;
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 {
210 public:
211 AccTreeMutationEvent(uint32_t aEventType, LocalAccessible* aTarget)
212 : AccEvent(aEventType, aTarget, eAutoDetect, eCoalesceReorder),
213 mGeneration(0) {}
215 // Event
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; }
232 private:
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 {
242 public:
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() {}
251 // Event
252 static const EventGroup kEventGroup = eMutationEvent;
253 virtual unsigned int GetEventGroups() const override {
254 return AccTreeMutationEvent::GetEventGroups() | (1U << eMutationEvent);
257 // MutationEvent
258 bool IsShow() const { return mEventType == nsIAccessibleEvent::EVENT_SHOW; }
259 bool IsHide() const { return mEventType == nsIAccessibleEvent::EVENT_HIDE; }
261 LocalAccessible* LocalParent() const { return mParent; }
263 protected:
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 {
276 public:
277 explicit AccHideEvent(LocalAccessible* aTarget, bool aNeedsShutdown = true);
279 // Event
280 static const EventGroup kEventGroup = eHideEvent;
281 virtual unsigned int GetEventGroups() const override {
282 return AccMutationEvent::GetEventGroups() | (1U << eHideEvent);
285 // AccHideEvent
286 LocalAccessible* TargetParent() const { return mParent; }
287 LocalAccessible* TargetNextSibling() const { return mNextSibling; }
288 LocalAccessible* TargetPrevSibling() const { return mPrevSibling; }
289 bool NeedsShutdown() const { return mNeedsShutdown; }
291 protected:
292 bool 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 {
304 public:
305 explicit AccShowEvent(LocalAccessible* aTarget);
307 // Event
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; }
315 private:
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 {
326 public:
327 explicit AccReorderEvent(LocalAccessible* aTarget)
328 : AccTreeMutationEvent(::nsIAccessibleEvent::EVENT_REORDER, aTarget) {}
329 virtual ~AccReorderEvent() {}
331 // Event
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 {
342 public:
343 AccCaretMoveEvent(LocalAccessible* aAccessible, int32_t aCaretOffset,
344 bool aIsSelectionCollapsed,
345 EIsFromUserInput aIsFromUserInput = eAutoDetect)
346 : AccEvent(::nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED, aAccessible,
347 aIsFromUserInput),
348 mCaretOffset(aCaretOffset),
349 mIsSelectionCollapsed(aIsSelectionCollapsed) {}
350 virtual ~AccCaretMoveEvent() {}
352 // AccEvent
353 static const EventGroup kEventGroup = eCaretMoveEvent;
354 virtual unsigned int GetEventGroups() const override {
355 return AccEvent::GetEventGroups() | (1U << eCaretMoveEvent);
358 // AccCaretMoveEvent
359 int32_t GetCaretOffset() const { return mCaretOffset; }
361 bool IsSelectionCollapsed() const { return mIsSelectionCollapsed; }
363 private:
364 int32_t mCaretOffset;
366 bool mIsSelectionCollapsed;
370 * Accessible text selection change event.
372 class AccTextSelChangeEvent : public AccEvent {
373 public:
374 AccTextSelChangeEvent(HyperTextAccessible* aTarget,
375 dom::Selection* aSelection, int32_t aReason);
376 virtual ~AccTextSelChangeEvent();
378 // AccEvent
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;
396 private:
397 RefPtr<dom::Selection> mSel;
398 int32_t mReason;
400 friend class EventQueue;
401 friend class SelectionManager;
405 * Accessible widget selection change event.
407 class AccSelChangeEvent : public AccEvent {
408 public:
409 enum SelChangeType { eSelectionAdd, eSelectionRemove };
411 AccSelChangeEvent(LocalAccessible* aWidget, LocalAccessible* aItem,
412 SelChangeType aSelChangeType);
414 virtual ~AccSelChangeEvent() {}
416 // AccEvent
417 static const EventGroup kEventGroup = eSelectionChangeEvent;
418 virtual unsigned int GetEventGroups() const override {
419 return AccEvent::GetEventGroups() | (1U << eSelectionChangeEvent);
422 // AccSelChangeEvent
423 LocalAccessible* Widget() const { return mWidget; }
425 private:
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 {
439 public:
440 AccTableChangeEvent(LocalAccessible* aAccessible, uint32_t aEventType,
441 int32_t aRowOrColIndex, int32_t aNumRowsOrCols);
443 // AccEvent
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; }
453 private:
454 uint32_t mRowOrColIndex; // the start row/column after which the rows are
455 // inserted/deleted.
456 uint32_t mNumRowsOrCols; // the number of inserted/deleted rows/columns
460 * Accessible virtual cursor change event.
462 class AccVCChangeEvent : public AccEvent {
463 public:
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() {}
473 // AccEvent
474 static const EventGroup kEventGroup = eVirtualCursorChangeEvent;
475 virtual unsigned int GetEventGroups() const override {
476 return AccEvent::GetEventGroups() | (1U << eVirtualCursorChangeEvent);
479 // AccVCChangeEvent
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; }
489 private:
490 RefPtr<LocalAccessible> mOldAccessible;
491 RefPtr<LocalAccessible> mNewAccessible;
492 int32_t mOldStart;
493 int32_t mNewStart;
494 int32_t mOldEnd;
495 int32_t mNewEnd;
496 int16_t mReason;
497 int16_t mBoundaryType;
501 * Accessible object attribute changed event.
503 class AccObjectAttrChangedEvent : public AccEvent {
504 public:
505 AccObjectAttrChangedEvent(LocalAccessible* aAccessible, nsAtom* aAttribute)
506 : AccEvent(::nsIAccessibleEvent::EVENT_OBJECT_ATTRIBUTE_CHANGED,
507 aAccessible),
508 mAttribute(aAttribute) {}
510 // AccEvent
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; }
519 private:
520 RefPtr<nsAtom> mAttribute;
522 virtual ~AccObjectAttrChangedEvent() {}
526 * Accessible scroll event.
528 class AccScrollingEvent : public AccEvent {
529 public:
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),
534 mScrollX(aScrollX),
535 mScrollY(aScrollY),
536 mMaxScrollX(aMaxScrollX),
537 mMaxScrollY(aMaxScrollY) {}
539 virtual ~AccScrollingEvent() {}
541 // AccEvent
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; }
556 private:
557 uint32_t mScrollX;
558 uint32_t mScrollY;
559 uint32_t mMaxScrollX;
560 uint32_t mMaxScrollY;
564 * Accessible announcement event.
566 class AccAnnouncementEvent : public AccEvent {
567 public:
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() {}
576 // AccEvent
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; }
586 private:
587 nsString mAnnouncement;
588 uint16_t mPriority;
592 * Downcast the generic accessible event object to derived type.
594 class downcast_accEvent {
595 public:
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)
604 : nullptr;
607 private:
608 AccEvent* mRawPtr;
612 * Return a new xpcom accessible event for the given internal one.
614 already_AddRefed<nsIAccessibleEvent> MakeXPCEvent(AccEvent* aEvent);
616 } // namespace a11y
617 } // namespace mozilla
619 #endif