Bug 1863801 - P2. Add DOMFormRemoved event listener after successful fetch or XHR request r=dimi

Differential Revision: https://phabricator.services.mozilla.com/D193308
This commit is contained in:
jneuberger 2023-12-06 14:55:01 +00:00
parent 26990b0cc3
commit 9fe5ac2c97
5 changed files with 59 additions and 12 deletions

View File

@ -3781,7 +3781,8 @@ class Document : public nsINode,
void SetNotifyFetchSuccess(bool aShouldNotify);
// When this is set, removing a form or a password field from DOM
// sends a Chrome-only event. This is now only used by the password manager.
// sends a Chrome-only event. This is now only used by the password manager
// and formautofill.
void SetNotifyFormOrPasswordRemoved(bool aShouldNotify);
// This function is used by HTMLFormElement and HTMLInputElement to determin

View File

@ -2072,9 +2072,9 @@ void HTMLFormElement::MaybeFireFormRemoved() {
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.
// Right now, only the password manager and formautofill listen to the event
// and only listen to it under certain circumstances. So don't fire this event
// unless necessary.
if (!doc->ShouldNotifyFormOrPasswordRemoved()) {
return;
}

View File

@ -593,7 +593,7 @@ class HTMLFormElement final : public nsGenericHTMLElement,
/**
* Fire an event when the form is removed from the DOM tree. This is now only
* used by the password manager.
* used by the password manager and formautofill.
*/
void MaybeFireFormRemoved();

View File

@ -1636,7 +1636,7 @@ class HTMLInputElement final : public TextControlElement,
/**
* Fire an event when the password input field is removed from the DOM tree.
* This is now only used by the password manager.
* This is now only used by the password manager and formautofill.
*/
void MaybeFireInputPasswordRemoved();

View File

@ -122,6 +122,23 @@ export class FormAutofillChild extends JSWindowActorChild {
);
}
/**
* After a DOMDocFetchSuccess event, we register an event listener for the DOMFormRemoved event
*
* @param {Document} document The document we want to be notified by of a DOMFormRemoved event
*/
registerDOMFormRemovedEventListener(document) {
document.setNotifyFormOrPasswordRemoved(true);
// Is removed after a DOMFormRemoved event (bug 1864855)
/* eslint-disable mozilla/balanced-listeners */
this.docShell.chromeEventHandler.addEventListener(
"DOMFormRemoved",
this,
true
);
}
/**
* After a DOMDocFetchSuccess event we remove the DOMDocFetchSuccess event listener
*
@ -135,6 +152,19 @@ export class FormAutofillChild extends JSWindowActorChild {
);
}
/**
* After a DOMFormRemoved event we remove the DOMFormRemoved event listener
*
* @param {Document} document The document we are notified by of a DOMFormRemoved event
*/
unregisterDOMFormRemovedEventListener(document) {
document.setNotifyFormOrPasswordRemoved(false);
this.docShell.chromeEventHandler.removeEventListener(
"DOMFormRemoved",
this
);
}
shouldIgnoreFormAutofillEvent(event) {
let nodePrincipal = event.target.nodePrincipal;
return (
@ -148,7 +178,6 @@ export class FormAutofillChild extends JSWindowActorChild {
if (!evt.isTrusted) {
return;
}
if (this.shouldIgnoreFormAutofillEvent(evt)) {
return;
}
@ -166,6 +195,10 @@ export class FormAutofillChild extends JSWindowActorChild {
}
break;
}
case "DOMFormRemoved": {
this.onDOMFormRemoved(evt);
break;
}
case "DOMDocFetchSuccess": {
this.onDOMDocFetchSuccess(evt);
break;
@ -213,13 +246,25 @@ export class FormAutofillChild extends JSWindowActorChild {
onDOMFormBeforeSubmit(evt) {
let formElement = evt.target;
if (!lazy.FormAutofill.isAutofillEnabled) {
return;
}
lazy.FormAutofillContent.formSubmitted(formElement);
}
/**
* Handle the DOMFormRemoved event.
*
* Infers a form submission when the form is removed
* after a successful fetch or XHR request.
*
* @param {Event} evt DOMFormRemoved
*/
onDOMFormRemoved(evt) {
const document = evt.composedTarget.ownerDocument;
// TODO: Infer a form submission (will be implemented P3)
this.unregisterDOMFormRemovedEventListener(document);
}
/**
* Handle the DOMDocFetchSuccess event.
*
@ -230,7 +275,8 @@ export class FormAutofillChild extends JSWindowActorChild {
*/
onDOMDocFetchSuccess(evt) {
const document = evt.target;
// TODO: Register mutation observer to watch for form removal (implemented in P2)
this.registerDOMFormRemovedEventListener(document);
this.unregisterDOMDocFetchSuccessEventListener(document);
}