Skip to content

Commit

Permalink
Preserve indentation with copy/paste
Browse files Browse the repository at this point in the history
Fixes #191
  • Loading branch information
bhollis committed May 3, 2023
1 parent 8283935 commit c9307c6
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 15 deletions.
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"version": "0.2.0",
"configurations": [
{
"type": "pwa-chrome",
"type": "chrome",
"request": "launch",
"name": "Launch Chrome against localhost",
"url": "https://jsonplaceholder.typicode.com/users",
Expand Down
32 changes: 19 additions & 13 deletions src/jsonformatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export function jsonToHTML(json: any, uri: string) {

/** Convert a whole JSON value / JSONP response into an HTML body, without title and scripts */
function jsonToHTMLBody(json: any) {
return `<div id="json">${valueToHTML(json, "<root>")}</div>`;
return `<div id="json">${valueToHTML(json, "<root>", 0)}</div>`;
}

/** Produce an error document for when parsing fails. */
Expand Down Expand Up @@ -72,15 +72,15 @@ function decorateWithSpan(value: any, className: string) {
}

// Convert a basic JSON datatype (number, string, boolean, null, object, array) into an HTML fragment.
function valueToHTML(value: any, path: string) {
function valueToHTML(value: any, path: string, indent: number) {
const valueType = typeof value;

if (value === null) {
return decorateWithSpan("null", "null");
} else if (Array.isArray(value)) {
return arrayToHTML(value, path);
return arrayToHTML(value, path, indent);
} else if (valueType === "object") {
return objectToHTML(value, path);
return objectToHTML(value, path, indent);
} else if (valueType === "number") {
return decorateWithSpan(value, "num");
} else if (valueType === "string" && value.charCodeAt(0) === 8203 && !isNaN(value.slice(1))) {
Expand All @@ -101,28 +101,32 @@ function valueToHTML(value: any, path: string) {
}

// Convert an array into an HTML fragment
function arrayToHTML(json: any, path: string) {
function arrayToHTML(json: any, path: string, indent: number) {
if (json.length === 0) {
return "[ ]";
}

let output = "";
for (let i = 0; i < json.length; i++) {
const subPath = `${path}[${i}]`;
output += "<li>" + valueToHTML(json[i], subPath);
output += "<li>" + addIndent(indent + 1) + valueToHTML(json[i], subPath, indent + 1);
if (i < json.length - 1) {
output += ",";
}
output += "</li>";
}
return (
(json.length === 0 ? "" : '<span class="collapser"></span>') +
`[<ul class="array collapsible">${output}</ul>]`
`[<ul class="array collapsible">${output}</ul>${addIndent(indent)}]`
);
}

function addIndent(indent: number) {
return `<span class="spacer">${"&nbsp;&nbsp;".repeat(indent)}</span>`;
}

// Convert a JSON object to an HTML fragment
function objectToHTML(json: any, path: string) {
function objectToHTML(json: any, path: string, indent: number) {
let numProps = Object.keys(json).length;
if (numProps === 0) {
return "{ }";
Expand All @@ -138,19 +142,21 @@ function objectToHTML(json: any, path: string) {
} else {
escapedProp = `"${escapedProp}"`;
}
output += `<li><span class="prop${bare ? "" : " quoted"}" title="${htmlEncode(
subPath
)}"><span class="q">&quot;</span>${jsString(
output += `<li>${addIndent(indent + 1)}<span class="prop${
bare ? "" : " quoted"
}" title="${htmlEncode(subPath)}"><span class="q">&quot;</span>${jsString(
prop
)}<span class="q">&quot;</span></span>: ${valueToHTML(json[prop], subPath)}`;
)}<span class="q">&quot;</span></span>: ${valueToHTML(json[prop], subPath, indent + 1)}`;
if (numProps > 1) {
output += ",";
}
output += "</li>";
numProps--;
}

return `<span class="collapser"></span>{<ul class="obj collapsible">${output}</ul>}`;
return `<span class="collapser"></span>{<ul class="obj collapsible">${output}</ul>${addIndent(
indent
)}}`;
}

// Clean up a JSON parsing error message
Expand Down
7 changes: 6 additions & 1 deletion src/viewer.css
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ body {

.collapser:before {
content: "▸";
-moz-user-select: none;
user-select: none;
}

.collapsible.collapsed {
Expand Down Expand Up @@ -178,4 +178,9 @@ h1 {
.errorline {
background-color: rgb(32, 29, 29);
}
}

.spacer {
display: inline-block;
width: 0px;
}

0 comments on commit c9307c6

Please sign in to comment.