| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/browser/accessibility/accessibility_tree_formatter.h" | 5 #include "content/browser/accessibility/accessibility_tree_formatter.h" |
| 6 | 6 |
| 7 #include <oleacc.h> | 7 #include <oleacc.h> |
| 8 #include <stddef.h> | 8 #include <stddef.h> |
| 9 #include <stdint.h> | 9 #include <stdint.h> |
| 10 | 10 |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 165 const BrowserAccessibility& node, base::DictionaryValue* dict) { | 165 const BrowserAccessibility& node, base::DictionaryValue* dict) { |
| 166 dict->SetInteger("id", node.GetId()); | 166 dict->SetInteger("id", node.GetId()); |
| 167 BrowserAccessibilityWin* ax_object = | 167 BrowserAccessibilityWin* ax_object = |
| 168 ToBrowserAccessibilityWin(const_cast<BrowserAccessibility*>(&node)); | 168 ToBrowserAccessibilityWin(const_cast<BrowserAccessibility*>(&node)); |
| 169 DCHECK(ax_object); | 169 DCHECK(ax_object); |
| 170 | 170 |
| 171 VARIANT variant_self; | 171 VARIANT variant_self; |
| 172 variant_self.vt = VT_I4; | 172 variant_self.vt = VT_I4; |
| 173 variant_self.lVal = CHILDID_SELF; | 173 variant_self.lVal = CHILDID_SELF; |
| 174 | 174 |
| 175 dict->SetString("role", | 175 long ia2_role = 0; |
| 176 IAccessible2RoleToString(ax_object->GetCOM()->ia2_role())); | 176 if (SUCCEEDED(ax_object->GetCOM()->role(&ia2_role))) { |
| 177 dict->SetString("role", IAccessible2RoleToString(ia2_role)); |
| 178 } |
| 177 | 179 |
| 178 base::win::ScopedBstr temp_bstr; | 180 base::win::ScopedBstr temp_bstr; |
| 179 // If S_FALSE it means there is no name | 181 // If S_FALSE it means there is no name |
| 180 if (S_OK == | 182 if (S_OK == |
| 181 ax_object->GetCOM()->get_accName(variant_self, temp_bstr.Receive())) { | 183 ax_object->GetCOM()->get_accName(variant_self, temp_bstr.Receive())) { |
| 182 base::string16 name = base::string16(temp_bstr, temp_bstr.Length()); | 184 base::string16 name = base::string16(temp_bstr, temp_bstr.Length()); |
| 183 | 185 |
| 184 // Ignore a JAWS workaround where the name of a document is " ". | 186 // Ignore a JAWS workaround where the name of a document is " ". |
| 185 if (name != L" " || ax_object->GetCOM()->ia2_role() != ROLE_SYSTEM_DOCUMENT) | 187 if (name != L" " || ia2_role != ROLE_SYSTEM_DOCUMENT) |
| 186 dict->SetString("name", name); | 188 dict->SetString("name", name); |
| 187 } | 189 } |
| 188 temp_bstr.Reset(); | 190 temp_bstr.Reset(); |
| 189 | 191 |
| 190 if (SUCCEEDED( | 192 if (SUCCEEDED( |
| 191 ax_object->GetCOM()->get_accValue(variant_self, temp_bstr.Receive()))) | 193 ax_object->GetCOM()->get_accValue(variant_self, temp_bstr.Receive()))) |
| 192 dict->SetString("value", base::string16(temp_bstr, temp_bstr.Length())); | 194 dict->SetString("value", base::string16(temp_bstr, temp_bstr.Length())); |
| 193 temp_bstr.Reset(); | 195 temp_bstr.Reset(); |
| 194 | 196 |
| 195 std::vector<base::string16> state_strings; | 197 std::vector<base::string16> state_strings; |
| 196 int32_t ia_state = ax_object->GetCOM()->ia_state(); | 198 |
| 199 int32_t ia_state = 0; |
| 200 VARIANT ia_state_variant; |
| 201 if (ax_object->GetCOM()->get_accState(variant_self, &ia_state_variant) == |
| 202 S_OK && |
| 203 ia_state_variant.vt == VT_I4) { |
| 204 ia_state = ia_state_variant.intVal; |
| 205 } |
| 197 | 206 |
| 198 // Avoid flakiness: these states depend on whether the window is focused | 207 // Avoid flakiness: these states depend on whether the window is focused |
| 199 // and the position of the mouse cursor. | 208 // and the position of the mouse cursor. |
| 200 ia_state &= ~STATE_SYSTEM_HOTTRACKED; | 209 ia_state &= ~STATE_SYSTEM_HOTTRACKED; |
| 201 ia_state &= ~STATE_SYSTEM_OFFSCREEN; | 210 ia_state &= ~STATE_SYSTEM_OFFSCREEN; |
| 202 | 211 |
| 203 IAccessibleStateToStringVector(ia_state, &state_strings); | 212 // For testing, having the focused state may also cause flakiness if the |
| 204 IAccessible2StateToStringVector(ax_object->GetCOM()->ia2_state(), | 213 // window isn't in the foreground. |
| 205 &state_strings); | 214 ia_state &= ~STATE_SYSTEM_FOCUSED; |
| 206 std::unique_ptr<base::ListValue> states(new base::ListValue()); | |
| 207 for (const base::string16& state_string : state_strings) | |
| 208 states->AppendString(base::UTF16ToUTF8(state_string)); | |
| 209 dict->Set("states", std::move(states)); | |
| 210 | 215 |
| 211 const std::vector<base::string16>& ia2_attributes = | 216 AccessibleStates states; |
| 212 ax_object->GetCOM()->ia2_attributes(); | 217 if (ax_object->GetCOM()->get_states(&states) == S_OK) { |
| 213 std::unique_ptr<base::ListValue> attributes(new base::ListValue()); | 218 IAccessibleStateToStringVector(ia_state, &state_strings); |
| 214 for (const base::string16& ia2_attribute : ia2_attributes) | 219 IAccessible2StateToStringVector(states, &state_strings); |
| 215 attributes->AppendString(base::UTF16ToUTF8(ia2_attribute)); | 220 std::unique_ptr<base::ListValue> states(new base::ListValue()); |
| 216 dict->Set("attributes", std::move(attributes)); | 221 for (const base::string16& state_string : state_strings) |
| 222 states->AppendString(base::UTF16ToUTF8(state_string)); |
| 223 dict->Set("states", std::move(states)); |
| 224 } |
| 225 |
| 226 if (ax_object->GetCOM()->get_attributes(temp_bstr.Receive()) == S_OK) { |
| 227 // get_attributes() returns a semicolon delimited string. Turn it into a |
| 228 // ListValue |
| 229 std::vector<base::string16> ia2_attributes = base::SplitString( |
| 230 base::string16(temp_bstr, temp_bstr.Length()), base::string16(1, ';'), |
| 231 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); |
| 232 |
| 233 std::unique_ptr<base::ListValue> attributes(new base::ListValue()); |
| 234 for (const base::string16& ia2_attribute : ia2_attributes) |
| 235 attributes->AppendString(base::UTF16ToUTF8(ia2_attribute)); |
| 236 dict->Set("attributes", std::move(attributes)); |
| 237 } |
| 238 temp_bstr.Reset(); |
| 217 | 239 |
| 218 ax_object->GetCOM()->ComputeStylesIfNeeded(); | 240 ax_object->GetCOM()->ComputeStylesIfNeeded(); |
| 219 const std::map<int, std::vector<base::string16>>& ia2_text_attributes = | 241 const std::map<int, std::vector<base::string16>>& ia2_text_attributes = |
| 220 ax_object->GetCOM()->offset_to_text_attributes(); | 242 ax_object->GetCOM()->offset_to_text_attributes(); |
| 221 std::unique_ptr<base::ListValue> text_attributes(new base::ListValue()); | 243 std::unique_ptr<base::ListValue> text_attributes(new base::ListValue()); |
| 222 for (const auto& style_span : ia2_text_attributes) { | 244 for (const auto& style_span : ia2_text_attributes) { |
| 223 int start_offset = style_span.first; | 245 int start_offset = style_span.first; |
| 224 text_attributes->AppendString("offset:" + base::IntToString(start_offset)); | 246 text_attributes->AppendString("offset:" + base::IntToString(start_offset)); |
| 225 for (const base::string16& text_attribute : style_span.second) | 247 for (const base::string16& text_attribute : style_span.second) |
| 226 text_attributes->AppendString(base::UTF16ToUTF8(text_attribute)); | 248 text_attributes->AppendString(base::UTF16ToUTF8(text_attribute)); |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 457 | 479 |
| 458 const std::string AccessibilityTreeFormatterWin::GetAllowString() { | 480 const std::string AccessibilityTreeFormatterWin::GetAllowString() { |
| 459 return "@WIN-ALLOW:"; | 481 return "@WIN-ALLOW:"; |
| 460 } | 482 } |
| 461 | 483 |
| 462 const std::string AccessibilityTreeFormatterWin::GetDenyString() { | 484 const std::string AccessibilityTreeFormatterWin::GetDenyString() { |
| 463 return "@WIN-DENY:"; | 485 return "@WIN-DENY:"; |
| 464 } | 486 } |
| 465 | 487 |
| 466 } // namespace content | 488 } // namespace content |
| OLD | NEW |