events.js 1.8 KB

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