mirror of
				https://github.com/mozilla/gecko-dev.git
				synced 2025-11-04 02:09:05 +02:00 
			
		
		
		
	
		
			
				
	
	
		
			114 lines
		
	
	
	
		
			3.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			114 lines
		
	
	
	
		
			3.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
/* This Source Code Form is subject to the terms of the Mozilla Public
 | 
						|
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
						|
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | 
						|
 | 
						|
/*
 | 
						|
 * This module enables consumers to register callbacks on every
 | 
						|
 * current and future browser window.
 | 
						|
 *
 | 
						|
 * Usage: EveryWindow.registerCallback(id, init, uninit);
 | 
						|
 *        EveryWindow.unregisterCallback(id);
 | 
						|
 *
 | 
						|
 * id is expected to be a unique value that identifies the
 | 
						|
 * consumer, to be used for unregistration. If the id is already
 | 
						|
 * in use, registerCallback returns false without doing anything.
 | 
						|
 *
 | 
						|
 * Each callback will receive the window for which it is presently
 | 
						|
 * being called as the first argument.
 | 
						|
 *
 | 
						|
 * init is called on every existing window at the time of registration,
 | 
						|
 * and on all future windows at browser-delayed-startup-finished.
 | 
						|
 *
 | 
						|
 * uninit is called on every existing window if requested at the time
 | 
						|
 * of unregistration, and at the time of domwindowclosed.
 | 
						|
 * If the window is closing, a second argument is passed with value `true`.
 | 
						|
 */
 | 
						|
 | 
						|
var initialized = false;
 | 
						|
var callbacks = new Map();
 | 
						|
 | 
						|
function callForEveryWindow(callback) {
 | 
						|
  let windowList = Services.wm.getEnumerator("navigator:browser");
 | 
						|
  for (let win of windowList) {
 | 
						|
    win.delayedStartupPromise.then(() => {
 | 
						|
      callback(win);
 | 
						|
    });
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
export const EveryWindow = {
 | 
						|
  /**
 | 
						|
   * The current list of all browser windows whose delayedStartupPromise has resolved
 | 
						|
   */
 | 
						|
  get readyWindows() {
 | 
						|
    return Array.from(Services.wm.getEnumerator("navigator:browser")).filter(
 | 
						|
      win => win.gBrowserInit?.delayedStartupFinished
 | 
						|
    );
 | 
						|
  },
 | 
						|
 | 
						|
  /**
 | 
						|
   * Registers init and uninit functions to be called on every window.
 | 
						|
   *
 | 
						|
   * @param {string} id A unique identifier for the consumer, to be
 | 
						|
   *   used for unregistration.
 | 
						|
   * @param {function} init The function to be called on every currently
 | 
						|
   *   existing window and every future window after delayed startup.
 | 
						|
   * @param {function} uninit The function to be called on every window
 | 
						|
   *   at the time of callback unregistration or after domwindowclosed.
 | 
						|
   * @returns {boolean} Returns false if the id was taken, else true.
 | 
						|
   */
 | 
						|
  registerCallback: function EW_registerCallback(id, init, uninit) {
 | 
						|
    if (callbacks.has(id)) {
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
 | 
						|
    if (!initialized) {
 | 
						|
      let addUnloadListener = win => {
 | 
						|
        function observer(subject, topic) {
 | 
						|
          if (topic == "domwindowclosed" && subject === win) {
 | 
						|
            Services.ww.unregisterNotification(observer);
 | 
						|
            for (let c of callbacks.values()) {
 | 
						|
              c.uninit(win, true);
 | 
						|
            }
 | 
						|
          }
 | 
						|
        }
 | 
						|
        Services.ww.registerNotification(observer);
 | 
						|
      };
 | 
						|
 | 
						|
      Services.obs.addObserver(win => {
 | 
						|
        for (let c of callbacks.values()) {
 | 
						|
          c.init(win);
 | 
						|
        }
 | 
						|
        addUnloadListener(win);
 | 
						|
      }, "browser-delayed-startup-finished");
 | 
						|
 | 
						|
      callForEveryWindow(addUnloadListener);
 | 
						|
 | 
						|
      initialized = true;
 | 
						|
    }
 | 
						|
 | 
						|
    callForEveryWindow(init);
 | 
						|
    callbacks.set(id, { id, init, uninit });
 | 
						|
 | 
						|
    return true;
 | 
						|
  },
 | 
						|
 | 
						|
  /**
 | 
						|
   * Unregisters a previously registered consumer.
 | 
						|
   *
 | 
						|
   * @param {string} id The id to unregister.
 | 
						|
   * @param {boolean} [callUninit=true] Whether to call the registered uninit
 | 
						|
   *   function on every window.
 | 
						|
   */
 | 
						|
  unregisterCallback: function EW_unregisterCallback(id, callUninit = true) {
 | 
						|
    if (!callbacks.has(id)) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
    if (callUninit) {
 | 
						|
      callForEveryWindow(callbacks.get(id).uninit);
 | 
						|
    }
 | 
						|
 | 
						|
    callbacks.delete(id);
 | 
						|
  },
 | 
						|
};
 |