ax_node_data.cc revision 116680a4aac90f2aa7413d9095a592090648e557
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
13using base::DoubleToString;
14using base::IntToString;
15
16namespace ui {
17
18namespace {
19
20std::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
32AXNodeData::AXNodeData()
33    : id(-1),
34      role(AX_ROLE_UNKNOWN),
35      state(0xFFFFFFFF) {
36}
37
38AXNodeData::~AXNodeData() {
39}
40
41void AXNodeData::AddStringAttribute(
42    AXStringAttribute attribute, const std::string& value) {
43  string_attributes.push_back(std::make_pair(attribute, value));
44}
45
46void AXNodeData::AddIntAttribute(
47    AXIntAttribute attribute, int value) {
48  int_attributes.push_back(std::make_pair(attribute, value));
49}
50
51void AXNodeData::AddFloatAttribute(
52    AXFloatAttribute attribute, float value) {
53  float_attributes.push_back(std::make_pair(attribute, value));
54}
55
56void AXNodeData::AddBoolAttribute(
57    AXBoolAttribute attribute, bool value) {
58  bool_attributes.push_back(std::make_pair(attribute, value));
59}
60
61void AXNodeData::AddIntListAttribute(
62    AXIntListAttribute attribute, const std::vector<int32>& value) {
63  intlist_attributes.push_back(std::make_pair(attribute, value));
64}
65
66void AXNodeData::SetName(std::string name) {
67  string_attributes.push_back(std::make_pair(AX_ATTR_NAME, name));
68}
69
70void AXNodeData::SetValue(std::string value) {
71  string_attributes.push_back(std::make_pair(AX_ATTR_VALUE, value));
72}
73
74std::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