let level = 1; const COLLAPSE_LEVEL = 2; export function jsonToHTML(json) { level = 1; let output = ''; output += '
'; output += valueToHTML(json); output += '
'; return output; } function htmlEncode(t) { return t !== undefined ? t .toString() .replace(/&/g, '&') .replace(/"/g, '"') .replace(//g, '>') : ''; } function decorateWithSpan(value, className) { return '' + htmlEncode(value) + ''; } function punctuation(val) { return '' + val + ''; } function valueToHTML(value) { const valueType = typeof value; let output = ''; if (value === undefined || value === null) { output += decorateWithSpan('null', 'token keyword'); } else if (value && value.constructor === Array) { level++; output += arrayToHTML(value); level--; } else if (value && value.constructor === Date) { output += decorateWithSpan('"' + value.toISOString() + '"', 'token string'); } else if (valueType === 'object') { level++; output += objectToHTML(value); level--; } else if (valueType === 'number') { output += decorateWithSpan(value, 'token number'); } else if (valueType === 'string') { if (/^(http|https):\/\/[^\s]+$/.test(value)) { output += decorateWithSpan('"', 'token string') + '' + htmlEncode(value) + '' + decorateWithSpan('"', 'token string'); } else { output += decorateWithSpan('"' + value + '"', 'token string'); } } else if (valueType === 'boolean') { output += decorateWithSpan(value, 'token boolean'); } return output; } function arrayToHTML(json) { const collapsed = level > COLLAPSE_LEVEL ? 'collapsed' : ''; let output = `
${punctuation( '[', )}${punctuation(']')}`; if (!hasContents) { output = punctuation('[ ]'); } return output; } function objectToHTML(json) { const collapsed = level > COLLAPSE_LEVEL ? 'collapsed' : ''; const keys = Object.keys(json); const length = keys.length; let output = `
${punctuation( '{', )}${punctuation('}')}`; if (!hasContents) { output = punctuation('{ }'); } return output; }