tor-browser

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

shell.js (2992B)


      1 /*---
      2 defines: [assertSetContainsExactOrderedItems, SetLike, SetIteratorLike, LoggingProxy]
      3 allow_unused: True
      4 ---*/
      5 (function(global) {
      6  // Save the primordial values.
      7  const {Array, Error, Object, Proxy, Reflect, Set} = global;
      8 
      9  const ArrayIsArray = Array.isArray;
     10  const ReflectApply = Reflect.apply;
     11  const ReflectDefineProperty = Reflect.defineProperty;
     12  const ReflectGet = Reflect.get;
     13  const ReflectGetPrototypeOf = Reflect.getPrototypeOf;
     14  const SetPrototype = Set.prototype;
     15  const SetPrototypeHas = SetPrototype.has;
     16  const SetPrototypeSize = Object.getOwnPropertyDescriptor(SetPrototype, "size").get;
     17  const SetPrototypeKeys = SetPrototype.keys;
     18  const SetIteratorPrototypeNext = new Set().values().next;
     19 
     20  function assertSetContainsExactOrderedItems(actual, expected) {
     21    assertEq(ReflectGetPrototypeOf(actual), SetPrototype, "actual is a native Set object");
     22    assertEq(ArrayIsArray(expected), true, "expected is an Array object");
     23 
     24    assertEq(ReflectApply(SetPrototypeSize, actual, []), expected.length);
     25 
     26    let index = 0;
     27    let keys = ReflectApply(SetPrototypeKeys, actual, []);
     28 
     29    while (true) {
     30      let {done, value: item} = ReflectApply(SetIteratorPrototypeNext, keys, []);
     31      if (done) {
     32        break;
     33      }
     34      assertEq(item, expected[index], `Element at index ${index}:`);
     35      index++;
     36    }
     37  }
     38  global.assertSetContainsExactOrderedItems = assertSetContainsExactOrderedItems;
     39 
     40  class SetLike {
     41    #set;
     42 
     43    constructor(values) {
     44      this.#set = new Set(values);
     45    }
     46 
     47    get size() {
     48      return ReflectApply(SetPrototypeSize, this.#set, []);
     49    }
     50 
     51    has(value) {
     52      return ReflectApply(SetPrototypeHas, this.#set, [value]);
     53    }
     54 
     55    keys() {
     56      let keys = ReflectApply(SetPrototypeKeys, this.#set, []);
     57      return new SetIteratorLike(keys);
     58    }
     59  }
     60  global.SetLike = SetLike;
     61 
     62  class SetIteratorLike {
     63    #keys;
     64 
     65    constructor(keys) {
     66      this.#keys = keys;
     67    }
     68 
     69    next() {
     70      return ReflectApply(SetIteratorPrototypeNext, this.#keys, []);
     71    }
     72 
     73    // The |return| method of the iterator protocol is never called.
     74    return() {
     75      throw new Error("Unexpected call to |return| method");
     76    }
     77 
     78    // The |throw| method of the iterator protocol is never called.
     79    throw() {
     80      throw new Error("Unexpected call to |throw| method");
     81    }
     82  }
     83 
     84  function LoggingProxy(obj, log) {
     85    assertEq(ArrayIsArray(log), true);
     86 
     87    let handler = new Proxy({
     88      get(t, pk, r) {
     89        ReflectDefineProperty(log, log.length, {
     90          value: pk, writable: true, enumerable: true, configurable: true,
     91        });
     92        return ReflectGet(t, pk, r);
     93      }
     94    }, {
     95      get(t, pk, r) {
     96        ReflectDefineProperty(log, log.length, {
     97          value: `[[${pk}]]`, writable: true, enumerable: true, configurable: true,
     98        });
     99        return ReflectGet(t, pk, r);
    100      }
    101    });
    102 
    103    return {obj, proxy: new Proxy(obj, handler)};
    104  }
    105  global.LoggingProxy = LoggingProxy;
    106 })(this);