| Index: content/renderer/accessibility/blink_ax_tree_source.cc
|
| diff --git a/content/renderer/accessibility/blink_ax_tree_source.cc b/content/renderer/accessibility/blink_ax_tree_source.cc
|
| index bd9b01cab0b8ba99d4efac4c2eedd807733257ed..0b4f56c3ec6d188d151edd2e3a46dea0a9a8f544 100644
|
| --- a/content/renderer/accessibility/blink_ax_tree_source.cc
|
| +++ b/content/renderer/accessibility/blink_ax_tree_source.cc
|
| @@ -128,8 +128,10 @@ ScopedFreezeBlinkAXTreeSource::~ScopedFreezeBlinkAXTreeSource() {
|
| tree_source_->Thaw();
|
| }
|
|
|
| -BlinkAXTreeSource::BlinkAXTreeSource(RenderFrameImpl* render_frame)
|
| +BlinkAXTreeSource::BlinkAXTreeSource(RenderFrameImpl* render_frame,
|
| + AccessibilityMode mode)
|
| : render_frame_(render_frame),
|
| + accessibility_mode_(mode),
|
| frozen_(false) {}
|
|
|
| BlinkAXTreeSource::~BlinkAXTreeSource() {
|
| @@ -341,10 +343,6 @@ void BlinkAXTreeSource::SerializeNode(blink::WebAXObject src,
|
| ui::AX_ATTR_DESCRIBEDBY_IDS, descriptionObjects, dst);
|
| }
|
|
|
| - blink::WebString web_placeholder = src.placeholder(nameFrom);
|
| - if (!web_placeholder.isEmpty())
|
| - dst->AddStringAttribute(ui::AX_ATTR_PLACEHOLDER, web_placeholder.utf8());
|
| -
|
| std::string value;
|
| if (src.valueDescription().length()) {
|
| dst->AddStringAttribute(ui::AX_ATTR_VALUE, src.valueDescription().utf8());
|
| @@ -352,178 +350,300 @@ void BlinkAXTreeSource::SerializeNode(blink::WebAXObject src,
|
| dst->AddStringAttribute(ui::AX_ATTR_VALUE, src.stringValue().utf8());
|
| }
|
|
|
| - if (dst->role == ui::AX_ROLE_COLOR_WELL)
|
| - dst->AddIntAttribute(ui::AX_ATTR_COLOR_VALUE, src.colorValue());
|
| + if (src.isButtonStateMixed())
|
| + dst->AddBoolAttribute(ui::AX_ATTR_STATE_MIXED, true);
|
|
|
| + if (src.canSetValueAttribute())
|
| + dst->AddBoolAttribute(ui::AX_ATTR_CAN_SET_VALUE, true);
|
|
|
| - // Text attributes.
|
| - if (src.backgroundColor())
|
| - dst->AddIntAttribute(ui::AX_ATTR_BACKGROUND_COLOR, src.backgroundColor());
|
| + if (!src.url().isEmpty())
|
| + dst->AddStringAttribute(ui::AX_ATTR_URL, src.url().string().utf8());
|
|
|
| - if (src.color())
|
| - dst->AddIntAttribute(ui::AX_ATTR_COLOR, src.color());
|
| + // The following set of attributes are only accessed when the accessibility
|
| + // mode is set to screen reader mode, otherwise only the more basic
|
| + // attributes are populated.
|
| + if (accessibility_mode_ & ACCESSIBILITY_MODE_FLAG_SCREEN_READER) {
|
| + blink::WebString web_placeholder = src.placeholder(nameFrom);
|
| + if (!web_placeholder.isEmpty())
|
| + dst->AddStringAttribute(ui::AX_ATTR_PLACEHOLDER, web_placeholder.utf8());
|
| +
|
| + if (dst->role == ui::AX_ROLE_COLOR_WELL)
|
| + dst->AddIntAttribute(ui::AX_ATTR_COLOR_VALUE, src.colorValue());
|
| +
|
| + // Text attributes.
|
| + if (src.backgroundColor())
|
| + dst->AddIntAttribute(ui::AX_ATTR_BACKGROUND_COLOR, src.backgroundColor());
|
| +
|
| + if (src.color())
|
| + dst->AddIntAttribute(ui::AX_ATTR_COLOR, src.color());
|
| +
|
| + WebAXObject parent = ParentObjectUnignored(src);
|
| + if (src.fontFamily().length()) {
|
| + if (parent.isNull() || parent.fontFamily() != src.fontFamily())
|
| + dst->AddStringAttribute(ui::AX_ATTR_FONT_FAMILY,
|
| + src.fontFamily().utf8());
|
| + }
|
|
|
| - WebAXObject parent = ParentObjectUnignored(src);
|
| - if (src.fontFamily().length()) {
|
| - if (parent.isNull() || parent.fontFamily() != src.fontFamily())
|
| - dst->AddStringAttribute(ui::AX_ATTR_FONT_FAMILY, src.fontFamily().utf8());
|
| - }
|
| + // Font size is in pixels.
|
| + if (src.fontSize())
|
| + dst->AddFloatAttribute(ui::AX_ATTR_FONT_SIZE, src.fontSize());
|
|
|
| - // Font size is in pixels.
|
| - if (src.fontSize())
|
| - dst->AddFloatAttribute(ui::AX_ATTR_FONT_SIZE, src.fontSize());
|
| + if (src.ariaCurrentState()) {
|
| + dst->AddIntAttribute(ui::AX_ATTR_ARIA_CURRENT_STATE,
|
| + AXAriaCurrentStateFromBlink(src.ariaCurrentState()));
|
| + }
|
|
|
| - if (src.ariaCurrentState()) {
|
| - dst->AddIntAttribute(ui::AX_ATTR_ARIA_CURRENT_STATE,
|
| - AXAriaCurrentStateFromBlink(src.ariaCurrentState()));
|
| - }
|
| + if (src.invalidState()) {
|
| + dst->AddIntAttribute(ui::AX_ATTR_INVALID_STATE,
|
| + AXInvalidStateFromBlink(src.invalidState()));
|
| + }
|
| + if (src.invalidState() == blink::WebAXInvalidStateOther &&
|
| + src.ariaInvalidValue().length()) {
|
| + dst->AddStringAttribute(
|
| + ui::AX_ATTR_ARIA_INVALID_VALUE, src.ariaInvalidValue().utf8());
|
| + }
|
|
|
| - if (src.invalidState()) {
|
| - dst->AddIntAttribute(ui::AX_ATTR_INVALID_STATE,
|
| - AXInvalidStateFromBlink(src.invalidState()));
|
| - }
|
| - if (src.invalidState() == blink::WebAXInvalidStateOther &&
|
| - src.ariaInvalidValue().length()) {
|
| - dst->AddStringAttribute(
|
| - ui::AX_ATTR_ARIA_INVALID_VALUE, src.ariaInvalidValue().utf8());
|
| - }
|
| + if (src.textDirection()) {
|
| + dst->AddIntAttribute(ui::AX_ATTR_TEXT_DIRECTION,
|
| + AXTextDirectionFromBlink(src.textDirection()));
|
| + }
|
|
|
| - if (src.textDirection()) {
|
| - dst->AddIntAttribute(ui::AX_ATTR_TEXT_DIRECTION,
|
| - AXTextDirectionFromBlink(src.textDirection()));
|
| - }
|
| + if (src.textStyle()) {
|
| + dst->AddIntAttribute(ui::AX_ATTR_TEXT_STYLE,
|
| + AXTextStyleFromBlink(src.textStyle()));
|
| + }
|
|
|
| - if (src.textStyle()) {
|
| - dst->AddIntAttribute(ui::AX_ATTR_TEXT_STYLE,
|
| - AXTextStyleFromBlink(src.textStyle()));
|
| - }
|
| + if (dst->role == ui::AX_ROLE_INLINE_TEXT_BOX) {
|
| + WebVector<int> src_character_offsets;
|
| + src.characterOffsets(src_character_offsets);
|
| + std::vector<int32_t> character_offsets;
|
| + character_offsets.reserve(src_character_offsets.size());
|
| + for (size_t i = 0; i < src_character_offsets.size(); ++i)
|
| + character_offsets.push_back(src_character_offsets[i]);
|
| + dst->AddIntListAttribute(ui::AX_ATTR_CHARACTER_OFFSETS,
|
| + character_offsets);
|
| +
|
| + WebVector<int> src_word_starts;
|
| + WebVector<int> src_word_ends;
|
| + src.wordBoundaries(src_word_starts, src_word_ends);
|
| + std::vector<int32_t> word_starts;
|
| + std::vector<int32_t> word_ends;
|
| + word_starts.reserve(src_word_starts.size());
|
| + word_ends.reserve(src_word_starts.size());
|
| + for (size_t i = 0; i < src_word_starts.size(); ++i) {
|
| + word_starts.push_back(src_word_starts[i]);
|
| + word_ends.push_back(src_word_ends[i]);
|
| + }
|
| + dst->AddIntListAttribute(ui::AX_ATTR_WORD_STARTS, word_starts);
|
| + dst->AddIntListAttribute(ui::AX_ATTR_WORD_ENDS, word_ends);
|
| + }
|
|
|
| + if (src.accessKey().length()) {
|
| + dst->AddStringAttribute(ui::AX_ATTR_ACCESS_KEY, src.accessKey().utf8());
|
| + }
|
|
|
| - if (dst->role == ui::AX_ROLE_INLINE_TEXT_BOX) {
|
| - WebVector<int> src_character_offsets;
|
| - src.characterOffsets(src_character_offsets);
|
| - std::vector<int32_t> character_offsets;
|
| - character_offsets.reserve(src_character_offsets.size());
|
| - for (size_t i = 0; i < src_character_offsets.size(); ++i)
|
| - character_offsets.push_back(src_character_offsets[i]);
|
| - dst->AddIntListAttribute(ui::AX_ATTR_CHARACTER_OFFSETS, character_offsets);
|
| -
|
| - WebVector<int> src_word_starts;
|
| - WebVector<int> src_word_ends;
|
| - src.wordBoundaries(src_word_starts, src_word_ends);
|
| - std::vector<int32_t> word_starts;
|
| - std::vector<int32_t> word_ends;
|
| - word_starts.reserve(src_word_starts.size());
|
| - word_ends.reserve(src_word_starts.size());
|
| - for (size_t i = 0; i < src_word_starts.size(); ++i) {
|
| - word_starts.push_back(src_word_starts[i]);
|
| - word_ends.push_back(src_word_ends[i]);
|
| - }
|
| - dst->AddIntListAttribute(ui::AX_ATTR_WORD_STARTS, word_starts);
|
| - dst->AddIntListAttribute(ui::AX_ATTR_WORD_ENDS, word_ends);
|
| - }
|
| + if (src.ariaAutoComplete().length()) {
|
| + dst->AddStringAttribute(
|
| + ui::AX_ATTR_AUTO_COMPLETE,
|
| + src.ariaAutoComplete().utf8());
|
| + }
|
|
|
| - if (src.accessKey().length()) {
|
| - dst->AddStringAttribute(ui::AX_ATTR_ACCESS_KEY, src.accessKey().utf8());
|
| - }
|
| + if (src.action() != blink::WebAXSupportedAction::None) {
|
| + dst->AddIntAttribute(ui::AX_ATTR_ACTION,
|
| + AXSupportedActionFromBlink(src.action()));
|
| + }
|
|
|
| - if (src.action() != blink::WebAXSupportedAction::None) {
|
| - dst->AddIntAttribute(ui::AX_ATTR_ACTION,
|
| - AXSupportedActionFromBlink(src.action()));
|
| - }
|
| + if (src.isAriaReadOnly())
|
| + dst->AddBoolAttribute(ui::AX_ATTR_ARIA_READONLY, true);
|
|
|
| - if (src.ariaAutoComplete().length()) {
|
| - dst->AddStringAttribute(
|
| - ui::AX_ATTR_AUTO_COMPLETE,
|
| - src.ariaAutoComplete().utf8());
|
| - }
|
| + if (src.hasComputedStyle()) {
|
| + dst->AddStringAttribute(
|
| + ui::AX_ATTR_DISPLAY, src.computedStyleDisplay().utf8());
|
| + }
|
|
|
| - if (src.isAriaReadOnly())
|
| - dst->AddBoolAttribute(ui::AX_ATTR_ARIA_READONLY, true);
|
| + if (src.language().length()) {
|
| + if (parent.isNull() || parent.language() != src.language())
|
| + dst->AddStringAttribute(ui::AX_ATTR_LANGUAGE, src.language().utf8());
|
| + }
|
|
|
| - if (src.isButtonStateMixed())
|
| - dst->AddBoolAttribute(ui::AX_ATTR_STATE_MIXED, true);
|
| + if (src.keyboardShortcut().length()) {
|
| + dst->AddStringAttribute(
|
| + ui::AX_ATTR_SHORTCUT,
|
| + src.keyboardShortcut().utf8());
|
| + }
|
|
|
| - if (src.canSetValueAttribute())
|
| - dst->AddBoolAttribute(ui::AX_ATTR_CAN_SET_VALUE, true);
|
| + if (!src.nextOnLine().isDetached()) {
|
| + dst->AddIntAttribute(ui::AX_ATTR_NEXT_ON_LINE_ID,
|
| + src.nextOnLine().axID());
|
| + }
|
|
|
| - if (src.hasComputedStyle()) {
|
| - dst->AddStringAttribute(
|
| - ui::AX_ATTR_DISPLAY, src.computedStyleDisplay().utf8());
|
| - }
|
| + if (!src.previousOnLine().isDetached()) {
|
| + dst->AddIntAttribute(ui::AX_ATTR_PREVIOUS_ON_LINE_ID,
|
| + src.previousOnLine().axID());
|
| + }
|
|
|
| - if (src.language().length()) {
|
| - if (parent.isNull() || parent.language() != src.language())
|
| - dst->AddStringAttribute(ui::AX_ATTR_LANGUAGE, src.language().utf8());
|
| - }
|
| + if (!src.ariaActiveDescendant().isDetached()) {
|
| + dst->AddIntAttribute(ui::AX_ATTR_ACTIVEDESCENDANT_ID,
|
| + src.ariaActiveDescendant().axID());
|
| + }
|
|
|
| - if (src.keyboardShortcut().length()) {
|
| - dst->AddStringAttribute(
|
| - ui::AX_ATTR_SHORTCUT,
|
| - src.keyboardShortcut().utf8());
|
| - }
|
| + if (dst->role == ui::AX_ROLE_HEADING && src.headingLevel()) {
|
| + dst->AddIntAttribute(ui::AX_ATTR_HIERARCHICAL_LEVEL, src.headingLevel());
|
| + } else if ((dst->role == ui::AX_ROLE_TREE_ITEM ||
|
| + dst->role == ui::AX_ROLE_ROW) &&
|
| + src.hierarchicalLevel()) {
|
| + dst->AddIntAttribute(ui::AX_ATTR_HIERARCHICAL_LEVEL,
|
| + src.hierarchicalLevel());
|
| + }
|
|
|
| - if (!src.nextOnLine().isDetached()) {
|
| - dst->AddIntAttribute(ui::AX_ATTR_NEXT_ON_LINE_ID, src.nextOnLine().axID());
|
| - }
|
| + if (src.setSize())
|
| + dst->AddIntAttribute(ui::AX_ATTR_SET_SIZE, src.setSize());
|
| +
|
| + if (src.posInSet())
|
| + dst->AddIntAttribute(ui::AX_ATTR_POS_IN_SET, src.posInSet());
|
| +
|
| + if (src.canvasHasFallbackContent())
|
| + dst->AddBoolAttribute(ui::AX_ATTR_CANVAS_HAS_FALLBACK, true);
|
| +
|
| + // Spelling, grammar and other document markers.
|
| + WebVector<blink::WebAXMarkerType> src_marker_types;
|
| + WebVector<int> src_marker_starts;
|
| + WebVector<int> src_marker_ends;
|
| + src.markers(src_marker_types, src_marker_starts, src_marker_ends);
|
| + DCHECK_EQ(src_marker_types.size(), src_marker_starts.size());
|
| + DCHECK_EQ(src_marker_starts.size(), src_marker_ends.size());
|
| +
|
| + if (src_marker_types.size()) {
|
| + std::vector<int32_t> marker_types;
|
| + std::vector<int32_t> marker_starts;
|
| + std::vector<int32_t> marker_ends;
|
| + marker_types.reserve(src_marker_types.size());
|
| + marker_starts.reserve(src_marker_starts.size());
|
| + marker_ends.reserve(src_marker_ends.size());
|
| + for (size_t i = 0; i < src_marker_types.size(); ++i) {
|
| + marker_types.push_back(
|
| + static_cast<int32_t>(AXMarkerTypeFromBlink(src_marker_types[i])));
|
| + marker_starts.push_back(src_marker_starts[i]);
|
| + marker_ends.push_back(src_marker_ends[i]);
|
| + }
|
| + dst->AddIntListAttribute(ui::AX_ATTR_MARKER_TYPES, marker_types);
|
| + dst->AddIntListAttribute(ui::AX_ATTR_MARKER_STARTS, marker_starts);
|
| + dst->AddIntListAttribute(ui::AX_ATTR_MARKER_ENDS, marker_ends);
|
| + }
|
|
|
| - if (!src.previousOnLine().isDetached()) {
|
| - dst->AddIntAttribute(ui::AX_ATTR_PREVIOUS_ON_LINE_ID,
|
| - src.previousOnLine().axID());
|
| - }
|
| + if (src.isInLiveRegion()) {
|
| + dst->AddBoolAttribute(ui::AX_ATTR_LIVE_ATOMIC, src.liveRegionAtomic());
|
| + dst->AddBoolAttribute(ui::AX_ATTR_LIVE_BUSY, src.liveRegionBusy());
|
| + if (src.liveRegionBusy())
|
| + dst->state |= (1 << ui::AX_STATE_BUSY);
|
| + if (!src.liveRegionStatus().isEmpty()) {
|
| + dst->AddStringAttribute(
|
| + ui::AX_ATTR_LIVE_STATUS,
|
| + src.liveRegionStatus().utf8());
|
| + }
|
| + dst->AddStringAttribute(
|
| + ui::AX_ATTR_LIVE_RELEVANT,
|
| + src.liveRegionRelevant().utf8());
|
| + // If we are not at the root of an atomic live region.
|
| + if (src.containerLiveRegionAtomic() &&
|
| + !src.liveRegionRoot().isDetached() &&
|
| + !src.liveRegionAtomic()) {
|
| + dst->AddIntAttribute(ui::AX_ATTR_MEMBER_OF_ID,
|
| + src.liveRegionRoot().axID());
|
| + }
|
| + dst->AddBoolAttribute(ui::AX_ATTR_CONTAINER_LIVE_ATOMIC,
|
| + src.containerLiveRegionAtomic());
|
| + dst->AddBoolAttribute(ui::AX_ATTR_CONTAINER_LIVE_BUSY,
|
| + src.containerLiveRegionBusy());
|
| + dst->AddStringAttribute(
|
| + ui::AX_ATTR_CONTAINER_LIVE_STATUS,
|
| + src.containerLiveRegionStatus().utf8());
|
| + dst->AddStringAttribute(
|
| + ui::AX_ATTR_CONTAINER_LIVE_RELEVANT,
|
| + src.containerLiveRegionRelevant().utf8());
|
| + }
|
|
|
| - if (!src.ariaActiveDescendant().isDetached()) {
|
| - dst->AddIntAttribute(ui::AX_ATTR_ACTIVEDESCENDANT_ID,
|
| - src.ariaActiveDescendant().axID());
|
| - }
|
| + if (dst->role == ui::AX_ROLE_PROGRESS_INDICATOR ||
|
| + dst->role == ui::AX_ROLE_METER ||
|
| + dst->role == ui::AX_ROLE_SCROLL_BAR ||
|
| + dst->role == ui::AX_ROLE_SLIDER ||
|
| + dst->role == ui::AX_ROLE_SPIN_BUTTON) {
|
| + dst->AddFloatAttribute(ui::AX_ATTR_VALUE_FOR_RANGE, src.valueForRange());
|
| + dst->AddFloatAttribute(ui::AX_ATTR_MAX_VALUE_FOR_RANGE,
|
| + src.maxValueForRange());
|
| + dst->AddFloatAttribute(ui::AX_ATTR_MIN_VALUE_FOR_RANGE,
|
| + src.minValueForRange());
|
| + }
|
|
|
| - if (!src.url().isEmpty())
|
| - dst->AddStringAttribute(ui::AX_ATTR_URL, src.url().string().utf8());
|
| + if (dst->role == ui::AX_ROLE_ROOT_WEB_AREA)
|
| + dst->AddStringAttribute(ui::AX_ATTR_HTML_TAG, "#document");
|
| +
|
| + if (dst->role == ui::AX_ROLE_TABLE) {
|
| + int column_count = src.columnCount();
|
| + int row_count = src.rowCount();
|
| + if (column_count > 0 && row_count > 0) {
|
| + std::set<int32_t> unique_cell_id_set;
|
| + std::vector<int32_t> cell_ids;
|
| + std::vector<int32_t> unique_cell_ids;
|
| + dst->AddIntAttribute(ui::AX_ATTR_TABLE_COLUMN_COUNT, column_count);
|
| + dst->AddIntAttribute(ui::AX_ATTR_TABLE_ROW_COUNT, row_count);
|
| + WebAXObject header = src.headerContainerObject();
|
| + if (!header.isDetached())
|
| + dst->AddIntAttribute(ui::AX_ATTR_TABLE_HEADER_ID, header.axID());
|
| + for (int i = 0; i < column_count * row_count; ++i) {
|
| + WebAXObject cell = src.cellForColumnAndRow(
|
| + i % column_count, i / column_count);
|
| + int cell_id = -1;
|
| + if (!cell.isDetached()) {
|
| + cell_id = cell.axID();
|
| + if (unique_cell_id_set.find(cell_id) == unique_cell_id_set.end()) {
|
| + unique_cell_id_set.insert(cell_id);
|
| + unique_cell_ids.push_back(cell_id);
|
| + }
|
| + }
|
| + cell_ids.push_back(cell_id);
|
| + }
|
| + dst->AddIntListAttribute(ui::AX_ATTR_CELL_IDS, cell_ids);
|
| + dst->AddIntListAttribute(ui::AX_ATTR_UNIQUE_CELL_IDS, unique_cell_ids);
|
| + }
|
| + }
|
|
|
| - if (dst->role == ui::AX_ROLE_HEADING && src.headingLevel()) {
|
| - dst->AddIntAttribute(ui::AX_ATTR_HIERARCHICAL_LEVEL, src.headingLevel());
|
| - } else if ((dst->role == ui::AX_ROLE_TREE_ITEM ||
|
| - dst->role == ui::AX_ROLE_ROW) &&
|
| - src.hierarchicalLevel()) {
|
| - dst->AddIntAttribute(ui::AX_ATTR_HIERARCHICAL_LEVEL,
|
| - src.hierarchicalLevel());
|
| - }
|
| + if (dst->role == ui::AX_ROLE_ROW) {
|
| + dst->AddIntAttribute(ui::AX_ATTR_TABLE_ROW_INDEX, src.rowIndex());
|
| + WebAXObject header = src.rowHeader();
|
| + if (!header.isDetached())
|
| + dst->AddIntAttribute(ui::AX_ATTR_TABLE_ROW_HEADER_ID, header.axID());
|
| + }
|
| +
|
| + if (dst->role == ui::AX_ROLE_COLUMN) {
|
| + dst->AddIntAttribute(ui::AX_ATTR_TABLE_COLUMN_INDEX, src.columnIndex());
|
| + WebAXObject header = src.columnHeader();
|
| + if (!header.isDetached())
|
| + dst->AddIntAttribute(ui::AX_ATTR_TABLE_COLUMN_HEADER_ID, header.axID());
|
| + }
|
| +
|
| + if (dst->role == ui::AX_ROLE_CELL ||
|
| + dst->role == ui::AX_ROLE_ROW_HEADER ||
|
| + dst->role == ui::AX_ROLE_COLUMN_HEADER) {
|
| + dst->AddIntAttribute(ui::AX_ATTR_TABLE_CELL_COLUMN_INDEX,
|
| + src.cellColumnIndex());
|
| + dst->AddIntAttribute(ui::AX_ATTR_TABLE_CELL_COLUMN_SPAN,
|
| + src.cellColumnSpan());
|
| + dst->AddIntAttribute(ui::AX_ATTR_TABLE_CELL_ROW_INDEX,
|
| + src.cellRowIndex());
|
| + dst->AddIntAttribute(ui::AX_ATTR_TABLE_CELL_ROW_SPAN, src.cellRowSpan());
|
| + }
|
|
|
| - if (src.setSize())
|
| - dst->AddIntAttribute(ui::AX_ATTR_SET_SIZE, src.setSize());
|
| -
|
| - if (src.posInSet())
|
| - dst->AddIntAttribute(ui::AX_ATTR_POS_IN_SET, src.posInSet());
|
| -
|
| - if (src.canvasHasFallbackContent())
|
| - dst->AddBoolAttribute(ui::AX_ATTR_CANVAS_HAS_FALLBACK, true);
|
| -
|
| - // Spelling, grammar and other document markers.
|
| - WebVector<blink::WebAXMarkerType> src_marker_types;
|
| - WebVector<int> src_marker_starts;
|
| - WebVector<int> src_marker_ends;
|
| - src.markers(src_marker_types, src_marker_starts, src_marker_ends);
|
| - DCHECK_EQ(src_marker_types.size(), src_marker_starts.size());
|
| - DCHECK_EQ(src_marker_starts.size(), src_marker_ends.size());
|
| -
|
| - if (src_marker_types.size()) {
|
| - std::vector<int32_t> marker_types;
|
| - std::vector<int32_t> marker_starts;
|
| - std::vector<int32_t> marker_ends;
|
| - marker_types.reserve(src_marker_types.size());
|
| - marker_starts.reserve(src_marker_starts.size());
|
| - marker_ends.reserve(src_marker_ends.size());
|
| - for (size_t i = 0; i < src_marker_types.size(); ++i) {
|
| - marker_types.push_back(
|
| - static_cast<int32_t>(AXMarkerTypeFromBlink(src_marker_types[i])));
|
| - marker_starts.push_back(src_marker_starts[i]);
|
| - marker_ends.push_back(src_marker_ends[i]);
|
| - }
|
| - dst->AddIntListAttribute(ui::AX_ATTR_MARKER_TYPES, marker_types);
|
| - dst->AddIntListAttribute(ui::AX_ATTR_MARKER_STARTS, marker_starts);
|
| - dst->AddIntListAttribute(ui::AX_ATTR_MARKER_ENDS, marker_ends);
|
| + if ((dst->role == ui::AX_ROLE_ROW_HEADER ||
|
| + dst->role == ui::AX_ROLE_COLUMN_HEADER) && src.sortDirection()) {
|
| + dst->AddIntAttribute(ui::AX_ATTR_SORT_DIRECTION,
|
| + AXSortDirectionFromBlink(src.sortDirection()));
|
| + }
|
| }
|
|
|
| + // The majority of the rest of this code computes attributes needed for
|
| + // all modes, not just for screen readers.
|
| +
|
| WebNode node = src.node();
|
| bool is_iframe = false;
|
|
|
| @@ -531,17 +651,19 @@ void BlinkAXTreeSource::SerializeNode(blink::WebAXObject src,
|
| WebElement element = node.to<WebElement>();
|
| is_iframe = element.hasHTMLTagName("iframe");
|
|
|
| - // TODO(ctguil): The tagName in WebKit is lower cased but
|
| - // HTMLElement::nodeName calls localNameUpper. Consider adding
|
| - // a WebElement method that returns the original lower cased tagName.
|
| - dst->AddStringAttribute(
|
| - ui::AX_ATTR_HTML_TAG,
|
| - base::ToLowerASCII(element.tagName().utf8()));
|
| - for (unsigned i = 0; i < element.attributeCount(); ++i) {
|
| - std::string name = base::ToLowerASCII(
|
| - element.attributeLocalName(i).utf8());
|
| - std::string value = element.attributeValue(i).utf8();
|
| - dst->html_attributes.push_back(std::make_pair(name, value));
|
| + if (accessibility_mode_ & ACCESSIBILITY_MODE_FLAG_HTML) {
|
| + // TODO(ctguil): The tagName in WebKit is lower cased but
|
| + // HTMLElement::nodeName calls localNameUpper. Consider adding
|
| + // a WebElement method that returns the original lower cased tagName.
|
| + dst->AddStringAttribute(
|
| + ui::AX_ATTR_HTML_TAG,
|
| + base::ToLowerASCII(element.tagName().utf8()));
|
| + for (unsigned i = 0; i < element.attributeCount(); ++i) {
|
| + std::string name = base::ToLowerASCII(
|
| + element.attributeLocalName(i).utf8());
|
| + std::string value = element.attributeValue(i).utf8();
|
| + dst->html_attributes.push_back(std::make_pair(name, value));
|
| + }
|
| }
|
|
|
| if (src.isEditable()) {
|
| @@ -592,113 +714,6 @@ void BlinkAXTreeSource::SerializeNode(blink::WebAXObject src,
|
| }
|
| }
|
|
|
| - if (src.isInLiveRegion()) {
|
| - dst->AddBoolAttribute(ui::AX_ATTR_LIVE_ATOMIC, src.liveRegionAtomic());
|
| - dst->AddBoolAttribute(ui::AX_ATTR_LIVE_BUSY, src.liveRegionBusy());
|
| - if (src.liveRegionBusy())
|
| - dst->state |= (1 << ui::AX_STATE_BUSY);
|
| - if (!src.liveRegionStatus().isEmpty()) {
|
| - dst->AddStringAttribute(
|
| - ui::AX_ATTR_LIVE_STATUS,
|
| - src.liveRegionStatus().utf8());
|
| - }
|
| - dst->AddStringAttribute(
|
| - ui::AX_ATTR_LIVE_RELEVANT,
|
| - src.liveRegionRelevant().utf8());
|
| - // If we are not at the root of an atomic live region.
|
| - if (src.containerLiveRegionAtomic() && !src.liveRegionRoot().isDetached() &&
|
| - !src.liveRegionAtomic()) {
|
| - dst->AddIntAttribute(ui::AX_ATTR_MEMBER_OF_ID,
|
| - src.liveRegionRoot().axID());
|
| - }
|
| - dst->AddBoolAttribute(ui::AX_ATTR_CONTAINER_LIVE_ATOMIC,
|
| - src.containerLiveRegionAtomic());
|
| - dst->AddBoolAttribute(ui::AX_ATTR_CONTAINER_LIVE_BUSY,
|
| - src.containerLiveRegionBusy());
|
| - dst->AddStringAttribute(
|
| - ui::AX_ATTR_CONTAINER_LIVE_STATUS,
|
| - src.containerLiveRegionStatus().utf8());
|
| - dst->AddStringAttribute(
|
| - ui::AX_ATTR_CONTAINER_LIVE_RELEVANT,
|
| - src.containerLiveRegionRelevant().utf8());
|
| - }
|
| -
|
| - if (dst->role == ui::AX_ROLE_PROGRESS_INDICATOR ||
|
| - dst->role == ui::AX_ROLE_METER ||
|
| - dst->role == ui::AX_ROLE_SCROLL_BAR ||
|
| - dst->role == ui::AX_ROLE_SLIDER ||
|
| - dst->role == ui::AX_ROLE_SPIN_BUTTON) {
|
| - dst->AddFloatAttribute(ui::AX_ATTR_VALUE_FOR_RANGE, src.valueForRange());
|
| - dst->AddFloatAttribute(ui::AX_ATTR_MAX_VALUE_FOR_RANGE,
|
| - src.maxValueForRange());
|
| - dst->AddFloatAttribute(ui::AX_ATTR_MIN_VALUE_FOR_RANGE,
|
| - src.minValueForRange());
|
| - }
|
| -
|
| - if (dst->role == ui::AX_ROLE_ROOT_WEB_AREA)
|
| - dst->AddStringAttribute(ui::AX_ATTR_HTML_TAG, "#document");
|
| -
|
| - if (dst->role == ui::AX_ROLE_TABLE) {
|
| - int column_count = src.columnCount();
|
| - int row_count = src.rowCount();
|
| - if (column_count > 0 && row_count > 0) {
|
| - std::set<int32_t> unique_cell_id_set;
|
| - std::vector<int32_t> cell_ids;
|
| - std::vector<int32_t> unique_cell_ids;
|
| - dst->AddIntAttribute(ui::AX_ATTR_TABLE_COLUMN_COUNT, column_count);
|
| - dst->AddIntAttribute(ui::AX_ATTR_TABLE_ROW_COUNT, row_count);
|
| - WebAXObject header = src.headerContainerObject();
|
| - if (!header.isDetached())
|
| - dst->AddIntAttribute(ui::AX_ATTR_TABLE_HEADER_ID, header.axID());
|
| - for (int i = 0; i < column_count * row_count; ++i) {
|
| - WebAXObject cell = src.cellForColumnAndRow(
|
| - i % column_count, i / column_count);
|
| - int cell_id = -1;
|
| - if (!cell.isDetached()) {
|
| - cell_id = cell.axID();
|
| - if (unique_cell_id_set.find(cell_id) == unique_cell_id_set.end()) {
|
| - unique_cell_id_set.insert(cell_id);
|
| - unique_cell_ids.push_back(cell_id);
|
| - }
|
| - }
|
| - cell_ids.push_back(cell_id);
|
| - }
|
| - dst->AddIntListAttribute(ui::AX_ATTR_CELL_IDS, cell_ids);
|
| - dst->AddIntListAttribute(ui::AX_ATTR_UNIQUE_CELL_IDS, unique_cell_ids);
|
| - }
|
| - }
|
| -
|
| - if (dst->role == ui::AX_ROLE_ROW) {
|
| - dst->AddIntAttribute(ui::AX_ATTR_TABLE_ROW_INDEX, src.rowIndex());
|
| - WebAXObject header = src.rowHeader();
|
| - if (!header.isDetached())
|
| - dst->AddIntAttribute(ui::AX_ATTR_TABLE_ROW_HEADER_ID, header.axID());
|
| - }
|
| -
|
| - if (dst->role == ui::AX_ROLE_COLUMN) {
|
| - dst->AddIntAttribute(ui::AX_ATTR_TABLE_COLUMN_INDEX, src.columnIndex());
|
| - WebAXObject header = src.columnHeader();
|
| - if (!header.isDetached())
|
| - dst->AddIntAttribute(ui::AX_ATTR_TABLE_COLUMN_HEADER_ID, header.axID());
|
| - }
|
| -
|
| - if (dst->role == ui::AX_ROLE_CELL ||
|
| - dst->role == ui::AX_ROLE_ROW_HEADER ||
|
| - dst->role == ui::AX_ROLE_COLUMN_HEADER) {
|
| - dst->AddIntAttribute(ui::AX_ATTR_TABLE_CELL_COLUMN_INDEX,
|
| - src.cellColumnIndex());
|
| - dst->AddIntAttribute(ui::AX_ATTR_TABLE_CELL_COLUMN_SPAN,
|
| - src.cellColumnSpan());
|
| - dst->AddIntAttribute(ui::AX_ATTR_TABLE_CELL_ROW_INDEX, src.cellRowIndex());
|
| - dst->AddIntAttribute(ui::AX_ATTR_TABLE_CELL_ROW_SPAN, src.cellRowSpan());
|
| - }
|
| -
|
| - if ((dst->role == ui::AX_ROLE_ROW_HEADER ||
|
| - dst->role == ui::AX_ROLE_COLUMN_HEADER) && src.sortDirection()) {
|
| - dst->AddIntAttribute(ui::AX_ATTR_SORT_DIRECTION,
|
| - AXSortDirectionFromBlink(src.sortDirection()));
|
| - }
|
| -
|
| // Add the ids of *indirect* children - those who are children of this node,
|
| // but whose parent is *not* this node. One example is a table
|
| // cell, which is a child of both a row and a column. Because the cell's
|
|
|