|
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 "use strict"; |
|
5 |
|
6 module.metadata = { |
|
7 "stability": "unstable" |
|
8 }; |
|
9 |
|
10 const { Ci } = require("chrome"); |
|
11 const { observe } = require("../event/chrome"); |
|
12 const { open } = require("../event/dom"); |
|
13 const { windows } = require("../window/utils"); |
|
14 const { filter, merge, map, expand } = require("../event/utils"); |
|
15 |
|
16 // Function registers single shot event listeners for relevant window events |
|
17 // that forward events to exported event stream. |
|
18 function eventsFor(window) { |
|
19 let interactive = open(window, "DOMContentLoaded", { capture: true }); |
|
20 let complete = open(window, "load", { capture: true }); |
|
21 let states = merge([interactive, complete]); |
|
22 let changes = filter(states, function({target}) target === window.document); |
|
23 return map(changes, function({type, target}) { |
|
24 return { type: type, target: target.defaultView } |
|
25 }); |
|
26 } |
|
27 |
|
28 // In addition to observing windows that are open we also observe windows |
|
29 // that are already already opened in case they're in process of loading. |
|
30 let opened = windows(null, { includePrivate: true }); |
|
31 let currentEvents = merge(opened.map(eventsFor)); |
|
32 |
|
33 // Register system event listeners for top level window open / close. |
|
34 function rename({type, target, data}) { |
|
35 return { type: rename[type], target: target, data: data } |
|
36 } |
|
37 rename.domwindowopened = "open"; |
|
38 rename.domwindowclosed = "close"; |
|
39 |
|
40 let openEvents = map(observe("domwindowopened"), rename); |
|
41 let closeEvents = map(observe("domwindowclosed"), rename); |
|
42 let futureEvents = expand(openEvents, function({target}) eventsFor(target)); |
|
43 |
|
44 let channel = merge([currentEvents, futureEvents, |
|
45 openEvents, closeEvents]); |
|
46 exports.events = channel; |