domma-cms 0.9.6 → 0.9.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import{api as Y}from"../api.js";import{attachEditorKeybindings as He,createToolbar as We,insertAtCursor as ke}from"../lib/markdown-toolbar.js?v=9";import{populateThemeSelect as _e}from"../lib/themes.js";import{createFoldingManager as Ye}from"../lib/editor-folding.js";function Je(){const a=E.slideover({title:"Editor Reference",size:"md",position:"right"}),ie="background:var(--dm-surface-subtle,#1a1a2e);padding:.2rem .4rem;border-radius:3px;font-size:.85em;font-family:monospace;",oe="margin:1rem 0 .5rem;font-size:1rem;";function U(T){const C=document.createElement("code");return C.style.cssText=ie,C.textContent=T,C}function J(T){const C=document.createElement("h3");return C.style.cssText=oe,C.textContent=T,C}const ze=document.createElement("div");ze.style.cssText="padding:1rem;";const $e=document.createElement("div");$e.className="tabs";const Ie=document.createElement("div");Ie.className="tab-list",["Basics","Layout","Components","Data","Advanced"].forEach((T,C)=>{const d=document.createElement("button");d.className="tab-item"+(C===0?" active":""),d.textContent=T,Ie.appendChild(d)});const W=document.createElement("div");W.className="tab-content";const Te="display:flex;flex-direction:column;gap:1rem;",Le=document.createElement("div");Le.className="tab-panel active",Le.style.cssText=Te;const ge=document.createElement("div");ge.className="tab-panel",ge.style.cssText=Te;const le=document.createElement("div");le.className="tab-panel",le.style.cssText=Te;const fe=document.createElement("div");fe.className="tab-panel",fe.style.cssText=Te;const Ce=document.createElement("div");Ce.className="tab-panel",Ce.style.cssText=Te,W.appendChild(Le),W.appendChild(ge),W.appendChild(le),W.appendChild(fe),W.appendChild(Ce),$e.appendChild(Ie),$e.appendChild(W),ze.appendChild($e);const Be=document.createElement("div");Be.appendChild(J("Markdown Basics"));const ce=document.createElement("table");ce.style.cssText="width:100%;border-collapse:collapse;font-size:.9em;";const Q=document.createElement("thead"),ne=document.createElement("tr");["Syntax","Result"].forEach(T=>{const C=document.createElement("th");C.style.cssText="text-align:left;padding:.4rem .5rem;border-bottom:1px solid var(--dm-border,#333);",C.textContent=T,ne.appendChild(C)}),Q.appendChild(ne),ce.appendChild(Q);const be=document.createElement("tbody");[["**bold**","bold (rendered bold)"],["_italic_","italic (rendered italic)"],["## Heading","Heading (h2)"],["[text](url)","Link"],["![alt](url)","Image"],["- item","Bullet list"],["`code`","Inline code"],["---","Divider"]].forEach(([T,C])=>{const d=document.createElement("tr"),s=document.createElement("td");s.style.cssText="padding:.35rem .5rem;vertical-align:top;",s.appendChild(U(T));const o=document.createElement("td");o.style.cssText="padding:.35rem .5rem;vertical-align:top;color:var(--dm-text-muted,#aaa);font-size:.85em;",o.textContent=C,d.appendChild(s),d.appendChild(o),be.appendChild(d)}),ce.appendChild(be),Be.appendChild(ce),Le.appendChild(Be);const ee=document.createElement("div");ee.appendChild(J("Grid & Columns"));function V(T){const C=document.createElement("p");return C.style.cssText="margin:.3rem 0 .6rem;font-size:.82em;color:var(--dm-text-muted,#aaa);",C.textContent=T,C}function z(T,C,d){const s=document.createElement("p");s.style.cssText="margin:.75rem 0 .25rem;font-size:.85em;font-weight:600;",s.textContent=T;const o=document.createElement("div");o.style.cssText="position:relative;";const he=document.createElement("pre");he.style.cssText=ie+"display:block;padding:.5rem 2rem .5rem .75rem;white-space:pre;overflow-x:auto;margin:0;",he.textContent=C;const H=document.createElement("button");H.type="button",H.title="Copy code",H.style.cssText="position:absolute;top:.3rem;right:.3rem;background:none;border:none;cursor:pointer;opacity:.45;padding:.15rem;line-height:1;color:inherit;",H.addEventListener("mouseenter",()=>{H.style.opacity="1"}),H.addEventListener("mouseleave",()=>{H.style.opacity=".45"});const X=document.createElement("span");X.setAttribute("data-icon","copy"),H.appendChild(X),H.addEventListener("click",()=>{const L=document.createElement("textarea");L.value=C,L.style.cssText="position:fixed;opacity:0;",document.body.appendChild(L),L.select(),document.execCommand("copy"),L.remove(),E.toast("Copied!",{type:"success",duration:1200})}),o.appendChild(he),o.appendChild(H);const P=document.createDocumentFragment();return P.appendChild(s),P.appendChild(o),d&&P.appendChild(V(d)),P}const ae=document.createElement("table");ae.style.cssText="width:100%;border-collapse:collapse;font-size:.85em;margin-bottom:.5rem;",[['cols="N"',"[grid] only","Number of columns (1\u201312)"],['gap="N"',"[grid], [row]","Gap between columns/rows (1\u20136)"],['span="N"',"[col] only","How many columns this cell spans"],['fullwidth="true"',"[grid] only","Break out of page container to span full viewport"],['class="x"',"all","Add extra CSS classes"]].forEach(([T,C,d])=>{const s=document.createElement("tr");[T,C,d].forEach((o,he)=>{const H=document.createElement("td");H.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;",he===0?H.appendChild(U(T)):(H.style.color="var(--dm-text-muted,#aaa)",H.textContent=o),s.appendChild(H)}),ae.appendChild(s)}),ee.appendChild(ae),ee.appendChild(z("Equal columns",`[grid cols="3" gap="4"]
1
+ import{api as Y}from"../api.js";import{CardBuilder as He}from"../lib/card-builder.js?v=4";import{attachEditorKeybindings as We,createToolbar as _e,insertAtCursor as ke}from"../lib/markdown-toolbar.js?v=9";import{populateThemeSelect as Ye}from"../lib/themes.js";import{createFoldingManager as Je}from"../lib/editor-folding.js";function Qe(){const a=E.slideover({title:"Editor Reference",size:"md",position:"right"}),ie="background:var(--dm-surface-subtle,#1a1a2e);padding:.2rem .4rem;border-radius:3px;font-size:.85em;font-family:monospace;",oe="margin:1rem 0 .5rem;font-size:1rem;";function U(T){const C=document.createElement("code");return C.style.cssText=ie,C.textContent=T,C}function J(T){const C=document.createElement("h3");return C.style.cssText=oe,C.textContent=T,C}const ze=document.createElement("div");ze.style.cssText="padding:1rem;";const $e=document.createElement("div");$e.className="tabs";const Ie=document.createElement("div");Ie.className="tab-list",["Basics","Layout","Components","Data","Advanced"].forEach((T,C)=>{const d=document.createElement("button");d.className="tab-item"+(C===0?" active":""),d.textContent=T,Ie.appendChild(d)});const W=document.createElement("div");W.className="tab-content";const Te="display:flex;flex-direction:column;gap:1rem;",Le=document.createElement("div");Le.className="tab-panel active",Le.style.cssText=Te;const ge=document.createElement("div");ge.className="tab-panel",ge.style.cssText=Te;const le=document.createElement("div");le.className="tab-panel",le.style.cssText=Te;const fe=document.createElement("div");fe.className="tab-panel",fe.style.cssText=Te;const Ce=document.createElement("div");Ce.className="tab-panel",Ce.style.cssText=Te,W.appendChild(Le),W.appendChild(ge),W.appendChild(le),W.appendChild(fe),W.appendChild(Ce),$e.appendChild(Ie),$e.appendChild(W),ze.appendChild($e);const Be=document.createElement("div");Be.appendChild(J("Markdown Basics"));const ce=document.createElement("table");ce.style.cssText="width:100%;border-collapse:collapse;font-size:.9em;";const Q=document.createElement("thead"),ne=document.createElement("tr");["Syntax","Result"].forEach(T=>{const C=document.createElement("th");C.style.cssText="text-align:left;padding:.4rem .5rem;border-bottom:1px solid var(--dm-border,#333);",C.textContent=T,ne.appendChild(C)}),Q.appendChild(ne),ce.appendChild(Q);const be=document.createElement("tbody");[["**bold**","bold (rendered bold)"],["_italic_","italic (rendered italic)"],["## Heading","Heading (h2)"],["[text](url)","Link"],["![alt](url)","Image"],["- item","Bullet list"],["`code`","Inline code"],["---","Divider"]].forEach(([T,C])=>{const d=document.createElement("tr"),s=document.createElement("td");s.style.cssText="padding:.35rem .5rem;vertical-align:top;",s.appendChild(U(T));const o=document.createElement("td");o.style.cssText="padding:.35rem .5rem;vertical-align:top;color:var(--dm-text-muted,#aaa);font-size:.85em;",o.textContent=C,d.appendChild(s),d.appendChild(o),be.appendChild(d)}),ce.appendChild(be),Be.appendChild(ce),Le.appendChild(Be);const ee=document.createElement("div");ee.appendChild(J("Grid & Columns"));function V(T){const C=document.createElement("p");return C.style.cssText="margin:.3rem 0 .6rem;font-size:.82em;color:var(--dm-text-muted,#aaa);",C.textContent=T,C}function z(T,C,d){const s=document.createElement("p");s.style.cssText="margin:.75rem 0 .25rem;font-size:.85em;font-weight:600;",s.textContent=T;const o=document.createElement("div");o.style.cssText="position:relative;";const he=document.createElement("pre");he.style.cssText=ie+"display:block;padding:.5rem 2rem .5rem .75rem;white-space:pre;overflow-x:auto;margin:0;",he.textContent=C;const H=document.createElement("button");H.type="button",H.title="Copy code",H.style.cssText="position:absolute;top:.3rem;right:.3rem;background:none;border:none;cursor:pointer;opacity:.45;padding:.15rem;line-height:1;color:inherit;",H.addEventListener("mouseenter",()=>{H.style.opacity="1"}),H.addEventListener("mouseleave",()=>{H.style.opacity=".45"});const X=document.createElement("span");X.setAttribute("data-icon","copy"),H.appendChild(X),H.addEventListener("click",()=>{const L=document.createElement("textarea");L.value=C,L.style.cssText="position:fixed;opacity:0;",document.body.appendChild(L),L.select(),document.execCommand("copy"),L.remove(),E.toast("Copied!",{type:"success",duration:1200})}),o.appendChild(he),o.appendChild(H);const P=document.createDocumentFragment();return P.appendChild(s),P.appendChild(o),d&&P.appendChild(V(d)),P}const ae=document.createElement("table");ae.style.cssText="width:100%;border-collapse:collapse;font-size:.85em;margin-bottom:.5rem;",[['cols="N"',"[grid] only","Number of columns (1\u201312)"],['gap="N"',"[grid], [row]","Gap between columns/rows (1\u20136)"],['span="N"',"[col] only","How many columns this cell spans"],['fullwidth="true"',"[grid] only","Break out of page container to span full viewport"],['class="x"',"all","Add extra CSS classes"]].forEach(([T,C,d])=>{const s=document.createElement("tr");[T,C,d].forEach((o,he)=>{const H=document.createElement("td");H.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;",he===0?H.appendChild(U(T)):(H.style.color="var(--dm-text-muted,#aaa)",H.textContent=o),s.appendChild(H)}),ae.appendChild(s)}),ee.appendChild(ae),ee.appendChild(z("Equal columns",`[grid cols="3" gap="4"]
2
2
  [col]One[/col]
3
3
  [col]Two[/col]
4
4
  [col]Three[/col]
@@ -81,11 +81,11 @@ In active development.
81
81
  Markdown content here.
82
82
  [/slideover]`,"Nested [card] and [grid] shortcodes work inside the slideover body.")),le.appendChild(B);const i=document.createElement("div");i.appendChild(J("DConfig \u2014 Declarative Behaviour")),i.appendChild(V("Define click handlers and class toggles without writing JavaScript. Use the DConfig section above or embed inline with [dconfig]...[/dconfig] in the content body. Inline shortcodes win on selector conflict.")),i.appendChild(z("Toggle a class on click",'{ "#my-btn": { "events": { "click": { "target": "#panel", "toggleClass": "hidden" } } } }','Selector keys use standard CSS selectors. "target" is optional \u2014 defaults to the element itself.')),i.appendChild(z("Inline shortcode syntax",`[dconfig]
83
83
  { "#my-btn": { "events": { "click": { "target": "#panel", "toggleClass": "hidden" } } } }
84
- [/dconfig]`,null)),Ce.appendChild(i);const g=document.createElement("div");g.appendChild(J("CSS Editor")),g.appendChild(V("The toolbar's </> button (left of the Split View icon) swaps the left pane between Markdown and Custom CSS. Edits are saved together with the page \u2014 one Save, one toast."));const n=document.createElement("table");n.style.cssText="width:100%;border-collapse:collapse;font-size:.85em;margin-bottom:.5rem;",[["</> button","Toggle between Markdown editor and Custom CSS editor"],["Split / Write / Preview","Standard view mode buttons to the right of </>"],["Save","Saves both page content and CSS in a single operation"]].forEach(([T,C])=>{const d=document.createElement("tr"),s=document.createElement("td");s.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;",s.appendChild(U(T));const o=document.createElement("td");o.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;color:var(--dm-text-muted,#aaa);",o.textContent=C,d.appendChild(s),d.appendChild(o),n.appendChild(d)}),g.appendChild(n),Ce.appendChild(g);const r=document.createElement("div");r.appendChild(J("Colour Picker")),r.appendChild(V("Insert \u2192 Colour Picker opens a centred colour picker. Pick a colour, then use Copy to copy the hex code to the clipboard or Insert to drop it at the cursor. Click outside the panel to dismiss.")),Ce.appendChild(r);const v=document.createElement("div");v.appendChild(J("Keyboard Shortcuts"));const A=document.createElement("table");A.style.cssText="width:100%;border-collapse:collapse;font-size:.85em;margin-bottom:.5rem;",[["Ctrl + B","Bold selected text"],["Ctrl + I","Italic selected text"],["Ctrl + K","Insert link dialog"],["Tab","Indent 2 spaces at cursor"],["Shift + Tab","Dedent 2 spaces on current line"],["Ctrl + X","Cut current line (no selection) or cut selection"],["Ctrl + C","Copy current line (no selection) or copy selection"],["Ctrl + V","Paste from clipboard"],["Ctrl + Z","Undo"],["Ctrl + Y","Redo"]].forEach(([T,C])=>{const d=document.createElement("tr"),s=document.createElement("td");s.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;white-space:nowrap;",s.appendChild(U(T));const o=document.createElement("td");o.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;color:var(--dm-text-muted,#aaa);",o.textContent=C,d.appendChild(s),d.appendChild(o),A.appendChild(d)}),v.appendChild(A),Le.appendChild(v);const q=document.createElement("div");q.appendChild(J("Tips"));const j=document.createElement("table");j.style.cssText="width:100%;border-collapse:collapse;font-size:.85em;margin-bottom:.5rem;",[['class="text-center"',"Centre text and inline elements on any shortcode"],['class="mx-auto"',"Centre a block element horizontally"],["[center]...[/center]","Shorthand wrapper for centred content"]].forEach(([T,C])=>{const d=document.createElement("tr"),s=document.createElement("td");s.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;",s.appendChild(U(T));const o=document.createElement("td");o.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;color:var(--dm-text-muted,#aaa);",o.textContent=C,d.appendChild(s),d.appendChild(o),j.appendChild(d)}),q.appendChild(j),q.appendChild(V("Most shortcodes accept a class attribute for custom styling.")),Le.appendChild(q),a.setContent(ze),a.open(),E.tabs($e),I.scan(ze)}function Qe(a,ie){const oe=a.find("#history-tab").get(0),U=a.find("#version-list").get(0),J=a.find("#version-compare").get(0),ze=a.find("#version-compare-old").get(0),$e=a.find("#version-compare-new").get(0),Ie=a.find("#version-compare-label").get(0),W=a.find("#version-compare-back-btn").get(0),Te=a.find("#version-restore-btn").get(0),Le=a.find("#history-save-named-btn").get(0),ge=a.find("#history-delete-selected-btn").get(0);let le=!1,fe=null;function Ce(){U.style.display="",J.style.display="none",fe=null}function Be(){U.style.display="none",J.style.display=""}async function ce(){U.textContent="";const Q=document.createElement("p");Q.style.color="var(--dm-text-muted)",Q.textContent="Loading\u2026",U.appendChild(Q);let ne;try{ne=(await Y.versions.list(ie)).versions||[]}catch(M){U.textContent="";const Z=document.createElement("p");Z.style.color="var(--dm-text-danger,#e55)",Z.textContent="Failed to load versions: "+M.message,U.appendChild(Z);return}if(U.textContent="",ge.style.display="none",!ne.length){const M=document.createElement("p");M.style.color="var(--dm-text-muted)",M.textContent="No versions saved yet. Versions are created automatically on each save.",U.appendChild(M);return}const be=document.createElement("table");be.style.cssText="width:100%;border-collapse:collapse;font-size:.875rem;";const ee=document.createElement("thead"),V=document.createElement("tr"),z=document.createElement("th");z.style.cssText="padding:.5rem .75rem;width:2rem;border-bottom:1px solid var(--dm-border);";const ae=document.createElement("input");ae.type="checkbox",ae.setAttribute("aria-label","Select all versions"),z.appendChild(ae),V.appendChild(z),["Date","Author","Type","Label","Actions"].forEach(M=>{const Z=document.createElement("th");Z.style.cssText="text-align:left;padding:.5rem .75rem;border-bottom:1px solid var(--dm-border);font-size:.8rem;color:var(--dm-text-muted);",Z.textContent=M,V.appendChild(Z)}),ee.appendChild(V),be.appendChild(ee);const pe=[];function ye(){const M=pe.some(se=>se.checked),Z=pe.length>0&&pe.every(se=>se.checked);ge.style.display=M?"":"none",ae.checked=Z,ae.indeterminate=M&&!Z}ae.addEventListener("change",()=>{pe.forEach(M=>{M.checked=ae.checked}),ye()});const De=document.createElement("tbody");ne.forEach(M=>{const Z=document.createElement("tr");Z.style.borderBottom="1px solid var(--dm-border)";const se=document.createElement("td");se.style.padding=".5rem .75rem";const xe=document.createElement("input");xe.type="checkbox",xe.value=M.filename,xe.addEventListener("change",ye),se.appendChild(xe),pe.push(xe);const de=document.createElement("td");de.style.padding=".5rem .75rem",de.textContent=D(M.createdAt).format("D MMM YYYY, HH:mm");const Ne=document.createElement("td");Ne.style.padding=".5rem .75rem",Ne.textContent=M.author||"\u2014";const me=document.createElement("td");me.style.padding=".5rem .75rem";const Se=document.createElement("span");Se.className="badge badge-"+(M.type==="manual"?"primary":"secondary"),Se.style.cssText="font-size:.75rem;padding:.2rem .5rem;border-radius:4px;",Se.textContent=M.type,me.appendChild(Se);const Ee=document.createElement("td");Ee.style.cssText="padding:.5rem .75rem;color:var(--dm-text-muted);",Ee.textContent=M.label||"\u2014";const te=document.createElement("td");te.style.padding=".5rem .75rem";const ve=document.createElement("button");ve.className="btn btn-ghost btn-xs",ve.style.marginRight=".4rem",ve.textContent="Compare",ve.addEventListener("click",async()=>{try{const ue=await Y.versions.get(ie,M.filename);ze.textContent=ue.content,$e.textContent=a.find("#markdown-editor").get(0).value,Ie.textContent=D(M.createdAt).format("D MMM YYYY, HH:mm")+(M.label?` \u2014 ${M.label}`:""),fe=M.filename,Be()}catch(ue){E.toast("Failed to load version: "+ue.message,{type:"error"})}});const re=document.createElement("button");re.className="btn btn-ghost btn-xs",re.style.color="var(--dm-text-danger,#e55)",re.textContent="Delete",re.addEventListener("click",async()=>{if(await E.confirm("Delete this version? This cannot be undone."))try{await Y.versions.delete(ie,M.filename),E.toast("Version deleted.",{type:"success"}),await ce()}catch(ue){E.toast("Failed to delete: "+ue.message,{type:"error"})}}),te.appendChild(ve),te.appendChild(re),Z.appendChild(se),Z.appendChild(de),Z.appendChild(Ne),Z.appendChild(me),Z.appendChild(Ee),Z.appendChild(te),De.appendChild(Z)}),be.appendChild(De),U.appendChild(be)}oe.addEventListener("click",async()=>{le||(le=!0,await ce())}),W.addEventListener("click",()=>{Ce()}),Te.addEventListener("click",async()=>{if(!(!fe||!await E.confirm("Restore this version? The current page content will be overwritten (a pre-restore snapshot will be saved automatically).")))try{await Y.versions.restore(ie,fe),E.toast("Page restored. Reloading editor\u2026",{type:"success"}),R.navigate("/pages"),setTimeout(()=>R.navigate(`/pages/edit${ie}`),300)}catch(Q){E.toast("Restore failed: "+Q.message,{type:"error"})}}),ge.addEventListener("click",async()=>{const Q=[...U.querySelectorAll("tbody input[type=checkbox]:checked")].map(ne=>ne.value);if(!(!Q.length||!await E.confirm(`Delete ${Q.length} version${Q.length>1?"s":""}? This cannot be undone.`)))try{await Y.versions.bulkDelete(ie,Q),E.toast(`${Q.length} version${Q.length>1?"s":""} deleted.`,{type:"success"}),await ce()}catch(ne){E.toast("Delete failed: "+ne.message,{type:"error"})}}),Le.addEventListener("click",()=>{const Q=E.modal({title:"Save Named Version"}),ne=document.createElement("div");ne.style.padding="1rem";const be=document.createElement("label");be.className="form-label",be.textContent="Version Label";const ee=document.createElement("input");ee.type="text",ee.className="form-input",ee.placeholder="e.g. Initial design, Before restructure",ee.style.marginBottom=".75rem";const V=document.createElement("button");V.className="btn btn-primary",V.textContent="Save Version",V.addEventListener("click",async()=>{const z=ee.value.trim();try{await Y.versions.create(ie,z||null),E.toast("Named version saved.",{type:"success"}),Q.close(),le=!1,oe.classList.contains("active")&&(le=!0,await ce())}catch(ae){E.toast("Failed to save version: "+ae.message,{type:"error"})}}),ne.appendChild(be),ne.appendChild(ee),ne.appendChild(V),Q.element.appendChild(ne),Q.open(),setTimeout(()=>ee.focus(),100)})}let Ae=!1,Pe=null,Oe=!1;function Ke(a){return a.split(`
84
+ [/dconfig]`,null)),Ce.appendChild(i);const g=document.createElement("div");g.appendChild(J("CSS Editor")),g.appendChild(V("The toolbar's </> button (left of the Split View icon) swaps the left pane between Markdown and Custom CSS. Edits are saved together with the page \u2014 one Save, one toast."));const n=document.createElement("table");n.style.cssText="width:100%;border-collapse:collapse;font-size:.85em;margin-bottom:.5rem;",[["</> button","Toggle between Markdown editor and Custom CSS editor"],["Split / Write / Preview","Standard view mode buttons to the right of </>"],["Save","Saves both page content and CSS in a single operation"]].forEach(([T,C])=>{const d=document.createElement("tr"),s=document.createElement("td");s.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;",s.appendChild(U(T));const o=document.createElement("td");o.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;color:var(--dm-text-muted,#aaa);",o.textContent=C,d.appendChild(s),d.appendChild(o),n.appendChild(d)}),g.appendChild(n),Ce.appendChild(g);const r=document.createElement("div");r.appendChild(J("Colour Picker")),r.appendChild(V("Insert \u2192 Colour Picker opens a centred colour picker. Pick a colour, then use Copy to copy the hex code to the clipboard or Insert to drop it at the cursor. Click outside the panel to dismiss.")),Ce.appendChild(r);const v=document.createElement("div");v.appendChild(J("Keyboard Shortcuts"));const A=document.createElement("table");A.style.cssText="width:100%;border-collapse:collapse;font-size:.85em;margin-bottom:.5rem;",[["Ctrl + B","Bold selected text"],["Ctrl + I","Italic selected text"],["Ctrl + K","Insert link dialog"],["Tab","Indent 2 spaces at cursor"],["Shift + Tab","Dedent 2 spaces on current line"],["Ctrl + X","Cut current line (no selection) or cut selection"],["Ctrl + C","Copy current line (no selection) or copy selection"],["Ctrl + V","Paste from clipboard"],["Ctrl + Z","Undo"],["Ctrl + Y","Redo"]].forEach(([T,C])=>{const d=document.createElement("tr"),s=document.createElement("td");s.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;white-space:nowrap;",s.appendChild(U(T));const o=document.createElement("td");o.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;color:var(--dm-text-muted,#aaa);",o.textContent=C,d.appendChild(s),d.appendChild(o),A.appendChild(d)}),v.appendChild(A),Le.appendChild(v);const q=document.createElement("div");q.appendChild(J("Tips"));const j=document.createElement("table");j.style.cssText="width:100%;border-collapse:collapse;font-size:.85em;margin-bottom:.5rem;",[['class="text-center"',"Centre text and inline elements on any shortcode"],['class="mx-auto"',"Centre a block element horizontally"],["[center]...[/center]","Shorthand wrapper for centred content"]].forEach(([T,C])=>{const d=document.createElement("tr"),s=document.createElement("td");s.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;",s.appendChild(U(T));const o=document.createElement("td");o.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;color:var(--dm-text-muted,#aaa);",o.textContent=C,d.appendChild(s),d.appendChild(o),j.appendChild(d)}),q.appendChild(j),q.appendChild(V("Most shortcodes accept a class attribute for custom styling.")),Le.appendChild(q),a.setContent(ze),a.open(),E.tabs($e),I.scan(ze)}function Ke(a,ie){const oe=a.find("#history-tab").get(0),U=a.find("#version-list").get(0),J=a.find("#version-compare").get(0),ze=a.find("#version-compare-old").get(0),$e=a.find("#version-compare-new").get(0),Ie=a.find("#version-compare-label").get(0),W=a.find("#version-compare-back-btn").get(0),Te=a.find("#version-restore-btn").get(0),Le=a.find("#history-save-named-btn").get(0),ge=a.find("#history-delete-selected-btn").get(0);let le=!1,fe=null;function Ce(){U.style.display="",J.style.display="none",fe=null}function Be(){U.style.display="none",J.style.display=""}async function ce(){U.textContent="";const Q=document.createElement("p");Q.style.color="var(--dm-text-muted)",Q.textContent="Loading\u2026",U.appendChild(Q);let ne;try{ne=(await Y.versions.list(ie)).versions||[]}catch(M){U.textContent="";const Z=document.createElement("p");Z.style.color="var(--dm-text-danger,#e55)",Z.textContent="Failed to load versions: "+M.message,U.appendChild(Z);return}if(U.textContent="",ge.style.display="none",!ne.length){const M=document.createElement("p");M.style.color="var(--dm-text-muted)",M.textContent="No versions saved yet. Versions are created automatically on each save.",U.appendChild(M);return}const be=document.createElement("table");be.style.cssText="width:100%;border-collapse:collapse;font-size:.875rem;";const ee=document.createElement("thead"),V=document.createElement("tr"),z=document.createElement("th");z.style.cssText="padding:.5rem .75rem;width:2rem;border-bottom:1px solid var(--dm-border);";const ae=document.createElement("input");ae.type="checkbox",ae.setAttribute("aria-label","Select all versions"),z.appendChild(ae),V.appendChild(z),["Date","Author","Type","Label","Actions"].forEach(M=>{const Z=document.createElement("th");Z.style.cssText="text-align:left;padding:.5rem .75rem;border-bottom:1px solid var(--dm-border);font-size:.8rem;color:var(--dm-text-muted);",Z.textContent=M,V.appendChild(Z)}),ee.appendChild(V),be.appendChild(ee);const pe=[];function ye(){const M=pe.some(se=>se.checked),Z=pe.length>0&&pe.every(se=>se.checked);ge.style.display=M?"":"none",ae.checked=Z,ae.indeterminate=M&&!Z}ae.addEventListener("change",()=>{pe.forEach(M=>{M.checked=ae.checked}),ye()});const De=document.createElement("tbody");ne.forEach(M=>{const Z=document.createElement("tr");Z.style.borderBottom="1px solid var(--dm-border)";const se=document.createElement("td");se.style.padding=".5rem .75rem";const xe=document.createElement("input");xe.type="checkbox",xe.value=M.filename,xe.addEventListener("change",ye),se.appendChild(xe),pe.push(xe);const de=document.createElement("td");de.style.padding=".5rem .75rem",de.textContent=D(M.createdAt).format("D MMM YYYY, HH:mm");const Ne=document.createElement("td");Ne.style.padding=".5rem .75rem",Ne.textContent=M.author||"\u2014";const me=document.createElement("td");me.style.padding=".5rem .75rem";const Se=document.createElement("span");Se.className="badge badge-"+(M.type==="manual"?"primary":"secondary"),Se.style.cssText="font-size:.75rem;padding:.2rem .5rem;border-radius:4px;",Se.textContent=M.type,me.appendChild(Se);const Ee=document.createElement("td");Ee.style.cssText="padding:.5rem .75rem;color:var(--dm-text-muted);",Ee.textContent=M.label||"\u2014";const te=document.createElement("td");te.style.padding=".5rem .75rem";const ve=document.createElement("button");ve.className="btn btn-ghost btn-xs",ve.style.marginRight=".4rem",ve.textContent="Compare",ve.addEventListener("click",async()=>{try{const ue=await Y.versions.get(ie,M.filename);ze.textContent=ue.content,$e.textContent=a.find("#markdown-editor").get(0).value,Ie.textContent=D(M.createdAt).format("D MMM YYYY, HH:mm")+(M.label?` \u2014 ${M.label}`:""),fe=M.filename,Be()}catch(ue){E.toast("Failed to load version: "+ue.message,{type:"error"})}});const re=document.createElement("button");re.className="btn btn-ghost btn-xs",re.style.color="var(--dm-text-danger,#e55)",re.textContent="Delete",re.addEventListener("click",async()=>{if(await E.confirm("Delete this version? This cannot be undone."))try{await Y.versions.delete(ie,M.filename),E.toast("Version deleted.",{type:"success"}),await ce()}catch(ue){E.toast("Failed to delete: "+ue.message,{type:"error"})}}),te.appendChild(ve),te.appendChild(re),Z.appendChild(se),Z.appendChild(de),Z.appendChild(Ne),Z.appendChild(me),Z.appendChild(Ee),Z.appendChild(te),De.appendChild(Z)}),be.appendChild(De),U.appendChild(be)}oe.addEventListener("click",async()=>{le||(le=!0,await ce())}),W.addEventListener("click",()=>{Ce()}),Te.addEventListener("click",async()=>{if(!(!fe||!await E.confirm("Restore this version? The current page content will be overwritten (a pre-restore snapshot will be saved automatically).")))try{await Y.versions.restore(ie,fe),E.toast("Page restored. Reloading editor\u2026",{type:"success"}),R.navigate("/pages"),setTimeout(()=>R.navigate(`/pages/edit${ie}`),300)}catch(Q){E.toast("Restore failed: "+Q.message,{type:"error"})}}),ge.addEventListener("click",async()=>{const Q=[...U.querySelectorAll("tbody input[type=checkbox]:checked")].map(ne=>ne.value);if(!(!Q.length||!await E.confirm(`Delete ${Q.length} version${Q.length>1?"s":""}? This cannot be undone.`)))try{await Y.versions.bulkDelete(ie,Q),E.toast(`${Q.length} version${Q.length>1?"s":""} deleted.`,{type:"success"}),await ce()}catch(ne){E.toast("Delete failed: "+ne.message,{type:"error"})}}),Le.addEventListener("click",()=>{const Q=E.modal({title:"Save Named Version"}),ne=document.createElement("div");ne.style.padding="1rem";const be=document.createElement("label");be.className="form-label",be.textContent="Version Label";const ee=document.createElement("input");ee.type="text",ee.className="form-input",ee.placeholder="e.g. Initial design, Before restructure",ee.style.marginBottom=".75rem";const V=document.createElement("button");V.className="btn btn-primary",V.textContent="Save Version",V.addEventListener("click",async()=>{const z=ee.value.trim();try{await Y.versions.create(ie,z||null),E.toast("Named version saved.",{type:"success"}),Q.close(),le=!1,oe.classList.contains("active")&&(le=!0,await ce())}catch(ae){E.toast("Failed to save version: "+ae.message,{type:"error"})}}),ne.appendChild(be),ne.appendChild(ee),ne.appendChild(V),Q.element.appendChild(ne),Q.open(),setTimeout(()=>ee.focus(),100)})}let Ae=!1,Pe=null,Oe=!1;function Ze(a){return a.split(`
85
85
  `).map(ie=>ie.trimEnd()).join(`
86
86
  `).replace(/\n{3,}/g,`
87
87
 
88
- `)}const Ge="editor_prefs";function Ue(){return S.get(Ge)||{viewMode:"split",fullscreen:!1}}function Ve(a,ie){const oe=Ue();oe[a]=ie,S.set(Ge,oe)}export const pageEditorView={templateUrl:"/admin/js/templates/page-editor.html",async onMount(a){const ie=window.location.hash.match(/#\/pages\/edit(\/.*)/),oe=ie?ie[1]:null,U=!!oe,J=E.loader(a.get(0),{type:"dots"}),ze=[Y.layouts.get().catch(()=>({})),Y.settings.get().catch(()=>({}))];U&&(ze.push(Y.pages.get(oe).catch(()=>null)),ze.push(Y.pages.list().catch(()=>[])));const[$e,Ie,W,Te]=await Promise.all(ze);J.destroy(),_e(a.find("#field-theme").get(0),{includeDefault:!0});const Le=Ie?.layoutOptions?.spacerSize??40;if(U&&!W){E.toast("Page not found.",{type:"error"}),R.navigate("/pages");return}a.find("#editor-title").text(U?`Edit Page \u2014 ${W.title||oe}`:"New Page"),U&&a.find("#page-url-path").val(oe),W&&(a.find("#field-title").val(W.title||""),a.find("#field-description").val(W.description||""),a.find("#field-status").val(W.status||"draft"),a.find("#field-sort-order").val(W.sortOrder??99),a.find("#field-show-in-nav").prop("checked",!!W.showInNav),a.find("#field-sidebar").prop("checked",!!W.sidebar),a.find("#field-show-breadcrumbs").prop("checked",W.breadcrumbs!==!1),a.find("#field-bundled").prop("checked",!!W.bundled),a.find("#field-category").val(W.category||""),a.find("#field-visibility").val(W.visibility||"public"),a.find("#field-theme").val(W.theme||""),a.find("#field-seo-title").val(W.seo?.title||""),a.find("#field-seo-desc").val(W.seo?.description||""),W.dconfig&&a.find("#field-dconfig").val(JSON.stringify(W.dconfig,null,2)));const ge=a.find("#quick-switch");U&&Array.isArray(Te)&&Te.length&&([...Te].sort((e,l)=>(e.title||e.urlPath).localeCompare(l.title||l.urlPath)).forEach(e=>{const l=document.createElement("option");l.value=e.urlPath,l.textContent=`${e.title||"Untitled"} (${e.urlPath})`,e.urlPath===oe&&(l.selected=!0),ge.get(0).appendChild(l)}),ge.css("display",""),ge.on("change",function(){const e=this.value;e&&R.navigate("/pages/edit"+e)}));const le=await Y.pages.tags().catch(()=>[]),fe=a.find("#field-tags").get(0),Ce=fe?E.pillbox(fe,{data:le,value:W?.tags||[],creatable:!0,searchable:!0,placeholder:"Add tag\u2026"}):null,Be=a.find("#field-layout").empty();if(Object.entries($e).forEach(([e,l])=>{const t=(W?.layout||"default")===e?"selected":"";Be.append(`<option value="${e}" ${t}>${l.label||e}</option>`)}),U){const e=a.find("#view-page-btn").get(0);e.href=oe,e.style.display="";const l=a.find("#live-preview-tab").get(0);l.style.display="";const t=a.find("#history-tab").get(0);t.style.display=""}if(E.tabs(a.find("#editor-meta-tabs").get(0)),U){const e=a.find("#live-preview-tab").get(0),l=a.find("#live-preview-frame").get(0);let t=!1;e.addEventListener("click",function(){t||(l.src=oe,t=!0)}),Qe(a,oe)}const ce=a.find("#markdown-editor"),Q=a.find("#markdown-preview");W&&ce.val(W.content||"");let ne=!1,be="";Y.settings.getCustomCss().then(({css:e})=>{if(be=e||"",!be)return;const l=document.createElement("style");l.id="preview-custom-css",l.textContent=be,Q.get(0).parentNode.insertBefore(l,Q.get(0))}).catch(()=>{});let ee=!1;const V=ce.get(0),z=document.createElement("div");z.className="editor-line-numbers editor-line-numbers--foldable",V.parentElement.insertBefore(z,V);const ae=Ye(V,z,{onFoldChange:()=>{}});ae.setGuard(e=>{ee=e});const pe=()=>{ae.refresh(),z.scrollTop=V.scrollTop};V.addEventListener("input",pe),V.addEventListener("scroll",()=>{z.scrollTop=V.scrollTop});let ye=null;const De=()=>{clearTimeout(ye),ye=setTimeout(async()=>{const e=ae.getUnfoldedContent();try{const{html:l}=await Y.pages.preview(e);Q.html(l,{safe:!1}),I.scan(Q.get(0)),Q.get(0).querySelectorAll(".tabs").forEach(t=>Domma.elements.tabs(t))}catch{window.marked&&Q.html(marked.parse(e))}},400)},M=We(ce,a.find("#editor-toolbar"),{spacerDefault:Le});let Z=!1,se="split",xe=null;const de=document.createElement("button");de.className="editor-view-btn",de.type="button";const Ne=document.createElement("span");Ne.setAttribute("data-icon","css-code"),de.appendChild(Ne);const me=document.createElement("button");me.className="editor-view-btn",me.type="button";const Se=document.createElement("span");Se.setAttribute("data-icon","code"),me.appendChild(Se);let Ee=!1;const te=document.createElement("button");te.className="editor-view-btn",te.type="button",te.textContent="\u25BC\u25BC",te.style.cssText="font-size:9px;letter-spacing:-1px;";const ve=a.find(".editor-toolbar-right").get(0);ve.prepend(te),ve.prepend(me),ve.prepend(de),I.scan(de),I.scan(me),E.tooltip(de,{content:"Edit Custom CSS",position:"top"}),E.tooltip(me,{content:"Format Markdown",position:"top"}),E.tooltip(te,{content:"Fold / unfold all shortcodes",position:"top"}),me.addEventListener("click",()=>{const e=ce.get(0),l=e.selectionStart,t=Ke(ae.getUnfoldedContent());ae.unfoldAll(),ee=!0,e.value=t,ee=!1,e.selectionStart=e.selectionEnd=Math.min(l,t.length),e.dispatchEvent(new Event("input")),ae.refresh(),E.toast("Markdown formatted.",{type:"success"})}),te.addEventListener("click",()=>{Ee?(ae.unfoldAll(),te.textContent="\u25BC\u25BC",te.classList.remove("active")):(ae.foldAll(),te.textContent="\u25B6\u25B6",te.classList.add("active")),Ee=!Ee});const re=document.createElement("span");re.className="editor-toolbar-sep",ve.insertBefore(re,ve.children[3]),de.addEventListener("click",()=>{Z=!Z;const e=a.find("#markdown-editor"),l=a.find("#css-editor"),t=a.find("#editor-body");if(Z){const k=a.find(".editor-view-btn[data-mode].active").get(0);se=k?k.getAttribute("data-mode"):"split",a.find(".editor-view-btn[data-mode]").removeClass("active"),a.find('.editor-view-btn[data-mode="split"]').addClass("active"),t.removeClass("editor-mode-write editor-mode-preview").addClass("editor-mode-split"),e.hide(),l.show(),ne||(l.val(be),ne=!0,He(l.get(0))),de.classList.add("active")}else a.find(".editor-view-btn[data-mode]").removeClass("active"),a.find(`.editor-view-btn[data-mode="${se}"]`).addClass("active"),t.removeClass("editor-mode-split editor-mode-write editor-mode-preview").addClass(`editor-mode-${se}`),l.hide(),e.show(),de.classList.remove("active")});const ue=Ue();ue.viewMode&&ue.viewMode!=="split"&&(a.find(".editor-view-btn[data-mode]").removeClass("active"),a.find(`.editor-view-btn[data-mode="${ue.viewMode}"]`).addClass("active"),a.find("#editor-body").removeClass("editor-mode-split editor-mode-write editor-mode-preview").addClass(`editor-mode-${ue.viewMode}`)),ue.fullscreen&&a.find(".editor-card").addClass("editor-fullscreen"),a.find("#css-editor").on("input",()=>{clearTimeout(xe),xe=setTimeout(()=>{let e=document.getElementById("preview-custom-css");e||(e=document.createElement("style"),e.id="preview-custom-css",Q.get(0).parentNode.insertBefore(e,Q.get(0))),e.textContent=a.find("#css-editor").val()},400)}),M.onLink(async e=>{const l=(await Y.pages.list().catch(()=>[])).map(f=>({label:f.title||f.urlPath,value:f.urlPath})),t=document.createElement("div");t.style.cssText="padding:.25rem 0 .5rem;display:flex;flex-direction:column;gap:.75rem;";const k=document.createElement("label");k.className="form-label",k.textContent="URL";const m=document.createElement("input");m.type="text",m.className="form-input",m.placeholder="/about or https://example.com";const u=e.value.substring(e.selectionStart,e.selectionEnd);u&&u.startsWith("/")&&(m.value=u),t.appendChild(k),t.appendChild(m);const w=document.createElement("label");w.className="form-label",w.textContent="Link text";const x=document.createElement("input");x.type="text",x.className="form-input",x.placeholder="Display text",u&&!u.startsWith("/")&&(x.value=u),t.appendChild(w),t.appendChild(x);const h=document.createElement("label");h.className="form-label",h.style.cssText="display:flex;align-items:center;gap:.5rem;cursor:pointer;";const c=document.createElement("input");c.type="checkbox",c.style.cssText="width:1rem;height:1rem;cursor:pointer;",h.appendChild(c),h.appendChild(document.createTextNode("Display as button")),t.appendChild(h);const p=document.createElement("label");p.className="form-label",p.textContent="Button colour",p.style.display="none";const F=document.createElement("select");F.className="form-select",F.style.display="none",[["primary","Primary"],["secondary","Secondary"],["success","Success (Green)"],["danger","Danger (Red)"],["warning","Warning (Orange)"],["info","Info (Blue)"],["outline","Outline"],["outline-success","Outline Success"],["outline-danger","Outline Danger"],["ghost","Ghost"]].forEach(([f,B])=>{const y=document.createElement("option");y.value=f,y.textContent=B,F.appendChild(y)}),t.appendChild(p),t.appendChild(F),c.addEventListener("change",()=>{const f=c.checked;p.style.display=f?"":"none",F.style.display=f?"":"none"});const N=document.createElement("button");N.type="button",N.className="btn btn-primary",N.textContent="Insert Link",t.appendChild(N);const b=E.modal({title:"Insert Link",size:"sm"});b.element.appendChild(t),b.open(),requestAnimationFrame(()=>{E.autocomplete(m,{data:l,minChars:1,onSelect:f=>{m.value=f.value,x.value||(x.value=f.label)}}),m.focus()}),N.addEventListener("click",()=>{const f=m.value.trim(),B=x.value.trim();if(!f)return;b.close();const y=c.checked?`[button href="${f}" variant="${F.value}"]${B||f}[/button]`:`[${B||f}](${f})`,i=e.selectionStart,g=e.selectionEnd;e.value=e.value.substring(0,i)+y+e.value.substring(g),e.selectionStart=e.selectionEnd=i+y.length,e.dispatchEvent(new Event("input",{bubbles:!0})),e.focus()})}),M.onImage(async e=>{const l=(await Y.media.list().catch(()=>[])).filter(m=>/\.(png|jpe?g|gif|webp|svg)$/i.test(m.name)),t=document.createElement("div");if(t.className="media-picker-grid",l.length)l.forEach(m=>{const u=document.createElement("div");u.className="media-picker-item",u.dataset.url=m.url;const w=document.createElement("img");w.src=m.url,w.alt=m.name;const x=document.createElement("span");x.textContent=m.name,u.appendChild(w),u.appendChild(x),t.appendChild(u)});else{const m=document.createElement("p");m.className="text-muted p-3",m.textContent="No images uploaded yet.",t.appendChild(m)}const k=E.modal({title:"Insert Image",size:"lg"});k.element.appendChild(t),$(k.element).on("click",".media-picker-item",function(){const m=$(this).data("url"),u=$(this).find("span").text();ke(e,`![${u}](${m})`),k.close(),ce.get(0).dispatchEvent(new Event("input",{bubbles:!0}))}),k.open()}),M.onCollection(async e=>{const[l,t]=await Promise.all([Y.collections.list().catch(()=>[]),Y.blocks.list().catch(()=>[])]),k=document.createElement("div");k.style.cssText="padding:1rem;display:flex;flex-direction:column;gap:.75rem;";const m="display:block;font-size:.85em;font-weight:600;margin-bottom:.25rem;color:var(--dm-text-muted,#aaa);text-transform:uppercase;letter-spacing:.05em;",u="width:100%;padding:.4rem .6rem;background:var(--dm-input-bg,#1a1a1a);border:1px solid var(--dm-border,#333);border-radius:4px;color:var(--dm-text,#eee);font-size:.9em;",w=document.createElement("div"),x=document.createElement("label");x.style.cssText=m,x.textContent="Collection";const h=document.createElement("select");if(h.style.cssText=u,l.length)l.forEach(G=>{const K=document.createElement("option");K.value=G.slug,K.textContent=G.title||G.slug,h.appendChild(K)});else{const G=document.createElement("option");G.value="",G.textContent="No collections found",h.appendChild(G)}w.appendChild(x),w.appendChild(h),k.appendChild(w);const c=document.createElement("div"),p=document.createElement("label");p.style.cssText=m,p.textContent="Display";const F=document.createElement("select");F.style.cssText=u,["table","cards","list","block"].forEach(G=>{const K=document.createElement("option");K.value=G,K.textContent=G.charAt(0).toUpperCase()+G.slice(1),F.appendChild(K)}),c.appendChild(p),c.appendChild(F),k.appendChild(c);const N=document.createElement("div");N.style.display="none";const b=document.createElement("label");b.style.cssText=m,b.textContent="Columns (2\u20134)";const f=document.createElement("input");f.type="number",f.min="2",f.max="4",f.value="3",f.style.cssText=u,N.appendChild(b),N.appendChild(f),k.appendChild(N);const B=document.createElement("div");B.style.display="none";const y=document.createElement("label");y.style.cssText=m,y.textContent="Block template";const i=document.createElement("select");if(i.style.cssText=u,t.length)t.forEach(G=>{const K=document.createElement("option");K.value=G.name??G,K.textContent=G.name??G,i.appendChild(K)});else{const G=document.createElement("option");G.value="",G.textContent="No block templates found",i.appendChild(G)}B.appendChild(y),B.appendChild(i),k.appendChild(B);const g=document.createElement("div"),n=document.createElement("label");n.style.cssText="display:flex;align-items:center;gap:.5rem;font-size:.9em;cursor:pointer;";const r=document.createElement("input");r.type="checkbox",r.checked=!0,n.appendChild(r),n.appendChild(document.createTextNode("Enable search")),g.appendChild(n),k.appendChild(g);const v=document.createElement("div"),A=document.createElement("label");A.style.cssText="display:flex;align-items:center;gap:.5rem;font-size:.9em;cursor:pointer;";const q=document.createElement("input");q.type="checkbox",q.checked=!0,A.appendChild(q),A.appendChild(document.createTextNode("Sortable columns")),v.appendChild(A),k.appendChild(v);const j=document.createElement("div"),T=document.createElement("label");T.style.cssText="display:flex;align-items:center;gap:.5rem;font-size:.9em;cursor:pointer;";const C=document.createElement("input");C.type="checkbox",C.checked=!1,T.appendChild(C),T.appendChild(document.createTextNode("CSV export")),j.appendChild(T),k.appendChild(j);const d=document.createElement("div"),s=document.createElement("label");s.style.cssText=m,s.textContent="Rows per page";const o=document.createElement("input");o.type="number",o.min="5",o.max="100",o.value="25",o.style.cssText=u,d.appendChild(s),d.appendChild(o),k.appendChild(d);const he=document.createElement("div"),H=document.createElement("label");H.style.cssText=m,H.textContent="Limit (optional)";const X=document.createElement("input");X.type="number",X.placeholder="All",X.style.cssText=u,he.appendChild(H),he.appendChild(X),k.appendChild(he);const P=document.createElement("button");P.type="button",P.className="btn btn-primary",P.textContent="Insert",k.appendChild(P);const L=[g,v,j,d],O=()=>{const G=F.value,K=G==="table";L.forEach(we=>{we.style.display=K?"":"none"}),N.style.display=G==="cards"||G==="block"?"":"none",B.style.display=G==="block"?"":"none"};F.addEventListener("change",O),O();const _=E.modal({title:"Insert Collection",size:"sm"});_.element.appendChild(k),_.open(),P.addEventListener("click",()=>{const G=h.value;if(!G)return;const K=F.value;let we=`[collection slug="${G}" display="${K}"`;if(K==="cards"&&(we+=` columns="${f.value}"`),K==="block"){const Me=i.value;Me&&(we+=` block="${Me}"`);const qe=f.value.trim();qe&&(we+=` cols="${qe}"`)}K==="table"&&!r.checked&&(we+=' search="false"'),K==="table"&&!q.checked&&(we+=' sortable="false"'),K==="table"&&C.checked&&(we+=' exportable="true"'),K==="table"&&o.value!=="25"&&(we+=` page-size="${o.value}"`);const Re=X.value.trim();Re&&(we+=` limit="${Re}"`),we+=" /]",_.close(),ke(e,we),e.dispatchEvent(new Event("input",{bubbles:!0})),e.focus()})}),M.onBlock(async e=>{let l=[];try{l=await Y.blocks.list()}catch{E.toast("Could not load blocks.",{type:"error"});return}if(!l.length){E.toast("No block templates found. Create one in Blocks first.",{type:"warning"});return}const t=E.modal({title:"Insert Block",size:"lg"}),k=document.createElement("div");k.style.cssText="display:flex;gap:1rem;min-height:320px;";const m=document.createElement("div");m.style.cssText="flex:1;display:flex;flex-direction:column;gap:.75rem;";const u=document.createElement("label");u.className="form-label",u.textContent="Block Template";const w=document.createElement("select");w.className="form-select";const x=document.createElement("option");x.value="",x.textContent="\u2014 select a template \u2014",w.appendChild(x),l.forEach(i=>{const g=document.createElement("option");g.value=i.name,g.textContent=i.name,w.appendChild(g)}),m.appendChild(u),m.appendChild(w);const h=document.createElement("div");h.style.cssText="display:flex;flex-direction:column;gap:.5rem;overflow-y:auto;max-height:260px;",m.appendChild(h);const c=document.createElement("button");c.className="btn btn-primary",c.type="button",c.textContent="Insert",c.disabled=!0,m.appendChild(c);const p=document.createElement("div");p.style.cssText="flex:1;border:1px solid var(--dm-border-color);border-radius:var(--dm-radius);padding:.75rem;overflow:auto;background:var(--dm-surface-bg);";const F=document.createElement("p");F.className="text-muted",F.style.cssText="font-size:.8rem;margin:0;",F.textContent="Select a template to see a preview.",p.appendChild(F),k.appendChild(m),k.appendChild(p),t.element.appendChild(k),t.open();let N=null,b=[];function f(i){return i.replace(/_/g," ").replace(/\b\w/g,g=>g.toUpperCase())}function B(){if(!N)return;const i={};b.forEach(({key:n,input:r})=>{i[n]=r.value});const g=N.replace(/\{\{([\w_]+)\}\}/g,(n,r)=>(i[r]??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;"));p.innerHTML=DOMPurify.sanitize(g)}function y(i){h.textContent="",b=[];const g=new Set(["_id","_createdAt","_updatedAt"]),n=new Set;for(const[,r]of i.matchAll(/\{\{([\w_]+)\}\}/g))g.has(r)||n.add(r);if(!n.size){const r=document.createElement("p");r.className="text-muted",r.style.cssText="font-size:.8rem;margin:0;",r.textContent="No editable placeholders in this template.",h.appendChild(r);return}n.forEach(r=>{const v=document.createElement("div"),A=document.createElement("label");A.className="form-label",A.style.cssText="font-size:.8rem;margin-bottom:.2rem;display:block;",A.textContent=f(r);const q=document.createElement("input");q.type="text",q.className="form-input",q.placeholder=f(r),q.addEventListener("input",B),v.appendChild(A),v.appendChild(q),h.appendChild(v),b.push({key:r,input:q})})}w.addEventListener("change",async()=>{const i=w.value;if(!i){N=null,b=[],h.textContent="",p.textContent="",p.appendChild(F),c.disabled=!0;return}N=null,b=[],h.textContent="",c.disabled=!0;try{N=(await Y.blocks.get(i)).content||"",y(N),B(),c.disabled=!1}catch{E.toast("Could not load template.",{type:"error"})}}),c.addEventListener("click",()=>{if(!w.value)return;const i=r=>r.replace(/"/g,"&quot;");let g=`template="${i(w.value)}"`;b.forEach(({key:r,input:v})=>{v.value!==""&&(g+=` ${r}="${i(v.value)}"`)});const n=`[block ${g} /]`;ke(e,n),e.dispatchEvent(new Event("input",{bubbles:!0})),t.close(),e.focus()})}),M.onForm(async e=>{const l=await Y.forms.list().catch(()=>[]),t=document.createElement("div");t.style.cssText="padding:1rem;display:flex;flex-direction:column;gap:.75rem;";const k="display:block;font-size:.85em;font-weight:600;margin-bottom:.25rem;color:var(--dm-text-muted,#aaa);text-transform:uppercase;letter-spacing:.05em;",m="width:100%;padding:.4rem .6rem;background:var(--dm-input-bg,#1a1a1a);border:1px solid var(--dm-border,#333);border-radius:4px;color:var(--dm-text,#eee);font-size:.9em;",u=document.createElement("div"),w=document.createElement("label");w.style.cssText=k,w.textContent="Form";const x=document.createElement("select");if(x.style.cssText=m,l.length)l.forEach(p=>{const F=document.createElement("option");F.value=p.slug,F.textContent=p.title||p.slug,x.appendChild(F)});else{const p=document.createElement("option");p.value="",p.textContent="No forms found",x.appendChild(p)}u.appendChild(w),u.appendChild(x),t.appendChild(u);const h=document.createElement("button");h.className="btn btn-primary btn-sm",h.style.cssText="align-self:flex-end;margin-top:.5rem;",h.textContent="Insert Form",t.appendChild(h);const c=E.modal({title:"Insert Form",size:"sm"});c.element.appendChild(t),c.open(),h.addEventListener("click",()=>{const p=x.value;p&&(ke(e,`[form slug="${p}" /]`),c.close(),ce.get(0).dispatchEvent(new Event("input",{bubbles:!0})))})}),M.onView(async e=>{const l=await Y.views.list().catch(()=>[]),t=document.createElement("div");t.style.cssText="padding:1rem;display:flex;flex-direction:column;gap:.75rem;";const k="display:block;font-size:.85em;font-weight:600;margin-bottom:.25rem;color:var(--dm-text-muted,#aaa);text-transform:uppercase;letter-spacing:.05em;",m="width:100%;padding:.4rem .6rem;background:var(--dm-input-bg,#1a1a1a);border:1px solid var(--dm-border,#333);border-radius:4px;color:var(--dm-text,#eee);font-size:.9em;",u=document.createElement("div"),w=document.createElement("label");w.style.cssText=k,w.textContent="View";const x=document.createElement("select");if(x.style.cssText=m,l.length)l.forEach(b=>{const f=document.createElement("option");f.value=b.slug,f.textContent=b.title||b.slug,x.appendChild(f)});else{const b=document.createElement("option");b.value="",b.textContent="No Views configured yet \u2014 create one under Data \u2192 Views",x.appendChild(b)}u.appendChild(w),u.appendChild(x),t.appendChild(u);const h=document.createElement("div"),c=document.createElement("label");c.style.cssText=k,c.textContent="Display";const p=document.createElement("select");p.style.cssText=m,["table","cards","list"].forEach(b=>{const f=document.createElement("option");f.value=b,f.textContent=b.charAt(0).toUpperCase()+b.slice(1),p.appendChild(f)}),h.appendChild(c),h.appendChild(p),t.appendChild(h);const F=document.createElement("button");F.type="button",F.className="btn btn-primary",F.textContent="Insert",t.appendChild(F);const N=E.modal({title:"Insert View",size:"sm"});N.element.appendChild(t),N.open(),F.addEventListener("click",()=>{const b=x.value;if(!b)return;const f=`[view slug="${b}" display="${p.value}" /]`;N.close(),ke(e,f),e.dispatchEvent(new Event("input",{bubbles:!0})),e.focus()})}),M.onCta(async e=>{const l=await Y.actions.list().catch(()=>[]),t=document.createElement("div");t.style.cssText="padding:1rem;display:flex;flex-direction:column;gap:.75rem;";const k="display:block;font-size:.85em;font-weight:600;margin-bottom:.25rem;color:var(--dm-text-muted,#aaa);text-transform:uppercase;letter-spacing:.05em;",m="width:100%;padding:.4rem .6rem;background:var(--dm-input-bg,#1a1a1a);border:1px solid var(--dm-border,#333);border-radius:4px;color:var(--dm-text,#eee);font-size:.9em;";function u(y,i){const g=document.createElement("div"),n=document.createElement("label");return n.style.cssText=k,n.textContent=y,g.appendChild(n),g.appendChild(i),g}function w(y){const i=document.createElement("select");return i.style.cssText=m,y.forEach(([g,n])=>{const r=document.createElement("option");r.value=g,r.textContent=n,i.appendChild(r)}),i}function x(y,i,g){const n=document.createElement("input");return n.type=y,n.placeholder=i||"",n.value=g||"",n.style.cssText=m,n}const h=w(l.length?l.map(y=>[y.slug,y.title||y.slug]):[["","No Actions configured yet \u2014 create one under Data \u2192 Actions"]]);t.appendChild(u("Action",h));const c=x("text","Button label","Run");if(t.appendChild(u("Label",c)),h.addEventListener("change",()=>{const y=l.find(i=>i.slug===h.value);y?.trigger?.label&&(c.value=y.trigger.label)}),l.length){const y=l[0];y?.trigger?.label&&(c.value=y.trigger.label)}const p=x("text","Paste entry UUID\u2026","");t.appendChild(u("Entry ID",p));const F=w([["primary","Primary"],["secondary","Secondary"],["ghost","Ghost"],["danger","Danger"]]);t.appendChild(u("Style",F));const N=x("text","e.g. check, zap, send (optional)","");t.appendChild(u("Icon",N));const b=x("text","Confirmation message (optional)","");t.appendChild(u("Confirm prompt",b));const f=document.createElement("button");f.type="button",f.className="btn btn-primary",f.textContent="Insert",t.appendChild(f);const B=E.modal({title:"Insert CTA Button",size:"sm"});B.element.appendChild(t),B.open(),f.addEventListener("click",()=>{const y=h.value;if(!y)return;const i=p.value.trim(),g=(c.value.trim()||"Run").replace(/\[\/cta\]/gi,""),n=F.value,r=N.value.trim().replace(/"/g,""),v=b.value.trim().replace(/"/g,""),A=i.replace(/"/g,"");let q=`action="${y}" style="${n}"`;A&&(q+=` entry="${A}"`),r&&(q+=` icon="${r}"`),v&&(q+=` confirm="${v}"`);const j=`[cta ${q}]${g}[/cta]`;B.close(),ke(e,j),e.dispatchEvent(new Event("input",{bubbles:!0})),e.focus()})}),M.onButton(async e=>{const l=(await Y.pages.list().catch(()=>[])).map(n=>({label:n.title||n.urlPath,value:n.urlPath})),t=document.createElement("div");t.style.cssText="padding:.25rem 0 .5rem;display:flex;flex-direction:column;gap:.75rem;";const k="display:block;font-size:.85em;font-weight:600;margin-bottom:.25rem;color:var(--dm-text-muted,#aaa);text-transform:uppercase;letter-spacing:.05em;",m="width:100%;padding:.4rem .6rem;background:var(--dm-input-bg,#1a1a1a);border:1px solid var(--dm-border,#333);border-radius:4px;color:var(--dm-text,#eee);font-size:.9em;";function u(n,r){const v=document.createElement("div"),A=document.createElement("label");return A.style.cssText=k,A.textContent=n,v.appendChild(A),v.appendChild(r),v}function w(n,r){const v=document.createElement("input");return v.type="text",v.placeholder=n,v.value=r||"",v.style.cssText=m,v}function x(n){const r=document.createElement("select");return r.style.cssText=m,n.forEach(([v,A])=>{const q=document.createElement("option");q.value=v,q.textContent=A,r.appendChild(q)}),r}const h=e.value.substring(e.selectionStart,e.selectionEnd),c=w("/about or https://example.com",h.startsWith("/")?h:"");t.appendChild(u("URL",c));const p=w("Button label",h&&!h.startsWith("/")?h:"");t.appendChild(u("Label",p));const F=x([["primary","Primary"],["secondary","Secondary"],["success","Success (Green)"],["danger","Danger (Red)"],["warning","Warning (Orange)"],["info","Info (Blue)"],["outline","Outline"],["ghost","Ghost"],["link","Link"],["outline-success","Outline Success"],["outline-danger","Outline Danger"]]);t.appendChild(u("Variant",F));const N=x([["","Default"],["sm","Small"],["lg","Large"]]);t.appendChild(u("Size",N));const b=w("e.g. arrow-right, star (optional)","");t.appendChild(u("Icon (before label)",b));const f=w("e.g. arrow-right (optional)","");t.appendChild(u("Icon (after label)",f));const B=document.createElement("label");B.style.cssText="display:flex;align-items:center;gap:.5rem;cursor:pointer;font-size:.9em;";const y=document.createElement("input");y.type="checkbox",y.style.cssText="width:1rem;height:1rem;",B.appendChild(y),B.appendChild(document.createTextNode("Open in new tab")),t.appendChild(B);const i=document.createElement("button");i.type="button",i.className="btn btn-primary",i.textContent="Insert Button",t.appendChild(i);const g=E.modal({title:"Insert Button",size:"sm"});g.element.appendChild(t),g.open(),requestAnimationFrame(()=>{E.autocomplete(c,{data:l,minChars:1,onSelect:n=>{c.value=n.value,p.value||(p.value=n.label)}}),c.focus()}),i.addEventListener("click",()=>{const n=c.value.trim();if(!n)return;g.close();const r=p.value.trim()||n;let v=`href="${n}" variant="${F.value}"`;N.value&&(v+=` size="${N.value}"`);const A=b.value.trim().replace(/"/g,"");A&&(v+=` icon="${A}"`);const q=f.value.trim().replace(/"/g,"");q&&(v+=` icon-after="${q}"`),y.checked&&(v+=' target="_blank"');const j=`[button ${v}]${r}[/button]`;ke(e,j)})}),M.onLinkShortcode(async e=>{const l=(await Y.pages.list().catch(()=>[])).map(i=>({label:i.title||i.urlPath,value:i.urlPath})),t=document.createElement("div");t.style.cssText="padding:.25rem 0 .5rem;display:flex;flex-direction:column;gap:.75rem;";const k="display:block;font-size:.85em;font-weight:600;margin-bottom:.25rem;color:var(--dm-text-muted,#aaa);text-transform:uppercase;letter-spacing:.05em;",m="width:100%;padding:.4rem .6rem;background:var(--dm-input-bg,#1a1a1a);border:1px solid var(--dm-border,#333);border-radius:4px;color:var(--dm-text,#eee);font-size:.9em;";function u(i,g){const n=document.createElement("div"),r=document.createElement("label");return r.style.cssText=k,r.textContent=i,n.appendChild(r),n.appendChild(g),n}function w(i,g){const n=document.createElement("input");return n.type="text",n.placeholder=i,n.value=g||"",n.style.cssText=m,n}const x=e.value.substring(e.selectionStart,e.selectionEnd),h=w("/about or https://example.com",x.startsWith("/")?x:"");t.appendChild(u("URL",h));const c=w("Link text",x&&!x.startsWith("/")?x:"");t.appendChild(u("Link text",c));const p=w("e.g. text-primary, fw-bold (optional)","");t.appendChild(u("CSS class",p));const F=w("e.g. arrow-right (optional)","");t.appendChild(u("Icon (before text)",F));const N=w("e.g. external-link (optional)","");t.appendChild(u("Icon (after text)",N));const b=document.createElement("label");b.style.cssText="display:flex;align-items:center;gap:.5rem;cursor:pointer;font-size:.9em;";const f=document.createElement("input");f.type="checkbox",f.style.cssText="width:1rem;height:1rem;",b.appendChild(f),b.appendChild(document.createTextNode("Open in new tab")),t.appendChild(b);const B=document.createElement("button");B.type="button",B.className="btn btn-primary",B.textContent="Insert Link",t.appendChild(B);const y=E.modal({title:"Insert Link Shortcode",size:"sm"});y.element.appendChild(t),y.open(),requestAnimationFrame(()=>{E.autocomplete(h,{data:l,minChars:1,onSelect:i=>{h.value=i.value,c.value||(c.value=i.label)}}),h.focus()}),B.addEventListener("click",()=>{const i=h.value.trim();if(!i)return;y.close();const g=c.value.trim()||i;let n=`href="${i}"`;const r=p.value.trim().replace(/"/g,"");r&&(n+=` class="${r}"`);const v=F.value.trim().replace(/"/g,"");v&&(n+=` icon="${v}"`);const A=N.value.trim().replace(/"/g,"");A&&(n+=` icon-after="${A}"`),f.checked&&(n+=' target="_blank"');const q=`[link ${n}]${g}[/link]`;ke(e,q)})}),M.onTabs(e=>{const l=document.createElement("div");l.style.cssText="padding:.25rem 0 .5rem;display:flex;flex-direction:column;gap:.75rem;";const t="display:block;font-size:.85em;font-weight:600;margin-bottom:.25rem;color:var(--dm-text-muted,#aaa);text-transform:uppercase;letter-spacing:.05em;",k="width:100%;padding:.4rem .6rem;background:var(--dm-input-bg,#1a1a1a);border:1px solid var(--dm-border,#333);border-radius:4px;color:var(--dm-text,#eee);font-size:.9em;";function m(y,i){const g=document.createElement("div"),n=document.createElement("label");return n.style.cssText=t,n.textContent=y,g.appendChild(n),g.appendChild(i),g}function u(y){const i=document.createElement("select");return i.style.cssText=k,y.forEach(([g,n])=>{const r=document.createElement("option");r.value=g,r.textContent=n,i.appendChild(r)}),i}const w=u([["","Default (underline)"],["pills","Pills"]]);l.appendChild(m("Style",w));const x=u([["","Left"],["center","Centre"]]);l.appendChild(m("Alignment",x));const h=document.createElement("div");h.style.cssText="display:flex;flex-direction:column;gap:.4rem;";const c=[];function p(){c.forEach(y=>{y.removeBtn.disabled=c.length<=2,y.removeBtn.style.opacity=c.length<=2?"0.3":"1"})}function F(y){const i=document.createElement("div");i.style.cssText="display:flex;gap:.4rem;align-items:center;";const g=document.createElement("input");g.type="text",g.placeholder="Tab title",g.value=y||"",g.style.cssText=k+"flex:1;";const n=document.createElement("button");n.type="button",n.textContent="\u2715",n.style.cssText="padding:.3rem .5rem;background:transparent;border:1px solid var(--dm-border,#333);border-radius:4px;color:var(--dm-text-muted,#aaa);cursor:pointer;font-size:.85em;flex-shrink:0;";const r={row:i,input:g,removeBtn:n};c.push(r),i.appendChild(g),i.appendChild(n),h.appendChild(i),n.addEventListener("click",()=>{if(c.length<=2)return;const v=c.indexOf(r);c.splice(v,1),h.removeChild(i),p()}),p()}F("Overview"),F("Details");const N=document.createElement("div");N.style.cssText=t,N.textContent="Tabs",l.appendChild(N),l.appendChild(h);const b=document.createElement("button");b.type="button",b.textContent="+ Add Tab",b.style.cssText="padding:.35rem .75rem;background:transparent;border:1px dashed var(--dm-border,#555);border-radius:4px;color:var(--dm-text-muted,#aaa);cursor:pointer;font-size:.85em;align-self:flex-start;",b.addEventListener("click",()=>{c.length>=10||(F(""),c[c.length-1].input.focus())}),l.appendChild(b);const f=document.createElement("button");f.type="button",f.className="btn btn-primary",f.textContent="Insert Tabs",l.appendChild(f);const B=E.modal({title:"Insert Tabs",size:"sm"});B.element.appendChild(l),B.open(),requestAnimationFrame(()=>c[0].input.focus()),f.addEventListener("click",()=>{B.close();const y=w.value,i=x.value;let g=y?` style="${y}"`:"";i&&(g+=` align="${i}"`);let n=`[tabs${g}]
88
+ `)}const Ge="editor_prefs";function Ue(){return S.get(Ge)||{viewMode:"split",fullscreen:!1}}function Ve(a,ie){const oe=Ue();oe[a]=ie,S.set(Ge,oe)}export const pageEditorView={templateUrl:"/admin/js/templates/page-editor.html",async onMount(a){const ie=window.location.hash.match(/#\/pages\/edit(\/.*)/),oe=ie?ie[1]:null,U=!!oe,J=E.loader(a.get(0),{type:"dots"}),ze=[Y.layouts.get().catch(()=>({})),Y.settings.get().catch(()=>({}))];U&&(ze.push(Y.pages.get(oe).catch(()=>null)),ze.push(Y.pages.list().catch(()=>[])));const[$e,Ie,W,Te]=await Promise.all(ze);J.destroy(),Ye(a.find("#field-theme").get(0),{includeDefault:!0});const Le=Ie?.layoutOptions?.spacerSize??40;if(U&&!W){E.toast("Page not found.",{type:"error"}),R.navigate("/pages");return}a.find("#editor-title").text(U?`Edit Page \u2014 ${W.title||oe}`:"New Page"),U&&a.find("#page-url-path").val(oe),W&&(a.find("#field-title").val(W.title||""),a.find("#field-description").val(W.description||""),a.find("#field-status").val(W.status||"draft"),a.find("#field-sort-order").val(W.sortOrder??99),a.find("#field-show-in-nav").prop("checked",!!W.showInNav),a.find("#field-sidebar").prop("checked",!!W.sidebar),a.find("#field-show-breadcrumbs").prop("checked",W.breadcrumbs!==!1),a.find("#field-bundled").prop("checked",!!W.bundled),a.find("#field-category").val(W.category||""),a.find("#field-visibility").val(W.visibility||"public"),a.find("#field-theme").val(W.theme||""),a.find("#field-seo-title").val(W.seo?.title||""),a.find("#field-seo-desc").val(W.seo?.description||""),W.dconfig&&a.find("#field-dconfig").val(JSON.stringify(W.dconfig,null,2)));const ge=a.find("#quick-switch");U&&Array.isArray(Te)&&Te.length&&([...Te].sort((e,l)=>(e.title||e.urlPath).localeCompare(l.title||l.urlPath)).forEach(e=>{const l=document.createElement("option");l.value=e.urlPath,l.textContent=`${e.title||"Untitled"} (${e.urlPath})`,e.urlPath===oe&&(l.selected=!0),ge.get(0).appendChild(l)}),ge.css("display",""),ge.on("change",function(){const e=this.value;e&&R.navigate("/pages/edit"+e)}));const le=await Y.pages.tags().catch(()=>[]),fe=a.find("#field-tags").get(0),Ce=fe?E.pillbox(fe,{data:le,value:W?.tags||[],creatable:!0,searchable:!0,placeholder:"Add tag\u2026"}):null,Be=a.find("#field-layout").empty();if(Object.entries($e).forEach(([e,l])=>{const t=(W?.layout||"default")===e?"selected":"";Be.append(`<option value="${e}" ${t}>${l.label||e}</option>`)}),U){const e=a.find("#view-page-btn").get(0);e.href=oe,e.style.display="";const l=a.find("#live-preview-tab").get(0);l.style.display="";const t=a.find("#history-tab").get(0);t.style.display=""}if(E.tabs(a.find("#editor-meta-tabs").get(0)),U){const e=a.find("#live-preview-tab").get(0),l=a.find("#live-preview-frame").get(0);let t=!1;e.addEventListener("click",function(){t||(l.src=oe,t=!0)}),Ke(a,oe)}const ce=a.find("#markdown-editor"),Q=a.find("#markdown-preview");W&&ce.val(W.content||"");let ne=!1,be="";Y.settings.getCustomCss().then(({css:e})=>{if(be=e||"",!be)return;const l=document.createElement("style");l.id="preview-custom-css",l.textContent=be,Q.get(0).parentNode.insertBefore(l,Q.get(0))}).catch(()=>{});let ee=!1;const V=ce.get(0),z=document.createElement("div");z.className="editor-line-numbers editor-line-numbers--foldable",V.parentElement.insertBefore(z,V);const ae=Je(V,z,{onFoldChange:()=>{}});ae.setGuard(e=>{ee=e});const pe=()=>{ae.refresh(),z.scrollTop=V.scrollTop};V.addEventListener("input",pe),V.addEventListener("scroll",()=>{z.scrollTop=V.scrollTop});let ye=null;const De=()=>{clearTimeout(ye),ye=setTimeout(async()=>{const e=ae.getUnfoldedContent();try{const{html:l}=await Y.pages.preview(e);Q.html(l,{safe:!1}),I.scan(Q.get(0)),Q.get(0).querySelectorAll(".tabs").forEach(t=>Domma.elements.tabs(t))}catch{window.marked&&Q.html(marked.parse(e))}},400)},M=_e(ce,a.find("#editor-toolbar"),{spacerDefault:Le});let Z=!1,se="split",xe=null;const de=document.createElement("button");de.className="editor-view-btn",de.type="button";const Ne=document.createElement("span");Ne.setAttribute("data-icon","css-code"),de.appendChild(Ne);const me=document.createElement("button");me.className="editor-view-btn",me.type="button";const Se=document.createElement("span");Se.setAttribute("data-icon","code"),me.appendChild(Se);let Ee=!1;const te=document.createElement("button");te.className="editor-view-btn",te.type="button",te.textContent="\u25BC\u25BC",te.style.cssText="font-size:9px;letter-spacing:-1px;";const ve=a.find(".editor-toolbar-right").get(0);ve.prepend(te),ve.prepend(me),ve.prepend(de),I.scan(de),I.scan(me),E.tooltip(de,{content:"Edit Custom CSS",position:"top"}),E.tooltip(me,{content:"Format Markdown",position:"top"}),E.tooltip(te,{content:"Fold / unfold all shortcodes",position:"top"}),me.addEventListener("click",()=>{const e=ce.get(0),l=e.selectionStart,t=Ze(ae.getUnfoldedContent());ae.unfoldAll(),ee=!0,e.value=t,ee=!1,e.selectionStart=e.selectionEnd=Math.min(l,t.length),e.dispatchEvent(new Event("input")),ae.refresh(),E.toast("Markdown formatted.",{type:"success"})}),te.addEventListener("click",()=>{Ee?(ae.unfoldAll(),te.textContent="\u25BC\u25BC",te.classList.remove("active")):(ae.foldAll(),te.textContent="\u25B6\u25B6",te.classList.add("active")),Ee=!Ee});const re=document.createElement("span");re.className="editor-toolbar-sep",ve.insertBefore(re,ve.children[3]),de.addEventListener("click",()=>{Z=!Z;const e=a.find("#markdown-editor"),l=a.find("#css-editor"),t=a.find("#editor-body");if(Z){const k=a.find(".editor-view-btn[data-mode].active").get(0);se=k?k.getAttribute("data-mode"):"split",a.find(".editor-view-btn[data-mode]").removeClass("active"),a.find('.editor-view-btn[data-mode="split"]').addClass("active"),t.removeClass("editor-mode-write editor-mode-preview").addClass("editor-mode-split"),e.hide(),l.show(),ne||(l.val(be),ne=!0,We(l.get(0))),de.classList.add("active")}else a.find(".editor-view-btn[data-mode]").removeClass("active"),a.find(`.editor-view-btn[data-mode="${se}"]`).addClass("active"),t.removeClass("editor-mode-split editor-mode-write editor-mode-preview").addClass(`editor-mode-${se}`),l.hide(),e.show(),de.classList.remove("active")});const ue=Ue();ue.viewMode&&ue.viewMode!=="split"&&(a.find(".editor-view-btn[data-mode]").removeClass("active"),a.find(`.editor-view-btn[data-mode="${ue.viewMode}"]`).addClass("active"),a.find("#editor-body").removeClass("editor-mode-split editor-mode-write editor-mode-preview").addClass(`editor-mode-${ue.viewMode}`)),ue.fullscreen&&a.find(".editor-card").addClass("editor-fullscreen"),a.find("#css-editor").on("input",()=>{clearTimeout(xe),xe=setTimeout(()=>{let e=document.getElementById("preview-custom-css");e||(e=document.createElement("style"),e.id="preview-custom-css",Q.get(0).parentNode.insertBefore(e,Q.get(0))),e.textContent=a.find("#css-editor").val()},400)}),M.onLink(async e=>{const l=(await Y.pages.list().catch(()=>[])).map(f=>({label:f.title||f.urlPath,value:f.urlPath})),t=document.createElement("div");t.style.cssText="padding:.25rem 0 .5rem;display:flex;flex-direction:column;gap:.75rem;";const k=document.createElement("label");k.className="form-label",k.textContent="URL";const m=document.createElement("input");m.type="text",m.className="form-input",m.placeholder="/about or https://example.com";const u=e.value.substring(e.selectionStart,e.selectionEnd);u&&u.startsWith("/")&&(m.value=u),t.appendChild(k),t.appendChild(m);const w=document.createElement("label");w.className="form-label",w.textContent="Link text";const x=document.createElement("input");x.type="text",x.className="form-input",x.placeholder="Display text",u&&!u.startsWith("/")&&(x.value=u),t.appendChild(w),t.appendChild(x);const h=document.createElement("label");h.className="form-label",h.style.cssText="display:flex;align-items:center;gap:.5rem;cursor:pointer;";const c=document.createElement("input");c.type="checkbox",c.style.cssText="width:1rem;height:1rem;cursor:pointer;",h.appendChild(c),h.appendChild(document.createTextNode("Display as button")),t.appendChild(h);const p=document.createElement("label");p.className="form-label",p.textContent="Button colour",p.style.display="none";const F=document.createElement("select");F.className="form-select",F.style.display="none",[["primary","Primary"],["secondary","Secondary"],["success","Success (Green)"],["danger","Danger (Red)"],["warning","Warning (Orange)"],["info","Info (Blue)"],["outline","Outline"],["outline-success","Outline Success"],["outline-danger","Outline Danger"],["ghost","Ghost"]].forEach(([f,B])=>{const y=document.createElement("option");y.value=f,y.textContent=B,F.appendChild(y)}),t.appendChild(p),t.appendChild(F),c.addEventListener("change",()=>{const f=c.checked;p.style.display=f?"":"none",F.style.display=f?"":"none"});const N=document.createElement("button");N.type="button",N.className="btn btn-primary",N.textContent="Insert Link",t.appendChild(N);const b=E.modal({title:"Insert Link",size:"sm"});b.element.appendChild(t),b.open(),requestAnimationFrame(()=>{E.autocomplete(m,{data:l,minChars:1,onSelect:f=>{m.value=f.value,x.value||(x.value=f.label)}}),m.focus()}),N.addEventListener("click",()=>{const f=m.value.trim(),B=x.value.trim();if(!f)return;b.close();const y=c.checked?`[button href="${f}" variant="${F.value}"]${B||f}[/button]`:`[${B||f}](${f})`,i=e.selectionStart,g=e.selectionEnd;e.value=e.value.substring(0,i)+y+e.value.substring(g),e.selectionStart=e.selectionEnd=i+y.length,e.dispatchEvent(new Event("input",{bubbles:!0})),e.focus()})}),M.onImage(async e=>{const l=(await Y.media.list().catch(()=>[])).filter(m=>/\.(png|jpe?g|gif|webp|svg)$/i.test(m.name)),t=document.createElement("div");if(t.className="media-picker-grid",l.length)l.forEach(m=>{const u=document.createElement("div");u.className="media-picker-item",u.dataset.url=m.url;const w=document.createElement("img");w.src=m.url,w.alt=m.name;const x=document.createElement("span");x.textContent=m.name,u.appendChild(w),u.appendChild(x),t.appendChild(u)});else{const m=document.createElement("p");m.className="text-muted p-3",m.textContent="No images uploaded yet.",t.appendChild(m)}const k=E.modal({title:"Insert Image",size:"lg"});k.element.appendChild(t),$(k.element).on("click",".media-picker-item",function(){const m=$(this).data("url"),u=$(this).find("span").text();ke(e,`![${u}](${m})`),k.close(),ce.get(0).dispatchEvent(new Event("input",{bubbles:!0}))}),k.open()}),M.onCollection(async e=>{const[l,t]=await Promise.all([Y.collections.list().catch(()=>[]),Y.blocks.list().catch(()=>[])]),k=document.createElement("div");k.style.cssText="padding:1rem;display:flex;flex-direction:column;gap:.75rem;";const m="display:block;font-size:.85em;font-weight:600;margin-bottom:.25rem;color:var(--dm-text-muted,#aaa);text-transform:uppercase;letter-spacing:.05em;",u="width:100%;padding:.4rem .6rem;background:var(--dm-input-bg,#1a1a1a);border:1px solid var(--dm-border,#333);border-radius:4px;color:var(--dm-text,#eee);font-size:.9em;",w=document.createElement("div"),x=document.createElement("label");x.style.cssText=m,x.textContent="Collection";const h=document.createElement("select");if(h.style.cssText=u,l.length)l.forEach(G=>{const K=document.createElement("option");K.value=G.slug,K.textContent=G.title||G.slug,h.appendChild(K)});else{const G=document.createElement("option");G.value="",G.textContent="No collections found",h.appendChild(G)}w.appendChild(x),w.appendChild(h),k.appendChild(w);const c=document.createElement("div"),p=document.createElement("label");p.style.cssText=m,p.textContent="Display";const F=document.createElement("select");F.style.cssText=u,["table","cards","list","block"].forEach(G=>{const K=document.createElement("option");K.value=G,K.textContent=G.charAt(0).toUpperCase()+G.slice(1),F.appendChild(K)}),c.appendChild(p),c.appendChild(F),k.appendChild(c);const N=document.createElement("div");N.style.display="none";const b=document.createElement("label");b.style.cssText=m,b.textContent="Columns (2\u20134)";const f=document.createElement("input");f.type="number",f.min="2",f.max="4",f.value="3",f.style.cssText=u,N.appendChild(b),N.appendChild(f),k.appendChild(N);const B=document.createElement("div");B.style.display="none";const y=document.createElement("label");y.style.cssText=m,y.textContent="Block template";const i=document.createElement("select");if(i.style.cssText=u,t.length)t.forEach(G=>{const K=document.createElement("option");K.value=G.name??G,K.textContent=G.name??G,i.appendChild(K)});else{const G=document.createElement("option");G.value="",G.textContent="No block templates found",i.appendChild(G)}B.appendChild(y),B.appendChild(i),k.appendChild(B);const g=document.createElement("div"),n=document.createElement("label");n.style.cssText="display:flex;align-items:center;gap:.5rem;font-size:.9em;cursor:pointer;";const r=document.createElement("input");r.type="checkbox",r.checked=!0,n.appendChild(r),n.appendChild(document.createTextNode("Enable search")),g.appendChild(n),k.appendChild(g);const v=document.createElement("div"),A=document.createElement("label");A.style.cssText="display:flex;align-items:center;gap:.5rem;font-size:.9em;cursor:pointer;";const q=document.createElement("input");q.type="checkbox",q.checked=!0,A.appendChild(q),A.appendChild(document.createTextNode("Sortable columns")),v.appendChild(A),k.appendChild(v);const j=document.createElement("div"),T=document.createElement("label");T.style.cssText="display:flex;align-items:center;gap:.5rem;font-size:.9em;cursor:pointer;";const C=document.createElement("input");C.type="checkbox",C.checked=!1,T.appendChild(C),T.appendChild(document.createTextNode("CSV export")),j.appendChild(T),k.appendChild(j);const d=document.createElement("div"),s=document.createElement("label");s.style.cssText=m,s.textContent="Rows per page";const o=document.createElement("input");o.type="number",o.min="5",o.max="100",o.value="25",o.style.cssText=u,d.appendChild(s),d.appendChild(o),k.appendChild(d);const he=document.createElement("div"),H=document.createElement("label");H.style.cssText=m,H.textContent="Limit (optional)";const X=document.createElement("input");X.type="number",X.placeholder="All",X.style.cssText=u,he.appendChild(H),he.appendChild(X),k.appendChild(he);const P=document.createElement("button");P.type="button",P.className="btn btn-primary",P.textContent="Insert",k.appendChild(P);const L=[g,v,j,d],O=()=>{const G=F.value,K=G==="table";L.forEach(we=>{we.style.display=K?"":"none"}),N.style.display=G==="cards"||G==="block"?"":"none",B.style.display=G==="block"?"":"none"};F.addEventListener("change",O),O();const _=E.modal({title:"Insert Collection",size:"sm"});_.element.appendChild(k),_.open(),P.addEventListener("click",()=>{const G=h.value;if(!G)return;const K=F.value;let we=`[collection slug="${G}" display="${K}"`;if(K==="cards"&&(we+=` columns="${f.value}"`),K==="block"){const Me=i.value;Me&&(we+=` block="${Me}"`);const qe=f.value.trim();qe&&(we+=` cols="${qe}"`)}K==="table"&&!r.checked&&(we+=' search="false"'),K==="table"&&!q.checked&&(we+=' sortable="false"'),K==="table"&&C.checked&&(we+=' exportable="true"'),K==="table"&&o.value!=="25"&&(we+=` page-size="${o.value}"`);const Re=X.value.trim();Re&&(we+=` limit="${Re}"`),we+=" /]",_.close(),ke(e,we),e.dispatchEvent(new Event("input",{bubbles:!0})),e.focus()})}),M.onBlock(async e=>{let l=[];try{l=await Y.blocks.list()}catch{E.toast("Could not load blocks.",{type:"error"});return}if(!l.length){E.toast("No block templates found. Create one in Blocks first.",{type:"warning"});return}const t=E.modal({title:"Insert Block",size:"lg"}),k=document.createElement("div");k.style.cssText="display:flex;gap:1rem;min-height:320px;";const m=document.createElement("div");m.style.cssText="flex:1;display:flex;flex-direction:column;gap:.75rem;";const u=document.createElement("label");u.className="form-label",u.textContent="Block Template";const w=document.createElement("select");w.className="form-select";const x=document.createElement("option");x.value="",x.textContent="\u2014 select a template \u2014",w.appendChild(x),l.forEach(i=>{const g=document.createElement("option");g.value=i.name,g.textContent=i.name,w.appendChild(g)}),m.appendChild(u),m.appendChild(w);const h=document.createElement("div");h.style.cssText="display:flex;flex-direction:column;gap:.5rem;overflow-y:auto;max-height:260px;",m.appendChild(h);const c=document.createElement("button");c.className="btn btn-primary",c.type="button",c.textContent="Insert",c.disabled=!0,m.appendChild(c);const p=document.createElement("div");p.style.cssText="flex:1;border:1px solid var(--dm-border-color);border-radius:var(--dm-radius);padding:.75rem;overflow:auto;background:var(--dm-surface-bg);";const F=document.createElement("p");F.className="text-muted",F.style.cssText="font-size:.8rem;margin:0;",F.textContent="Select a template to see a preview.",p.appendChild(F),k.appendChild(m),k.appendChild(p),t.element.appendChild(k),t.open();let N=null,b=[];function f(i){return i.replace(/_/g," ").replace(/\b\w/g,g=>g.toUpperCase())}function B(){if(!N)return;const i={};b.forEach(({key:n,input:r})=>{i[n]=r.value});const g=N.replace(/\{\{([\w_]+)\}\}/g,(n,r)=>(i[r]??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;"));p.innerHTML=DOMPurify.sanitize(g)}function y(i){h.textContent="",b=[];const g=new Set(["_id","_createdAt","_updatedAt"]),n=new Set;for(const[,r]of i.matchAll(/\{\{([\w_]+)\}\}/g))g.has(r)||n.add(r);if(!n.size){const r=document.createElement("p");r.className="text-muted",r.style.cssText="font-size:.8rem;margin:0;",r.textContent="No editable placeholders in this template.",h.appendChild(r);return}n.forEach(r=>{const v=document.createElement("div"),A=document.createElement("label");A.className="form-label",A.style.cssText="font-size:.8rem;margin-bottom:.2rem;display:block;",A.textContent=f(r);const q=document.createElement("input");q.type="text",q.className="form-input",q.placeholder=f(r),q.addEventListener("input",B),v.appendChild(A),v.appendChild(q),h.appendChild(v),b.push({key:r,input:q})})}w.addEventListener("change",async()=>{const i=w.value;if(!i){N=null,b=[],h.textContent="",p.textContent="",p.appendChild(F),c.disabled=!0;return}N=null,b=[],h.textContent="",c.disabled=!0;try{N=(await Y.blocks.get(i)).content||"",y(N),B(),c.disabled=!1}catch{E.toast("Could not load template.",{type:"error"})}}),c.addEventListener("click",()=>{if(!w.value)return;const i=r=>r.replace(/"/g,"&quot;");let g=`template="${i(w.value)}"`;b.forEach(({key:r,input:v})=>{v.value!==""&&(g+=` ${r}="${i(v.value)}"`)});const n=`[block ${g} /]`;ke(e,n),e.dispatchEvent(new Event("input",{bubbles:!0})),t.close(),e.focus()})}),M.onForm(async e=>{const l=await Y.forms.list().catch(()=>[]),t=document.createElement("div");t.style.cssText="padding:1rem;display:flex;flex-direction:column;gap:.75rem;";const k="display:block;font-size:.85em;font-weight:600;margin-bottom:.25rem;color:var(--dm-text-muted,#aaa);text-transform:uppercase;letter-spacing:.05em;",m="width:100%;padding:.4rem .6rem;background:var(--dm-input-bg,#1a1a1a);border:1px solid var(--dm-border,#333);border-radius:4px;color:var(--dm-text,#eee);font-size:.9em;",u=document.createElement("div"),w=document.createElement("label");w.style.cssText=k,w.textContent="Form";const x=document.createElement("select");if(x.style.cssText=m,l.length)l.forEach(p=>{const F=document.createElement("option");F.value=p.slug,F.textContent=p.title||p.slug,x.appendChild(F)});else{const p=document.createElement("option");p.value="",p.textContent="No forms found",x.appendChild(p)}u.appendChild(w),u.appendChild(x),t.appendChild(u);const h=document.createElement("button");h.className="btn btn-primary btn-sm",h.style.cssText="align-self:flex-end;margin-top:.5rem;",h.textContent="Insert Form",t.appendChild(h);const c=E.modal({title:"Insert Form",size:"sm"});c.element.appendChild(t),c.open(),h.addEventListener("click",()=>{const p=x.value;p&&(ke(e,`[form slug="${p}" /]`),c.close(),ce.get(0).dispatchEvent(new Event("input",{bubbles:!0})))})}),M.onView(async e=>{const l=await Y.views.list().catch(()=>[]),t=document.createElement("div");t.style.cssText="padding:1rem;display:flex;flex-direction:column;gap:.75rem;";const k="display:block;font-size:.85em;font-weight:600;margin-bottom:.25rem;color:var(--dm-text-muted,#aaa);text-transform:uppercase;letter-spacing:.05em;",m="width:100%;padding:.4rem .6rem;background:var(--dm-input-bg,#1a1a1a);border:1px solid var(--dm-border,#333);border-radius:4px;color:var(--dm-text,#eee);font-size:.9em;",u=document.createElement("div"),w=document.createElement("label");w.style.cssText=k,w.textContent="View";const x=document.createElement("select");if(x.style.cssText=m,l.length)l.forEach(b=>{const f=document.createElement("option");f.value=b.slug,f.textContent=b.title||b.slug,x.appendChild(f)});else{const b=document.createElement("option");b.value="",b.textContent="No Views configured yet \u2014 create one under Data \u2192 Views",x.appendChild(b)}u.appendChild(w),u.appendChild(x),t.appendChild(u);const h=document.createElement("div"),c=document.createElement("label");c.style.cssText=k,c.textContent="Display";const p=document.createElement("select");p.style.cssText=m,["table","cards","list"].forEach(b=>{const f=document.createElement("option");f.value=b,f.textContent=b.charAt(0).toUpperCase()+b.slice(1),p.appendChild(f)}),h.appendChild(c),h.appendChild(p),t.appendChild(h);const F=document.createElement("button");F.type="button",F.className="btn btn-primary",F.textContent="Insert",t.appendChild(F);const N=E.modal({title:"Insert View",size:"sm"});N.element.appendChild(t),N.open(),F.addEventListener("click",()=>{const b=x.value;if(!b)return;const f=`[view slug="${b}" display="${p.value}" /]`;N.close(),ke(e,f),e.dispatchEvent(new Event("input",{bubbles:!0})),e.focus()})}),M.onCta(async e=>{const l=await Y.actions.list().catch(()=>[]),t=document.createElement("div");t.style.cssText="padding:1rem;display:flex;flex-direction:column;gap:.75rem;";const k="display:block;font-size:.85em;font-weight:600;margin-bottom:.25rem;color:var(--dm-text-muted,#aaa);text-transform:uppercase;letter-spacing:.05em;",m="width:100%;padding:.4rem .6rem;background:var(--dm-input-bg,#1a1a1a);border:1px solid var(--dm-border,#333);border-radius:4px;color:var(--dm-text,#eee);font-size:.9em;";function u(y,i){const g=document.createElement("div"),n=document.createElement("label");return n.style.cssText=k,n.textContent=y,g.appendChild(n),g.appendChild(i),g}function w(y){const i=document.createElement("select");return i.style.cssText=m,y.forEach(([g,n])=>{const r=document.createElement("option");r.value=g,r.textContent=n,i.appendChild(r)}),i}function x(y,i,g){const n=document.createElement("input");return n.type=y,n.placeholder=i||"",n.value=g||"",n.style.cssText=m,n}const h=w(l.length?l.map(y=>[y.slug,y.title||y.slug]):[["","No Actions configured yet \u2014 create one under Data \u2192 Actions"]]);t.appendChild(u("Action",h));const c=x("text","Button label","Run");if(t.appendChild(u("Label",c)),h.addEventListener("change",()=>{const y=l.find(i=>i.slug===h.value);y?.trigger?.label&&(c.value=y.trigger.label)}),l.length){const y=l[0];y?.trigger?.label&&(c.value=y.trigger.label)}const p=x("text","Paste entry UUID\u2026","");t.appendChild(u("Entry ID",p));const F=w([["primary","Primary"],["secondary","Secondary"],["ghost","Ghost"],["danger","Danger"]]);t.appendChild(u("Style",F));const N=x("text","e.g. check, zap, send (optional)","");t.appendChild(u("Icon",N));const b=x("text","Confirmation message (optional)","");t.appendChild(u("Confirm prompt",b));const f=document.createElement("button");f.type="button",f.className="btn btn-primary",f.textContent="Insert",t.appendChild(f);const B=E.modal({title:"Insert CTA Button",size:"sm"});B.element.appendChild(t),B.open(),f.addEventListener("click",()=>{const y=h.value;if(!y)return;const i=p.value.trim(),g=(c.value.trim()||"Run").replace(/\[\/cta\]/gi,""),n=F.value,r=N.value.trim().replace(/"/g,""),v=b.value.trim().replace(/"/g,""),A=i.replace(/"/g,"");let q=`action="${y}" style="${n}"`;A&&(q+=` entry="${A}"`),r&&(q+=` icon="${r}"`),v&&(q+=` confirm="${v}"`);const j=`[cta ${q}]${g}[/cta]`;B.close(),ke(e,j),e.dispatchEvent(new Event("input",{bubbles:!0})),e.focus()})}),M.onButton(async e=>{const l=(await Y.pages.list().catch(()=>[])).map(n=>({label:n.title||n.urlPath,value:n.urlPath})),t=document.createElement("div");t.style.cssText="padding:.25rem 0 .5rem;display:flex;flex-direction:column;gap:.75rem;";const k="display:block;font-size:.85em;font-weight:600;margin-bottom:.25rem;color:var(--dm-text-muted,#aaa);text-transform:uppercase;letter-spacing:.05em;",m="width:100%;padding:.4rem .6rem;background:var(--dm-input-bg,#1a1a1a);border:1px solid var(--dm-border,#333);border-radius:4px;color:var(--dm-text,#eee);font-size:.9em;";function u(n,r){const v=document.createElement("div"),A=document.createElement("label");return A.style.cssText=k,A.textContent=n,v.appendChild(A),v.appendChild(r),v}function w(n,r){const v=document.createElement("input");return v.type="text",v.placeholder=n,v.value=r||"",v.style.cssText=m,v}function x(n){const r=document.createElement("select");return r.style.cssText=m,n.forEach(([v,A])=>{const q=document.createElement("option");q.value=v,q.textContent=A,r.appendChild(q)}),r}const h=e.value.substring(e.selectionStart,e.selectionEnd),c=w("/about or https://example.com",h.startsWith("/")?h:"");t.appendChild(u("URL",c));const p=w("Button label",h&&!h.startsWith("/")?h:"");t.appendChild(u("Label",p));const F=x([["primary","Primary"],["secondary","Secondary"],["success","Success (Green)"],["danger","Danger (Red)"],["warning","Warning (Orange)"],["info","Info (Blue)"],["outline","Outline"],["ghost","Ghost"],["link","Link"],["outline-success","Outline Success"],["outline-danger","Outline Danger"]]);t.appendChild(u("Variant",F));const N=x([["","Default"],["sm","Small"],["lg","Large"]]);t.appendChild(u("Size",N));const b=w("e.g. arrow-right, star (optional)","");t.appendChild(u("Icon (before label)",b));const f=w("e.g. arrow-right (optional)","");t.appendChild(u("Icon (after label)",f));const B=document.createElement("label");B.style.cssText="display:flex;align-items:center;gap:.5rem;cursor:pointer;font-size:.9em;";const y=document.createElement("input");y.type="checkbox",y.style.cssText="width:1rem;height:1rem;",B.appendChild(y),B.appendChild(document.createTextNode("Open in new tab")),t.appendChild(B);const i=document.createElement("button");i.type="button",i.className="btn btn-primary",i.textContent="Insert Button",t.appendChild(i);const g=E.modal({title:"Insert Button",size:"sm"});g.element.appendChild(t),g.open(),requestAnimationFrame(()=>{E.autocomplete(c,{data:l,minChars:1,onSelect:n=>{c.value=n.value,p.value||(p.value=n.label)}}),c.focus()}),i.addEventListener("click",()=>{const n=c.value.trim();if(!n)return;g.close();const r=p.value.trim()||n;let v=`href="${n}" variant="${F.value}"`;N.value&&(v+=` size="${N.value}"`);const A=b.value.trim().replace(/"/g,"");A&&(v+=` icon="${A}"`);const q=f.value.trim().replace(/"/g,"");q&&(v+=` icon-after="${q}"`),y.checked&&(v+=' target="_blank"');const j=`[button ${v}]${r}[/button]`;ke(e,j)})}),M.onLinkShortcode(async e=>{const l=(await Y.pages.list().catch(()=>[])).map(i=>({label:i.title||i.urlPath,value:i.urlPath})),t=document.createElement("div");t.style.cssText="padding:.25rem 0 .5rem;display:flex;flex-direction:column;gap:.75rem;";const k="display:block;font-size:.85em;font-weight:600;margin-bottom:.25rem;color:var(--dm-text-muted,#aaa);text-transform:uppercase;letter-spacing:.05em;",m="width:100%;padding:.4rem .6rem;background:var(--dm-input-bg,#1a1a1a);border:1px solid var(--dm-border,#333);border-radius:4px;color:var(--dm-text,#eee);font-size:.9em;";function u(i,g){const n=document.createElement("div"),r=document.createElement("label");return r.style.cssText=k,r.textContent=i,n.appendChild(r),n.appendChild(g),n}function w(i,g){const n=document.createElement("input");return n.type="text",n.placeholder=i,n.value=g||"",n.style.cssText=m,n}const x=e.value.substring(e.selectionStart,e.selectionEnd),h=w("/about or https://example.com",x.startsWith("/")?x:"");t.appendChild(u("URL",h));const c=w("Link text",x&&!x.startsWith("/")?x:"");t.appendChild(u("Link text",c));const p=w("e.g. text-primary, fw-bold (optional)","");t.appendChild(u("CSS class",p));const F=w("e.g. arrow-right (optional)","");t.appendChild(u("Icon (before text)",F));const N=w("e.g. external-link (optional)","");t.appendChild(u("Icon (after text)",N));const b=document.createElement("label");b.style.cssText="display:flex;align-items:center;gap:.5rem;cursor:pointer;font-size:.9em;";const f=document.createElement("input");f.type="checkbox",f.style.cssText="width:1rem;height:1rem;",b.appendChild(f),b.appendChild(document.createTextNode("Open in new tab")),t.appendChild(b);const B=document.createElement("button");B.type="button",B.className="btn btn-primary",B.textContent="Insert Link",t.appendChild(B);const y=E.modal({title:"Insert Link Shortcode",size:"sm"});y.element.appendChild(t),y.open(),requestAnimationFrame(()=>{E.autocomplete(h,{data:l,minChars:1,onSelect:i=>{h.value=i.value,c.value||(c.value=i.label)}}),h.focus()}),B.addEventListener("click",()=>{const i=h.value.trim();if(!i)return;y.close();const g=c.value.trim()||i;let n=`href="${i}"`;const r=p.value.trim().replace(/"/g,"");r&&(n+=` class="${r}"`);const v=F.value.trim().replace(/"/g,"");v&&(n+=` icon="${v}"`);const A=N.value.trim().replace(/"/g,"");A&&(n+=` icon-after="${A}"`),f.checked&&(n+=' target="_blank"');const q=`[link ${n}]${g}[/link]`;ke(e,q)})}),M.onTabs(e=>{const l=document.createElement("div");l.style.cssText="padding:.25rem 0 .5rem;display:flex;flex-direction:column;gap:.75rem;";const t="display:block;font-size:.85em;font-weight:600;margin-bottom:.25rem;color:var(--dm-text-muted,#aaa);text-transform:uppercase;letter-spacing:.05em;",k="width:100%;padding:.4rem .6rem;background:var(--dm-input-bg,#1a1a1a);border:1px solid var(--dm-border,#333);border-radius:4px;color:var(--dm-text,#eee);font-size:.9em;";function m(y,i){const g=document.createElement("div"),n=document.createElement("label");return n.style.cssText=t,n.textContent=y,g.appendChild(n),g.appendChild(i),g}function u(y){const i=document.createElement("select");return i.style.cssText=k,y.forEach(([g,n])=>{const r=document.createElement("option");r.value=g,r.textContent=n,i.appendChild(r)}),i}const w=u([["","Default (underline)"],["pills","Pills"]]);l.appendChild(m("Style",w));const x=u([["","Left"],["center","Centre"]]);l.appendChild(m("Alignment",x));const h=document.createElement("div");h.style.cssText="display:flex;flex-direction:column;gap:.4rem;";const c=[];function p(){c.forEach(y=>{y.removeBtn.disabled=c.length<=2,y.removeBtn.style.opacity=c.length<=2?"0.3":"1"})}function F(y){const i=document.createElement("div");i.style.cssText="display:flex;gap:.4rem;align-items:center;";const g=document.createElement("input");g.type="text",g.placeholder="Tab title",g.value=y||"",g.style.cssText=k+"flex:1;";const n=document.createElement("button");n.type="button",n.textContent="\u2715",n.style.cssText="padding:.3rem .5rem;background:transparent;border:1px solid var(--dm-border,#333);border-radius:4px;color:var(--dm-text-muted,#aaa);cursor:pointer;font-size:.85em;flex-shrink:0;";const r={row:i,input:g,removeBtn:n};c.push(r),i.appendChild(g),i.appendChild(n),h.appendChild(i),n.addEventListener("click",()=>{if(c.length<=2)return;const v=c.indexOf(r);c.splice(v,1),h.removeChild(i),p()}),p()}F("Overview"),F("Details");const N=document.createElement("div");N.style.cssText=t,N.textContent="Tabs",l.appendChild(N),l.appendChild(h);const b=document.createElement("button");b.type="button",b.textContent="+ Add Tab",b.style.cssText="padding:.35rem .75rem;background:transparent;border:1px dashed var(--dm-border,#555);border-radius:4px;color:var(--dm-text-muted,#aaa);cursor:pointer;font-size:.85em;align-self:flex-start;",b.addEventListener("click",()=>{c.length>=10||(F(""),c[c.length-1].input.focus())}),l.appendChild(b);const f=document.createElement("button");f.type="button",f.className="btn btn-primary",f.textContent="Insert Tabs",l.appendChild(f);const B=E.modal({title:"Insert Tabs",size:"sm"});B.element.appendChild(l),B.open(),requestAnimationFrame(()=>c[0].input.focus()),f.addEventListener("click",()=>{B.close();const y=w.value,i=x.value;let g=y?` style="${y}"`:"";i&&(g+=` align="${i}"`);let n=`[tabs${g}]
89
89
  `;c.forEach((r,v)=>{const A=r.input.value.trim()||`Tab ${v+1}`;n+=`[tab title="${A}"]Tab content here.[/tab]
90
90
  `}),n+="[/tabs]",ke(e,n),e.dispatchEvent(new Event("input",{bubbles:!0})),e.focus()})}),M.onGrid(e=>{const l=document.createElement("div");l.style.cssText="padding:.25rem 0 .5rem;display:flex;flex-direction:column;gap:.75rem;";const t="display:block;font-size:.85em;font-weight:600;margin-bottom:.25rem;color:var(--dm-text-muted,#aaa);text-transform:uppercase;letter-spacing:.05em;",k="width:100%;padding:.4rem .6rem;background:var(--dm-input-bg,#1a1a1a);border:1px solid var(--dm-border,#333);border-radius:4px;color:var(--dm-text,#eee);font-size:.9em;";function m(H,X){const P=document.createElement("div"),L=document.createElement("label");return L.style.cssText=t,L.textContent=H,P.appendChild(L),P.appendChild(X),P}function u(H){const X=document.createElement("select");return X.style.cssText=k,H.forEach(([P,L])=>{const O=document.createElement("option");O.value=P,O.textContent=L,X.appendChild(O)}),X}let w="grid";const x=document.createElement("div");x.style.cssText="display:flex;gap:.5rem;";const h=document.createElement("button");h.type="button",h.className="btn btn-sm btn-primary",h.textContent="Grid";const c=document.createElement("button");c.type="button",c.className="btn btn-sm btn-ghost",c.textContent="Row",x.appendChild(h),x.appendChild(c),l.appendChild(x);const p=document.createElement("input");p.type="number",p.min="1",p.max="12",p.value="2",p.style.cssText=k,l.appendChild(m("Columns",p));const F=u([["0","0"],["1","1"],["2","2"],["3","3"],["4","4 (default)"],["6","6"],["8","8"],["10","10"],["12","12"],["16","16"]]);F.value="4",l.appendChild(m("Gap",F));const N=document.createElement("div");N.style.cssText="display:flex;flex-direction:column;gap:.5rem;";const b=document.createElement("label");b.style.cssText="display:flex;align-items:center;gap:.5rem;font-size:.9em;cursor:pointer;";const f=document.createElement("input");f.type="checkbox",b.appendChild(f),b.appendChild(document.createTextNode("Full width (breakout)")),N.appendChild(b);const B=document.createElement("div");B.style.cssText=t+"margin-top:.25rem;",B.textContent="Column Spans",N.appendChild(B);const y=document.createElement("div");y.style.cssText="display:flex;flex-direction:column;gap:.3rem;",N.appendChild(y),l.appendChild(N);const i=[];function g(){const H=Math.min(Math.max(parseInt(p.value)||2,1),12),X=i.map(P=>P.value);y.textContent="",i.length=0;for(let P=0;P<H;P++){const L=document.createElement("div");L.style.cssText="display:flex;align-items:center;gap:.5rem;";const O=document.createElement("span");O.style.cssText="font-size:.85em;color:var(--dm-text-muted,#aaa);white-space:nowrap;min-width:3em;",O.textContent=`Col ${P+1}`;const _=document.createElement("input");_.type="number",_.min="1",_.max="12",_.placeholder="auto",_.value=X[P]||"",_.style.cssText=k+"width:5em;flex:none;",L.appendChild(O),L.appendChild(_),y.appendChild(L),i.push(_)}}p.addEventListener("input",g),g();const n=document.createElement("div");n.style.cssText="display:none;flex-direction:column;gap:.5rem;";const r=document.createElement("label");r.style.cssText="display:flex;align-items:center;gap:.5rem;font-size:.9em;cursor:pointer;";const v=document.createElement("input");v.type="checkbox",r.appendChild(v),r.appendChild(document.createTextNode("Enable staggered reveal")),n.appendChild(r);const A=document.createElement("div");A.style.cssText="display:none;flex-direction:column;gap:.5rem;padding-left:.5rem;border-left:2px solid var(--dm-border,#333);";const q=u([["slide-up","Slide Up"],["slide-down","Slide Down"],["slide-left","Slide Left"],["slide-right","Slide Right"],["fade","Fade"],["zoom","Zoom"],["flip","Flip"]]);A.appendChild(m("Animation",q));const j=u([["stagger","Stagger"],["sequence","Sequence"]]);A.appendChild(m("Mode",j));const T=document.createElement("input");T.type="number",T.value="400",T.style.cssText=k,A.appendChild(m("Duration (ms)",T));const C=document.createElement("input");C.type="number",C.value="60",C.style.cssText=k,A.appendChild(m("Stagger (ms)",C));const d=document.createElement("input");d.type="number",d.value="0",d.style.cssText=k,A.appendChild(m("Delay (ms)",d));const s=u([["ltr","Left to Right"],["rtl","Right to Left"]]);A.appendChild(m("Direction",s)),n.appendChild(A),l.appendChild(n),v.addEventListener("change",()=>{A.style.display=v.checked?"flex":"none"});const o=document.createElement("button");o.type="button",o.className="btn btn-primary",o.textContent="Insert Grid",l.appendChild(o),h.addEventListener("click",()=>{w="grid",h.className="btn btn-sm btn-primary",c.className="btn btn-sm btn-ghost",N.style.display="flex",n.style.display="none",o.textContent="Insert Grid"}),c.addEventListener("click",()=>{w="row",c.className="btn btn-sm btn-primary",h.className="btn btn-sm btn-ghost",n.style.display="flex",N.style.display="none",o.textContent="Insert Row"});const he=E.modal({title:"Insert Grid / Row",size:"sm"});he.element.appendChild(l),he.open(),requestAnimationFrame(()=>p.focus()),o.addEventListener("click",()=>{he.close();const H=Math.min(Math.max(parseInt(p.value)||2,1),12),X=F.value;let P;if(w==="grid"){let L=`cols="${H}"`;X!=="4"&&(L+=` gap="${X}"`),f.checked&&(L+=' fullwidth="true"'),P=`[grid ${L}]
91
91
  `;for(let O=0;O<H;O++){const _=i[O]?.value?.trim(),G=_?` span="${_}"`:"";P+=`[col${G}]
@@ -97,4 +97,4 @@ Column ${O+1}
97
97
  `,p.forEach((L,O)=>{const _=L.input.value.trim()||`Item ${O+1}`;P+=`[item title="${_}"]Content here.[/item]
98
98
  `}),P+="[/accordion]";else{const L=g.value;if(!L)return;const O=v.value,_=j.value;let G=`slug="${L}" display="accordion"`;O&&(G+=` title-field="${O}"`),_&&(G+=` body-field="${_}"`);const K=s.value.trim();K&&(G+=` limit="${K}"`),he.checked&&(G+=' multiple="true"'),P=`[collection ${G} /]`}ke(e,P),e.dispatchEvent(new Event("input",{bubbles:!0})),e.focus()})}),M.onListGroup(e=>{const l=document.createElement("div");l.style.cssText="padding:.25rem 0 .5rem;display:flex;flex-direction:column;gap:.75rem;";const t="display:block;font-size:.85em;font-weight:600;margin-bottom:.25rem;color:var(--dm-text-muted,#aaa);text-transform:uppercase;letter-spacing:.05em;",k="width:100%;padding:.4rem .6rem;background:var(--dm-input-bg,#1a1a1a);border:1px solid var(--dm-border,#333);border-radius:4px;color:var(--dm-text,#eee);font-size:.9em;";function m(n,r){const v=document.createElement("div"),A=document.createElement("label");return A.style.cssText=t,A.textContent=n,v.appendChild(A),v.appendChild(r),v}function u(n){const r=document.createElement("select");return r.style.cssText=k,n.forEach(([v,A])=>{const q=document.createElement("option");q.value=v,q.textContent=A,r.appendChild(q)}),r}const w=u([["","Default"],["flush","Flush (no outer border)"],["numbered","Numbered"],["horizontal","Horizontal"]]);l.appendChild(m("Variant",w));const x=u([["","Default"],["sm","Small"],["lg","Large"]]);l.appendChild(m("Size",x));const h=u([["","Default"],["primary","Primary"],["secondary","Secondary"],["success","Success"],["danger","Danger"],["warning","Warning"],["info","Info"]]);l.appendChild(m("Item Colour",h));const c=document.createElement("label");c.style.cssText="display:flex;align-items:center;gap:.5rem;font-size:.9em;cursor:pointer;";const p=document.createElement("input");p.type="checkbox",c.appendChild(p),c.appendChild(document.createTextNode("Actionable items (hover highlight)")),l.appendChild(c);const F=document.createElement("div");F.style.cssText=t+"margin-bottom:.35rem;",F.textContent="Items",l.appendChild(F);const N=document.createElement("div");N.style.cssText="display:flex;flex-direction:column;gap:.4rem;",l.appendChild(N);const b=[];function f(){b.forEach(n=>{n.removeBtn.disabled=b.length<=1,n.removeBtn.style.opacity=b.length<=1?"0.3":"1"})}function B(n){const r=document.createElement("div");r.style.cssText="display:flex;gap:.4rem;align-items:center;";const v=document.createElement("input");v.type="text",v.placeholder="Item text",v.value=n||"",v.style.cssText=k+"flex:1;";const A=document.createElement("button");A.type="button",A.textContent="\u2715",A.style.cssText="padding:.3rem .5rem;background:transparent;border:1px solid var(--dm-border,#333);border-radius:4px;color:var(--dm-text-muted,#aaa);cursor:pointer;font-size:.85em;flex-shrink:0;";const q={row:r,input:v,removeBtn:A};b.push(q),r.appendChild(v),r.appendChild(A),N.appendChild(r),A.addEventListener("click",()=>{if(b.length<=1)return;const j=b.indexOf(q);b.splice(j,1),N.removeChild(r),f()}),f()}B("Item 1"),B("Item 2"),B("Item 3");const y=document.createElement("button");y.type="button",y.textContent="+ Add Item",y.style.cssText="padding:.35rem .75rem;background:transparent;border:1px dashed var(--dm-border,#555);border-radius:4px;color:var(--dm-text-muted,#aaa);cursor:pointer;font-size:.85em;align-self:flex-start;",y.addEventListener("click",()=>{b.length>=20||(B(""),b[b.length-1].input.focus())}),l.appendChild(y);const i=document.createElement("button");i.type="button",i.className="btn btn-primary",i.textContent="Insert List Group",l.appendChild(i);const g=E.modal({title:"Insert List Group",size:"sm"});g.element.appendChild(l),g.open(),requestAnimationFrame(()=>b[0].input.focus()),i.addEventListener("click",()=>{g.close();let n="";w.value&&(n+=` variant="${w.value}"`),x.value&&(n+=` size="${x.value}"`),h.value&&(n+=` itemvariant="${h.value}"`),p.checked&&(n+=' action="true"');let r=`[listgroup${n}]
99
99
  `;b.forEach(v=>{const A=v.input.value.trim();A&&(r+=`[item]${A}[/item]
100
- `)}),r+="[/listgroup]",ke(e,r),e.dispatchEvent(new Event("input",{bubbles:!0})),e.focus()})}),M.onHelp(()=>{Je()}),a.find(".editor-view-btn").on("click",function(){const e=$(this).data("mode");e&&(a.find(".editor-view-btn").removeClass("active"),$(this).addClass("active"),a.find("#editor-body").removeClass("editor-mode-split editor-mode-write editor-mode-preview").addClass(`editor-mode-${e}`),Ve("viewMode",e))}),a.find("#fullscreen-btn").on("click",function(){a.find(".editor-card").toggleClass("editor-fullscreen"),Ve("fullscreen",a.find(".editor-card").hasClass("editor-fullscreen"))}),Ae=!1,a.find("#quick-switch").prop("disabled",!1),Pe&&window.removeEventListener("beforeunload",Pe),Pe=e=>{Ae&&e.preventDefault()},window.addEventListener("beforeunload",Pe),Oe||(Oe=!0,R.use((e,l,t)=>{const k=window.location.hash.startsWith("#/pages/edit")||window.location.hash==="#/pages/new";if(!Ae||!k)return t();E.confirm("You have unsaved changes. Leave this page?").then(m=>{m&&(Ae=!1,t())})})),ce.on("input",()=>{ee||(Ae=!0,a.find("#quick-switch").prop("disabled",!0),De())});const Fe=a.find("#editor-meta-tabs").get(0);Fe&&(Fe.addEventListener("input",()=>{Ae=!0,a.find("#quick-switch").prop("disabled",!0)}),Fe.addEventListener("change",e=>{e.target.id!=="quick-switch"&&(Ae=!0,a.find("#quick-switch").prop("disabled",!0))})),De(),a.find("#save-btn").on("click",async()=>{const e=a.find("#page-url-path").val().trim();if(!e){E.toast("URL path is required.",{type:"warning"});return}const l=a.find("#field-dconfig").val().trim();let t=null;if(l)try{t=JSON.parse(l)}catch{E.toast("DConfig JSON is invalid. Please check the format before saving.",{type:"warning"});return}const k={title:a.find("#field-title").val().trim()||"Untitled",description:a.find("#field-description").val().trim(),layout:a.find("#field-layout").val(),status:a.find("#field-status").val(),sortOrder:parseInt(a.find("#field-sort-order").val(),10)||99,showInNav:a.find("#field-show-in-nav").is(":checked"),sidebar:a.find("#field-sidebar").is(":checked"),...a.find("#field-show-breadcrumbs").is(":checked")?{}:{breadcrumbs:!1},...a.find("#field-bundled").is(":checked")?{bundled:!0}:{},tags:Ce?Ce.getValue():[],category:a.find("#field-category").val().trim()||null,visibility:a.find("#field-visibility").val()||"public",seo:{title:a.find("#field-seo-title").val().trim(),description:a.find("#field-seo-desc").val().trim()},dconfig:t,...a.find("#field-theme").val()?{theme:a.find("#field-theme").val()}:{}};try{a.find("#save-btn").prop("disabled",!0).text("Saving\u2026");const m=ae.getUnfoldedContent();if(U){const u={frontmatter:k,body:m};e!==oe&&(u.newUrlPath=e),await Y.pages.update(oe,u),ne&&await Y.settings.saveCustomCss(a.find("#css-editor").val()),E.toast(ne?"Page and CSS saved.":"Page saved successfully.",{type:"success"}),Ae=!1,a.find("#quick-switch").prop("disabled",!1),e!==oe&&R.navigate(`/pages/edit${e}`)}else await Y.pages.create({urlPath:e,frontmatter:k,body:m}),ne&&await Y.settings.saveCustomCss(a.find("#css-editor").val()),E.toast(ne?"Page and CSS saved.":"Page saved successfully.",{type:"success"}),Ae=!1,R.navigate("/pages")}catch(m){E.toast(`Save failed: ${m.message||"Unknown error"}`,{type:"error"})}finally{a.find("#save-btn").prop("disabled",!1).text("Save")}}),a.find("#cancel-btn").on("click",()=>R.navigate("/pages")),Domma.icons.scan()}};
100
+ `)}),r+="[/listgroup]",ke(e,r),e.dispatchEvent(new Event("input",{bubbles:!0})),e.focus()})}),M.onCard(e=>{He.open(e,{onMediaBrowse:()=>Y.media.list().catch(()=>[])})}),M.onHelp(()=>{Qe()}),a.find(".editor-view-btn").on("click",function(){const e=$(this).data("mode");e&&(a.find(".editor-view-btn").removeClass("active"),$(this).addClass("active"),a.find("#editor-body").removeClass("editor-mode-split editor-mode-write editor-mode-preview").addClass(`editor-mode-${e}`),Ve("viewMode",e))}),a.find("#fullscreen-btn").on("click",function(){a.find(".editor-card").toggleClass("editor-fullscreen"),Ve("fullscreen",a.find(".editor-card").hasClass("editor-fullscreen"))}),Ae=!1,a.find("#quick-switch").prop("disabled",!1),Pe&&window.removeEventListener("beforeunload",Pe),Pe=e=>{Ae&&e.preventDefault()},window.addEventListener("beforeunload",Pe),Oe||(Oe=!0,R.use((e,l,t)=>{const k=window.location.hash.startsWith("#/pages/edit")||window.location.hash==="#/pages/new";if(!Ae||!k)return t();E.confirm("You have unsaved changes. Leave this page?").then(m=>{m&&(Ae=!1,t())})})),ce.on("input",()=>{ee||(Ae=!0,a.find("#quick-switch").prop("disabled",!0),De())});const Fe=a.find("#editor-meta-tabs").get(0);Fe&&(Fe.addEventListener("input",()=>{Ae=!0,a.find("#quick-switch").prop("disabled",!0)}),Fe.addEventListener("change",e=>{e.target.id!=="quick-switch"&&(Ae=!0,a.find("#quick-switch").prop("disabled",!0))})),De(),a.find("#save-btn").on("click",async()=>{const e=a.find("#page-url-path").val().trim();if(!e){E.toast("URL path is required.",{type:"warning"});return}const l=a.find("#field-dconfig").val().trim();let t=null;if(l)try{t=JSON.parse(l)}catch{E.toast("DConfig JSON is invalid. Please check the format before saving.",{type:"warning"});return}const k={title:a.find("#field-title").val().trim()||"Untitled",description:a.find("#field-description").val().trim(),layout:a.find("#field-layout").val(),status:a.find("#field-status").val(),sortOrder:parseInt(a.find("#field-sort-order").val(),10)||99,showInNav:a.find("#field-show-in-nav").is(":checked"),sidebar:a.find("#field-sidebar").is(":checked"),...a.find("#field-show-breadcrumbs").is(":checked")?{}:{breadcrumbs:!1},...a.find("#field-bundled").is(":checked")?{bundled:!0}:{},tags:Ce?Ce.getValue():[],category:a.find("#field-category").val().trim()||null,visibility:a.find("#field-visibility").val()||"public",seo:{title:a.find("#field-seo-title").val().trim(),description:a.find("#field-seo-desc").val().trim()},dconfig:t,...a.find("#field-theme").val()?{theme:a.find("#field-theme").val()}:{}};try{a.find("#save-btn").prop("disabled",!0).text("Saving\u2026");const m=ae.getUnfoldedContent();if(U){const u={frontmatter:k,body:m};e!==oe&&(u.newUrlPath=e),await Y.pages.update(oe,u),ne&&await Y.settings.saveCustomCss(a.find("#css-editor").val()),E.toast(ne?"Page and CSS saved.":"Page saved successfully.",{type:"success"}),Ae=!1,a.find("#quick-switch").prop("disabled",!1),e!==oe&&R.navigate(`/pages/edit${e}`)}else await Y.pages.create({urlPath:e,frontmatter:k,body:m}),ne&&await Y.settings.saveCustomCss(a.find("#css-editor").val()),E.toast(ne?"Page and CSS saved.":"Page saved successfully.",{type:"success"}),Ae=!1,R.navigate("/pages")}catch(m){E.toast(`Save failed: ${m.message||"Unknown error"}`,{type:"error"})}finally{a.find("#save-btn").prop("disabled",!1).text("Save")}}),a.find("#cancel-btn").on("click",()=>R.navigate("/pages")),Domma.icons.scan()}};
@@ -1 +1 @@
1
- export const tutorialsView={templateUrl:"/admin/js/templates/tutorials.html",async onMount(t){Domma.icons.scan(),Domma.syntax.scan()}};
1
+ export const tutorialsView={templateUrl:"/admin/js/templates/tutorials.html",async onMount(t){E.tabs(t.find("#tutorials-tabs").get(0)),Domma.icons.scan(),Domma.syntax.scan()}};
package/config/site.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "tagline": "A nice little bloggy type thingy.",
4
4
  "fontFamily": "Roboto",
5
5
  "fontSize": 16,
6
- "theme": "charcoal-dark",
6
+ "theme": "lemon-light",
7
7
  "autoTheme": {
8
8
  "enabled": false,
9
9
  "dayTheme": "charcoal-light",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "domma-cms",
3
- "version": "0.9.6",
3
+ "version": "0.9.10",
4
4
  "description": "File-based CMS powered by Domma and Fastify. Run npx domma-cms my-site to create a new project.",
5
5
  "type": "module",
6
6
  "main": "server/server.js",
@@ -44,7 +44,6 @@ export const notesView = {
44
44
  let activeCategory = '';
45
45
  let searchQuery = '';
46
46
  let editingNoteId = null;
47
- let notesTable = null;
48
47
 
49
48
  // ---- DOM refs ----
50
49
  const editorEl = $container.find('#note-editor').get(0);
@@ -79,16 +78,13 @@ export const notesView = {
79
78
  }
80
79
  }
81
80
 
82
- // ---- Render table (T.create on first call, setData on subsequent) ----
81
+ // ---- Render table ----
83
82
  function renderTable() {
84
- if (notesTable) {
85
- notesTable.setData(notes);
86
- return;
87
- }
83
+ const wrap = $container.find('#notes-table').get(0);
84
+ if (!wrap) return;
88
85
 
89
- notesTable = T.create('#notes-table', {
86
+ T.create(wrap, {
90
87
  data: notes,
91
- onRender: (el) => Domma.icons.scan(el),
92
88
  columns: [
93
89
  {
94
90
  key: 'title',
@@ -133,33 +129,35 @@ export const notesView = {
133
129
  title: 'Actions',
134
130
  sortable: false,
135
131
  render: (id) =>
136
- `<button class="btn btn-sm btn-outline note-edit-btn" data-id="${esc(id)}" style="margin-right:4px;">` +
137
- `<span data-icon="edit" data-icon-size="13"></span> Edit</button>` +
138
- `<button class="btn btn-sm btn-danger note-delete-btn" data-id="${esc(id)}">` +
139
- `<span data-icon="trash" data-icon-size="13"></span></button>`
132
+ `<div style="display:flex;gap:.4rem;">` +
133
+ `<button class="btn btn-sm btn-outline note-edit-btn" data-id="${esc(id)}">Edit</button>` +
134
+ `<button class="btn btn-sm btn-danger note-delete-btn" data-id="${esc(id)}">Delete</button>` +
135
+ `</div>`
140
136
  }
141
137
  ],
142
138
  emptyMessage: 'No notes yet. Click New Note to get started.'
143
139
  });
144
140
 
145
- // Event delegation on the table container
146
- const tableContainer = $container.find('#notes-table').get(0);
147
- tableContainer.addEventListener('click', (e) => {
148
- const editBtn = e.target.closest('.note-edit-btn');
149
- const deleteBtn = e.target.closest('.note-delete-btn');
150
- const catTag = e.target.closest('.notes-cat-tag');
151
-
152
- if (editBtn) {
153
- const note = notes.find((n) => n.id === editBtn.dataset.id);
141
+ wrap.querySelectorAll('.note-edit-btn').forEach((btn) => {
142
+ btn.addEventListener('click', () => {
143
+ const note = notes.find((n) => n.id === btn.dataset.id);
154
144
  if (note) openEditor(note);
155
- } else if (deleteBtn) {
156
- deleteNote(deleteBtn.dataset.id);
157
- } else if (catTag) {
158
- activeCategory = catTag.dataset.cat;
145
+ });
146
+ });
147
+
148
+ wrap.querySelectorAll('.note-delete-btn').forEach((btn) => {
149
+ btn.addEventListener('click', () => deleteNote(btn.dataset.id));
150
+ });
151
+
152
+ wrap.querySelectorAll('.notes-cat-tag').forEach((tag) => {
153
+ tag.addEventListener('click', () => {
154
+ activeCategory = tag.dataset.cat;
159
155
  renderCategoryFilter();
160
156
  loadNotes().then(renderTable);
161
- }
157
+ });
162
158
  });
159
+
160
+ Domma.icons.scan(wrap);
163
161
  }
164
162
 
165
163
  // ---- Render category filter bar (DOM methods — no innerHTML with user data) ----
@@ -55,7 +55,6 @@ export const todoView = {
55
55
  // ---- State ----
56
56
  let todos = [];
57
57
  let activeFilter = 'all';
58
- let todoTable = null;
59
58
 
60
59
  // ---- Fetch ----
61
60
  async function loadTodos() {
@@ -70,18 +69,15 @@ export const todoView = {
70
69
 
71
70
  // ---- Render table ----
72
71
  function render() {
72
+ const wrap = $container.find('#todo-table').get(0);
73
+ if (!wrap) return;
74
+
73
75
  const filtered = activeFilter === 'all'
74
76
  ? todos
75
77
  : todos.filter((t) => t.status === activeFilter);
76
78
 
77
- if (todoTable) {
78
- todoTable.setData(filtered);
79
- return;
80
- }
81
-
82
- todoTable = T.create('#todo-table', {
79
+ T.create(wrap, {
83
80
  data: filtered,
84
- onRender: (el) => Domma.icons.scan(el),
85
81
  columns: [
86
82
  {
87
83
  key: 'status',
@@ -150,40 +146,42 @@ export const todoView = {
150
146
  title: 'Actions',
151
147
  sortable: false,
152
148
  render: (id) =>
153
- `<button class="btn btn-sm btn-ghost edit-todo" data-id="${esc(id)}" title="Edit" style="margin-right:3px;">` +
154
- `<span data-icon="edit" data-icon-size="13"></span></button>` +
155
- `<button class="btn btn-sm btn-danger delete-todo" data-id="${esc(id)}" title="Delete">` +
156
- `<span data-icon="trash" data-icon-size="13"></span></button>`
149
+ `<div style="display:flex;gap:.4rem;">` +
150
+ `<button class="btn btn-sm btn-outline edit-todo" data-id="${esc(id)}">Edit</button>` +
151
+ `<button class="btn btn-sm btn-danger delete-todo" data-id="${esc(id)}">Delete</button>` +
152
+ `</div>`
157
153
  }
158
154
  ],
159
155
  emptyMessage: 'No tasks yet. Add one above to get started.'
160
156
  });
161
157
 
162
- // Event delegation on the table container
163
- const tableContainer = $container.find('#todo-table').get(0);
164
-
165
- tableContainer.addEventListener('change', (e) => {
166
- const target = e.target;
167
- const id = target.dataset.id;
168
- if (!id) return;
169
-
170
- if (target.classList.contains('todo-checkbox')) {
171
- toggleTodo(id);
172
- } else if (target.classList.contains('status-select')) {
173
- target.className = target.className.replace(/status-pill-\S+/g, `status-pill-${target.value}`);
174
- updateStatus(id, target.value);
175
- } else if (target.classList.contains('priority-select')) {
176
- target.className = target.className.replace(/priority-pill-\S+/g, `priority-pill-${target.value}`);
177
- updatePriority(id, target.value);
178
- }
158
+ wrap.querySelectorAll('.edit-todo').forEach((btn) => {
159
+ btn.addEventListener('click', () => editTodo(btn.dataset.id));
179
160
  });
180
161
 
181
- tableContainer.addEventListener('click', (e) => {
182
- const editBtn = e.target.closest('.edit-todo');
183
- const deleteBtn = e.target.closest('.delete-todo');
184
- if (editBtn) editTodo(editBtn.dataset.id);
185
- if (deleteBtn) deleteTodo(deleteBtn.dataset.id);
162
+ wrap.querySelectorAll('.delete-todo').forEach((btn) => {
163
+ btn.addEventListener('click', () => deleteTodo(btn.dataset.id));
186
164
  });
165
+
166
+ wrap.querySelectorAll('.todo-checkbox').forEach((cb) => {
167
+ cb.addEventListener('change', () => toggleTodo(cb.dataset.id));
168
+ });
169
+
170
+ wrap.querySelectorAll('.status-select').forEach((sel) => {
171
+ sel.addEventListener('change', () => {
172
+ sel.className = sel.className.replace(/status-pill-\S+/g, `status-pill-${sel.value}`);
173
+ updateStatus(sel.dataset.id, sel.value);
174
+ });
175
+ });
176
+
177
+ wrap.querySelectorAll('.priority-select').forEach((sel) => {
178
+ sel.addEventListener('change', () => {
179
+ sel.className = sel.className.replace(/priority-pill-\S+/g, `priority-pill-${sel.value}`);
180
+ updatePriority(sel.dataset.id, sel.value);
181
+ });
182
+ });
183
+
184
+ Domma.icons.scan(wrap);
187
185
  }
188
186
 
189
187
  // ---- Add todo ----