86 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			86 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
'use strict';
 | 
						|
var redefineAll = require('./_redefine-all');
 | 
						|
var getWeak = require('./_meta').getWeak;
 | 
						|
var anObject = require('./_an-object');
 | 
						|
var isObject = require('./_is-object');
 | 
						|
var anInstance = require('./_an-instance');
 | 
						|
var forOf = require('./_for-of');
 | 
						|
var createArrayMethod = require('./_array-methods');
 | 
						|
var $has = require('./_has');
 | 
						|
var validate = require('./_validate-collection');
 | 
						|
var arrayFind = createArrayMethod(5);
 | 
						|
var arrayFindIndex = createArrayMethod(6);
 | 
						|
var id = 0;
 | 
						|
 | 
						|
// fallback for uncaught frozen keys
 | 
						|
var uncaughtFrozenStore = function (that) {
 | 
						|
  return that._l || (that._l = new UncaughtFrozenStore());
 | 
						|
};
 | 
						|
var UncaughtFrozenStore = function () {
 | 
						|
  this.a = [];
 | 
						|
};
 | 
						|
var findUncaughtFrozen = function (store, key) {
 | 
						|
  return arrayFind(store.a, function (it) {
 | 
						|
    return it[0] === key;
 | 
						|
  });
 | 
						|
};
 | 
						|
UncaughtFrozenStore.prototype = {
 | 
						|
  get: function (key) {
 | 
						|
    var entry = findUncaughtFrozen(this, key);
 | 
						|
    if (entry) return entry[1];
 | 
						|
  },
 | 
						|
  has: function (key) {
 | 
						|
    return !!findUncaughtFrozen(this, key);
 | 
						|
  },
 | 
						|
  set: function (key, value) {
 | 
						|
    var entry = findUncaughtFrozen(this, key);
 | 
						|
    if (entry) entry[1] = value;
 | 
						|
    else this.a.push([key, value]);
 | 
						|
  },
 | 
						|
  'delete': function (key) {
 | 
						|
    var index = arrayFindIndex(this.a, function (it) {
 | 
						|
      return it[0] === key;
 | 
						|
    });
 | 
						|
    if (~index) this.a.splice(index, 1);
 | 
						|
    return !!~index;
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
module.exports = {
 | 
						|
  getConstructor: function (wrapper, NAME, IS_MAP, ADDER) {
 | 
						|
    var C = wrapper(function (that, iterable) {
 | 
						|
      anInstance(that, C, NAME, '_i');
 | 
						|
      that._t = NAME;      // collection type
 | 
						|
      that._i = id++;      // collection id
 | 
						|
      that._l = undefined; // leak store for uncaught frozen objects
 | 
						|
      if (iterable != undefined) forOf(iterable, IS_MAP, that[ADDER], that);
 | 
						|
    });
 | 
						|
    redefineAll(C.prototype, {
 | 
						|
      // 23.3.3.2 WeakMap.prototype.delete(key)
 | 
						|
      // 23.4.3.3 WeakSet.prototype.delete(value)
 | 
						|
      'delete': function (key) {
 | 
						|
        if (!isObject(key)) return false;
 | 
						|
        var data = getWeak(key);
 | 
						|
        if (data === true) return uncaughtFrozenStore(validate(this, NAME))['delete'](key);
 | 
						|
        return data && $has(data, this._i) && delete data[this._i];
 | 
						|
      },
 | 
						|
      // 23.3.3.4 WeakMap.prototype.has(key)
 | 
						|
      // 23.4.3.4 WeakSet.prototype.has(value)
 | 
						|
      has: function has(key) {
 | 
						|
        if (!isObject(key)) return false;
 | 
						|
        var data = getWeak(key);
 | 
						|
        if (data === true) return uncaughtFrozenStore(validate(this, NAME)).has(key);
 | 
						|
        return data && $has(data, this._i);
 | 
						|
      }
 | 
						|
    });
 | 
						|
    return C;
 | 
						|
  },
 | 
						|
  def: function (that, key, value) {
 | 
						|
    var data = getWeak(anObject(key), true);
 | 
						|
    if (data === true) uncaughtFrozenStore(that).set(key, value);
 | 
						|
    else data[that._i] = value;
 | 
						|
    return that;
 | 
						|
  },
 | 
						|
  ufstore: uncaughtFrozenStore
 | 
						|
};
 |