summaryrefslogtreecommitdiffstats
path: root/content/renderer/accessibility/renderer_accessibility_complete.h
blob: 82fe4f81d44df0196873075c316060815959279a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CONTENT_RENDERER_ACCESSIBILITY_RENDERER_ACCESSIBILITY_COMPLETE_H_
#define CONTENT_RENDERER_ACCESSIBILITY_RENDERER_ACCESSIBILITY_COMPLETE_H_

#include <vector>

#include "base/containers/hash_tables.h"
#include "base/memory/weak_ptr.h"
#include "content/common/accessibility_node_data.h"
#include "content/public/renderer/render_view_observer.h"
#include "content/renderer/accessibility/renderer_accessibility.h"
#include "third_party/WebKit/public/web/WebAccessibilityNotification.h"

namespace WebKit {
class WebAccessibilityObject;
class WebDocument;
class WebNode;
};

namespace content {
class RenderViewImpl;

// This is the subclass of RendererAccessibility that implements
// complete accessibility support for assistive technology (as opposed to
// partial support - see RendererAccessibilityFocusOnly).
//
// This version turns on WebKit's accessibility code and sends
// a serialized representation of that tree whenever it changes. It also
// handles requests from the browser to perform accessibility actions on
// nodes in the tree (e.g., change focus, or click on a button).
class CONTENT_EXPORT RendererAccessibilityComplete
    : public RendererAccessibility {
 public:
  explicit RendererAccessibilityComplete(RenderViewImpl* render_view);
  virtual ~RendererAccessibilityComplete();

  // RenderView::Observer implementation.
  virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
  virtual void FocusedNodeChanged(const WebKit::WebNode& node) OVERRIDE;
  virtual void DidFinishLoad(WebKit::WebFrame* frame) OVERRIDE;

  // RendererAccessibility.
  virtual void HandleWebAccessibilityNotification(
      const WebKit::WebAccessibilityObject& obj,
      WebKit::WebAccessibilityNotification notification) OVERRIDE;

  // In order to keep track of what nodes the browser knows about, we keep a
  // representation of the browser tree - just IDs and parent/child
  // relationships.
  struct CONTENT_EXPORT BrowserTreeNode {
    BrowserTreeNode();
    virtual ~BrowserTreeNode();
    int32 id;
    gfx::Rect location;
    BrowserTreeNode* parent;
    std::vector<BrowserTreeNode*> children;
  };

  virtual BrowserTreeNode* CreateBrowserTreeNode();

 protected:
  // Send queued notifications from the renderer to the browser.
  void SendPendingAccessibilityNotifications();

  // Check the entire accessibility tree to see if any nodes have
  // changed location, by comparing their locations to the cached
  // versions. If any have moved, append a notification to |notifications|
  // that updates the coordinates of these objects.
  void AppendLocationChangeNotifications(
      std::vector<AccessibilityHostMsg_NotificationParams>* notifications);

 private:
  // Handle an accessibility notification to be sent to the browser process.
  void HandleAccessibilityNotification(
      const WebKit::WebAccessibilityObject& obj,
      AccessibilityNotification notification);

  // Serialize the given accessibility object |obj| and append it to
  // |dst|, and then recursively also serialize any *new* children of
  // |obj|, based on what object ids we know the browser already has.
  void SerializeChangedNodes(const WebKit::WebAccessibilityObject& obj,
                             std::vector<AccessibilityNodeData>* dst);

  // Clear the given node and recursively delete all of its descendants
  // from the browser tree. (Does not delete |browser_node|).
  void ClearBrowserTreeNode(BrowserTreeNode* browser_node);

  // Handlers for messages from the browser to the renderer.
  void OnDoDefaultAction(int acc_obj_id);
  void OnNotificationsAck();
  void OnChangeScrollPosition(int acc_obj_id, int scroll_x, int scroll_y);
  void OnScrollToMakeVisible(int acc_obj_id, gfx::Rect subfocus);
  void OnScrollToPoint(int acc_obj_id, gfx::Point point);
  void OnSetFocus(int acc_obj_id);
  void OnSetTextSelection(int acc_obj_id, int start_offset, int end_offset);
  void OnFatalError();

  // Checks if a WebKit accessibility object is an editable text node.
  bool IsEditableText(const WebKit::WebAccessibilityObject& node);

  // Recursively explore the tree of WebKit accessibility objects rooted
  // at |src|, and for each editable text node encountered, add a
  // corresponding WebAccessibility node as a child of |dst|.
  void RecursiveAddEditableTextNodesToTree(
      const WebKit::WebAccessibilityObject& src,
      AccessibilityNodeData* dst);

  // Build a tree of serializable AccessibilityNodeData nodes to send to the
  // browser process, given a WebAccessibilityObject node from WebKit.
  // Modifies |dst| in-place, it's assumed to be empty.
  void BuildAccessibilityTree(const WebKit::WebAccessibilityObject& src,
                              bool include_children,
                              AccessibilityNodeData* dst);

  // So we can queue up tasks to be executed later.
  base::WeakPtrFactory<RendererAccessibilityComplete> weak_factory_;

  // Notifications from WebKit are collected until they are ready to be
  // sent to the browser.
  std::vector<AccessibilityHostMsg_NotificationParams> pending_notifications_;

  // Our representation of the browser tree.
  BrowserTreeNode* browser_root_;

  // A map from IDs to nodes in the browser tree.
  base::hash_map<int32, BrowserTreeNode*> browser_id_map_;

  // The most recently observed scroll offset of the root document element.
  // TODO(dmazzoni): remove once https://bugs.webkit.org/show_bug.cgi?id=73460
  // is fixed.
  gfx::Size last_scroll_offset_;

  // The current accessibility mode.
  AccessibilityMode mode_;

  // Set if we are waiting for an accessibility notification ack.
  bool ack_pending_;

  // True if verbose logging of accessibility events is on.
  bool logging_;

  DISALLOW_COPY_AND_ASSIGN(RendererAccessibilityComplete);
};

#endif  // CONTENT_RENDERER_ACCESSIBILITY_RENDERER_ACCESSIBILITY_COMPLETE_H_

}  // namespace content