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 3 // found in the LICENSE file. 4 5 #ifndef CONTENT_RENDERER_ACCESSIBILITY_RENDERER_ACCESSIBILITY_COMPLETE_H_ 6 #define CONTENT_RENDERER_ACCESSIBILITY_RENDERER_ACCESSIBILITY_COMPLETE_H_ 7 8 #include <set> 9 #include <vector> 10 11 #include "base/containers/hash_tables.h" 12 #include "base/memory/weak_ptr.h" 13 #include "content/common/accessibility_node_data.h" 14 #include "content/public/renderer/render_view_observer.h" 15 #include "content/renderer/accessibility/renderer_accessibility.h" 16 #include "third_party/WebKit/public/web/WebAXEnums.h" 17 #include "third_party/WebKit/public/web/WebAXObject.h" 18 19 namespace blink { 20 class WebDocument; 21 class WebNode; 22 }; 23 24 namespace content { 25 class RenderViewImpl; 26 27 // This is the subclass of RendererAccessibility that implements 28 // complete accessibility support for assistive technology (as opposed to 29 // partial support - see RendererAccessibilityFocusOnly). 30 // 31 // This version turns on WebKit's accessibility code and sends 32 // a serialized representation of that tree whenever it changes. It also 33 // handles requests from the browser to perform accessibility actions on 34 // nodes in the tree (e.g., change focus, or click on a button). 35 class CONTENT_EXPORT RendererAccessibilityComplete 36 : public RendererAccessibility { 37 public: 38 explicit RendererAccessibilityComplete(RenderViewImpl* render_view); 39 virtual ~RendererAccessibilityComplete(); 40 41 // RenderView::Observer implementation. 42 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; 43 virtual void FocusedNodeChanged(const blink::WebNode& node) OVERRIDE; 44 virtual void DidFinishLoad(blink::WebFrame* frame) OVERRIDE; 45 46 // RendererAccessibility. 47 virtual void HandleWebAccessibilityEvent( 48 const blink::WebAXObject& obj, blink::WebAXEvent event) OVERRIDE; 49 50 // In order to keep track of what nodes the browser knows about, we keep a 51 // representation of the browser tree - just IDs and parent/child 52 // relationships. 53 struct CONTENT_EXPORT BrowserTreeNode { 54 BrowserTreeNode(); 55 virtual ~BrowserTreeNode(); 56 int32 id; 57 gfx::Rect location; 58 BrowserTreeNode* parent; 59 std::vector<BrowserTreeNode*> children; 60 }; 61 62 virtual BrowserTreeNode* CreateBrowserTreeNode(); 63 64 protected: 65 // Send queued events from the renderer to the browser. 66 void SendPendingAccessibilityEvents(); 67 68 // Check the entire accessibility tree to see if any nodes have 69 // changed location, by comparing their locations to the cached 70 // versions. If any have moved, append a event to |events| 71 // that updates the coordinates of these objects. 72 void AppendLocationChangeEvents( 73 std::vector<AccessibilityHostMsg_EventParams>* events); 74 75 private: 76 // Serialize the given accessibility object |obj| and append it to 77 // |dst|, and then recursively also serialize any *new* children of 78 // |obj|, based on what object ids we know the browser already has. 79 // The set of ids serialized is added to |ids_serialized|, and any 80 // ids previously in that set are not serialized again. 81 void SerializeChangedNodes(const blink::WebAXObject& obj, 82 std::vector<AccessibilityNodeData>* dst, 83 std::set<int>* ids_serialized); 84 85 // Clear the given node and recursively delete all of its descendants 86 // from the browser tree. (Does not delete |browser_node|). 87 void ClearBrowserTreeNode(BrowserTreeNode* browser_node); 88 89 // Handlers for messages from the browser to the renderer. 90 void OnDoDefaultAction(int acc_obj_id); 91 void OnEventsAck(); 92 void OnChangeScrollPosition(int acc_obj_id, int scroll_x, int scroll_y); 93 void OnScrollToMakeVisible(int acc_obj_id, gfx::Rect subfocus); 94 void OnScrollToPoint(int acc_obj_id, gfx::Point point); 95 void OnSetFocus(int acc_obj_id); 96 void OnSetTextSelection(int acc_obj_id, int start_offset, int end_offset); 97 void OnFatalError(); 98 99 // Checks if a WebKit accessibility object is an editable text node. 100 bool IsEditableText(const blink::WebAXObject& node); 101 102 // Recursively explore the tree of WebKit accessibility objects rooted 103 // at |src|, and for each editable text node encountered, add a 104 // corresponding WebAccessibility node as a child of |dst|. 105 void RecursiveAddEditableTextNodesToTree( 106 const blink::WebAXObject& src, 107 AccessibilityNodeData* dst); 108 109 // Build a tree of serializable AccessibilityNodeData nodes to send to the 110 // browser process, given a WebAXObject node from WebKit. 111 // Modifies |dst| in-place, it's assumed to be empty. 112 void BuildAccessibilityTree(const blink::WebAXObject& src, 113 bool include_children, 114 AccessibilityNodeData* dst); 115 116 // So we can queue up tasks to be executed later. 117 base::WeakPtrFactory<RendererAccessibilityComplete> weak_factory_; 118 119 // Events from WebKit are collected until they are ready to be 120 // sent to the browser. 121 std::vector<AccessibilityHostMsg_EventParams> pending_events_; 122 123 // Our representation of the browser tree. 124 BrowserTreeNode* browser_root_; 125 126 // A map from IDs to nodes in the browser tree. 127 base::hash_map<int32, BrowserTreeNode*> browser_id_map_; 128 129 // The most recently observed scroll offset of the root document element. 130 // TODO(dmazzoni): remove once https://bugs.webkit.org/show_bug.cgi?id=73460 131 // is fixed. 132 gfx::Size last_scroll_offset_; 133 134 // The current accessibility mode. 135 AccessibilityMode mode_; 136 137 // Set if we are waiting for an accessibility event ack. 138 bool ack_pending_; 139 140 // True if verbose logging of accessibility events is on. 141 bool logging_; 142 143 DISALLOW_COPY_AND_ASSIGN(RendererAccessibilityComplete); 144 }; 145 146 #endif // CONTENT_RENDERER_ACCESSIBILITY_RENDERER_ACCESSIBILITY_COMPLETE_H_ 147 148 } // namespace content 149