UNPKG

2.82 kBJavaScriptView Raw
1/* @flow */
2const MAP_EXISTS = typeof Map !== 'undefined';
3
4export default class OrderedElements {
5 /* ::
6 elements: {[string]: any};
7 keyOrder: string[];
8 */
9
10 constructor() {
11 this.elements = {};
12 this.keyOrder = [];
13 }
14
15 forEach(callback /* : (string, any) => void */) {
16 for (let i = 0; i < this.keyOrder.length; i++) {
17 // (value, key) to match Map's API
18 callback(this.elements[this.keyOrder[i]], this.keyOrder[i]);
19 }
20 }
21
22 set(key /* : string */, value /* : any */, shouldReorder /* : ?boolean */) {
23 if (!this.elements.hasOwnProperty(key)) {
24 this.keyOrder.push(key);
25 } else if (shouldReorder) {
26 const index = this.keyOrder.indexOf(key);
27 this.keyOrder.splice(index, 1);
28 this.keyOrder.push(key);
29 }
30
31 if (value == null) {
32 this.elements[key] = value;
33 return;
34 }
35
36 if ((MAP_EXISTS && value instanceof Map) || value instanceof OrderedElements) {
37 // We have found a nested Map, so we need to recurse so that all
38 // of the nested objects and Maps are merged properly.
39 const nested = this.elements.hasOwnProperty(key)
40 ? this.elements[key]
41 : new OrderedElements();
42 value.forEach((value, key) => {
43 nested.set(key, value, shouldReorder);
44 });
45 this.elements[key] = nested;
46 return;
47 }
48
49 if (!Array.isArray(value) && typeof value === 'object') {
50 // We have found a nested object, so we need to recurse so that all
51 // of the nested objects and Maps are merged properly.
52 const nested = this.elements.hasOwnProperty(key)
53 ? this.elements[key]
54 : new OrderedElements();
55 const keys = Object.keys(value);
56 for (let i = 0; i < keys.length; i += 1) {
57 nested.set(keys[i], value[keys[i]], shouldReorder);
58 }
59 this.elements[key] = nested;
60 return;
61 }
62
63 this.elements[key] = value;
64 }
65
66 get(key /* : string */) /* : any */ {
67 return this.elements[key];
68 }
69
70 has(key /* : string */) /* : boolean */ {
71 return this.elements.hasOwnProperty(key);
72 }
73
74 addStyleType(styleType /* : any */) /* : void */ {
75 if ((MAP_EXISTS && styleType instanceof Map) || styleType instanceof OrderedElements) {
76 styleType.forEach((value, key) => {
77 this.set(key, value, true);
78 });
79 } else {
80 const keys = Object.keys(styleType);
81 for (let i = 0; i < keys.length; i++) {
82 this.set(keys[i], styleType[keys[i]], true);
83 }
84 }
85 }
86}