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