Chromium Code Reviews| Index: components/autofill/content/renderer/autofill_agent.cc |
| diff --git a/components/autofill/content/renderer/autofill_agent.cc b/components/autofill/content/renderer/autofill_agent.cc |
| index 0e28b78c10db35135223f6169657d13d83112efd..99eec7913be6ab46028fff7bdfb18dd6fe63f7d2 100644 |
| --- a/components/autofill/content/renderer/autofill_agent.cc |
| +++ b/components/autofill/content/renderer/autofill_agent.cc |
| @@ -27,6 +27,7 @@ |
| #include "content/public/common/content_switches.h" |
| #include "content/public/common/ssl_status.h" |
| #include "content/public/common/url_constants.h" |
| +#include "content/public/renderer/render_frame.h" |
| #include "content/public/renderer/render_view.h" |
| #include "net/cert/cert_status_flags.h" |
| #include "third_party/WebKit/public/platform/WebRect.h" |
| @@ -119,27 +120,23 @@ void TrimStringVectorForIPC(std::vector<base::string16>* strings) { |
| } // namespace |
| -AutofillAgent::AutofillAgent(content::RenderView* render_view, |
| +AutofillAgent::AutofillAgent(content::RenderFrame* render_frame, |
| PasswordAutofillAgent* password_autofill_agent, |
| PasswordGenerationAgent* password_generation_agent) |
| - : content::RenderViewObserver(render_view), |
| + : content::RenderFrameObserver(render_frame), |
| password_autofill_agent_(password_autofill_agent), |
| password_generation_agent_(password_generation_agent), |
| + legacy_(render_frame->GetRenderView(), this), |
| + page_click_tracker_(render_frame->GetRenderView(), this), |
| autofill_query_id_(0), |
| - web_view_(render_view->GetWebView()), |
| display_warning_if_disabled_(false), |
| was_query_node_autofilled_(false), |
| has_shown_autofill_popup_for_current_edit_(false), |
| did_set_node_text_(false), |
| ignore_text_changes_(false), |
| is_popup_possibly_visible_(false), |
| - main_frame_processed_(false), |
| weak_ptr_factory_(this) { |
| - render_view->GetWebView()->setAutofillClient(this); |
| - |
| - // The PageClickTracker is a RenderViewObserver, and hence will be freed when |
| - // the RenderView is destroyed. |
| - new PageClickTracker(render_view, this); |
| + render_frame->GetWebFrame()->setAutofillClient(this); |
| } |
| AutofillAgent::~AutofillAgent() {} |
| @@ -147,6 +144,8 @@ AutofillAgent::~AutofillAgent() {} |
| bool AutofillAgent::OnMessageReceived(const IPC::Message& message) { |
| bool handled = true; |
| IPC_BEGIN_MESSAGE_MAP(AutofillAgent, message) |
| + IPC_MESSAGE_HANDLER(AutofillMsg_FirstUserGestureObservedInTab, |
| + OnFirstUserGestureObservedInTab) |
| IPC_MESSAGE_HANDLER(AutofillMsg_Ping, OnPing) |
| IPC_MESSAGE_HANDLER(AutofillMsg_FillForm, OnFillForm) |
| IPC_MESSAGE_HANDLER(AutofillMsg_PreviewForm, OnPreviewForm) |
| @@ -170,38 +169,34 @@ bool AutofillAgent::OnMessageReceived(const IPC::Message& message) { |
| return handled; |
| } |
| -void AutofillAgent::DidFinishDocumentLoad(WebLocalFrame* frame) { |
| - // If the main frame just finished loading, we should process it. |
| - if (!frame->parent()) |
| - main_frame_processed_ = false; |
| - |
| - ProcessForms(*frame); |
| +void AutofillAgent::DidCommitProvisionalLoad(bool is_new_navigation) { |
| + // TODO(estade): |form_cache_| shouldn't track multiple frames. |
| + form_cache_.ResetFrame(*render_frame()->GetWebFrame()); |
| } |
| -void AutofillAgent::DidCommitProvisionalLoad(WebLocalFrame* frame, |
| - bool is_new_navigation) { |
| - form_cache_.ResetFrame(*frame); |
| +void AutofillAgent::DidFinishDocumentLoad() { |
| + ProcessForms(); |
| } |
| -void AutofillAgent::FrameDetached(WebFrame* frame) { |
| - form_cache_.ResetFrame(*frame); |
| +void AutofillAgent::FrameWillClose() { |
| + if (in_flight_request_form_.isNull()) |
| + return; |
| + |
| + Send(new AutofillHostMsg_CancelRequestAutocomplete(routing_id())); |
| } |
| -void AutofillAgent::FrameWillClose(WebFrame* frame) { |
| - if (in_flight_request_form_.isNull()) |
| +void AutofillAgent::FrameDetached(WebFrame* frame) { |
| + if (frame != render_frame()->GetWebFrame()) |
| return; |
| - for (WebFrame* temp = in_flight_request_form_.document().frame(); |
| - temp; temp = temp->parent()) { |
| - if (temp == frame) { |
| - Send(new AutofillHostMsg_CancelRequestAutocomplete(routing_id())); |
| - break; |
| - } |
| - } |
| + form_cache_.ResetFrame(*frame); |
| } |
| void AutofillAgent::WillSubmitForm(WebLocalFrame* frame, |
| const WebFormElement& form) { |
| + if (frame != render_frame()->GetWebFrame()) |
| + return; |
| + |
| FormData form_data; |
| if (WebFormElementToFormData(form, |
| WebFormControlElement(), |
| @@ -215,22 +210,32 @@ void AutofillAgent::WillSubmitForm(WebLocalFrame* frame, |
| } |
| } |
| +void AutofillAgent::DidChangeScrollOffset(WebLocalFrame* frame) { |
| + if (frame != render_frame()->GetWebFrame()) |
| + return; |
| + |
| + HidePopup(); |
| +} |
| + |
| void AutofillAgent::FocusedNodeChanged(const WebNode& node) { |
| HidePopup(); |
| + if (node.isNull() || !node.isElementNode()) |
| + return; |
| + |
| + if (node.document().frame() != render_frame()->GetWebFrame()) |
| + return; |
| + |
| if (password_generation_agent_ && |
| password_generation_agent_->FocusedNodeHasChanged(node)) { |
| is_popup_possibly_visible_ = true; |
| return; |
| } |
| - if (node.isNull() || !node.isElementNode()) |
| - return; |
| - |
| WebElement web_element = node.toConst<WebElement>(); |
| if (!web_element.document().frame()) |
| - return; |
| + return; |
| const WebInputElement* element = toWebInputElement(&web_element); |
| @@ -249,19 +254,18 @@ void AutofillAgent::Resized() { |
| HidePopup(); |
| } |
| -void AutofillAgent::DidChangeScrollOffset(WebLocalFrame*) { |
| - HidePopup(); |
| -} |
| - |
| void AutofillAgent::didRequestAutocomplete( |
| const WebFormElement& form) { |
| + DCHECK_EQ(form.document().frame(), render_frame()->GetWebFrame()); |
| + |
| // Disallow the dialog over non-https or broken https, except when the |
| // ignore SSL flag is passed. See http://crbug.com/272512. |
| // TODO(palmer): this should be moved to the browser process after frames |
| // get their own processes. |
| GURL url(form.document().url()); |
| content::SSLStatus ssl_status = |
| - render_view()->GetSSLStatusOfFrame(form.document().frame()); |
| + render_frame()->GetRenderView()->GetSSLStatusOfFrame( |
| + form.document().frame()); |
| bool is_safe = url.SchemeIs(url::kHttpsScheme) && |
| !net::IsCertStatusError(ssl_status.cert_status); |
| bool allow_unsafe = CommandLine::ForCurrentProcess()->HasSwitch( |
| @@ -312,6 +316,10 @@ void AutofillAgent::setIgnoreTextChanges(bool ignore) { |
| void AutofillAgent::FormControlElementClicked( |
| const WebFormControlElement& element, |
| bool was_focused) { |
| + // TODO(estade): Remove this check when PageClickTracker is per-frame. |
| + if (element.document().frame() != render_frame()->GetWebFrame()) |
| + return; |
| + |
| const WebInputElement* input_element = toWebInputElement(&element); |
| if (!input_element && !IsTextAreaElement(element)) |
| return; |
| @@ -415,7 +423,7 @@ void AutofillAgent::openTextDataListChooser(const WebInputElement& element) { |
| } |
| void AutofillAgent::firstUserGestureObserved() { |
| - password_autofill_agent_->FirstUserGestureObserved(); |
| + Send(new AutofillHostMsg_FirstUserGestureObserved(routing_id())); |
|
Evan Stade
2014/11/17 20:34:39
Had to make some changes when updating blink code.
vabr (Chromium)
2014/11/18 09:49:17
Thanks for spotting this! I completely missed it,
|
| } |
| void AutofillAgent::AcceptDataListSuggestion( |
| @@ -456,7 +464,7 @@ void AutofillAgent::OnFieldTypePredictionsAvailable( |
| } |
| void AutofillAgent::OnFillForm(int query_id, const FormData& form) { |
| - if (!render_view()->GetWebView() || query_id != autofill_query_id_) |
| + if (query_id != autofill_query_id_) |
| return; |
| was_query_node_autofilled_ = element_.isAutofilled(); |
| @@ -465,12 +473,16 @@ void AutofillAgent::OnFillForm(int query_id, const FormData& form) { |
| base::TimeTicks::Now())); |
| } |
| +void AutofillAgent::OnFirstUserGestureObservedInTab() { |
| + password_autofill_agent_->FirstUserGestureObserved(); |
| +} |
| + |
| void AutofillAgent::OnPing() { |
| Send(new AutofillHostMsg_PingAck(routing_id())); |
| } |
| void AutofillAgent::OnPreviewForm(int query_id, const FormData& form) { |
| - if (!render_view()->GetWebView() || query_id != autofill_query_id_) |
| + if (query_id != autofill_query_id_) |
| return; |
| was_query_node_autofilled_ = element_.isAutofilled(); |
| @@ -661,8 +673,9 @@ void AutofillAgent::QueryAutofillSuggestions( |
| if (datalist_only) |
| field.should_autocomplete = false; |
| - gfx::RectF bounding_box_scaled = |
| - GetScaledBoundingBox(web_view_->pageScaleFactor(), &element_); |
| + gfx::RectF bounding_box_scaled = GetScaledBoundingBox( |
| + render_frame()->GetRenderView()->GetWebView()->pageScaleFactor(), |
| + &element_); |
| std::vector<base::string16> data_list_values; |
| std::vector<base::string16> data_list_labels; |
| @@ -705,22 +718,19 @@ void AutofillAgent::PreviewFieldWithValue(const base::string16& value, |
| node->suggestedValue().length()); |
| } |
| -void AutofillAgent::ProcessForms(const WebLocalFrame& frame) { |
| +void AutofillAgent::ProcessForms() { |
| // Record timestamp of when the forms are first seen. This is used to |
| // measure the overhead of the Autofill feature. |
| base::TimeTicks forms_seen_timestamp = base::TimeTicks::Now(); |
| - std::vector<FormData> forms = form_cache_.ExtractNewForms(frame); |
| + WebLocalFrame* frame = render_frame()->GetWebFrame(); |
| + std::vector<FormData> forms = form_cache_.ExtractNewForms(*frame); |
| // Always communicate to browser process for topmost frame. |
| - if (!forms.empty() || |
| - (!frame.parent() && !main_frame_processed_)) { |
| + if (!forms.empty() || !frame->parent()) { |
| Send(new AutofillHostMsg_FormsSeen(routing_id(), forms, |
| forms_seen_timestamp)); |
| } |
| - |
| - if (!frame.parent()) |
| - main_frame_processed_ = true; |
| } |
| void AutofillAgent::HidePopup() { |
| @@ -737,18 +747,62 @@ void AutofillAgent::HidePopup() { |
| void AutofillAgent::didAssociateFormControls(const WebVector<WebNode>& nodes) { |
| for (size_t i = 0; i < nodes.size(); ++i) { |
| WebLocalFrame* frame = nodes[i].document().frame(); |
| + DCHECK_EQ(frame, render_frame()->GetWebFrame()); |
| // Only monitors dynamic forms created in the top frame. Dynamic forms |
| // inserted in iframes are not captured yet. Frame is only processed |
| // if it has finished loading, otherwise you can end up with a partially |
| // parsed form. |
| - if (frame && !frame->parent() && !frame->isLoading()) { |
| - ProcessForms(*frame); |
| - password_autofill_agent_->OnDynamicFormsSeen(frame); |
| + if (!frame->isLoading()) { |
| + ProcessForms(); |
| + password_autofill_agent_->OnDynamicFormsSeen(); |
| if (password_generation_agent_) |
| - password_generation_agent_->OnDynamicFormsSeen(frame); |
| + password_generation_agent_->OnDynamicFormsSeen(); |
| return; |
| } |
| } |
| } |
| +// LegacyAutofillAgent --------------------------------------------------------- |
| + |
| +AutofillAgent::LegacyAutofillAgent::LegacyAutofillAgent( |
| + content::RenderView* render_view, |
| + AutofillAgent* agent) |
| + : content::RenderViewObserver(render_view), agent_(agent) { |
| +} |
| + |
| +AutofillAgent::LegacyAutofillAgent::~LegacyAutofillAgent() { |
| +} |
| + |
| +void AutofillAgent::LegacyAutofillAgent::OnDestruct() { |
| + // No-op. Don't delete |this|. |
| +} |
| + |
| +void AutofillAgent::LegacyAutofillAgent::FrameDetached(WebFrame* frame) { |
| + agent_->FrameDetached(frame); |
| +} |
| + |
| +void AutofillAgent::LegacyAutofillAgent::WillSubmitForm( |
| + WebLocalFrame* frame, |
| + const WebFormElement& form) { |
| + agent_->WillSubmitForm(frame, form); |
| +} |
| + |
| +void AutofillAgent::LegacyAutofillAgent::DidChangeScrollOffset( |
| + WebLocalFrame* frame) { |
| + agent_->DidChangeScrollOffset(frame); |
| +} |
| + |
| +void AutofillAgent::LegacyAutofillAgent::FocusedNodeChanged( |
| + const WebNode& node) { |
| + agent_->FocusedNodeChanged(node); |
| +} |
| + |
| +void AutofillAgent::LegacyAutofillAgent::OrientationChangeEvent() { |
| + agent_->OrientationChangeEvent(); |
| +} |
| + |
| +void AutofillAgent::LegacyAutofillAgent::Resized() { |
| + agent_->Resized(); |
| +} |
| + |
| } // namespace autofill |