bsl
Version:
基于React的框架和UI组件
90 lines (77 loc) • 2.53 kB
text/typescript
/* @flow */
const MAP_EXISTS = typeof Map !== 'undefined';
export default class OrderedElements {
/* ::
elements: {[string]: any};
keyOrder: string[];
*/
constructor() {
this.elements = {};
this.keyOrder = [];
}
public elements: Record<string, any>;
public keyOrder: string[];
forEach(callback: (key: string, value: 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: string, key: string) => {
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: string, key: string) => {
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);
}
}
}
}