123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- /*******************************************************************************
- ηMatrix - a browser extension to black/white list requests.
- Copyright (C) 2014-2019 The uMatrix/uBlock Origin authors
- Copyright (C) 2019-2022 Alessio Vanni
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see {http://www.gnu.org/licenses/}.
- Home: https://gitlab.com/vannilla/ematrix
- uMatrix Home: https://github.com/gorhill/uMatrix
- */
- 'use strict';
- /******************************************************************************/
- (function () {
- vAPI.window = (function () {
- let windowToIdMap = new Map();
- let windowIdGenerator = 1;
- let api = {
- onOpenWindow: null,
- onCloseWindow: null
- };
- // https://github.com/gorhill/uMatrix/issues/586 This is
- // necessary hack because on SeaMonkey 2.40, for unknown
- // reasons private windows do not have the attribute
- // `windowtype` set to `navigator:browser`. As a fallback, the
- // code here will also test whether the id attribute is
- // `main-window`.
- api.toBrowserWindow = function (win) {
- let docElement = win && win.document
- && win.document.documentElement;
- if (!docElement) {
- return null;
- }
- if (vAPI.thunderbird) {
- return docElement.getAttribute('windowtype') === 'mail:3pane'
- ? win
- : null;
- }
- return docElement.getAttribute('windowtype') === 'navigator:browser'
- || docElement.getAttribute('id') === 'main-window'
- ? win
- : null;
- };
- api.getWindows = function () {
- return windowToIdMap.keys();
- };
- api.idFromWindow = function (win) {
- return windowToIdMap.get(win) || 0;
- };
- api.getCurrentWindow = function () {
- return this.toBrowserWindow(Services.wm.getMostRecentWindow(null));
- };
- let addWindow = function (win) {
- if (!win || windowToIdMap.has(win)) {
- return;
- }
- windowToIdMap.set(win, windowIdGenerator++);
- if (typeof api.onOpenWindow === 'function') {
- api.onOpenWindow(win);
- }
- };
- let removeWindow = function (win) {
- if (!win || windowToIdMap.delete(win) !== true) {
- return;
- }
- if (typeof api.onCloseWindow === 'function') {
- api.onCloseWindow(win);
- }
- };
- // https://github.com/gorhill/uMatrix/issues/357
- // Use nsIWindowMediator for being notified of opened/closed windows.
- let listeners = {
- onOpenWindow: function (aWindow) {
- let win;
- try {
- win = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindow);
- } catch (e) {
- // Ignore
- }
- addWindow(win);
- },
- onCloseWindow: function (aWindow) {
- let win;
- try {
- win = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindow);
- } catch (e) {
- // Ignore
- }
- removeWindow(win);
- },
- observe: function (aSubject, topic) {
- let win;
- try {
- win = aSubject.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindow);
- } catch (e) {
- // Ignore
- }
- if (!win) {
- return;
- }
- switch (topic) {
- case 'domwindowopened':
- addWindow(win);
- break;
- case 'domwindowclosed':
- removeWindow(win);
- break;
- default:
- console.error('unknown observer topic');
- break;
- }
- }
- };
- (function() {
- let winumerator;
- winumerator = Services.wm.getEnumerator(null);
- while (winumerator.hasMoreElements()) {
- let win = winumerator.getNext();
- if (!win.closed) {
- windowToIdMap.set(win, windowIdGenerator++);
- }
- }
- winumerator = Services.ww.getWindowEnumerator();
- while (winumerator.hasMoreElements()) {
- let win = winumerator.getNext()
- .QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindow);
- if (!win.closed) {
- windowToIdMap.set(win, windowIdGenerator++);
- }
- }
- Services.wm.addListener(listeners);
- Services.ww.registerNotification(listeners);
- })();
- vAPI.addCleanUpTask(function() {
- Services.wm.removeListener(listeners);
- Services.ww.unregisterNotification(listeners);
- windowToIdMap.clear();
- });
- return api;
- })();
- })();
|