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

Side by Side Diff: content/renderer/accessibility/render_accessibility_impl.cc

Issue 2430473003: Revert of Create AXAction and AXActionData as a way to simplify accessibility actions (Closed)
Patch Set: Created 4 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
« no previous file with comments | « content/renderer/accessibility/render_accessibility_impl.h ('k') | ui/accessibility/BUILD.gn » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/renderer/accessibility/render_accessibility_impl.h" 5 #include "content/renderer/accessibility/render_accessibility_impl.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <queue> 10 #include <queue>
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 } 111 }
112 } 112 }
113 113
114 RenderAccessibilityImpl::~RenderAccessibilityImpl() { 114 RenderAccessibilityImpl::~RenderAccessibilityImpl() {
115 } 115 }
116 116
117 bool RenderAccessibilityImpl::OnMessageReceived(const IPC::Message& message) { 117 bool RenderAccessibilityImpl::OnMessageReceived(const IPC::Message& message) {
118 bool handled = true; 118 bool handled = true;
119 during_action_ = true; 119 during_action_ = true;
120 IPC_BEGIN_MESSAGE_MAP(RenderAccessibilityImpl, message) 120 IPC_BEGIN_MESSAGE_MAP(RenderAccessibilityImpl, message)
121 IPC_MESSAGE_HANDLER(AccessibilityMsg_PerformAction, OnPerformAction) 121 IPC_MESSAGE_HANDLER(AccessibilityMsg_SetFocus, OnSetFocus)
122 IPC_MESSAGE_HANDLER(AccessibilityMsg_DoDefaultAction, OnDoDefaultAction)
122 IPC_MESSAGE_HANDLER(AccessibilityMsg_Events_ACK, OnEventsAck) 123 IPC_MESSAGE_HANDLER(AccessibilityMsg_Events_ACK, OnEventsAck)
124 IPC_MESSAGE_HANDLER(AccessibilityMsg_ScrollToMakeVisible,
125 OnScrollToMakeVisible)
126 IPC_MESSAGE_HANDLER(AccessibilityMsg_ScrollToPoint, OnScrollToPoint)
127 IPC_MESSAGE_HANDLER(AccessibilityMsg_SetScrollOffset, OnSetScrollOffset)
128 IPC_MESSAGE_HANDLER(AccessibilityMsg_SetSelection, OnSetSelection)
129 IPC_MESSAGE_HANDLER(AccessibilityMsg_SetValue, OnSetValue)
130 IPC_MESSAGE_HANDLER(AccessibilityMsg_ShowContextMenu, OnShowContextMenu)
123 IPC_MESSAGE_HANDLER(AccessibilityMsg_HitTest, OnHitTest) 131 IPC_MESSAGE_HANDLER(AccessibilityMsg_HitTest, OnHitTest)
132 IPC_MESSAGE_HANDLER(AccessibilityMsg_SetAccessibilityFocus,
133 OnSetAccessibilityFocus)
124 IPC_MESSAGE_HANDLER(AccessibilityMsg_Reset, OnReset) 134 IPC_MESSAGE_HANDLER(AccessibilityMsg_Reset, OnReset)
125 IPC_MESSAGE_HANDLER(AccessibilityMsg_FatalError, OnFatalError) 135 IPC_MESSAGE_HANDLER(AccessibilityMsg_FatalError, OnFatalError)
126 IPC_MESSAGE_UNHANDLED(handled = false) 136 IPC_MESSAGE_UNHANDLED(handled = false)
127 IPC_END_MESSAGE_MAP() 137 IPC_END_MESSAGE_MAP()
128 during_action_ = false; 138 during_action_ = false;
129 return handled; 139 return handled;
130 } 140 }
131 141
132 void RenderAccessibilityImpl::HandleWebAccessibilityEvent( 142 void RenderAccessibilityImpl::HandleWebAccessibilityEvent(
133 const blink::WebAXObject& obj, blink::WebAXEvent event) { 143 const blink::WebAXObject& obj, blink::WebAXEvent event) {
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 std::vector<blink::WebAXObject> children; 436 std::vector<blink::WebAXObject> children;
427 tree_source_.GetChildren(obj, &children); 437 tree_source_.GetChildren(obj, &children);
428 for (size_t i = 0; i < children.size(); ++i) 438 for (size_t i = 0; i < children.size(); ++i)
429 objs_to_explore.push(children[i]); 439 objs_to_explore.push(children[i]);
430 } 440 }
431 locations_.swap(new_locations); 441 locations_.swap(new_locations);
432 442
433 Send(new AccessibilityHostMsg_LocationChanges(routing_id(), messages)); 443 Send(new AccessibilityHostMsg_LocationChanges(routing_id(), messages));
434 } 444 }
435 445
436 void RenderAccessibilityImpl::OnPerformAction( 446 void RenderAccessibilityImpl::OnDoDefaultAction(int acc_obj_id) {
437 const ui::AXActionData& data) {
438 const WebDocument& document = GetMainDocument(); 447 const WebDocument& document = GetMainDocument();
439 if (document.isNull()) 448 if (document.isNull())
440 return; 449 return;
441 450
442 WebAXObject root = document.accessibilityObject(); 451 WebAXObject obj = document.accessibilityObjectFromID(acc_obj_id);
443 if (!root.updateLayoutAndCheckValidity()) 452 if (obj.isDetached()) {
453 #ifndef NDEBUG
454 LOG(WARNING) << "DoDefaultAction on invalid object id " << acc_obj_id;
455 #endif
444 return; 456 return;
457 }
445 458
446 WebAXObject target = document.accessibilityObjectFromID(data.target_node_id); 459 obj.performDefaultAction();
447 WebAXObject anchor = document.accessibilityObjectFromID(data.anchor_node_id);
448 WebAXObject focus = document.accessibilityObjectFromID(data.focus_node_id);
449
450 switch (data.action) {
451 case ui::AX_ACTION_DO_DEFAULT:
452 target.performDefaultAction();
453 break;
454 case ui::AX_ACTION_HIT_TEST:
455 OnHitTest(data.target_point);
456 break;
457 case ui::AX_ACTION_SCROLL_TO_MAKE_VISIBLE:
458 target.scrollToMakeVisibleWithSubFocus(
459 WebRect(data.target_rect.x(), data.target_rect.y(),
460 data.target_rect.width(), data.target_rect.height()));
461 break;
462 case ui::AX_ACTION_SCROLL_TO_POINT:
463 target.scrollToGlobalPoint(
464 WebPoint(data.target_point.x(), data.target_point.y()));
465 break;
466 case ui::AX_ACTION_SET_ACCESSIBILITY_FOCUS:
467 OnSetAccessibilityFocus(target);
468 break;
469 case ui::AX_ACTION_SET_FOCUS:
470 // By convention, calling SetFocus on the root of the tree should
471 // clear the current focus. Otherwise set the focus to the new node.
472 if (data.target_node_id == root.axID())
473 render_frame_->GetRenderView()->GetWebView()->clearFocusedElement();
474 else
475 target.setFocused(true);
476 break;
477 case ui::AX_ACTION_SET_SCROLL_OFFSET:
478 target.setScrollOffset(
479 WebPoint(data.target_point.x(), data.target_point.y()));
480 break;
481 case ui::AX_ACTION_SET_SELECTION:
482 anchor.setSelection(anchor, data.anchor_offset, focus, data.focus_offset);
483 HandleAXEvent(root, ui::AX_EVENT_LAYOUT_COMPLETE);
484 break;
485 case ui::AX_ACTION_SET_VALUE:
486 target.setValue(data.value);
487 HandleAXEvent(target, ui::AX_EVENT_VALUE_CHANGED);
488 break;
489 case ui::AX_ACTION_SHOW_CONTEXT_MENU:
490 target.showContextMenu();
491 break;
492 case ui::AX_ACTION_NONE:
493 NOTREACHED();
494 break;
495 }
496 } 460 }
497 461
498 void RenderAccessibilityImpl::OnEventsAck(int ack_token) { 462 void RenderAccessibilityImpl::OnEventsAck(int ack_token) {
499 // Ignore acks intended for a different or previous instance. 463 // Ignore acks intended for a different or previous instance.
500 if (ack_token_ != ack_token) 464 if (ack_token_ != ack_token)
501 return; 465 return;
502 466
503 DCHECK(ack_pending_); 467 DCHECK(ack_pending_);
504 ack_pending_ = false; 468 ack_pending_ = false;
505 SendPendingAccessibilityEvents(); 469 SendPendingAccessibilityEvents();
506 } 470 }
507 471
508 void RenderAccessibilityImpl::OnFatalError() { 472 void RenderAccessibilityImpl::OnFatalError() {
509 CHECK(false) << "Invalid accessibility tree."; 473 CHECK(false) << "Invalid accessibility tree.";
510 } 474 }
511 475
512 void RenderAccessibilityImpl::OnHitTest(const gfx::Point& point) { 476 void RenderAccessibilityImpl::OnHitTest(gfx::Point point) {
513 const WebDocument& document = GetMainDocument(); 477 const WebDocument& document = GetMainDocument();
514 if (document.isNull()) 478 if (document.isNull())
515 return; 479 return;
516 WebAXObject root_obj = document.accessibilityObject(); 480 WebAXObject root_obj = document.accessibilityObject();
517 if (!root_obj.updateLayoutAndCheckValidity()) 481 if (!root_obj.updateLayoutAndCheckValidity())
518 return; 482 return;
519 483
520 WebAXObject obj = root_obj.hitTest(point); 484 WebAXObject obj = root_obj.hitTest(point);
521 if (obj.isDetached()) 485 if (obj.isDetached())
522 return; 486 return;
523 487
524 // If the object that was hit has a child frame, we have to send a 488 // If the object that was hit has a child frame, we have to send a
525 // message back to the browser to do the hit test in the child frame, 489 // message back to the browser to do the hit test in the child frame,
526 // recursively. 490 // recursively.
527 AXContentNodeData data; 491 AXContentNodeData data;
528 ScopedFreezeBlinkAXTreeSource freeze(&tree_source_); 492 ScopedFreezeBlinkAXTreeSource freeze(&tree_source_);
529 tree_source_.SerializeNode(obj, &data); 493 tree_source_.SerializeNode(obj, &data);
530 if (data.HasContentIntAttribute(AX_CONTENT_ATTR_CHILD_ROUTING_ID) || 494 if (data.HasContentIntAttribute(AX_CONTENT_ATTR_CHILD_ROUTING_ID) ||
531 data.HasContentIntAttribute( 495 data.HasContentIntAttribute(
532 AX_CONTENT_ATTR_CHILD_BROWSER_PLUGIN_INSTANCE_ID)) { 496 AX_CONTENT_ATTR_CHILD_BROWSER_PLUGIN_INSTANCE_ID)) {
533 Send(new AccessibilityHostMsg_ChildFrameHitTestResult(routing_id(), point, 497 Send(new AccessibilityHostMsg_ChildFrameHitTestResult(routing_id(), point,
534 obj.axID())); 498 obj.axID()));
535 return; 499 return;
536 } 500 }
537 501
538 // Otherwise, send a HOVER event on the node that was hit. 502 // Otherwise, send a HOVER event on the node that was hit.
539 HandleAXEvent(obj, ui::AX_EVENT_HOVER); 503 HandleAXEvent(obj, ui::AX_EVENT_HOVER);
540 } 504 }
541 505
542 void RenderAccessibilityImpl::OnSetAccessibilityFocus( 506 void RenderAccessibilityImpl::OnSetAccessibilityFocus(int acc_obj_id) {
543 const blink::WebAXObject& obj) {
544 ScopedFreezeBlinkAXTreeSource freeze(&tree_source_); 507 ScopedFreezeBlinkAXTreeSource freeze(&tree_source_);
545 if (tree_source_.accessibility_focus_id() == obj.axID()) 508 if (tree_source_.accessibility_focus_id() == acc_obj_id)
546 return; 509 return;
547 510
548 tree_source_.set_accessibility_focus_id(obj.axID()); 511 tree_source_.set_accessibility_focus_id(acc_obj_id);
549 512
550 const WebDocument& document = GetMainDocument(); 513 const WebDocument& document = GetMainDocument();
551 if (document.isNull()) 514 if (document.isNull())
552 return; 515 return;
553 516
517 WebAXObject obj = document.accessibilityObjectFromID(acc_obj_id);
518
554 // This object may not be a leaf node. Force the whole subtree to be 519 // This object may not be a leaf node. Force the whole subtree to be
555 // re-serialized. 520 // re-serialized.
556 serializer_.DeleteClientSubtree(obj); 521 serializer_.DeleteClientSubtree(obj);
557 522
558 // Explicitly send a tree change update event now. 523 // Explicitly send a tree change update event now.
559 HandleAXEvent(obj, ui::AX_EVENT_TREE_CHANGED); 524 HandleAXEvent(obj, ui::AX_EVENT_TREE_CHANGED);
560 } 525 }
561 526
562 void RenderAccessibilityImpl::OnReset(int reset_token) { 527 void RenderAccessibilityImpl::OnReset(int reset_token) {
563 reset_token_ = reset_token; 528 reset_token_ = reset_token;
564 serializer_.Reset(); 529 serializer_.Reset();
565 pending_events_.clear(); 530 pending_events_.clear();
566 531
567 const WebDocument& document = GetMainDocument(); 532 const WebDocument& document = GetMainDocument();
568 if (!document.isNull()) { 533 if (!document.isNull()) {
569 // Tree-only mode gets used by the automation extension API which requires a 534 // Tree-only mode gets used by the automation extension API which requires a
570 // load complete event to invoke listener callbacks. 535 // load complete event to invoke listener callbacks.
571 ui::AXEvent evt = document.accessibilityObject().isLoaded() 536 ui::AXEvent evt = document.accessibilityObject().isLoaded()
572 ? ui::AX_EVENT_LOAD_COMPLETE : ui::AX_EVENT_LAYOUT_COMPLETE; 537 ? ui::AX_EVENT_LOAD_COMPLETE : ui::AX_EVENT_LAYOUT_COMPLETE;
573 HandleAXEvent(document.accessibilityObject(), evt); 538 HandleAXEvent(document.accessibilityObject(), evt);
574 } 539 }
575 } 540 }
576 541
542 void RenderAccessibilityImpl::OnScrollToMakeVisible(
543 int acc_obj_id, gfx::Rect subfocus) {
544 if (plugin_tree_source_ && plugin_tree_source_->GetFromId(acc_obj_id)) {
545 ScrollPlugin(acc_obj_id);
546 return;
547 }
548
549 const WebDocument& document = GetMainDocument();
550 if (document.isNull())
551 return;
552
553 WebAXObject obj = document.accessibilityObjectFromID(acc_obj_id);
554 if (obj.isDetached()) {
555 #ifndef NDEBUG
556 LOG(WARNING) << "ScrollToMakeVisible on invalid object id " << acc_obj_id;
557 #endif
558 return;
559 }
560
561 obj.scrollToMakeVisibleWithSubFocus(
562 WebRect(subfocus.x(), subfocus.y(), subfocus.width(), subfocus.height()));
563
564 // Make sure the browser gets an event when the scroll
565 // position actually changes.
566 // TODO(dmazzoni): remove this once this bug is fixed:
567 // https://bugs.webkit.org/show_bug.cgi?id=73460
568 HandleAXEvent(document.accessibilityObject(), ui::AX_EVENT_LAYOUT_COMPLETE);
569 }
570
571 void RenderAccessibilityImpl::OnScrollToPoint(
572 int acc_obj_id, gfx::Point point) {
573 const WebDocument& document = GetMainDocument();
574 if (document.isNull())
575 return;
576
577 WebAXObject obj = document.accessibilityObjectFromID(acc_obj_id);
578 if (obj.isDetached()) {
579 #ifndef NDEBUG
580 LOG(WARNING) << "ScrollToPoint on invalid object id " << acc_obj_id;
581 #endif
582 return;
583 }
584
585 obj.scrollToGlobalPoint(WebPoint(point.x(), point.y()));
586
587 // Make sure the browser gets an event when the scroll
588 // position actually changes.
589 // TODO(dmazzoni): remove this once this bug is fixed:
590 // https://bugs.webkit.org/show_bug.cgi?id=73460
591 HandleAXEvent(document.accessibilityObject(), ui::AX_EVENT_LAYOUT_COMPLETE);
592 }
593
594 void RenderAccessibilityImpl::OnSetScrollOffset(int acc_obj_id,
595 gfx::Point offset) {
596 const WebDocument& document = GetMainDocument();
597 if (document.isNull())
598 return;
599
600 WebAXObject obj = document.accessibilityObjectFromID(acc_obj_id);
601 if (obj.isDetached())
602 return;
603
604 obj.setScrollOffset(WebPoint(offset.x(), offset.y()));
605 }
606
607 void RenderAccessibilityImpl::OnSetFocus(int acc_obj_id) {
608 const WebDocument& document = GetMainDocument();
609 if (document.isNull())
610 return;
611
612 WebAXObject obj = document.accessibilityObjectFromID(acc_obj_id);
613 if (obj.isDetached()) {
614 #ifndef NDEBUG
615 LOG(WARNING) << "OnSetAccessibilityFocus on invalid object id "
616 << acc_obj_id;
617 #endif
618 return;
619 }
620
621 WebAXObject root = document.accessibilityObject();
622 if (root.isDetached()) {
623 #ifndef NDEBUG
624 LOG(WARNING) << "OnSetAccessibilityFocus but root is invalid";
625 #endif
626 return;
627 }
628
629 // By convention, calling SetFocus on the root of the tree should clear the
630 // current focus. Otherwise set the focus to the new node.
631 if (acc_obj_id == root.axID())
632 render_frame_->GetRenderView()->GetWebView()->clearFocusedElement();
633 else
634 obj.setFocused(true);
635 }
636
637 void RenderAccessibilityImpl::OnSetSelection(int anchor_acc_obj_id,
638 int anchor_offset,
639 int focus_acc_obj_id,
640 int focus_offset) {
641 const WebDocument& document = GetMainDocument();
642 if (document.isNull())
643 return;
644
645 WebAXObject anchor_obj =
646 document.accessibilityObjectFromID(anchor_acc_obj_id);
647 if (anchor_obj.isDetached()) {
648 #ifndef NDEBUG
649 LOG(WARNING) << "SetTextSelection on invalid object id "
650 << anchor_acc_obj_id;
651 #endif
652 return;
653 }
654
655 WebAXObject focus_obj = document.accessibilityObjectFromID(focus_acc_obj_id);
656 if (focus_obj.isDetached()) {
657 #ifndef NDEBUG
658 LOG(WARNING) << "SetTextSelection on invalid object id "
659 << focus_acc_obj_id;
660 #endif
661 return;
662 }
663
664 anchor_obj.setSelection(anchor_obj, anchor_offset, focus_obj, focus_offset);
665 WebAXObject root = document.accessibilityObject();
666 if (root.isDetached()) {
667 #ifndef NDEBUG
668 LOG(WARNING) << "OnSetAccessibilityFocus but root is invalid";
669 #endif
670 return;
671 }
672 HandleAXEvent(root, ui::AX_EVENT_LAYOUT_COMPLETE);
673 }
674
675 void RenderAccessibilityImpl::OnSetValue(
676 int acc_obj_id,
677 base::string16 value) {
678 const WebDocument& document = GetMainDocument();
679 if (document.isNull())
680 return;
681
682 WebAXObject obj = document.accessibilityObjectFromID(acc_obj_id);
683 if (obj.isDetached()) {
684 #ifndef NDEBUG
685 LOG(WARNING) << "SetTextSelection on invalid object id " << acc_obj_id;
686 #endif
687 return;
688 }
689
690 obj.setValue(value);
691 HandleAXEvent(obj, ui::AX_EVENT_VALUE_CHANGED);
692 }
693
694 void RenderAccessibilityImpl::OnShowContextMenu(int acc_obj_id) {
695 const WebDocument& document = GetMainDocument();
696 if (document.isNull())
697 return;
698
699 WebAXObject obj = document.accessibilityObjectFromID(acc_obj_id);
700 if (obj.isDetached()) {
701 #ifndef NDEBUG
702 LOG(WARNING) << "ShowContextMenu on invalid object id " << acc_obj_id;
703 #endif
704 return;
705 }
706
707 obj.showContextMenu();
708 }
709
577 void RenderAccessibilityImpl::OnDestruct() { 710 void RenderAccessibilityImpl::OnDestruct() {
578 delete this; 711 delete this;
579 } 712 }
580 713
581 void RenderAccessibilityImpl::AddPluginTreeToUpdate( 714 void RenderAccessibilityImpl::AddPluginTreeToUpdate(
582 AXContentTreeUpdate* update) { 715 AXContentTreeUpdate* update) {
583 for (size_t i = 0; i < update->nodes.size(); ++i) { 716 for (size_t i = 0; i < update->nodes.size(); ++i) {
584 if (update->nodes[i].role == ui::AX_ROLE_EMBEDDED_OBJECT) { 717 if (update->nodes[i].role == ui::AX_ROLE_EMBEDDED_OBJECT) {
585 const ui::AXNode* root = plugin_tree_source_->GetRoot(); 718 const ui::AXNode* root = plugin_tree_source_->GetRoot();
586 update->nodes[i].child_ids.push_back(root->id()); 719 update->nodes[i].child_ids.push_back(root->id());
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
623 756
624 const WebDocument& document = GetMainDocument(); 757 const WebDocument& document = GetMainDocument();
625 if (document.isNull()) 758 if (document.isNull())
626 return; 759 return;
627 760
628 document.accessibilityObject().scrollToMakeVisibleWithSubFocus( 761 document.accessibilityObject().scrollToMakeVisibleWithSubFocus(
629 WebRect(bounds.x(), bounds.y(), bounds.width(), bounds.height())); 762 WebRect(bounds.x(), bounds.y(), bounds.width(), bounds.height()));
630 } 763 }
631 764
632 } // namespace content 765 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/accessibility/render_accessibility_impl.h ('k') | ui/accessibility/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698