/
githubmirror
/
servo
Обзор
Документация
Войти
/
githubmirror
/
servo
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
components/default-resources/resources/json-viewer.html
269 строк
7 KB
webbeef
parser: add a pretty printer for top-level json documents (#43702)
05 апр 2026, 09:50
Не верифицирован
05 апр 2026, 09:50
0b5688f
Код
Авторство
О чём код?
<html> <head> <style> body { font-family: monospace; margin: 0; padding: 0; background: #fff; color: #333; } #json-raw { display: none; } #viewer { display: none; padding: 0.5em 1em; line-height: 1.5; &.active { display: block; } } #toolbar { display: flex; gap: 1em; padding: 0.5em; align-items: center; background: #f5f5f5; border-bottom: 1px solid #ddd; & button { min-width: 5em; &.active { background: #ddd; font-weight: bold; } } } #raw-view { display: none; padding: 0.5em 1em; white-space: pre-wrap; word-break: break-all; &.active { display: block; } } .json-error { padding: 0.5em 1em; color: #c00; font-weight: bold; } /* Syntax highlighting for Json data types */ .json-key { color: #881391; } .json-string { color: #1a1aa6; } .json-number { color: #1c00cf; } .json-boolean { color: #0d22aa; } .json-null { color: #808080; } /* Collapsible tree */ .toggle { cursor: pointer; user-select: none; &::before { content: "\25BC"; display: inline-block; width: 1em; transition: transform 0.1s; } &.collapsed::before { transform: rotate(-90deg); } } .collapsible { margin-left: 1.5em; &.hidden { display: none; } } .bracket { color: #333; } .comma { color: #333; } .line { padding-left: 0; } </style> <script> // Shortcut to create an element with an optional class and text content. function createElement(name, classes = null, textContent = null) { let node = document.createElement(name); if (classes) { node.className = classes; } if (textContent) { node.textContent = textContent; } return node; } function renderNode(value, container) { if (value === null) { let s = createElement("span", "json-null", "null"); container.append(s); } else if (typeof value === "boolean") { let s = createElement("span", "json-boolean", String(value)); container.append(s); } else if (typeof value === "number") { let s = createElement("span", "json-number", String(value)); container.append(s); } else if (typeof value === "string") { let s = createElement("span", "json-string", JSON.stringify(value)); container.append(s); } else if (Array.isArray(value)) { renderArray(value, container); } else if (typeof value === "object") { renderObject(value, container); } } function renderObject(obj, container) { let keys = Object.keys(obj); if (keys.length === 0) { container.append(createElement("span", "bracket", "{}")); return; } let toggle = createElement("span", "toggle"); container.append(toggle); container.append(createElement("span", "bracket", "{")); let inner = createElement("div", "collapsible"); container.append(inner); keys.forEach((key, i) => { let line = createElement("div", "line"); line.append(createElement("span", "json-key", JSON.stringify(key))); line.append(document.createTextNode(": ")); renderNode(obj[key], line); if (i < keys.length - 1) { line.append(createElement("span", "comma", ",")); } inner.append(line); }); container.append(createElement("span", "bracket", "}")); toggle.onclick = function () { toggle.classList.toggle("collapsed"); inner.classList.toggle("hidden"); }; } function renderArray(arr, container) { if (arr.length === 0) { container.append(createElement("span", "bracket", "[]")); return; } let toggle = createElement("span", "toggle"); container.append(toggle); container.append(createElement("span", "bracket", "[")); let inner = createElement("div", "collapsible"); container.append(inner); arr.forEach((item, i) => { let line = createElement("div", "line"); renderNode(item, line); if (i < arr.length - 1) { line.append(createElement("span", "comma", ",")); } inner.append(line); }); container.append(createElement("span", "bracket", "]")); toggle.onclick = function () { toggle.classList.toggle("collapsed"); inner.classList.toggle("hidden"); }; } document.addEventListener("DOMContentLoaded", function () { const viewer = document.getElementById("viewer"); const prettyButton = document.getElementById("pretty-toggle"); const rawButton = document.getElementById("raw-toggle"); const rawView = document.getElementById("raw-view"); const rawText = rawView.innerText; let data; let parseError = null; try { data = JSON.parse(rawText); } catch (e) { parseError = e; } if (parseError) { let errDiv = createElement( "div", "json-error", "Invalid JSON: " + parseError.message, ); viewer.append(errDiv); viewer.append(createElement("pre", null, rawText)); } else { renderNode(data, viewer); rawView.textContent = JSON.stringify(data, null, 2); } // Toggle buttons prettyButton.onclick = function () { viewer.classList.add("active"); rawView.classList.remove("active"); prettyButton.classList.add("active"); rawButton.classList.remove("active"); }; rawButton.onclick = function () { rawView.classList.add("active"); viewer.classList.remove("active"); rawButton.classList.add("active"); prettyButton.classList.remove("active"); }; }); </script> </head> <body> <div id="toolbar"> <button id="pretty-toggle" class="active">Pretty</button> <button id="raw-toggle">Raw</button> </div> <div id="viewer" class="active"></div> <pre id="raw-view">