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

Side by Side Diff: views/accessibility/view_accessibility.cc

Issue 261044: Accessibility information from the renderer was not being returned to tools l... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 2 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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 "views/accessibility/view_accessibility.h" 5 #include "views/accessibility/view_accessibility.h"
6 6
7 #include "views/accessibility/view_accessibility_wrapper.h" 7 #include "views/accessibility/view_accessibility_wrapper.h"
8 #include "views/widget/widget.h" 8 #include "views/widget/widget.h"
9 9
10 const wchar_t kViewsUninitializeAccessibilityInstance[] =
11 L"Views_Uninitialize_AccessibilityInstance";
12
13 const wchar_t kViewsNativeHostPropForAccessibility[] =
14 L"Views_NativeViewHostHWNDForAccessibility";
15
16
10 HRESULT ViewAccessibility::Initialize(views::View* view) { 17 HRESULT ViewAccessibility::Initialize(views::View* view) {
11 if (!view) { 18 if (!view) {
12 return E_INVALIDARG; 19 return E_INVALIDARG;
13 } 20 }
14 21
15 view_ = view; 22 view_ = view;
16 return S_OK; 23 return S_OK;
17 } 24 }
18 25
19 // TODO(klink): Handle case where child View is not contained by parent. 26 // TODO(klink): Handle case where child View is not contained by parent.
20 STDMETHODIMP ViewAccessibility::accHitTest(LONG x_left, LONG y_top, 27 STDMETHODIMP ViewAccessibility::accHitTest(LONG x_left, LONG y_top,
21 VARIANT* child) { 28 VARIANT* child) {
22 if (!child) { 29 if (!child) {
23 return E_INVALIDARG; 30 return E_INVALIDARG;
24 } 31 }
25 32
33 if (!view_) {
34 return E_FAIL;
35 }
36
26 gfx::Point pt(x_left, y_top); 37 gfx::Point pt(x_left, y_top);
27 views::View::ConvertPointToView(NULL, view_, &pt); 38 views::View::ConvertPointToView(NULL, view_, &pt);
28 39
29 if (!view_->HitTest(pt)) { 40 if (!view_->HitTest(pt)) {
30 // If containing parent is not hit, return with failure. 41 // If containing parent is not hit, return with failure.
31 child->vt = VT_EMPTY; 42 child->vt = VT_EMPTY;
32 return S_FALSE; 43 return S_FALSE;
33 } 44 }
34 45
35 int child_count = view_->GetChildViewCount(); 46 int child_count = view_->GetChildViewCount();
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 return S_OK; 86 return S_OK;
76 } 87 }
77 88
78 STDMETHODIMP ViewAccessibility::accLocation(LONG* x_left, LONG* y_top, 89 STDMETHODIMP ViewAccessibility::accLocation(LONG* x_left, LONG* y_top,
79 LONG* width, LONG* height, 90 LONG* width, LONG* height,
80 VARIANT var_id) { 91 VARIANT var_id) {
81 if (var_id.vt != VT_I4 || !x_left || !y_top || !width || !height) { 92 if (var_id.vt != VT_I4 || !x_left || !y_top || !width || !height) {
82 return E_INVALIDARG; 93 return E_INVALIDARG;
83 } 94 }
84 95
96 if (!view_) {
97 return E_FAIL;
98 }
99
85 gfx::Rect view_bounds; 100 gfx::Rect view_bounds;
86 // Retrieving the parent View to be used for converting from view-to-screen 101 // Retrieving the parent View to be used for converting from view-to-screen
87 // coordinates. 102 // coordinates.
88 views::View* parent = view_->GetParent(); 103 views::View* parent = view_->GetParent();
89 104
90 if (parent == NULL) { 105 if (parent == NULL) {
91 // If no parent, remain within the same View. 106 // If no parent, remain within the same View.
92 parent = view_; 107 parent = view_;
93 } 108 }
94 109
(...skipping 24 matching lines...) Expand all
119 } 134 }
120 return S_OK; 135 return S_OK;
121 } 136 }
122 137
123 STDMETHODIMP ViewAccessibility::accNavigate(LONG nav_dir, VARIANT start, 138 STDMETHODIMP ViewAccessibility::accNavigate(LONG nav_dir, VARIANT start,
124 VARIANT* end) { 139 VARIANT* end) {
125 if (start.vt != VT_I4 || !end) { 140 if (start.vt != VT_I4 || !end) {
126 return E_INVALIDARG; 141 return E_INVALIDARG;
127 } 142 }
128 143
144 if (!view_) {
145 return E_FAIL;
146 }
147
129 switch (nav_dir) { 148 switch (nav_dir) {
130 case NAVDIR_FIRSTCHILD: 149 case NAVDIR_FIRSTCHILD:
131 case NAVDIR_LASTCHILD: { 150 case NAVDIR_LASTCHILD: {
132 if (start.lVal != CHILDID_SELF) { 151 if (start.lVal != CHILDID_SELF) {
133 // Start of navigation must be on the View itself. 152 // Start of navigation must be on the View itself.
134 return E_INVALIDARG; 153 return E_INVALIDARG;
135 } else if (view_->GetChildViewCount() == 0) { 154 } else if (view_->GetChildViewCount() == 0) {
136 // No children found. 155 // No children found.
137 return S_FALSE; 156 return S_FALSE;
138 } 157 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 views::View* parent = view_->GetParent(); 193 views::View* parent = view_->GetParent();
175 if (!parent) { 194 if (!parent) {
176 return E_FAIL; 195 return E_FAIL;
177 } 196 }
178 197
179 if (start.lVal == CHILDID_SELF) { 198 if (start.lVal == CHILDID_SELF) {
180 int view_index = parent->GetChildIndex(view_); 199 int view_index = parent->GetChildIndex(view_);
181 // Check navigation bounds, adjusting for View child indexing (MSAA 200 // Check navigation bounds, adjusting for View child indexing (MSAA
182 // child indexing starts with 1, whereas View indexing starts with 0). 201 // child indexing starts with 1, whereas View indexing starts with 0).
183 if (!IsValidNav(nav_dir, view_index, -1, 202 if (!IsValidNav(nav_dir, view_index, -1,
184 parent->GetChildViewCount())) { 203 parent->GetChildViewCount() - 1)) {
185 // Navigation attempted to go out-of-bounds. 204 // Navigation attempted to go out-of-bounds.
186 end->vt = VT_EMPTY; 205 end->vt = VT_EMPTY;
187 return S_FALSE; 206 return S_FALSE;
188 } else { 207 } else {
189 if (IsNavDirNext(nav_dir)) { 208 if (IsNavDirNext(nav_dir)) {
190 view_index += 1; 209 view_index += 1;
191 } else { 210 } else {
192 view_index -=1; 211 view_index -=1;
193 } 212 }
194 } 213 }
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 IDispatch** disp_child) { 273 IDispatch** disp_child) {
255 if (var_child.vt != VT_I4 || !disp_child) { 274 if (var_child.vt != VT_I4 || !disp_child) {
256 return E_INVALIDARG; 275 return E_INVALIDARG;
257 } 276 }
258 277
259 // If var_child is the parent, remain with the same IDispatch. 278 // If var_child is the parent, remain with the same IDispatch.
260 if (var_child.lVal == CHILDID_SELF) { 279 if (var_child.lVal == CHILDID_SELF) {
261 return S_OK; 280 return S_OK;
262 } 281 }
263 282
283 if (!view_) {
284 return E_FAIL;
285 }
286
264 views::View* child_view = NULL; 287 views::View* child_view = NULL;
265 bool get_iaccessible = false; 288 bool get_iaccessible = false;
266 289
267 // Check to see if child is out-of-bounds. 290 // Check to see if child is out-of-bounds.
268 if (IsValidChild((var_child.lVal - 1), view_)) { 291 if (IsValidChild((var_child.lVal - 1), view_)) {
269 child_view = view_->GetChildViewAt(var_child.lVal - 1); 292 child_view = view_->GetChildViewAt(var_child.lVal - 1);
270 } else { 293 } else {
271 // Child is located elsewhere in the hierarchy, get ID and adjust for MSAA. 294 // Child is located elsewhere in the hierarchy, get ID and adjust for MSAA.
272 child_view = view_->GetViewByID(static_cast<int>(var_child.lVal)); 295 child_view = view_->GetViewByID(static_cast<int>(var_child.lVal));
273 get_iaccessible = true; 296 get_iaccessible = true;
(...skipping 12 matching lines...) Expand all
286 GetInstance(IID_IAccessible, 309 GetInstance(IID_IAccessible,
287 reinterpret_cast<void**>(disp_child)) == S_OK) { 310 reinterpret_cast<void**>(disp_child)) == S_OK) {
288 // Increment the reference count for the retrieved interface. 311 // Increment the reference count for the retrieved interface.
289 (*disp_child)->AddRef(); 312 (*disp_child)->AddRef();
290 return S_OK; 313 return S_OK;
291 } else { 314 } else {
292 // No interface, return failure. 315 // No interface, return failure.
293 return E_NOINTERFACE; 316 return E_NOINTERFACE;
294 } 317 }
295 } else { 318 } else {
319 if (child_view->GetClassName() == views::NativeViewHost::kViewClassName) {
320 views::NativeViewHost* native_host =
321 static_cast<views::NativeViewHost*>(child_view);
322 if (GetNativeIAccessibleInterface(native_host, disp_child) == S_OK)
323 return S_OK;
324 }
296 // When at a leaf, children are handled by the parent object. 325 // When at a leaf, children are handled by the parent object.
297 *disp_child = NULL; 326 *disp_child = NULL;
298 return S_FALSE; 327 return S_FALSE;
299 } 328 }
300 } 329 }
301 330
302 STDMETHODIMP ViewAccessibility::get_accChildCount(LONG* child_count) { 331 STDMETHODIMP ViewAccessibility::get_accChildCount(LONG* child_count) {
303 if (!child_count || !view_) { 332 if (!child_count || !view_) {
304 return E_INVALIDARG; 333 return E_INVALIDARG;
305 } 334 }
306 335
336 if (!view_) {
337 return E_FAIL;
338 }
339
307 *child_count = view_->GetChildViewCount(); 340 *child_count = view_->GetChildViewCount();
308 return S_OK; 341 return S_OK;
309 } 342 }
310 343
311 STDMETHODIMP ViewAccessibility::get_accDefaultAction(VARIANT var_id, 344 STDMETHODIMP ViewAccessibility::get_accDefaultAction(VARIANT var_id,
312 BSTR* def_action) { 345 BSTR* def_action) {
313 if (var_id.vt != VT_I4 || !def_action) { 346 if (var_id.vt != VT_I4 || !def_action) {
314 return E_INVALIDARG; 347 return E_INVALIDARG;
315 } 348 }
316 349
350 if (!view_) {
351 return E_FAIL;
352 }
353
317 std::wstring temp_action; 354 std::wstring temp_action;
318 355
319 if (var_id.lVal == CHILDID_SELF) { 356 if (var_id.lVal == CHILDID_SELF) {
320 view_->GetAccessibleDefaultAction(&temp_action); 357 view_->GetAccessibleDefaultAction(&temp_action);
321 } else { 358 } else {
322 if (!IsValidChild((var_id.lVal - 1), view_)) { 359 if (!IsValidChild((var_id.lVal - 1), view_)) {
323 return E_INVALIDARG; 360 return E_INVALIDARG;
324 } 361 }
325 view_->GetChildViewAt(var_id.lVal - 1)-> 362 view_->GetChildViewAt(var_id.lVal - 1)->
326 GetAccessibleDefaultAction(&temp_action); 363 GetAccessibleDefaultAction(&temp_action);
(...skipping 29 matching lines...) Expand all
356 } 393 }
357 394
358 return S_OK; 395 return S_OK;
359 } 396 }
360 397
361 STDMETHODIMP ViewAccessibility::get_accFocus(VARIANT* focus_child) { 398 STDMETHODIMP ViewAccessibility::get_accFocus(VARIANT* focus_child) {
362 if (!focus_child) { 399 if (!focus_child) {
363 return E_INVALIDARG; 400 return E_INVALIDARG;
364 } 401 }
365 402
403 if (!view_) {
404 return E_FAIL;
405 }
406
366 if (view_->GetChildViewCount() == 0 && view_->HasFocus()) { 407 if (view_->GetChildViewCount() == 0 && view_->HasFocus()) {
367 // Parent view has focus. 408 // Parent view has focus.
368 focus_child->vt = VT_I4; 409 focus_child->vt = VT_I4;
369 focus_child->lVal = CHILDID_SELF; 410 focus_child->lVal = CHILDID_SELF;
370 } else { 411 } else {
371 bool has_focus = false; 412 bool has_focus = false;
372 int child_count = view_->GetChildViewCount(); 413 int child_count = view_->GetChildViewCount();
373 // Search for child view with focus. 414 // Search for child view with focus.
374 for (int child_id = 0; child_id < child_count; ++child_id) { 415 for (int child_id = 0; child_id < child_count; ++child_id) {
375 if (view_->GetChildViewAt(child_id)->HasFocus()) { 416 if (view_->GetChildViewAt(child_id)->HasFocus()) {
(...skipping 18 matching lines...) Expand all
394 435
395 return S_OK; 436 return S_OK;
396 } 437 }
397 438
398 STDMETHODIMP ViewAccessibility::get_accKeyboardShortcut(VARIANT var_id, 439 STDMETHODIMP ViewAccessibility::get_accKeyboardShortcut(VARIANT var_id,
399 BSTR* acc_key) { 440 BSTR* acc_key) {
400 if (var_id.vt != VT_I4 || !acc_key) { 441 if (var_id.vt != VT_I4 || !acc_key) {
401 return E_INVALIDARG; 442 return E_INVALIDARG;
402 } 443 }
403 444
445 if (!view_) {
446 return E_FAIL;
447 }
448
404 std::wstring temp_key; 449 std::wstring temp_key;
405 450
406 if (var_id.lVal == CHILDID_SELF) { 451 if (var_id.lVal == CHILDID_SELF) {
407 view_->GetAccessibleKeyboardShortcut(&temp_key); 452 view_->GetAccessibleKeyboardShortcut(&temp_key);
408 } else { 453 } else {
409 if (!IsValidChild((var_id.lVal - 1), view_)) { 454 if (!IsValidChild((var_id.lVal - 1), view_)) {
410 return E_INVALIDARG; 455 return E_INVALIDARG;
411 } 456 }
412 view_->GetChildViewAt(var_id.lVal - 1)-> 457 view_->GetChildViewAt(var_id.lVal - 1)->
413 GetAccessibleKeyboardShortcut(&temp_key); 458 GetAccessibleKeyboardShortcut(&temp_key);
414 } 459 }
415 if (!temp_key.empty()) { 460 if (!temp_key.empty()) {
416 *acc_key = SysAllocString(temp_key.c_str()); 461 *acc_key = SysAllocString(temp_key.c_str());
417 } else { 462 } else {
418 return S_FALSE; 463 return S_FALSE;
419 } 464 }
420 465
421 return S_OK; 466 return S_OK;
422 } 467 }
423 468
424 STDMETHODIMP ViewAccessibility::get_accName(VARIANT var_id, BSTR* name) { 469 STDMETHODIMP ViewAccessibility::get_accName(VARIANT var_id, BSTR* name) {
425 if (var_id.vt != VT_I4 || !name) { 470 if (var_id.vt != VT_I4 || !name) {
426 return E_INVALIDARG; 471 return E_INVALIDARG;
427 } 472 }
428 473
474 if (!view_) {
475 return E_FAIL;
476 }
477
429 std::wstring temp_name; 478 std::wstring temp_name;
430 479
431 if (var_id.lVal == CHILDID_SELF) { 480 if (var_id.lVal == CHILDID_SELF) {
432 // Retrieve the parent view's name. 481 // Retrieve the parent view's name.
433 view_->GetAccessibleName(&temp_name); 482 view_->GetAccessibleName(&temp_name);
434 } else { 483 } else {
435 if (!IsValidChild((var_id.lVal - 1), view_)) { 484 if (!IsValidChild((var_id.lVal - 1), view_)) {
436 return E_INVALIDARG; 485 return E_INVALIDARG;
437 } 486 }
438 // Retrieve the child view's name. 487 // Retrieve the child view's name.
439 view_->GetChildViewAt(var_id.lVal - 1)->GetAccessibleName(&temp_name); 488 view_->GetChildViewAt(var_id.lVal - 1)->GetAccessibleName(&temp_name);
440 } 489 }
441 if (!temp_name.empty()) { 490 if (!temp_name.empty()) {
442 // Return name retrieved. 491 // Return name retrieved.
443 *name = SysAllocString(temp_name.c_str()); 492 *name = SysAllocString(temp_name.c_str());
444 } else { 493 } else {
445 // If view has no name, return S_FALSE. 494 // If view has no name, return S_FALSE.
446 return S_FALSE; 495 return S_FALSE;
447 } 496 }
448 497
449 return S_OK; 498 return S_OK;
450 } 499 }
451 500
452 STDMETHODIMP ViewAccessibility::get_accParent(IDispatch** disp_parent) { 501 STDMETHODIMP ViewAccessibility::get_accParent(IDispatch** disp_parent) {
453 if (!disp_parent) { 502 if (!disp_parent) {
454 return E_INVALIDARG; 503 return E_INVALIDARG;
455 } 504 }
456 505
506 if (!view_) {
507 return E_FAIL;
508 }
509
457 views::View* parent_view = view_->GetParent(); 510 views::View* parent_view = view_->GetParent();
458 511
459 if (!parent_view) { 512 if (!parent_view) {
460 // This function can get called during teardown of WidetWin so we 513 // This function can get called during teardown of WidetWin so we
461 // should bail out if we fail to get the HWND. 514 // should bail out if we fail to get the HWND.
462 if (!view_->GetWidget() || !view_->GetWidget()->GetNativeView()) { 515 if (!view_->GetWidget() || !view_->GetWidget()->GetNativeView()) {
463 *disp_parent = NULL; 516 *disp_parent = NULL;
464 return S_FALSE; 517 return S_FALSE;
465 } 518 }
466 519
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
698 } 751 }
699 return E_NOTIMPL; 752 return E_NOTIMPL;
700 } 753 }
701 754
702 STDMETHODIMP ViewAccessibility::put_accName(VARIANT var_id, BSTR put_name) { 755 STDMETHODIMP ViewAccessibility::put_accName(VARIANT var_id, BSTR put_name) {
703 // Deprecated. 756 // Deprecated.
704 return E_NOTIMPL; 757 return E_NOTIMPL;
705 } 758 }
706 759
707 STDMETHODIMP ViewAccessibility::put_accValue(VARIANT var_id, BSTR put_val) { 760 STDMETHODIMP ViewAccessibility::put_accValue(VARIANT var_id, BSTR put_val) {
761 if (V_VT(&var_id) == VT_BSTR) {
762 if (!lstrcmpi(var_id.bstrVal, kViewsUninitializeAccessibilityInstance)) {
763 view_ = NULL;
764 return S_OK;
765 }
766 }
708 // Deprecated. 767 // Deprecated.
709 return E_NOTIMPL; 768 return E_NOTIMPL;
710 } 769 }
770
771 HRESULT ViewAccessibility::GetNativeIAccessibleInterface(
772 views::NativeViewHost* native_host, IDispatch** disp_child) {
773 if (!native_host || !disp_child) {
774 return E_INVALIDARG;
775 }
776
777 HWND render_view_window =
778 static_cast<HWND>(GetProp(native_host->native_view(),
779 kViewsNativeHostPropForAccessibility));
780
781 if (IsWindow(render_view_window)) {
782 LRESULT ret = SendMessage(render_view_window, WM_GETOBJECT, 0,
783 OBJID_CLIENT);
784 return ObjectFromLresult(ret, IID_IDispatch, 0,
785 reinterpret_cast<void**>(disp_child));
786 }
787
788 return E_FAIL;
789 }
OLDNEW
« no previous file with comments | « views/accessibility/view_accessibility.h ('k') | views/accessibility/view_accessibility_wrapper.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698