diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /toolkit/components/formautofill/FormAutofillChild.sys.mjs | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | toolkit/components/formautofill/FormAutofillChild.sys.mjs | 195 |
1 files changed, 195 insertions, 0 deletions
diff --git a/toolkit/components/formautofill/FormAutofillChild.sys.mjs b/toolkit/components/formautofill/FormAutofillChild.sys.mjs new file mode 100644 index 0000000000..acefdcdc87 --- /dev/null +++ b/toolkit/components/formautofill/FormAutofillChild.sys.mjs @@ -0,0 +1,195 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +const lazy = {}; + +ChromeUtils.defineESModuleGetters(lazy, { + AutoCompleteChild: "resource://gre/actors/AutoCompleteChild.sys.mjs", + FormAutofill: "resource://autofill/FormAutofill.sys.mjs", + FormAutofillContent: "resource://autofill/FormAutofillContent.sys.mjs", + FormAutofillUtils: "resource://gre/modules/shared/FormAutofillUtils.sys.mjs", + setTimeout: "resource://gre/modules/Timer.sys.mjs", +}); + +/** + * Handles content's interactions for the frame. + */ +export class FormAutofillChild extends JSWindowActorChild { + constructor() { + super(); + + this._nextHandleElement = null; + this._alreadyDOMContentLoaded = false; + this._hasDOMContentLoadedHandler = false; + this._hasPendingTask = false; + this.testListener = null; + + lazy.AutoCompleteChild.addPopupStateListener(this); + } + + didDestroy() { + lazy.AutoCompleteChild.removePopupStateListener(this); + } + + popupStateChanged(messageName, data, target) { + let docShell; + try { + docShell = this.docShell; + } catch (ex) { + lazy.AutoCompleteChild.removePopupStateListener(this); + return; + } + + if (!lazy.FormAutofill.isAutofillEnabled) { + return; + } + + const { chromeEventHandler } = docShell; + + switch (messageName) { + case "FormAutoComplete:PopupClosed": { + lazy.FormAutofillContent.onPopupClosed(data.selectedRowStyle); + Services.tm.dispatchToMainThread(() => { + chromeEventHandler.removeEventListener( + "keydown", + lazy.FormAutofillContent._onKeyDown, + true + ); + }); + + break; + } + case "FormAutoComplete:PopupOpened": { + lazy.FormAutofillContent.onPopupOpened(); + chromeEventHandler.addEventListener( + "keydown", + lazy.FormAutofillContent._onKeyDown, + true + ); + break; + } + } + } + + _doIdentifyAutofillFields() { + if (this._hasPendingTask) { + return; + } + this._hasPendingTask = true; + + lazy.setTimeout(() => { + lazy.FormAutofillContent.identifyAutofillFields(this._nextHandleElement); + this._hasPendingTask = false; + this._nextHandleElement = null; + // This is for testing purpose only which sends a notification to indicate that the + // form has been identified, and ready to open popup. + this.sendAsyncMessage("FormAutofill:FieldsIdentified"); + lazy.FormAutofillContent.updateActiveInput(); + }); + } + + shouldIgnoreFormAutofillEvent(event) { + let nodePrincipal = event.target.nodePrincipal; + return ( + nodePrincipal.isSystemPrincipal || + nodePrincipal.isNullPrincipal || + nodePrincipal.schemeIs("about") + ); + } + + handleEvent(evt) { + if (!evt.isTrusted) { + return; + } + + if (this.shouldIgnoreFormAutofillEvent(evt)) { + return; + } + + switch (evt.type) { + case "focusin": { + if (lazy.FormAutofill.isAutofillEnabled) { + this.onFocusIn(evt); + } + break; + } + case "DOMFormBeforeSubmit": { + if (lazy.FormAutofill.isAutofillEnabled) { + this.onDOMFormBeforeSubmit(evt); + } + break; + } + + default: { + throw new Error("Unexpected event type"); + } + } + } + + onFocusIn(evt) { + lazy.FormAutofillContent.updateActiveInput(); + + let element = evt.target; + if (!lazy.FormAutofillUtils.isCreditCardOrAddressFieldType(element)) { + return; + } + this._nextHandleElement = element; + + if (!this._alreadyDOMContentLoaded) { + let doc = element.ownerDocument; + if (doc.readyState === "loading") { + if (!this._hasDOMContentLoadedHandler) { + this._hasDOMContentLoadedHandler = true; + doc.addEventListener( + "DOMContentLoaded", + () => this._doIdentifyAutofillFields(), + { once: true } + ); + } + return; + } + this._alreadyDOMContentLoaded = true; + } + + this._doIdentifyAutofillFields(); + } + + /** + * Handle the DOMFormBeforeSubmit event. + * + * @param {Event} evt + */ + onDOMFormBeforeSubmit(evt) { + let formElement = evt.target; + + if (!lazy.FormAutofill.isAutofillEnabled) { + return; + } + + lazy.FormAutofillContent.formSubmitted(formElement); + } + + receiveMessage(message) { + if (!lazy.FormAutofill.isAutofillEnabled) { + return; + } + + const doc = this.document; + + switch (message.name) { + case "FormAutofill:PreviewProfile": { + lazy.FormAutofillContent.previewProfile(doc); + break; + } + case "FormAutofill:ClearForm": { + lazy.FormAutofillContent.clearForm(); + break; + } + case "FormAutofill:FillForm": { + lazy.FormAutofillContent.activeHandler.autofillFormFields(message.data); + break; + } + } + } +} |