tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

TabStateCache.sys.mjs (4852B)


      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 file,
      3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 /**
      6 * A cache for tabs data.
      7 *
      8 * This cache implements a weak map from tabs (as XUL elements)
      9 * to tab data (as objects).
     10 *
     11 * Note that we should never cache private data, as:
     12 * - that data is used very seldom by SessionStore;
     13 * - caching private data in addition to public data is memory consuming.
     14 */
     15 export var TabStateCache = Object.freeze({
     16  /**
     17   * Retrieves cached data for a given |tab| or associated |browser|.
     18   *
     19   * @param permanentKey (object)
     20   *        The tab or browser to retrieve cached data for.
     21   * @return (object)
     22   *         The cached data stored for the given |tab|
     23   *         or associated |browser|.
     24   */
     25  get(permanentKey) {
     26    return TabStateCacheInternal.get(permanentKey);
     27  },
     28 
     29  /**
     30   * Updates cached data for a given |tab| or associated |browser|.
     31   *
     32   * @param permanentKey (object)
     33   *        The tab or browser belonging to the given tab data.
     34   * @param newData (object)
     35   *        The new data to be stored for the given |tab|
     36   *        or associated |browser|.
     37   */
     38  update(permanentKey, newData) {
     39    TabStateCacheInternal.update(permanentKey, newData);
     40  },
     41 });
     42 
     43 var TabStateCacheInternal = {
     44  _data: new WeakMap(),
     45 
     46  /**
     47   * Retrieves cached data for a given |tab| or associated |browser|.
     48   *
     49   * @param permanentKey (object)
     50   *        The tab or browser to retrieve cached data for.
     51   * @return (object)
     52   *         The cached data stored for the given |tab|
     53   *         or associated |browser|.
     54   */
     55  get(permanentKey) {
     56    return this._data.get(permanentKey);
     57  },
     58 
     59  /**
     60   * Helper function used by update (see below). For message size
     61   * optimization sometimes we don't update the whole session storage
     62   * only the values that have been changed.
     63   *
     64   * @param data (object)
     65   *        The cached data where we want to update the changes.
     66   * @param change (object)
     67   *        The actual changed values per domain.
     68   */
     69  updatePartialStorageChange(data, change) {
     70    if (!data.storage) {
     71      data.storage = {};
     72    }
     73 
     74    let storage = data.storage;
     75    for (let domain of Object.keys(change)) {
     76      if (!change[domain]) {
     77        // We were sent null in place of the change object, which means
     78        // we should delete session storage entirely for this domain.
     79        delete storage[domain];
     80      } else {
     81        for (let key of Object.keys(change[domain])) {
     82          let value = change[domain][key];
     83          if (value === null) {
     84            if (storage[domain] && storage[domain][key]) {
     85              delete storage[domain][key];
     86            }
     87          } else {
     88            if (!storage[domain]) {
     89              storage[domain] = {};
     90            }
     91            storage[domain][key] = value;
     92          }
     93        }
     94      }
     95    }
     96  },
     97 
     98  /**
     99   * Helper function used by update (see below). For message size
    100   * optimization sometimes we don't update the whole browser history
    101   * only the current index and the tail of the history from a certain
    102   * index (specified by change.fromIdx)
    103   *
    104   * @param data (object)
    105   *        The cached data where we want to update the changes.
    106   * @param change (object)
    107   *        Object containing the tail of the history array, and
    108   *        some additional metadata.
    109   */
    110  updatePartialHistoryChange(data, change) {
    111    const kLastIndex = Number.MAX_SAFE_INTEGER - 1;
    112 
    113    if (!data.history) {
    114      data.history = { entries: [] };
    115    }
    116 
    117    let history = data.history;
    118    for (let key of Object.keys(change)) {
    119      if (key == "entries") {
    120        if (change.fromIdx != kLastIndex) {
    121          let start = change.fromIdx + 1;
    122          history.entries.splice(start, Infinity, ...change.entries);
    123        }
    124      } else if (key != "fromIdx") {
    125        history[key] = change[key];
    126      }
    127    }
    128  },
    129 
    130  /**
    131   * Updates cached data for a given |tab| or associated |browser|.
    132   *
    133   * @param permanentKey (object)
    134   *        The tab or browser belonging to the given tab data.
    135   * @param newData (object)
    136   *        The new data to be stored for the given permanent key.
    137   */
    138  update(permanentKey, newData) {
    139    let data = this._data.get(permanentKey) || {};
    140 
    141    for (let key of Object.keys(newData)) {
    142      if (key == "storagechange") {
    143        this.updatePartialStorageChange(data, newData.storagechange);
    144        continue;
    145      }
    146 
    147      if (key == "historychange") {
    148        this.updatePartialHistoryChange(data, newData.historychange);
    149        continue;
    150      }
    151 
    152      let value = newData[key];
    153      if (value === null) {
    154        delete data[key];
    155      } else {
    156        data[key] = value;
    157      }
    158    }
    159 
    160    this._data.set(permanentKey, data);
    161  },
    162 };