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: "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 method = require("../../method/core"); michael@0: const { add, remove, iterator } = require("../lang/weak-set"); michael@0: michael@0: let getTargetWindow = method("getTargetWindow"); michael@0: michael@0: getTargetWindow.define(function (target) { michael@0: if (target instanceof Ci.nsIDOMWindow) michael@0: return target; michael@0: if (target instanceof Ci.nsIDOMDocument) michael@0: return target.defaultView || null; michael@0: michael@0: return null; michael@0: }); michael@0: michael@0: exports.getTargetWindow = getTargetWindow; michael@0: michael@0: let attachTo = method("attachTo"); michael@0: exports.attachTo = attachTo; michael@0: michael@0: let detachFrom = method("detatchFrom"); michael@0: exports.detachFrom = detachFrom; michael@0: michael@0: function attach(modification, target) { michael@0: if (!modification) michael@0: return; michael@0: michael@0: let window = getTargetWindow(target); michael@0: michael@0: attachTo(modification, window); michael@0: michael@0: // modification are stored per content; `window` reference can still be the michael@0: // same even if the content is changed, therefore `document` is used instead. michael@0: add(modification, window.document); michael@0: } michael@0: exports.attach = attach; michael@0: michael@0: function detach(modification, target) { michael@0: if (!modification) michael@0: return; michael@0: michael@0: if (target) { michael@0: let window = getTargetWindow(target); michael@0: detachFrom(modification, window); michael@0: remove(modification, window.document); michael@0: } michael@0: else { michael@0: let documents = iterator(modification); michael@0: for (let document of documents) { michael@0: detachFrom(modification, document.defaultView); michael@0: remove(modification, document); michael@0: } michael@0: } michael@0: } michael@0: exports.detach = detach;