import * as _ from './is';
import { Json2htmlOptions } from '../types';
function toggleJS(options?: Json2htmlOptions): string {
if (options?.plainHtml) {
return '';
} else {
return 'onclick="json-to-html.toggleVisibility(this);return false"';
}
}
function makeLabelDiv(options: any, level: number, keyName: string | number, datatype?: string): string {
if (typeof keyName === 'number') {
return `
${keyName}
`;
} else if (typeof keyName === 'string') {
if (datatype === 'array') {
return `${keyName}
`;
} else if (datatype === 'object') {
return `${keyName}:
`;
} else {
return `${keyName}:
`;
}
} else {
return '';
}
}
function getContentClass(keyName: string | number): string {
if (typeof keyName === 'string') {
return 'content';
} else {
return '';
}
}
function isPlainObject(val: any): boolean {
let lastKey: string | undefined;
let lastOwnKey: string | undefined;
for (const key in val) {
if (val.hasOwnProperty(key)) {
lastOwnKey = key;
}
}
for (const key in val) {
lastKey = key;
}
return lastOwnKey === lastKey;
}
function isLeafValue(val: any): boolean {
return (
_.isNumber(val) ||
_.isString(val) ||
_.isBoolean(val) ||
_.isDate(val) ||
_.isNull(val) ||
_.isUndefined(val) ||
isNaN(val) ||
_.isFunction(val) ||
!isPlainObject(val)
);
}
function isLeafObject(obj: any): boolean {
if (!_.isObject(obj)) {
return false;
}
for (const key in obj) {
const val = obj[key];
if (!isLeafValue(val)) {
return false;
}
}
return true;
}
function isTable(arr: any[]): boolean {
if (!_.isArray(arr)) {
return false;
}
if (arr.length === 0 || !_.isObject(arr[0])) {
return false;
} else {
let nonCompliant = arr.find(row => !isLeafObject(row));
if (nonCompliant) {
return false;
} else {
const cols = Object.keys(arr[0]);
nonCompliant = arr.find((row: object) => !_.isEqual(cols, Object.keys(row)));
if (nonCompliant) {
return false;
} else {
return true;
}
}
}
}
function drawTable(arr: any[]): string {
function drawRow(headers: string[], rowObj: any): string {
return '' + headers.map(header => rowObj[header]).join(' | ') + ' | ';
}
const cols = Object.keys(arr[0]);
const content = arr.map(rowObj => drawRow(cols, rowObj));
const headingHtml = '' + cols.join(' | ') + ' |
';
const contentHtml = '' + content.join('
') + '
';
return '' + headingHtml + contentHtml + '
';
}
function _render(name: string, data: any, options: Json2htmlOptions, level: number, altRow: number): string {
const contentClass = getContentClass(name);
if (_.isArray(data)) {
const title = makeLabelDiv(options, level, `${name}`, 'array');
let subs: string;
if (isTable(data)) {
subs = drawTable(data);
} else {
subs =
"" +
data
.map((val: any, idx: number) => _render(idx.toString(), val, options, level + 1, idx % 2))
.join("
") +
'
';
}
return ``;
} else if (isLeafValue(data)) {
const title = makeLabelDiv(options, level, name);
if (_.isFunction(data)) {
return `${title} -function() can't _render-`;
} else if (!isPlainObject(data)) {
if (_.isFunction(data.toString)) {
return `${title} ${data.toString()}`;
} else {
return `${title} -instance object, can't render-`;
}
} else {
return `${title} ${data}`;
}
} else {
const title = makeLabelDiv(options, level, name, 'object');
let count = 0;
const subs =
'' +
Object.entries(data)
.map(([key, val]) => _render(key, val, options, level + 1, count++ % 2))
.join('
') +
'
';
const inner = ``;
return `${level === 0 ? "" : ''}
${inner}
${level === 0 ? '
' : ''}`;
}
}
export function render(name: string, json: any, options: Json2htmlOptions): string {
// return `${head}${_render('', json, options, 0, 0)}`;
return `${_render(name, json, options, 0, 0)}`;
}
// const head = `
// `;