michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: "use strict"; michael@0: michael@0: module.metadata = { michael@0: "stability": "experimental" michael@0: }; michael@0: michael@0: const { Ci } = require("chrome"); michael@0: const { open } = require("../event/dom"); michael@0: const { observe } = require("../event/chrome"); michael@0: const { filter, merge, map, expand } = require("../event/utils"); michael@0: const { windows } = require("../window/utils"); michael@0: const { events: windowEvents } = require("sdk/window/events"); michael@0: michael@0: // Note: Please note that even though pagehide event is included michael@0: // it's not observable reliably since it's not always triggered michael@0: // when closing tabs. Implementation can be imrpoved once that michael@0: // event will be necessary. michael@0: let TYPES = ["DOMContentLoaded", "load", "pageshow", "pagehide"]; michael@0: michael@0: let insert = observe("document-element-inserted"); michael@0: let windowCreate = merge([ michael@0: observe("content-document-global-created"), michael@0: observe("chrome-document-global-created") michael@0: ]); michael@0: let create = map(windowCreate, function({target, data, type}) { michael@0: return { target: target.document, type: type, data: data } michael@0: }); michael@0: michael@0: function streamEventsFrom({document}) { michael@0: // Map supported event types to a streams of those events on the given michael@0: // `window` for the inserted document and than merge these streams into michael@0: // single form stream off all window state change events. michael@0: let stateChanges = TYPES.map(function(type) { michael@0: return open(document, type, { capture: true }); michael@0: }); michael@0: michael@0: // Since load events on document occur for every loded resource michael@0: return filter(merge(stateChanges), function({target}) { michael@0: return target instanceof Ci.nsIDOMDocument michael@0: }) michael@0: } michael@0: exports.streamEventsFrom = streamEventsFrom; michael@0: michael@0: let opened = windows(null, { includePrivate: true }); michael@0: let state = merge(opened.map(streamEventsFrom)); michael@0: michael@0: michael@0: let futureReady = filter(windowEvents, function({type}) michael@0: type === "DOMContentLoaded"); michael@0: let futureWindows = map(futureReady, function({target}) target); michael@0: let futureState = expand(futureWindows, streamEventsFrom); michael@0: michael@0: exports.events = merge([insert, create, state, futureState]);