live preview

This commit is contained in:
schmeeve
2026-09-23 16:34:27 -07:00
parent 67769c50d8
commit 5c938042a3
4 changed files with 60 additions and 3 deletions

View File

@@ -0,0 +1 @@
{"uploadUuid":"4dae4288f9724a00b69f76b77b1da011","channel":"unlisted","xpiCrcHash":"77714bcdd59075c7a0167c21f97f0214fbc0e80e137095ac6f3ba232aa9d08b9"}

View File

@@ -1,7 +1,7 @@
{ {
"manifest_version": 3, "manifest_version": 3,
"name": "quickSnote", "name": "quickSnote",
"version": "1.0.0", "version": "1.0.2",
"description": "Quick-capture a note to snotes from any page, with the selected text and page link ready to use", "description": "Quick-capture a note to snotes from any page, with the selected text and page link ready to use",
"permissions": [ "permissions": [
"storage" "storage"

View File

@@ -326,6 +326,47 @@ body {
.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-split {
display: grid;
grid-template-columns: 1fr 1fr;
border: 1px solid var(--border);
border-top: none;
border-radius: 0 0 var(--radius) var(--radius);
overflow: hidden;
}
.editor-split .editor {
border: none;
border-right: 1px solid var(--border);
border-radius: 0;
}
.editor-split .preview {
background: var(--surface);
padding: 16px 20px;
min-height: 60vh;
overflow-y: auto;
line-height: 1.6;
}
.editor-split.preview-hidden { grid-template-columns: 1fr; }
.editor-split.preview-hidden .preview { display: none; }
.editor-split.preview-hidden .editor { border-right: none; }
.preview-toggle.active { color: var(--primary); }
.preview h1, .preview h2, .preview h3, .preview h4 { margin: 0.5em 0 0.25em; color: var(--secondary); }
.preview h1 { font-size: 1.6em; }
.preview h2 { font-size: 1.35em; }
.preview h3 { font-size: 1.15em; }
.preview p { margin: 0.4em 0; }
.preview ul, .preview ol { padding-left: 1.5em; margin: 0.4em 0; }
.preview pre { background: var(--code-bg); color: var(--code-fg); padding: 12px; border-radius: 8px; overflow-x: auto; }
.preview code { background: color-mix(in srgb, var(--border) 55%, transparent); padding: 1px 4px; border-radius: 4px; font-size: 0.9em; }
.preview pre code { background: none; padding: 0; }
.preview blockquote { border-left: 3px solid var(--secondary); margin: 0.5em 0; padding-left: 12px; color: var(--muted); }
.preview a { color: var(--secondary); text-decoration: underline; }
.preview hr { border: none; border-top: 1px solid var(--border); margin: 1em 0; }
.preview img { max-width: 100%; }
.preview table { border-collapse: collapse; }
.preview th, .preview td { border: 1px solid var(--border); padding: 4px 8px; }
.status { margin-top: 10px; color: var(--muted); font-size: 13px; min-height: 20px; } .status { margin-top: 10px; color: var(--muted); font-size: 13px; min-height: 20px; }
.editor-hint { margin-top: 12px; padding: 10px 14px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); font-size: 13px; color: var(--muted); line-height: 1.6; } .editor-hint { margin-top: 12px; padding: 10px 14px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); font-size: 13px; color: var(--muted); line-height: 1.6; }
.editor-hint p { margin: 0.25em 0; } .editor-hint p { margin: 0.25em 0; }

View File

@@ -496,6 +496,9 @@ function renderEditor(body, owner) {
sep(), toolbarBtn("—", "horizontalRule"), sep(), toolbarBtn("—", "horizontalRule"),
]); ]);
const editorArea = el("div", { class: "editor" }); const editorArea = el("div", { class: "editor" });
const previewArea = el("div", { class: "preview" });
const split = el("div", { class: "editor-split" }, [editorArea, previewArea]);
const previewBtn = el("button", { class: "btn ghost preview-toggle active", text: "Preview", title: "Toggle live preview", onclick: () => { split.classList.toggle("preview-hidden"); previewBtn.classList.toggle("active"); } });
const status = el("div", { class: "status", text: "" }); const status = el("div", { class: "status", text: "" });
const hint = el("div", { class: "editor-hint" }, [ const hint = el("div", { class: "editor-hint" }, [
el("p", { html: 'Tags: type <code>#tag</code> anywhere in your note to add a tag.' }), el("p", { html: 'Tags: type <code>#tag</code> anywhere in your note to add a tag.' }),
@@ -508,9 +511,9 @@ 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, save]), el("div", { class: "editor-topbar" }, [back, spaceSel, el("div", { class: "spacer" }), attach, hist, del, commonLabel, previewBtn, save]),
toolbar, toolbar,
editorArea, split,
hint, hint,
status, status,
]); ]);
@@ -523,6 +526,18 @@ function renderEditor(body, owner) {
content: marked.parse(body), content: marked.parse(body),
autofocus: true, autofocus: true,
}); });
function updatePreview() {
const md = turndownService.turndown(state.editor.getHTML());
previewArea.innerHTML = marked.parse(md);
}
state.editor.on("update", 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" }); }