summaryrefslogtreecommitdiffstats
path: root/devtools/client/shared/WeakMapMap.js
blob: 37eac656dc5f938de47b27e5d3ee925ef4a15d77 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/* 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/. */

/**
 * WeakMapMap is a weakmap collection dual-keyed using an object and a string.
 * This is useful for keeping data compartmentalized e.g. grouped by tab.
 *
 * It's name comes from the internal structure which maps a WeakMap to a map,
 * which contains the target data.
 *
 * Usage:
 *   const myWeakMapMap = new WeakMapMap();
 *   const key = { randomObject: true };
 *   myWeakMapMap.set(key, "text1", "Some value1");
 *   myWeakMapMap.set(key, "text2", "Some value2");
 *   myWeakMapMap.get(key, "text1"); // Returns "Some value1"
 *   myWeakMapMap.get(key, "text2"); // Returns "Some value2"
 *   myWeakMapMap.has(key, "text1"); // Returns true
 *   myWeakMapMap.has(key, "notakey"); // Returns false
 */

"use strict";

class WeakMapMap {
  constructor() {
    this.clear();
  }

  /**
   * Returns the value associated to the key and nestedKey, or undefined if
   * there is none.
   *
   * @param {Object} key
   *        The key associated with the desired value.
   * @param {String} nestedKey
   *        The nested key associated with the desired value.
   */
  get(key, nestedKey) {
    if (!this.has(key, nestedKey)) {
      return undefined;
    }

    return this.store.get(key).get(nestedKey);
  }

  /**
   * Returns the value associated to the key and nestedKey, or undefined if
   * there is none.
   *
   * @param {Object} key
   *        The key associated with the desired value.
   * @param {String} nestedKey
   *        The nested key associated with the desired value.
   */
  has(key, nestedKey) {
    const hasKey = this.store.has(key);

    return hasKey && this.store.get(key).has(nestedKey);
  }

  /**
   *
   * @param {Object} key
   *        The key associated with the value.
   * @param {String} nestedKey
   *        The nested key associated with the value.
   * @param {any} value
   *        The value to add.
   */
  set(key, nestedKey, value) {
    if (!this.store.has(key)) {
      this.store.set(key, new Map());
    }

    const innerMap = this.store.get(key);
    innerMap.set(nestedKey, value);
  }

  /**
   * Removes the value associated to the key and nestedKey.
   *
   * @param {Object} key
   *        The key associated with the desired value.
   * @param {String} nestedKey
   *        The nested key associated with the desired value.
   *
   * @returns True if an element in the store has been removed successfully.
   *          False if the key is not found in the store.
   */
  delete(key, nestedKey) {
    if (!this.store.has(key)) {
      return false;
    }

    return this.store.get(key).delete(nestedKey);
  }

  /**
   * Clear the store.
   */
  clear() {
    this.store = new WeakMap();
  }
}

module.exports = WeakMapMap;