Bug 1166995 - P2. Call onFormSubmit when a form or a password field is removed from the DOM tree r=sfoster,tgiles,smaug

This patch adds two events - `DOMFormRemoved` and `DOMInputPasswordRemoved`.
These events are notified when a form/password field is removed from
the DOM tree. When the LoginManagerChild receives the event, it calls
_onFormSubmit as the form is submitted.

This patch also adds a WeakFieldSet formlessModifiedPasswordFields to
record all the form-less password fields that users have interacted
with to track whether a formless password is removed

Depends on D106024

Differential Revision: https://phabricator.services.mozilla.com/D106025
This commit is contained in:
Dimi Lee
2021-03-16 09:15:19 +00:00
parent a4b2ea0e4a
commit d8a6e9ef56
8 changed files with 225 additions and 9 deletions

View File

@@ -4240,6 +4240,10 @@ nsresult HTMLInputElement::BindToTree(BindContext& aContext, nsINode& aParent) {
}
void HTMLInputElement::UnbindFromTree(bool aNullParent) {
if (mType == NS_FORM_INPUT_PASSWORD) {
MaybeFireInputPasswordRemoved();
}
// If we have a form and are unbound from it,
// nsGenericHTMLFormElementWithState::UnbindFromTree() will unset the form and
// that takes care of form's WillRemove so we just have to take care
@@ -7034,6 +7038,29 @@ already_AddRefed<nsINodeList> HTMLInputElement::GetLabels() {
return nsGenericHTMLElement::Labels();
}
void HTMLInputElement::MaybeFireInputPasswordRemoved() {
// We want this event to be fired only when the password field is removed
// from the DOM tree, not when it is released (ex, tab is closed). So don't
// fire an event when the password input field doesn't have a docshell.
Document* doc = GetComposedDoc();
nsIDocShell* container = doc ? doc->GetDocShell() : nullptr;
if (!container) {
return;
}
// Right now, only the password manager listens to the event and only listen
// to it under certain circumstances. So don't fire this event unless
// necessary.
if (!doc->ShouldNotifyFormOrPasswordRemoved()) {
return;
}
RefPtr<AsyncEventDispatcher> asyncDispatcher =
new AsyncEventDispatcher(this, u"DOMInputPasswordRemoved"_ns,
CanBubble::eNo, ChromeOnlyDispatch::eYes);
asyncDispatcher->RunDOMEventWhenSafe();
}
} // namespace mozilla::dom
#undef NS_ORIGINAL_CHECKED_VALUE