accessible/src/base/AccEvent.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial