1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// found in the LICENSE file. 4a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/shell/renderer/test_runner/accessibility_controller.h" 6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "gin/handle.h" 8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "gin/object_template_builder.h" 9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "gin/wrappable.h" 10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "third_party/WebKit/public/web/WebElement.h" 11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "third_party/WebKit/public/web/WebFrame.h" 12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "third_party/WebKit/public/web/WebKit.h" 13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "third_party/WebKit/public/web/WebView.h" 14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace content { 16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class AccessibilityControllerBindings 18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : public gin::Wrappable<AccessibilityControllerBindings> { 19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public: 20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) static gin::WrapperInfo kWrapperInfo; 21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) static void Install(base::WeakPtr<AccessibilityController> controller, 23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) blink::WebFrame* frame); 24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) private: 26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) explicit AccessibilityControllerBindings( 27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::WeakPtr<AccessibilityController> controller); 28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual ~AccessibilityControllerBindings(); 29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // gin::Wrappable: 31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual gin::ObjectTemplateBuilder GetObjectTemplateBuilder( 32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) v8::Isolate* isolate) OVERRIDE; 33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void LogAccessibilityEvents(); 35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void SetNotificationListener(v8::Handle<v8::Function> callback); 36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void UnsetNotificationListener(); 37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) v8::Handle<v8::Object> FocusedElement(); 38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) v8::Handle<v8::Object> RootElement(); 39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) v8::Handle<v8::Object> AccessibleElementById(const std::string& id); 40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::WeakPtr<AccessibilityController> controller_; 42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(AccessibilityControllerBindings); 44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}; 45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)gin::WrapperInfo AccessibilityControllerBindings::kWrapperInfo = { 47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gin::kEmbedderNativeGin}; 48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// static 50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void AccessibilityControllerBindings::Install( 51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::WeakPtr<AccessibilityController> controller, 52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) blink::WebFrame* frame) { 53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) v8::Isolate* isolate = blink::mainThreadIsolate(); 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) v8::HandleScope handle_scope(isolate); 55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) v8::Handle<v8::Context> context = frame->mainWorldScriptContext(); 56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (context.IsEmpty()) 57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) v8::Context::Scope context_scope(context); 60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gin::Handle<AccessibilityControllerBindings> bindings = 62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gin::CreateHandle(isolate, 63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) new AccessibilityControllerBindings(controller)); 645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (bindings.IsEmpty()) 655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return; 66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) v8::Handle<v8::Object> global = context->Global(); 67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) global->Set(gin::StringToV8(isolate, "accessibilityController"), 68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bindings.ToV8()); 69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)AccessibilityControllerBindings::AccessibilityControllerBindings( 72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::WeakPtr<AccessibilityController> controller) 73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : controller_(controller) { 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)AccessibilityControllerBindings::~AccessibilityControllerBindings() { 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)gin::ObjectTemplateBuilder 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)AccessibilityControllerBindings::GetObjectTemplateBuilder( 81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) v8::Isolate* isolate) { 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return gin::Wrappable<AccessibilityControllerBindings>:: 83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GetObjectTemplateBuilder(isolate) 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) .SetMethod("logAccessibilityEvents", 85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &AccessibilityControllerBindings::LogAccessibilityEvents) 86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) .SetMethod("setNotificationListener", 87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &AccessibilityControllerBindings::SetNotificationListener) 88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) .SetMethod("unsetNotificationListener", 89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &AccessibilityControllerBindings::UnsetNotificationListener) 90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) .SetProperty("focusedElement", 91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &AccessibilityControllerBindings::FocusedElement) 92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) .SetProperty("rootElement", 93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &AccessibilityControllerBindings::RootElement) 94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) .SetMethod("accessibleElementById", 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &AccessibilityControllerBindings::AccessibleElementById) 96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // TODO(hajimehoshi): These are for backward compatibility. Remove them. 97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) .SetMethod("addNotificationListener", 98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &AccessibilityControllerBindings::SetNotificationListener) 99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) .SetMethod("removeNotificationListener", 100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &AccessibilityControllerBindings::UnsetNotificationListener); 101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void AccessibilityControllerBindings::LogAccessibilityEvents() { 104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (controller_) 105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) controller_->LogAccessibilityEvents(); 106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void AccessibilityControllerBindings::SetNotificationListener( 109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) v8::Handle<v8::Function> callback) { 110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (controller_) 111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) controller_->SetNotificationListener(callback); 112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void AccessibilityControllerBindings::UnsetNotificationListener() { 115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (controller_) 116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) controller_->UnsetNotificationListener(); 117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)v8::Handle<v8::Object> AccessibilityControllerBindings::FocusedElement() { 120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return controller_ ? controller_->FocusedElement() : v8::Handle<v8::Object>(); 121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)v8::Handle<v8::Object> AccessibilityControllerBindings::RootElement() { 124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return controller_ ? controller_->RootElement() : v8::Handle<v8::Object>(); 125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)v8::Handle<v8::Object> AccessibilityControllerBindings::AccessibleElementById( 128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& id) { 129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return controller_ ? controller_->AccessibleElementById(id) 130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : v8::Handle<v8::Object>(); 131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)AccessibilityController::AccessibilityController() 134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : log_accessibility_events_(false), 135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) weak_factory_(this) { 136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)AccessibilityController::~AccessibilityController() {} 139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void AccessibilityController::Reset() { 141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) root_element_ = blink::WebAXObject(); 142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) focused_element_ = blink::WebAXObject(); 143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) elements_.Clear(); 144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) notification_callback_.Reset(); 145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) log_accessibility_events_ = false; 146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void AccessibilityController::Install(blink::WebFrame* frame) { 149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) blink::WebAXObject::enableAccessibility(); 150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) blink::WebAXObject::enableInlineTextBoxAccessibility(); 151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) AccessibilityControllerBindings::Install(weak_factory_.GetWeakPtr(), frame); 152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void AccessibilityController::SetFocusedElement( 155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const blink::WebAXObject& focused_element) { 156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) focused_element_ = focused_element; 157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool AccessibilityController::ShouldLogAccessibilityEvents() { 160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return log_accessibility_events_; 161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void AccessibilityController::NotificationReceived( 164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const blink::WebAXObject& target, const std::string& notification_name) { 165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) v8::Isolate* isolate = blink::mainThreadIsolate(); 166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) v8::HandleScope handle_scope(isolate); 167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) blink::WebFrame* frame = web_view_->mainFrame(); 169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!frame) 170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) v8::Handle<v8::Context> context = frame->mainWorldScriptContext(); 173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (context.IsEmpty()) 174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) v8::Context::Scope context_scope(context); 177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Call notification listeners on the element. 179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) v8::Handle<v8::Object> element_handle = elements_.GetOrCreate(target); 180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (element_handle.IsEmpty()) 181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 183a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) WebAXObjectProxy* element; 184a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool result = gin::ConvertFromV8(isolate, element_handle, &element); 185a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(result); 186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) element->NotificationReceived(frame, notification_name); 187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 188a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (notification_callback_.IsEmpty()) 189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 190a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Call global notification listeners. 192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) v8::Handle<v8::Value> argv[] = { 193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) element_handle, 194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) v8::String::NewFromUtf8(isolate, notification_name.data(), 195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) v8::String::kNormalString, 196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) notification_name.size()), 197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) }; 198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) frame->callFunctionEvenIfScriptDisabled( 199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) v8::Local<v8::Function>::New(isolate, notification_callback_), 200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) context->Global(), 201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) arraysize(argv), 202a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) argv); 203a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 204a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 205010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void AccessibilityController::SetDelegate(WebTestDelegate* delegate) { 206a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) delegate_ = delegate; 207a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 208a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 209a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void AccessibilityController::SetWebView(blink::WebView* web_view) { 210a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) web_view_ = web_view; 211a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 212a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 213a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void AccessibilityController::LogAccessibilityEvents() { 214a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) log_accessibility_events_ = true; 215a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 216a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 217a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void AccessibilityController::SetNotificationListener( 218a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) v8::Handle<v8::Function> callback) { 219a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) v8::Isolate* isolate = blink::mainThreadIsolate(); 220a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) notification_callback_.Reset(isolate, callback); 221a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 222a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 223a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void AccessibilityController::UnsetNotificationListener() { 224a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) notification_callback_.Reset(); 225a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 226a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 227a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)v8::Handle<v8::Object> AccessibilityController::FocusedElement() { 228a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (focused_element_.isNull()) 229a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) focused_element_ = web_view_->accessibilityObject(); 230a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return elements_.GetOrCreate(focused_element_); 231a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 232a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 233a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)v8::Handle<v8::Object> AccessibilityController::RootElement() { 234a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (root_element_.isNull()) 235a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) root_element_ = web_view_->accessibilityObject(); 236a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return elements_.CreateRoot(root_element_); 237a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 238a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 239a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)v8::Handle<v8::Object> 240a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)AccessibilityController::AccessibleElementById(const std::string& id) { 241a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (root_element_.isNull()) 242a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) root_element_ = web_view_->accessibilityObject(); 243a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 244a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!root_element_.updateBackingStoreAndCheckValidity()) 245a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return v8::Handle<v8::Object>(); 246a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 247a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return FindAccessibleElementByIdRecursive( 248a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) root_element_, blink::WebString::fromUTF8(id.c_str())); 249a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 250a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)v8::Handle<v8::Object> 252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)AccessibilityController::FindAccessibleElementByIdRecursive( 253a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const blink::WebAXObject& obj, const blink::WebString& id) { 254a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (obj.isNull() || obj.isDetached()) 255a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return v8::Handle<v8::Object>(); 256a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 257a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) blink::WebNode node = obj.node(); 258a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!node.isNull() && node.isElementNode()) { 259a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) blink::WebElement element = node.to<blink::WebElement>(); 260a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) element.getAttribute("id"); 261a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (element.getAttribute("id") == id) 262a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return elements_.GetOrCreate(obj); 263a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 264a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 265a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) unsigned childCount = obj.childCount(); 266a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (unsigned i = 0; i < childCount; i++) { 267a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) v8::Handle<v8::Object> result = 268a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) FindAccessibleElementByIdRecursive(obj.childAt(i), id); 269a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (*result) 270a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return result; 271a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 272a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 273a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return v8::Handle<v8::Object>(); 274a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 275a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 276a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace content 277