Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
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/Accessible.h"
13 namespace mozilla {
15 namespace dom {
16 class Selection;
17 }
19 namespace a11y {
21 class DocAccessible;
23 // Constants used to point whether the event is from user input.
24 enum EIsFromUserInput
25 {
26 // eNoUserInput: event is not from user input
27 eNoUserInput = 0,
28 // eFromUserInput: event is from user input
29 eFromUserInput = 1,
30 // eAutoDetect: the value should be obtained from event state manager
31 eAutoDetect = -1
32 };
34 /**
35 * Generic accessible event.
36 */
37 class AccEvent
38 {
39 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 // eCoalesceMutationTextChange : coalesce text change events caused by
54 // tree mutations of the same tree level.
55 eCoalesceMutationTextChange,
57 // eCoalesceOfSameType : For events of the same type, only the newest event
58 // will be processed.
59 eCoalesceOfSameType,
61 // eCoalesceSelectionChange: coalescence of selection change events.
62 eCoalesceSelectionChange,
64 // eCoalesceStateChange: coalesce state change events.
65 eCoalesceStateChange,
67 // eCoalesceTextSelChange: coalescence of text selection change events.
68 eCoalesceTextSelChange,
70 // eRemoveDupes : For repeat events, only the newest event in queue
71 // will be emitted.
72 eRemoveDupes,
74 // eDoNotEmit : This event is confirmed as a duplicate, do not emit it.
75 eDoNotEmit
76 };
78 // Initialize with an nsIAccessible
79 AccEvent(uint32_t aEventType, Accessible* aAccessible,
80 EIsFromUserInput aIsFromUserInput = eAutoDetect,
81 EEventRule aEventRule = eRemoveDupes);
82 virtual ~AccEvent() {}
84 // AccEvent
85 uint32_t GetEventType() const { return mEventType; }
86 EEventRule GetEventRule() const { return mEventRule; }
87 bool IsFromUserInput() const { return mIsFromUserInput; }
88 EIsFromUserInput FromUserInput() const
89 { return static_cast<EIsFromUserInput>(mIsFromUserInput); }
91 Accessible* GetAccessible() const { return mAccessible; }
92 DocAccessible* GetDocAccessible() const { return mAccessible->Document(); }
94 /**
95 * Down casting.
96 */
97 enum EventGroup {
98 eGenericEvent,
99 eStateChangeEvent,
100 eTextChangeEvent,
101 eMutationEvent,
102 eReorderEvent,
103 eHideEvent,
104 eShowEvent,
105 eCaretMoveEvent,
106 eTextSelChangeEvent,
107 eSelectionChangeEvent,
108 eTableChangeEvent,
109 eVirtualCursorChangeEvent
110 };
112 static const EventGroup kEventGroup = eGenericEvent;
113 virtual unsigned int GetEventGroups() const
114 {
115 return 1U << eGenericEvent;
116 }
118 /**
119 * Reference counting and cycle collection.
120 */
121 NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(AccEvent)
122 NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(AccEvent)
124 protected:
125 bool mIsFromUserInput;
126 uint32_t mEventType;
127 EEventRule mEventRule;
128 nsRefPtr<Accessible> mAccessible;
130 friend class EventQueue;
131 friend class AccReorderEvent;
132 };
135 /**
136 * Accessible state change event.
137 */
138 class AccStateChangeEvent: public AccEvent
139 {
140 public:
141 AccStateChangeEvent(Accessible* aAccessible, uint64_t aState,
142 bool aIsEnabled,
143 EIsFromUserInput aIsFromUserInput = eAutoDetect) :
144 AccEvent(nsIAccessibleEvent::EVENT_STATE_CHANGE, aAccessible,
145 aIsFromUserInput, eCoalesceStateChange),
146 mState(aState), mIsEnabled(aIsEnabled) { }
148 AccStateChangeEvent(Accessible* aAccessible, uint64_t aState) :
149 AccEvent(::nsIAccessibleEvent::EVENT_STATE_CHANGE, aAccessible,
150 eAutoDetect, eCoalesceStateChange), mState(aState)
151 { mIsEnabled = (mAccessible->State() & mState) != 0; }
153 // AccEvent
154 static const EventGroup kEventGroup = eStateChangeEvent;
155 virtual unsigned int GetEventGroups() const
156 {
157 return AccEvent::GetEventGroups() | (1U << eStateChangeEvent);
158 }
160 // AccStateChangeEvent
161 uint64_t GetState() const { return mState; }
162 bool IsStateEnabled() const { return mIsEnabled; }
164 private:
165 uint64_t mState;
166 bool mIsEnabled;
168 friend class EventQueue;
169 };
172 /**
173 * Accessible text change event.
174 */
175 class AccTextChangeEvent: public AccEvent
176 {
177 public:
178 AccTextChangeEvent(Accessible* aAccessible, int32_t aStart,
179 const nsAString& aModifiedText, bool aIsInserted,
180 EIsFromUserInput aIsFromUserInput = eAutoDetect);
182 // AccEvent
183 static const EventGroup kEventGroup = eTextChangeEvent;
184 virtual unsigned int GetEventGroups() const
185 {
186 return AccEvent::GetEventGroups() | (1U << eTextChangeEvent);
187 }
189 // AccTextChangeEvent
190 int32_t GetStartOffset() const { return mStart; }
191 uint32_t GetLength() const { return mModifiedText.Length(); }
192 bool IsTextInserted() const { return mIsInserted; }
193 void GetModifiedText(nsAString& aModifiedText)
194 { aModifiedText = mModifiedText; }
196 private:
197 int32_t mStart;
198 bool mIsInserted;
199 nsString mModifiedText;
201 friend class EventQueue;
202 friend class AccReorderEvent;
203 };
206 /**
207 * Base class for show and hide accessible events.
208 */
209 class AccMutationEvent: public AccEvent
210 {
211 public:
212 AccMutationEvent(uint32_t aEventType, Accessible* aTarget,
213 nsINode* aTargetNode) :
214 AccEvent(aEventType, aTarget, eAutoDetect, eCoalesceMutationTextChange)
215 {
216 // Don't coalesce these since they are coalesced by reorder event. Coalesce
217 // contained text change events.
218 mParent = mAccessible->Parent();
219 }
220 virtual ~AccMutationEvent() { }
222 // Event
223 static const EventGroup kEventGroup = eMutationEvent;
224 virtual unsigned int GetEventGroups() const
225 {
226 return AccEvent::GetEventGroups() | (1U << eMutationEvent);
227 }
229 // MutationEvent
230 bool IsShow() const { return mEventType == nsIAccessibleEvent::EVENT_SHOW; }
231 bool IsHide() const { return mEventType == nsIAccessibleEvent::EVENT_HIDE; }
233 protected:
234 nsCOMPtr<nsINode> mNode;
235 nsRefPtr<Accessible> mParent;
236 nsRefPtr<AccTextChangeEvent> mTextChangeEvent;
238 friend class EventQueue;
239 };
242 /**
243 * Accessible hide event.
244 */
245 class AccHideEvent: public AccMutationEvent
246 {
247 public:
248 AccHideEvent(Accessible* aTarget, nsINode* aTargetNode);
250 // Event
251 static const EventGroup kEventGroup = eHideEvent;
252 virtual unsigned int GetEventGroups() const
253 {
254 return AccMutationEvent::GetEventGroups() | (1U << eHideEvent);
255 }
257 // AccHideEvent
258 Accessible* TargetParent() const { return mParent; }
259 Accessible* TargetNextSibling() const { return mNextSibling; }
260 Accessible* TargetPrevSibling() const { return mPrevSibling; }
262 protected:
263 nsRefPtr<Accessible> mNextSibling;
264 nsRefPtr<Accessible> mPrevSibling;
266 friend class EventQueue;
267 };
270 /**
271 * Accessible show event.
272 */
273 class AccShowEvent: public AccMutationEvent
274 {
275 public:
276 AccShowEvent(Accessible* aTarget, nsINode* aTargetNode);
278 // Event
279 static const EventGroup kEventGroup = eShowEvent;
280 virtual unsigned int GetEventGroups() const
281 {
282 return AccMutationEvent::GetEventGroups() | (1U << eShowEvent);
283 }
284 };
287 /**
288 * Class for reorder accessible event. Takes care about
289 */
290 class AccReorderEvent : public AccEvent
291 {
292 public:
293 AccReorderEvent(Accessible* aTarget) :
294 AccEvent(::nsIAccessibleEvent::EVENT_REORDER, aTarget,
295 eAutoDetect, eCoalesceReorder) { }
296 virtual ~AccReorderEvent() { }
298 // Event
299 static const EventGroup kEventGroup = eReorderEvent;
300 virtual unsigned int GetEventGroups() const
301 {
302 return AccEvent::GetEventGroups() | (1U << eReorderEvent);
303 }
305 /**
306 * Get connected with mutation event.
307 */
308 void AddSubMutationEvent(AccMutationEvent* aEvent)
309 { mDependentEvents.AppendElement(aEvent); }
311 /**
312 * Do not emit the reorder event and its connected mutation events.
313 */
314 void DoNotEmitAll()
315 {
316 mEventRule = AccEvent::eDoNotEmit;
317 uint32_t eventsCount = mDependentEvents.Length();
318 for (uint32_t idx = 0; idx < eventsCount; idx++)
319 mDependentEvents[idx]->mEventRule = AccEvent::eDoNotEmit;
320 }
322 /**
323 * Return true if the given accessible is a target of connected mutation
324 * event.
325 */
326 uint32_t IsShowHideEventTarget(const Accessible* aTarget) const;
328 protected:
329 /**
330 * Show and hide events causing this reorder event.
331 */
332 nsTArray<AccMutationEvent*> mDependentEvents;
334 friend class EventQueue;
335 };
338 /**
339 * Accessible caret move event.
340 */
341 class AccCaretMoveEvent: public AccEvent
342 {
343 public:
344 AccCaretMoveEvent(Accessible* aAccessible, int32_t aCaretOffset,
345 EIsFromUserInput aIsFromUserInput = eAutoDetect) :
346 AccEvent(::nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED, aAccessible,
347 aIsFromUserInput),
348 mCaretOffset(aCaretOffset) { }
349 virtual ~AccCaretMoveEvent() { }
351 // AccEvent
352 static const EventGroup kEventGroup = eCaretMoveEvent;
353 virtual unsigned int GetEventGroups() const
354 {
355 return AccEvent::GetEventGroups() | (1U << eCaretMoveEvent);
356 }
358 // AccCaretMoveEvent
359 int32_t GetCaretOffset() const { return mCaretOffset; }
361 private:
362 int32_t mCaretOffset;
363 };
366 /**
367 * Accessible text selection change event.
368 */
369 class AccTextSelChangeEvent : public AccEvent
370 {
371 public:
372 AccTextSelChangeEvent(HyperTextAccessible* aTarget,
373 dom::Selection* aSelection,
374 int32_t aReason);
375 virtual ~AccTextSelChangeEvent();
377 // AccEvent
378 static const EventGroup kEventGroup = eTextSelChangeEvent;
379 virtual unsigned int GetEventGroups() const
380 {
381 return AccEvent::GetEventGroups() | (1U << eTextSelChangeEvent);
382 }
384 // AccTextSelChangeEvent
386 /**
387 * Return true if the text selection change wasn't caused by pure caret move.
388 */
389 bool IsCaretMoveOnly() const;
391 private:
392 nsRefPtr<dom::Selection> mSel;
393 int32_t mReason;
395 friend class EventQueue;
396 friend class SelectionManager;
397 };
400 /**
401 * Accessible widget selection change event.
402 */
403 class AccSelChangeEvent : public AccEvent
404 {
405 public:
406 enum SelChangeType {
407 eSelectionAdd,
408 eSelectionRemove
409 };
411 AccSelChangeEvent(Accessible* aWidget, Accessible* aItem,
412 SelChangeType aSelChangeType);
414 virtual ~AccSelChangeEvent() { }
416 // AccEvent
417 static const EventGroup kEventGroup = eSelectionChangeEvent;
418 virtual unsigned int GetEventGroups() const
419 {
420 return AccEvent::GetEventGroups() | (1U << eSelectionChangeEvent);
421 }
423 // AccSelChangeEvent
424 Accessible* Widget() const { return mWidget; }
426 private:
427 nsRefPtr<Accessible> mWidget;
428 nsRefPtr<Accessible> mItem;
429 SelChangeType mSelChangeType;
430 uint32_t mPreceedingCount;
431 AccSelChangeEvent* mPackedEvent;
433 friend class EventQueue;
434 };
437 /**
438 * Accessible table change event.
439 */
440 class AccTableChangeEvent : public AccEvent
441 {
442 public:
443 AccTableChangeEvent(Accessible* aAccessible, uint32_t aEventType,
444 int32_t aRowOrColIndex, int32_t aNumRowsOrCols);
446 // AccEvent
447 static const EventGroup kEventGroup = eTableChangeEvent;
448 virtual unsigned int GetEventGroups() const
449 {
450 return AccEvent::GetEventGroups() | (1U << eTableChangeEvent);
451 }
453 // AccTableChangeEvent
454 uint32_t GetIndex() const { return mRowOrColIndex; }
455 uint32_t GetCount() const { return mNumRowsOrCols; }
457 private:
458 uint32_t mRowOrColIndex; // the start row/column after which the rows are inserted/deleted.
459 uint32_t mNumRowsOrCols; // the number of inserted/deleted rows/columns
460 };
462 /**
463 * Accessible virtual cursor change event.
464 */
465 class AccVCChangeEvent : public AccEvent
466 {
467 public:
468 AccVCChangeEvent(Accessible* aAccessible,
469 nsIAccessible* aOldAccessible,
470 int32_t aOldStart, int32_t aOldEnd,
471 int16_t aReason);
473 virtual ~AccVCChangeEvent() { }
475 // AccEvent
476 static const EventGroup kEventGroup = eVirtualCursorChangeEvent;
477 virtual unsigned int GetEventGroups() const
478 {
479 return AccEvent::GetEventGroups() | (1U << eVirtualCursorChangeEvent);
480 }
482 // AccTableChangeEvent
483 nsIAccessible* OldAccessible() const { return mOldAccessible; }
484 int32_t OldStartOffset() const { return mOldStart; }
485 int32_t OldEndOffset() const { return mOldEnd; }
486 int32_t Reason() const { return mReason; }
488 private:
489 nsRefPtr<nsIAccessible> mOldAccessible;
490 int32_t mOldStart;
491 int32_t mOldEnd;
492 int16_t mReason;
493 };
495 /**
496 * Downcast the generic accessible event object to derived type.
497 */
498 class downcast_accEvent
499 {
500 public:
501 downcast_accEvent(AccEvent* e) : mRawPtr(e) { }
503 template<class Destination>
504 operator Destination*() {
505 if (!mRawPtr)
506 return nullptr;
508 return mRawPtr->GetEventGroups() & (1U << Destination::kEventGroup) ?
509 static_cast<Destination*>(mRawPtr) : nullptr;
510 }
512 private:
513 AccEvent* mRawPtr;
514 };
516 /**
517 * Return a new xpcom accessible event for the given internal one.
518 */
519 already_AddRefed<nsIAccessibleEvent>
520 MakeXPCEvent(AccEvent* aEvent);
522 } // namespace a11y
523 } // namespace mozilla
525 #endif