summaryrefslogtreecommitdiffstats
path: root/browser/components/sessionstore/FrameTree.jsm
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/sessionstore/FrameTree.jsm')
-rw-r--r--browser/components/sessionstore/FrameTree.jsm254
1 files changed, 0 insertions, 254 deletions
diff --git a/browser/components/sessionstore/FrameTree.jsm b/browser/components/sessionstore/FrameTree.jsm
deleted file mode 100644
index e8ed12a8f..000000000
--- a/browser/components/sessionstore/FrameTree.jsm
+++ /dev/null
@@ -1,254 +0,0 @@
-/* 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";
-
-this.EXPORTED_SYMBOLS = ["FrameTree"];
-
-const Cu = Components.utils;
-const Ci = Components.interfaces;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
-
-const EXPORTED_METHODS = ["addObserver", "contains", "map", "forEach"];
-
-/**
- * A FrameTree represents all frames that were reachable when the document
- * was loaded. We use this information to ignore frames when collecting
- * sessionstore data as we can't currently restore anything for frames that
- * have been created dynamically after or at the load event.
- *
- * @constructor
- */
-function FrameTree(chromeGlobal) {
- let internal = new FrameTreeInternal(chromeGlobal);
- let external = {};
-
- for (let method of EXPORTED_METHODS) {
- external[method] = internal[method].bind(internal);
- }
-
- return Object.freeze(external);
-}
-
-/**
- * The internal frame tree API that the public one points to.
- *
- * @constructor
- */
-function FrameTreeInternal(chromeGlobal) {
- // A WeakMap that uses frames (DOMWindows) as keys and their initial indices
- // in their parents' child lists as values. Suppose we have a root frame with
- // three subframes i.e. a page with three iframes. The WeakMap would have
- // four entries and look as follows:
- //
- // root -> 0
- // subframe1 -> 0
- // subframe2 -> 1
- // subframe3 -> 2
- //
- // Should one of the subframes disappear we will stop collecting data for it
- // as |this._frames.has(frame) == false|. All other subframes will maintain
- // their initial indices to ensure we can restore frame data appropriately.
- this._frames = new WeakMap();
-
- // The Set of observers that will be notified when the frame changes.
- this._observers = new Set();
-
- // The chrome global we use to retrieve the current DOMWindow.
- this._chromeGlobal = chromeGlobal;
-
- // Register a web progress listener to be notified about new page loads.
- let docShell = chromeGlobal.docShell;
- let ifreq = docShell.QueryInterface(Ci.nsIInterfaceRequestor);
- let webProgress = ifreq.getInterface(Ci.nsIWebProgress);
- webProgress.addProgressListener(this, Ci.nsIWebProgress.NOTIFY_STATE_DOCUMENT);
-}
-
-FrameTreeInternal.prototype = {
-
- // Returns the docShell's current global.
- get content() {
- return this._chromeGlobal.content;
- },
-
- /**
- * Adds a given observer |obs| to the set of observers that will be notified
- * when the frame tree is reset (when a new document starts loading) or
- * recollected (when a document finishes loading).
- *
- * @param obs (object)
- */
- addObserver: function (obs) {
- this._observers.add(obs);
- },
-
- /**
- * Notifies all observers that implement the given |method|.
- *
- * @param method (string)
- */
- notifyObservers: function (method) {
- for (let obs of this._observers) {
- if (obs.hasOwnProperty(method)) {
- obs[method]();
- }
- }
- },
-
- /**
- * Checks whether a given |frame| is contained in the collected frame tree.
- * If it is not, this indicates that we should not collect data for it.
- *
- * @param frame (nsIDOMWindow)
- * @return bool
- */
- contains: function (frame) {
- return this._frames.has(frame);
- },
-
- /**
- * Recursively applies the given function |cb| to the stored frame tree. Use
- * this method to collect sessionstore data for all reachable frames stored
- * in the frame tree.
- *
- * If a given function |cb| returns a value, it must be an object. It may
- * however return "null" to indicate that there is no data to be stored for
- * the given frame.
- *
- * The object returned by |cb| cannot have any property named "children" as
- * that is used to store information about subframes in the tree returned
- * by |map()| and might be overridden.
- *
- * @param cb (function)
- * @return object
- */
- map: function (cb) {
- let frames = this._frames;
-
- function walk(frame) {
- let obj = cb(frame) || {};
-
- if (frames.has(frame)) {
- let children = [];
-
- Array.forEach(frame.frames, subframe => {
- // Don't collect any data if the frame is not contained in the
- // initial frame tree. It's a dynamic frame added later.
- if (!frames.has(subframe)) {
- return;
- }
-
- // Retrieve the frame's original position in its parent's child list.
- let index = frames.get(subframe);
-
- // Recursively collect data for the current subframe.
- let result = walk(subframe, cb);
- if (result && Object.keys(result).length) {
- children[index] = result;
- }
- });
-
- if (children.length) {
- obj.children = children;
- }
- }
-
- return Object.keys(obj).length ? obj : null;
- }
-
- return walk(this.content);
- },
-
- /**
- * Applies the given function |cb| to all frames stored in the tree. Use this
- * method if |map()| doesn't suit your needs and you want more control over
- * how data is collected.
- *
- * @param cb (function)
- * This callback receives the current frame as the only argument.
- */
- forEach: function (cb) {
- let frames = this._frames;
-
- function walk(frame) {
- cb(frame);
-
- if (!frames.has(frame)) {
- return;
- }
-
- Array.forEach(frame.frames, subframe => {
- if (frames.has(subframe)) {
- cb(subframe);
- }
- });
- }
-
- walk(this.content);
- },
-
- /**
- * Stores a given |frame| and its children in the frame tree.
- *
- * @param frame (nsIDOMWindow)
- * @param index (int)
- * The index in the given frame's parent's child list.
- */
- collect: function (frame, index = 0) {
- // Mark the given frame as contained in the frame tree.
- this._frames.set(frame, index);
-
- // Mark the given frame's subframes as contained in the tree.
- Array.forEach(frame.frames, this.collect, this);
- },
-
- /**
- * @see nsIWebProgressListener.onStateChange
- *
- * We want to be notified about:
- * - new documents that start loading to clear the current frame tree;
- * - completed document loads to recollect reachable frames.
- */
- onStateChange: function (webProgress, request, stateFlags, status) {
- // Ignore state changes for subframes because we're only interested in the
- // top-document starting or stopping its load. We thus only care about any
- // changes to the root of the frame tree, not to any of its nodes/leafs.
- if (!webProgress.isTopLevel || webProgress.DOMWindow != this.content) {
- return;
- }
-
- // onStateChange will be fired when loading the initial about:blank URI for
- // a browser, which we don't actually care about. This is particularly for
- // the case of unrestored background tabs, where the content has not yet
- // been restored: we don't want to accidentally send any updates to the
- // parent when the about:blank placeholder page has loaded.
- if (!this._chromeGlobal.docShell.hasLoadedNonBlankURI) {
- return;
- }
-
- if (stateFlags & Ci.nsIWebProgressListener.STATE_START) {
- // Clear the list of frames until we can recollect it.
- this._frames = new WeakMap();
-
- // Notify observers that the frame tree has been reset.
- this.notifyObservers("onFrameTreeReset");
- } else if (stateFlags & Ci.nsIWebProgressListener.STATE_STOP) {
- // The document and its resources have finished loading.
- this.collect(webProgress.DOMWindow);
-
- // Notify observers that the frame tree has been reset.
- this.notifyObservers("onFrameTreeCollected");
- }
- },
-
- // Unused nsIWebProgressListener methods.
- onLocationChange: function () {},
- onProgressChange: function () {},
- onSecurityChange: function () {},
- onStatusChange: function () {},
-
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener,
- Ci.nsISupportsWeakReference])
-};