-
Notifications
You must be signed in to change notification settings - Fork 2
/
foreach_nsIDOMWindow.js
84 lines (80 loc) · 3.58 KB
/
foreach_nsIDOMWindow.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
const isFennec = require('sdk/system/xul-app').ID === '{aa3c5121-dab2-40e2-81ca-7ea25febc110}';
const tabs = isFennec ? require("sdk/tabs") : null; // sdk/tabs is required only on fennec
const { Cu, Ci } = require("chrome");
const { getTargetWindow } = require('sdk/content/mod');
Cu.import("resource://gre/modules/Services.jsm");
// const { getContentFrame } = require('sdk/panel/utils');
// sdk/panel/utils crashes inside process script. copied implementation here
const getContentFrame = panel =>
((panel.state === "open") || (panel.state === "showing")) ?
panel.firstChild :
panel.backgroundFrame;
function processNsIDocShell(docshell, processed_windows, callback) {
if (docshell.getDocShellEnumerator) {
let enumerator = docshell.getDocShellEnumerator(
docshell.typeAll,
docshell.ENUMERATE_FORWARDS
);
while (enumerator.hasMoreElements()) {
let el = enumerator.getNext();
if (el !== docshell) {
let docShell = el.QueryInterface(Ci.nsIDocShell);
let window = getTargetWindow(docShell.contentViewer.DOMDocument);
if (!processed_windows.has(window)) {
callback(window);
processed_windows.add(window);
}
processNsIDocShell(docShell, processed_windows, callback);
}
}
}
}
function forEachNsIDOMWindow(callback) {
let processed_windows = new WeakSet();
if (isFennec) {
for (let tab of tabs) {
try {
let window = getTargetWindow(tab);
if (window && !processed_windows.has(window)) {
callback(window);
processed_windows.add(window);
}
processNsIDocShell(window.document.docShell, processed_windows, callback);
} catch (e) {
console.log(e);
// TODO: investigate why tab is undefined sometimes
}
}
} else {
let enumerator = Services.wm.getEnumerator(null);
if (!enumerator.hasMoreElements()) // content process //TODO: write it more clear and test Services.ww.getWindowEnumerator() with fennec.
enumerator = Services.ww.getWindowEnumerator();
while (enumerator.hasMoreElements()) {
let rootWindow = enumerator.getNext();
if (!processed_windows.has(rootWindow)) {
callback(rootWindow);
processed_windows.add(rootWindow);
}
let mainPopupSet = rootWindow.document.querySelector('#mainPopupSet');
if (mainPopupSet) {
Array.prototype.forEach.call(mainPopupSet.childNodes, node => {
if (node.backgroundFrame) {
try {
let { docShell } = getContentFrame(node);
//TODO: get rid of getTargetWindow
let window = getTargetWindow(docShell.contentViewer.DOMDocument);
callback(window);
processed_windows.add(window);
processNsIDocShell(docShell);
} catch (e) {
console.error(e)
}
}
})
}
processNsIDocShell(rootWindow.document.docShell, processed_windows, callback);
}
//processNsIDocShell(appShellService.hiddenDOMWindow.document.docShell, processed_windows, callback);
}
}
exports.forEachNsIDOMWindow = forEachNsIDOMWindow;