Index: components/autofill/content/renderer/password_autofill_agent.cc |
diff --git a/components/autofill/content/renderer/password_autofill_agent.cc b/components/autofill/content/renderer/password_autofill_agent.cc |
index 062823790691580d1b96b309733e65eb693cc7be..a202c8b3b75ea675d03632f579a5db850f1571e3 100644 |
--- a/components/autofill/content/renderer/password_autofill_agent.cc |
+++ b/components/autofill/content/renderer/password_autofill_agent.cc |
@@ -44,6 +44,7 @@ |
#include "third_party/WebKit/public/web/WebDocument.h" |
#include "third_party/WebKit/public/web/WebElement.h" |
#include "third_party/WebKit/public/web/WebFormElement.h" |
+#include "third_party/WebKit/public/web/WebFormElementObserverCallback.h" |
#include "third_party/WebKit/public/web/WebLocalFrame.h" |
#include "third_party/WebKit/public/web/WebNode.h" |
#include "third_party/WebKit/public/web/WebUserGestureIndicator.h" |
@@ -618,6 +619,35 @@ bool HasPasswordField(const blink::WebLocalFrame& frame) { |
} // namespace |
+class PasswordAutofillAgent::FormElementObserver |
+ : public blink::WebFormElementObserverCallback { |
+ public: |
+ explicit FormElementObserver(PasswordAutofillAgent* agent) : agent_(agent) {} |
+ ~FormElementObserver() override { Detach(); } |
+ |
+ void Detach() { |
+ if (agent_) { |
+ DCHECK_EQ(agent_->form_element_observer_, this); |
+ agent_->form_element_observer_ = nullptr; |
+ } |
+ agent_ = nullptr; |
+ } |
+ |
+ bool ShouldStopObserving() override { |
+ if (!agent_) |
+ return true; |
+ agent_->OnSameDocumentNavigationCompleted(); |
+ // The above call will invoke Detach() if the form no longer needs to be |
+ // observed. |
+ return agent_ == nullptr; |
+ } |
+ |
+ private: |
+ PasswordAutofillAgent* agent_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(FormElementObserver); |
+}; |
+ |
//////////////////////////////////////////////////////////////////////////////// |
// PasswordAutofillAgent, public: |
@@ -628,13 +658,16 @@ PasswordAutofillAgent::PasswordAutofillAgent(content::RenderFrame* render_frame) |
was_password_autofilled_(false), |
sent_request_to_store_(false), |
checked_safe_browsing_reputation_(false), |
- binding_(this) { |
+ binding_(this), |
+ form_element_observer_(nullptr) { |
// PasswordAutofillAgent is guaranteed to outlive |render_frame|. |
render_frame->GetInterfaceRegistry()->AddInterface( |
base::Bind(&PasswordAutofillAgent::BindRequest, base::Unretained(this))); |
} |
PasswordAutofillAgent::~PasswordAutofillAgent() { |
+ if (form_element_observer_) |
+ form_element_observer_->Detach(); |
} |
void PasswordAutofillAgent::BindRequest( |
@@ -1051,10 +1084,28 @@ void PasswordAutofillAgent::OnSameDocumentNavigationCompleted() { |
frame, provisionally_saved_form_.input_element(), |
password_form.action, password_form.origin, password_form.form_data, |
form_predictions_))) { |
+ if (!form_element_observer_) { |
+ std::unique_ptr<FormElementObserver> observer( |
+ new FormElementObserver(this)); |
+ form_element_observer_ = observer.get(); |
+ if (provisionally_saved_form_.form_element().IsNull()) { |
+ provisionally_saved_form_.input_element() |
+ .GetDocument() |
+ .ObserveFormElement(provisionally_saved_form_.input_element(), |
+ std::move(observer)); |
+ } else { |
+ provisionally_saved_form_.form_element() |
+ .GetDocument() |
+ .ObserveFormElement(provisionally_saved_form_.form_element(), |
+ std::move(observer)); |
+ } |
+ } |
return; |
} |
GetPasswordManagerDriver()->InPageNavigation(password_form); |
+ if (form_element_observer_) |
+ form_element_observer_->Detach(); |
provisionally_saved_form_.Reset(); |
} |
@@ -1287,6 +1338,8 @@ void PasswordAutofillAgent::WillSubmitForm(const blink::WebFormElement& form) { |
// RenderView to be instantiated (such as redirects to the WebStore) |
// we will never get to finish the load. |
GetPasswordManagerDriver()->PasswordFormSubmitted(*submitted_form); |
+ if (form_element_observer_) |
+ form_element_observer_->Detach(); |
provisionally_saved_form_.Reset(); |
} else if (logger) { |
logger->LogMessage(Logger::STRING_FORM_IS_NOT_PASSWORD); |
@@ -1334,6 +1387,8 @@ void PasswordAutofillAgent::DidStartProvisionalLoad( |
} |
GetPasswordManagerDriver()->PasswordFormSubmitted( |
provisionally_saved_form_.password_form()); |
+ if (form_element_observer_) |
+ form_element_observer_->Detach(); |
provisionally_saved_form_.Reset(); |
} else { |
std::vector<std::unique_ptr<PasswordForm>> possible_submitted_forms; |
@@ -1615,6 +1670,8 @@ void PasswordAutofillAgent::FrameClosing() { |
password_to_username_.erase(iter.second.password_field); |
} |
web_input_to_password_info_.clear(); |
+ if (form_element_observer_) |
+ form_element_observer_->Detach(); |
provisionally_saved_form_.Reset(); |
field_value_and_properties_map_.clear(); |
sent_request_to_store_ = false; |