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

Side by Side Diff: content/shell/renderer/test_runner/accessibility_controller.cc

Issue 172263002: Move WebAXObjectProxy and AccessibleController from CppBoundClass to gin::Wrappable (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: (rebasing) Created 6 years, 9 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
(Empty)
1 // Copyright 2014 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 // TODO(hajimehoshi): Remove this when UnsafePersistent is removed.
6 #define V8_ALLOW_ACCESS_TO_RAW_HANDLE_CONSTRUCTOR
7
8 #include "content/shell/renderer/test_runner/accessibility_controller.h"
9
10 #include "gin/handle.h"
11 #include "gin/object_template_builder.h"
12 #include "gin/wrappable.h"
13 #include "third_party/WebKit/public/web/WebElement.h"
14 #include "third_party/WebKit/public/web/WebFrame.h"
15 #include "third_party/WebKit/public/web/WebKit.h"
16 #include "third_party/WebKit/public/web/WebView.h"
17
18 namespace content {
19
20 class AccessibilityControllerBindings
21 : public gin::Wrappable<AccessibilityControllerBindings> {
22 public:
23 static gin::WrapperInfo kWrapperInfo;
24
25 static void Install(base::WeakPtr<AccessibilityController> controller,
26 blink::WebFrame* frame);
27
28 private:
29 explicit AccessibilityControllerBindings(
30 base::WeakPtr<AccessibilityController> controller);
31 virtual ~AccessibilityControllerBindings();
32
33 // gin::Wrappable:
34 virtual gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
35 v8::Isolate* isolate) OVERRIDE;
36
37 void LogAccessibilityEvents();
38 void AddNotificationListener(v8::Handle<v8::Function> callback);
39 void RemoveNotificationListener();
40 v8::Handle<v8::Object> FocusedElement();
41 v8::Handle<v8::Object> RootElement();
42 v8::Handle<v8::Object> AccessibleElementById(const std::string& id);
43
44 base::WeakPtr<AccessibilityController> controller_;
45
46 DISALLOW_COPY_AND_ASSIGN(AccessibilityControllerBindings);
47 };
48
49 gin::WrapperInfo AccessibilityControllerBindings::kWrapperInfo = {
50 gin::kEmbedderNativeGin};
51
52 // static
53 void AccessibilityControllerBindings::Install(
54 base::WeakPtr<AccessibilityController> controller,
55 blink::WebFrame* frame) {
56 v8::Isolate* isolate = blink::mainThreadIsolate();
57 v8::HandleScope handle_scope(isolate);
58 v8::Handle<v8::Context> context = frame->mainWorldScriptContext();
59 if (context.IsEmpty())
60 return;
61
62 v8::Context::Scope context_scope(context);
63
64 gin::Handle<AccessibilityControllerBindings> bindings =
65 gin::CreateHandle(isolate,
66 new AccessibilityControllerBindings(controller));
67 v8::Handle<v8::Object> global = context->Global();
68 global->Set(gin::StringToV8(isolate, "accessibilityController"),
69 bindings.ToV8());
70 }
71
72 AccessibilityControllerBindings::AccessibilityControllerBindings(
73 base::WeakPtr<AccessibilityController> controller)
74 : controller_(controller) {
75 }
76
77 AccessibilityControllerBindings::~AccessibilityControllerBindings() {
78 }
79
80 gin::ObjectTemplateBuilder
81 AccessibilityControllerBindings::GetObjectTemplateBuilder(
82 v8::Isolate* isolate) {
83 return gin::Wrappable<AccessibilityControllerBindings>::
84 GetObjectTemplateBuilder(isolate)
85 .SetMethod("logAccessibilityEvents",
86 &AccessibilityControllerBindings::LogAccessibilityEvents)
87 .SetMethod("addNotificationListener",
88 &AccessibilityControllerBindings::AddNotificationListener)
89 .SetMethod("removeNotificationListener",
90 &AccessibilityControllerBindings::RemoveNotificationListener)
91 .SetProperty("focusedElement",
92 &AccessibilityControllerBindings::FocusedElement)
93 .SetProperty("rootElement",
94 &AccessibilityControllerBindings::RootElement)
95 .SetMethod("accessibleElementById",
96 &AccessibilityControllerBindings::AccessibleElementById);
97 }
98
99 void AccessibilityControllerBindings::LogAccessibilityEvents() {
100 if (controller_)
101 controller_->LogAccessibilityEvents();
102 }
103
104 void AccessibilityControllerBindings::AddNotificationListener(
105 v8::Handle<v8::Function> callback) {
106 if (controller_)
107 controller_->AddNotificationListener(callback);
108 }
109
110 void AccessibilityControllerBindings::RemoveNotificationListener() {
111 if (controller_)
112 controller_->RemoveNotificationListener();
113 }
114
115 v8::Handle<v8::Object> AccessibilityControllerBindings::FocusedElement() {
116 return controller_ ? controller_->FocusedElement() : v8::Handle<v8::Object>();
117 }
118
119 v8::Handle<v8::Object> AccessibilityControllerBindings::RootElement() {
120 return controller_ ? controller_->RootElement() : v8::Handle<v8::Object>();
121 }
122
123 v8::Handle<v8::Object> AccessibilityControllerBindings::AccessibleElementById(
124 const std::string& id) {
125 return controller_ ? controller_->AccessibleElementById(id)
126 : v8::Handle<v8::Object>();
127 }
128
129 AccessibilityController::AccessibilityController()
130 : log_accessibility_events_(false),
131 weak_factory_(this) {
132 }
133
134 AccessibilityController::~AccessibilityController() {
135 ClearNotificationCallbacks();
136 }
137
138 void AccessibilityController::Reset() {
139 root_element_ = blink::WebAXObject();
140 focused_element_ = blink::WebAXObject();
141 elements_.Clear();
142 ClearNotificationCallbacks();
143 log_accessibility_events_ = false;
144 }
145
146 void AccessibilityController::Install(blink::WebFrame* frame) {
147 blink::WebAXObject::enableAccessibility();
148 blink::WebAXObject::enableInlineTextBoxAccessibility();
149 AccessibilityControllerBindings::Install(weak_factory_.GetWeakPtr(), frame);
150 }
151
152 void AccessibilityController::SetFocusedElement(
153 const blink::WebAXObject& focused_element) {
154 focused_element_ = focused_element;
155 }
156
157 bool AccessibilityController::ShouldLogAccessibilityEvents() {
158 return log_accessibility_events_;
159 }
160
161 void AccessibilityController::NotificationReceived(
162 const blink::WebAXObject& target, const std::string& notification_name) {
163 v8::Isolate* isolate = blink::mainThreadIsolate();
164 v8::HandleScope handle_scope(isolate);
165
166 blink::WebFrame* frame = web_view_->mainFrame();
167 if (!frame)
168 return;
169
170 v8::Handle<v8::Context> context = frame->mainWorldScriptContext();
171 if (context.IsEmpty())
172 return;
173
174 v8::Context::Scope context_scope(context);
175
176 // Call notification listeners on the element.
177 v8::Handle<v8::Object> element_handle = elements_.GetOrCreate(target);
178 WebAXObjectProxy* element;
179 bool result = gin::ConvertFromV8(isolate, element_handle, &element);
180 DCHECK(result);
181 element->NotificationReceived(frame, notification_name);
182
183 // Call global notification listeners.
184 v8::Handle<v8::Value> argv[] = {
185 element_handle,
186 v8::String::NewFromUtf8(isolate, notification_name.data(),
187 v8::String::kNormalString,
188 notification_name.size()),
189 };
190 for (CallbackList::iterator it = notification_callbacks_.begin();
191 it != notification_callbacks_.end(); ++it) {
192 frame->callFunctionEvenIfScriptDisabled((*it).NewLocal(isolate),
193 context->Global(),
194 arraysize(argv),
195 argv);
196 }
197 }
198
199 void AccessibilityController::SetDelegate(
200 WebTestRunner::WebTestDelegate* delegate) {
201 delegate_ = delegate;
202 }
203
204 void AccessibilityController::SetWebView(blink::WebView* web_view) {
205 web_view_ = web_view;
206 }
207
208 void AccessibilityController::LogAccessibilityEvents() {
209 log_accessibility_events_ = true;
210 }
211
212 void AccessibilityController::AddNotificationListener(
213 v8::Handle<v8::Function> callback) {
214 v8::Isolate* isolate = blink::mainThreadIsolate();
215 notification_callbacks_.push_back(
216 UnsafePersistent<v8::Function>(isolate, callback));
217 }
218
219 void AccessibilityController::RemoveNotificationListener() {
220 // FIXME: Implement this
kouhei (in TOK) 2014/02/27 05:50:54 Would you implement this? notification_callbacks_
hajimehoshi 2014/02/27 07:33:07 We realized that we don't have to set multiple cal
221 }
222
223 v8::Handle<v8::Object> AccessibilityController::FocusedElement() {
224 if (focused_element_.isNull())
225 focused_element_ = web_view_->accessibilityObject();
226 return elements_.GetOrCreate(focused_element_);
227 }
228
229 v8::Handle<v8::Object> AccessibilityController::RootElement() {
230 if (root_element_.isNull())
231 root_element_ = web_view_->accessibilityObject();
232 return elements_.CreateRoot(root_element_);
233 }
234
235 v8::Handle<v8::Object>
236 AccessibilityController::AccessibleElementById(const std::string& id) {
237 if (root_element_.isNull())
238 root_element_ = web_view_->accessibilityObject();
239
240 if (!root_element_.updateBackingStoreAndCheckValidity())
241 return v8::Handle<v8::Object>();
242
243 return FindAccessibleElementByIdRecursive(
244 root_element_, blink::WebString::fromUTF8(id.c_str()));
245 }
246
247 v8::Handle<v8::Object>
248 AccessibilityController::FindAccessibleElementByIdRecursive(
249 const blink::WebAXObject& obj, const blink::WebString& id) {
250 if (obj.isNull() || obj.isDetached())
251 return v8::Handle<v8::Object>();
252
253 blink::WebNode node = obj.node();
254 if (!node.isNull() && node.isElementNode()) {
255 blink::WebElement element = node.to<blink::WebElement>();
256 element.getAttribute("id");
257 if (element.getAttribute("id") == id)
258 return elements_.GetOrCreate(obj);
259 }
260
261 unsigned childCount = obj.childCount();
262 for (unsigned i = 0; i < childCount; i++) {
263 v8::Handle<v8::Object> result =
264 FindAccessibleElementByIdRecursive(obj.childAt(i), id);
265 if (*result)
266 return result;
267 }
268
269 return v8::Handle<v8::Object>();
270 }
271
272 void AccessibilityController::ClearNotificationCallbacks() {
273 for (CallbackList::iterator it = notification_callbacks_.begin();
274 it != notification_callbacks_.end(); ++it) {
275 it->Dispose();
276 }
277 notification_callbacks_.clear();
278 }
279
280 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698