Don't show supervised user as "already on this device" while they're being imported.
[chromium-blink-merge.git] / components / autofill / content / renderer / page_click_tracker.cc
blob8f1b0c211070051829239e9b6f4ad015d0b68ad7
1 // Copyright 2013 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 "components/autofill/content/renderer/page_click_tracker.h"
7 #include "base/command_line.h"
8 #include "components/autofill/content/renderer/form_autofill_util.h"
9 #include "components/autofill/content/renderer/page_click_listener.h"
10 #include "components/autofill/core/common/autofill_switches.h"
11 #include "content/public/renderer/render_frame.h"
12 #include "content/public/renderer/render_view.h"
13 #include "third_party/WebKit/public/platform/WebPoint.h"
14 #include "third_party/WebKit/public/platform/WebSize.h"
15 #include "third_party/WebKit/public/web/WebDocument.h"
16 #include "third_party/WebKit/public/web/WebHitTestResult.h"
17 #include "third_party/WebKit/public/web/WebInputElement.h"
18 #include "third_party/WebKit/public/web/WebInputEvent.h"
19 #include "third_party/WebKit/public/web/WebLocalFrame.h"
20 #include "third_party/WebKit/public/web/WebTextAreaElement.h"
21 #include "third_party/WebKit/public/web/WebView.h"
23 using blink::WebElement;
24 using blink::WebGestureEvent;
25 using blink::WebInputElement;
26 using blink::WebInputEvent;
27 using blink::WebMouseEvent;
28 using blink::WebNode;
29 using blink::WebPoint;
30 using blink::WebSize;
31 using blink::WebTextAreaElement;
33 namespace {
35 // Casts |node| to a WebInputElement.
36 // Returns an empty (isNull()) WebInputElement if |node| is not a text field.
37 const WebInputElement GetTextWebInputElement(const WebNode& node) {
38 if (!node.isElementNode())
39 return WebInputElement();
40 const WebElement element = node.toConst<WebElement>();
41 if (!element.hasHTMLTagName("input"))
42 return WebInputElement();
43 const WebInputElement* input = blink::toWebInputElement(&element);
44 if (!autofill::IsTextInput(input))
45 return WebInputElement();
46 return *input;
49 // Casts |node| to a WebTextAreaElement.
50 // Returns an empty (isNull()) WebTextAreaElement if |node| is not a
51 // textarea field.
52 const WebTextAreaElement GetWebTextAreaElement(const WebNode& node) {
53 if (!node.isElementNode())
54 return WebTextAreaElement();
55 const WebElement element = node.toConst<WebElement>();
56 if (!element.hasHTMLTagName("textarea"))
57 return WebTextAreaElement();
58 return element.toConst<WebTextAreaElement>();
61 } // namespace
63 namespace autofill {
65 PageClickTracker::PageClickTracker(content::RenderFrame* render_frame,
66 PageClickListener* listener)
67 : content::RenderFrameObserver(render_frame),
68 focused_node_was_last_clicked_(false),
69 was_focused_before_now_(false),
70 listener_(listener),
71 legacy_(this) {
74 PageClickTracker::~PageClickTracker() {
77 void PageClickTracker::DidHandleMouseEvent(const WebMouseEvent& event) {
78 if (event.type != WebInputEvent::MouseDown ||
79 event.button != WebMouseEvent::ButtonLeft) {
80 return;
83 WebNode clicked_node = render_frame()->GetRenderView()->GetWebView()
84 ->hitTestResultAt(WebPoint(event.x, event.y)).node();
85 focused_node_was_last_clicked_ = !clicked_node.isNull() &&
86 clicked_node.focused();
89 void PageClickTracker::DidHandleGestureEvent(const WebGestureEvent& event) {
90 if (event.type != WebGestureEvent::GestureTap)
91 return;
93 WebNode tapped_node = render_frame()->GetRenderView()->GetWebView()
94 ->hitTestResultForTap(
95 WebPoint(event.x, event.y),
96 WebSize(event.data.tap.width, event.data.tap.height)).node();
97 focused_node_was_last_clicked_ = !tapped_node.isNull() &&
98 tapped_node.focused();
101 void PageClickTracker::FocusedNodeChanged(const WebNode& node) {
102 was_focused_before_now_ = false;
104 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
105 switches::kEnableAccessorySuggestionView)) {
106 focused_node_was_last_clicked_ = true;
107 DoFocusChangeComplete();
111 void PageClickTracker::FocusChangeComplete() {
112 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
113 switches::kEnableAccessorySuggestionView)) {
114 return;
117 DoFocusChangeComplete();
120 void PageClickTracker::DoFocusChangeComplete() {
121 WebNode focused_node = render_frame()->GetFocusedElement();
122 if (focused_node_was_last_clicked_ && !focused_node.isNull()) {
123 const WebInputElement input_element = GetTextWebInputElement(focused_node);
124 if (!input_element.isNull()) {
125 listener_->FormControlElementClicked(input_element,
126 was_focused_before_now_);
127 } else {
128 const WebTextAreaElement textarea_element =
129 GetWebTextAreaElement(focused_node);
130 if (!textarea_element.isNull()) {
131 listener_->FormControlElementClicked(textarea_element,
132 was_focused_before_now_);
137 was_focused_before_now_ = true;
138 focused_node_was_last_clicked_ = false;
141 // PageClickTracker::Legacy ----------------------------------------------------
143 PageClickTracker::Legacy::Legacy(PageClickTracker* tracker)
144 : content::RenderViewObserver(tracker->render_frame()->GetRenderView()),
145 tracker_(tracker) {
148 void PageClickTracker::Legacy::OnDestruct() {
149 // No-op. Don't delete |this|.
152 void PageClickTracker::Legacy::DidHandleMouseEvent(const WebMouseEvent& event) {
153 tracker_->DidHandleMouseEvent(event);
156 void PageClickTracker::Legacy::DidHandleGestureEvent(
157 const WebGestureEvent& event) {
158 tracker_->DidHandleGestureEvent(event);
161 void PageClickTracker::Legacy::FocusChangeComplete() {
162 tracker_->FocusChangeComplete();
165 } // namespace autofill