Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(345)

Unified Diff: ui/accessibility/platform/ax_platform_node_win.cc

Issue 2975413002: Move ia2_attributes handling to AXPlatformNodeWin. (Closed)
Patch Set: Initial Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: ui/accessibility/platform/ax_platform_node_win.cc
diff --git a/ui/accessibility/platform/ax_platform_node_win.cc b/ui/accessibility/platform/ax_platform_node_win.cc
index ca9ef23a165e5e247c421f5fa581a03b3787fa71..df2e25f3719e6c2b8a66f08cf80b0e1e8052cc63 100644
--- a/ui/accessibility/platform/ax_platform_node_win.cc
+++ b/ui/accessibility/platform/ax_platform_node_win.cc
@@ -204,6 +204,48 @@ AXPlatformNodeWin::AXPlatformNodeWin() {
AXPlatformNodeWin::~AXPlatformNodeWin() {
}
+// Static
+void AXPlatformNodeWin::SanitizeStringAttributeForIA2(
+ const base::string16& input,
+ base::string16* output) {
+ DCHECK(output);
+ // According to the IA2 Spec, these characters need to be escaped with a
+ // backslash: backslash, colon, comma, equals and semicolon.
+ // Note that backslash must be replaced first.
+ base::ReplaceChars(input, L"\\", L"\\\\", output);
+ base::ReplaceChars(*output, L":", L"\\:", output);
+ base::ReplaceChars(*output, L",", L"\\,", output);
+ base::ReplaceChars(*output, L"=", L"\\=", output);
+ base::ReplaceChars(*output, L";", L"\\;", output);
+}
+
+void AXPlatformNodeWin::StringAttributeToIA2(ui::AXStringAttribute attribute,
+ const char* ia2_attr) {
+ base::string16 value;
+ if (GetString16Attribute(attribute, &value)) {
+ SanitizeStringAttributeForIA2(value, &value);
+ ia2_attributes_.push_back(base::ASCIIToUTF16(ia2_attr) + L":" + value);
+ }
+}
+
+void AXPlatformNodeWin::BoolAttributeToIA2(ui::AXBoolAttribute attribute,
+ const char* ia2_attr) {
+ bool value;
+ if (GetBoolAttribute(attribute, &value)) {
+ ia2_attributes_.push_back((base::ASCIIToUTF16(ia2_attr) + L":") +
+ (value ? L"true" : L"false"));
+ }
+}
+
+void AXPlatformNodeWin::IntAttributeToIA2(ui::AXIntAttribute attribute,
+ const char* ia2_attr) {
+ int value;
+ if (GetIntAttribute(attribute, &value)) {
+ ia2_attributes_.push_back(base::ASCIIToUTF16(ia2_attr) + L":" +
+ base::IntToString16(value));
+ }
+}
+
//
// AXPlatformNodeBase implementation.
//
@@ -2426,6 +2468,215 @@ int32_t AXPlatformNodeWin::IA2Role() {
return ia2_role;
}
+std::vector<base::string16> AXPlatformNodeWin::IA2Attributes() {
+ // maybe use a cache?
+ ia2_attributes_.clear();
dmazzoni 2017/07/17 08:27:18 It doesn't seem to make sense to store ia2_attribu
dougt 2017/07/17 19:28:27 Done.
+
+ // Expose some HTLM and ARIA attributes in the IAccessible2 attributes string.
+ // "display", "tag", and "xml-roles" have somewhat unusual names for
+ // historical reasons. Aside from that virtually every ARIA attribute
+ // is exposed in a really straightforward way, i.e. "aria-foo" is exposed
+ // as "foo".
+ StringAttributeToIA2(ui::AX_ATTR_DISPLAY, "display");
+ StringAttributeToIA2(ui::AX_ATTR_HTML_TAG, "tag");
+ StringAttributeToIA2(ui::AX_ATTR_ROLE, "xml-roles");
+ StringAttributeToIA2(ui::AX_ATTR_PLACEHOLDER, "placeholder");
+
+ StringAttributeToIA2(ui::AX_ATTR_AUTO_COMPLETE, "autocomplete");
+ StringAttributeToIA2(ui::AX_ATTR_ROLE_DESCRIPTION, "roledescription");
+ StringAttributeToIA2(ui::AX_ATTR_KEY_SHORTCUTS, "keyshortcuts");
+
+ IntAttributeToIA2(ui::AX_ATTR_HIERARCHICAL_LEVEL, "level");
+ IntAttributeToIA2(ui::AX_ATTR_SET_SIZE, "setsize");
+ IntAttributeToIA2(ui::AX_ATTR_POS_IN_SET, "posinset");
+
+ if (HasIntAttribute(ui::AX_ATTR_CHECKED_STATE))
+ ia2_attributes_.push_back(L"checkable:true");
+
+ // Expose live region attributes.
+ StringAttributeToIA2(ui::AX_ATTR_LIVE_STATUS, "live");
+ StringAttributeToIA2(ui::AX_ATTR_LIVE_RELEVANT, "relevant");
+ BoolAttributeToIA2(ui::AX_ATTR_LIVE_ATOMIC, "atomic");
+ BoolAttributeToIA2(ui::AX_ATTR_LIVE_BUSY, "busy");
+
+ // Expose container live region attributes.
+ StringAttributeToIA2(ui::AX_ATTR_CONTAINER_LIVE_STATUS, "container-live");
+ StringAttributeToIA2(ui::AX_ATTR_CONTAINER_LIVE_RELEVANT,
+ "container-relevant");
+ BoolAttributeToIA2(ui::AX_ATTR_CONTAINER_LIVE_ATOMIC, "container-atomic");
+ BoolAttributeToIA2(ui::AX_ATTR_CONTAINER_LIVE_BUSY, "container-busy");
+
+ // Expose the non-standard explicit-name IA2 attribute.
+ int name_from;
+ if (GetIntAttribute(ui::AX_ATTR_NAME_FROM, &name_from) &&
+ name_from != ui::AX_NAME_FROM_CONTENTS) {
+ ia2_attributes_.push_back(L"explicit-name:true");
+ }
+
+ // Expose the aria-current attribute.
+ int32_t aria_current_state;
+ if (GetIntAttribute(ui::AX_ATTR_ARIA_CURRENT_STATE, &aria_current_state)) {
+ switch (static_cast<ui::AXAriaCurrentState>(aria_current_state)) {
+ case ui::AX_ARIA_CURRENT_STATE_NONE:
+ break;
+ case ui::AX_ARIA_CURRENT_STATE_FALSE:
+ ia2_attributes_.push_back(L"current:false");
+ break;
+ case ui::AX_ARIA_CURRENT_STATE_TRUE:
+ ia2_attributes_.push_back(L"current:true");
+ break;
+ case ui::AX_ARIA_CURRENT_STATE_PAGE:
+ ia2_attributes_.push_back(L"current:page");
+ break;
+ case ui::AX_ARIA_CURRENT_STATE_STEP:
+ ia2_attributes_.push_back(L"current:step");
+ break;
+ case ui::AX_ARIA_CURRENT_STATE_LOCATION:
+ ia2_attributes_.push_back(L"current:location");
+ break;
+ case ui::AX_ARIA_CURRENT_STATE_DATE:
+ ia2_attributes_.push_back(L"current:date");
+ break;
+ case ui::AX_ARIA_CURRENT_STATE_TIME:
+ ia2_attributes_.push_back(L"current:time");
+ break;
+ }
+ }
+
+ // Expose table cell index.
+ if (ui::IsCellOrTableHeaderRole(GetData().role)) {
+ AXPlatformNodeBase* table = FromNativeViewAccessible(GetParent());
+
+ while (table && !ui::IsTableLikeRole(table->GetData().role))
+ table = FromNativeViewAccessible(table->GetParent());
+
+ if (table) {
+ const std::vector<int32_t>& unique_cell_ids =
+ table->GetIntListAttribute(ui::AX_ATTR_UNIQUE_CELL_IDS);
+ for (size_t i = 0; i < unique_cell_ids.size(); ++i) {
+ if (unique_cell_ids[i] == GetData().id) {
+ ia2_attributes_.push_back(base::string16(L"table-cell-index:") +
+ base::IntToString16(static_cast<int>(i)));
+ }
+ }
+ }
+ }
+
+ // Expose aria-colcount and aria-rowcount in a table, grid or treegrid.
+ if (ui::IsTableLikeRole(GetData().role)) {
+ IntAttributeToIA2(ui::AX_ATTR_ARIA_COLUMN_COUNT, "colcount");
+ IntAttributeToIA2(ui::AX_ATTR_ARIA_ROW_COUNT, "rowcount");
+ }
+
+ // Expose aria-colindex and aria-rowindex in a cell or row.
+ if (ui::IsCellOrTableHeaderRole(GetData().role) ||
+ GetData().role == ui::AX_ROLE_ROW) {
+ if (GetData().role != ui::AX_ROLE_ROW)
+ IntAttributeToIA2(ui::AX_ATTR_ARIA_CELL_COLUMN_INDEX, "colindex");
+ IntAttributeToIA2(ui::AX_ATTR_ARIA_CELL_ROW_INDEX, "rowindex");
+ }
+
+ // Expose row or column header sort direction.
+ int32_t sort_direction;
+ if ((MSAARole() == ROLE_SYSTEM_COLUMNHEADER ||
+ MSAARole() == ROLE_SYSTEM_ROWHEADER) &&
+ GetIntAttribute(ui::AX_ATTR_SORT_DIRECTION, &sort_direction)) {
+ switch (static_cast<ui::AXSortDirection>(sort_direction)) {
+ case ui::AX_SORT_DIRECTION_NONE:
+ break;
+ case ui::AX_SORT_DIRECTION_UNSORTED:
+ ia2_attributes_.push_back(L"sort:none");
+ break;
+ case ui::AX_SORT_DIRECTION_ASCENDING:
+ ia2_attributes_.push_back(L"sort:ascending");
+ break;
+ case ui::AX_SORT_DIRECTION_DESCENDING:
+ ia2_attributes_.push_back(L"sort:descending");
+ break;
+ case ui::AX_SORT_DIRECTION_OTHER:
+ ia2_attributes_.push_back(L"sort:other");
+ break;
+ }
+ }
+
+ if (ui::IsCellOrTableHeaderRole(GetData().role)) {
+ // Expose colspan attribute.
+ base::string16 colspan;
+ if (GetData().GetHtmlAttribute("aria-colspan", &colspan)) {
+ SanitizeStringAttributeForIA2(colspan, &colspan);
+ ia2_attributes_.push_back(L"colspan:" + colspan);
+ }
+ // Expose rowspan attribute.
+ base::string16 rowspan;
+ if (GetData().GetHtmlAttribute("aria-rowspan", &rowspan)) {
+ SanitizeStringAttributeForIA2(rowspan, &rowspan);
+ ia2_attributes_.push_back(L"rowspan:" + rowspan);
+ }
+ }
+
+ // Expose slider value.
+ if (IsRangeValueSupported()) {
+ base::string16 value = GetRangeValueText();
+ SanitizeStringAttributeForIA2(value, &value);
+ ia2_attributes_.push_back(L"valuetext:" + value);
+ }
+
+ // Expose dropeffect attribute.
+ base::string16 drop_effect;
+ if (GetData().GetHtmlAttribute("aria-dropeffect", &drop_effect)) {
+ SanitizeStringAttributeForIA2(drop_effect, &drop_effect);
+ ia2_attributes_.push_back(L"dropeffect:" + drop_effect);
+ }
+
+ // Expose grabbed attribute.
+ base::string16 grabbed;
+ if (GetData().GetHtmlAttribute("aria-grabbed", &grabbed)) {
+ SanitizeStringAttributeForIA2(grabbed, &grabbed);
+ ia2_attributes_.push_back(L"grabbed:" + grabbed);
+ }
+
+ // Expose class attribute.
+ base::string16 class_attr;
+ if (GetData().GetHtmlAttribute("class", &class_attr)) {
+ SanitizeStringAttributeForIA2(class_attr, &class_attr);
+ ia2_attributes_.push_back(L"class:" + class_attr);
+ }
+
+ // Expose datetime attribute.
+ base::string16 datetime;
+ if (GetData().role == ui::AX_ROLE_TIME &&
+ GetData().GetHtmlAttribute("datetime", &datetime)) {
+ SanitizeStringAttributeForIA2(datetime, &datetime);
+ ia2_attributes_.push_back(L"datetime:" + datetime);
+ }
+
+ // Expose id attribute.
+ base::string16 id;
+ if (GetData().GetHtmlAttribute("id", &id)) {
+ SanitizeStringAttributeForIA2(id, &id);
+ ia2_attributes_.push_back(L"id:" + id);
+ }
+
+ // Expose src attribute.
+ base::string16 src;
+ if (GetData().role == ui::AX_ROLE_IMAGE &&
+ GetData().GetHtmlAttribute("src", &src)) {
+ SanitizeStringAttributeForIA2(src, &src);
+ ia2_attributes_.push_back(L"src:" + src);
+ }
+
+ // Expose input-text type attribute.
+ base::string16 type;
+ base::string16 html_tag = GetString16Attribute(ui::AX_ATTR_HTML_TAG);
+ if (IsSimpleTextControl() && html_tag == L"input" &&
+ GetData().GetHtmlAttribute("type", &type)) {
+ SanitizeStringAttributeForIA2(type, &type);
+ ia2_attributes_.push_back(L"text-input-type:" + type);
+ }
+
+ return ia2_attributes_;
+}
+
bool AXPlatformNodeWin::ShouldNodeHaveReadonlyState(
const AXNodeData& data) const {
if (data.GetBoolAttribute(ui::AX_ATTR_ARIA_READONLY))

Powered by Google App Engine
This is Rietveld 408576698