accessible/src/base/AccEvent.cpp

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:0c73e5320ad0
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 #include "AccEvent.h"
8
9 #include "nsAccUtils.h"
10 #include "DocAccessible.h"
11 #include "xpcAccEvents.h"
12 #include "States.h"
13
14 #include "mozilla/EventStateManager.h"
15 #include "mozilla/dom/Selection.h"
16
17 using namespace mozilla;
18 using namespace mozilla::a11y;
19
20 static_assert(static_cast<bool>(eNoUserInput) == false &&
21 static_cast<bool>(eFromUserInput) == true,
22 "EIsFromUserInput cannot be casted to bool");
23
24 ////////////////////////////////////////////////////////////////////////////////
25 // AccEvent
26 ////////////////////////////////////////////////////////////////////////////////
27
28 ////////////////////////////////////////////////////////////////////////////////
29 // AccEvent constructors
30
31 AccEvent::AccEvent(uint32_t aEventType, Accessible* aAccessible,
32 EIsFromUserInput aIsFromUserInput, EEventRule aEventRule) :
33 mEventType(aEventType), mEventRule(aEventRule), mAccessible(aAccessible)
34 {
35 if (aIsFromUserInput == eAutoDetect)
36 mIsFromUserInput = EventStateManager::IsHandlingUserInput();
37 else
38 mIsFromUserInput = aIsFromUserInput == eFromUserInput ? true : false;
39 }
40
41 ////////////////////////////////////////////////////////////////////////////////
42 // AccEvent cycle collection
43
44 NS_IMPL_CYCLE_COLLECTION(AccEvent, mAccessible)
45
46 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(AccEvent, AddRef)
47 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(AccEvent, Release)
48
49 ////////////////////////////////////////////////////////////////////////////////
50 ////////////////////////////////////////////////////////////////////////////////
51 // AccTextChangeEvent
52 ////////////////////////////////////////////////////////////////////////////////
53
54 // Note: we pass in eAllowDupes to the base class because we don't support text
55 // events coalescence. We fire delayed text change events in DocAccessible but
56 // we continue to base the event off the accessible object rather than just the
57 // node. This means we won't try to create an accessible based on the node when
58 // we are ready to fire the event and so we will no longer assert at that point
59 // if the node was removed from the document. Either way, the AT won't work with
60 // a defunct accessible so the behaviour should be equivalent.
61 AccTextChangeEvent::
62 AccTextChangeEvent(Accessible* aAccessible, int32_t aStart,
63 const nsAString& aModifiedText, bool aIsInserted,
64 EIsFromUserInput aIsFromUserInput)
65 : AccEvent(aIsInserted ?
66 static_cast<uint32_t>(nsIAccessibleEvent::EVENT_TEXT_INSERTED) :
67 static_cast<uint32_t>(nsIAccessibleEvent::EVENT_TEXT_REMOVED),
68 aAccessible, aIsFromUserInput, eAllowDupes)
69 , mStart(aStart)
70 , mIsInserted(aIsInserted)
71 , mModifiedText(aModifiedText)
72 {
73 // XXX We should use IsFromUserInput here, but that isn't always correct
74 // when the text change isn't related to content insertion or removal.
75 mIsFromUserInput = mAccessible->State() &
76 (states::FOCUSED | states::EDITABLE);
77 }
78
79
80 ////////////////////////////////////////////////////////////////////////////////
81 // AccReorderEvent
82 ////////////////////////////////////////////////////////////////////////////////
83
84 uint32_t
85 AccReorderEvent::IsShowHideEventTarget(const Accessible* aTarget) const
86 {
87 uint32_t count = mDependentEvents.Length();
88 for (uint32_t index = count - 1; index < count; index--) {
89 if (mDependentEvents[index]->mAccessible == aTarget) {
90 uint32_t eventType = mDependentEvents[index]->mEventType;
91 if (eventType == nsIAccessibleEvent::EVENT_SHOW ||
92 eventType == nsIAccessibleEvent::EVENT_HIDE) {
93 return mDependentEvents[index]->mEventType;
94 }
95 }
96 }
97
98 return 0;
99 }
100
101 ////////////////////////////////////////////////////////////////////////////////
102 // AccHideEvent
103 ////////////////////////////////////////////////////////////////////////////////
104
105 AccHideEvent::
106 AccHideEvent(Accessible* aTarget, nsINode* aTargetNode) :
107 AccMutationEvent(::nsIAccessibleEvent::EVENT_HIDE, aTarget, aTargetNode)
108 {
109 mNextSibling = mAccessible->NextSibling();
110 mPrevSibling = mAccessible->PrevSibling();
111 }
112
113
114 ////////////////////////////////////////////////////////////////////////////////
115 // AccShowEvent
116 ////////////////////////////////////////////////////////////////////////////////
117
118 AccShowEvent::
119 AccShowEvent(Accessible* aTarget, nsINode* aTargetNode) :
120 AccMutationEvent(::nsIAccessibleEvent::EVENT_SHOW, aTarget, aTargetNode)
121 {
122 }
123
124
125 ////////////////////////////////////////////////////////////////////////////////
126 // AccTextSelChangeEvent
127 ////////////////////////////////////////////////////////////////////////////////
128
129 AccTextSelChangeEvent::AccTextSelChangeEvent(HyperTextAccessible* aTarget,
130 dom::Selection* aSelection,
131 int32_t aReason) :
132 AccEvent(nsIAccessibleEvent::EVENT_TEXT_SELECTION_CHANGED, aTarget,
133 eAutoDetect, eCoalesceTextSelChange),
134 mSel(aSelection), mReason(aReason) {}
135
136 AccTextSelChangeEvent::~AccTextSelChangeEvent() { }
137
138 bool
139 AccTextSelChangeEvent::IsCaretMoveOnly() const
140 {
141 return mSel->GetRangeCount() == 1 && mSel->IsCollapsed() &&
142 ((mReason & (nsISelectionListener::COLLAPSETOSTART_REASON |
143 nsISelectionListener::COLLAPSETOEND_REASON)) == 0);
144 }
145
146 ////////////////////////////////////////////////////////////////////////////////
147 // AccSelChangeEvent
148 ////////////////////////////////////////////////////////////////////////////////
149
150 AccSelChangeEvent::
151 AccSelChangeEvent(Accessible* aWidget, Accessible* aItem,
152 SelChangeType aSelChangeType) :
153 AccEvent(0, aItem, eAutoDetect, eCoalesceSelectionChange),
154 mWidget(aWidget), mItem(aItem), mSelChangeType(aSelChangeType),
155 mPreceedingCount(0), mPackedEvent(nullptr)
156 {
157 if (aSelChangeType == eSelectionAdd) {
158 if (mWidget->GetSelectedItem(1))
159 mEventType = nsIAccessibleEvent::EVENT_SELECTION_ADD;
160 else
161 mEventType = nsIAccessibleEvent::EVENT_SELECTION;
162 } else {
163 mEventType = nsIAccessibleEvent::EVENT_SELECTION_REMOVE;
164 }
165 }
166
167
168 ////////////////////////////////////////////////////////////////////////////////
169 // AccTableChangeEvent
170 ////////////////////////////////////////////////////////////////////////////////
171
172 AccTableChangeEvent::
173 AccTableChangeEvent(Accessible* aAccessible, uint32_t aEventType,
174 int32_t aRowOrColIndex, int32_t aNumRowsOrCols) :
175 AccEvent(aEventType, aAccessible),
176 mRowOrColIndex(aRowOrColIndex), mNumRowsOrCols(aNumRowsOrCols)
177 {
178 }
179
180
181 ////////////////////////////////////////////////////////////////////////////////
182 // AccVCChangeEvent
183 ////////////////////////////////////////////////////////////////////////////////
184
185 AccVCChangeEvent::
186 AccVCChangeEvent(Accessible* aAccessible,
187 nsIAccessible* aOldAccessible,
188 int32_t aOldStart, int32_t aOldEnd,
189 int16_t aReason) :
190 AccEvent(::nsIAccessibleEvent::EVENT_VIRTUALCURSOR_CHANGED, aAccessible),
191 mOldAccessible(aOldAccessible), mOldStart(aOldStart), mOldEnd(aOldEnd),
192 mReason(aReason)
193 {
194 }
195
196 already_AddRefed<nsIAccessibleEvent>
197 a11y::MakeXPCEvent(AccEvent* aEvent)
198 {
199 DocAccessible* doc = aEvent->GetDocAccessible();
200 Accessible* acc = aEvent->GetAccessible();
201 nsINode* node = acc->GetNode();
202 nsIDOMNode* domNode = node ? node->AsDOMNode() : nullptr;
203 bool fromUser = aEvent->IsFromUserInput();
204 uint32_t type = aEvent->GetEventType();
205 uint32_t eventGroup = aEvent->GetEventGroups();
206 nsCOMPtr<nsIAccessibleEvent> xpEvent;
207
208 if (eventGroup & (1 << AccEvent::eStateChangeEvent)) {
209 AccStateChangeEvent* sc = downcast_accEvent(aEvent);
210 bool extra = false;
211 uint32_t state = nsAccUtils::To32States(sc->GetState(), &extra);
212 xpEvent = new xpcAccStateChangeEvent(type, acc, doc, domNode, fromUser,
213 state, extra, sc->IsStateEnabled());
214 return xpEvent.forget();
215 }
216
217 if (eventGroup & (1 << AccEvent::eTextChangeEvent)) {
218 AccTextChangeEvent* tc = downcast_accEvent(aEvent);
219 nsString text;
220 tc->GetModifiedText(text);
221 xpEvent = new xpcAccTextChangeEvent(type, acc, doc, domNode, fromUser,
222 tc->GetStartOffset(), tc->GetLength(),
223 tc->IsTextInserted(), text);
224 return xpEvent.forget();
225 }
226
227 if (eventGroup & (1 << AccEvent::eHideEvent)) {
228 AccHideEvent* hideEvent = downcast_accEvent(aEvent);
229 xpEvent = new xpcAccHideEvent(type, acc, doc, domNode, fromUser,
230 hideEvent->TargetParent(),
231 hideEvent->TargetNextSibling(),
232 hideEvent->TargetPrevSibling());
233 return xpEvent.forget();
234 }
235
236 if (eventGroup & (1 << AccEvent::eCaretMoveEvent)) {
237 AccCaretMoveEvent* cm = downcast_accEvent(aEvent);
238 xpEvent = new xpcAccCaretMoveEvent(type, acc, doc, domNode, fromUser,
239 cm->GetCaretOffset());
240 return xpEvent.forget();
241 }
242
243 if (eventGroup & (1 << AccEvent::eVirtualCursorChangeEvent)) {
244 AccVCChangeEvent* vcc = downcast_accEvent(aEvent);
245 xpEvent = new xpcAccVirtualCursorChangeEvent(type, acc, doc, domNode, fromUser,
246 vcc->OldAccessible(),
247 vcc->OldStartOffset(),
248 vcc->OldEndOffset(),
249 vcc->Reason());
250 return xpEvent.forget();
251 }
252
253 xpEvent = new xpcAccEvent(type, acc, doc, domNode, fromUser);
254 return xpEvent.forget();
255 }

mercurial