[safe-browsing] Database full hash matches like prefix match.
[chromium-blink-merge.git] / content / shell / renderer / test_runner / accessibility_controller.cc
blob430e00c17518cc920f14ff2871a6f099bd3976bd
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.
5 #include "content/shell/renderer/test_runner/accessibility_controller.h"
7 #include "gin/handle.h"
8 #include "gin/object_template_builder.h"
9 #include "gin/wrappable.h"
10 #include "third_party/WebKit/public/web/WebElement.h"
11 #include "third_party/WebKit/public/web/WebFrame.h"
12 #include "third_party/WebKit/public/web/WebKit.h"
13 #include "third_party/WebKit/public/web/WebView.h"
15 namespace content {
17 class AccessibilityControllerBindings
18 : public gin::Wrappable<AccessibilityControllerBindings> {
19 public:
20 static gin::WrapperInfo kWrapperInfo;
22 static void Install(base::WeakPtr<AccessibilityController> controller,
23 blink::WebFrame* frame);
25 private:
26 explicit AccessibilityControllerBindings(
27 base::WeakPtr<AccessibilityController> controller);
28 virtual ~AccessibilityControllerBindings();
30 // gin::Wrappable:
31 virtual gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
32 v8::Isolate* isolate) OVERRIDE;
34 void LogAccessibilityEvents();
35 void SetNotificationListener(v8::Handle<v8::Function> callback);
36 void UnsetNotificationListener();
37 v8::Handle<v8::Object> FocusedElement();
38 v8::Handle<v8::Object> RootElement();
39 v8::Handle<v8::Object> AccessibleElementById(const std::string& id);
41 base::WeakPtr<AccessibilityController> controller_;
43 DISALLOW_COPY_AND_ASSIGN(AccessibilityControllerBindings);
46 gin::WrapperInfo AccessibilityControllerBindings::kWrapperInfo = {
47 gin::kEmbedderNativeGin};
49 // static
50 void AccessibilityControllerBindings::Install(
51 base::WeakPtr<AccessibilityController> controller,
52 blink::WebFrame* frame) {
53 v8::Isolate* isolate = blink::mainThreadIsolate();
54 v8::HandleScope handle_scope(isolate);
55 v8::Handle<v8::Context> context = frame->mainWorldScriptContext();
56 if (context.IsEmpty())
57 return;
59 v8::Context::Scope context_scope(context);
61 gin::Handle<AccessibilityControllerBindings> bindings =
62 gin::CreateHandle(isolate,
63 new AccessibilityControllerBindings(controller));
64 if (bindings.IsEmpty())
65 return;
66 v8::Handle<v8::Object> global = context->Global();
67 global->Set(gin::StringToV8(isolate, "accessibilityController"),
68 bindings.ToV8());
71 AccessibilityControllerBindings::AccessibilityControllerBindings(
72 base::WeakPtr<AccessibilityController> controller)
73 : controller_(controller) {
76 AccessibilityControllerBindings::~AccessibilityControllerBindings() {
79 gin::ObjectTemplateBuilder
80 AccessibilityControllerBindings::GetObjectTemplateBuilder(
81 v8::Isolate* isolate) {
82 return gin::Wrappable<AccessibilityControllerBindings>::
83 GetObjectTemplateBuilder(isolate)
84 .SetMethod("logAccessibilityEvents",
85 &AccessibilityControllerBindings::LogAccessibilityEvents)
86 .SetMethod("setNotificationListener",
87 &AccessibilityControllerBindings::SetNotificationListener)
88 .SetMethod("unsetNotificationListener",
89 &AccessibilityControllerBindings::UnsetNotificationListener)
90 .SetProperty("focusedElement",
91 &AccessibilityControllerBindings::FocusedElement)
92 .SetProperty("rootElement",
93 &AccessibilityControllerBindings::RootElement)
94 .SetMethod("accessibleElementById",
95 &AccessibilityControllerBindings::AccessibleElementById)
96 // TODO(hajimehoshi): These are for backward compatibility. Remove them.
97 .SetMethod("addNotificationListener",
98 &AccessibilityControllerBindings::SetNotificationListener)
99 .SetMethod("removeNotificationListener",
100 &AccessibilityControllerBindings::UnsetNotificationListener);
103 void AccessibilityControllerBindings::LogAccessibilityEvents() {
104 if (controller_)
105 controller_->LogAccessibilityEvents();
108 void AccessibilityControllerBindings::SetNotificationListener(
109 v8::Handle<v8::Function> callback) {
110 if (controller_)
111 controller_->SetNotificationListener(callback);
114 void AccessibilityControllerBindings::UnsetNotificationListener() {
115 if (controller_)
116 controller_->UnsetNotificationListener();
119 v8::Handle<v8::Object> AccessibilityControllerBindings::FocusedElement() {
120 return controller_ ? controller_->FocusedElement() : v8::Handle<v8::Object>();
123 v8::Handle<v8::Object> AccessibilityControllerBindings::RootElement() {
124 return controller_ ? controller_->RootElement() : v8::Handle<v8::Object>();
127 v8::Handle<v8::Object> AccessibilityControllerBindings::AccessibleElementById(
128 const std::string& id) {
129 return controller_ ? controller_->AccessibleElementById(id)
130 : v8::Handle<v8::Object>();
133 AccessibilityController::AccessibilityController()
134 : log_accessibility_events_(false),
135 weak_factory_(this) {
138 AccessibilityController::~AccessibilityController() {}
140 void AccessibilityController::Reset() {
141 root_element_ = blink::WebAXObject();
142 focused_element_ = blink::WebAXObject();
143 elements_.Clear();
144 notification_callback_.Reset();
145 log_accessibility_events_ = false;
148 void AccessibilityController::Install(blink::WebFrame* frame) {
149 blink::WebAXObject::enableAccessibility();
150 blink::WebAXObject::enableInlineTextBoxAccessibility();
151 AccessibilityControllerBindings::Install(weak_factory_.GetWeakPtr(), frame);
154 void AccessibilityController::SetFocusedElement(
155 const blink::WebAXObject& focused_element) {
156 focused_element_ = focused_element;
159 bool AccessibilityController::ShouldLogAccessibilityEvents() {
160 return log_accessibility_events_;
163 void AccessibilityController::NotificationReceived(
164 const blink::WebAXObject& target, const std::string& notification_name) {
165 v8::Isolate* isolate = blink::mainThreadIsolate();
166 v8::HandleScope handle_scope(isolate);
168 blink::WebFrame* frame = web_view_->mainFrame();
169 if (!frame)
170 return;
172 v8::Handle<v8::Context> context = frame->mainWorldScriptContext();
173 if (context.IsEmpty())
174 return;
176 v8::Context::Scope context_scope(context);
178 // Call notification listeners on the element.
179 v8::Handle<v8::Object> element_handle = elements_.GetOrCreate(target);
180 if (element_handle.IsEmpty())
181 return;
183 WebAXObjectProxy* element;
184 bool result = gin::ConvertFromV8(isolate, element_handle, &element);
185 DCHECK(result);
186 element->NotificationReceived(frame, notification_name);
188 if (notification_callback_.IsEmpty())
189 return;
191 // Call global notification listeners.
192 v8::Handle<v8::Value> argv[] = {
193 element_handle,
194 v8::String::NewFromUtf8(isolate, notification_name.data(),
195 v8::String::kNormalString,
196 notification_name.size()),
198 frame->callFunctionEvenIfScriptDisabled(
199 v8::Local<v8::Function>::New(isolate, notification_callback_),
200 context->Global(),
201 arraysize(argv),
202 argv);
205 void AccessibilityController::SetDelegate(
206 WebTestRunner::WebTestDelegate* delegate) {
207 delegate_ = delegate;
210 void AccessibilityController::SetWebView(blink::WebView* web_view) {
211 web_view_ = web_view;
214 void AccessibilityController::LogAccessibilityEvents() {
215 log_accessibility_events_ = true;
218 void AccessibilityController::SetNotificationListener(
219 v8::Handle<v8::Function> callback) {
220 v8::Isolate* isolate = blink::mainThreadIsolate();
221 notification_callback_.Reset(isolate, callback);
224 void AccessibilityController::UnsetNotificationListener() {
225 notification_callback_.Reset();
228 v8::Handle<v8::Object> AccessibilityController::FocusedElement() {
229 if (focused_element_.isNull())
230 focused_element_ = web_view_->accessibilityObject();
231 return elements_.GetOrCreate(focused_element_);
234 v8::Handle<v8::Object> AccessibilityController::RootElement() {
235 if (root_element_.isNull())
236 root_element_ = web_view_->accessibilityObject();
237 return elements_.CreateRoot(root_element_);
240 v8::Handle<v8::Object>
241 AccessibilityController::AccessibleElementById(const std::string& id) {
242 if (root_element_.isNull())
243 root_element_ = web_view_->accessibilityObject();
245 if (!root_element_.updateBackingStoreAndCheckValidity())
246 return v8::Handle<v8::Object>();
248 return FindAccessibleElementByIdRecursive(
249 root_element_, blink::WebString::fromUTF8(id.c_str()));
252 v8::Handle<v8::Object>
253 AccessibilityController::FindAccessibleElementByIdRecursive(
254 const blink::WebAXObject& obj, const blink::WebString& id) {
255 if (obj.isNull() || obj.isDetached())
256 return v8::Handle<v8::Object>();
258 blink::WebNode node = obj.node();
259 if (!node.isNull() && node.isElementNode()) {
260 blink::WebElement element = node.to<blink::WebElement>();
261 element.getAttribute("id");
262 if (element.getAttribute("id") == id)
263 return elements_.GetOrCreate(obj);
266 unsigned childCount = obj.childCount();
267 for (unsigned i = 0; i < childCount; i++) {
268 v8::Handle<v8::Object> result =
269 FindAccessibleElementByIdRecursive(obj.childAt(i), id);
270 if (*result)
271 return result;
274 return v8::Handle<v8::Object>();
277 } // namespace content