aboutsummaryrefslogtreecommitdiff
path: root/www
diff options
context:
space:
mode:
Diffstat (limited to 'www')
-rw-r--r--www/index.html15
-rw-r--r--www/index.js69
2 files changed, 70 insertions, 14 deletions
diff --git a/www/index.html b/www/index.html
index 01ba57d..1404993 100644
--- a/www/index.html
+++ b/www/index.html
@@ -10,15 +10,24 @@
10 grid-template-columns: 1fr 1fr; 10 grid-template-columns: 1fr 1fr;
11 grid-gap: 20px; 11 grid-gap: 20px;
12} 12}
13.syntax-node {
14 padding: 0px;
15 padding-left: 20px;
16}
17.syntax-err {
18 color: red;
19}
20pre {
21 padding: 0px;
22 margin: 0px
23}
13 </style> 24 </style>
14 <body> 25 <body>
15 <noscript>This page contains webassembly and javascript content, please enable javascript in your browser.</noscript> 26 <noscript>This page contains webassembly and javascript content, please enable javascript in your browser.</noscript>
16 <script src="./bootstrap.js"></script> 27 <script src="./bootstrap.js"></script>
17 <div class="grid-container"> 28 <div class="grid-container">
18 <div id="source-code"></div> 29 <div id="source-code"></div>
19 <div> 30 <div id="cst">
20 <pre id="cst">
21 </pre>
22 </div> 31 </div>
23 </div> 32 </div>
24 <!-- button id="gen-cst">Generate CST</button --> 33 <!-- button id="gen-cst">Generate CST</button -->
diff --git a/www/index.js b/www/index.js
index 2665873..52253c0 100644
--- a/www/index.js
+++ b/www/index.js
@@ -1,5 +1,7 @@
1import {SynNode, put_cst} from "cstea"; 1import {SynNode, put_cst} from "cstea";
2import {EditorState, EditorView, basicSetup} from "@codemirror/basic-setup" 2import {EditorState, EditorView, basicSetup} from "@codemirror/basic-setup"
3import {Decoration, DecorationSet} from "@codemirror/view"
4import {StateField, StateEffect} from "@codemirror/state"
3import {rust} from "@codemirror/lang-rust" 5import {rust} from "@codemirror/lang-rust"
4 6
5let cst = document.getElementById('cst'); 7let cst = document.getElementById('cst');
@@ -18,32 +20,77 @@ let view = new EditorView({
18 parent: document.getElementById('source-code') 20 parent: document.getElementById('source-code')
19}) 21})
20 22
23const doHighlight = StateEffect.define()
24
25const highlightField = StateField.define({
26 create() {
27 return Decoration.none;
28 },
29 update(highlight, tr) {
30 for (let e of tr.effects) if (e.is(doHighlight)) {
31 return (Decoration.none).update({
32 add: [hlMark.range(e.value.from, e.value.to)]
33 });
34 }
35 },
36 provide: f => EditorView.decorations.from(f)
37})
38
39const hlMark = Decoration.mark({class: "cm-highlight"})
40
41const hlTheme = EditorView.baseTheme({
42 ".cm-highlight": { textDecoration: "underline 3px red" }
43})
44
45function highlightArea(view, textRange) {
46 let effects = [doHighlight.of({from: textRange.start(), to: textRange.end()})];
47 if (!view.state.field(highlightField, false)) {
48 effects.push(StateEffect.appendConfig.of([highlightField, hlTheme]));
49 }
50 view.dispatch({effects});
51}
52
21function render_cst(synRoot) { 53function render_cst(synRoot) {
22 cst.innerText += "\n" + synRoot.to_string(); 54 let nodeDiv = document.createElement("div");
55 nodeDiv.className = "syntax-node";
56 let r = synRoot.range();
57 let synText = wrap(synRoot.text() + synRoot.range().to_string(), "pre");
58 synText.onmouseover = () => {
59 console.log(r.to_string());
60 highlightArea(view, r);
61 }
62 nodeDiv.appendChild(synText);
23 if (!synRoot.is_token()) { 63 if (!synRoot.is_token()) {
24 synRoot.children().forEach(node => { 64 synRoot.children().forEach(node => {
25 render_cst(node); 65 nodeDiv.appendChild(render_cst(node));
26 return;
27 }); 66 });
28 } else {
29 return;
30 } 67 }
68 return nodeDiv;
69}
70
71function wrap(s, tag) {
72 let t = document.createElement(tag);
73 t.innerText = s;
74 return t;
31} 75}
32 76
33function render_err(errorList) { 77function render_err(errorList) {
34 cst.innerText = ""; 78 let errDiv = document.createElement("div");
79 errDiv.className = "syntax-err";
35 errorList.forEach(err => { 80 errorList.forEach(err => {
36 cst.innerText += "\n" + err.to_string(); 81 errDiv.appendChild(wrap(err.to_string(), "pre"));
82 highlightArea(view, err.range());
37 }); 83 });
84 return errDiv;
38} 85}
39 86
40function doRender() { 87function doRender() {
41 let sourceFile = view.state.doc.toString();; 88 let sourceFile = view.state.doc.toString();;
42 cst.innerText = ""; 89 cst.innerHTML = "";
43 try { 90 try {
44 var synRoot = SynNode.from_str(sourceFile); 91 let synRoot = SynNode.from_str(sourceFile);
45 render_cst(synRoot); 92 cst.appendChild(render_cst(synRoot));
46 } catch (synError) { 93 } catch (synError) {
47 render_err(synError) 94 cst.appendChild(render_err(synError));
48 } 95 }
49} 96}