Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / extensions / renderer / api / automation / automation_api_helper.cc
blobab10682f6db7f3f6529873034c7071300a507fcf
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 "extensions/renderer/api/automation/automation_api_helper.h"
7 #include "content/public/renderer/render_view.h"
8 #include "extensions/common/extension_messages.h"
9 #include "third_party/WebKit/public/web/WebAXObject.h"
10 #include "third_party/WebKit/public/web/WebDocument.h"
11 #include "third_party/WebKit/public/web/WebElement.h"
12 #include "third_party/WebKit/public/web/WebExceptionCode.h"
13 #include "third_party/WebKit/public/web/WebFrame.h"
14 #include "third_party/WebKit/public/web/WebNode.h"
15 #include "third_party/WebKit/public/web/WebView.h"
17 namespace extensions {
19 AutomationApiHelper::AutomationApiHelper(content::RenderView* render_view)
20 : content::RenderViewObserver(render_view) {
23 AutomationApiHelper::~AutomationApiHelper() {
26 bool AutomationApiHelper::OnMessageReceived(const IPC::Message& message) {
27 bool handled = true;
28 IPC_BEGIN_MESSAGE_MAP(AutomationApiHelper, message)
29 IPC_MESSAGE_HANDLER(ExtensionMsg_AutomationQuerySelector, OnQuerySelector)
30 IPC_MESSAGE_UNHANDLED(handled = false)
31 IPC_END_MESSAGE_MAP()
32 return handled;
35 void AutomationApiHelper::OnQuerySelector(int request_id,
36 int acc_obj_id,
37 const base::string16& selector) {
38 ExtensionHostMsg_AutomationQuerySelector_Error error;
39 if (!render_view() || !render_view()->GetWebView() ||
40 !render_view()->GetWebView()->mainFrame()) {
41 error.value = ExtensionHostMsg_AutomationQuerySelector_Error::kNoMainFrame;
42 Send(new ExtensionHostMsg_AutomationQuerySelector_Result(
43 routing_id(), request_id, error, 0));
44 return;
46 blink::WebDocument document =
47 render_view()->GetWebView()->mainFrame()->document();
48 if (document.isNull()) {
49 error.value =
50 ExtensionHostMsg_AutomationQuerySelector_Error::kNoDocument;
51 Send(new ExtensionHostMsg_AutomationQuerySelector_Result(
52 routing_id(), request_id, error, 0));
53 return;
55 blink::WebNode start_node = document;
56 if (acc_obj_id > 0) {
57 blink::WebAXObject start_acc_obj =
58 document.accessibilityObjectFromID(acc_obj_id);
59 if (start_acc_obj.isNull()) {
60 error.value =
61 ExtensionHostMsg_AutomationQuerySelector_Error::kNodeDestroyed;
62 Send(new ExtensionHostMsg_AutomationQuerySelector_Result(
63 routing_id(), request_id, error, 0));
64 return;
67 start_node = start_acc_obj.node();
68 while (start_node.isNull()) {
69 start_acc_obj = start_acc_obj.parentObject();
70 start_node = start_acc_obj.node();
73 blink::WebString web_selector(selector);
74 blink::WebExceptionCode ec = 0;
75 blink::WebElement result_element = start_node.querySelector(web_selector, ec);
76 int result_acc_obj_id = 0;
77 if (!ec && !result_element.isNull()) {
78 blink::WebAXObject result_acc_obj = result_element.accessibilityObject();
79 if (!result_acc_obj.isDetached()) {
80 while (result_acc_obj.accessibilityIsIgnored())
81 result_acc_obj = result_acc_obj.parentObject();
83 result_acc_obj_id = result_acc_obj.axID();
86 Send(new ExtensionHostMsg_AutomationQuerySelector_Result(
87 routing_id(), request_id, error, result_acc_obj_id));
90 } // namespace extensions