| 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 1b4daba736456c7f7e02d0cd7a6f5b32c068a1da..8a9350e9304bc369045479377850335096a0421e 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"
|
| @@ -128,27 +129,23 @@ AutofillAgent::ShowSuggestionsOptions::ShowSuggestionsOptions()
|
| show_password_suggestions_only(false) {
|
| }
|
|
|
| -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() {}
|
| @@ -156,6 +153,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)
|
| @@ -179,38 +178,27 @@ 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(WebFrame* frame) {
|
| - if (in_flight_request_form_.isNull())
|
| + 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(),
|
| @@ -224,22 +212,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);
|
|
|
| @@ -258,19 +256,31 @@ void AutofillAgent::Resized() {
|
| HidePopup();
|
| }
|
|
|
| -void AutofillAgent::DidChangeScrollOffset(WebLocalFrame*) {
|
| - HidePopup();
|
| +void AutofillAgent::LegacyFrameWillClose(blink::WebFrame* frame) {
|
| + if (in_flight_request_form_.isNull())
|
| + return;
|
| +
|
| + for (blink::WebFrame* temp = render_frame()->GetWebFrame(); temp;
|
| + temp = temp->parent()) {
|
| + if (temp == frame) {
|
| + Send(new AutofillHostMsg_CancelRequestAutocomplete(routing_id()));
|
| + break;
|
| + }
|
| + }
|
| }
|
|
|
| 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 = base::CommandLine::ForCurrentProcess()->HasSwitch(
|
| @@ -321,6 +331,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;
|
| @@ -437,6 +451,7 @@ void AutofillAgent::openTextDataListChooser(const WebInputElement& element) {
|
|
|
| void AutofillAgent::firstUserGestureObserved() {
|
| password_autofill_agent_->FirstUserGestureObserved();
|
| + Send(new AutofillHostMsg_FirstUserGestureObserved(routing_id()));
|
| }
|
|
|
| void AutofillAgent::AcceptDataListSuggestion(
|
| @@ -477,7 +492,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();
|
| @@ -486,12 +501,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();
|
| @@ -678,8 +697,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;
|
| @@ -722,22 +742,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() {
|
| @@ -758,14 +775,62 @@ void AutofillAgent::didAssociateFormControls(const WebVector<WebNode>& nodes) {
|
| // 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 && !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();
|
| +}
|
| +
|
| +void AutofillAgent::LegacyAutofillAgent::FrameWillClose(
|
| + blink::WebFrame* frame) {
|
| + agent_->LegacyFrameWillClose(frame);
|
| +}
|
| +
|
| } // namespace autofill
|
|
|