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
) {
28 IPC_BEGIN_MESSAGE_MAP(AutomationApiHelper
, message
)
29 IPC_MESSAGE_HANDLER(ExtensionMsg_AutomationQuerySelector
, OnQuerySelector
)
30 IPC_MESSAGE_UNHANDLED(handled
= false)
35 void AutomationApiHelper::OnQuerySelector(int request_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));
46 blink::WebDocument document
=
47 render_view()->GetWebView()->mainFrame()->document();
48 if (document
.isNull()) {
50 ExtensionHostMsg_AutomationQuerySelector_Error::kNoDocument
;
51 Send(new ExtensionHostMsg_AutomationQuerySelector_Result(
52 routing_id(), request_id
, error
, 0));
55 blink::WebNode start_node
= document
;
57 blink::WebAXObject start_acc_obj
=
58 document
.accessibilityObjectFromID(acc_obj_id
);
59 if (start_acc_obj
.isNull()) {
61 ExtensionHostMsg_AutomationQuerySelector_Error::kNodeDestroyed
;
62 Send(new ExtensionHostMsg_AutomationQuerySelector_Result(
63 routing_id(), request_id
, error
, 0));
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