GeckoViewAutofill.sys.mjs (3070B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 const lazy = {}; 6 7 import { GeckoViewUtils } from "resource://gre/modules/GeckoViewUtils.sys.mjs"; 8 9 ChromeUtils.defineESModuleGetters(lazy, { 10 FormAutofillUtils: "resource://gre/modules/shared/FormAutofillUtils.sys.mjs", 11 }); 12 13 class Autofill { 14 constructor(sessionId, eventDispatcher) { 15 this.eventDispatcher = eventDispatcher; 16 this.sessionId = sessionId; 17 } 18 19 start() { 20 this.eventDispatcher.sendRequest({ 21 type: "GeckoView:StartAutofill", 22 sessionId: this.sessionId, 23 }); 24 } 25 26 add(node) { 27 return this.eventDispatcher.sendRequestForResult({ 28 type: "GeckoView:AddAutofill", 29 node, 30 }); 31 } 32 33 focus(node) { 34 this.eventDispatcher.sendRequest({ 35 type: "GeckoView:OnAutofillFocus", 36 node, 37 }); 38 } 39 40 update(node) { 41 this.eventDispatcher.sendRequest({ 42 type: "GeckoView:UpdateAutofill", 43 node, 44 }); 45 } 46 47 commit(node) { 48 this.eventDispatcher.sendRequest({ 49 type: "GeckoView:CommitAutofill", 50 node, 51 }); 52 } 53 54 clear() { 55 this.eventDispatcher.sendRequest({ 56 type: "GeckoView:ClearAutofill", 57 }); 58 } 59 } 60 61 class AutofillManager { 62 sessions = new Set(); 63 autofill = null; 64 65 ensure(sessionId, eventDispatcher) { 66 if (!this.sessions.has(sessionId)) { 67 this.autofill = new Autofill(sessionId, eventDispatcher); 68 this.sessions.add(sessionId); 69 this.autofill.start(); 70 } 71 // This could be called for an outdated session, in which case we will just 72 // ignore the autofill call. 73 if (sessionId !== this.autofill.sessionId) { 74 return null; 75 } 76 return this.autofill; 77 } 78 79 get(sessionId) { 80 if (!this.autofill || sessionId !== this.autofill.sessionId) { 81 warn`Disregarding old session ${sessionId}`; 82 // We disregard old sessions 83 return null; 84 } 85 return this.autofill; 86 } 87 88 delete(sessionId) { 89 this.sessions.delete(sessionId); 90 if (!this.autofill || sessionId !== this.autofill.sessionId) { 91 // this delete call might happen *after* the next session already 92 // started, in that case, we can safely ignore this call. 93 return; 94 } 95 this.autofill.clear(); 96 this.autofill = null; 97 } 98 } 99 100 export var gAutofillManager = new AutofillManager(); 101 102 // Runtime functionality 103 export const GeckoViewAutofillRuntime = { 104 async onEvent(aEvent, aData, aCallback) { 105 debug`onEvent: event=${aEvent}, data=${aData}`; 106 107 switch (aEvent) { 108 case "GeckoView:Autofill:GetAddressStructure": { 109 debug`onEvent: event=${aEvent}, data=${aData}`; 110 const country = aData.country ? aData.country : "US"; 111 const layout = lazy.FormAutofillUtils.getFormLayout({ 112 country: `${country}`, 113 }); 114 aCallback.onSuccess({ 115 fields: layout, 116 }); 117 break; 118 } 119 } 120 }, 121 }; 122 123 const { debug, warn } = GeckoViewUtils.initLogging("Autofill");