accessible/src/mac/AccessibleWrap.mm

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 /* 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 #include "DocAccessible.h"
     7 #include "nsObjCExceptions.h"
     9 #include "Accessible-inl.h"
    10 #include "nsAccUtils.h"
    11 #include "Role.h"
    13 #import "mozAccessible.h"
    14 #import "mozActionElements.h"
    15 #import "mozHTMLAccessible.h"
    16 #import "mozTextAccessible.h"
    18 using namespace mozilla::a11y;
    20 AccessibleWrap::
    21   AccessibleWrap(nsIContent* aContent, DocAccessible* aDoc) :
    22   Accessible(aContent, aDoc), mNativeObject(nil),  
    23   mNativeInited(false)
    24 {
    25 }
    27 AccessibleWrap::~AccessibleWrap()
    28 {
    29 }
    31 mozAccessible* 
    32 AccessibleWrap::GetNativeObject()
    33 {
    34   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
    36   if (!mNativeInited && !mNativeObject && !IsDefunct() && !AncestorIsFlat())
    37     mNativeObject = [[GetNativeType() alloc] initWithAccessible:this];
    39   mNativeInited = true;
    41   return mNativeObject;
    43   NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
    44 }
    46 NS_IMETHODIMP
    47 AccessibleWrap::GetNativeInterface (void **aOutInterface) 
    48 {
    49   NS_ENSURE_ARG_POINTER(aOutInterface);
    51   *aOutInterface = static_cast<void*>(GetNativeObject());
    53   return *aOutInterface ? NS_OK : NS_ERROR_FAILURE;
    54 }
    56 // overridden in subclasses to create the right kind of object. by default we create a generic
    57 // 'mozAccessible' node.
    58 Class
    59 AccessibleWrap::GetNativeType () 
    60 {
    61   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
    63   if (IsXULTabpanels())
    64     return [mozPaneAccessible class];
    66   roles::Role role = Role();
    67   switch (role) {
    68     case roles::PUSHBUTTON:
    69     case roles::SPLITBUTTON:
    70     case roles::TOGGLE_BUTTON:
    71     {
    72       // if this button may show a popup, let's make it of the popupbutton type.
    73       return HasPopup() ? [mozPopupButtonAccessible class] : 
    74              [mozButtonAccessible class];
    75     }
    77     case roles::PAGETAB:
    78       return [mozButtonAccessible class];
    80     case roles::CHECKBUTTON:
    81       return [mozCheckboxAccessible class];
    83     case roles::HEADING:
    84       return [mozHeadingAccessible class];
    86     case roles::PAGETABLIST:
    87       return [mozTabsAccessible class];
    89     case roles::ENTRY:
    90     case roles::STATICTEXT:
    91     case roles::CAPTION:
    92     case roles::ACCEL_LABEL:
    93     case roles::PASSWORD_TEXT:
    94       // normal textfield (static or editable)
    95       return [mozTextAccessible class];
    97     case roles::TEXT_LEAF:
    98       return [mozTextLeafAccessible class];
   100     case roles::LINK:
   101       return [mozLinkAccessible class];
   103     case roles::COMBOBOX:
   104       return [mozPopupButtonAccessible class];
   106     default:
   107       return [mozAccessible class];
   108   }
   110   return nil;
   112   NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
   113 }
   115 // this method is very important. it is fired when an accessible object "dies". after this point
   116 // the object might still be around (because some 3rd party still has a ref to it), but it is
   117 // in fact 'dead'.
   118 void
   119 AccessibleWrap::Shutdown ()
   120 {
   121   // this ensure we will not try to re-create the native object.
   122   mNativeInited = true;
   124   // we really intend to access the member directly.
   125   if (mNativeObject) {
   126     [mNativeObject expire];
   127     [mNativeObject release];
   128     mNativeObject = nil;
   129   }
   131   Accessible::Shutdown();
   132 }
   134 nsresult
   135 AccessibleWrap::HandleAccEvent(AccEvent* aEvent)
   136 {
   137   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
   139   nsresult rv = Accessible::HandleAccEvent(aEvent);
   140   NS_ENSURE_SUCCESS(rv, rv);
   142   uint32_t eventType = aEvent->GetEventType();
   144   // ignore everything but focus-changed, value-changed, caret and selection
   145   // events for now.
   146   if (eventType != nsIAccessibleEvent::EVENT_FOCUS &&
   147       eventType != nsIAccessibleEvent::EVENT_VALUE_CHANGE &&
   148       eventType != nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED &&
   149       eventType != nsIAccessibleEvent::EVENT_TEXT_SELECTION_CHANGED)
   150     return NS_OK;
   152   Accessible* accessible = aEvent->GetAccessible();
   153   NS_ENSURE_STATE(accessible);
   155   mozAccessible *nativeAcc = nil;
   156   accessible->GetNativeInterface((void**)&nativeAcc);
   157   if (!nativeAcc)
   158     return NS_ERROR_FAILURE;
   160   switch (eventType) {
   161     case nsIAccessibleEvent::EVENT_FOCUS:
   162       [nativeAcc didReceiveFocus];
   163       break;
   164     case nsIAccessibleEvent::EVENT_VALUE_CHANGE:
   165       [nativeAcc valueDidChange];
   166       break;
   167     case nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED:
   168     case nsIAccessibleEvent::EVENT_TEXT_SELECTION_CHANGED:
   169       [nativeAcc selectedTextDidChange];
   170       break;
   171   }
   173   return NS_OK;
   175   NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
   176 }
   178 void
   179 AccessibleWrap::InvalidateChildren()
   180 {
   181   NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
   183   [GetNativeObject() invalidateChildren];
   185   Accessible::InvalidateChildren();
   187   NS_OBJC_END_TRY_ABORT_BLOCK;
   188 }
   190 bool
   191 AccessibleWrap::InsertChildAt(uint32_t aIdx, Accessible* aAccessible)
   192 {
   193   bool inserted = Accessible::InsertChildAt(aIdx, aAccessible);
   194   if (inserted && mNativeObject)
   195     [mNativeObject appendChild:aAccessible];
   197   return inserted;
   198 }
   200 bool
   201 AccessibleWrap::RemoveChild(Accessible* aAccessible)
   202 {
   203   bool removed = Accessible::RemoveChild(aAccessible);
   205   if (removed && mNativeObject)
   206     [mNativeObject invalidateChildren];
   208   return removed;
   209 }
   211 // if we for some reason have no native accessible, we should be skipped over (and traversed)
   212 // when fetching all unignored children, etc.  when counting unignored children, we will not be counted.
   213 bool 
   214 AccessibleWrap::IsIgnored() 
   215 {
   216   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
   218   mozAccessible* nativeObject = GetNativeObject();
   219   return (!nativeObject) || [nativeObject accessibilityIsIgnored];
   221   NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(false);
   222 }
   224 void
   225 AccessibleWrap::GetUnignoredChildren(nsTArray<Accessible*>* aChildrenArray)
   226 {
   227   // we're flat; there are no children.
   228   if (nsAccUtils::MustPrune(this))
   229     return;
   231   uint32_t childCount = ChildCount();
   232   for (uint32_t childIdx = 0; childIdx < childCount; childIdx++) {
   233     AccessibleWrap* childAcc =
   234       static_cast<AccessibleWrap*>(GetChildAt(childIdx));
   236     // If element is ignored, then add its children as substitutes.
   237     if (childAcc->IsIgnored()) {
   238       childAcc->GetUnignoredChildren(aChildrenArray);
   239       continue;
   240     }
   242     aChildrenArray->AppendElement(childAcc);
   243   }
   244 }
   246 Accessible*
   247 AccessibleWrap::GetUnignoredParent() const
   248 {
   249   // Go up the chain to find a parent that is not ignored.
   250   AccessibleWrap* parentWrap = static_cast<AccessibleWrap*>(Parent());
   251   while (parentWrap && parentWrap->IsIgnored()) 
   252     parentWrap = static_cast<AccessibleWrap*>(parentWrap->Parent());
   254   return parentWrap;
   255 }
   257 ////////////////////////////////////////////////////////////////////////////////
   258 // AccessibleWrap protected
   260 bool
   261 AccessibleWrap::AncestorIsFlat()
   262 {
   263   // We don't create a native object if we're child of a "flat" accessible;
   264   // for example, on OS X buttons shouldn't have any children, because that
   265   // makes the OS confused. 
   266   //
   267   // To maintain a scripting environment where the XPCOM accessible hierarchy
   268   // look the same on all platforms, we still let the C++ objects be created
   269   // though.
   271   Accessible* parent = Parent();
   272   while (parent) {
   273     if (nsAccUtils::MustPrune(parent))
   274       return true;
   276     parent = parent->Parent();
   277   }
   278   // no parent was flat
   279   return false;
   280 }

mercurial