Home | History | Annotate | Download | only in accessibility
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "content/browser/accessibility/accessibility_tree_formatter_utils_win.h"
      6 
      7 #include <oleacc.h>
      8 
      9 #include <map>
     10 #include <string>
     11 
     12 #include "base/memory/singleton.h"
     13 #include "base/strings/string_util.h"
     14 #include "third_party/iaccessible2/ia2_api_all.h"
     15 
     16 namespace content {
     17 namespace {
     18 
     19 class AccessibilityRoleStateMap {
     20  public:
     21   static AccessibilityRoleStateMap* GetInstance();
     22 
     23   std::map<int32, base::string16> ia_role_string_map;
     24   std::map<int32, base::string16> ia2_role_string_map;
     25   std::map<int32, base::string16> ia_state_string_map;
     26   std::map<int32, base::string16> ia2_state_string_map;
     27 
     28  private:
     29   AccessibilityRoleStateMap();
     30   virtual ~AccessibilityRoleStateMap() {}
     31 
     32   friend struct DefaultSingletonTraits<AccessibilityRoleStateMap>;
     33 
     34   DISALLOW_COPY_AND_ASSIGN(AccessibilityRoleStateMap);
     35 };
     36 
     37 // static
     38 AccessibilityRoleStateMap* AccessibilityRoleStateMap::GetInstance() {
     39   return Singleton<AccessibilityRoleStateMap,
     40                    LeakySingletonTraits<AccessibilityRoleStateMap> >::get();
     41 }
     42 
     43 AccessibilityRoleStateMap::AccessibilityRoleStateMap() {
     44 // Convenience macros for generating readable strings.
     45 #define IA_ROLE_MAP(x) ia_role_string_map[x] = L###x;  \
     46                        ia2_role_string_map[x] = L###x;
     47 #define IA2_ROLE_MAP(x) ia2_role_string_map[x] = L###x;
     48 #define IA_STATE_MAP(x) ia_state_string_map[STATE_SYSTEM_##x] = L###x;
     49 #define IA2_STATE_MAP(x) ia2_state_string_map[x] = L###x;
     50 
     51   // MSAA / IAccessible roles. Each one of these is also a valid
     52   // IAccessible2 role, the IA_ROLE_MAP macro adds it to both.
     53   IA_ROLE_MAP(ROLE_SYSTEM_ALERT)
     54   IA_ROLE_MAP(ROLE_SYSTEM_ANIMATION)
     55   IA_ROLE_MAP(ROLE_SYSTEM_APPLICATION)
     56   IA_ROLE_MAP(ROLE_SYSTEM_BORDER)
     57   IA_ROLE_MAP(ROLE_SYSTEM_BUTTONDROPDOWN)
     58   IA_ROLE_MAP(ROLE_SYSTEM_BUTTONDROPDOWNGRID)
     59   IA_ROLE_MAP(ROLE_SYSTEM_BUTTONMENU)
     60   IA_ROLE_MAP(ROLE_SYSTEM_CARET)
     61   IA_ROLE_MAP(ROLE_SYSTEM_CELL)
     62   IA_ROLE_MAP(ROLE_SYSTEM_CHARACTER)
     63   IA_ROLE_MAP(ROLE_SYSTEM_CHART)
     64   IA_ROLE_MAP(ROLE_SYSTEM_CHECKBUTTON)
     65   IA_ROLE_MAP(ROLE_SYSTEM_CLIENT)
     66   IA_ROLE_MAP(ROLE_SYSTEM_CLOCK)
     67   IA_ROLE_MAP(ROLE_SYSTEM_COLUMN)
     68   IA_ROLE_MAP(ROLE_SYSTEM_COLUMNHEADER)
     69   IA_ROLE_MAP(ROLE_SYSTEM_COMBOBOX)
     70   IA_ROLE_MAP(ROLE_SYSTEM_CURSOR)
     71   IA_ROLE_MAP(ROLE_SYSTEM_DIAGRAM)
     72   IA_ROLE_MAP(ROLE_SYSTEM_DIAL)
     73   IA_ROLE_MAP(ROLE_SYSTEM_DIALOG)
     74   IA_ROLE_MAP(ROLE_SYSTEM_DOCUMENT)
     75   IA_ROLE_MAP(ROLE_SYSTEM_DROPLIST)
     76   IA_ROLE_MAP(ROLE_SYSTEM_EQUATION)
     77   IA_ROLE_MAP(ROLE_SYSTEM_GRAPHIC)
     78   IA_ROLE_MAP(ROLE_SYSTEM_GRIP)
     79   IA_ROLE_MAP(ROLE_SYSTEM_GROUPING)
     80   IA_ROLE_MAP(ROLE_SYSTEM_HELPBALLOON)
     81   IA_ROLE_MAP(ROLE_SYSTEM_HOTKEYFIELD)
     82   IA_ROLE_MAP(ROLE_SYSTEM_INDICATOR)
     83   IA_ROLE_MAP(ROLE_SYSTEM_IPADDRESS)
     84   IA_ROLE_MAP(ROLE_SYSTEM_LINK)
     85   IA_ROLE_MAP(ROLE_SYSTEM_LIST)
     86   IA_ROLE_MAP(ROLE_SYSTEM_LISTITEM)
     87   IA_ROLE_MAP(ROLE_SYSTEM_MENUBAR)
     88   IA_ROLE_MAP(ROLE_SYSTEM_MENUITEM)
     89   IA_ROLE_MAP(ROLE_SYSTEM_MENUPOPUP)
     90   IA_ROLE_MAP(ROLE_SYSTEM_OUTLINE)
     91   IA_ROLE_MAP(ROLE_SYSTEM_OUTLINEBUTTON)
     92   IA_ROLE_MAP(ROLE_SYSTEM_OUTLINEITEM)
     93   IA_ROLE_MAP(ROLE_SYSTEM_PAGETAB)
     94   IA_ROLE_MAP(ROLE_SYSTEM_PAGETABLIST)
     95   IA_ROLE_MAP(ROLE_SYSTEM_PANE)
     96   IA_ROLE_MAP(ROLE_SYSTEM_PROGRESSBAR)
     97   IA_ROLE_MAP(ROLE_SYSTEM_PROPERTYPAGE)
     98   IA_ROLE_MAP(ROLE_SYSTEM_PUSHBUTTON)
     99   IA_ROLE_MAP(ROLE_SYSTEM_RADIOBUTTON)
    100   IA_ROLE_MAP(ROLE_SYSTEM_ROW)
    101   IA_ROLE_MAP(ROLE_SYSTEM_ROWHEADER)
    102   IA_ROLE_MAP(ROLE_SYSTEM_SCROLLBAR)
    103   IA_ROLE_MAP(ROLE_SYSTEM_SEPARATOR)
    104   IA_ROLE_MAP(ROLE_SYSTEM_SLIDER)
    105   IA_ROLE_MAP(ROLE_SYSTEM_SOUND)
    106   IA_ROLE_MAP(ROLE_SYSTEM_SPINBUTTON)
    107   IA_ROLE_MAP(ROLE_SYSTEM_SPLITBUTTON)
    108   IA_ROLE_MAP(ROLE_SYSTEM_STATICTEXT)
    109   IA_ROLE_MAP(ROLE_SYSTEM_STATUSBAR)
    110   IA_ROLE_MAP(ROLE_SYSTEM_TABLE)
    111   IA_ROLE_MAP(ROLE_SYSTEM_TEXT)
    112   IA_ROLE_MAP(ROLE_SYSTEM_TITLEBAR)
    113   IA_ROLE_MAP(ROLE_SYSTEM_TOOLBAR)
    114   IA_ROLE_MAP(ROLE_SYSTEM_TOOLTIP)
    115   IA_ROLE_MAP(ROLE_SYSTEM_WHITESPACE)
    116   IA_ROLE_MAP(ROLE_SYSTEM_WINDOW)
    117 
    118   // IAccessible2 roles.
    119   IA2_ROLE_MAP(IA2_ROLE_CANVAS)
    120   IA2_ROLE_MAP(IA2_ROLE_CAPTION)
    121   IA2_ROLE_MAP(IA2_ROLE_CHECK_MENU_ITEM)
    122   IA2_ROLE_MAP(IA2_ROLE_COLOR_CHOOSER)
    123   IA2_ROLE_MAP(IA2_ROLE_DATE_EDITOR)
    124   IA2_ROLE_MAP(IA2_ROLE_DESKTOP_ICON)
    125   IA2_ROLE_MAP(IA2_ROLE_DESKTOP_PANE)
    126   IA2_ROLE_MAP(IA2_ROLE_DIRECTORY_PANE)
    127   IA2_ROLE_MAP(IA2_ROLE_EDITBAR)
    128   IA2_ROLE_MAP(IA2_ROLE_EMBEDDED_OBJECT)
    129   IA2_ROLE_MAP(IA2_ROLE_ENDNOTE)
    130   IA2_ROLE_MAP(IA2_ROLE_FILE_CHOOSER)
    131   IA2_ROLE_MAP(IA2_ROLE_FONT_CHOOSER)
    132   IA2_ROLE_MAP(IA2_ROLE_FOOTER)
    133   IA2_ROLE_MAP(IA2_ROLE_FOOTNOTE)
    134   IA2_ROLE_MAP(IA2_ROLE_FORM)
    135   IA2_ROLE_MAP(IA2_ROLE_FRAME)
    136   IA2_ROLE_MAP(IA2_ROLE_GLASS_PANE)
    137   IA2_ROLE_MAP(IA2_ROLE_HEADER)
    138   IA2_ROLE_MAP(IA2_ROLE_HEADING)
    139   IA2_ROLE_MAP(IA2_ROLE_ICON)
    140   IA2_ROLE_MAP(IA2_ROLE_IMAGE_MAP)
    141   IA2_ROLE_MAP(IA2_ROLE_INPUT_METHOD_WINDOW)
    142   IA2_ROLE_MAP(IA2_ROLE_INTERNAL_FRAME)
    143   IA2_ROLE_MAP(IA2_ROLE_LABEL)
    144   IA2_ROLE_MAP(IA2_ROLE_LAYERED_PANE)
    145   IA2_ROLE_MAP(IA2_ROLE_NOTE)
    146   IA2_ROLE_MAP(IA2_ROLE_OPTION_PANE)
    147   IA2_ROLE_MAP(IA2_ROLE_PAGE)
    148   IA2_ROLE_MAP(IA2_ROLE_PARAGRAPH)
    149   IA2_ROLE_MAP(IA2_ROLE_RADIO_MENU_ITEM)
    150   IA2_ROLE_MAP(IA2_ROLE_REDUNDANT_OBJECT)
    151   IA2_ROLE_MAP(IA2_ROLE_ROOT_PANE)
    152   IA2_ROLE_MAP(IA2_ROLE_RULER)
    153   IA2_ROLE_MAP(IA2_ROLE_SCROLL_PANE)
    154   IA2_ROLE_MAP(IA2_ROLE_SECTION)
    155   IA2_ROLE_MAP(IA2_ROLE_SHAPE)
    156   IA2_ROLE_MAP(IA2_ROLE_SPLIT_PANE)
    157   IA2_ROLE_MAP(IA2_ROLE_TEAR_OFF_MENU)
    158   IA2_ROLE_MAP(IA2_ROLE_TERMINAL)
    159   IA2_ROLE_MAP(IA2_ROLE_TEXT_FRAME)
    160   IA2_ROLE_MAP(IA2_ROLE_TOGGLE_BUTTON)
    161   IA2_ROLE_MAP(IA2_ROLE_UNKNOWN)
    162   IA2_ROLE_MAP(IA2_ROLE_VIEW_PORT)
    163 
    164   // MSAA / IAccessible states. Unlike roles, these are not also IA2 states.
    165   IA_STATE_MAP(ALERT_HIGH)
    166   IA_STATE_MAP(ALERT_LOW)
    167   IA_STATE_MAP(ALERT_MEDIUM)
    168   IA_STATE_MAP(ANIMATED)
    169   IA_STATE_MAP(BUSY)
    170   IA_STATE_MAP(CHECKED)
    171   IA_STATE_MAP(COLLAPSED)
    172   IA_STATE_MAP(DEFAULT)
    173   IA_STATE_MAP(EXPANDED)
    174   IA_STATE_MAP(EXTSELECTABLE)
    175   IA_STATE_MAP(FLOATING)
    176   IA_STATE_MAP(FOCUSABLE)
    177   IA_STATE_MAP(FOCUSED)
    178   IA_STATE_MAP(HASPOPUP)
    179   IA_STATE_MAP(HOTTRACKED)
    180   IA_STATE_MAP(INVISIBLE)
    181   IA_STATE_MAP(LINKED)
    182   IA_STATE_MAP(MARQUEED)
    183   IA_STATE_MAP(MIXED)
    184   IA_STATE_MAP(MOVEABLE)
    185   IA_STATE_MAP(MULTISELECTABLE)
    186   IA_STATE_MAP(OFFSCREEN)
    187   IA_STATE_MAP(PRESSED)
    188   IA_STATE_MAP(PROTECTED)
    189   IA_STATE_MAP(READONLY)
    190   IA_STATE_MAP(SELECTABLE)
    191   IA_STATE_MAP(SELECTED)
    192   IA_STATE_MAP(SELFVOICING)
    193   IA_STATE_MAP(SIZEABLE)
    194   IA_STATE_MAP(TRAVERSED)
    195   IA_STATE_MAP(UNAVAILABLE)
    196 
    197   // IAccessible2 states.
    198   IA2_STATE_MAP(IA2_STATE_ACTIVE)
    199   IA2_STATE_MAP(IA2_STATE_ARMED)
    200   IA2_STATE_MAP(IA2_STATE_DEFUNCT)
    201   IA2_STATE_MAP(IA2_STATE_EDITABLE)
    202   IA2_STATE_MAP(IA2_STATE_ICONIFIED)
    203   IA2_STATE_MAP(IA2_STATE_INVALID_ENTRY)
    204   IA2_STATE_MAP(IA2_STATE_MANAGES_DESCENDANTS)
    205   IA2_STATE_MAP(IA2_STATE_MODAL)
    206   IA2_STATE_MAP(IA2_STATE_MULTI_LINE)
    207   IA2_STATE_MAP(IA2_STATE_REQUIRED)
    208   IA2_STATE_MAP(IA2_STATE_SELECTABLE_TEXT)
    209   IA2_STATE_MAP(IA2_STATE_SINGLE_LINE)
    210   IA2_STATE_MAP(IA2_STATE_STALE)
    211   IA2_STATE_MAP(IA2_STATE_SUPPORTS_AUTOCOMPLETION)
    212   IA2_STATE_MAP(IA2_STATE_TRANSIENT)
    213 
    214   // Untested states include those that would be repeated on nearly every node,
    215   // or would vary based on window size.
    216   // IA2_STATE_MAP(IA2_STATE_HORIZONTAL) // Untested.
    217   // IA2_STATE_MAP(IA2_STATE_OPAQUE) // Untested.
    218   // IA2_STATE_MAP(IA2_STATE_VERTICAL) // Untested.
    219 }
    220 
    221 }  // namespace.
    222 
    223 base::string16 IAccessibleRoleToString(int32 ia_role) {
    224   return AccessibilityRoleStateMap::GetInstance()->ia_role_string_map[ia_role];
    225 }
    226 
    227 base::string16 IAccessible2RoleToString(int32 ia_role) {
    228   return AccessibilityRoleStateMap::GetInstance()->ia2_role_string_map[ia_role];
    229 }
    230 
    231 void IAccessibleStateToStringVector(int32 ia_state,
    232                                     std::vector<base::string16>* result) {
    233   const std::map<int32, base::string16>& state_string_map =
    234       AccessibilityRoleStateMap::GetInstance()->ia_state_string_map;
    235   std::map<int32, base::string16>::const_iterator it;
    236   for (it = state_string_map.begin(); it != state_string_map.end(); ++it) {
    237     if (it->first & ia_state)
    238       result->push_back(it->second);
    239   }
    240 }
    241 
    242 base::string16 IAccessibleStateToString(int32 ia_state) {
    243   std::vector<base::string16> strings;
    244   IAccessibleStateToStringVector(ia_state, &strings);
    245   return JoinString(strings, ',');
    246 }
    247 
    248 void IAccessible2StateToStringVector(int32 ia2_state,
    249                                      std::vector<base::string16>* result) {
    250   const std::map<int32, base::string16>& state_string_map =
    251       AccessibilityRoleStateMap::GetInstance()->ia2_state_string_map;
    252   std::map<int32, base::string16>::const_iterator it;
    253   for (it = state_string_map.begin(); it != state_string_map.end(); ++it) {
    254     if (it->first & ia2_state)
    255       result->push_back(it->second);
    256   }
    257 }
    258 
    259 base::string16 IAccessible2StateToString(int32 ia2_state) {
    260   std::vector<base::string16> strings;
    261   IAccessible2StateToStringVector(ia2_state, &strings);
    262   return JoinString(strings, ',');
    263 }
    264 
    265 }  // namespace content
    266