addon-sdk/source/lib/sdk/deprecated/list.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4 "use strict";
michael@0 5
michael@0 6 module.metadata = {
michael@0 7 "stability": "experimental"
michael@0 8 };
michael@0 9
michael@0 10 const { Trait } = require('../deprecated/traits');
michael@0 11 const { iteratorSymbol } = require('../util/iteration');
michael@0 12
michael@0 13 /**
michael@0 14 * @see https://jetpack.mozillalabs.com/sdk/latest/docs/#module/api-utils/list
michael@0 15 */
michael@0 16 const Iterable = Trait.compose({
michael@0 17 /**
michael@0 18 * Hash map of key-values to iterate over.
michael@0 19 * Note: That this property can be a getter if you need dynamic behavior.
michael@0 20 * @type {Object}
michael@0 21 */
michael@0 22 _keyValueMap: Trait.required,
michael@0 23 /**
michael@0 24 * Custom iterator providing `Iterable`s enumeration behavior.
michael@0 25 * @param {Boolean} onKeys
michael@0 26 */
michael@0 27 __iterator__: function __iterator__(onKeys, onKeyValue) {
michael@0 28 let map = this._keyValueMap;
michael@0 29 for (let key in map)
michael@0 30 yield onKeyValue ? [key, map[key]] : onKeys ? key : map[key];
michael@0 31 }
michael@0 32 });
michael@0 33 exports.Iterable = Iterable;
michael@0 34
michael@0 35 /**
michael@0 36 * An ordered collection (also known as a sequence) disallowing duplicate
michael@0 37 * elements. List is composed out of `Iterable` there for it provides custom
michael@0 38 * enumeration behavior that is similar to array (enumerates only on the
michael@0 39 * elements of the list). List is a base trait and is meant to be a part of
michael@0 40 * composition, since all of it's API is private except length property.
michael@0 41 */
michael@0 42 const listOptions = {
michael@0 43 _keyValueMap: null,
michael@0 44 /**
michael@0 45 * List constructor can take any number of element to populate itself.
michael@0 46 * @params {Object|String|Number} element
michael@0 47 * @example
michael@0 48 * List(1,2,3).length == 3 // true
michael@0 49 */
michael@0 50 constructor: function List() {
michael@0 51 this._keyValueMap = [];
michael@0 52 for (let i = 0, ii = arguments.length; i < ii; i++)
michael@0 53 this._add(arguments[i]);
michael@0 54 },
michael@0 55 /**
michael@0 56 * Number of elements in this list.
michael@0 57 * @type {Number}
michael@0 58 */
michael@0 59 get length() this._keyValueMap.length,
michael@0 60 /**
michael@0 61 * Returns a string representing this list.
michael@0 62 * @returns {String}
michael@0 63 */
michael@0 64 toString: function toString() 'List(' + this._keyValueMap + ')',
michael@0 65 /**
michael@0 66 * Returns `true` if this list contains the specified `element`.
michael@0 67 * @param {Object|Number|String} element
michael@0 68 * @returns {Boolean}
michael@0 69 */
michael@0 70 _has: function _has(element) 0 <= this._keyValueMap.indexOf(element),
michael@0 71 /**
michael@0 72 * Appends the specified `element` to the end of this list, if it doesn't
michael@0 73 * contains it. Ignores the call if `element` is already contained.
michael@0 74 * @param {Object|Number|String} element
michael@0 75 */
michael@0 76 _add: function _add(element) {
michael@0 77 let list = this._keyValueMap,
michael@0 78 index = list.indexOf(element);
michael@0 79 if (0 > index)
michael@0 80 list.push(this._public[list.length] = element);
michael@0 81 },
michael@0 82 /**
michael@0 83 * Removes specified `element` from this list, if it contains it.
michael@0 84 * Ignores the call if `element` is not contained.
michael@0 85 * @param {Object|Number|String} element
michael@0 86 */
michael@0 87 _remove: function _remove(element) {
michael@0 88 let list = this._keyValueMap,
michael@0 89 index = list.indexOf(element);
michael@0 90 if (0 <= index) {
michael@0 91 delete this._public[list.length - 1];
michael@0 92 list.splice(index, 1);
michael@0 93 for (let length = list.length; index < length; index++)
michael@0 94 this._public[index] = list[index];
michael@0 95 }
michael@0 96 },
michael@0 97 /**
michael@0 98 * Removes all of the elements from this list.
michael@0 99 */
michael@0 100 _clear: function _clear() {
michael@0 101 for (let i = 0, ii = this._keyValueMap.length; i < ii; i ++)
michael@0 102 delete this._public[i];
michael@0 103 this._keyValueMap.splice(0);
michael@0 104 },
michael@0 105 /**
michael@0 106 * Custom iterator providing `List`s enumeration behavior.
michael@0 107 * We cant reuse `_iterator` that is defined by `Iterable` since it provides
michael@0 108 * iteration in an arbitrary order.
michael@0 109 * @see https://developer.mozilla.org/en/JavaScript/Reference/Statements/for...in
michael@0 110 * @param {Boolean} onKeys
michael@0 111 */
michael@0 112 __iterator__: function __iterator__(onKeys, onKeyValue) {
michael@0 113 let array = this._keyValueMap.slice(0),
michael@0 114 i = -1;
michael@0 115 for (let element of array)
michael@0 116 yield onKeyValue ? [++i, element] : onKeys ? ++i : element;
michael@0 117 },
michael@0 118 };
michael@0 119 listOptions[iteratorSymbol] = function* iterator() {
michael@0 120 let array = this._keyValueMap.slice(0);
michael@0 121
michael@0 122 for (let element of array)
michael@0 123 yield element;
michael@0 124 }
michael@0 125 const List = Trait.resolve({ toString: null }).compose(listOptions);
michael@0 126 exports.List = List;

mercurial