summaryrefslogtreecommitdiff
path: root/graph/web/index.html
diff options
context:
space:
mode:
authorDibyendu Majumdar <mobile@majumdar.org.uk>2023-08-19 08:52:57 -0700
committerDibyendu Majumdar <mobile@majumdar.org.uk>2026-09-29 12:34:58 -0700
commita0edb627c5459f433a31b689abcdd722d2d49b05 (patch)
tree8ee95ede877c07ceb52d9b17075a477f0a3347e1 /graph/web/index.html
downloadSimple-a0edb627c5459f433a31b689abcdd722d2d49b05.tar.gz
Simple-a0edb627c5459f433a31b689abcdd722d2d49b05.zip
Chapter 1: Introduction
Co-authored-by: Cliff Click <cliffc@acm.org> Co-authored-by: Thalia Archibald <thalia@archibald.dev> Co-authored-by: hadha <helsgithub15@gmail.com> Co-authored-by: XmiliaH <45106915+XmiliaH@users.noreply.github.com> Co-authored-by: Tamás Hadházy <85063808+Hels15@users.noreply.github.com>
Diffstat (limited to 'graph/web/index.html')
-rw-r--r--graph/web/index.html111
1 files changed, 111 insertions, 0 deletions
diff --git a/graph/web/index.html b/graph/web/index.html
new file mode 100644
index 00000000..7e66fe5a
--- /dev/null
+++ b/graph/web/index.html
@@ -0,0 +1,111 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>Simple Viewer</title>
+ <link rel="icon" href="data:,">
+ <style>
+ html, body { height:100%; margin:0; font-family:sans-serif; }
+ .viewer { height:100%; display:grid; grid-template-rows:auto minmax(0,1fr) auto; }
+ .source { padding:8px; border-bottom:1px solid #ccc; }
+ #program { width:min(600px,80vw); vertical-align:middle; }
+ #status { margin-top:4px; }
+ #graph { min-height:0; overflow:hidden; position:relative; background:#fafbfc; }
+ #elk { width:100%; height:100%; }
+ #graph svg { display:block; }
+ .tools { display:flex; flex-wrap:wrap; align-items:center; gap:14px; margin-top:8px; font-size:12px; }
+ .hint { color:#616c78; }
+ .ctrl { color:#b63838; } .mem { color:#2867b2; } .data { color:#536477; }
+ .edge { fill:none; stroke-width:1.5; }
+ .edge.CTRL { stroke-width:2; }
+ .edge.ASSOC { stroke-dasharray:4 4; }
+ .edge.PARSER { stroke-dasharray:5 4; }
+ .parser rect { fill:#f6f0ff; stroke:#7956a5; stroke-width:1.5; stroke-dasharray:5 4; }
+ .edge.selected { stroke-width:3.5; }
+ .edge.bundle { stroke-width:4; }
+ .edge.bundle.selected { stroke-width:6; }
+ .edge-hit { fill:none; stroke:transparent; stroke-width:12; vector-effect:non-scaling-stroke; pointer-events:stroke; cursor:pointer; }
+ .edge-jump { fill:transparent; pointer-events:all; cursor:pointer; }
+ .node { cursor:pointer; }
+ .box { stroke:#758191; stroke-width:1; }
+ .node.held .box { stroke-dasharray:5 3; }
+ .node.near .box { stroke:#c18221; stroke-width:2; }
+ .node.focus .box { stroke:#9c4900; stroke-width:3; }
+ .node.selected .box { stroke:#1569b9; stroke-width:3; }
+ .node.folded .box { stroke-width:4; }
+ .node.folding .box { fill:#f4ccd7; }
+ .fold-tag { font-size:9px; font-weight:700; fill:#963751; }
+ .peep-area { fill:#fff3d9; fill-opacity:.8; stroke:#c18221; stroke-width:2; pointer-events:none; }
+ .node.peep-edit .box { stroke:#9c4900; stroke-width:3; }
+ .node.error .box { stroke:#b42318; stroke-width:4; }
+ #event.error { color:#b42318; font-weight:600; white-space:pre-wrap; overflow-wrap:anywhere; }
+ .peep-ghosts { pointer-events:none; }
+ .region-box { stroke:#9da9b8; stroke-width:1.5; }
+ .fold-btn { cursor:pointer; }
+ .fold-btn rect { fill:white; stroke:#596674; }
+ .fold-btn text { font-size:14px; fill:#152330; }
+ .fold-btn:focus rect { stroke:#1569b9; stroke-width:2; }
+ .shortcut { cursor:pointer; }
+ .shortcut path { fill:none; stroke-width:1.5; }
+ .shortcut rect { fill:#fff8ec; stroke:#b63838; stroke-dasharray:3 2; }
+ .shortcut text { font-size:11px; fill:#783030; }
+ .shortcut.selected rect, .shortcut:focus rect { stroke-width:2.5; }
+ .label { font-size:12px; fill:#152330; font-weight:600; }
+ .node-id { font-size:10px; fill:#596674; font-weight:400; }
+ .type { font-size:11px; fill:#455768; }
+ .port { stroke:#536477; stroke-width:1; }
+ .row { stroke:#b6afcf; stroke-width:1; }
+ .bind { font-size:12px; fill:#152330; }
+ .slot { font-size:10px; fill:#364352; paint-order:stroke; stroke:#fafbfc; stroke-width:3; }
+ #detail { position:absolute; top:8px; right:8px; margin:0; padding:12px; max-width:320px;
+ max-height:45%; overflow:auto; white-space:pre-wrap; overflow-wrap:anywhere;
+ background:#fffffff2; border:1px solid #bac5d0; border-radius:4px; font-size:12px; }
+ .controls { display:flex; flex-wrap:wrap; justify-content:center; align-items:center; gap:6px; padding:6px; }
+ .button { color:white; background:black; font-size:20px; min-width:30px; }
+ .button:disabled { background:grey; }
+ .count { font-size:20px; min-width:35px; text-align:center; }
+ #N { width:6ch; }
+ #scrub { width:clamp(120px,35vw,600px); }
+ </style>
+ <script src="vendor/d3.v7.min.js"></script>
+ <script src="vendor/elk-api.js"></script>
+ <script src="groups.js"></script>
+ <script src="layout.js"></script>
+ <script src="peep.js"></script>
+ <script src="render.js"></script>
+</head>
+<body>
+ <div class="viewer">
+ <div class="source">
+ <label for="program">Simple program:</label><br>
+ <textarea id="program" rows="3" autofocus></textarea>
+ <button id="compile" type="button" disabled>Compile</button>
+ <div id="status" role="status">Connecting to compiler...</div>
+ <div class="tools">
+ <button id="fit" type="button" disabled>Fit</button>
+ <button id="save" type="button" disabled>Save SVG</button>
+ <button id="unfold" type="button" disabled>Unfold all</button>
+ <label><input id="assocs" type="checkbox"> Associations</label>
+ <label><input id="near" type="checkbox" checked> Peep neighborhood</label>
+ <span class="ctrl">Control</span><span class="data">Data</span><span class="mem">Memory</span>
+ <span class="hint">Scroll to zoom · drag to pan · click a node for details · click an edge to jump between ends</span>
+ </div>
+ <div id="event" class="hint" role="status"></div>
+ </div>
+ <div id="graph"><div id="elk"></div><pre id="detail" hidden></pre></div>
+ <div class="controls">
+ <button id="doFirst" type="button" onclick="doFirst()" class="button" aria-label="First frame" title="First frame">|&#11164;</button>
+ <button id="doPrev" type="button" onclick="doPrev()" class="button" aria-label="Previous frame" aria-keyshortcuts="ArrowLeft" title="Previous step (Left arrow)">&#11164;</button>
+ <label for="N">Frame</label>
+ <input id="N" class="count" type="number" min="1" max="1" step="1" value="0" disabled title="Enter a frame number">
+ <span>/</span>
+ <span id="len" class="count">0</span>
+ <button id="doNext" type="button" onclick="doNext()" class="button" aria-label="Next frame" aria-keyshortcuts="ArrowRight" title="Next step (Right arrow)">&#11166;</button>
+ <button id="doLast" type="button" onclick="doLast()" class="button" aria-label="Last frame" title="Last available frame">&#11166;|</button>
+ <input id="scrub" type="range" min="1" max="1" step="1" value="1" disabled aria-label="Frame slider">
+ <button id="doExit" type="button" onclick="doExit()" class="button">Exit</button>
+ </div>
+ </div>
+ <script src="viewer.js"></script>
+</body>
+</html>