/*
* Copyright 2017, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
function transform({obj, kind, name, children, timestamp, rect, bounds, highlight, rects_transform, chips, visible, flattened, stableId}) {
function call(fn, arg) {
return (typeof fn == 'function') ? fn(arg) : fn;
}
function handle_children(arg, transform) {
return [].concat(...arg.map((item) => {
var childrenFunc = item[0];
var transformFunc = item[1];
var childs = call(childrenFunc, obj);
if (childs) {
if (typeof childs.map != 'function'){
throw 'Childs should be an array, but is: ' + (typeof childs) + '.'
}
return transform ? childs.map(transformFunc) : childs;
} else {
return [];
}
}));
}
function concat(arg, args, argsmap) {
var validArg = arg !== undefined && arg !== null;
if (Array.isArray(args)) {
if (validArg) {
return [arg].concat(...args.map(argsmap));
} else {
return [].concat(...args.map(argsmap));
}
} else if (validArg) {
return [arg];
} else {
return undefined;
}
}
var transformed_children = handle_children(children, true /* transform */);
rects_transform = (rects_transform === undefined) ? (e) => e : rects_transform;
var kindResolved = call(kind, obj);
var nameResolved = call(name, obj);
var rectResolved = call(rect, obj);
var stableIdResolved = (stableId === undefined) ?
kindResolved + '|-|' + nameResolved :
call(stableId, obj);
var result = {
kind: kindResolved,
name: nameResolved,
children: transformed_children,
obj: obj,
timestamp: call(timestamp, obj),
skip: handle_children(children, false /* transform */),
bounds: call(bounds, obj) || transformed_children.map((e) => e.bounds).find((e) => true) || undefined,
rect: rectResolved,
rects: rects_transform(concat(rectResolved, transformed_children, (e) => e.rects)),
highlight: call(highlight, obj),
chips: call(chips, obj),
stableId: stableIdResolved,
visible: call(visible, obj),
childrenVisible: transformed_children.some((c) => {
return c.childrenVisible || c.visible
}),
flattened: call(flattened, obj),
};
if (rectResolved) {
rectResolved.ref = result;
}
return Object.freeze(result);
}
function transform_json(obj, name, options) {
let {skip, formatter} = options;
var children = [];
var formatted = undefined;
if (skip && skip.includes(obj)) {
// skip
} else if ((formatted = formatter(obj))) {
children.push(transform_json(null, formatted, options));
} else if (Array.isArray(obj)) {
obj.forEach((e, i) => {
children.push(transform_json(e, ""+i, options));
})
} else if (typeof obj == 'string') {
children.push(transform_json(null, obj, options));
} else if (typeof obj == 'number' || typeof obj == 'boolean') {
children.push(transform_json(null, ""+obj, options));
} else if (obj && typeof obj == 'object') {
Object.keys(obj).forEach((key) => {
children.push(transform_json(obj[key], key, options));
});
}
if (children.length == 1 && !children[0].combined) {
return Object.freeze({
kind: "",
name: name + ": " + children[0].name,
children: children[0].children,
combined: true
});
}
return Object.freeze({
kind: "",
name: name,
children: children,
});
}
function nanos_to_string(elapsedRealtimeNanos) {
var units = [
[1000000, '(ns)'],
[1000, 'ms'],
[60, 's'],
[60, 'm'],
[24, 'h'],
[Infinity, 'd'],
];
var parts = []
units.some(([div, str], i) => {
var part = (elapsedRealtimeNanos % div).toFixed()
if (!str.startsWith('(')) {
parts.push(part + str);
}
elapsedRealtimeNanos = Math.floor(elapsedRealtimeNanos / div);
return elapsedRealtimeNanos == 0;
});
return parts.reverse().join('');
}
// Returns a UI element used highlight a visible entry.
function get_visible_chip() {
return {short: 'V', long: "visible", class: 'default'};
}
export {transform, transform_json, nanos_to_string, get_visible_chip};