ASRouterNewTabHook.sys.mjs (3577B)
1 /* vim: set ts=2 sw=2 sts=2 et tw=80: */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 class ASRouterNewTabHookInstance { 7 constructor() { 8 this._newTabMessageHandler = null; 9 this._parentProcessMessageHandler = null; 10 this._router = null; 11 this._clearChildMessages = (...params) => 12 this._newTabMessageHandler === null 13 ? Promise.resolve() 14 : this._newTabMessageHandler.clearChildMessages(...params); 15 this._clearChildProviders = (...params) => 16 this._newTabMessageHandler === null 17 ? Promise.resolve() 18 : this._newTabMessageHandler.clearChildProviders(...params); 19 this._updateAdminState = (...params) => 20 this._newTabMessageHandler === null 21 ? Promise.resolve() 22 : this._newTabMessageHandler.updateAdminState(...params); 23 } 24 25 /** 26 * Params: 27 * object - { 28 * messageHandler: message handler for parent process messages 29 * { 30 * handleCFRAction: Responds to CFR action and returns a Promise 31 * handleTelemetry: Logs telemetry events and returns nothing 32 * }, 33 * router: ASRouter instance 34 * createStorage: function to create DB storage for ASRouter 35 * } 36 */ 37 async initialize({ messageHandler, router, createStorage }) { 38 this._parentProcessMessageHandler = messageHandler; 39 this._router = router; 40 if (!this._router.initialized) { 41 const storage = await createStorage(); 42 await this._router.init({ 43 storage, 44 sendTelemetry: this._parentProcessMessageHandler.handleTelemetry, 45 dispatchCFRAction: this._parentProcessMessageHandler.handleCFRAction, 46 clearChildMessages: this._clearChildMessages, 47 clearChildProviders: this._clearChildProviders, 48 updateAdminState: this._updateAdminState, 49 }); 50 } 51 } 52 53 destroy() { 54 if (this._router?.initialized) { 55 this.disconnect(); 56 this._router.uninit(); 57 } 58 } 59 60 /** 61 * Connects new tab message handler to hook. 62 * Note: Should only ever be called on an initialized instance 63 * Params: 64 * newTabMessageHandler - { 65 * clearChildMessages: clears child messages and returns Promise 66 * clearChildProviders: clears child providers and returns Promise. 67 * updateAdminState: updates admin state and returns Promise 68 * } 69 * Returns: parentProcessMessageHandler 70 */ 71 connect(newTabMessageHandler) { 72 this._newTabMessageHandler = newTabMessageHandler; 73 return this._parentProcessMessageHandler; 74 } 75 76 /** 77 * Disconnects new tab message handler from hook. 78 */ 79 disconnect() { 80 this._newTabMessageHandler = null; 81 } 82 } 83 84 class AwaitSingleton { 85 constructor() { 86 this.instance = null; 87 const initialized = new Promise(resolve => { 88 this.setInstance = instance => { 89 this.setInstance = () => {}; 90 this.instance = instance; 91 resolve(instance); 92 }; 93 }); 94 this.getInstance = () => initialized; 95 } 96 } 97 98 export const ASRouterNewTabHook = (() => { 99 const singleton = new AwaitSingleton(); 100 const instance = new ASRouterNewTabHookInstance(); 101 return { 102 getInstance: singleton.getInstance, 103 104 /** 105 * Param: 106 * params - see ASRouterNewTabHookInstance.init 107 */ 108 createInstance: async params => { 109 await instance.initialize(params); 110 singleton.setInstance(instance); 111 }, 112 113 destroy: () => { 114 instance.destroy(); 115 }, 116 }; 117 })();