From b41ec22aab5686437dfffc607699df63a47b4ba4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Gruszczy=C5=84ski?= Date: Wed, 5 Aug 2026 22:56:02 +0200 Subject: [PATCH] fixes and functions --- static/css/styles.css | 24 ++++++++++++++++++++++++ static/editor.html | 7 ++++++- static/js/note-editor.js | 21 ++++++++++++++++++++- static/js/note-files.js | 1 + static/js/public.js | 21 ++++++++++++++++++++- 5 files changed, 71 insertions(+), 3 deletions(-) diff --git a/static/css/styles.css b/static/css/styles.css index 1dda90a..0afe0c5 100644 --- a/static/css/styles.css +++ b/static/css/styles.css @@ -2368,6 +2368,18 @@ dialog::backdrop { font-size: .8rem; } +.files-head-actions { + display: flex; + align-items: center; + gap: 8px; + flex: 0 0 auto; +} + +.files-head-actions .primary-button, +.files-head-actions .action-button { + width: auto; +} + .files-list { display: grid; gap: 9px; @@ -2416,6 +2428,18 @@ dialog::backdrop { } @media (max-width: 620px) { + .files-head { + gap: 10px; + } + + .files-head-actions { + gap: 6px; + } + + .files-head-actions .action-button { + padding-inline: 9px; + } + .file-row { grid-template-columns: 1fr; } diff --git a/static/editor.html b/static/editor.html index 389579d..3884e74 100644 --- a/static/editor.html +++ b/static/editor.html @@ -287,7 +287,12 @@

Note files

Copy a direct link or ready Markdown/Alias code.

-
+ +
+ + +
diff --git a/static/js/note-editor.js b/static/js/note-editor.js index 71019f2..eea5745 100644 --- a/static/js/note-editor.js +++ b/static/js/note-editor.js @@ -329,7 +329,26 @@ export function startNoteEditor(adapter) { setStatus(null, "Connecting…"); } function updateAddressLabel() { document.querySelector(adapter.addressSelector).textContent = `${location.pathname}${location.search}`; } - async function renderMermaid() { const nodes = preview.querySelectorAll(".mermaid"); if (!nodes.length) return; try { const mermaid = await loadMermaid(); mermaid.initialize({ startOnLoad: false, theme: getTheme() === "dark" ? "dark" : "default", securityLevel: "strict" }); await mermaid.run({ nodes: [...nodes] }); } catch { nodes.forEach(n => n.insertAdjacentHTML("beforebegin", '

Failed to load Mermaid.

')); } } + let mermaidRenderVersion = 0; + async function renderMermaid() { + const renderVersion = ++mermaidRenderVersion; + const nodes = [...preview.querySelectorAll(".mermaid")]; + if (!nodes.length) return; + try { + const mermaid = await loadMermaid(); + mermaid.initialize({ startOnLoad: false, theme: getTheme() === "dark" ? "dark" : "default", securityLevel: "strict" }); + await mermaid.run({ nodes }); + } catch { + if (renderVersion !== mermaidRenderVersion) return; + nodes.forEach(node => { + if (!node.isConnected || !preview.contains(node) || !node.parentNode) return; + const message = document.createElement("p"); + message.className = "error mermaid-error"; + message.textContent = "Failed to load Mermaid."; + node.parentNode.insertBefore(message, node); + }); + } + } async function renderCodeHighlight() { const nodes = preview.querySelectorAll('pre code[class^="language-"]:not(.language-mermaid)'); if (!nodes.length) return; try { const hljs = await loadHighlight(); nodes.forEach(node => { const lines = node.querySelectorAll(".code-line"); if (!lines.length) { hljs.highlightElement(node); return; } const language = [...node.classList].find(name => name.startsWith("language-"))?.slice(9); lines.forEach(line => { try { line.innerHTML = hljs.highlight(line.textContent, { language, ignoreIllegals: true }).value; } catch { line.innerHTML = hljs.highlightAuto(line.textContent).value; } }); node.classList.add("hljs"); }); } catch { } } async function renderMediaPlayers() { const nodes = preview.querySelectorAll("[data-rustpad-player]"); if (!nodes.length) return; try { const { hydrateMediaPlayers } = await loadMediaPlayer(); hydrateMediaPlayers(preview); } catch { } } function renderParticipantBadges(owners) { diff --git a/static/js/note-files.js b/static/js/note-files.js index 0a06a46..dcce389 100644 --- a/static/js/note-files.js +++ b/static/js/note-files.js @@ -237,6 +237,7 @@ export function bindNoteFiles({ editor, endpoints, getAccessToken, getUploadMaxS document.querySelector("#upload-button")?.addEventListener("click", requestUpload); document.querySelector("#mobile-upload-button")?.addEventListener("click", requestUpload); + document.querySelector("#files-upload-button")?.addEventListener("click", requestUpload); input.addEventListener("change", async event => { let file = event.target.files[0]; diff --git a/static/js/public.js b/static/js/public.js index 110b6b5..423e896 100644 --- a/static/js/public.js +++ b/static/js/public.js @@ -22,8 +22,27 @@ const content = document.querySelector("#public-content"); const lineNumbersToggle = document.querySelector("#public-line-numbers-toggle"); const passwordDialog = document.querySelector("#public-password-dialog"), passwordForm = document.querySelector("#public-password-form"), passwordInput = document.querySelector("#public-password"), passwordError = document.querySelector("#public-password-error"); let pagePassword = ""; +let mermaidRenderVersion = 0; function pageHeaders() { return pagePassword ? { "X-RustPad-Page-Password": pagePassword } : {}; } -async function renderMermaid() { const nodes = content.querySelectorAll(".mermaid"); if (!nodes.length) return; try { const mermaid = await loadMermaid(); mermaid.initialize({ startOnLoad: false, theme: getTheme() === "dark" ? "dark" : "default", securityLevel: "strict" }); await mermaid.run({ nodes: [...nodes] }); } catch { nodes.forEach(n => n.insertAdjacentHTML("beforebegin", '

Failed to load Mermaid.

')); } } +async function renderMermaid() { + const renderVersion = ++mermaidRenderVersion; + const nodes = [...content.querySelectorAll(".mermaid")]; + if (!nodes.length) return; + try { + const mermaid = await loadMermaid(); + mermaid.initialize({ startOnLoad: false, theme: getTheme() === "dark" ? "dark" : "default", securityLevel: "strict" }); + await mermaid.run({ nodes }); + } catch { + if (renderVersion !== mermaidRenderVersion) return; + nodes.forEach(node => { + if (!node.isConnected || !content.contains(node) || !node.parentNode) return; + const message = document.createElement("p"); + message.className = "error mermaid-error"; + message.textContent = "Failed to load Mermaid."; + node.parentNode.insertBefore(message, node); + }); + } +} async function renderCodeHighlight() { const blocks = content.querySelectorAll('pre code[class^="language-"]'); if (!blocks.length) return; try { const hljs = await loadHighlight(); blocks.forEach(block => { const lines = block.querySelectorAll(".code-line"); if (!lines.length) { hljs.highlightElement(block); return; } const language = [...block.classList].find(name => name.startsWith("language-"))?.slice(9); lines.forEach(line => { try { line.innerHTML = hljs.highlight(line.textContent, { language, ignoreIllegals: true }).value; } catch { line.innerHTML = hljs.highlightAuto(line.textContent).value; } }); block.classList.add("hljs"); }); } catch { } } async function renderMediaPlayers() { const nodes = content.querySelectorAll("[data-rustpad-player]"); if (!nodes.length) return; try { const { hydrateMediaPlayers } = await loadMediaPlayer(); hydrateMediaPlayers(content); } catch { } } function lockPublicContent(allowTaskUpdates) {