|
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'; |
|
5 |
|
6 module.metadata = { |
|
7 "stability": "experimental" |
|
8 }; |
|
9 |
|
10 const { Class } = require('../core/heritage'); |
|
11 const listNS = require('../core/namespace').ns(); |
|
12 const { iteratorSymbol } = require('../util/iteration'); |
|
13 |
|
14 const listOptions = { |
|
15 /** |
|
16 * List constructor can take any number of element to populate itself. |
|
17 * @params {Object|String|Number} element |
|
18 * @example |
|
19 * List(1,2,3).length == 3 // true |
|
20 */ |
|
21 initialize: function List() { |
|
22 listNS(this).keyValueMap = []; |
|
23 |
|
24 for (let i = 0, ii = arguments.length; i < ii; i++) |
|
25 addListItem(this, arguments[i]); |
|
26 }, |
|
27 /** |
|
28 * Number of elements in this list. |
|
29 * @type {Number} |
|
30 */ |
|
31 get length() listNS(this).keyValueMap.length, |
|
32 /** |
|
33 * Returns a string representing this list. |
|
34 * @returns {String} |
|
35 */ |
|
36 toString: function toString() 'List(' + listNS(this).keyValueMap + ')', |
|
37 /** |
|
38 * Custom iterator providing `List`s enumeration behavior. |
|
39 * We cant reuse `_iterator` that is defined by `Iterable` since it provides |
|
40 * iteration in an arbitrary order. |
|
41 * @see https://developer.mozilla.org/en/JavaScript/Reference/Statements/for...in |
|
42 * @param {Boolean} onKeys |
|
43 */ |
|
44 __iterator__: function __iterator__(onKeys, onKeyValue) { |
|
45 let array = listNS(this).keyValueMap.slice(0), |
|
46 i = -1; |
|
47 for each(let element in array) |
|
48 yield onKeyValue ? [++i, element] : onKeys ? ++i : element; |
|
49 }, |
|
50 }; |
|
51 listOptions[iteratorSymbol] = function iterator() { |
|
52 return listNS(this).keyValueMap.slice(0)[iteratorSymbol](); |
|
53 }; |
|
54 const List = Class(listOptions); |
|
55 exports.List = List; |
|
56 |
|
57 function addListItem(that, value) { |
|
58 let list = listNS(that).keyValueMap, |
|
59 index = list.indexOf(value); |
|
60 |
|
61 if (-1 === index) { |
|
62 try { |
|
63 that[that.length] = value; |
|
64 } |
|
65 catch (e) {} |
|
66 list.push(value); |
|
67 } |
|
68 } |
|
69 exports.addListItem = addListItem; |
|
70 |
|
71 function removeListItem(that, element) { |
|
72 let list = listNS(that).keyValueMap, |
|
73 index = list.indexOf(element); |
|
74 |
|
75 if (0 <= index) { |
|
76 list.splice(index, 1); |
|
77 try { |
|
78 for (let length = list.length; index < length; index++) |
|
79 that[index] = list[index]; |
|
80 that[list.length] = undefined; |
|
81 } |
|
82 catch(e){} |
|
83 } |
|
84 } |
|
85 exports.removeListItem = removeListItem; |
|
86 |
|
87 exports.listNS = listNS; |