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

Side by Side Diff: content/browser/accessibility/accessibility_tree_formatter_win.cc

Issue 2864953002: Split out the MSCOM pieces of BrowserAccessibilityWin into a seperate class. (Closed)
Patch Set: follow up comment Created 3 years, 7 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 unified diff | Download patch
OLDNEW
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 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 "localized_extended_role", 88 "localized_extended_role",
89 "inner_html", 89 "inner_html",
90 }; 90 };
91 91
92 namespace { 92 namespace {
93 93
94 base::string16 GetIA2Hypertext(BrowserAccessibilityWin& ax_object) { 94 base::string16 GetIA2Hypertext(BrowserAccessibilityWin& ax_object) {
95 base::win::ScopedBstr text_bstr; 95 base::win::ScopedBstr text_bstr;
96 HRESULT hr; 96 HRESULT hr;
97 97
98 hr = ax_object.get_text(0, IA2_TEXT_OFFSET_LENGTH, text_bstr.Receive()); 98 hr = ax_object.GetCOM()->get_text(0, IA2_TEXT_OFFSET_LENGTH,
99 text_bstr.Receive());
99 if (FAILED(hr)) 100 if (FAILED(hr))
100 return base::string16(); 101 return base::string16();
101 102
102 base::string16 ia2_hypertext(text_bstr, text_bstr.Length()); 103 base::string16 ia2_hypertext(text_bstr, text_bstr.Length());
103 // IA2 Spec calls embedded objects hyperlinks. We stick to embeds for clarity. 104 // IA2 Spec calls embedded objects hyperlinks. We stick to embeds for clarity.
104 LONG number_of_embeds; 105 LONG number_of_embeds;
105 hr = ax_object.get_nHyperlinks(&number_of_embeds); 106 hr = ax_object.GetCOM()->get_nHyperlinks(&number_of_embeds);
106 if (FAILED(hr) || number_of_embeds == 0) 107 if (FAILED(hr) || number_of_embeds == 0)
107 return ia2_hypertext; 108 return ia2_hypertext;
108 109
109 // Replace all embedded characters with the child indices of the accessibility 110 // Replace all embedded characters with the child indices of the accessibility
110 // objects they refer to. 111 // objects they refer to.
111 base::string16 embedded_character(1, 112 base::string16 embedded_character(
112 BrowserAccessibilityWin::kEmbeddedCharacter); 113 1, BrowserAccessibilityComWin::kEmbeddedCharacter);
113 size_t character_index = 0; 114 size_t character_index = 0;
114 size_t hypertext_index = 0; 115 size_t hypertext_index = 0;
115 while (hypertext_index < ia2_hypertext.length()) { 116 while (hypertext_index < ia2_hypertext.length()) {
116 if (ia2_hypertext[hypertext_index] != 117 if (ia2_hypertext[hypertext_index] !=
117 BrowserAccessibilityWin::kEmbeddedCharacter) { 118 BrowserAccessibilityComWin::kEmbeddedCharacter) {
118 ++character_index; 119 ++character_index;
119 ++hypertext_index; 120 ++hypertext_index;
120 continue; 121 continue;
121 } 122 }
122 123
123 LONG index_of_embed; 124 LONG index_of_embed;
124 hr = ax_object.get_hyperlinkIndex(character_index, &index_of_embed); 125 hr = ax_object.GetCOM()->get_hyperlinkIndex(character_index,
126 &index_of_embed);
125 // S_FALSE will be returned if no embedded object is found at the given 127 // S_FALSE will be returned if no embedded object is found at the given
126 // embedded character offset. Exclude child index from such cases. 128 // embedded character offset. Exclude child index from such cases.
127 LONG child_index = -1; 129 LONG child_index = -1;
128 if (hr == S_OK) { 130 if (hr == S_OK) {
129 DCHECK_GE(index_of_embed, 0); 131 DCHECK_GE(index_of_embed, 0);
130 base::win::ScopedComPtr<IAccessibleHyperlink> embedded_object; 132 base::win::ScopedComPtr<IAccessibleHyperlink> embedded_object;
131 hr = ax_object.get_hyperlink( 133 hr = ax_object.GetCOM()->get_hyperlink(index_of_embed,
132 index_of_embed, embedded_object.Receive()); 134 embedded_object.Receive());
133 DCHECK(SUCCEEDED(hr)); 135 DCHECK(SUCCEEDED(hr));
134 base::win::ScopedComPtr<IAccessible2> ax_embed; 136 base::win::ScopedComPtr<IAccessible2> ax_embed;
135 hr = embedded_object.CopyTo(ax_embed.Receive()); 137 hr = embedded_object.CopyTo(ax_embed.Receive());
136 DCHECK(SUCCEEDED(hr)); 138 DCHECK(SUCCEEDED(hr));
137 hr = ax_embed->get_indexInParent(&child_index); 139 hr = ax_embed->get_indexInParent(&child_index);
138 DCHECK(SUCCEEDED(hr)); 140 DCHECK(SUCCEEDED(hr));
139 } 141 }
140 142
141 base::string16 child_index_str(L"<obj"); 143 base::string16 child_index_str(L"<obj");
142 if (child_index >= 0) { 144 if (child_index >= 0) {
(...skipping 18 matching lines...) Expand all
161 const BrowserAccessibility& node, base::DictionaryValue* dict) { 163 const BrowserAccessibility& node, base::DictionaryValue* dict) {
162 dict->SetInteger("id", node.GetId()); 164 dict->SetInteger("id", node.GetId());
163 BrowserAccessibilityWin* ax_object = 165 BrowserAccessibilityWin* ax_object =
164 ToBrowserAccessibilityWin(const_cast<BrowserAccessibility*>(&node)); 166 ToBrowserAccessibilityWin(const_cast<BrowserAccessibility*>(&node));
165 DCHECK(ax_object); 167 DCHECK(ax_object);
166 168
167 VARIANT variant_self; 169 VARIANT variant_self;
168 variant_self.vt = VT_I4; 170 variant_self.vt = VT_I4;
169 variant_self.lVal = CHILDID_SELF; 171 variant_self.lVal = CHILDID_SELF;
170 172
171 dict->SetString("role", IAccessible2RoleToString(ax_object->ia2_role())); 173 dict->SetString("role",
174 IAccessible2RoleToString(ax_object->GetCOM()->ia2_role()));
172 175
173 base::win::ScopedBstr temp_bstr; 176 base::win::ScopedBstr temp_bstr;
174 // If S_FALSE it means there is no name 177 // If S_FALSE it means there is no name
175 if (S_OK == ax_object->get_accName(variant_self, temp_bstr.Receive())) { 178 if (S_OK ==
179 ax_object->GetCOM()->get_accName(variant_self, temp_bstr.Receive())) {
176 base::string16 name = base::string16(temp_bstr, temp_bstr.Length()); 180 base::string16 name = base::string16(temp_bstr, temp_bstr.Length());
177 181
178 // Ignore a JAWS workaround where the name of a document is " ". 182 // Ignore a JAWS workaround where the name of a document is " ".
179 if (name != L" " || ax_object->ia2_role() != ROLE_SYSTEM_DOCUMENT) 183 if (name != L" " || ax_object->GetCOM()->ia2_role() != ROLE_SYSTEM_DOCUMENT)
180 dict->SetString("name", name); 184 dict->SetString("name", name);
181 } 185 }
182 temp_bstr.Reset(); 186 temp_bstr.Reset();
183 187
184 if (SUCCEEDED(ax_object->get_accValue(variant_self, temp_bstr.Receive()))) 188 if (SUCCEEDED(
189 ax_object->GetCOM()->get_accValue(variant_self, temp_bstr.Receive())))
185 dict->SetString("value", base::string16(temp_bstr, temp_bstr.Length())); 190 dict->SetString("value", base::string16(temp_bstr, temp_bstr.Length()));
186 temp_bstr.Reset(); 191 temp_bstr.Reset();
187 192
188 std::vector<base::string16> state_strings; 193 std::vector<base::string16> state_strings;
189 int32_t ia_state = ax_object->ia_state(); 194 int32_t ia_state = ax_object->GetCOM()->ia_state();
190 195
191 // Avoid flakiness: these states depend on whether the window is focused 196 // Avoid flakiness: these states depend on whether the window is focused
192 // and the position of the mouse cursor. 197 // and the position of the mouse cursor.
193 ia_state &= ~STATE_SYSTEM_HOTTRACKED; 198 ia_state &= ~STATE_SYSTEM_HOTTRACKED;
194 ia_state &= ~STATE_SYSTEM_OFFSCREEN; 199 ia_state &= ~STATE_SYSTEM_OFFSCREEN;
195 200
196 IAccessibleStateToStringVector(ia_state, &state_strings); 201 IAccessibleStateToStringVector(ia_state, &state_strings);
197 IAccessible2StateToStringVector(ax_object->ia2_state(), &state_strings); 202 IAccessible2StateToStringVector(ax_object->GetCOM()->ia2_state(),
203 &state_strings);
198 std::unique_ptr<base::ListValue> states(new base::ListValue()); 204 std::unique_ptr<base::ListValue> states(new base::ListValue());
199 for (const base::string16& state_string : state_strings) 205 for (const base::string16& state_string : state_strings)
200 states->AppendString(base::UTF16ToUTF8(state_string)); 206 states->AppendString(base::UTF16ToUTF8(state_string));
201 dict->Set("states", std::move(states)); 207 dict->Set("states", std::move(states));
202 208
203 const std::vector<base::string16>& ia2_attributes = 209 const std::vector<base::string16>& ia2_attributes =
204 ax_object->ia2_attributes(); 210 ax_object->GetCOM()->ia2_attributes();
205 std::unique_ptr<base::ListValue> attributes(new base::ListValue()); 211 std::unique_ptr<base::ListValue> attributes(new base::ListValue());
206 for (const base::string16& ia2_attribute : ia2_attributes) 212 for (const base::string16& ia2_attribute : ia2_attributes)
207 attributes->AppendString(base::UTF16ToUTF8(ia2_attribute)); 213 attributes->AppendString(base::UTF16ToUTF8(ia2_attribute));
208 dict->Set("attributes", std::move(attributes)); 214 dict->Set("attributes", std::move(attributes));
209 215
210 ax_object->ComputeStylesIfNeeded(); 216 ax_object->GetCOM()->ComputeStylesIfNeeded();
211 const std::map<int, std::vector<base::string16>>& ia2_text_attributes = 217 const std::map<int, std::vector<base::string16>>& ia2_text_attributes =
212 ax_object->offset_to_text_attributes(); 218 ax_object->GetCOM()->offset_to_text_attributes();
213 std::unique_ptr<base::ListValue> text_attributes(new base::ListValue()); 219 std::unique_ptr<base::ListValue> text_attributes(new base::ListValue());
214 for (const auto& style_span : ia2_text_attributes) { 220 for (const auto& style_span : ia2_text_attributes) {
215 int start_offset = style_span.first; 221 int start_offset = style_span.first;
216 text_attributes->AppendString("offset:" + base::IntToString(start_offset)); 222 text_attributes->AppendString("offset:" + base::IntToString(start_offset));
217 for (const base::string16& text_attribute : style_span.second) 223 for (const base::string16& text_attribute : style_span.second)
218 text_attributes->AppendString(base::UTF16ToUTF8(text_attribute)); 224 text_attributes->AppendString(base::UTF16ToUTF8(text_attribute));
219 } 225 }
220 dict->Set("text_attributes", std::move(text_attributes)); 226 dict->Set("text_attributes", std::move(text_attributes));
221 227
222 dict->SetString("role_name", ax_object->role_name()); 228 dict->SetString("role_name", ax_object->GetCOM()->role_name());
223 dict->SetString("ia2_hypertext", GetIA2Hypertext(*ax_object)); 229 dict->SetString("ia2_hypertext", GetIA2Hypertext(*ax_object));
224 230
225 VARIANT currentValue; 231 VARIANT currentValue;
226 if (ax_object->get_currentValue(&currentValue) == S_OK) 232 if (ax_object->GetCOM()->get_currentValue(&currentValue) == S_OK)
227 dict->SetDouble("currentValue", V_R8(&currentValue)); 233 dict->SetDouble("currentValue", V_R8(&currentValue));
228 234
229 VARIANT minimumValue; 235 VARIANT minimumValue;
230 if (ax_object->get_minimumValue(&minimumValue) == S_OK) 236 if (ax_object->GetCOM()->get_minimumValue(&minimumValue) == S_OK)
231 dict->SetDouble("minimumValue", V_R8(&minimumValue)); 237 dict->SetDouble("minimumValue", V_R8(&minimumValue));
232 238
233 VARIANT maximumValue; 239 VARIANT maximumValue;
234 if (ax_object->get_maximumValue(&maximumValue) == S_OK) 240 if (ax_object->GetCOM()->get_maximumValue(&maximumValue) == S_OK)
235 dict->SetDouble("maximumValue", V_R8(&maximumValue)); 241 dict->SetDouble("maximumValue", V_R8(&maximumValue));
236 242
237 if (SUCCEEDED(ax_object->get_accDescription(variant_self, 243 if (SUCCEEDED(ax_object->GetCOM()->get_accDescription(variant_self,
238 temp_bstr.Receive()))) { 244 temp_bstr.Receive()))) {
239 dict->SetString("description", base::string16(temp_bstr, 245 dict->SetString("description", base::string16(temp_bstr,
240 temp_bstr.Length())); 246 temp_bstr.Length()));
241 } 247 }
242 temp_bstr.Reset(); 248 temp_bstr.Reset();
243 249
244 if (SUCCEEDED(ax_object->get_accDefaultAction(variant_self, 250 if (SUCCEEDED(ax_object->GetCOM()->get_accDefaultAction(
245 temp_bstr.Receive()))) { 251 variant_self, temp_bstr.Receive()))) {
246 dict->SetString("default_action", base::string16(temp_bstr, 252 dict->SetString("default_action", base::string16(temp_bstr,
247 temp_bstr.Length())); 253 temp_bstr.Length()));
248 } 254 }
249 temp_bstr.Reset(); 255 temp_bstr.Reset();
250 256
251 if (SUCCEEDED( 257 if (SUCCEEDED(ax_object->GetCOM()->get_accKeyboardShortcut(
252 ax_object->get_accKeyboardShortcut(variant_self, temp_bstr.Receive()))) { 258 variant_self, temp_bstr.Receive()))) {
253 dict->SetString("keyboard_shortcut", base::string16(temp_bstr, 259 dict->SetString("keyboard_shortcut", base::string16(temp_bstr,
254 temp_bstr.Length())); 260 temp_bstr.Length()));
255 } 261 }
256 temp_bstr.Reset(); 262 temp_bstr.Reset();
257 263
258 if (SUCCEEDED(ax_object->get_accHelp(variant_self, temp_bstr.Receive()))) 264 if (SUCCEEDED(
265 ax_object->GetCOM()->get_accHelp(variant_self, temp_bstr.Receive())))
259 dict->SetString("help", base::string16(temp_bstr, temp_bstr.Length())); 266 dict->SetString("help", base::string16(temp_bstr, temp_bstr.Length()));
260 temp_bstr.Reset(); 267 temp_bstr.Reset();
261 268
262 BrowserAccessibility* root = node.manager()->GetRootManager()->GetRoot(); 269 BrowserAccessibility* root = node.manager()->GetRootManager()->GetRoot();
263 LONG left, top, width, height; 270 LONG left, top, width, height;
264 LONG root_left, root_top, root_width, root_height; 271 LONG root_left, root_top, root_width, root_height;
265 if (SUCCEEDED(ax_object->accLocation( 272 if (SUCCEEDED(ax_object->GetCOM()->accLocation(&left, &top, &width, &height,
266 &left, &top, &width, &height, variant_self)) && 273 variant_self)) &&
267 SUCCEEDED(ToBrowserAccessibilityWin(root)->accLocation( 274 SUCCEEDED(ToBrowserAccessibilityWin(root)->GetCOM()->accLocation(
268 &root_left, &root_top, &root_width, &root_height, variant_self))) { 275 &root_left, &root_top, &root_width, &root_height, variant_self))) {
269 base::DictionaryValue* location = new base::DictionaryValue; 276 base::DictionaryValue* location = new base::DictionaryValue;
270 location->SetInteger("x", left - root_left); 277 location->SetInteger("x", left - root_left);
271 location->SetInteger("y", top - root_top); 278 location->SetInteger("y", top - root_top);
272 dict->Set("location", location); 279 dict->Set("location", location);
273 280
274 base::DictionaryValue* size = new base::DictionaryValue; 281 base::DictionaryValue* size = new base::DictionaryValue;
275 size->SetInteger("width", width); 282 size->SetInteger("width", width);
276 size->SetInteger("height", height); 283 size->SetInteger("height", height);
277 dict->Set("size", size); 284 dict->Set("size", size);
278 } 285 }
279 286
280 LONG index_in_parent; 287 LONG index_in_parent;
281 if (SUCCEEDED(ax_object->get_indexInParent(&index_in_parent))) 288 if (SUCCEEDED(ax_object->GetCOM()->get_indexInParent(&index_in_parent)))
282 dict->SetInteger("index_in_parent", index_in_parent); 289 dict->SetInteger("index_in_parent", index_in_parent);
283 290
284 LONG n_relations; 291 LONG n_relations;
285 if (SUCCEEDED(ax_object->get_nRelations(&n_relations))) 292 if (SUCCEEDED(ax_object->GetCOM()->get_nRelations(&n_relations)))
286 dict->SetInteger("n_relations", n_relations); 293 dict->SetInteger("n_relations", n_relations);
287 294
288 LONG group_level, similar_items_in_group, position_in_group; 295 LONG group_level, similar_items_in_group, position_in_group;
289 // |GetGroupPosition| returns S_FALSE when no grouping information is 296 // |GetGroupPosition| returns S_FALSE when no grouping information is
290 // available so avoid using |SUCCEEDED|. 297 // available so avoid using |SUCCEEDED|.
291 if (ax_object->get_groupPosition(&group_level, &similar_items_in_group, 298 if (ax_object->GetCOM()->get_groupPosition(
292 &position_in_group) == S_OK) { 299 &group_level, &similar_items_in_group, &position_in_group) == S_OK) {
293 dict->SetInteger("group_level", group_level); 300 dict->SetInteger("group_level", group_level);
294 dict->SetInteger("similar_items_in_group", similar_items_in_group); 301 dict->SetInteger("similar_items_in_group", similar_items_in_group);
295 dict->SetInteger("position_in_group", position_in_group); 302 dict->SetInteger("position_in_group", position_in_group);
296 } 303 }
297 304
298 LONG table_rows; 305 LONG table_rows;
299 if (SUCCEEDED(ax_object->get_nRows(&table_rows))) 306 if (SUCCEEDED(ax_object->GetCOM()->get_nRows(&table_rows)))
300 dict->SetInteger("table_rows", table_rows); 307 dict->SetInteger("table_rows", table_rows);
301 308
302 LONG table_columns; 309 LONG table_columns;
303 if (SUCCEEDED(ax_object->get_nRows(&table_columns))) 310 if (SUCCEEDED(ax_object->GetCOM()->get_nRows(&table_columns)))
304 dict->SetInteger("table_columns", table_columns); 311 dict->SetInteger("table_columns", table_columns);
305 312
306 LONG row_index; 313 LONG row_index;
307 if (SUCCEEDED(ax_object->get_rowIndex(&row_index))) 314 if (SUCCEEDED(ax_object->GetCOM()->get_rowIndex(&row_index)))
308 dict->SetInteger("row_index", row_index); 315 dict->SetInteger("row_index", row_index);
309 316
310 LONG column_index; 317 LONG column_index;
311 if (SUCCEEDED(ax_object->get_columnIndex(&column_index))) 318 if (SUCCEEDED(ax_object->GetCOM()->get_columnIndex(&column_index)))
312 dict->SetInteger("column_index", column_index); 319 dict->SetInteger("column_index", column_index);
313 320
314 LONG n_characters; 321 LONG n_characters;
315 if (SUCCEEDED(ax_object->get_nCharacters(&n_characters))) 322 if (SUCCEEDED(ax_object->GetCOM()->get_nCharacters(&n_characters)))
316 dict->SetInteger("n_characters", n_characters); 323 dict->SetInteger("n_characters", n_characters);
317 324
318 LONG caret_offset; 325 LONG caret_offset;
319 if (ax_object->get_caretOffset(&caret_offset) == S_OK) 326 if (ax_object->GetCOM()->get_caretOffset(&caret_offset) == S_OK)
320 dict->SetInteger("caret_offset", caret_offset); 327 dict->SetInteger("caret_offset", caret_offset);
321 328
322 LONG n_selections; 329 LONG n_selections;
323 if (SUCCEEDED(ax_object->get_nSelections(&n_selections))) { 330 if (SUCCEEDED(ax_object->GetCOM()->get_nSelections(&n_selections))) {
324 dict->SetInteger("n_selections", n_selections); 331 dict->SetInteger("n_selections", n_selections);
325 if (n_selections > 0) { 332 if (n_selections > 0) {
326 LONG start, end; 333 LONG start, end;
327 if (SUCCEEDED(ax_object->get_selection(0, &start, &end))) { 334 if (SUCCEEDED(ax_object->GetCOM()->get_selection(0, &start, &end))) {
328 dict->SetInteger("selection_start", start); 335 dict->SetInteger("selection_start", start);
329 dict->SetInteger("selection_end", end); 336 dict->SetInteger("selection_end", end);
330 } 337 }
331 } 338 }
332 } 339 }
333 340
334 if (SUCCEEDED(ax_object->get_localizedExtendedRole(temp_bstr.Receive()))) { 341 if (SUCCEEDED(ax_object->GetCOM()->get_localizedExtendedRole(
342 temp_bstr.Receive()))) {
335 dict->SetString("localized_extended_role", base::string16(temp_bstr, 343 dict->SetString("localized_extended_role", base::string16(temp_bstr,
336 temp_bstr.Length())); 344 temp_bstr.Length()));
337 } 345 }
338 temp_bstr.Reset(); 346 temp_bstr.Reset();
339 347
340 if (SUCCEEDED(ax_object->get_innerHTML(temp_bstr.Receive()))) { 348 if (SUCCEEDED(ax_object->GetCOM()->get_innerHTML(temp_bstr.Receive()))) {
341 dict->SetString("inner_html", 349 dict->SetString("inner_html",
342 base::string16(temp_bstr, temp_bstr.Length())); 350 base::string16(temp_bstr, temp_bstr.Length()));
343 } 351 }
344 temp_bstr.Reset(); 352 temp_bstr.Reset();
345 } 353 }
346 354
347 base::string16 AccessibilityTreeFormatterWin::ToString( 355 base::string16 AccessibilityTreeFormatterWin::ToString(
348 const base::DictionaryValue& dict) { 356 const base::DictionaryValue& dict) {
349 base::string16 line; 357 base::string16 line;
350 358
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
447 455
448 const std::string AccessibilityTreeFormatterWin::GetAllowString() { 456 const std::string AccessibilityTreeFormatterWin::GetAllowString() {
449 return "@WIN-ALLOW:"; 457 return "@WIN-ALLOW:";
450 } 458 }
451 459
452 const std::string AccessibilityTreeFormatterWin::GetDenyString() { 460 const std::string AccessibilityTreeFormatterWin::GetDenyString() {
453 return "@WIN-DENY:"; 461 return "@WIN-DENY:";
454 } 462 }
455 463
456 } // namespace content 464 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698