Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1474)

Unified Diff: components/autofill/content/renderer/password_autofill_agent.cc

Issue 2865233003: Use an MutationObserver to check when a password form disappears after XHR (Closed)
Patch Set: tests Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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;

Powered by Google App Engine
This is Rietveld 408576698