preview changes

This commit is contained in:
schmeeve
2026-09-23 16:51:46 -07:00
parent 5c938042a3
commit 3294716337
2 changed files with 23 additions and 10 deletions

View File

@@ -325,6 +325,7 @@ body {
.editor pre code { background: none; padding: 0; } .editor pre code { background: none; padding: 0; }
.editor blockquote { border-left: 3px solid var(--secondary); margin: 0.5em 0; padding-left: 12px; color: var(--muted); } .editor blockquote { border-left: 3px solid var(--secondary); margin: 0.5em 0; padding-left: 12px; color: var(--muted); }
.editor a { color: var(--secondary); text-decoration: underline; cursor: pointer; } .editor a { color: var(--secondary); text-decoration: underline; cursor: pointer; }
.editor img { max-width: 100%; }
.editor-split { .editor-split {
display: grid; display: grid;

View File

@@ -1,6 +1,7 @@
import { Editor } from "https://esm.sh/@tiptap/core@2.11.5"; import { Editor } from "https://esm.sh/@tiptap/core@2.11.5";
import StarterKit from "https://esm.sh/@tiptap/starter-kit@2.11.5"; import StarterKit from "https://esm.sh/@tiptap/starter-kit@2.11.5";
import Link from "https://esm.sh/@tiptap/extension-link@2.11.5"; import Link from "https://esm.sh/@tiptap/extension-link@2.11.5";
import Image from "https://esm.sh/@tiptap/extension-image@2.11.5";
const root = document.getElementById("root"); const root = document.getElementById("root");
const turndownService = new TurndownService({ headingStyle: "atx", codeBlockStyle: "fenced" }); const turndownService = new TurndownService({ headingStyle: "atx", codeBlockStyle: "fenced" });
@@ -467,8 +468,9 @@ function renderEditor(body, owner) {
root.innerHTML = ""; root.innerHTML = "";
state.editor?.destroy(); state.editor?.destroy();
const back = el("button", { class: "btn ghost", text: "← Back", onclick: showHome }); const isNew = !state.noteId;
const save = el("button", { class: "btn primary", text: "Save", onclick: saveNote }); const back = el("button", { class: "btn ghost", text: "← Back", onclick: exitEditor });
const save = isNew ? null : el("button", { class: "btn primary", text: "Save", onclick: saveNote });
const del = state.noteId ? el("button", { class: "btn danger", text: "Delete", onclick: deleteNote }) : null; const del = state.noteId ? el("button", { class: "btn danger", text: "Delete", onclick: deleteNote }) : null;
const hist = state.noteId ? el("button", { class: "btn ghost", text: "History", onclick: showHistory }) : null; const hist = state.noteId ? el("button", { class: "btn ghost", text: "History", onclick: showHistory }) : null;
@@ -511,7 +513,7 @@ function renderEditor(body, owner) {
const attach = el("button", { class: "btn", text: "Attach", onclick: () => fileInput.click() }); const attach = el("button", { class: "btn", text: "Attach", onclick: () => fileInput.click() });
const wrap = el("div", { class: "editor-wrap" }, [ const wrap = el("div", { class: "editor-wrap" }, [
el("div", { class: "editor-topbar" }, [back, spaceSel, el("div", { class: "spacer" }), attach, hist, del, commonLabel, previewBtn, save]), el("div", { class: "editor-topbar" }, [back, ...(isNew ? [] : [spaceSel]), el("div", { class: "spacer" }), attach, hist, del, commonLabel, previewBtn, ...(isNew ? [] : [save])]),
toolbar, toolbar,
split, split,
hint, hint,
@@ -522,7 +524,7 @@ function renderEditor(body, owner) {
state.editor = new Editor({ state.editor = new Editor({
element: editorArea, element: editorArea,
extensions: [StarterKit, Link.configure({ openOnClick: false })], extensions: [StarterKit, Link.configure({ openOnClick: false }), Image],
content: marked.parse(body), content: marked.parse(body),
autofocus: true, autofocus: true,
}); });
@@ -530,14 +532,13 @@ function renderEditor(body, owner) {
function updatePreview() { function updatePreview() {
const md = turndownService.turndown(state.editor.getHTML()); const md = turndownService.turndown(state.editor.getHTML());
previewArea.innerHTML = marked.parse(md); previewArea.innerHTML = marked.parse(md);
previewArea.querySelectorAll("a").forEach((a) => {
a.target = "_blank";
a.rel = "noopener noreferrer";
});
} }
state.editor.on("update", updatePreview); state.editor.on("update", updatePreview);
updatePreview(); updatePreview();
previewArea.addEventListener("click", (e) => {
const a = e.target.closest("a");
if (a) e.preventDefault();
});
} }
function sep() { return el("span", { class: "sep" }); } function sep() { return el("span", { class: "sep" }); }
@@ -588,6 +589,17 @@ async function saveNote() {
if (isNew) showHome(); if (isNew) showHome();
} }
function editorIsEmpty() {
return !state.editor || state.editor.getText().trim() === "";
}
async function exitEditor() {
if (!state.noteId && !editorIsEmpty()) {
await persistNote();
}
showHome();
}
async function saveAndNewNote() { async function saveAndNewNote() {
await persistNote(); await persistNote();
openNote(null); openNote(null);
@@ -653,7 +665,7 @@ document.addEventListener("keydown", (e) => {
if (mod && e.key.toLowerCase() === "s") { if (mod && e.key.toLowerCase() === "s") {
e.preventDefault(); e.preventDefault();
if (e.shiftKey) saveAndNewNote(); if (e.shiftKey) saveAndNewNote();
else saveNote(); else persistNote();
} }
} }
}); });