ObserverForwarder.sys.mjs (3188B)
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 3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 5 import { AppConstants } from "resource://gre/modules/AppConstants.sys.mjs"; 6 7 // Because of the indirection with which we call into these modules, eslint 8 // does not realize which of these modules are used, so we have to disable 9 // the relevant lint rule. However, this does mean that when modifying the 10 // list of observers or the modules they are associated with, you must be 11 // more careful to ensure we remove unused modules. 12 /* eslint-disable mozilla/valid-lazy */ 13 let lazy = {}; 14 ChromeUtils.defineESModuleGetters(lazy, { 15 CanvasPermissionPromptHelper: 16 "moz-src:///browser/modules/CanvasPermissionPromptHelper.sys.mjs", 17 FilePickerCrashed: "resource:///modules/FilePickerCrashed.sys.mjs", 18 PluginManager: "resource:///actors/PluginParent.sys.mjs", 19 UnexpectedScriptObserver: 20 "moz-src:///browser/modules/UnexpectedScriptObserver.sys.mjs", 21 WebAuthnPromptHelper: 22 "moz-src:///browser/modules/WebAuthnPromptHelper.sys.mjs", 23 }); 24 25 // Map from observer topic to a list of exported objects whose observe() 26 // method should be called when the topic is fired. The exported objects 27 // are expected to be defined in the modules imported above. 28 let gObservers = { 29 "canvas-permissions-prompt": ["CanvasPermissionPromptHelper"], 30 "canvas-permissions-prompt-hide-doorhanger": ["CanvasPermissionPromptHelper"], 31 32 "UnexpectedJavaScriptLoad-Live": ["UnexpectedScriptObserver"], 33 "UnexpectedJavaScriptLoad-UserTookAction": ["UnexpectedScriptObserver"], 34 35 "file-picker-crashed": ["FilePickerCrashed"], 36 "gmp-plugin-crash": ["PluginManager"], 37 "plugin-crashed": ["PluginManager"], 38 39 "webauthn-prompt": ["WebAuthnPromptHelper"], 40 }; 41 if (Cu.isInAutomation) { 42 gObservers["UnexpectedJavaScriptLoad-ResetNotification"] = [ 43 "UnexpectedScriptObserver", 44 ]; 45 } 46 47 if (AppConstants.MOZ_UPDATER) { 48 ChromeUtils.defineESModuleGetters(lazy, { 49 UpdateListener: "resource://gre/modules/UpdateListener.sys.mjs", 50 }); 51 52 gObservers["update-downloading"] = ["UpdateListener"]; 53 gObservers["update-staged"] = ["UpdateListener"]; 54 gObservers["update-downloaded"] = ["UpdateListener"]; 55 gObservers["update-available"] = ["UpdateListener"]; 56 gObservers["update-error"] = ["UpdateListener"]; 57 gObservers["update-swap"] = ["UpdateListener"]; 58 } 59 60 /** 61 * Utility to avoid eagerly loading modules that are only needed 62 * once a given observer topic is fired. Note that in an ideal world, 63 * these observers would be added in parts of the same component that 64 * are already loaded at startup, but not all components have such code. 65 * 66 * This module exists to avoid each component having to reinvent that wheel. 67 */ 68 export const ObserverForwarder = { 69 init() { 70 for (const topic of Object.keys(gObservers)) { 71 Services.obs.addObserver(this, topic); 72 } 73 }, 74 75 observe(subject, topic, data) { 76 for (let objectName of gObservers[topic]) { 77 try { 78 lazy[objectName].observe(subject, topic, data); 79 } catch (e) { 80 console.error(e); 81 } 82 } 83 }, 84 };