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.

     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/. */
     7 #include "AccEvent.h"
     9 #include "nsAccUtils.h"
    10 #include "DocAccessible.h"
    11 #include "xpcAccEvents.h"
    12 #include "States.h"
    14 #include "mozilla/EventStateManager.h"
    15 #include "mozilla/dom/Selection.h"
    17 using namespace mozilla;
    18 using namespace mozilla::a11y;
    20 static_assert(static_cast<bool>(eNoUserInput) == false &&
    21               static_cast<bool>(eFromUserInput) == true,
    22               "EIsFromUserInput cannot be casted to bool");
    24 ////////////////////////////////////////////////////////////////////////////////
    25 // AccEvent
    26 ////////////////////////////////////////////////////////////////////////////////
    28 ////////////////////////////////////////////////////////////////////////////////
    29 // AccEvent constructors
    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 }
    41 ////////////////////////////////////////////////////////////////////////////////
    42 // AccEvent cycle collection
    44 NS_IMPL_CYCLE_COLLECTION(AccEvent, mAccessible)
    46 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(AccEvent, AddRef)
    47 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(AccEvent, Release)
    49 ////////////////////////////////////////////////////////////////////////////////
    50 ////////////////////////////////////////////////////////////////////////////////
    51 // AccTextChangeEvent
    52 ////////////////////////////////////////////////////////////////////////////////
    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 }
    80 ////////////////////////////////////////////////////////////////////////////////
    81 // AccReorderEvent
    82 ////////////////////////////////////////////////////////////////////////////////
    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   }
    98   return 0;
    99 }
   101 ////////////////////////////////////////////////////////////////////////////////
   102 // AccHideEvent
   103 ////////////////////////////////////////////////////////////////////////////////
   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 }
   114 ////////////////////////////////////////////////////////////////////////////////
   115 // AccShowEvent
   116 ////////////////////////////////////////////////////////////////////////////////
   118 AccShowEvent::
   119   AccShowEvent(Accessible* aTarget, nsINode* aTargetNode) :
   120   AccMutationEvent(::nsIAccessibleEvent::EVENT_SHOW, aTarget, aTargetNode)
   121 {
   122 }
   125 ////////////////////////////////////////////////////////////////////////////////
   126 // AccTextSelChangeEvent
   127 ////////////////////////////////////////////////////////////////////////////////
   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) {}
   136 AccTextSelChangeEvent::~AccTextSelChangeEvent() { }
   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 }
   146 ////////////////////////////////////////////////////////////////////////////////
   147 // AccSelChangeEvent
   148 ////////////////////////////////////////////////////////////////////////////////
   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 }
   168 ////////////////////////////////////////////////////////////////////////////////
   169 // AccTableChangeEvent
   170 ////////////////////////////////////////////////////////////////////////////////
   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 }
   181 ////////////////////////////////////////////////////////////////////////////////
   182 // AccVCChangeEvent
   183 ////////////////////////////////////////////////////////////////////////////////
   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 }
   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;
   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   }
   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   }
   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   }
   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   }
   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   }
   253   xpEvent = new xpcAccEvent(type, acc, doc, domNode, fromUser);
   254   return xpEvent.forget();
   255   }

mercurial