зеркало из https://github.com/mozilla/gecko-dev.git
110 строки
3.3 KiB
JavaScript
110 строки
3.3 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/. */
|
|
|
|
"use strict";
|
|
|
|
var EXPORTED_SYMBOLS = ["EveryWindow"];
|
|
|
|
/*
|
|
* 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);
|
|
});
|
|
}
|
|
}
|
|
|
|
const EveryWindow = {
|
|
/**
|
|
* 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, data) {
|
|
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);
|
|
},
|
|
};
|