tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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 }