diff --git a/site/css/visualizer.css b/site/css/visualizer.css index eb258cd..a121611 100644 --- a/site/css/visualizer.css +++ b/site/css/visualizer.css @@ -4,20 +4,54 @@ } /* --- Input section --- */ +.viz-editor { + position: relative; + background: var(--grain); + border: 1px solid var(--border); +} +.viz-editor:focus-within { + outline: 2px solid var(--copper); + outline-offset: -2px; +} +.viz-highlight { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + margin: 0; + font-family: var(--mono); + font-size: 0.8rem; + line-height: 1.5; + padding: 0.75rem 1rem; + overflow: hidden; + white-space: pre-wrap; + overflow-wrap: break-word; + pointer-events: none; + color: var(--graphite); +} .viz-textarea { width: 100%; font-family: var(--mono); font-size: 0.8rem; line-height: 1.5; - background: var(--grain); - border: 1px solid var(--border); - color: var(--graphite); + background: transparent; + border: none; + color: transparent; + caret-color: var(--graphite); padding: 0.75rem 1rem; resize: vertical; + position: relative; + z-index: 1; } .viz-textarea:focus { - outline: 2px solid var(--copper); - outline-offset: -2px; + outline: none; +} +.viz-textarea::selection { + background: #b5652b30; +} +.viz-textarea::placeholder { + color: var(--pencil); } .viz-buttons { @@ -209,6 +243,20 @@ word-break: break-all; margin: 0.5rem 0; } + +/* Diff line backgrounds */ +.viz-detail-body .token.inserted { + display: block; + background: #6e7d3a12; +} +.viz-detail-body .token.deleted { + display: block; + background: #c4403010; +} +.viz-detail-body .token.coord { + color: #8a8078; + font-style: italic; +} .viz-detail-body .detail-section { margin-bottom: 1rem; } diff --git a/site/js/visualizer.js b/site/js/visualizer.js index 1bd8fa4..aab43c0 100644 --- a/site/js/visualizer.js +++ b/site/js/visualizer.js @@ -126,6 +126,7 @@ // --- DOM refs --- var input = document.getElementById("viz-input"); + var highlight = document.getElementById("viz-highlight"); var fileInput = document.getElementById("viz-file"); var exampleBtn = document.getElementById("viz-example"); var renderBtn = document.getElementById("viz-render"); @@ -689,12 +690,20 @@ ); var ch = step.change[f]; if (ch.raw) { - html.push("
" + escapeHtml(ch.raw) + "
"); + html.push( + "
" +
+              Prism.highlight(ch.raw, Prism.languages.diff, "diff") +
+              "
", + ); } if (ch.structural) { html.push( "
" +
-              escapeHtml(JSON.stringify(ch.structural, null, 2)) +
+              Prism.highlight(
+                JSON.stringify(ch.structural, null, 2),
+                Prism.languages.json,
+                "json",
+              ) +
               "
", ); } @@ -705,7 +714,15 @@ // Full JSON html.push('
'); html.push('
Raw JSON
'); - html.push("
" + escapeHtml(JSON.stringify(step, null, 2)) + "
"); + html.push( + "
" +
+        Prism.highlight(
+          JSON.stringify(step, null, 2),
+          Prism.languages.json,
+          "json",
+        ) +
+        "
", + ); html.push("
"); detailBody.innerHTML = html.join(""); @@ -784,11 +801,26 @@ errorBox.hidden = true; } + // --- Input highlight sync --- + function syncHighlight() { + var code = input.value; + highlight.innerHTML = code + ? Prism.highlight(code, Prism.languages.json, "json") + : ""; + highlight.scrollTop = input.scrollTop; + } + + input.addEventListener("input", syncHighlight); + input.addEventListener("scroll", function () { + highlight.scrollTop = input.scrollTop; + }); + // --- Event wiring --- renderBtn.addEventListener("click", render); exampleBtn.addEventListener("click", function () { input.value = JSON.stringify(DEFAULT_EXAMPLE, null, 2); + syncHighlight(); render(); }); @@ -798,6 +830,7 @@ var reader = new FileReader(); reader.onload = function () { input.value = reader.result; + syncHighlight(); render(); }; reader.readAsText(file); @@ -839,5 +872,6 @@ // --- Auto-load example on page load --- input.value = JSON.stringify(DEFAULT_EXAMPLE, null, 2); + syncHighlight(); render(); })(); diff --git a/site/pages/visualizer.njk b/site/pages/visualizer.njk index 767610e..4162d5a 100644 --- a/site/pages/visualizer.njk +++ b/site/pages/visualizer.njk @@ -13,8 +13,11 @@ permalink: /visualizer/
- +
+ + +