[mod] isolate beer
This commit is contained in:
parent
9dadee8b84
commit
03e30fb082
6 changed files with 446 additions and 2 deletions
30
package-lock.json
generated
30
package-lock.json
generated
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
80
webapp/static/clients/codemirror/beer.css
Normal file
80
webapp/static/clients/codemirror/beer.css
Normal file
|
@ -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 */
|
||||
}
|
152
webapp/static/clients/codemirror/beer.html
Normal file
152
webapp/static/clients/codemirror/beer.html
Normal file
|
@ -0,0 +1,152 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Beer example using BaseX LSP</title>
|
||||
<link rel="icon" type="image/png" href="../favicon.png" />
|
||||
<link href="../beercss-3.12.3/beer.min.css" rel="stylesheet" />
|
||||
<link href="beer.css" rel="stylesheet" />
|
||||
|
||||
<script src="popover.js" defer></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="wrapper">
|
||||
<header class="header row tertiary">
|
||||
|
||||
<a id="help">XQuery 4.0 LSP client</a>
|
||||
<button popovertarget="popHelp" class="circle transparent"><i>info</i></button>
|
||||
<div class="max"></div>
|
||||
<a class="nav-link active" aria-current="page" href="#">Editor</a>
|
||||
|
||||
<a class="nav-link" href="#">Msgs</a>
|
||||
|
||||
<a class="nav-link" href="/dba/logs" target="dba">Dba</a>
|
||||
|
||||
<div class="max"></div>
|
||||
|
||||
<button id="popcon" popovertarget="popConnect" class="circle transparent error">
|
||||
<i>Cloud_Off</i>
|
||||
</button>
|
||||
|
||||
|
||||
</header>
|
||||
<article class="sidebar">
|
||||
|
||||
<div id="msg">(msgs)</div>
|
||||
<select id="load">
|
||||
<option selected value="">load..</option>
|
||||
<optgroup label="XQuery3">
|
||||
<option
|
||||
value="https://raw.githubusercontent.com/expkg-zone58/pdfbox/refs/heads/main/src/Pdfbox3.xqm">
|
||||
Pdfbox3.xqm</option>
|
||||
<option
|
||||
value="https://raw.githubusercontent.com/Quodatum/xqdoca/refs/heads/master/src/main/lib/model.xqm">
|
||||
model.xqm</option>
|
||||
</optgroup>
|
||||
<optgroup label="XQuery4">
|
||||
<option
|
||||
value="https://git.quodatum.duckdns.org/quodatum/basex-lsp/raw/branch/main/webapp/lsp/lsp-text.xqm">
|
||||
lsp-text.xqm</option>
|
||||
|
||||
</optgroup>
|
||||
<optgroup label="xpath">
|
||||
<option
|
||||
value="https://raw.githubusercontent.com/dnovatchev/Articles/refs/heads/main/Generators/Code/generator.xpath">
|
||||
generator.xpath</option>
|
||||
|
||||
</optgroup>
|
||||
</select>
|
||||
|
||||
<ul id="traffic" style="overflow: scroll;">
|
||||
<li>-</li>
|
||||
</ul>
|
||||
</article>
|
||||
|
||||
<main class="content">
|
||||
<div class="row top">
|
||||
<nav class="group connected">
|
||||
<label for="file">File:</label>
|
||||
<input id="iFile" type="url" value="file:///some/file.xqm" />
|
||||
<select id="language">
|
||||
<option selected>Language</option>
|
||||
<option value="plaintext">plaintext</option>
|
||||
<option value="xquery">xquery</option>
|
||||
<option value="xml">xml</option>
|
||||
</select>
|
||||
<label for="symbols">Symbols:</label><select id="symbols" disabled="disabled"></select>
|
||||
</nav>
|
||||
|
||||
<nav class="group connected">
|
||||
<button id="search" title="Search" type="button" class=""><i>Search</i></button>
|
||||
|
||||
<button id="lint" title="Diagnostics" type="button" class=""><i>Data_Alert</i></button>
|
||||
|
||||
<button id="sync" title="Sync changes to server" type="button" class="btn btn-light">
|
||||
<i>Sync</i>
|
||||
</button>
|
||||
<button id="fullscreen" title="Full screen" type="button" class="btn btn-light">
|
||||
<i>Fullscreen</i>
|
||||
</button>
|
||||
</nav>
|
||||
|
||||
<nav class="group connected">
|
||||
|
||||
<button id="syntax" type="button" class="btn btn-light" title="Syntax">
|
||||
<i>Chat</i></button>
|
||||
|
||||
<button id="format" type="button" class="btn btn-light" title="Format (Shift-Alt-f)">
|
||||
<i>Format_Align_Left</i></button>
|
||||
|
||||
<button id="cmd" type="button" class="btn btn-light" title="Cmd ">
|
||||
<i>Order_Play</i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-light" popovertarget="popSettings" title="Settings">
|
||||
<i>Settings</i></button>
|
||||
</nav>
|
||||
</div>
|
||||
<!-- Editor goes in here -->
|
||||
<div id="editor"></div>
|
||||
</main>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Popovers -->
|
||||
<dialog id="popConnect" popover>
|
||||
<header>Connect to LSP
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</header>
|
||||
<div class="modal-body">
|
||||
<div id="state">🔴</div>
|
||||
<input id="iServer" type="text" style="width:25em" />
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button id="connect">connect</button>
|
||||
</div>
|
||||
</dialog>
|
||||
|
||||
<popup-info id="popHelp">hhhh</popup-info>
|
||||
|
||||
<dialog id="popSettings" popover>
|
||||
<header>Editor configuration
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"
|
||||
onclick="$('popSettings').hidePopover(); "></button>
|
||||
</header>
|
||||
<div class="modal-body">
|
||||
@TODO
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button id="connect">ok</button>
|
||||
</div>
|
||||
</dialog>
|
||||
|
||||
<!-- CodeMirror 6 -->
|
||||
<script src="./lsp.bundle.js"></script>
|
||||
<script type="module" src="../beercss-3.12.3/beer.min.js"></script>
|
||||
<script src="./beer.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
127
webapp/static/clients/codemirror/beer.js
Normal file
127
webapp/static/clients/codemirror/beer.js
Normal file
|
@ -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)
|
||||
};
|
||||
|
56
webapp/static/clients/codemirror/deepseek.html
Normal file
56
webapp/static/clients/codemirror/deepseek.html
Normal file
|
@ -0,0 +1,56 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Holy Grail Layout with BeerCSS</title>
|
||||
|
||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
}
|
||||
.container {
|
||||
display: grid;
|
||||
grid-template-rows: auto 1fr auto;
|
||||
min-height: 100vh;
|
||||
}
|
||||
.main-layout {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: 1rem;
|
||||
padding: 1rem;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
.main-layout {
|
||||
grid-template-columns: 1fr 1fr;
|
||||
}
|
||||
}
|
||||
@media (min-width: 1024px) {
|
||||
.main-layout {
|
||||
grid-template-columns: 200px 1fr 200px;
|
||||
}
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
.main-layout {
|
||||
grid-template-areas:
|
||||
"main"
|
||||
"left-sidebar"
|
||||
"right-sidebar";
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<header class="primary padding large">Header</header>
|
||||
<div class="main-layout">
|
||||
<nav class="left-sidebar surface padding">Left Sidebar</nav>
|
||||
<main class="padding">Main Content</main>
|
||||
<aside class="right-sidebar surface padding">Right Sidebar</aside>
|
||||
</div>
|
||||
<footer class="primary padding large">Footer</footer>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
Loading…
Add table
Reference in a new issue