Bug 1378754 - Don't clear marked fields in nsFormFillController upon a persisted pagehide. r=smaug

While moving to a new window (using SwapDocShells), a pagehide event[1] is dispatched causing nsFormFillController to clean up mPwmgrInputs and mAutofillInputs for the document. This commit changes the pagehide handler to not clear the hash tables or mutation observers with persisted=true (which would also fix the same bug in password manager autocomplete).

This approach comes at the cost of increased memory (hash table entries for fields in session history) but would reduce CPU usage compared to the alternative of re-marking password manager and autofill fields upon every pageshow event. This approach also solves the issue of autofill and password manager autocomplete not working after session history navigation.

[1] https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XUL/Method/SwapDocShells

MozReview-Commit-ID: 8DFWuFynDex
This commit is contained in:
Matthew Noorenberghe
2017-07-21 13:32:48 -07:00
parent 2d3e8270ae
commit 80e800c67b

View File

@@ -11,6 +11,7 @@
#include "mozilla/dom/Element.h"
#include "mozilla/dom/Event.h" // for nsIDOMEvent::InternalDOMEvent()
#include "mozilla/dom/HTMLInputElement.h"
#include "mozilla/dom/PageTransitionEvent.h"
#include "mozilla/Logging.h"
#include "nsIFormAutoComplete.h"
#include "nsIInputListAutoComplete.h"
@@ -981,7 +982,13 @@ nsFormFillController::HandleEvent(nsIDOMEvent* aEvent)
}
}
RemoveForDocument(doc);
// Only remove the observer notifications and marked autofill and password
// manager fields if the page isn't going to be persisted (i.e. it's being
// unloaded) so that appropriate autocomplete handling works with bfcache.
bool persisted = aEvent->InternalDOMEvent()->AsPageTransitionEvent()->Persisted();
if (!persisted) {
RemoveForDocument(doc);
}
}
break;
default:
@@ -996,6 +1003,7 @@ nsFormFillController::HandleEvent(nsIDOMEvent* aEvent)
void
nsFormFillController::RemoveForDocument(nsIDocument* aDoc)
{
MOZ_LOG(sLogger, LogLevel::Verbose, ("RemoveForDocument: %p", aDoc));
for (auto iter = mPwmgrInputs.Iter(); !iter.Done(); iter.Next()) {
const nsINode* key = iter.Key();
if (key && (!aDoc || key->OwnerDoc() == aDoc)) {