You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							88 lines
						
					
					
						
							2.2 KiB
						
					
					
				
			
		
		
	
	
							88 lines
						
					
					
						
							2.2 KiB
						
					
					
				
 | 
						|
module.exports = ProtoList | 
						|
 | 
						|
function setProto(obj, proto) { | 
						|
  if (typeof Object.setPrototypeOf === "function") | 
						|
    return Object.setPrototypeOf(obj, proto) | 
						|
  else | 
						|
    obj.__proto__ = proto | 
						|
} | 
						|
 | 
						|
function ProtoList () { | 
						|
  this.list = [] | 
						|
  var root = null | 
						|
  Object.defineProperty(this, 'root', { | 
						|
    get: function () { return root }, | 
						|
    set: function (r) { | 
						|
      root = r | 
						|
      if (this.list.length) { | 
						|
        setProto(this.list[this.list.length - 1], r) | 
						|
      } | 
						|
    }, | 
						|
    enumerable: true, | 
						|
    configurable: true | 
						|
  }) | 
						|
} | 
						|
 | 
						|
ProtoList.prototype = | 
						|
  { get length () { return this.list.length } | 
						|
  , get keys () { | 
						|
      var k = [] | 
						|
      for (var i in this.list[0]) k.push(i) | 
						|
      return k | 
						|
    } | 
						|
  , get snapshot () { | 
						|
      var o = {} | 
						|
      this.keys.forEach(function (k) { o[k] = this.get(k) }, this) | 
						|
      return o | 
						|
    } | 
						|
  , get store () { | 
						|
      return this.list[0] | 
						|
    } | 
						|
  , push : function (obj) { | 
						|
      if (typeof obj !== "object") obj = {valueOf:obj} | 
						|
      if (this.list.length >= 1) { | 
						|
        setProto(this.list[this.list.length - 1], obj) | 
						|
      } | 
						|
      setProto(obj, this.root) | 
						|
      return this.list.push(obj) | 
						|
    } | 
						|
  , pop : function () { | 
						|
      if (this.list.length >= 2) { | 
						|
        setProto(this.list[this.list.length - 2], this.root) | 
						|
      } | 
						|
      return this.list.pop() | 
						|
    } | 
						|
  , unshift : function (obj) { | 
						|
      setProto(obj, this.list[0] || this.root) | 
						|
      return this.list.unshift(obj) | 
						|
    } | 
						|
  , shift : function () { | 
						|
      if (this.list.length === 1) { | 
						|
        setProto(this.list[0], this.root) | 
						|
      } | 
						|
      return this.list.shift() | 
						|
    } | 
						|
  , get : function (key) { | 
						|
      return this.list[0][key] | 
						|
    } | 
						|
  , set : function (key, val, save) { | 
						|
      if (!this.length) this.push({}) | 
						|
      if (save && this.list[0].hasOwnProperty(key)) this.push({}) | 
						|
      return this.list[0][key] = val | 
						|
    } | 
						|
  , forEach : function (fn, thisp) { | 
						|
      for (var key in this.list[0]) fn.call(thisp, key, this.list[0][key]) | 
						|
    } | 
						|
  , slice : function () { | 
						|
      return this.list.slice.apply(this.list, arguments) | 
						|
    } | 
						|
  , splice : function () { | 
						|
      // handle injections | 
						|
      var ret = this.list.splice.apply(this.list, arguments) | 
						|
      for (var i = 0, l = this.list.length; i < l; i++) { | 
						|
        setProto(this.list[i], this.list[i + 1] || this.root) | 
						|
      } | 
						|
      return ret | 
						|
    } | 
						|
  }
 | 
						|
 |