ExternalComponentsFeed.sys.mjs (2991B)
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 http://mozilla.org/MPL/2.0/. */ 4 5 import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs"; 6 import { 7 actionTypes as at, 8 actionCreators as ac, 9 } from "resource://newtab/common/Actions.mjs"; 10 11 const lazy = XPCOMUtils.declareLazy({ 12 AboutNewTabComponentRegistry: 13 "moz-src:///browser/components/newtab/AboutNewTabComponents.sys.mjs", 14 }); 15 16 /** 17 * ExternalComponentsFeed manages the integration between the 18 * AboutNewTabComponentRegistry and the New Tab Redux store. 19 * 20 * This feed: 21 * - Listens to the AboutNewTabComponentRegistry for component updates 22 * - Dispatches REFRESH_EXTERNAL_COMPONENTS actions to update the store 23 * - Ensures external components are loaded during New Tab initialization 24 * 25 * External components registered through this system can be rendered on the 26 * newtab page via the ExternalComponentWrapper React component. 27 */ 28 export class ExternalComponentsFeed { 29 /** 30 * The AboutNewTabComponentRegistry instance that tracks registered components. 31 * 32 * @type {AboutNewTabComponentRegistry} 33 */ 34 #registry = null; 35 36 /** 37 * Creates a new ExternalComponentsFeed instance. 38 * 39 * Initializes the AboutNewTabComponentRegistry and sets up a listener to 40 * refresh components whenever the registry updates. 41 */ 42 constructor() { 43 this.#registry = new lazy.AboutNewTabComponentRegistry(); 44 this.#registry.on(lazy.AboutNewTabComponentRegistry.UPDATED_EVENT, () => { 45 this.refreshComponents(); 46 }); 47 } 48 49 /** 50 * Dispatches a REFRESH_EXTERNAL_COMPONENTS action with the current list of 51 * registered components from the registry. 52 * 53 * This action is broadcast to all content processes to update their Redux 54 * stores with the latest component configurations. 55 * 56 * @param {object} options - Optional configuration 57 * @param {boolean} [options.isStartup=false] - If true, marks the action as a 58 * startup action (meta.isStartup: true), which prevents the cached 59 * about:home document from unnecessarily reprocessing the action. 60 */ 61 refreshComponents(options = {}) { 62 const action = { 63 type: at.REFRESH_EXTERNAL_COMPONENTS, 64 data: [...this.#registry.values], 65 }; 66 67 if (options.isStartup) { 68 action.meta = { isStartup: true }; 69 } 70 71 this.store.dispatch(ac.BroadcastToContent(action)); 72 } 73 74 /** 75 * Handles Redux actions dispatched to this feed. 76 * 77 * Currently handles: 78 * - INIT: Refreshes components when Activity Stream initializes, marking 79 * the action as a startup action to optimize cached document handling. 80 * 81 * @param {object} action - The Redux action to handle 82 * @param {string} action.type - The action type 83 */ 84 onAction(action) { 85 switch (action.type) { 86 case at.INIT: 87 this.refreshComponents({ isStartup: true }); 88 break; 89 } 90 } 91 }