@obelism/content 0.19.1 → 0.19.2
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.
- package/dist/bridge.global.js +17 -4
- package/dist/bridge.js +24 -4
- package/dist/bridge.mjs +24 -4
- package/package.json +1 -1
package/dist/bridge.global.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
!/*! Obelism Content bridge (@obelism/content), MIT. https://content.obelism.studio/docs/guides/visual-editor */function(){"use strict";var e;let t="data-cms-uid",r="data-cms-entry",n="data-cms-product",o="cms_environment",a={clicked:"{rate}% clicked",title:"{clickers} of {viewers} visitors of its page clicked it in the last 30 days ({clicks} clicks)"},i=(e,t)=>e.replace(/\{(\w+)\}/g,(e,r)=>r in t?String(t[r]):e),
|
|
1
|
+
!/*! Obelism Content bridge (@obelism/content), MIT. https://content.obelism.studio/docs/guides/visual-editor */function(){"use strict";var e;let t="data-cms-uid",r="data-cms-entry",n="data-cms-product",o="cms_environment",a={clicked:"{rate}% clicked",title:"{clickers} of {viewers} visitors of its page clicked it in the last 30 days ({clicks} clicks)"},i=(e,t)=>e.replace(/\{(\w+)\}/g,(e,r)=>r in t?String(t[r]):e),s=`
|
|
2
2
|
:host { all: initial; }
|
|
3
3
|
.layer {
|
|
4
4
|
position: fixed; inset: 0; pointer-events: none;
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
.badge[data-place='beside'] { transform: translateY(-50%); }
|
|
23
23
|
.badge[data-place='above'] { transform: translate(-100%, -100%); }
|
|
24
24
|
.badge:focus-visible { outline: 2px solid rgb(212 130 30); outline-offset: 2px; }
|
|
25
|
-
`,
|
|
25
|
+
`,l=(e,t)=>e.height>=64?{place:"inside",top:Math.max(e.top,0)+8,left:e.right-8}:e.right+8+140<=t?{place:"beside",top:e.top+e.height/2,left:e.right+8}:{place:"above",top:e.top-4,left:e.right},d="obelism-content-bridge",c="#d58a1f",p=(e="")=>`${e}[${t}]{cursor:pointer;transition:outline-color .15s}${e}[${t}]:hover{outline:2px dashed ${c};outline-offset:2px}${e}[${t}][data-cms-selected]{outline:2px solid ${c};outline-offset:2px}`,g={features:[],selectedUid:null,prompting:!1,canUndo:!1,unsaved:!1,saving:!1,publishing:!1,selecting:!1,stats:{},statsVisible:!1},u=()=>{let e={update:new Set,saved:new Set,published:new Set,change:new Set};return{listeners:e,on:(t,r)=>(e[t].add(r),()=>{e[t].delete(r)}),emit(t,r){for(let n of e[t])try{n(r)}catch(e){console.error("[@obelism/content bridge]",e)}}}},h=()=>Promise.reject(Error("Save and publish in the visual editor itself")),m=()=>Promise.reject(Error("Only while signed in to edit on the site")),b={prompt:()=>Promise.reject(Error("Prompts only work inside the visual editor")),createPage:()=>Promise.reject(Error("New pages are made on the site itself")),createProductPage:()=>Promise.reject(Error("Product pages are made on the site itself")),view:m,applyJson:m,openForm:(e,t={})=>(queueMicrotask(()=>t.onError?.("Only while signed in to edit on the site")),{close:()=>{}}),pages:m,openPage:()=>{},undo:()=>{},save:h,publish:h,signOut:()=>{},select:()=>{},setSelecting:()=>{}},f=e=>"number"==typeof e&&Number.isFinite(e)&&e>=0,v=e=>`[${t}="${e.replace(/["\\]/g,"\\$&")}"]`,y=(e,t)=>{let r=u();e.on("saved",()=>r.emit("saved",{})),e.on("published",()=>r.emit("published",{}));let n=!1;return{isEditing:e.isEditing,mode:e.isEditing?"editor":null,entryId:e.entryId,environment:t.get(o),product:null,on:(t,o)=>("update"!==t||n||(n=!0,e.on("update",e=>{let t=e?.entry;t&&r.emit("update",{entry:t,selectedUid:null})})),r.on(t,o)),getState:()=>g,...b,destroy:()=>{}}},x={open:"Edit with a prompt",placeholder:"Describe a change, e.g. “make the heading shorter”",send:"Apply",undo:"Undo",close:"Close",minimize:"Minimize, to see the page",expand:"Expand",scopeEntry:"Whole page",scopeBlock:"Selected block",clearBlock:"Edit the whole page instead",working:"Working on it…",save:"Save",publish:"Publish",saving:"Saving…",publishing:"Publishing…",saved:"Saved as a draft",published:"Published",unsaved:"Unsaved changes",signOut:"Exit editing",viewingDrafts:"Viewing drafts",selectHint:"Click a block to change only that block",newPage:"New page",newPageCancel:"Edit this page instead",newPagePlaceholder:"Describe the new page, e.g. “a pricing page for agencies”",path:"Path",pathPlaceholder:"/pricing",creating:"Writing the page…",created:"Opening the new page…",modes:"Edit with",modePrompt:"Prompt",form:"Form",formTitle:"The content form",formLoading:"Opening the form…",pages:"Pages",pagesSearch:"Find a page",pagesLoading:"Loading pages…",pagesEmpty:"No pages match",pageCurrent:"This page",pageDraft:"Draft",pageChanged:"Changed",addProductPage:"Add a product page",addingProductPage:"Making the product page…",addedProductPage:"Opening the product page…",productPageHint:"This product has no page yet. Add one for what the store doesn’t say."},w="obelism-content-prompt-side",k={page:'<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/>',newPage:'<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/><path d="M9 15h6"/><path d="M12 18v-6"/>',block:'<rect width="18" height="18" x="3" y="3" rx="2"/><path d="M7 8h10"/><path d="M7 12h6"/>',undo:'<path d="M9 14 4 9l5-5"/><path d="M4 9h10.5a5.5 5.5 0 0 1 0 11H11"/>',close:'<path d="M18 6 6 18"/><path d="m6 6 12 12"/>',minimize:'<path d="m6 9 6 6 6-6"/>',expand:'<path d="m18 15-6-6-6 6"/>',chevrons:'<path d="m7 15 5 5 5-5"/><path d="m7 9 5-5 5 5"/>',search:'<circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/>',check:'<path d="M20 6 9 17l-5-5"/>',mark:'<path d="M12 3v18M3 12h18"/><g fill="currentColor" stroke="none"><circle cx="7" cy="7" r="1.75"/><circle cx="17" cy="7" r="1.75"/><circle cx="7" cy="17" r="1.75"/><circle cx="17" cy="17" r="1.75"/></g>',send:'<path d="M3.714 3.048a.498.498 0 0 0-.683.627l2.843 7.627a2 2 0 0 1 0 1.396l-2.842 7.627a.498.498 0 0 0 .682.627l18-8.5a.5.5 0 0 0 0-.904z"/><path d="M6 12h16"/>'},E=`
|
|
26
26
|
:host { all: initial; }
|
|
27
27
|
* { box-sizing: border-box; font: inherit; color: inherit; margin: 0; }
|
|
28
28
|
.root {
|
|
@@ -136,7 +136,20 @@ textarea::placeholder { color: rgb(var(--theme-foreground-muted-rgb)); }
|
|
|
136
136
|
display: block; width: 100%; height: min(560px, 60vh); border: none; border-radius: 12px;
|
|
137
137
|
background: rgb(var(--theme-background-actions-rgb) / .45);
|
|
138
138
|
}
|
|
139
|
-
|
|
139
|
+
/* Loading, it keeps the form's own height, the spinner in the middle,
|
|
140
|
+
whatever the form says meanwhile; the frame shows once the form does. */
|
|
141
|
+
.form.loading { position: relative; height: calc(min(560px, 60vh) + 12px); }
|
|
142
|
+
.form.loading iframe { position: absolute; visibility: hidden; }
|
|
143
|
+
.form-loader {
|
|
144
|
+
position: absolute; inset: 12px 12px 0; display: flex; align-items: center; justify-content: center;
|
|
145
|
+
gap: 10px; border-radius: 12px; color: rgb(var(--theme-foreground-muted-rgb));
|
|
146
|
+
background: rgb(var(--theme-background-actions-rgb) / .45);
|
|
147
|
+
}
|
|
148
|
+
.form-loader::before {
|
|
149
|
+
content: ''; width: 16px; height: 16px; flex: none; border-radius: 50%;
|
|
150
|
+
border: 2px solid rgb(var(--theme-border-rgb) / .3); border-top-color: rgb(var(--theme-accent-rgb));
|
|
151
|
+
animation: spin .7s linear infinite;
|
|
152
|
+
}
|
|
140
153
|
/* New page: where it goes, above what it is for. */
|
|
141
154
|
.path {
|
|
142
155
|
display: flex; align-items: center; gap: 10px; padding: 16px 22px 0;
|
|
@@ -244,4 +257,4 @@ button.chip:disabled { opacity: .5; }
|
|
|
244
257
|
.empty { padding: 8px 12px; color: rgb(var(--theme-foreground-muted-rgb)); }
|
|
245
258
|
.empty.error { color: var(--theme-error); }
|
|
246
259
|
[hidden] { display: none !important; }
|
|
247
|
-
`,C=(e,t,r={},...n)=>{let o=e.createElement(t);for(let t of(Object.assign(o,r),n))o.appendChild("string"==typeof t?e.createTextNode(t):t);return o},P=(e,t)=>{let r=C(e,"span",{className:"icon"});return r.setAttribute("aria-hidden","true"),r.innerHTML=`<svg viewBox="0 0 24 24">${k[t]}</svg>`,r},S=(e,t,r={})=>{let n,o={...x,...r.labels},a=C(e,"div");a.setAttribute("data-obelism-content-prompt","");let i=a.attachShadow({mode:"open"}),l="site"===t.mode,s=C(e,"span",{textContent:o.open}),d=C(e,"button",{className:"pill",type:"button"},s,((n=P(e,"mark")).classList.add("mark"),n)),c=C(e,"span",{className:"pill compact"},`${o.viewingDrafts} \xb7 `),p=C(e,"button",{className:"link",type:"button",textContent:o.signOut});c.appendChild(p);let g=C(e,"p",{className:"status"});g.setAttribute("role","status");let u=C(e,"textarea",{placeholder:o.placeholder,rows:1});u.setAttribute("aria-label",o.open);let h=C(e,"div",{className:"form"}),m=P(e,"page"),b=P(e,"block"),f=C(e,"span"),v=C(e,"button",{type:"button",title:o.clearBlock});v.setAttribute("aria-label",o.clearBlock),v.appendChild(P(e,"close"));let y=C(e,"span",{className:"chip scope"},m,b,f,v),k=C(e,"button",{className:"action chip",type:"button"},P(e,"undo"),o.undo),S=t=>{let r=C(e,"button",{type:"button",textContent:t});return r.setAttribute("aria-pressed","false"),r},L=S(o.modePrompt),A=S(o.form),N=C(e,"span",{className:"modes"},L,A);N.setAttribute("role","group"),N.setAttribute("aria-label",o.modes);let I=C(e,"button",{className:"action chip",type:"button"},P(e,"newPage"),o.newPage),U=C(e,"button",{className:"action chip product",type:"button"},P(e,"newPage"),o.addProductPage),M=C(e,"button",{type:"button",title:o.newPageCancel});M.setAttribute("aria-label",o.newPageCancel),M.appendChild(P(e,"close"));let $=C(e,"span",{className:"chip scope"},P(e,"newPage"),C(e,"span",{textContent:o.newPage}),M),O=C(e,"input",{type:"text",placeholder:o.pathPlaceholder,autocomplete:"off",spellcheck:!1}),j=C(e,"label",{className:"path"},C(e,"span",{textContent:o.path}),O),R=C(e,"button",{className:"close icon-button",type:"button",title:o.close},P(e,"close"));R.setAttribute("aria-label",o.close);let T=P(e,"minimize"),z=P(e,"expand"),D=C(e,"button",{className:"icon-button",type:"button"},T,z),F=C(e,"button",{className:"action primary icon-button",type:"submit"},C(e,"span",{className:"visually-hidden",textContent:o.send}),P(e,"send"));F.title=o.send;let B=C(e,"span",{className:"divider"}),q=C(e,"div",{className:"toolbar"},y,$,N,k,U,I,C(e,"span",{className:"spacer"}),D,R,B,F),V=C(e,"span",{textContent:o.pages}),W=C(e,"button",{className:"chip page-chip",type:"button",title:o.pages},P(e,"page"),V,P(e,"chevrons"));W.setAttribute("aria-haspopup","listbox"),W.setAttribute("aria-expanded","false"),W.setAttribute("aria-controls","obelism-pages");let H=C(e,"input",{type:"text",placeholder:o.pagesSearch,autocomplete:"off",spellcheck:!1});H.setAttribute("role","combobox"),H.setAttribute("aria-label",o.pagesSearch),H.setAttribute("aria-autocomplete","list"),H.setAttribute("aria-expanded","true"),H.setAttribute("aria-controls","obelism-pages");let Y=C(e,"ul",{className:"options",id:"obelism-pages"});Y.setAttribute("role","listbox"),Y.setAttribute("aria-label",o.pages);let X=C(e,"p",{className:"empty"}),_=C(e,"div",{className:"pages"},C(e,"label",{className:"search"},P(e,"search"),H),Y,X),J=C(e,"span",{className:"unsaved"});J.appendChild(C(e,"span",{className:"dot"})),J.appendChild(e.createTextNode(o.unsaved));let Z=C(e,"button",{className:"link",type:"button",textContent:o.signOut}),K=C(e,"button",{className:"action chip",type:"button",textContent:o.save}),G=C(e,"button",{className:"action chip",type:"button",textContent:o.publish}),Q=C(e,"div",{className:"footer"},W,J,C(e,"span",{className:"spacer"}),Z,K,G),ee=C(e,"form",{className:"panel"},g,j,u,h,q,_,Q),et=C(e,"div",{className:"root"},C(e,"div",{className:"bar"},d,c),ee);i.append(C(e,"style",{textContent:E}),et);let er=e.defaultView,en=e=>{"center"===e?delete et.dataset.side:et.dataset.side=e};en((()=>{try{let e=er?.localStorage.getItem(w);return"left"===e||"right"===e?e:"center"}catch{return"center"}})());let eo=null,ea=!1;et.addEventListener("pointerdown",e=>{if(ea=!1,0!==e.button||!e.isPrimary)return;let t=e.target.closest("button, input, textarea, iframe, a, label, .pages, .form");if(t&&t!==d)return;let{left:r,right:n}=et.getBoundingClientRect();eo={id:e.pointerId,startX:e.clientX,x:e.clientX,velocity:0,time:e.timeStamp,moved:!1,min:Math.min(0,16-r),max:Math.max(0,(er?.innerWidth??0)-16-n)}}),et.addEventListener("pointermove",e=>{if(!eo||e.pointerId!==eo.id)return;let t=e.clientX-eo.startX;if(!eo.moved){if(6>Math.abs(t))return;eo.moved=!0,et.classList.add("dragging");try{et.setPointerCapture(e.pointerId)}catch{}}let r=e.timeStamp-eo.time;r>0&&(eo.velocity=(e.clientX-eo.x)/r),eo.x=e.clientX,eo.time=e.timeStamp;let n=Math.min(Math.max(t,eo.min),eo.max);et.style.translate=`${n+(t-n)/3}px 0`});let ei=e=>{if(!eo||e.pointerId!==eo.id)return;let{moved:t,x:r,velocity:n,time:o}=eo;if(eo=null,!t)return;ea=!0;let a=et.getBoundingClientRect().left,i=er?.innerWidth??0,l=r+(e.timeStamp-o>80?0:Math.min(Math.max(150*n,-120),120)),s=l<i/3?"left":l>2*i/3?"right":"center";en(s),et.style.translate="";let d=et.getBoundingClientRect().left;et.style.translate=`${a-d}px 0`,et.offsetWidth,et.classList.remove("dragging"),et.style.translate="";try{er?.localStorage.setItem(w,s)}catch{}};et.addEventListener("pointerup",ei),et.addEventListener("pointercancel",ei),et.addEventListener("click",e=>{ea&&(ea=!1,e.preventDefault(),e.stopPropagation())},!0);let el=!1,es=!1,ed=!1,ec=null,ep=!1,eg=null,eu=!1,eh=!1,em=null,eb=null,ef=null,ev=0,ey=e=>({text:e instanceof Error?e.message:String(e),error:!0}),ex=e=>{let r=e.features.includes("prompt"),n=e.saving||e.publishing,a=e.prompting||n;et.hidden=!r&&!l,d.hidden=el||!r,c.hidden=r||!l,ee.hidden=!el||!r;let i=l&&e.features.includes("create"),p=l&&null===t.entryId,x=p&&i&&null!==t.product,w=p&&i&&!x;i||(ed=!1),w&&(ed=!0),(ed||p||!l)&&(ep=!1);let E=el&&r&&ep;E&&!eg?eE():!E&&eg&&eC();let C=x&&!ed;s.textContent=C?o.addProductPage:w?o.newPage:o.open,M.hidden=w,y.hidden=ed||C,$.hidden=!ed,U.hidden=!C,U.disabled=a,I.hidden=ed||ep||!i,I.disabled=a,es&&(eh=!1),j.hidden=!ed||eh||es,O.disabled=a,u.hidden=ep||eh||es||C,h.hidden=!ep||eh||es,h.classList.toggle("loading",eu),q.hidden=eh,_.hidden=!eh,u.placeholder=ed?o.newPagePlaceholder:o.placeholder,f.textContent=e.selectedUid?o.scopeBlock:o.scopeEntry,v.hidden=!e.selectedUid,m.hidden=!!e.selectedUid,b.hidden=!e.selectedUid,N.hidden=!l||ed||p||!e.features.includes("form"),L.setAttribute("aria-pressed",String(!ep)),A.setAttribute("aria-pressed",String(ep)),N.querySelectorAll("button").forEach(e=>{e.disabled=a}),k.hidden=ed||!e.canUndo,k.disabled=a,F.hidden=ep||es||C,B.hidden=ep||es||C;let P=es?o.expand:o.minimize;D.title=P,D.setAttribute("aria-label",P),D.setAttribute("aria-expanded",String(!es)),T.hidden=es,z.hidden=!es,F.disabled=a||""===u.value.trim()||ed&&""===O.value.trim(),u.disabled=a,K.hidden=!e.features.includes("save")||p,K.disabled=a||!e.unsaved,K.textContent=e.saving?o.saving:o.save,G.hidden=!e.features.includes("publish")||p,G.disabled=a,G.textContent=e.publishing?o.publishing:o.publish,Z.hidden=!l,Q.hidden=!l,J.hidden=!e.unsaved,W.hidden=!l,W.setAttribute("aria-expanded",String(eh)),V.textContent=em?.find(({entryId:e})=>e===t.entryId)?.name??o.pages;let S=ep&&eu&&!eh,R=e.prompting||S,H=e.prompting?ed?o.creating:C?o.addingProductPage:o.working:S?o.formLoading:ec?.text??(C?o.productPageHint:!l||ed||eh||e.selectedUid?"":o.selectHint);g.textContent=H,g.hidden=!H||es,g.className=`status${R?" working":""}${!a&&!S&&ec?.error?" error":""}`},ew=()=>ex(t.getState()),ek=()=>{u.style.height="auto",u.style.height=`${u.scrollHeight}px`},eE=()=>{eu=!0,h.classList.add("loading");let e=t.openForm(h,{title:o.formTitle,onReady:()=>{eg===e&&(eu=!1,ec=null,ew())},onError:t=>{eg===e&&(eu=!1,ec={text:t,error:!0},ew())}});eg=e},eC=()=>{eg?.close(),eg=null,eu=!1},eP=e=>{ep!==e&&(ep=e,ec=null,ew(),ep||u.focus())},eS=async()=>{if(ep)return;let e=u.value.trim();if(e&&!t.getState().prompting){ec=null;try{if(ed){let r=O.value.trim();if(!r)return O.focus();await t.createPage(r,e),em=null,eb=null,ec={text:o.created,error:!1}}else{let{summary:r}=await t.prompt(e);ec={text:r,error:!1}}u.value="",ek()}catch(e){ec=ey(e)}ew(),u.focus()}},eL=()=>(eb??(eb=t.pages().then(e=>{em=e,ef=null,eN(),ew()},e=>{eb=null,ef=ey(e).text,eN()})),eb),eA=()=>{let e=H.value.trim().toLowerCase();return(em??[]).filter(t=>!e||t.name.toLowerCase().includes(e)||t.url.toLowerCase().includes(e)||`/${t.path}`.toLowerCase().includes(e))},eN=()=>{let r=eA();ev=Math.max(0,Math.min(ev,r.length-1)),Y.textContent="",r.forEach((r,n)=>{let a=r.entryId===t.entryId,i=C(e,"li",{className:`option${n===ev?" active":""}`,id:`obelism-page-${n}`},C(e,"span",{className:"option-text"},C(e,"span",{textContent:r.name}),C(e,"span",{className:"option-path",textContent:r.url})));if(i.setAttribute("role","option"),i.setAttribute("aria-selected",String(n===ev)),"published"!==r.status&&i.appendChild(C(e,"span",{className:"badge",textContent:"draft"===r.status?o.pageDraft:o.pageChanged})),a){i.setAttribute("aria-current","page");let t=P(e,"check");t.removeAttribute("aria-hidden"),t.setAttribute("role","img"),t.setAttribute("aria-label",o.pageCurrent),i.appendChild(t)}i.addEventListener("click",()=>eU(r)),Y.appendChild(i)});let n=Y.children[ev];n?(H.setAttribute("aria-activedescendant",n.id),n.scrollIntoView?.({block:"nearest"})):H.removeAttribute("aria-activedescendant"),X.textContent=(ef??(em?"":o.pagesLoading))||(0===r.length?o.pagesEmpty:""),X.hidden=!X.textContent,X.className=`empty${ef?" error":""}`},eI=e=>{ec=null,(eh=e)&&(H.value="",ev=Math.max(0,(em??[]).findIndex(({entryId:e})=>e===t.entryId)),eL(),eN()),ew(),(eh?H:W).focus()},eU=e=>{if(e.entryId===t.entryId)return eI(!1);t.openPage(e)},eM=e=>{(el=e)||(eh=!1,es=!1),ew(),l&&t.setSelecting(el&&!ed),el&&l&&eL()},e$=e=>{ed=e,ec=null,t.setSelecting(el&&!ed),ed&&t.select(null),ew(),(ed?O:u).focus()},eO=async e=>{ec=null;try{await t[e](),ec={text:"save"===e?o.saved:o.published,error:!1}}catch(e){ec=ey(e)}ew()};d.addEventListener("click",()=>{eM(!0),ep||(ed?O:u).focus()}),R.addEventListener("click",()=>eM(!1)),D.addEventListener("click",()=>{es=!es,ew(),es||(ep?D:u).focus()}),ee.addEventListener("click",e=>{if(!es)return;let t=e.target.closest("button");t&&t!==D&&t!==R&&(es=!1,ew())},!0),K.addEventListener("click",()=>void eO("save")),G.addEventListener("click",()=>void eO("publish")),Z.addEventListener("click",()=>t.signOut()),p.addEventListener("click",()=>t.signOut()),v.addEventListener("click",()=>t.select(null)),I.addEventListener("click",()=>e$(!0)),U.addEventListener("click",async()=>{ec=null;try{await t.createProductPage(),ec={text:o.addedProductPage,error:!1}}catch(e){ec=ey(e)}ew()}),M.addEventListener("click",()=>e$(!1)),L.addEventListener("click",()=>eP(!1)),A.addEventListener("click",()=>eP(!0)),W.addEventListener("click",()=>eI(!eh)),O.addEventListener("input",ew),O.addEventListener("keydown",e=>{"Enter"!==e.key||e.isComposing?"Escape"===e.key&&eM(!1):(e.preventDefault(),u.focus())}),H.addEventListener("input",()=>{ev=0,eN()}),H.addEventListener("keydown",e=>{let t=Y.children.length;if("ArrowDown"===e.key||"ArrowUp"===e.key){if(e.preventDefault(),0===t)return;ev=(ev+("ArrowDown"===e.key?1:-1)+t)%t,eN()}else if("Enter"!==e.key||e.isComposing)"Escape"===e.key&&(e.preventDefault(),eI(!1));else{e.preventDefault();let t=eA()[ev];t&&eU(t)}}),k.addEventListener("click",()=>{ec=null,t.undo()}),ee.addEventListener("submit",e=>{e.preventDefault(),eS()}),u.addEventListener("input",()=>{ek(),ew()}),u.addEventListener("keydown",e=>{"Enter"!==e.key||e.shiftKey||e.isComposing?"Escape"===e.key&&eM(!1):(e.preventDefault(),eS())});let ej=t.on("change",ex);return ew(),e.body.appendChild(a),()=>{ej(),eC(),a.remove()}},L="https://content.obelism.studio",A=(e,t)=>JSON.stringify(e)===JSON.stringify(t),N=Symbol.for("@obelism/content/bridge"),I=y({isEditing:!1,entryId:null,on:()=>{}},new URLSearchParams),U=({url:e,prompt:c=!0,pagePath:h,productPath:m}={})=>{let x;if("u"<typeof window)return I;let w=window;if(w[N])return w[N];if(w.ObelismBridge)x=y(w.ObelismBridge,new URLSearchParams(w.location.search));else{let y=(x=((e,r)=>{let n=new URLSearchParams(e.location.search),c=e.parent!==e&&n.has("cms_preview"),h=u(),m=[],y={...g,selecting:!0},x=e=>{y={...y,...e},h.emit("change",y)},w={isEditing:c,mode:c?"editor":null,entryId:n.get("cms_entry"),environment:n.get(o),product:null,on:h.on,getState:()=>y,...b,destroy:()=>{m.splice(0).forEach(e=>e())}};if(!c)return w;let k=e.document,E=(t,n={})=>{e.parent.postMessage({source:d,type:t,...n},r)},C=k.createElement("style");C.textContent=p(),k.head.appendChild(C),m.push(()=>C.remove());let P=(e,t)=>{if(k.querySelectorAll("[data-cms-selected]").forEach(e=>{e.removeAttribute("data-cms-selected")}),y.selectedUid!==(e??null)&&x({selectedUid:e??null}),!e)return;let r=k.querySelector(v(e));r&&(r.setAttribute("data-cms-selected",""),t&&r.scrollIntoView({behavior:"smooth",block:"center"}))},S=e=>{let r=e.target,n=r?.closest?.(`[${t}]`);if(!n)return;e.preventDefault(),e.stopPropagation();let o=n.getAttribute(t);P(o,!1),E("select",{uid:o})};k.addEventListener("click",S,!0),m.push(()=>k.removeEventListener("click",S,!0));let L=()=>E("ready",{url:e.location.href}),A=new Map,N=0,I=e=>{let t=A.get(e);return t?(clearTimeout(t.timer),A.delete(e),0===A.size&&x({prompting:!1}),t):null};w.prompt=(e,t={})=>{let r=e.trim();if(!r)return Promise.reject(Error("Say what to change"));if(!y.features.includes("prompt"))return Promise.reject(Error("The editor does not offer prompts here"));let n=`prompt_${++N}`,o=void 0===t.uid?y.selectedUid:t.uid;return new Promise((e,t)=>{let a=setTimeout(()=>{I(n)?.reject(Error("The editor did not answer in time"))},12e4);A.set(n,{resolve:e,reject:t,timer:a}),x({prompting:!0}),E("prompt",{id:n,prompt:r,uid:o})})},w.undo=()=>E("undo"),w.select=e=>{P(e,!1),E("select",{uid:e})};let U=null;m.push(()=>U?.destroy()),m.push(()=>{for(let e of A.keys())I(e)?.reject(Error("The bridge was destroyed"))});let M=t=>{if(t.origin!==r||t.source!==e.parent)return;let n=t.data;if(n&&"obelism-content-editor"===n.source){if("connect"===n.type)L();else if("update"===n.type&&n.entry)h.emit("update",{entry:n.entry,selectedUid:n.selectedUid??null}),e.requestAnimationFrame(()=>P(n.selectedUid,!1)),U?.refresh();else if("select"===n.type)P(n.uid,!0);else if("saved"===n.type||"published"===n.type)h.emit(n.type,{}),0===h.listeners.update.size&&e.location.reload();else if("features"===n.type&&Array.isArray(n.features))x({features:n.features.filter(e=>"string"==typeof e)});else if("stats"===n.type)x({stats:(e=>{if(!e||"object"!=typeof e||Array.isArray(e))return{};let t={};for(let[r,n]of Object.entries(e)){let{clicks:e,clickers:o,viewers:a,rate:i}=n??{};f(e)&&f(o)&&f(a)&&f(i)&&(t[r]={clicks:e,clickers:o,viewers:a,rate:i})}return t})(n.stats),statsVisible:!1!==n.visible}),(U||Object.keys(y.stats).length)&&(U??(U=((e,{selector:t,onSelect:r,labels:n})=>{let o=e.document,d={...a,...n},c=o.createElement("div");c.setAttribute("data-obelism-stats","");let p=c.attachShadow({mode:"open"}),g=o.createElement("style");g.textContent=l;let u=o.createElement("div");u.className="layer",p.append(g,u),o.body.appendChild(c);let h={},m=!1,b=null,f=()=>{if(b=null,u.replaceChildren(),u.hidden=!m,!m)return;let n=e.innerHeight;for(let[a,l]of Object.entries(h)){let c=o.querySelector(t(a));if(!c)continue;let p=c.getBoundingClientRect();if(!p.width&&!p.height||p.bottom<0||p.top>n)continue;let g=o.createElement("button");g.type="button",g.className="badge",g.dataset.uid=a,g.textContent=i(d.clicked,{rate:Math.round(100*l.rate)}),g.title=i(d.title,{clickers:l.clickers,viewers:l.viewers,clicks:l.clicks});let{place:h,top:m,left:b}=s(p,e.innerWidth);g.dataset.place=h,g.style.top=`${m}px`,g.style.left=`${b}px`,g.addEventListener("click",()=>r(a)),u.appendChild(g)}},v=()=>{null===b&&m&&(b=e.requestAnimationFrame(f))};e.addEventListener("scroll",v,{capture:!0,passive:!0}),e.addEventListener("resize",v);let y=e.MutationObserver,x="function"==typeof y?new y(v):null;return x?.observe(o.body,{childList:!0,subtree:!0}),{update(t,r){h=t,m=r,null!==b&&(e.cancelAnimationFrame?.(b),b=null),f()},refresh:v,destroy(){null!==b&&e.cancelAnimationFrame?.(b),e.removeEventListener("scroll",v,{capture:!0}),e.removeEventListener("resize",v),x?.disconnect(),c.remove()}}})(e,{selector:v,onSelect:e=>w.select(e)})),U.update(y.stats,y.statsVisible));else if("promptState"===n.type)x({canUndo:!0===n.canUndo});else if("promptResult"===n.type&&"string"==typeof n.id){let e=I(n.id);if(!e)return;!0===n.ok?e.resolve({summary:"string"==typeof n.summary?n.summary:""}):e.reject(Error("string"==typeof n.error?n.error:"The prompt failed"))}}};return e.addEventListener("message",M),m.push(()=>e.removeEventListener("message",M)),"loading"===k.readyState?(k.addEventListener("DOMContentLoaded",L,{once:!0}),m.push(()=>k.removeEventListener("DOMContentLoaded",L))):L(),w})(w,new URL(e||L).origin)).isEditing||w.parent!==w?null:(e=>{for(let t of e.cookie.split(";")){let[e,...r]=t.trim().split("=");if("obelism_content_editing"===e)try{let e=decodeURIComponent(r.join("="));return e.startsWith("/")&&!e.startsWith("//")?e:null}catch{break}}return null})(w.document);if(y&&(x=((e,o,{pagePath:a=e=>`/${e}`,productPath:i}={})=>{let l=e.document,s=u(),c=[],h=new Map,m=[],b=new Set,f=null,y=null,x=-1/0,w=new Map,k=g,E=e=>{k={...k,...e},s.emit("change",k)},C=()=>E({unsaved:[...h.values()].some(({content:e,saved:t})=>!A(e,t)),canUndo:m.length>0}),P=async(t,r)=>{let n=await e.fetch(`${o}/api/${t}`,void 0===r?{credentials:"same-origin"}:{method:"POST",credentials:"same-origin",headers:{"Content-Type":"application/json","x-obelism-content":"1"},body:JSON.stringify(r)}),a=await n.json().catch(()=>({}));if(401===n.status)throw E({features:[]}),Error("You were signed out. Sign in again to edit.");if(!n.ok)throw Error("string"==typeof a.error?a.error:`Obelism Content answered ${n.status}`);return a},S=()=>l.querySelector(`[${r}]`)?.getAttribute(r)??null,L=()=>{let e=l.querySelector(`[${n}]`),t=e?.getAttribute(n),r=e?.getAttribute("data-cms-product-handle");return t&&r?{id:t,handle:r}:null},N=e=>{let t=e?l.querySelector(v(e)):null;return t?.closest(`[${r}]`)?.getAttribute(r)??S()},I=()=>{if(!f)return;let e=f.space.locales.map(({code:e})=>e),t=l.documentElement.lang;if(e.includes(t))return t;let r=t.split("-")[0]??"";return e.includes(r)?r:f.space.defaultLocale},U=new Map,M=async e=>{let t=h.get(e);if(t)return t;let r=U.get(e);return r||(r=P(`entries/${encodeURIComponent(e)}`).then(t=>{let r=h.get(e)??{content:t.content,saved:t.content,revision:t.draftRevision};return h.set(e,r),r}).finally(()=>U.delete(e)),U.set(e,r)),r},$=e=>{let t=void 0===e?k.selectedUid:e,r=N(t);if(!r)throw Error("Nothing on this page is marked as an entry: add editable(entry)");return{uid:t,entryId:r}},O=e=>{l.querySelectorAll("[data-cms-selected]").forEach(e=>{e.removeAttribute("data-cms-selected")}),k.selectedUid!==e&&E({selectedUid:e}),e&&l.querySelector(v(e))?.setAttribute("data-cms-selected","")},j=async t=>{if(0===s.listeners.update.size)return;let r=h.get(t)?.content,{entry:n}=await P(`entries/${encodeURIComponent(t)}/preview`,{content:r,locale:I()});s.emit("update",{entry:n,selectedUid:k.selectedUid}),e.requestAnimationFrame(()=>O(k.selectedUid))},R=e=>console.error("[@obelism/content bridge]",e),T=t=>{s.emit(t,{}),0===s.listeners.update.size&&e.location.reload()},z=async()=>{for(let[e,t]of h){if(A(t.content,t.saved))continue;let{draftRevision:r}=await P(`entries/${encodeURIComponent(e)}/save`,{content:t.content,baseRevision:t.revision});t.saved=t.content,t.revision=r,b.add(e)}m.length=0,x=-1/0,C()},D={isEditing:!0,mode:"site",get entryId(){return S()},get product(){return L()},environment:null,on:s.on,getState:()=>k,async prompt(e,t={}){let r=e.trim();if(!r)throw Error("Say what to change");if(!k.features.includes("prompt"))throw Error("You may not edit content here");let{uid:n,entryId:o}=$(t.uid);E({prompting:!0});try{let e=await M(o),t=await P(`entries/${encodeURIComponent(o)}/prompt`,{prompt:r,content:e.content,locale:I(),uid:n});return m.push({entryId:o,content:e.content}),x=-1/0,e.content=t.content,C(),await j(o),{summary:t.summary}}finally{E({prompting:!1})}},async createPage(t,r){let n=r.trim();if(!n)throw Error("Say what the page is for");if(!t.trim())throw Error("Say where the page goes, like /pricing");if(!k.features.includes("create"))throw Error("You may not add pages here");if(k.unsaved)throw Error("Save or undo your changes before adding a page");E({prompting:!0});try{let r=await P("entries",{path:t,prompt:n,locale:I(),from:S()}),o=a(r.path,I()??"");return e.location.assign(o),{summary:r.summary,entryId:r.entryId,path:r.path,url:o}}finally{E({prompting:!1})}},async createProductPage(t=L()??void 0){if(!t)throw Error("Nothing on this page is marked as a product: add editableProduct(product)");if(!k.features.includes("create"))throw Error("You may not add pages here");if(k.unsaved)throw Error("Save or undo your changes before adding a page");E({prompting:!0});try{let r=await P("product-pages",{product:{id:t.id,handle:t.handle}});return e.location.reload(),r}finally{E({prompting:!1})}},async view(e={}){let{uid:t,entryId:r}=$(e.uid),n=await M(r),{view:o}=await P(`entries/${encodeURIComponent(r)}/view`,{content:n.content,locale:I(),uid:t});return o},async applyJson(e,t={}){if(!k.features.includes("prompt"))throw Error("You may not edit content here");if(!e||"object"!=typeof e||Array.isArray(e))throw Error("Send the fields to change as an object");let{uid:r,entryId:n}=$(t.uid);E({prompting:!0});try{let t=await M(n),o=await P(`entries/${encodeURIComponent(n)}/apply`,{changes:e,content:t.content,locale:I(),uid:r});return A(o.content,t.content)||(m.push({entryId:n,content:t.content}),x=-1/0,t.content=o.content,C(),await j(n)),{changed:o.changed??[],...o.view&&{view:o.view}}}finally{E({prompting:!1})}},openForm(t,r={}){let{title:n="Content form",onReady:o,onError:a}=r;y?.();let i=!1,l=null,c=null,p=()=>{},g=e=>{i||a?.(e instanceof Error?e.message:String(e))},u=()=>{i||(i=!0,p(),l?.destroy(),y===u&&(y=null))};y=u;let b=()=>{if(i||!l)return;let e=N(k.selectedUid);if(!e)return;let t=h.get(e);if(!t)return void M(e).then(b,g);let r={entryId:e,content:t.content,locale:I(),selectedUid:k.selectedUid};c&&c.entryId===r.entryId&&c.content===r.content&&c.locale===r.locale&&c.selectedUid===r.selectedUid||(c=r,l.show(r))},f=(e,t)=>{let r=t??c?.entryId,n=void 0===r?void 0:h.get(r);if(i||void 0===r||!n||A(e,n.content))return;let o=Date.now();o-x>=1e3&&m.push({entryId:r,content:n.content}),x=o,n.content=e,c?.entryId===r&&(c={...c,content:e}),C(),clearTimeout(w.get(r)),w.set(r,setTimeout(()=>{w.delete(r),j(r).catch(R)},300))};return(async()=>{if(!k.features.includes("form"))throw Error("You may not edit content here");await M($(void 0).entryId);let{url:r}=await P("form",{});i||(l=((e,t,r,n,o)=>{let a=null;try{a=new URL(r)}catch{}if(!a||!/^https?:$/.test(a.protocol))throw Error("Obelism Content sent no form to open");let i=a.origin,l=t.ownerDocument.createElement("iframe");l.title=n,l.src=r;let s=!1,c=!1,p=null,g=()=>{s&&p&&l.contentWindow?.postMessage({source:d,type:"content",...p},i)},u=setTimeout(()=>{c||o.onError("The form did not open")},3e4),h=()=>{c=!0,clearTimeout(u),o.onReady()},m=e=>{if(e.origin!==i||!l.contentWindow||e.source!==l.contentWindow)return;let t=e.data;if(t&&"obelism-content-form"===t.source)if("ready"===t.type)s=!0,g(),!0!==t.loading&&h();else if("loaded"===t.type)s&&h();else{let e;if("change"!==t.type||!(e=t.content)||"object"!=typeof e||Array.isArray(e))if("height"===t.type){let e=t.height;if("number"==typeof e&&Number.isFinite(e)){let t=Math.round(Math.min(Math.max(e,80),4e3));l.style.height=`min(${t}px, 60vh)`}}else"error"===t.type&&o.onError("string"==typeof t.message&&t.message?t.message:"The form failed");else o.onChange(t.content,"string"==typeof t.entryId?t.entryId:void 0)}};return e.addEventListener("message",m),t.appendChild(l),{show(e){p=e,g()},destroy(){clearTimeout(u),e.removeEventListener("message",m),l.remove()}}})(e,t,"string"==typeof r?r:"",n,{onReady:()=>o?.(),onChange:f,onError:e=>a?.(e)}),p=s.on("change",b),b())})().catch(g),{close:u}},async pages(){let{pages:e}=await P("pages"),t=[I(),f?.space.defaultLocale];return e.flatMap(e=>{let r,n=t.find(t=>void 0!==t&&void 0!==e.paths[t])??Object.keys(e.paths)[0],o=void 0===n?void 0:e.paths[n];return void 0===n||void 0===o?[]:[{entryId:e.entryId,name:e.name,contentType:e.contentType,status:e.status,path:o,url:e.product?(r=e.product.handle,i?i(r,n):(f?.productPath??"/products/{handle}").replaceAll("{handle}",encodeURIComponent(r))):a(o,n),product:e.product??null}]})},openPage(t){(!k.unsaved||e.confirm("Leave this page and lose the changes you have not saved?"))&&(h.clear(),m.length=0,C(),e.location.assign(t.url))},undo(){let e=m.pop(),t=e&&h.get(e.entryId);e&&t&&(x=-1/0,t.content=e.content,C(),j(e.entryId).catch(R))},async save(){if(!k.features.includes("save"))throw Error("You may not edit content here");E({saving:!0});try{await z()}finally{E({saving:!1})}T("saved")},async publish(){if(!k.features.includes("publish"))throw Error("You may not publish here");E({publishing:!0});try{await z();let e=S(),t=b.size>0?[...b]:e?[e]:[];if(0===t.length)throw Error("Nothing on this page is marked as an entry: add editable(entry)");for(let e of t)await P(`entries/${encodeURIComponent(e)}/publish`,{}),b.delete(e)}finally{E({publishing:!1})}T("published")},signOut(){if(k.unsaved&&!e.confirm("Sign out and lose the changes you have not saved?"))return;h.clear(),C();let t=e.location.pathname+e.location.search;e.location.href=`${o}/logout?return_to=${encodeURIComponent(t)}`},select(e){O(e)},setSelecting(e){e?l.documentElement.setAttribute("data-cms-selecting",""):l.documentElement.removeAttribute("data-cms-selecting"),E({selecting:e})},destroy(){y?.(),w.forEach(e=>clearTimeout(e)),w.clear(),c.splice(0).forEach(e=>e())}},F=l.createElement("style");F.textContent=p("html[data-cms-selecting] "),l.head.appendChild(F),c.push(()=>F.remove()),c.push(()=>l.documentElement.removeAttribute("data-cms-selecting"));let B=e=>{if(!k.selecting)return;let r=e.target,n=r?.closest?.(`[${t}]`);n&&(e.preventDefault(),e.stopPropagation(),O(n.getAttribute(t)))};l.addEventListener("click",B,!0),c.push(()=>l.removeEventListener("click",B,!0));let q=e=>{k.unsaved&&(e.preventDefault(),e.returnValue="")};return e.addEventListener("beforeunload",q),c.push(()=>e.removeEventListener("beforeunload",q)),P("session").then(e=>{f=e,E({features:e.features})}).catch(e=>console.error("[@obelism/content bridge]",e)),D})(w,y,{pagePath:h,productPath:m})),x.isEditing&&c){let e=S(w.document,x,!0===c?{}:c),t=x.destroy;x.destroy=()=>{e(),t()}}}return w[N]=x,x};(e=window).ObelismBridge=U((e=>{let t=e?.dataset.url,r=t||L;if(!t&&e?.src){let t=new URL(e.src);"/bridge.js"===t.pathname&&(r=t.origin)}return{url:r,prompt:e?.dataset.prompt!=="false"}})(document.currentScript)),e.ObelismContent={getContentBridge:U,mountPromptBox:S}}();
|
|
260
|
+
`,C=(e,t,r={},...n)=>{let o=e.createElement(t);for(let t of(Object.assign(o,r),n))o.appendChild("string"==typeof t?e.createTextNode(t):t);return o},P=(e,t)=>{let r=C(e,"span",{className:"icon"});return r.setAttribute("aria-hidden","true"),r.innerHTML=`<svg viewBox="0 0 24 24">${k[t]}</svg>`,r},L=(e,t,r={})=>{let n,o={...x,...r.labels},a=C(e,"div");a.setAttribute("data-obelism-content-prompt","");let i=a.attachShadow({mode:"open"}),s="site"===t.mode,l=C(e,"span",{textContent:o.open}),d=C(e,"button",{className:"pill",type:"button"},l,((n=P(e,"mark")).classList.add("mark"),n)),c=C(e,"span",{className:"pill compact"},`${o.viewingDrafts} \xb7 `),p=C(e,"button",{className:"link",type:"button",textContent:o.signOut});c.appendChild(p);let g=C(e,"p",{className:"status"});g.setAttribute("role","status");let u=C(e,"textarea",{placeholder:o.placeholder,rows:1});u.setAttribute("aria-label",o.open);let h=C(e,"div",{className:"form-loader",textContent:o.formLoading});h.setAttribute("role","status");let m=C(e,"div",{className:"form"},h),b=P(e,"page"),f=P(e,"block"),v=C(e,"span"),y=C(e,"button",{type:"button",title:o.clearBlock});y.setAttribute("aria-label",o.clearBlock),y.appendChild(P(e,"close"));let k=C(e,"span",{className:"chip scope"},b,f,v,y),L=C(e,"button",{className:"action chip",type:"button"},P(e,"undo"),o.undo),S=t=>{let r=C(e,"button",{type:"button",textContent:t});return r.setAttribute("aria-pressed","false"),r},A=S(o.modePrompt),N=S(o.form),I=C(e,"span",{className:"modes"},A,N);I.setAttribute("role","group"),I.setAttribute("aria-label",o.modes);let U=C(e,"button",{className:"action chip",type:"button"},P(e,"newPage"),o.newPage),M=C(e,"button",{className:"action chip product",type:"button"},P(e,"newPage"),o.addProductPage),$=C(e,"button",{type:"button",title:o.newPageCancel});$.setAttribute("aria-label",o.newPageCancel),$.appendChild(P(e,"close"));let O=C(e,"span",{className:"chip scope"},P(e,"newPage"),C(e,"span",{textContent:o.newPage}),$),j=C(e,"input",{type:"text",placeholder:o.pathPlaceholder,autocomplete:"off",spellcheck:!1}),R=C(e,"label",{className:"path"},C(e,"span",{textContent:o.path}),j),T=C(e,"button",{className:"close icon-button",type:"button",title:o.close},P(e,"close"));T.setAttribute("aria-label",o.close);let z=P(e,"minimize"),D=P(e,"expand"),F=C(e,"button",{className:"icon-button",type:"button"},z,D),B=C(e,"button",{className:"action primary icon-button",type:"submit"},C(e,"span",{className:"visually-hidden",textContent:o.send}),P(e,"send"));B.title=o.send;let q=C(e,"span",{className:"divider"}),V=C(e,"div",{className:"toolbar"},k,O,I,L,M,U,C(e,"span",{className:"spacer"}),F,T,q,B),W=C(e,"span",{textContent:o.pages}),H=C(e,"button",{className:"chip page-chip",type:"button",title:o.pages},P(e,"page"),W,P(e,"chevrons"));H.setAttribute("aria-haspopup","listbox"),H.setAttribute("aria-expanded","false"),H.setAttribute("aria-controls","obelism-pages");let Y=C(e,"input",{type:"text",placeholder:o.pagesSearch,autocomplete:"off",spellcheck:!1});Y.setAttribute("role","combobox"),Y.setAttribute("aria-label",o.pagesSearch),Y.setAttribute("aria-autocomplete","list"),Y.setAttribute("aria-expanded","true"),Y.setAttribute("aria-controls","obelism-pages");let X=C(e,"ul",{className:"options",id:"obelism-pages"});X.setAttribute("role","listbox"),X.setAttribute("aria-label",o.pages);let _=C(e,"p",{className:"empty"}),J=C(e,"div",{className:"pages"},C(e,"label",{className:"search"},P(e,"search"),Y),X,_),Z=C(e,"span",{className:"unsaved"});Z.appendChild(C(e,"span",{className:"dot"})),Z.appendChild(e.createTextNode(o.unsaved));let K=C(e,"button",{className:"link",type:"button",textContent:o.signOut}),G=C(e,"button",{className:"action chip",type:"button",textContent:o.save}),Q=C(e,"button",{className:"action chip",type:"button",textContent:o.publish}),ee=C(e,"div",{className:"footer"},H,Z,C(e,"span",{className:"spacer"}),K,G,Q),et=C(e,"form",{className:"panel"},g,R,u,m,V,J,ee),er=C(e,"div",{className:"root"},C(e,"div",{className:"bar"},d,c),et);i.append(C(e,"style",{textContent:E}),er);let en=e.defaultView,eo=e=>{"center"===e?delete er.dataset.side:er.dataset.side=e};eo((()=>{try{let e=en?.localStorage.getItem(w);return"left"===e||"right"===e?e:"center"}catch{return"center"}})());let ea=null,ei=!1;er.addEventListener("pointerdown",e=>{if(ei=!1,0!==e.button||!e.isPrimary)return;let t=e.target.closest("button, input, textarea, iframe, a, label, .pages, .form");if(t&&t!==d)return;let{left:r,right:n}=er.getBoundingClientRect();ea={id:e.pointerId,startX:e.clientX,x:e.clientX,velocity:0,time:e.timeStamp,moved:!1,min:Math.min(0,16-r),max:Math.max(0,(en?.innerWidth??0)-16-n)}}),er.addEventListener("pointermove",e=>{if(!ea||e.pointerId!==ea.id)return;let t=e.clientX-ea.startX;if(!ea.moved){if(6>Math.abs(t))return;ea.moved=!0,er.classList.add("dragging");try{er.setPointerCapture(e.pointerId)}catch{}}let r=e.timeStamp-ea.time;r>0&&(ea.velocity=(e.clientX-ea.x)/r),ea.x=e.clientX,ea.time=e.timeStamp;let n=Math.min(Math.max(t,ea.min),ea.max);er.style.translate=`${n+(t-n)/3}px 0`});let es=e=>{if(!ea||e.pointerId!==ea.id)return;let{moved:t,x:r,velocity:n,time:o}=ea;if(ea=null,!t)return;ei=!0;let a=er.getBoundingClientRect().left,i=en?.innerWidth??0,s=r+(e.timeStamp-o>80?0:Math.min(Math.max(150*n,-120),120)),l=s<i/3?"left":s>2*i/3?"right":"center";eo(l),er.style.translate="";let d=er.getBoundingClientRect().left;er.style.translate=`${a-d}px 0`,er.offsetWidth,er.classList.remove("dragging"),er.style.translate="";try{en?.localStorage.setItem(w,l)}catch{}};er.addEventListener("pointerup",es),er.addEventListener("pointercancel",es),er.addEventListener("click",e=>{ei&&(ei=!1,e.preventDefault(),e.stopPropagation())},!0);let el=!1,ed=!1,ec=!1,ep=null,eg=!1,eu=null,eh=!1,em=!1,eb=null,ef=null,ev=null,ey=0,ex=e=>({text:e instanceof Error?e.message:String(e),error:!0}),ew=e=>{let r=e.features.includes("prompt"),n=e.saving||e.publishing,a=e.prompting||n;er.hidden=!r&&!s,d.hidden=el||!r,c.hidden=r||!s,et.hidden=!el||!r;let i=s&&e.features.includes("create"),p=s&&null===t.entryId,x=p&&i&&null!==t.product,w=p&&i&&!x;i||(ec=!1),w&&(ec=!0),(ec||p||!s)&&(eg=!1);let E=el&&r&⪚E&&!eu?eC():!E&&eu&&eP();let C=x&&!ec;l.textContent=C?o.addProductPage:w?o.newPage:o.open,$.hidden=w,k.hidden=ec||C,O.hidden=!ec,M.hidden=!C,M.disabled=a,U.hidden=ec||eg||!i,U.disabled=a,ed&&(em=!1),R.hidden=!ec||em||ed,j.disabled=a,u.hidden=eg||em||ed||C,m.hidden=!eg||em||ed,m.classList.toggle("loading",eh),h.hidden=!eh,V.hidden=em,J.hidden=!em,u.placeholder=ec?o.newPagePlaceholder:o.placeholder,v.textContent=e.selectedUid?o.scopeBlock:o.scopeEntry,y.hidden=!e.selectedUid,b.hidden=!!e.selectedUid,f.hidden=!e.selectedUid,I.hidden=!s||ec||p||!e.features.includes("form"),A.setAttribute("aria-pressed",String(!eg)),N.setAttribute("aria-pressed",String(eg)),I.querySelectorAll("button").forEach(e=>{e.disabled=a}),L.hidden=ec||!e.canUndo,L.disabled=a,B.hidden=eg||ed||C,q.hidden=eg||ed||C;let P=ed?o.expand:o.minimize;F.title=P,F.setAttribute("aria-label",P),F.setAttribute("aria-expanded",String(!ed)),z.hidden=ed,D.hidden=!ed,B.disabled=a||""===u.value.trim()||ec&&""===j.value.trim(),u.disabled=a,G.hidden=!e.features.includes("save")||p,G.disabled=a||!e.unsaved,G.textContent=e.saving?o.saving:o.save,Q.hidden=!e.features.includes("publish")||p,Q.disabled=a,Q.textContent=e.publishing?o.publishing:o.publish,K.hidden=!s,ee.hidden=!s,Z.hidden=!e.unsaved,H.hidden=!s,H.setAttribute("aria-expanded",String(em)),W.textContent=eb?.find(({entryId:e})=>e===t.entryId)?.name??o.pages;let S=eg&&eh&&!em,T=e.prompting,Y=e.prompting?ec?o.creating:C?o.addingProductPage:o.working:S?"":ep?.text??(C?o.productPageHint:!s||ec||em||e.selectedUid?"":o.selectHint);g.textContent=Y,g.hidden=!Y||ed,g.className=`status${T?" working":""}${!a&&!S&&ep?.error?" error":""}`},ek=()=>ew(t.getState()),eE=()=>{u.style.height="auto",u.style.height=`${u.scrollHeight}px`},eC=()=>{eh=!0,m.classList.add("loading");let e=t.openForm(m,{title:o.formTitle,onReady:()=>{eu===e&&(eh=!1,ep=null,ek())},onError:t=>{eu===e&&(eh=!1,ep={text:t,error:!0},ek())}});eu=e},eP=()=>{eu?.close(),eu=null,eh=!1},eL=e=>{eg!==e&&(eg=e,ep=null,ek(),eg||u.focus())},eS=async()=>{if(eg)return;let e=u.value.trim();if(e&&!t.getState().prompting){ep=null;try{if(ec){let r=j.value.trim();if(!r)return j.focus();await t.createPage(r,e),eb=null,ef=null,ep={text:o.created,error:!1}}else{let{summary:r}=await t.prompt(e);ep={text:r,error:!1}}u.value="",eE()}catch(e){ep=ex(e)}ek(),u.focus()}},eA=()=>(ef??(ef=t.pages().then(e=>{eb=e,ev=null,eI(),ek()},e=>{ef=null,ev=ex(e).text,eI()})),ef),eN=()=>{let e=Y.value.trim().toLowerCase();return(eb??[]).filter(t=>!e||t.name.toLowerCase().includes(e)||t.url.toLowerCase().includes(e)||`/${t.path}`.toLowerCase().includes(e))},eI=()=>{let r=eN();ey=Math.max(0,Math.min(ey,r.length-1)),X.textContent="",r.forEach((r,n)=>{let a=r.entryId===t.entryId,i=C(e,"li",{className:`option${n===ey?" active":""}`,id:`obelism-page-${n}`},C(e,"span",{className:"option-text"},C(e,"span",{textContent:r.name}),C(e,"span",{className:"option-path",textContent:r.url})));if(i.setAttribute("role","option"),i.setAttribute("aria-selected",String(n===ey)),"published"!==r.status&&i.appendChild(C(e,"span",{className:"badge",textContent:"draft"===r.status?o.pageDraft:o.pageChanged})),a){i.setAttribute("aria-current","page");let t=P(e,"check");t.removeAttribute("aria-hidden"),t.setAttribute("role","img"),t.setAttribute("aria-label",o.pageCurrent),i.appendChild(t)}i.addEventListener("click",()=>eM(r)),X.appendChild(i)});let n=X.children[ey];n?(Y.setAttribute("aria-activedescendant",n.id),n.scrollIntoView?.({block:"nearest"})):Y.removeAttribute("aria-activedescendant"),_.textContent=(ev??(eb?"":o.pagesLoading))||(0===r.length?o.pagesEmpty:""),_.hidden=!_.textContent,_.className=`empty${ev?" error":""}`},eU=e=>{ep=null,(em=e)&&(Y.value="",ey=Math.max(0,(eb??[]).findIndex(({entryId:e})=>e===t.entryId)),eA(),eI()),ek(),(em?Y:H).focus()},eM=e=>{if(e.entryId===t.entryId)return eU(!1);t.openPage(e)},e$=e=>{(el=e)||(em=!1,ed=!1),ek(),s&&t.setSelecting(el&&!ec),el&&s&&eA()},eO=e=>{ec=e,ep=null,t.setSelecting(el&&!ec),ec&&t.select(null),ek(),(ec?j:u).focus()},ej=async e=>{ep=null;try{await t[e](),ep={text:"save"===e?o.saved:o.published,error:!1}}catch(e){ep=ex(e)}ek()};d.addEventListener("click",()=>{e$(!0),eg||(ec?j:u).focus()}),T.addEventListener("click",()=>e$(!1)),F.addEventListener("click",()=>{ed=!ed,ek(),ed||(eg?F:u).focus()}),et.addEventListener("click",e=>{if(!ed)return;let t=e.target.closest("button");t&&t!==F&&t!==T&&(ed=!1,ek())},!0),G.addEventListener("click",()=>void ej("save")),Q.addEventListener("click",()=>void ej("publish")),K.addEventListener("click",()=>t.signOut()),p.addEventListener("click",()=>t.signOut()),y.addEventListener("click",()=>t.select(null)),U.addEventListener("click",()=>eO(!0)),M.addEventListener("click",async()=>{ep=null;try{await t.createProductPage(),ep={text:o.addedProductPage,error:!1}}catch(e){ep=ex(e)}ek()}),$.addEventListener("click",()=>eO(!1)),A.addEventListener("click",()=>eL(!1)),N.addEventListener("click",()=>eL(!0)),H.addEventListener("click",()=>eU(!em)),j.addEventListener("input",ek),j.addEventListener("keydown",e=>{"Enter"!==e.key||e.isComposing?"Escape"===e.key&&e$(!1):(e.preventDefault(),u.focus())}),Y.addEventListener("input",()=>{ey=0,eI()}),Y.addEventListener("keydown",e=>{let t=X.children.length;if("ArrowDown"===e.key||"ArrowUp"===e.key){if(e.preventDefault(),0===t)return;ey=(ey+("ArrowDown"===e.key?1:-1)+t)%t,eI()}else if("Enter"!==e.key||e.isComposing)"Escape"===e.key&&(e.preventDefault(),eU(!1));else{e.preventDefault();let t=eN()[ey];t&&eM(t)}}),L.addEventListener("click",()=>{ep=null,t.undo()}),et.addEventListener("submit",e=>{e.preventDefault(),eS()}),u.addEventListener("input",()=>{eE(),ek()}),u.addEventListener("keydown",e=>{"Enter"!==e.key||e.shiftKey||e.isComposing?"Escape"===e.key&&e$(!1):(e.preventDefault(),eS())});let eR=t.on("change",ew);return ek(),e.body.appendChild(a),()=>{eR(),eP(),a.remove()}},S="https://content.obelism.studio",A=(e,t)=>JSON.stringify(e)===JSON.stringify(t),N=Symbol.for("@obelism/content/bridge"),I=y({isEditing:!1,entryId:null,on:()=>{}},new URLSearchParams),U=({url:e,prompt:c=!0,pagePath:h,productPath:m}={})=>{let x;if("u"<typeof window)return I;let w=window;if(w[N])return w[N];if(w.ObelismBridge)x=y(w.ObelismBridge,new URLSearchParams(w.location.search));else{let y=(x=((e,r)=>{let n=new URLSearchParams(e.location.search),c=e.parent!==e&&n.has("cms_preview"),h=u(),m=[],y={...g,selecting:!0},x=e=>{y={...y,...e},h.emit("change",y)},w={isEditing:c,mode:c?"editor":null,entryId:n.get("cms_entry"),environment:n.get(o),product:null,on:h.on,getState:()=>y,...b,destroy:()=>{m.splice(0).forEach(e=>e())}};if(!c)return w;let k=e.document,E=(t,n={})=>{e.parent.postMessage({source:d,type:t,...n},r)},C=k.createElement("style");C.textContent=p(),k.head.appendChild(C),m.push(()=>C.remove());let P=(e,t)=>{if(k.querySelectorAll("[data-cms-selected]").forEach(e=>{e.removeAttribute("data-cms-selected")}),y.selectedUid!==(e??null)&&x({selectedUid:e??null}),!e)return;let r=k.querySelector(v(e));r&&(r.setAttribute("data-cms-selected",""),t&&r.scrollIntoView({behavior:"smooth",block:"center"}))},L=e=>{let r=e.target,n=r?.closest?.(`[${t}]`);if(!n)return;e.preventDefault(),e.stopPropagation();let o=n.getAttribute(t);P(o,!1),E("select",{uid:o})};k.addEventListener("click",L,!0),m.push(()=>k.removeEventListener("click",L,!0));let S=()=>E("ready",{url:e.location.href}),A=new Map,N=0,I=e=>{let t=A.get(e);return t?(clearTimeout(t.timer),A.delete(e),0===A.size&&x({prompting:!1}),t):null};w.prompt=(e,t={})=>{let r=e.trim();if(!r)return Promise.reject(Error("Say what to change"));if(!y.features.includes("prompt"))return Promise.reject(Error("The editor does not offer prompts here"));let n=`prompt_${++N}`,o=void 0===t.uid?y.selectedUid:t.uid;return new Promise((e,t)=>{let a=setTimeout(()=>{I(n)?.reject(Error("The editor did not answer in time"))},12e4);A.set(n,{resolve:e,reject:t,timer:a}),x({prompting:!0}),E("prompt",{id:n,prompt:r,uid:o})})},w.undo=()=>E("undo"),w.select=e=>{P(e,!1),E("select",{uid:e})};let U=null;m.push(()=>U?.destroy()),m.push(()=>{for(let e of A.keys())I(e)?.reject(Error("The bridge was destroyed"))});let M=t=>{if(t.origin!==r||t.source!==e.parent)return;let n=t.data;if(n&&"obelism-content-editor"===n.source){if("connect"===n.type)S();else if("update"===n.type&&n.entry)h.emit("update",{entry:n.entry,selectedUid:n.selectedUid??null}),e.requestAnimationFrame(()=>P(n.selectedUid,!1)),U?.refresh();else if("select"===n.type)P(n.uid,!0);else if("saved"===n.type||"published"===n.type)h.emit(n.type,{}),0===h.listeners.update.size&&e.location.reload();else if("features"===n.type&&Array.isArray(n.features))x({features:n.features.filter(e=>"string"==typeof e)});else if("stats"===n.type)x({stats:(e=>{if(!e||"object"!=typeof e||Array.isArray(e))return{};let t={};for(let[r,n]of Object.entries(e)){let{clicks:e,clickers:o,viewers:a,rate:i}=n??{};f(e)&&f(o)&&f(a)&&f(i)&&(t[r]={clicks:e,clickers:o,viewers:a,rate:i})}return t})(n.stats),statsVisible:!1!==n.visible}),(U||Object.keys(y.stats).length)&&(U??(U=((e,{selector:t,onSelect:r,labels:n})=>{let o=e.document,d={...a,...n},c=o.createElement("div");c.setAttribute("data-obelism-stats","");let p=c.attachShadow({mode:"open"}),g=o.createElement("style");g.textContent=s;let u=o.createElement("div");u.className="layer",p.append(g,u),o.body.appendChild(c);let h={},m=!1,b=null,f=()=>{if(b=null,u.replaceChildren(),u.hidden=!m,!m)return;let n=e.innerHeight;for(let[a,s]of Object.entries(h)){let c=o.querySelector(t(a));if(!c)continue;let p=c.getBoundingClientRect();if(!p.width&&!p.height||p.bottom<0||p.top>n)continue;let g=o.createElement("button");g.type="button",g.className="badge",g.dataset.uid=a,g.textContent=i(d.clicked,{rate:Math.round(100*s.rate)}),g.title=i(d.title,{clickers:s.clickers,viewers:s.viewers,clicks:s.clicks});let{place:h,top:m,left:b}=l(p,e.innerWidth);g.dataset.place=h,g.style.top=`${m}px`,g.style.left=`${b}px`,g.addEventListener("click",()=>r(a)),u.appendChild(g)}},v=()=>{null===b&&m&&(b=e.requestAnimationFrame(f))};e.addEventListener("scroll",v,{capture:!0,passive:!0}),e.addEventListener("resize",v);let y=e.MutationObserver,x="function"==typeof y?new y(v):null;return x?.observe(o.body,{childList:!0,subtree:!0}),{update(t,r){h=t,m=r,null!==b&&(e.cancelAnimationFrame?.(b),b=null),f()},refresh:v,destroy(){null!==b&&e.cancelAnimationFrame?.(b),e.removeEventListener("scroll",v,{capture:!0}),e.removeEventListener("resize",v),x?.disconnect(),c.remove()}}})(e,{selector:v,onSelect:e=>w.select(e)})),U.update(y.stats,y.statsVisible));else if("promptState"===n.type)x({canUndo:!0===n.canUndo});else if("promptResult"===n.type&&"string"==typeof n.id){let e=I(n.id);if(!e)return;!0===n.ok?e.resolve({summary:"string"==typeof n.summary?n.summary:""}):e.reject(Error("string"==typeof n.error?n.error:"The prompt failed"))}}};return e.addEventListener("message",M),m.push(()=>e.removeEventListener("message",M)),"loading"===k.readyState?(k.addEventListener("DOMContentLoaded",S,{once:!0}),m.push(()=>k.removeEventListener("DOMContentLoaded",S))):S(),w})(w,new URL(e||S).origin)).isEditing||w.parent!==w?null:(e=>{for(let t of e.cookie.split(";")){let[e,...r]=t.trim().split("=");if("obelism_content_editing"===e)try{let e=decodeURIComponent(r.join("="));return e.startsWith("/")&&!e.startsWith("//")?e:null}catch{break}}return null})(w.document);if(y&&(x=((e,o,{pagePath:a=e=>`/${e}`,productPath:i}={})=>{let s=e.document,l=u(),c=[],h=new Map,m=[],b=new Set,f=null,y=null,x=-1/0,w=new Map,k=g,E=e=>{k={...k,...e},l.emit("change",k)},C=()=>E({unsaved:[...h.values()].some(({content:e,saved:t})=>!A(e,t)),canUndo:m.length>0}),P=async(t,r)=>{let n=await e.fetch(`${o}/api/${t}`,void 0===r?{credentials:"same-origin"}:{method:"POST",credentials:"same-origin",headers:{"Content-Type":"application/json","x-obelism-content":"1"},body:JSON.stringify(r)}),a=await n.json().catch(()=>({}));if(401===n.status)throw E({features:[]}),Error("You were signed out. Sign in again to edit.");if(!n.ok)throw Error("string"==typeof a.error?a.error:`Obelism Content answered ${n.status}`);return a},L=()=>s.querySelector(`[${r}]`)?.getAttribute(r)??null,S=()=>{let e=s.querySelector(`[${n}]`),t=e?.getAttribute(n),r=e?.getAttribute("data-cms-product-handle");return t&&r?{id:t,handle:r}:null},N=e=>{let t=e?s.querySelector(v(e)):null;return t?.closest(`[${r}]`)?.getAttribute(r)??L()},I=()=>{if(!f)return;let e=f.space.locales.map(({code:e})=>e),t=s.documentElement.lang;if(e.includes(t))return t;let r=t.split("-")[0]??"";return e.includes(r)?r:f.space.defaultLocale},U=new Map,M=async e=>{let t=h.get(e);if(t)return t;let r=U.get(e);return r||(r=P(`entries/${encodeURIComponent(e)}`).then(t=>{let r=h.get(e)??{content:t.content,saved:t.content,revision:t.draftRevision};return h.set(e,r),r}).finally(()=>U.delete(e)),U.set(e,r)),r},$=e=>{let t=void 0===e?k.selectedUid:e,r=N(t);if(!r)throw Error("Nothing on this page is marked as an entry: add editable(entry)");return{uid:t,entryId:r}},O=e=>{s.querySelectorAll("[data-cms-selected]").forEach(e=>{e.removeAttribute("data-cms-selected")}),k.selectedUid!==e&&E({selectedUid:e}),e&&s.querySelector(v(e))?.setAttribute("data-cms-selected","")},j=async t=>{if(0===l.listeners.update.size)return;let r=h.get(t)?.content,{entry:n}=await P(`entries/${encodeURIComponent(t)}/preview`,{content:r,locale:I()});l.emit("update",{entry:n,selectedUid:k.selectedUid}),e.requestAnimationFrame(()=>O(k.selectedUid))},R=e=>console.error("[@obelism/content bridge]",e),T=t=>{l.emit(t,{}),0===l.listeners.update.size&&e.location.reload()},z=async()=>{for(let[e,t]of h){if(A(t.content,t.saved))continue;let{draftRevision:r}=await P(`entries/${encodeURIComponent(e)}/save`,{content:t.content,baseRevision:t.revision});t.saved=t.content,t.revision=r,b.add(e)}m.length=0,x=-1/0,C()},D={isEditing:!0,mode:"site",get entryId(){return L()},get product(){return S()},environment:null,on:l.on,getState:()=>k,async prompt(e,t={}){let r=e.trim();if(!r)throw Error("Say what to change");if(!k.features.includes("prompt"))throw Error("You may not edit content here");let{uid:n,entryId:o}=$(t.uid);E({prompting:!0});try{let e=await M(o),t=await P(`entries/${encodeURIComponent(o)}/prompt`,{prompt:r,content:e.content,locale:I(),uid:n});return m.push({entryId:o,content:e.content}),x=-1/0,e.content=t.content,C(),await j(o),{summary:t.summary}}finally{E({prompting:!1})}},async createPage(t,r){let n=r.trim();if(!n)throw Error("Say what the page is for");if(!t.trim())throw Error("Say where the page goes, like /pricing");if(!k.features.includes("create"))throw Error("You may not add pages here");if(k.unsaved)throw Error("Save or undo your changes before adding a page");E({prompting:!0});try{let r=await P("entries",{path:t,prompt:n,locale:I(),from:L()}),o=a(r.path,I()??"");return e.location.assign(o),{summary:r.summary,entryId:r.entryId,path:r.path,url:o}}finally{E({prompting:!1})}},async createProductPage(t=S()??void 0){if(!t)throw Error("Nothing on this page is marked as a product: add editableProduct(product)");if(!k.features.includes("create"))throw Error("You may not add pages here");if(k.unsaved)throw Error("Save or undo your changes before adding a page");E({prompting:!0});try{let r=await P("product-pages",{product:{id:t.id,handle:t.handle}});return e.location.reload(),r}finally{E({prompting:!1})}},async view(e={}){let{uid:t,entryId:r}=$(e.uid),n=await M(r),{view:o}=await P(`entries/${encodeURIComponent(r)}/view`,{content:n.content,locale:I(),uid:t});return o},async applyJson(e,t={}){if(!k.features.includes("prompt"))throw Error("You may not edit content here");if(!e||"object"!=typeof e||Array.isArray(e))throw Error("Send the fields to change as an object");let{uid:r,entryId:n}=$(t.uid);E({prompting:!0});try{let t=await M(n),o=await P(`entries/${encodeURIComponent(n)}/apply`,{changes:e,content:t.content,locale:I(),uid:r});return A(o.content,t.content)||(m.push({entryId:n,content:t.content}),x=-1/0,t.content=o.content,C(),await j(n)),{changed:o.changed??[],...o.view&&{view:o.view}}}finally{E({prompting:!1})}},openForm(t,r={}){let{title:n="Content form",onReady:o,onError:a}=r;y?.();let i=!1,s=null,c=null,p=()=>{},g=e=>{i||a?.(e instanceof Error?e.message:String(e))},u=()=>{i||(i=!0,p(),s?.destroy(),y===u&&(y=null))};y=u;let b=()=>{if(i||!s)return;let e=N(k.selectedUid);if(!e)return;let t=h.get(e);if(!t)return void M(e).then(b,g);let r={entryId:e,content:t.content,locale:I(),selectedUid:k.selectedUid};c&&c.entryId===r.entryId&&c.content===r.content&&c.locale===r.locale&&c.selectedUid===r.selectedUid||(c=r,s.show(r))},f=(e,t)=>{let r=t??c?.entryId,n=void 0===r?void 0:h.get(r);if(i||void 0===r||!n||A(e,n.content))return;let o=Date.now();o-x>=1e3&&m.push({entryId:r,content:n.content}),x=o,n.content=e,c?.entryId===r&&(c={...c,content:e}),C(),clearTimeout(w.get(r)),w.set(r,setTimeout(()=>{w.delete(r),j(r).catch(R)},300))};return(async()=>{if(!k.features.includes("form"))throw Error("You may not edit content here");await M($(void 0).entryId);let{url:r}=await P("form",{});i||(s=((e,t,r,n,o)=>{let a=null;try{a=new URL(r)}catch{}if(!a||!/^https?:$/.test(a.protocol))throw Error("Obelism Content sent no form to open");let i=a.origin,s=t.ownerDocument.createElement("iframe");s.title=n,s.src=r;let l=!1,c=!1,p=null,g=()=>{l&&p&&s.contentWindow?.postMessage({source:d,type:"content",...p},i)},u=setTimeout(()=>{c||o.onError("The form did not open")},3e4),h=()=>{c=!0,clearTimeout(u),o.onReady()},m=e=>{if(e.origin!==i||!s.contentWindow||e.source!==s.contentWindow)return;let t=e.data;if(t&&"obelism-content-form"===t.source)if("ready"===t.type)l=!0,g(),!0!==t.loading&&h();else if("loaded"===t.type)l&&h();else{let e;if("change"!==t.type||!(e=t.content)||"object"!=typeof e||Array.isArray(e))if("height"===t.type){let e=t.height;if("number"==typeof e&&Number.isFinite(e)){let t=Math.round(Math.min(Math.max(e,80),4e3));s.style.height=`min(${t}px, 60vh)`}}else"error"===t.type&&o.onError("string"==typeof t.message&&t.message?t.message:"The form failed");else o.onChange(t.content,"string"==typeof t.entryId?t.entryId:void 0)}};return e.addEventListener("message",m),t.appendChild(s),{show(e){p=e,g()},destroy(){clearTimeout(u),e.removeEventListener("message",m),s.remove()}}})(e,t,"string"==typeof r?r:"",n,{onReady:()=>o?.(),onChange:f,onError:e=>a?.(e)}),p=l.on("change",b),b())})().catch(g),{close:u}},async pages(){let{pages:e}=await P("pages"),t=[I(),f?.space.defaultLocale];return e.flatMap(e=>{let r,n=t.find(t=>void 0!==t&&void 0!==e.paths[t])??Object.keys(e.paths)[0],o=void 0===n?void 0:e.paths[n];return void 0===n||void 0===o?[]:[{entryId:e.entryId,name:e.name,contentType:e.contentType,status:e.status,path:o,url:e.product?(r=e.product.handle,i?i(r,n):(f?.productPath??"/products/{handle}").replaceAll("{handle}",encodeURIComponent(r))):a(o,n),product:e.product??null}]})},openPage(t){(!k.unsaved||e.confirm("Leave this page and lose the changes you have not saved?"))&&(h.clear(),m.length=0,C(),e.location.assign(t.url))},undo(){let e=m.pop(),t=e&&h.get(e.entryId);e&&t&&(x=-1/0,t.content=e.content,C(),j(e.entryId).catch(R))},async save(){if(!k.features.includes("save"))throw Error("You may not edit content here");E({saving:!0});try{await z()}finally{E({saving:!1})}T("saved")},async publish(){if(!k.features.includes("publish"))throw Error("You may not publish here");E({publishing:!0});try{await z();let e=L(),t=b.size>0?[...b]:e?[e]:[];if(0===t.length)throw Error("Nothing on this page is marked as an entry: add editable(entry)");for(let e of t)await P(`entries/${encodeURIComponent(e)}/publish`,{}),b.delete(e)}finally{E({publishing:!1})}T("published")},signOut(){if(k.unsaved&&!e.confirm("Sign out and lose the changes you have not saved?"))return;h.clear(),C();let t=e.location.pathname+e.location.search;e.location.href=`${o}/logout?return_to=${encodeURIComponent(t)}`},select(e){O(e)},setSelecting(e){e?s.documentElement.setAttribute("data-cms-selecting",""):s.documentElement.removeAttribute("data-cms-selecting"),E({selecting:e})},destroy(){y?.(),w.forEach(e=>clearTimeout(e)),w.clear(),c.splice(0).forEach(e=>e())}},F=s.createElement("style");F.textContent=p("html[data-cms-selecting] "),s.head.appendChild(F),c.push(()=>F.remove()),c.push(()=>s.documentElement.removeAttribute("data-cms-selecting"));let B=e=>{if(!k.selecting)return;let r=e.target,n=r?.closest?.(`[${t}]`);n&&(e.preventDefault(),e.stopPropagation(),O(n.getAttribute(t)))};s.addEventListener("click",B,!0),c.push(()=>s.removeEventListener("click",B,!0));let q=e=>{k.unsaved&&(e.preventDefault(),e.returnValue="")};return e.addEventListener("beforeunload",q),c.push(()=>e.removeEventListener("beforeunload",q)),P("session").then(e=>{f=e,E({features:e.features})}).catch(e=>console.error("[@obelism/content bridge]",e)),D})(w,y,{pagePath:h,productPath:m})),x.isEditing&&c){let e=L(w.document,x,!0===c?{}:c),t=x.destroy;x.destroy=()=>{e(),t()}}}return w[N]=x,x};(e=window).ObelismBridge=U((e=>{let t=e?.dataset.url,r=t||S;if(!t&&e?.src){let t=new URL(e.src);"/bridge.js"===t.pathname&&(r=t.origin)}return{url:r,prompt:e?.dataset.prompt!=="false"}})(document.currentScript)),e.ObelismContent={getContentBridge:U,mountPromptBox:L}}();
|
package/dist/bridge.js
CHANGED
|
@@ -689,7 +689,20 @@ textarea::placeholder { color: rgb(var(--theme-foreground-muted-rgb)); }
|
|
|
689
689
|
display: block; width: 100%; height: min(560px, 60vh); border: none; border-radius: 12px;
|
|
690
690
|
background: rgb(var(--theme-background-actions-rgb) / .45);
|
|
691
691
|
}
|
|
692
|
-
|
|
692
|
+
/* Loading, it keeps the form's own height, the spinner in the middle,
|
|
693
|
+
whatever the form says meanwhile; the frame shows once the form does. */
|
|
694
|
+
.form.loading { position: relative; height: calc(min(560px, 60vh) + 12px); }
|
|
695
|
+
.form.loading iframe { position: absolute; visibility: hidden; }
|
|
696
|
+
.form-loader {
|
|
697
|
+
position: absolute; inset: 12px 12px 0; display: flex; align-items: center; justify-content: center;
|
|
698
|
+
gap: 10px; border-radius: 12px; color: rgb(var(--theme-foreground-muted-rgb));
|
|
699
|
+
background: rgb(var(--theme-background-actions-rgb) / .45);
|
|
700
|
+
}
|
|
701
|
+
.form-loader::before {
|
|
702
|
+
content: ''; width: 16px; height: 16px; flex: none; border-radius: 50%;
|
|
703
|
+
border: 2px solid rgb(var(--theme-border-rgb) / .3); border-top-color: rgb(var(--theme-accent-rgb));
|
|
704
|
+
animation: spin .7s linear infinite;
|
|
705
|
+
}
|
|
693
706
|
/* New page: where it goes, above what it is for. */
|
|
694
707
|
.path {
|
|
695
708
|
display: flex; align-items: center; gap: 10px; padding: 16px 22px 0;
|
|
@@ -862,9 +875,14 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
862
875
|
});
|
|
863
876
|
input.setAttribute('aria-label', labels.open);
|
|
864
877
|
// Form mode (on the site): the CMS's form, mounted while shown.
|
|
878
|
+
const formLoader = element(doc, 'div', {
|
|
879
|
+
className: 'form-loader',
|
|
880
|
+
textContent: labels.formLoading
|
|
881
|
+
});
|
|
882
|
+
formLoader.setAttribute('role', 'status');
|
|
865
883
|
const formBox = element(doc, 'div', {
|
|
866
884
|
className: 'form'
|
|
867
|
-
});
|
|
885
|
+
}, formLoader);
|
|
868
886
|
// What the prompt acts on: the whole page, or the selected block with a
|
|
869
887
|
// way back to the page.
|
|
870
888
|
const pageIcon = icon(doc, 'page');
|
|
@@ -1185,6 +1203,7 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1185
1203
|
input.hidden = form || picking || minimized || offerProduct;
|
|
1186
1204
|
formBox.hidden = !form || picking || minimized;
|
|
1187
1205
|
formBox.classList.toggle('loading', formLoading);
|
|
1206
|
+
formLoader.hidden = !formLoading;
|
|
1188
1207
|
toolbar.hidden = picking;
|
|
1189
1208
|
pagesSection.hidden = !picking;
|
|
1190
1209
|
input.placeholder = creating ? labels.newPagePlaceholder : labels.placeholder;
|
|
@@ -1225,8 +1244,9 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1225
1244
|
pageChip.setAttribute('aria-expanded', String(picking));
|
|
1226
1245
|
pageChipText.textContent = pages?.find(({ entryId })=>entryId === bridge.entryId)?.name ?? labels.pages;
|
|
1227
1246
|
const loadingForm = form && formLoading && !picking;
|
|
1228
|
-
const working = state.prompting
|
|
1229
|
-
|
|
1247
|
+
const working = state.prompting;
|
|
1248
|
+
// A form opening says so in its own place.
|
|
1249
|
+
const note = state.prompting ? creating ? labels.creating : offerProduct ? labels.addingProductPage : labels.working : loadingForm ? '' : message?.text ?? (offerProduct ? labels.productPageHint : site && !creating && !picking && !state.selectedUid ? labels.selectHint : '');
|
|
1230
1250
|
status.textContent = note;
|
|
1231
1251
|
status.hidden = !note || minimized;
|
|
1232
1252
|
status.className = `status${working ? ' working' : ''}${!busy && !loadingForm && message?.error ? ' error' : ''}`;
|
package/dist/bridge.mjs
CHANGED
|
@@ -687,7 +687,20 @@ textarea::placeholder { color: rgb(var(--theme-foreground-muted-rgb)); }
|
|
|
687
687
|
display: block; width: 100%; height: min(560px, 60vh); border: none; border-radius: 12px;
|
|
688
688
|
background: rgb(var(--theme-background-actions-rgb) / .45);
|
|
689
689
|
}
|
|
690
|
-
|
|
690
|
+
/* Loading, it keeps the form's own height, the spinner in the middle,
|
|
691
|
+
whatever the form says meanwhile; the frame shows once the form does. */
|
|
692
|
+
.form.loading { position: relative; height: calc(min(560px, 60vh) + 12px); }
|
|
693
|
+
.form.loading iframe { position: absolute; visibility: hidden; }
|
|
694
|
+
.form-loader {
|
|
695
|
+
position: absolute; inset: 12px 12px 0; display: flex; align-items: center; justify-content: center;
|
|
696
|
+
gap: 10px; border-radius: 12px; color: rgb(var(--theme-foreground-muted-rgb));
|
|
697
|
+
background: rgb(var(--theme-background-actions-rgb) / .45);
|
|
698
|
+
}
|
|
699
|
+
.form-loader::before {
|
|
700
|
+
content: ''; width: 16px; height: 16px; flex: none; border-radius: 50%;
|
|
701
|
+
border: 2px solid rgb(var(--theme-border-rgb) / .3); border-top-color: rgb(var(--theme-accent-rgb));
|
|
702
|
+
animation: spin .7s linear infinite;
|
|
703
|
+
}
|
|
691
704
|
/* New page: where it goes, above what it is for. */
|
|
692
705
|
.path {
|
|
693
706
|
display: flex; align-items: center; gap: 10px; padding: 16px 22px 0;
|
|
@@ -860,9 +873,14 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
860
873
|
});
|
|
861
874
|
input.setAttribute('aria-label', labels.open);
|
|
862
875
|
// Form mode (on the site): the CMS's form, mounted while shown.
|
|
876
|
+
const formLoader = element(doc, 'div', {
|
|
877
|
+
className: 'form-loader',
|
|
878
|
+
textContent: labels.formLoading
|
|
879
|
+
});
|
|
880
|
+
formLoader.setAttribute('role', 'status');
|
|
863
881
|
const formBox = element(doc, 'div', {
|
|
864
882
|
className: 'form'
|
|
865
|
-
});
|
|
883
|
+
}, formLoader);
|
|
866
884
|
// What the prompt acts on: the whole page, or the selected block with a
|
|
867
885
|
// way back to the page.
|
|
868
886
|
const pageIcon = icon(doc, 'page');
|
|
@@ -1183,6 +1201,7 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1183
1201
|
input.hidden = form || picking || minimized || offerProduct;
|
|
1184
1202
|
formBox.hidden = !form || picking || minimized;
|
|
1185
1203
|
formBox.classList.toggle('loading', formLoading);
|
|
1204
|
+
formLoader.hidden = !formLoading;
|
|
1186
1205
|
toolbar.hidden = picking;
|
|
1187
1206
|
pagesSection.hidden = !picking;
|
|
1188
1207
|
input.placeholder = creating ? labels.newPagePlaceholder : labels.placeholder;
|
|
@@ -1223,8 +1242,9 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1223
1242
|
pageChip.setAttribute('aria-expanded', String(picking));
|
|
1224
1243
|
pageChipText.textContent = pages?.find(({ entryId })=>entryId === bridge.entryId)?.name ?? labels.pages;
|
|
1225
1244
|
const loadingForm = form && formLoading && !picking;
|
|
1226
|
-
const working = state.prompting
|
|
1227
|
-
|
|
1245
|
+
const working = state.prompting;
|
|
1246
|
+
// A form opening says so in its own place.
|
|
1247
|
+
const note = state.prompting ? creating ? labels.creating : offerProduct ? labels.addingProductPage : labels.working : loadingForm ? '' : message?.text ?? (offerProduct ? labels.productPageHint : site && !creating && !picking && !state.selectedUid ? labels.selectHint : '');
|
|
1228
1248
|
status.textContent = note;
|
|
1229
1249
|
status.hidden = !note || minimized;
|
|
1230
1250
|
status.className = `status${working ? ' working' : ''}${!busy && !loadingForm && message?.error ? ' error' : ''}`;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@obelism/content",
|
|
3
3
|
"description": "Obelism Content SDK: the delivery API client, the visual editor bridge with prompt editing, editing on your own site, webhook verification, and the content model CLI",
|
|
4
|
-
"version": "0.19.
|
|
4
|
+
"version": "0.19.2",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cms",
|
|
7
7
|
"headless-cms",
|