Home | History | Annotate | Download | only in accessibility
      1 // Copyright 2013 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 "ui/accessibility/ax_node_data.h"
      6 
      7 #include <set>
      8 
      9 #include "base/strings/string_number_conversions.h"
     10 #include "base/strings/string_util.h"
     11 #include "base/strings/utf_string_conversions.h"
     12 
     13 using base::DoubleToString;
     14 using base::IntToString;
     15 
     16 namespace ui {
     17 
     18 namespace {
     19 
     20 std::string IntVectorToString(const std::vector<int>& items) {
     21   std::string str;
     22   for (size_t i = 0; i < items.size(); ++i) {
     23     if (i > 0)
     24       str += ",";
     25     str += IntToString(items[i]);
     26   }
     27   return str;
     28 }
     29 
     30 }  // Anonymous namespace
     31 
     32 AXNodeData::AXNodeData()
     33     : id(-1),
     34       role(AX_ROLE_UNKNOWN),
     35       state(-1) {
     36 }
     37 
     38 AXNodeData::~AXNodeData() {
     39 }
     40 
     41 void AXNodeData::AddStringAttribute(
     42     AXStringAttribute attribute, const std::string& value) {
     43   string_attributes.push_back(std::make_pair(attribute, value));
     44 }
     45 
     46 void AXNodeData::AddIntAttribute(
     47     AXIntAttribute attribute, int value) {
     48   int_attributes.push_back(std::make_pair(attribute, value));
     49 }
     50 
     51 void AXNodeData::AddFloatAttribute(
     52     AXFloatAttribute attribute, float value) {
     53   float_attributes.push_back(std::make_pair(attribute, value));
     54 }
     55 
     56 void AXNodeData::AddBoolAttribute(
     57     AXBoolAttribute attribute, bool value) {
     58   bool_attributes.push_back(std::make_pair(attribute, value));
     59 }
     60 
     61 void AXNodeData::AddIntListAttribute(
     62     AXIntListAttribute attribute, const std::vector<int32>& value) {
     63   intlist_attributes.push_back(std::make_pair(attribute, value));
     64 }
     65 
     66 void AXNodeData::SetName(std::string name) {
     67   string_attributes.push_back(std::make_pair(AX_ATTR_NAME, name));
     68 }
     69 
     70 void AXNodeData::SetValue(std::string value) {
     71   string_attributes.push_back(std::make_pair(AX_ATTR_VALUE, value));
     72 }
     73 
     74 std::string AXNodeData::ToString() const {
     75   std::string result;
     76 
     77   result += "id=" + IntToString(id);
     78   result += " " + ui::ToString(role);
     79 
     80   if (state & (1 << ui::AX_STATE_BUSY))
     81     result += " BUSY";
     82   if (state & (1 << ui::AX_STATE_CHECKED))
     83     result += " CHECKED";
     84   if (state & (1 << ui::AX_STATE_COLLAPSED))
     85     result += " COLLAPSED";
     86   if (state & (1 << ui::AX_STATE_EXPANDED))
     87     result += " EXPANDED";
     88   if (state & (1 << ui::AX_STATE_FOCUSABLE))
     89     result += " FOCUSABLE";
     90   if (state & (1 << ui::AX_STATE_FOCUSED))
     91     result += " FOCUSED";
     92   if (state & (1 << ui::AX_STATE_HASPOPUP))
     93     result += " HASPOPUP";
     94   if (state & (1 << ui::AX_STATE_HOVERED))
     95     result += " HOVERED";
     96   if (state & (1 << ui::AX_STATE_INDETERMINATE))
     97     result += " INDETERMINATE";
     98   if (state & (1 << ui::AX_STATE_INVISIBLE))
     99     result += " INVISIBLE";
    100   if (state & (1 << ui::AX_STATE_LINKED))
    101     result += " LINKED";
    102   if (state & (1 << ui::AX_STATE_MULTISELECTABLE))
    103     result += " MULTISELECTABLE";
    104   if (state & (1 << ui::AX_STATE_OFFSCREEN))
    105     result += " OFFSCREEN";
    106   if (state & (1 << ui::AX_STATE_PRESSED))
    107     result += " PRESSED";
    108   if (state & (1 << ui::AX_STATE_PROTECTED))
    109     result += " PROTECTED";
    110   if (state & (1 << ui::AX_STATE_READ_ONLY))
    111     result += " READONLY";
    112   if (state & (1 << ui::AX_STATE_REQUIRED))
    113     result += " REQUIRED";
    114   if (state & (1 << ui::AX_STATE_SELECTABLE))
    115     result += " SELECTABLE";
    116   if (state & (1 << ui::AX_STATE_SELECTED))
    117     result += " SELECTED";
    118   if (state & (1 << ui::AX_STATE_VERTICAL))
    119     result += " VERTICAL";
    120   if (state & (1 << ui::AX_STATE_VISITED))
    121     result += " VISITED";
    122 
    123   result += " (" + IntToString(location.x()) + ", " +
    124                    IntToString(location.y()) + ")-(" +
    125                    IntToString(location.width()) + ", " +
    126                    IntToString(location.height()) + ")";
    127 
    128   for (size_t i = 0; i < int_attributes.size(); ++i) {
    129     std::string value = IntToString(int_attributes[i].second);
    130     switch (int_attributes[i].first) {
    131       case AX_ATTR_SCROLL_X:
    132         result += " scroll_x=" + value;
    133         break;
    134       case AX_ATTR_SCROLL_X_MIN:
    135         result += " scroll_x_min=" + value;
    136         break;
    137       case AX_ATTR_SCROLL_X_MAX:
    138         result += " scroll_x_max=" + value;
    139         break;
    140       case AX_ATTR_SCROLL_Y:
    141         result += " scroll_y=" + value;
    142         break;
    143       case AX_ATTR_SCROLL_Y_MIN:
    144         result += " scroll_y_min=" + value;
    145         break;
    146       case AX_ATTR_SCROLL_Y_MAX:
    147         result += " scroll_y_max=" + value;
    148         break;
    149       case AX_ATTR_HIERARCHICAL_LEVEL:
    150         result += " level=" + value;
    151         break;
    152       case AX_ATTR_TEXT_SEL_START:
    153         result += " sel_start=" + value;
    154         break;
    155       case AX_ATTR_TEXT_SEL_END:
    156         result += " sel_end=" + value;
    157         break;
    158       case AX_ATTR_TABLE_ROW_COUNT:
    159         result += " rows=" + value;
    160         break;
    161       case AX_ATTR_TABLE_COLUMN_COUNT:
    162         result += " cols=" + value;
    163         break;
    164       case AX_ATTR_TABLE_CELL_COLUMN_INDEX:
    165         result += " col=" + value;
    166         break;
    167       case AX_ATTR_TABLE_CELL_ROW_INDEX:
    168         result += " row=" + value;
    169         break;
    170       case AX_ATTR_TABLE_CELL_COLUMN_SPAN:
    171         result += " colspan=" + value;
    172         break;
    173       case AX_ATTR_TABLE_CELL_ROW_SPAN:
    174         result += " rowspan=" + value;
    175         break;
    176       case AX_ATTR_TABLE_COLUMN_HEADER_ID:
    177         result += " column_header_id=" + value;
    178         break;
    179       case AX_ATTR_TABLE_COLUMN_INDEX:
    180         result += " column_index=" + value;
    181         break;
    182       case AX_ATTR_TABLE_HEADER_ID:
    183         result += " header_id=" + value;
    184         break;
    185       case AX_ATTR_TABLE_ROW_HEADER_ID:
    186         result += " row_header_id=" + value;
    187         break;
    188       case AX_ATTR_TABLE_ROW_INDEX:
    189         result += " row_index=" + value;
    190         break;
    191       case AX_ATTR_TITLE_UI_ELEMENT:
    192         result += " title_elem=" + value;
    193         break;
    194       case AX_ATTR_ACTIVEDESCENDANT_ID:
    195         result += " activedescendant=" + value;
    196         break;
    197       case AX_ATTR_COLOR_VALUE_RED:
    198         result += " color_value_red=" + value;
    199         break;
    200       case AX_ATTR_COLOR_VALUE_GREEN:
    201         result += " color_value_green=" + value;
    202         break;
    203       case AX_ATTR_COLOR_VALUE_BLUE:
    204         result += " color_value_blue=" + value;
    205         break;
    206       case AX_ATTR_TEXT_DIRECTION:
    207         switch (int_attributes[i].second) {
    208           case AX_TEXT_DIRECTION_LR:
    209           default:
    210             result += " text_direction=lr";
    211             break;
    212           case AX_TEXT_DIRECTION_RL:
    213             result += " text_direction=rl";
    214             break;
    215           case AX_TEXT_DIRECTION_TB:
    216             result += " text_direction=tb";
    217             break;
    218           case AX_TEXT_DIRECTION_BT:
    219             result += " text_direction=bt";
    220             break;
    221         }
    222         break;
    223       case AX_INT_ATTRIBUTE_NONE:
    224         break;
    225     }
    226   }
    227 
    228   for (size_t i = 0; i < string_attributes.size(); ++i) {
    229     std::string value = string_attributes[i].second;
    230     switch (string_attributes[i].first) {
    231       case AX_ATTR_DOC_URL:
    232         result += " doc_url=" + value;
    233         break;
    234       case AX_ATTR_DOC_TITLE:
    235         result += " doc_title=" + value;
    236         break;
    237       case AX_ATTR_DOC_MIMETYPE:
    238         result += " doc_mimetype=" + value;
    239         break;
    240       case AX_ATTR_DOC_DOCTYPE:
    241         result += " doc_doctype=" + value;
    242         break;
    243       case AX_ATTR_ACCESS_KEY:
    244         result += " access_key=" + value;
    245         break;
    246       case AX_ATTR_ACTION:
    247         result += " action=" + value;
    248         break;
    249       case AX_ATTR_DESCRIPTION:
    250         result += " description=" + value;
    251         break;
    252       case AX_ATTR_DISPLAY:
    253         result += " display=" + value;
    254         break;
    255       case AX_ATTR_HELP:
    256         result += " help=" + value;
    257         break;
    258       case AX_ATTR_HTML_TAG:
    259         result += " html_tag=" + value;
    260         break;
    261       case AX_ATTR_LIVE_RELEVANT:
    262         result += " relevant=" + value;
    263         break;
    264       case AX_ATTR_LIVE_STATUS:
    265         result += " live=" + value;
    266         break;
    267       case AX_ATTR_CONTAINER_LIVE_RELEVANT:
    268         result += " container_relevant=" + value;
    269         break;
    270       case AX_ATTR_CONTAINER_LIVE_STATUS:
    271         result += " container_live=" + value;
    272         break;
    273       case AX_ATTR_ROLE:
    274         result += " role=" + value;
    275         break;
    276       case AX_ATTR_SHORTCUT:
    277         result += " shortcut=" + value;
    278         break;
    279       case AX_ATTR_URL:
    280         result += " url=" + value;
    281         break;
    282       case AX_ATTR_NAME:
    283         result += " name=" + value;
    284         break;
    285       case AX_ATTR_VALUE:
    286         result += " value=" + value;
    287         break;
    288       case AX_STRING_ATTRIBUTE_NONE:
    289         break;
    290     }
    291   }
    292 
    293   for (size_t i = 0; i < float_attributes.size(); ++i) {
    294     std::string value = DoubleToString(float_attributes[i].second);
    295     switch (float_attributes[i].first) {
    296       case AX_ATTR_DOC_LOADING_PROGRESS:
    297         result += " doc_progress=" + value;
    298         break;
    299       case AX_ATTR_VALUE_FOR_RANGE:
    300         result += " value_for_range=" + value;
    301         break;
    302       case AX_ATTR_MAX_VALUE_FOR_RANGE:
    303         result += " max_value=" + value;
    304         break;
    305       case AX_ATTR_MIN_VALUE_FOR_RANGE:
    306         result += " min_value=" + value;
    307         break;
    308       case AX_FLOAT_ATTRIBUTE_NONE:
    309         break;
    310     }
    311   }
    312 
    313   for (size_t i = 0; i < bool_attributes.size(); ++i) {
    314     std::string value = bool_attributes[i].second ? "true" : "false";
    315     switch (bool_attributes[i].first) {
    316       case AX_ATTR_DOC_LOADED:
    317         result += " doc_loaded=" + value;
    318         break;
    319       case AX_ATTR_BUTTON_MIXED:
    320         result += " mixed=" + value;
    321         break;
    322       case AX_ATTR_LIVE_ATOMIC:
    323         result += " atomic=" + value;
    324         break;
    325       case AX_ATTR_LIVE_BUSY:
    326         result += " busy=" + value;
    327         break;
    328       case AX_ATTR_CONTAINER_LIVE_ATOMIC:
    329         result += " container_atomic=" + value;
    330         break;
    331       case AX_ATTR_CONTAINER_LIVE_BUSY:
    332         result += " container_busy=" + value;
    333         break;
    334       case AX_ATTR_ARIA_READONLY:
    335         result += " aria_readonly=" + value;
    336         break;
    337       case AX_ATTR_CAN_SET_VALUE:
    338         result += " can_set_value=" + value;
    339         break;
    340       case AX_ATTR_UPDATE_LOCATION_ONLY:
    341         result += " update_location_only=" + value;
    342         break;
    343       case AX_ATTR_CANVAS_HAS_FALLBACK:
    344         result += " has_fallback=" + value;
    345         break;
    346       case AX_BOOL_ATTRIBUTE_NONE:
    347         break;
    348     }
    349   }
    350 
    351   for (size_t i = 0; i < intlist_attributes.size(); ++i) {
    352     const std::vector<int32>& values = intlist_attributes[i].second;
    353     switch (intlist_attributes[i].first) {
    354       case AX_ATTR_INDIRECT_CHILD_IDS:
    355         result += " indirect_child_ids=" + IntVectorToString(values);
    356         break;
    357       case AX_ATTR_CONTROLS_IDS:
    358         result += " controls_ids=" + IntVectorToString(values);
    359         break;
    360       case AX_ATTR_DESCRIBEDBY_IDS:
    361         result += " describedby_ids=" + IntVectorToString(values);
    362         break;
    363       case AX_ATTR_FLOWTO_IDS:
    364         result += " flowto_ids=" + IntVectorToString(values);
    365         break;
    366       case AX_ATTR_LABELLEDBY_IDS:
    367         result += " labelledby_ids=" + IntVectorToString(values);
    368         break;
    369       case AX_ATTR_OWNS_IDS:
    370         result += " owns_ids=" + IntVectorToString(values);
    371         break;
    372       case AX_ATTR_LINE_BREAKS:
    373         result += " line_breaks=" + IntVectorToString(values);
    374         break;
    375       case AX_ATTR_CELL_IDS:
    376         result += " cell_ids=" + IntVectorToString(values);
    377         break;
    378       case AX_ATTR_UNIQUE_CELL_IDS:
    379         result += " unique_cell_ids=" + IntVectorToString(values);
    380         break;
    381       case AX_ATTR_CHARACTER_OFFSETS:
    382         result += " character_offsets=" + IntVectorToString(values);
    383         break;
    384       case AX_ATTR_WORD_STARTS:
    385         result += " word_starts=" + IntVectorToString(values);
    386         break;
    387       case AX_ATTR_WORD_ENDS:
    388         result += " word_ends=" + IntVectorToString(values);
    389         break;
    390       case AX_INT_LIST_ATTRIBUTE_NONE:
    391         break;
    392     }
    393   }
    394 
    395   if (!child_ids.empty())
    396     result += " child_ids=" + IntVectorToString(child_ids);
    397 
    398   return result;
    399 }
    400 
    401 }  // namespace ui
    402