1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/addon-sdk/source/lib/sdk/deprecated/list.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,126 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 +"use strict"; 1.8 + 1.9 +module.metadata = { 1.10 + "stability": "experimental" 1.11 +}; 1.12 + 1.13 +const { Trait } = require('../deprecated/traits'); 1.14 +const { iteratorSymbol } = require('../util/iteration'); 1.15 + 1.16 +/** 1.17 + * @see https://jetpack.mozillalabs.com/sdk/latest/docs/#module/api-utils/list 1.18 + */ 1.19 +const Iterable = Trait.compose({ 1.20 + /** 1.21 + * Hash map of key-values to iterate over. 1.22 + * Note: That this property can be a getter if you need dynamic behavior. 1.23 + * @type {Object} 1.24 + */ 1.25 + _keyValueMap: Trait.required, 1.26 + /** 1.27 + * Custom iterator providing `Iterable`s enumeration behavior. 1.28 + * @param {Boolean} onKeys 1.29 + */ 1.30 + __iterator__: function __iterator__(onKeys, onKeyValue) { 1.31 + let map = this._keyValueMap; 1.32 + for (let key in map) 1.33 + yield onKeyValue ? [key, map[key]] : onKeys ? key : map[key]; 1.34 + } 1.35 +}); 1.36 +exports.Iterable = Iterable; 1.37 + 1.38 +/** 1.39 + * An ordered collection (also known as a sequence) disallowing duplicate 1.40 + * elements. List is composed out of `Iterable` there for it provides custom 1.41 + * enumeration behavior that is similar to array (enumerates only on the 1.42 + * elements of the list). List is a base trait and is meant to be a part of 1.43 + * composition, since all of it's API is private except length property. 1.44 + */ 1.45 +const listOptions = { 1.46 + _keyValueMap: null, 1.47 + /** 1.48 + * List constructor can take any number of element to populate itself. 1.49 + * @params {Object|String|Number} element 1.50 + * @example 1.51 + * List(1,2,3).length == 3 // true 1.52 + */ 1.53 + constructor: function List() { 1.54 + this._keyValueMap = []; 1.55 + for (let i = 0, ii = arguments.length; i < ii; i++) 1.56 + this._add(arguments[i]); 1.57 + }, 1.58 + /** 1.59 + * Number of elements in this list. 1.60 + * @type {Number} 1.61 + */ 1.62 + get length() this._keyValueMap.length, 1.63 + /** 1.64 + * Returns a string representing this list. 1.65 + * @returns {String} 1.66 + */ 1.67 + toString: function toString() 'List(' + this._keyValueMap + ')', 1.68 + /** 1.69 + * Returns `true` if this list contains the specified `element`. 1.70 + * @param {Object|Number|String} element 1.71 + * @returns {Boolean} 1.72 + */ 1.73 + _has: function _has(element) 0 <= this._keyValueMap.indexOf(element), 1.74 + /** 1.75 + * Appends the specified `element` to the end of this list, if it doesn't 1.76 + * contains it. Ignores the call if `element` is already contained. 1.77 + * @param {Object|Number|String} element 1.78 + */ 1.79 + _add: function _add(element) { 1.80 + let list = this._keyValueMap, 1.81 + index = list.indexOf(element); 1.82 + if (0 > index) 1.83 + list.push(this._public[list.length] = element); 1.84 + }, 1.85 + /** 1.86 + * Removes specified `element` from this list, if it contains it. 1.87 + * Ignores the call if `element` is not contained. 1.88 + * @param {Object|Number|String} element 1.89 + */ 1.90 + _remove: function _remove(element) { 1.91 + let list = this._keyValueMap, 1.92 + index = list.indexOf(element); 1.93 + if (0 <= index) { 1.94 + delete this._public[list.length - 1]; 1.95 + list.splice(index, 1); 1.96 + for (let length = list.length; index < length; index++) 1.97 + this._public[index] = list[index]; 1.98 + } 1.99 + }, 1.100 + /** 1.101 + * Removes all of the elements from this list. 1.102 + */ 1.103 + _clear: function _clear() { 1.104 + for (let i = 0, ii = this._keyValueMap.length; i < ii; i ++) 1.105 + delete this._public[i]; 1.106 + this._keyValueMap.splice(0); 1.107 + }, 1.108 + /** 1.109 + * Custom iterator providing `List`s enumeration behavior. 1.110 + * We cant reuse `_iterator` that is defined by `Iterable` since it provides 1.111 + * iteration in an arbitrary order. 1.112 + * @see https://developer.mozilla.org/en/JavaScript/Reference/Statements/for...in 1.113 + * @param {Boolean} onKeys 1.114 + */ 1.115 + __iterator__: function __iterator__(onKeys, onKeyValue) { 1.116 + let array = this._keyValueMap.slice(0), 1.117 + i = -1; 1.118 + for (let element of array) 1.119 + yield onKeyValue ? [++i, element] : onKeys ? ++i : element; 1.120 + }, 1.121 +}; 1.122 +listOptions[iteratorSymbol] = function* iterator() { 1.123 + let array = this._keyValueMap.slice(0); 1.124 + 1.125 + for (let element of array) 1.126 + yield element; 1.127 +} 1.128 +const List = Trait.resolve({ toString: null }).compose(listOptions); 1.129 +exports.List = List;