toolkit/modules/sessionstore/ScrollPosition.jsm

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/toolkit/modules/sessionstore/ScrollPosition.jsm	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,90 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 +* License, v. 2.0. If a copy of the MPL was not distributed with this file,
     1.6 +* You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +
     1.8 +"use strict";
     1.9 +
    1.10 +this.EXPORTED_SYMBOLS = ["ScrollPosition"];
    1.11 +
    1.12 +const Ci = Components.interfaces;
    1.13 +
    1.14 +/**
    1.15 + * It provides methods to collect and restore scroll positions for single
    1.16 + * frames and frame trees.
    1.17 + *
    1.18 + * This is a child process module.
    1.19 + */
    1.20 +this.ScrollPosition = Object.freeze({
    1.21 +  /**
    1.22 +   * Collects scroll position data for any given |frame| in the frame hierarchy.
    1.23 +   *
    1.24 +   * @param frame (DOMWindow)
    1.25 +   *
    1.26 +   * @return {scroll: "x,y"} e.g. {scroll: "100,200"}
    1.27 +   *         Returns null when there is no scroll data we want to store for the
    1.28 +   *         given |frame|.
    1.29 +   */
    1.30 +  collect: function (frame) {
    1.31 +    let ifreq = frame.QueryInterface(Ci.nsIInterfaceRequestor);
    1.32 +    let utils = ifreq.getInterface(Ci.nsIDOMWindowUtils);
    1.33 +    let scrollX = {}, scrollY = {};
    1.34 +    utils.getScrollXY(false /* no layout flush */, scrollX, scrollY);
    1.35 +
    1.36 +    if (scrollX.value || scrollY.value) {
    1.37 +      return {scroll: scrollX.value + "," + scrollY.value};
    1.38 +    }
    1.39 +
    1.40 +    return null;
    1.41 +  },
    1.42 +
    1.43 +  /**
    1.44 +   * Restores scroll position data for any given |frame| in the frame hierarchy.
    1.45 +   *
    1.46 +   * @param frame (DOMWindow)
    1.47 +   * @param value (object, see collect())
    1.48 +   */
    1.49 +  restore: function (frame, value) {
    1.50 +    let match;
    1.51 +
    1.52 +    if (value && (match = /(\d+),(\d+)/.exec(value))) {
    1.53 +      frame.scrollTo(match[1], match[2]);
    1.54 +    }
    1.55 +  },
    1.56 +
    1.57 +  /**
    1.58 +   * Restores scroll position data for the current frame hierarchy starting at
    1.59 +   * |root| using the given scroll position |data|.
    1.60 +   *
    1.61 +   * If the given |root| frame's hierarchy doesn't match that of the given
    1.62 +   * |data| object we will silently discard data for unreachable frames. We
    1.63 +   * may as well assign scroll positions to the wrong frames if some were
    1.64 +   * reordered or removed.
    1.65 +   *
    1.66 +   * @param root (DOMWindow)
    1.67 +   * @param data (object)
    1.68 +   *        {
    1.69 +   *          scroll: "100,200",
    1.70 +   *          children: [
    1.71 +   *            {scroll: "100,200"},
    1.72 +   *            null,
    1.73 +   *            {scroll: "200,300", children: [ ... ]}
    1.74 +   *          ]
    1.75 +   *        }
    1.76 +   */
    1.77 +  restoreTree: function (root, data) {
    1.78 +    if (data.hasOwnProperty("scroll")) {
    1.79 +      this.restore(root, data.scroll);
    1.80 +    }
    1.81 +
    1.82 +    if (!data.hasOwnProperty("children")) {
    1.83 +      return;
    1.84 +    }
    1.85 +
    1.86 +    let frames = root.frames;
    1.87 +    data.children.forEach((child, index) => {
    1.88 +      if (child && index < frames.length) {
    1.89 +        this.restoreTree(frames[index], child);
    1.90 +      }
    1.91 +    });
    1.92 +  }
    1.93 +});

mercurial