OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/renderer/accessibility/blink_ax_tree_source.h" | 5 #include "content/renderer/accessibility/blink_ax_tree_source.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 | 8 |
9 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
99 void AddIntListAttributeFromWebObjects(ui::AXIntListAttribute attr, | 99 void AddIntListAttributeFromWebObjects(ui::AXIntListAttribute attr, |
100 WebVector<WebAXObject> objects, | 100 WebVector<WebAXObject> objects, |
101 AXContentNodeData* dst) { | 101 AXContentNodeData* dst) { |
102 std::vector<int32> ids; | 102 std::vector<int32> ids; |
103 for(size_t i = 0; i < objects.size(); i++) | 103 for(size_t i = 0; i < objects.size(); i++) |
104 ids.push_back(objects[i].axID()); | 104 ids.push_back(objects[i].axID()); |
105 if (ids.size() > 0) | 105 if (ids.size() > 0) |
106 dst->AddIntListAttribute(attr, ids); | 106 dst->AddIntListAttribute(attr, ids); |
107 } | 107 } |
108 | 108 |
109 } // Anonymous namespace | 109 } // namespace |
110 | 110 |
111 BlinkAXTreeSource::BlinkAXTreeSource(RenderFrameImpl* render_frame) | 111 BlinkAXTreeSource::BlinkAXTreeSource(RenderFrameImpl* render_frame) |
112 : render_frame_(render_frame), | 112 : render_frame_(render_frame), |
113 accessibility_focus_id_(-1) { | 113 accessibility_focus_id_(-1) { |
114 } | 114 } |
115 | 115 |
116 BlinkAXTreeSource::~BlinkAXTreeSource() { | 116 BlinkAXTreeSource::~BlinkAXTreeSource() { |
117 } | 117 } |
118 | 118 |
119 void BlinkAXTreeSource::SetRoot(blink::WebAXObject root) { | 119 void BlinkAXTreeSource::SetRoot(blink::WebAXObject root) { |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
251 blink::WebAXObject BlinkAXTreeSource::GetNull() const { | 251 blink::WebAXObject BlinkAXTreeSource::GetNull() const { |
252 return blink::WebAXObject(); | 252 return blink::WebAXObject(); |
253 } | 253 } |
254 | 254 |
255 void BlinkAXTreeSource::SerializeNode(blink::WebAXObject src, | 255 void BlinkAXTreeSource::SerializeNode(blink::WebAXObject src, |
256 AXContentNodeData* dst) const { | 256 AXContentNodeData* dst) const { |
257 dst->role = AXRoleFromBlink(src.role()); | 257 dst->role = AXRoleFromBlink(src.role()); |
258 dst->state = AXStateFromBlink(src); | 258 dst->state = AXStateFromBlink(src); |
259 dst->location = src.boundingBoxRect(); | 259 dst->location = src.boundingBoxRect(); |
260 dst->id = src.axID(); | 260 dst->id = src.axID(); |
261 std::string name = src.deprecatedTitle().utf8(); | 261 |
| 262 blink::WebAXNameFrom nameFrom; |
| 263 blink::WebVector<blink::WebAXObject> nameObjects; |
| 264 blink::WebString web_name = src.name(nameFrom, nameObjects); |
| 265 if (!web_name.isEmpty()) { |
| 266 dst->AddStringAttribute(ui::AX_ATTR_NAME, web_name.utf8()); |
| 267 dst->AddIntAttribute(ui::AX_ATTR_NAME_FROM, AXNameFromFromBlink(nameFrom)); |
| 268 AddIntListAttributeFromWebObjects( |
| 269 ui::AX_ATTR_LABELLEDBY_IDS, nameObjects, dst); |
| 270 } |
| 271 |
| 272 blink::WebAXDescriptionFrom descriptionFrom; |
| 273 blink::WebVector<blink::WebAXObject> descriptionObjects; |
| 274 blink::WebString web_description = src.description( |
| 275 nameFrom, descriptionFrom, descriptionObjects); |
| 276 if (!web_description.isEmpty()) { |
| 277 dst->AddStringAttribute(ui::AX_ATTR_DESCRIPTION, web_description.utf8()); |
| 278 dst->AddIntAttribute(ui::AX_ATTR_DESCRIPTION_FROM, |
| 279 AXDescriptionFromFromBlink(descriptionFrom)); |
| 280 AddIntListAttributeFromWebObjects( |
| 281 ui::AX_ATTR_DESCRIBEDBY_IDS, descriptionObjects, dst); |
| 282 } |
| 283 |
| 284 blink::WebString web_placeholder = src.placeholder(nameFrom, descriptionFrom); |
| 285 if (!web_placeholder.isEmpty()) |
| 286 dst->AddStringAttribute(ui::AX_ATTR_PLACEHOLDER, web_placeholder.utf8()); |
262 | 287 |
263 std::string value; | 288 std::string value; |
264 if (src.valueDescription().length()) { | 289 if (src.valueDescription().length()) { |
265 dst->AddStringAttribute(ui::AX_ATTR_VALUE, src.valueDescription().utf8()); | 290 dst->AddStringAttribute(ui::AX_ATTR_VALUE, src.valueDescription().utf8()); |
266 } else { | 291 } else { |
267 dst->AddStringAttribute(ui::AX_ATTR_VALUE, src.stringValue().utf8()); | 292 dst->AddStringAttribute(ui::AX_ATTR_VALUE, src.stringValue().utf8()); |
268 } | 293 } |
269 | 294 |
270 if (dst->role == ui::AX_ROLE_COLOR_WELL) | 295 if (dst->role == ui::AX_ROLE_COLOR_WELL) |
271 dst->AddIntAttribute(ui::AX_ATTR_COLOR_VALUE, src.colorValue()); | 296 dst->AddIntAttribute(ui::AX_ATTR_COLOR_VALUE, src.colorValue()); |
272 | 297 |
273 | 298 |
274 // Text attributes. | 299 // Text attributes. |
275 if (src.backgroundColor()) | 300 if (src.backgroundColor()) |
276 dst->AddIntAttribute(ui::AX_ATTR_BACKGROUND_COLOR, src.backgroundColor()); | 301 dst->AddIntAttribute(ui::AX_ATTR_BACKGROUND_COLOR, src.backgroundColor()); |
277 | 302 |
278 if (src.color()) | 303 if (src.color()) |
279 dst->AddIntAttribute(ui::AX_ATTR_COLOR, src.color()); | 304 dst->AddIntAttribute(ui::AX_ATTR_COLOR, src.color()); |
280 | 305 |
281 // Font size is in pixels. | 306 // Font size is in pixels. |
282 if (src.fontSize()) | 307 if (src.fontSize()) |
283 dst->AddFloatAttribute(ui::AX_ATTR_FONT_SIZE, src.fontSize()); | 308 dst->AddFloatAttribute(ui::AX_ATTR_FONT_SIZE, src.fontSize()); |
284 | 309 |
285 if (src.invalidState()) { | 310 if (src.invalidState()) { |
286 dst->AddIntAttribute(ui::AX_ATTR_INVALID_STATE, | 311 dst->AddIntAttribute(ui::AX_ATTR_INVALID_STATE, |
287 AXInvalidStateFromBlink(src.invalidState())); | 312 AXInvalidStateFromBlink(src.invalidState())); |
288 } | 313 } |
289 if (src.invalidState() == blink::WebAXInvalidStateOther) { | 314 if (src.invalidState() == blink::WebAXInvalidStateOther) { |
290 dst->AddStringAttribute( | 315 dst->AddStringAttribute( |
291 ui::AX_ATTR_ARIA_INVALID_VALUE, | 316 ui::AX_ATTR_ARIA_INVALID_VALUE, src.ariaInvalidValue().utf8()); |
292 src.ariaInvalidValue().utf8()); | |
293 } | 317 } |
294 | 318 |
295 if (src.textDirection()) { | 319 if (src.textDirection()) { |
296 dst->AddIntAttribute(ui::AX_ATTR_TEXT_DIRECTION, | 320 dst->AddIntAttribute(ui::AX_ATTR_TEXT_DIRECTION, |
297 AXTextDirectionFromBlink(src.textDirection())); | 321 AXTextDirectionFromBlink(src.textDirection())); |
298 } | 322 } |
299 | 323 |
300 if (src.textStyle()) { | 324 if (src.textStyle()) { |
301 dst->AddIntAttribute(ui::AX_ATTR_TEXT_STYLE, | 325 dst->AddIntAttribute(ui::AX_ATTR_TEXT_STYLE, |
302 AXTextStyleFromBlink(src.textStyle())); | 326 AXTextStyleFromBlink(src.textStyle())); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
337 if (src.ariaAutoComplete().length()) | 361 if (src.ariaAutoComplete().length()) |
338 dst->AddStringAttribute( | 362 dst->AddStringAttribute( |
339 ui::AX_ATTR_AUTO_COMPLETE, | 363 ui::AX_ATTR_AUTO_COMPLETE, |
340 src.ariaAutoComplete().utf8()); | 364 src.ariaAutoComplete().utf8()); |
341 if (src.isAriaReadOnly()) | 365 if (src.isAriaReadOnly()) |
342 dst->AddBoolAttribute(ui::AX_ATTR_ARIA_READONLY, true); | 366 dst->AddBoolAttribute(ui::AX_ATTR_ARIA_READONLY, true); |
343 if (src.isButtonStateMixed()) | 367 if (src.isButtonStateMixed()) |
344 dst->AddBoolAttribute(ui::AX_ATTR_BUTTON_MIXED, true); | 368 dst->AddBoolAttribute(ui::AX_ATTR_BUTTON_MIXED, true); |
345 if (src.canSetValueAttribute()) | 369 if (src.canSetValueAttribute()) |
346 dst->AddBoolAttribute(ui::AX_ATTR_CAN_SET_VALUE, true); | 370 dst->AddBoolAttribute(ui::AX_ATTR_CAN_SET_VALUE, true); |
347 if (src.deprecatedAccessibilityDescription().length()) { | |
348 dst->AddStringAttribute( | |
349 ui::AX_ATTR_DESCRIPTION, | |
350 src.deprecatedAccessibilityDescription().utf8()); | |
351 } | |
352 if (src.hasComputedStyle()) { | 371 if (src.hasComputedStyle()) { |
353 dst->AddStringAttribute( | 372 dst->AddStringAttribute( |
354 ui::AX_ATTR_DISPLAY, | 373 ui::AX_ATTR_DISPLAY, src.computedStyleDisplay().utf8()); |
355 src.computedStyleDisplay().utf8()); | |
356 } | |
357 if (src.deprecatedHelpText().length()) | |
358 dst->AddStringAttribute(ui::AX_ATTR_HELP, src.deprecatedHelpText().utf8()); | |
359 if (src.deprecatedPlaceholder().length()) { | |
360 dst->AddStringAttribute( | |
361 ui::AX_ATTR_PLACEHOLDER, | |
362 src.deprecatedPlaceholder().utf8()); | |
363 } | 374 } |
364 if (src.keyboardShortcut().length()) { | 375 if (src.keyboardShortcut().length()) { |
365 dst->AddStringAttribute( | 376 dst->AddStringAttribute( |
366 ui::AX_ATTR_SHORTCUT, | 377 ui::AX_ATTR_SHORTCUT, |
367 src.keyboardShortcut().utf8()); | 378 src.keyboardShortcut().utf8()); |
368 } | 379 } |
369 if (!src.deprecatedTitleUIElement().isDetached()) { | |
370 dst->AddIntAttribute(ui::AX_ATTR_TITLE_UI_ELEMENT, | |
371 src.deprecatedTitleUIElement().axID()); | |
372 } | |
373 if (!src.ariaActiveDescendant().isDetached()) { | 380 if (!src.ariaActiveDescendant().isDetached()) { |
374 dst->AddIntAttribute(ui::AX_ATTR_ACTIVEDESCENDANT_ID, | 381 dst->AddIntAttribute(ui::AX_ATTR_ACTIVEDESCENDANT_ID, |
375 src.ariaActiveDescendant().axID()); | 382 src.ariaActiveDescendant().axID()); |
376 } | 383 } |
377 | 384 |
378 if (!src.url().isEmpty()) | 385 if (!src.url().isEmpty()) |
379 dst->AddStringAttribute(ui::AX_ATTR_URL, src.url().spec()); | 386 dst->AddStringAttribute(ui::AX_ATTR_URL, src.url().spec()); |
380 | 387 |
381 if (dst->role == ui::AX_ROLE_HEADING) | 388 if (dst->role == ui::AX_ROLE_HEADING) |
382 dst->AddIntAttribute(ui::AX_ATTR_HIERARCHICAL_LEVEL, src.headingLevel()); | 389 dst->AddIntAttribute(ui::AX_ATTR_HIERARCHICAL_LEVEL, src.headingLevel()); |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
503 dst->role == ui::AX_ROLE_SCROLL_BAR || | 510 dst->role == ui::AX_ROLE_SCROLL_BAR || |
504 dst->role == ui::AX_ROLE_SLIDER || | 511 dst->role == ui::AX_ROLE_SLIDER || |
505 dst->role == ui::AX_ROLE_SPIN_BUTTON) { | 512 dst->role == ui::AX_ROLE_SPIN_BUTTON) { |
506 dst->AddFloatAttribute(ui::AX_ATTR_VALUE_FOR_RANGE, src.valueForRange()); | 513 dst->AddFloatAttribute(ui::AX_ATTR_VALUE_FOR_RANGE, src.valueForRange()); |
507 dst->AddFloatAttribute(ui::AX_ATTR_MAX_VALUE_FOR_RANGE, | 514 dst->AddFloatAttribute(ui::AX_ATTR_MAX_VALUE_FOR_RANGE, |
508 src.maxValueForRange()); | 515 src.maxValueForRange()); |
509 dst->AddFloatAttribute(ui::AX_ATTR_MIN_VALUE_FOR_RANGE, | 516 dst->AddFloatAttribute(ui::AX_ATTR_MIN_VALUE_FOR_RANGE, |
510 src.minValueForRange()); | 517 src.minValueForRange()); |
511 } | 518 } |
512 | 519 |
513 if (dst->role == ui::AX_ROLE_WEB_AREA) { | 520 if (dst->role == ui::AX_ROLE_WEB_AREA) |
514 dst->AddStringAttribute(ui::AX_ATTR_HTML_TAG, "#document"); | 521 dst->AddStringAttribute(ui::AX_ATTR_HTML_TAG, "#document"); |
515 const WebDocument& document = src.document(); | |
516 if (name.empty()) | |
517 name = document.title().utf8(); | |
518 } | |
519 | 522 |
520 if (dst->role == ui::AX_ROLE_TABLE) { | 523 if (dst->role == ui::AX_ROLE_TABLE) { |
521 int column_count = src.columnCount(); | 524 int column_count = src.columnCount(); |
522 int row_count = src.rowCount(); | 525 int row_count = src.rowCount(); |
523 if (column_count > 0 && row_count > 0) { | 526 if (column_count > 0 && row_count > 0) { |
524 std::set<int32> unique_cell_id_set; | 527 std::set<int32> unique_cell_id_set; |
525 std::vector<int32> cell_ids; | 528 std::vector<int32> cell_ids; |
526 std::vector<int32> unique_cell_ids; | 529 std::vector<int32> unique_cell_ids; |
527 dst->AddIntAttribute(ui::AX_ATTR_TABLE_COLUMN_COUNT, column_count); | 530 dst->AddIntAttribute(ui::AX_ATTR_TABLE_COLUMN_COUNT, column_count); |
528 dst->AddIntAttribute(ui::AX_ATTR_TABLE_ROW_COUNT, row_count); | 531 dst->AddIntAttribute(ui::AX_ATTR_TABLE_ROW_COUNT, row_count); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
571 dst->AddIntAttribute(ui::AX_ATTR_TABLE_CELL_ROW_INDEX, src.cellRowIndex()); | 574 dst->AddIntAttribute(ui::AX_ATTR_TABLE_CELL_ROW_INDEX, src.cellRowIndex()); |
572 dst->AddIntAttribute(ui::AX_ATTR_TABLE_CELL_ROW_SPAN, src.cellRowSpan()); | 575 dst->AddIntAttribute(ui::AX_ATTR_TABLE_CELL_ROW_SPAN, src.cellRowSpan()); |
573 } | 576 } |
574 | 577 |
575 if ((dst->role == ui::AX_ROLE_ROW_HEADER || | 578 if ((dst->role == ui::AX_ROLE_ROW_HEADER || |
576 dst->role == ui::AX_ROLE_COLUMN_HEADER) && src.sortDirection()) { | 579 dst->role == ui::AX_ROLE_COLUMN_HEADER) && src.sortDirection()) { |
577 dst->AddIntAttribute(ui::AX_ATTR_SORT_DIRECTION, | 580 dst->AddIntAttribute(ui::AX_ATTR_SORT_DIRECTION, |
578 AXSortDirectionFromBlink(src.sortDirection())); | 581 AXSortDirectionFromBlink(src.sortDirection())); |
579 } | 582 } |
580 | 583 |
581 dst->AddStringAttribute(ui::AX_ATTR_NAME, name); | |
582 | |
583 // Add the ids of *indirect* children - those who are children of this node, | 584 // Add the ids of *indirect* children - those who are children of this node, |
584 // but whose parent is *not* this node. One example is a table | 585 // but whose parent is *not* this node. One example is a table |
585 // cell, which is a child of both a row and a column. Because the cell's | 586 // cell, which is a child of both a row and a column. Because the cell's |
586 // parent is the row, the row adds it as a child, and the column adds it | 587 // parent is the row, the row adds it as a child, and the column adds it |
587 // as an indirect child. | 588 // as an indirect child. |
588 int child_count = src.childCount(); | 589 int child_count = src.childCount(); |
589 for (int i = 0; i < child_count; ++i) { | 590 for (int i = 0; i < child_count; ++i) { |
590 WebAXObject child = src.childAt(i); | 591 WebAXObject child = src.childAt(i); |
591 std::vector<int32> indirect_child_ids; | 592 std::vector<int32> indirect_child_ids; |
592 if (!is_iframe && !child.isDetached() && !IsParentUnignoredOf(src, child)) | 593 if (!is_iframe && !child.isDetached() && !IsParentUnignoredOf(src, child)) |
593 indirect_child_ids.push_back(child.axID()); | 594 indirect_child_ids.push_back(child.axID()); |
594 if (indirect_child_ids.size() > 0) { | 595 if (indirect_child_ids.size() > 0) { |
595 dst->AddIntListAttribute( | 596 dst->AddIntListAttribute( |
596 ui::AX_ATTR_INDIRECT_CHILD_IDS, indirect_child_ids); | 597 ui::AX_ATTR_INDIRECT_CHILD_IDS, indirect_child_ids); |
597 } | 598 } |
598 } | 599 } |
599 | 600 |
600 WebVector<WebAXObject> controls; | 601 WebVector<WebAXObject> controls; |
601 if (src.ariaControls(controls)) | 602 if (src.ariaControls(controls)) |
602 AddIntListAttributeFromWebObjects(ui::AX_ATTR_CONTROLS_IDS, controls, dst); | 603 AddIntListAttributeFromWebObjects(ui::AX_ATTR_CONTROLS_IDS, controls, dst); |
603 | 604 |
604 WebVector<WebAXObject> describedby; | |
605 if (src.deprecatedAriaDescribedby(describedby)) { | |
606 AddIntListAttributeFromWebObjects( | |
607 ui::AX_ATTR_DESCRIBEDBY_IDS, describedby, dst); | |
608 } | |
609 | |
610 WebVector<WebAXObject> flowTo; | 605 WebVector<WebAXObject> flowTo; |
611 if (src.ariaFlowTo(flowTo)) | 606 if (src.ariaFlowTo(flowTo)) |
612 AddIntListAttributeFromWebObjects(ui::AX_ATTR_FLOWTO_IDS, flowTo, dst); | 607 AddIntListAttributeFromWebObjects(ui::AX_ATTR_FLOWTO_IDS, flowTo, dst); |
613 | 608 |
614 WebVector<WebAXObject> labelledby; | |
615 if (src.deprecatedAriaLabelledby(labelledby)) { | |
616 AddIntListAttributeFromWebObjects( | |
617 ui::AX_ATTR_LABELLEDBY_IDS, labelledby, dst); | |
618 } | |
619 | |
620 WebVector<WebAXObject> owns; | |
621 if (src.ariaOwns(owns)) | |
622 AddIntListAttributeFromWebObjects(ui::AX_ATTR_OWNS_IDS, owns, dst); | |
623 | |
624 | |
625 if (src.isScrollableContainer()) { | 609 if (src.isScrollableContainer()) { |
626 const gfx::Point& scrollOffset = src.scrollOffset(); | 610 const gfx::Point& scrollOffset = src.scrollOffset(); |
627 dst->AddIntAttribute(ui::AX_ATTR_SCROLL_X, scrollOffset.x()); | 611 dst->AddIntAttribute(ui::AX_ATTR_SCROLL_X, scrollOffset.x()); |
628 dst->AddIntAttribute(ui::AX_ATTR_SCROLL_Y, scrollOffset.y()); | 612 dst->AddIntAttribute(ui::AX_ATTR_SCROLL_Y, scrollOffset.y()); |
629 | 613 |
630 const gfx::Point& minScrollOffset = src.minimumScrollOffset(); | 614 const gfx::Point& minScrollOffset = src.minimumScrollOffset(); |
631 dst->AddIntAttribute(ui::AX_ATTR_SCROLL_X_MIN, minScrollOffset.x()); | 615 dst->AddIntAttribute(ui::AX_ATTR_SCROLL_X_MIN, minScrollOffset.x()); |
632 dst->AddIntAttribute(ui::AX_ATTR_SCROLL_Y_MIN, minScrollOffset.y()); | 616 dst->AddIntAttribute(ui::AX_ATTR_SCROLL_Y_MIN, minScrollOffset.y()); |
633 | 617 |
634 const gfx::Point& maxScrollOffset = src.maximumScrollOffset(); | 618 const gfx::Point& maxScrollOffset = src.maximumScrollOffset(); |
635 dst->AddIntAttribute(ui::AX_ATTR_SCROLL_X_MAX, maxScrollOffset.x()); | 619 dst->AddIntAttribute(ui::AX_ATTR_SCROLL_X_MAX, maxScrollOffset.x()); |
636 dst->AddIntAttribute(ui::AX_ATTR_SCROLL_Y_MAX, maxScrollOffset.y()); | 620 dst->AddIntAttribute(ui::AX_ATTR_SCROLL_Y_MAX, maxScrollOffset.y()); |
637 } | 621 } |
638 } | 622 } |
639 | 623 |
640 blink::WebDocument BlinkAXTreeSource::GetMainDocument() const { | 624 blink::WebDocument BlinkAXTreeSource::GetMainDocument() const { |
641 if (render_frame_ && render_frame_->GetWebFrame()) | 625 if (render_frame_ && render_frame_->GetWebFrame()) |
642 return render_frame_->GetWebFrame()->document(); | 626 return render_frame_->GetWebFrame()->document(); |
643 return WebDocument(); | 627 return WebDocument(); |
644 } | 628 } |
645 | 629 |
646 } // namespace content | 630 } // namespace content |
OLD | NEW |