From 03e30fb08217c3e348c74dccd3ea9e04246864b8 Mon Sep 17 00:00:00 2001 From: Andy Bunce Date: Sun, 14 Sep 2025 18:15:03 +0100 Subject: [PATCH] [mod] isolate beer --- package-lock.json | 30 +++- package.json | 3 +- webapp/static/clients/codemirror/beer.css | 80 +++++++++ webapp/static/clients/codemirror/beer.html | 152 ++++++++++++++++++ webapp/static/clients/codemirror/beer.js | 127 +++++++++++++++ .../static/clients/codemirror/deepseek.html | 56 +++++++ 6 files changed, 446 insertions(+), 2 deletions(-) create mode 100644 webapp/static/clients/codemirror/beer.css create mode 100644 webapp/static/clients/codemirror/beer.html create mode 100644 webapp/static/clients/codemirror/beer.js create mode 100644 webapp/static/clients/codemirror/deepseek.html diff --git a/package-lock.json b/package-lock.json index 4b21431..c20aa70 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,8 @@ "@codemirror/theme-one-dark": "^6.1.0", "@codemirror/view": "^6.38.1", "ace-builds": "^1.43.2", - "ace-linters": "^1.8.3" + "ace-linters": "^1.8.3", + "beercss": "^3.12.3" }, "devDependencies": { "@rollup/plugin-node-resolve": "^15.0.1", @@ -672,6 +673,12 @@ "integrity": "sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==", "license": "MIT" }, + "node_modules/@material/material-color-utilities": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@material/material-color-utilities/-/material-color-utilities-0.2.7.tgz", + "integrity": "sha512-0FCeqG6WvK4/Cc06F/xXMd/pv4FeisI0c1tUpBbfhA2n9Y8eZEv4Karjbmf2ZqQCPUWMrGp8A571tCjizxoTiQ==", + "license": "Apache-2.0" + }, "node_modules/@rollup/plugin-node-resolve": { "version": "15.3.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.3.1.tgz", @@ -1098,6 +1105,15 @@ "node": ">=0.4.0" } }, + "node_modules/beercss": { + "version": "3.12.3", + "resolved": "https://registry.npmjs.org/beercss/-/beercss-3.12.3.tgz", + "integrity": "sha512-t/rO4rbC+48aJe1pI6tMPNyBSLNNbHqmv4f3D8jZV9XBRKu0JVokpku8KeIQNzC1FAzYnW1t7/Yt2kPVjEp0yg==", + "license": "MIT", + "dependencies": { + "material-dynamic-colors": "^1.1.2" + } + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -1371,6 +1387,18 @@ "node": ">= 18" } }, + "node_modules/material-dynamic-colors": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/material-dynamic-colors/-/material-dynamic-colors-1.1.2.tgz", + "integrity": "sha512-8KD0jrPTFs2x06UJWbvkg6E0HyzFjrvS5oOc2DsXzIEOqZTbb3ruLMUhNuPSl8WeHA/O/RTAlTLcxqYXJzYwPA==", + "license": "MIT", + "dependencies": { + "@material/material-color-utilities": "^0.2.7" + }, + "bin": { + "material-dynamic-colors": "cli.js" + } + }, "node_modules/minify": { "version": "9.2.0", "resolved": "https://registry.npmjs.org/minify/-/minify-9.2.0.tgz", diff --git a/package.json b/package.json index f14e5e2..37124e7 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,8 @@ "@codemirror/theme-one-dark": "^6.1.0", "@codemirror/view": "^6.38.1", "ace-builds": "^1.43.2", - "ace-linters": "^1.8.3" + "ace-linters": "^1.8.3", + "beercss": "^3.12.3" }, "devDependencies": { "@rollup/plugin-node-resolve": "^15.0.1", diff --git a/webapp/static/clients/codemirror/beer.css b/webapp/static/clients/codemirror/beer.css new file mode 100644 index 0000000..ef2f06d --- /dev/null +++ b/webapp/static/clients/codemirror/beer.css @@ -0,0 +1,80 @@ + .wrapper { + height: 100vh; + overflow: hidden; + display: grid; + grid-gap: 0; + grid-template-areas: + "header header" + "sidebar content" + "footer footer" + } + + .sidebar { + grid-area: sidebar; + } + + .content { + grid-area: content; + } + + .header { + grid-area: header; + } + + .footer { + grid-area: footer; + } + + /* Set editor dimensions */ + #editor { + height: 90%; + max-width: 100%; + overflow: hidden; + } + + /* Stretch editor to fit inside its containing div */ + .cm-editor { + height: 100%; + width: 100%; + overflow: auto; + + } + + .container { + display: grid; + grid-template-rows: auto 1fr auto; + min-height: 100vh; + } + + + /* Tablet view */ + @media (min-width: 768px) { + .main-layout { + grid-template-columns: 1fr 1fr; + /* Two columns for sidebars */ + } + } + + /* Desktop view */ + @media (min-width: 1024px) { + .main-layout { + grid-template-columns: 200px 1fr 200px; + /* Fixed sidebars, fluid main */ + } + } + + body { + margin: 0; + font-family: 'Roboto', sans-serif; + } + + .left-sidebar, + .right-sidebar { + background-color: var(--surface); + /* Use BeerCSS surface color */ + } + + main { + background-color: var(--background); + /* Main content background */ + } \ No newline at end of file diff --git a/webapp/static/clients/codemirror/beer.html b/webapp/static/clients/codemirror/beer.html new file mode 100644 index 0000000..1237046 --- /dev/null +++ b/webapp/static/clients/codemirror/beer.html @@ -0,0 +1,152 @@ + + + + + + + Beer example using BaseX LSP + + + + + + + + +
+
+ + XQuery 4.0 LSP client + +
+ Editor + + Msgs + + Dba + +
+ + + + +
+ + +
+
+ + + + + +
+ +
+
+ +
+ + + + +
Connect to LSP + +
+ + +
+ + hhhh + + +
Editor configuration + +
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/webapp/static/clients/codemirror/beer.js b/webapp/static/clients/codemirror/beer.js new file mode 100644 index 0000000..66a1be6 --- /dev/null +++ b/webapp/static/clients/codemirror/beer.js @@ -0,0 +1,127 @@ +const view = new lsp.EditorView({ + extensions: lsp.baseExts, + parent: document.getElementById("editor") +}); +let doc = "xquery version '3.1';\n(:~ comment:)\nmodule namespace pdfbox='ns';\n"; +var client; +var extLint; + +function $(id) { return document.getElementById(id) }; + +// Load saved content from localStorage when the page loads +window.addEventListener('load', () => { + const savedText = localStorage.getItem('code'); + if (savedText) doc = savedText; + let svr = localStorage.getItem('lsp'); + if (!svr) { + let x = new URL(window.location.href); + x.protocol = "ws"; + x.pathname = "ws/lsp" + svr = x.href; + } + $("iServer").value = svr; + view.setState(lsp.EditorState.create({ doc: doc, extensions: lsp.baseExts })); + connect(); +}); + +// Save content to localStorage when the page is about to unload +window.addEventListener('beforeunload', () => { + const doc = view.state.doc.toString(); + localStorage.setItem('code', doc); + localStorage.setItem('lsp', $("iServer").value); +}); + +$("connect").onclick = e => { e.preventDefault(); connect() }; + +$("search").onclick = e => lsp.openSearchPanel(view); + +$("fullscreen").onclick = e => $("editor").requestFullscreen(); + +$("cmd").onclick = e => console.log("CMDS", lsp.listCommands(view)); + +$("lint").onclick = async e => { + console.log("word", view.state.wordAt(1)); + lsp.openLintPanel(view); +}; + +$("sync").onclick = e => { client.sync(); console.log("XXXsync"); }; + +$("format").onclick = e => { + console.log("FMT", lsp.formatDocument(view)); +}; + +$("load").onchange = e => { + const url = e.target.value; + if (url.length == 0) return + fetch(url) + .then(response => response.text()) + .then(t => { + view.dispatch({ + + changes: { + from: 0, + to: view.state.doc.length, + insert: t + } + }) + //client.sync(); + //console.log("SYNC"); + }); + $("load").value = ""; +}; +function connect() { + const server = $("iServer").value; + const file = $("iFile").value; + lsp.simpleWebSocketTransport(server) + .then(transport => { + transport.socket.onclose = (event) => connectStatus(false); + transport.socket.oneror = (event) => $("msg").innerText = "sock error!"; + transport.subscribe(incoming); + client = new lsp.LSPClient({ extensions: lsp.languageServerExtensions() }); + client.connect(transport); + $("popConnect").hidePopover(); + connectStatus(true); + let extLsp = client.plugin(file, "xquery"); + + view.dispatch({ + effects: lsp.StateEffect.appendConfig.of( + [lsp.linter(null, { autoPanel: true }), ...extLsp, + lsp.keymap.of([...lsp.formatKeymap])]) + }) + }) + .catch(e => { + console.log(e); + connectStatus(false); + alert("connection failed: " + server) + }); + +}; + +function connectStatus(bool) { + if (bool) { + $("popcon").querySelector("i").innerText="cloud" + $("popcon").classList.remove("error") + $("popcon").classList.add("primary") + } else { + $("popcon").querySelector("i").innerText="cloud_off" + $("popcon").classList.add("error") + $("popcon").classList.remove("primary") + } +}; + +function incoming(msg) { + const rpc = JSON.parse(msg); + log(rpc); +}; + + +function log(rpc) { + console.log("<-", rpc) + if (rpc.id) return + const text = rpc.method; + const li = document.createElement("li"); + const n = $("traffic").childElementCount + " "; + li.appendChild(document.createTextNode(n + text)); + $("traffic").insertBefore(li, $("traffic").firstChild) +}; + diff --git a/webapp/static/clients/codemirror/deepseek.html b/webapp/static/clients/codemirror/deepseek.html new file mode 100644 index 0000000..b156076 --- /dev/null +++ b/webapp/static/clients/codemirror/deepseek.html @@ -0,0 +1,56 @@ + + + + + + Holy Grail Layout with BeerCSS + + + + + +
+
Header
+
+ +
Main Content
+ +
+ +
+ + \ No newline at end of file