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

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial