Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dist/include/AccEvent.h
Line
Count
Source (jump to first uncovered line)
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/. */
5
6
#ifndef _AccEvent_H_
7
#define _AccEvent_H_
8
9
#include "nsIAccessibleEvent.h"
10
11
#include "mozilla/a11y/Accessible.h"
12
13
class nsEventShell;
14
namespace mozilla {
15
16
namespace dom {
17
class Selection;
18
}
19
20
namespace a11y {
21
22
class DocAccessible;
23
24
// Constants used to point whether the event is from user input.
25
enum EIsFromUserInput
26
{
27
  // eNoUserInput: event is not from user input
28
  eNoUserInput = 0,
29
  // eFromUserInput: event is from user input
30
  eFromUserInput = 1,
31
  // eAutoDetect: the value should be obtained from event state manager
32
  eAutoDetect = -1
33
};
34
35
/**
36
 * Generic accessible event.
37
 */
38
class AccEvent
39
{
40
public:
41
42
  // Rule for accessible events.
43
  // The rule will be applied when flushing pending events.
44
  enum EEventRule {
45
    // eAllowDupes : More than one event of the same type is allowed.
46
    //    This event will always be emitted. This flag is used for events that
47
    //    don't support coalescence.
48
    eAllowDupes,
49
50
     // eCoalesceReorder : For reorder events from the same subtree or the same
51
     //    node, only the umbrella event on the ancestor will be emitted.
52
    eCoalesceReorder,
53
54
    // eCoalesceOfSameType : For events of the same type, only the newest event
55
    // will be processed.
56
    eCoalesceOfSameType,
57
58
    // eCoalesceSelectionChange: coalescence of selection change events.
59
    eCoalesceSelectionChange,
60
61
    // eCoalesceStateChange: coalesce state change events.
62
    eCoalesceStateChange,
63
64
    // eCoalesceTextSelChange: coalescence of text selection change events.
65
    eCoalesceTextSelChange,
66
67
     // eRemoveDupes : For repeat events, only the newest event in queue
68
     //    will be emitted.
69
    eRemoveDupes,
70
71
     // eDoNotEmit : This event is confirmed as a duplicate, do not emit it.
72
    eDoNotEmit
73
  };
74
75
  // Initialize with an accessible.
76
  AccEvent(uint32_t aEventType, Accessible* aAccessible,
77
           EIsFromUserInput aIsFromUserInput = eAutoDetect,
78
           EEventRule aEventRule = eRemoveDupes);
79
80
  // AccEvent
81
  uint32_t GetEventType() const { return mEventType; }
82
0
  EEventRule GetEventRule() const { return mEventRule; }
83
  bool IsFromUserInput() const { return mIsFromUserInput; }
84
  EIsFromUserInput FromUserInput() const
85
    { return static_cast<EIsFromUserInput>(mIsFromUserInput); }
86
87
  Accessible* GetAccessible() const { return mAccessible; }
88
  DocAccessible* Document() const { return mAccessible->Document(); }
89
90
  /**
91
   * Down casting.
92
   */
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
  };
110
111
  static const EventGroup kEventGroup = eGenericEvent;
112
  virtual unsigned int GetEventGroups() const
113
  {
114
    return 1U << eGenericEvent;
115
  }
116
117
  /**
118
   * Reference counting and cycle collection.
119
   */
120
  NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(AccEvent)
121
  NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(AccEvent)
122
123
protected:
124
  virtual ~AccEvent() {}
125
126
  bool mIsFromUserInput;
127
  uint32_t mEventType;
128
  EEventRule mEventRule;
129
  RefPtr<Accessible> mAccessible;
130
131
  friend class EventQueue;
132
  friend class EventTree;
133
  friend class ::nsEventShell;
134
  friend class NotificationController;
135
};
136
137
138
/**
139
 * Accessible state change event.
140
 */
141
class AccStateChangeEvent: public AccEvent
142
{
143
public:
144
  AccStateChangeEvent(Accessible* aAccessible, uint64_t aState,
145
                      bool aIsEnabled,
146
                      EIsFromUserInput aIsFromUserInput = eAutoDetect) :
147
    AccEvent(nsIAccessibleEvent::EVENT_STATE_CHANGE, aAccessible,
148
             aIsFromUserInput, eCoalesceStateChange),
149
             mState(aState), mIsEnabled(aIsEnabled) { }
150
151
  AccStateChangeEvent(Accessible* aAccessible, uint64_t aState) :
152
    AccEvent(::nsIAccessibleEvent::EVENT_STATE_CHANGE, aAccessible,
153
             eAutoDetect, eCoalesceStateChange), mState(aState)
154
    { mIsEnabled = (mAccessible->State() & mState) != 0; }
155
156
  // AccEvent
157
  static const EventGroup kEventGroup = eStateChangeEvent;
158
  virtual unsigned int GetEventGroups() const override
159
  {
160
    return AccEvent::GetEventGroups() | (1U << eStateChangeEvent);
161
  }
162
163
  // AccStateChangeEvent
164
  uint64_t GetState() const { return mState; }
165
  bool IsStateEnabled() const { return mIsEnabled; }
166
167
private:
168
  uint64_t mState;
169
  bool mIsEnabled;
170
171
  friend class EventQueue;
172
};
173
174
175
/**
176
 * Accessible text change event.
177
 */
178
class AccTextChangeEvent: public AccEvent
179
{
180
public:
181
  AccTextChangeEvent(Accessible* aAccessible, int32_t aStart,
182
                     const nsAString& aModifiedText, bool aIsInserted,
183
                     EIsFromUserInput aIsFromUserInput = eAutoDetect);
184
185
  // AccEvent
186
  static const EventGroup kEventGroup = eTextChangeEvent;
187
  virtual unsigned int GetEventGroups() const override
188
  {
189
    return AccEvent::GetEventGroups() | (1U << eTextChangeEvent);
190
  }
191
192
  // AccTextChangeEvent
193
  int32_t GetStartOffset() const { return mStart; }
194
  uint32_t GetLength() const { return mModifiedText.Length(); }
195
  bool IsTextInserted() const { return mIsInserted; }
196
  void GetModifiedText(nsAString& aModifiedText)
197
    { aModifiedText = mModifiedText; }
198
  const nsString& ModifiedText() const { return mModifiedText; }
199
200
private:
201
  int32_t mStart;
202
  bool mIsInserted;
203
  nsString mModifiedText;
204
205
  friend class EventTree;
206
  friend class NotificationController;
207
};
208
209
/**
210
 * A base class for events related to tree mutation, either an AccMutation
211
 * event, or an AccReorderEvent.
212
 */
213
class AccTreeMutationEvent : public AccEvent
214
{
215
public:
216
  AccTreeMutationEvent(uint32_t aEventType, Accessible* aTarget) :
217
    AccEvent(aEventType, aTarget, eAutoDetect, eCoalesceReorder), mGeneration(0) {}
218
219
  // Event
220
  static const EventGroup kEventGroup = eTreeMutationEvent;
221
  virtual unsigned int GetEventGroups() const override
222
  {
223
    return AccEvent::GetEventGroups() | (1U << eTreeMutationEvent);
224
  }
225
226
  void SetNextEvent(AccTreeMutationEvent* aNext) { mNextEvent = aNext; }
227
  void SetPrevEvent(AccTreeMutationEvent* aPrev) { mPrevEvent = aPrev; }
228
  AccTreeMutationEvent* NextEvent() const { return mNextEvent; }
229
  AccTreeMutationEvent* PrevEvent() const { return mPrevEvent; }
230
231
  /**
232
   * A sequence number to know when this event was fired.
233
   */
234
  uint32_t EventGeneration() const { return mGeneration; }
235
  void SetEventGeneration(uint32_t aGeneration) { mGeneration = aGeneration; }
236
237
private:
238
  RefPtr<AccTreeMutationEvent> mNextEvent;
239
  RefPtr<AccTreeMutationEvent> mPrevEvent;
240
  uint32_t mGeneration;
241
};
242
243
/**
244
 * Base class for show and hide accessible events.
245
 */
246
class AccMutationEvent: public AccTreeMutationEvent
247
{
248
public:
249
  AccMutationEvent(uint32_t aEventType, Accessible* aTarget) :
250
    AccTreeMutationEvent(aEventType, aTarget)
251
  {
252
    // Don't coalesce these since they are coalesced by reorder event. Coalesce
253
    // contained text change events.
254
    mParent = mAccessible->Parent();
255
  }
256
  virtual ~AccMutationEvent() { }
257
258
  // Event
259
  static const EventGroup kEventGroup = eMutationEvent;
260
  virtual unsigned int GetEventGroups() const override
261
  {
262
    return AccTreeMutationEvent::GetEventGroups() | (1U << eMutationEvent);
263
  }
264
265
  // MutationEvent
266
  bool IsShow() const { return mEventType == nsIAccessibleEvent::EVENT_SHOW; }
267
  bool IsHide() const { return mEventType == nsIAccessibleEvent::EVENT_HIDE; }
268
269
  Accessible* Parent() const { return mParent; }
270
271
protected:
272
  nsCOMPtr<nsINode> mNode;
273
  RefPtr<Accessible> mParent;
274
  RefPtr<AccTextChangeEvent> mTextChangeEvent;
275
276
  friend class EventTree;
277
  friend class NotificationController;
278
};
279
280
281
/**
282
 * Accessible hide event.
283
 */
284
class AccHideEvent: public AccMutationEvent
285
{
286
public:
287
  explicit AccHideEvent(Accessible* aTarget, bool aNeedsShutdown = true);
288
289
  // Event
290
  static const EventGroup kEventGroup = eHideEvent;
291
  virtual unsigned int GetEventGroups() const override
292
  {
293
    return AccMutationEvent::GetEventGroups() | (1U << eHideEvent);
294
  }
295
296
  // AccHideEvent
297
  Accessible* TargetParent() const { return mParent; }
298
  Accessible* TargetNextSibling() const { return mNextSibling; }
299
  Accessible* TargetPrevSibling() const { return mPrevSibling; }
300
  bool NeedsShutdown() const { return mNeedsShutdown; }
301
302
protected:
303
  bool mNeedsShutdown;
304
  RefPtr<Accessible> mNextSibling;
305
  RefPtr<Accessible> mPrevSibling;
306
307
  friend class EventTree;
308
  friend class NotificationController;
309
};
310
311
312
/**
313
 * Accessible show event.
314
 */
315
class AccShowEvent: public AccMutationEvent
316
{
317
public:
318
  explicit AccShowEvent(Accessible* aTarget);
319
320
  // Event
321
  static const EventGroup kEventGroup = eShowEvent;
322
  virtual unsigned int GetEventGroups() const override
323
  {
324
    return AccMutationEvent::GetEventGroups() | (1U << eShowEvent);
325
  }
326
327
0
  uint32_t InsertionIndex() const { return mInsertionIndex; }
328
329
private:
330
  nsTArray<RefPtr<AccHideEvent>> mPrecedingEvents;
331
  uint32_t mInsertionIndex;
332
333
  friend class EventTree;
334
};
335
336
337
/**
338
 * Class for reorder accessible event. Takes care about
339
 */
340
class AccReorderEvent : public AccTreeMutationEvent
341
{
342
public:
343
  explicit AccReorderEvent(Accessible* aTarget) :
344
    AccTreeMutationEvent(::nsIAccessibleEvent::EVENT_REORDER, aTarget) { }
345
0
  virtual ~AccReorderEvent() { }
346
347
  // Event
348
  static const EventGroup kEventGroup = eReorderEvent;
349
  virtual unsigned int GetEventGroups() const override
350
  {
351
    return AccTreeMutationEvent::GetEventGroups() | (1U << eReorderEvent);
352
  }
353
};
354
355
356
/**
357
 * Accessible caret move event.
358
 */
359
class AccCaretMoveEvent: public AccEvent
360
{
361
public:
362
  AccCaretMoveEvent(Accessible* aAccessible, int32_t aCaretOffset,
363
                    EIsFromUserInput aIsFromUserInput = eAutoDetect) :
364
    AccEvent(::nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED, aAccessible,
365
             aIsFromUserInput),
366
    mCaretOffset(aCaretOffset) { }
367
0
  virtual ~AccCaretMoveEvent() { }
368
369
  // AccEvent
370
  static const EventGroup kEventGroup = eCaretMoveEvent;
371
  virtual unsigned int GetEventGroups() const override
372
  {
373
    return AccEvent::GetEventGroups() | (1U << eCaretMoveEvent);
374
  }
375
376
  // AccCaretMoveEvent
377
  int32_t GetCaretOffset() const { return mCaretOffset; }
378
379
private:
380
  int32_t mCaretOffset;
381
};
382
383
384
/**
385
 * Accessible text selection change event.
386
 */
387
class AccTextSelChangeEvent : public AccEvent
388
{
389
public:
390
  AccTextSelChangeEvent(HyperTextAccessible* aTarget,
391
                        dom::Selection* aSelection,
392
                        int32_t aReason);
393
  virtual ~AccTextSelChangeEvent();
394
395
  // AccEvent
396
  static const EventGroup kEventGroup = eTextSelChangeEvent;
397
  virtual unsigned int GetEventGroups() const override
398
  {
399
    return AccEvent::GetEventGroups() | (1U << eTextSelChangeEvent);
400
  }
401
402
  // AccTextSelChangeEvent
403
404
  /**
405
   * Return true if the text selection change wasn't caused by pure caret move.
406
   */
407
  bool IsCaretMoveOnly() const;
408
409
private:
410
  RefPtr<dom::Selection> mSel;
411
  int32_t mReason;
412
413
  friend class EventQueue;
414
  friend class SelectionManager;
415
};
416
417
418
/**
419
 * Accessible widget selection change event.
420
 */
421
class AccSelChangeEvent : public AccEvent
422
{
423
public:
424
  enum SelChangeType {
425
    eSelectionAdd,
426
    eSelectionRemove
427
  };
428
429
  AccSelChangeEvent(Accessible* aWidget, Accessible* aItem,
430
                    SelChangeType aSelChangeType);
431
432
  virtual ~AccSelChangeEvent() { }
433
434
  // AccEvent
435
  static const EventGroup kEventGroup = eSelectionChangeEvent;
436
  virtual unsigned int GetEventGroups() const override
437
  {
438
    return AccEvent::GetEventGroups() | (1U << eSelectionChangeEvent);
439
  }
440
441
  // AccSelChangeEvent
442
  Accessible* Widget() const { return mWidget; }
443
444
private:
445
  RefPtr<Accessible> mWidget;
446
  RefPtr<Accessible> mItem;
447
  SelChangeType mSelChangeType;
448
  uint32_t mPreceedingCount;
449
  AccSelChangeEvent* mPackedEvent;
450
451
  friend class EventQueue;
452
};
453
454
455
/**
456
 * Accessible table change event.
457
 */
458
class AccTableChangeEvent : public AccEvent
459
{
460
public:
461
  AccTableChangeEvent(Accessible* aAccessible, uint32_t aEventType,
462
                      int32_t aRowOrColIndex, int32_t aNumRowsOrCols);
463
464
  // AccEvent
465
  static const EventGroup kEventGroup = eTableChangeEvent;
466
  virtual unsigned int GetEventGroups() const override
467
  {
468
    return AccEvent::GetEventGroups() | (1U << eTableChangeEvent);
469
  }
470
471
  // AccTableChangeEvent
472
  uint32_t GetIndex() const { return mRowOrColIndex; }
473
  uint32_t GetCount() const { return mNumRowsOrCols; }
474
475
private:
476
  uint32_t mRowOrColIndex;   // the start row/column after which the rows are inserted/deleted.
477
  uint32_t mNumRowsOrCols;   // the number of inserted/deleted rows/columns
478
};
479
480
/**
481
 * Accessible virtual cursor change event.
482
 */
483
class AccVCChangeEvent : public AccEvent
484
{
485
public:
486
  AccVCChangeEvent(Accessible* aAccessible,
487
                   Accessible* aOldAccessible,
488
                   int32_t aOldStart, int32_t aOldEnd,
489
                   Accessible* aNewAccessible,
490
                   int32_t aNewStart, int32_t aNewEnd,
491
                   int16_t aReason,
492
                   int16_t aBoundaryType,
493
                   EIsFromUserInput aIsFromUserInput = eFromUserInput);
494
495
  virtual ~AccVCChangeEvent() { }
496
497
  // AccEvent
498
  static const EventGroup kEventGroup = eVirtualCursorChangeEvent;
499
  virtual unsigned int GetEventGroups() const override
500
  {
501
    return AccEvent::GetEventGroups() | (1U << eVirtualCursorChangeEvent);
502
  }
503
504
  // AccVCChangeEvent
505
  Accessible* OldAccessible() const { return mOldAccessible; }
506
  int32_t OldStartOffset() const { return mOldStart; }
507
  int32_t OldEndOffset() const { return mOldEnd; }
508
  Accessible* NewAccessible() const { return mNewAccessible; }
509
  int32_t NewStartOffset() const { return mNewStart; }
510
  int32_t NewEndOffset() const { return mNewEnd; }
511
  int32_t Reason() const { return mReason; }
512
  int32_t BoundaryType() const { return mBoundaryType; }
513
514
private:
515
  RefPtr<Accessible> mOldAccessible;
516
  RefPtr<Accessible> mNewAccessible;
517
  int32_t mOldStart;
518
  int32_t mNewStart;
519
  int32_t mOldEnd;
520
  int32_t mNewEnd;
521
  int16_t mReason;
522
  int16_t mBoundaryType;
523
};
524
525
/**
526
 * Accessible object attribute changed event.
527
 */
528
class AccObjectAttrChangedEvent: public AccEvent
529
{
530
public:
531
  AccObjectAttrChangedEvent(Accessible* aAccessible, nsAtom* aAttribute) :
532
    AccEvent(::nsIAccessibleEvent::EVENT_OBJECT_ATTRIBUTE_CHANGED, aAccessible),
533
    mAttribute(aAttribute) { }
534
535
  // AccEvent
536
  static const EventGroup kEventGroup = eObjectAttrChangedEvent;
537
  virtual unsigned int GetEventGroups() const override
538
  {
539
    return AccEvent::GetEventGroups() | (1U << eObjectAttrChangedEvent);
540
  }
541
542
  // AccObjectAttrChangedEvent
543
  nsAtom* GetAttribute() const { return mAttribute; }
544
545
private:
546
  RefPtr<nsAtom> mAttribute;
547
548
  virtual ~AccObjectAttrChangedEvent() { }
549
};
550
551
/**
552
 * Accessible scroll event.
553
 */
554
class AccScrollingEvent : public AccEvent
555
{
556
public:
557
  AccScrollingEvent(uint32_t aEventType, Accessible* aAccessible,
558
                    uint32_t aScrollX, uint32_t aScrollY,
559
                    uint32_t aMaxScrollX, uint32_t aMaxScrollY) :
560
    AccEvent(aEventType, aAccessible),
561
    mScrollX(aScrollX),
562
    mScrollY(aScrollY),
563
    mMaxScrollX(aMaxScrollX),
564
    mMaxScrollY(aMaxScrollY) { }
565
566
0
  virtual ~AccScrollingEvent() { }
567
568
  // AccEvent
569
  static const EventGroup kEventGroup = eScrollingEvent;
570
  virtual unsigned int GetEventGroups() const override
571
  {
572
    return AccEvent::GetEventGroups() | (1U << eScrollingEvent);
573
  }
574
575
  // The X scrolling offset of the container when the event was fired.
576
  uint32_t ScrollX() { return mScrollX; }
577
  // The Y scrolling offset of the container when the event was fired.
578
  uint32_t ScrollY() { return mScrollY; }
579
  // The max X offset of the container.
580
  uint32_t MaxScrollX() { return mMaxScrollX; }
581
  // The max Y offset of the container.
582
  uint32_t MaxScrollY() { return mMaxScrollY; }
583
584
private:
585
  uint32_t mScrollX;
586
  uint32_t mScrollY;
587
  uint32_t mMaxScrollX;
588
  uint32_t mMaxScrollY;
589
};
590
591
/**
592
 * Downcast the generic accessible event object to derived type.
593
 */
594
class downcast_accEvent
595
{
596
public:
597
  explicit downcast_accEvent(AccEvent* e) : mRawPtr(e) { }
598
599
  template<class Destination>
600
  operator Destination*() {
601
    if (!mRawPtr)
602
      return nullptr;
603
604
    return mRawPtr->GetEventGroups() & (1U << Destination::kEventGroup) ?
605
      static_cast<Destination*>(mRawPtr) : nullptr;
606
  }
607
608
private:
609
  AccEvent* mRawPtr;
610
};
611
612
/**
613
 * Return a new xpcom accessible event for the given internal one.
614
 */
615
already_AddRefed<nsIAccessibleEvent>
616
MakeXPCEvent(AccEvent* aEvent);
617
618
} // namespace a11y
619
} // namespace mozilla
620
621
#endif