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
|
/* 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";
const { windows, isBrowser, isInteractive, isDocumentLoaded,
getOuterId } = require("../window/utils");
const { InputPort } = require("./system");
const { lift, merges, foldp, keepIf, start, Input } = require("../event/utils");
const { patch } = require("diffpatcher/index");
const { Sequence, seq, filter, object, pairs } = require("../util/sequence");
// Create lazy iterators from the regular arrays, although
// once https://github.com/mozilla/addon-sdk/pull/1314 lands
// `windows` will be transforme to lazy iterators.
// When iterated over belowe sequences items will represent
// state of windows at the time of iteration.
const opened = seq(function*() {
const items = windows("navigator:browser", {includePrivate: true});
for (let item of items) {
yield [getOuterId(item), item];
}
});
const interactive = filter(([_, window]) => isInteractive(window), opened);
const loaded = filter(([_, window]) => isDocumentLoaded(window), opened);
// Helper function that converts given argument to a delta.
const Update = window => window && object([getOuterId(window), window]);
const Delete = window => window && object([getOuterId(window), null]);
// Signal represents delta for last top level window close.
const LastClosed = lift(Delete,
keepIf(isBrowser, null,
new InputPort({topic: "domwindowclosed"})));
exports.LastClosed = LastClosed;
const windowFor = document => document && document.defaultView;
// Signal represent delta for last top level window document becoming interactive.
const InteractiveDoc = new InputPort({topic: "chrome-document-interactive"});
const InteractiveWin = lift(windowFor, InteractiveDoc);
const LastInteractive = lift(Update, keepIf(isBrowser, null, InteractiveWin));
exports.LastInteractive = LastInteractive;
// Signal represent delta for last top level window loaded.
const LoadedDoc = new InputPort({topic: "chrome-document-loaded"});
const LoadedWin = lift(windowFor, LoadedDoc);
const LastLoaded = lift(Update, keepIf(isBrowser, null, LoadedWin));
exports.LastLoaded = LastLoaded;
const initialize = input => {
if (!input.initialized) {
input.value = object(...input.value);
Input.start(input);
input.initialized = true;
}
};
// Signal represents set of top level interactive windows, updated any
// time new window becomes interactive or one get's closed.
const Interactive = foldp(patch, interactive, merges([LastInteractive,
LastClosed]));
Interactive[start] = initialize;
exports.Interactive = Interactive;
// Signal represents set of top level loaded window, updated any time
// new window becomes interactive or one get's closed.
const Loaded = foldp(patch, loaded, merges([LastLoaded, LastClosed]));
Loaded[start] = initialize;
exports.Loaded = Loaded;
|