@obelism/content 0.14.0 → 0.16.0
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/README.md +3 -1
- package/dist/bridge.d.mts +2 -0
- package/dist/bridge.d.mts.map +1 -1
- package/dist/bridge.d.ts +2 -0
- package/dist/bridge.d.ts.map +1 -1
- package/dist/bridge.global.js +2 -2
- package/dist/bridge.js +46 -10
- package/dist/bridge.mjs +46 -10
- package/dist/index.js +4 -1
- package/dist/index.mjs +4 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -160,7 +160,9 @@ CMS's own form for the page — or for the entry around the selected block —
|
|
|
160
160
|
right in the box: the fields, and blocks as cards to open and add,
|
|
161
161
|
as in the dashboard. Edits apply as you make them: they land in the unsaved
|
|
162
162
|
changes, show on the page, and undo a burst of typing at a time. A prompt or
|
|
163
|
-
an undo shows in the form too.
|
|
163
|
+
an undo shows in the form too. The form is as tall as it needs to be (up to
|
|
164
|
+
60% of the window), and the box can be minimized to its toolbar and footer to
|
|
165
|
+
see the page, keeping the form as it is. A chip under the prompt names the page and
|
|
164
166
|
opens every page of the space, drafts included, to go to one (at
|
|
165
167
|
`pagePath`, in the page's language when it has a path there):
|
|
166
168
|
|
package/dist/bridge.d.mts
CHANGED
package/dist/bridge.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bridge.d.mts","sources":["../src/bridge/statsOverlay.ts","../src/bridge/createBridge.ts","../src/bridge/promptBox.ts","../src/bridge.ts"],"mappings":";;AAAA,KAAK,UAAU;AACf;AACA;AACA;AACA;AACA;AACA,KAAK,WAAW;AAChB;AACA;AACA;AACA,cAAc,oBAAoB,EAAE,WAAW;AAc/C,KAAK,YAAY;AACjB,kBAAkB,QAAQ,CAAC,MAAM,SAAS,UAAU;AACpD;AACA;AACA;AACA,cAAc,iBAAiB,QAAQ,MAAM;AAC7C;AACA;AACA,aAAa,OAAO,CAAC,WAAW;AAChC,MAAM,YAAY;;AC5BlB,KAAK,YAAY;AACjB;AACA,eAAe,KAAK;AACpB;AACA;AACA,WAAW,MAAM;AACjB,eAAe,MAAM;AACrB,YAAY,WAAW;AACvB;AACA,KAAK,WAAW,SAAS,YAAY;AACrC,KAAK,cAAc,WAAW,WAAW,cAAc,YAAY;AACnE,KAAK,WAAW;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ,CAAC,MAAM,SAAS,UAAU;AAC7C;AACA;AACA,KAAK,YAAY;AACjB;AACA;AACA,KAAK,gBAAgB;AACrB;AACA;AACA;AACA;AACA;AACA,KAAK,eAAe;AACpB;AACA,WAAW,MAAM;AACjB;AACA,KAAK,WAAW;AAChB;AACA;AACA;AACA;AACA,KAAK,UAAU;AACf;AACA;AACA,KAAK,QAAQ;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK,aAAa;AAClB;AACA;AACA;AACA;AACA,iBAAiB,WAAW,sBAAsB,cAAc;AAChE,gBAAgB,WAAW;AAC3B;AACA;AACA,QAAQ,OAAO,CAAC,YAAY;AAC5B,8CAA8C,OAAO,CAAC,gBAAgB;AACtE;AACA;AACA,QAAQ,OAAO,CAAC,MAAM;AACtB,uBAAuB,MAAM;AAC7B;AACA,QAAQ,OAAO,CAAC,eAAe;AAC/B,wBAAwB,WAAW,YAAY,WAAW,GAAG,UAAU;AACvE,aAAa,OAAO,CAAC,QAAQ;AAC7B,mBAAmB,QAAQ;AAC3B;AACA,YAAY,OAAO;AACnB,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AAEA,cAAc,aAAa,EAAE,WAAW;;ACrFxC,KAAK,YAAY;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,qBAAqB,EAAE,YAAY;AACjD,KAAK,gBAAgB;AACrB,aAAa,OAAO,CAAC,YAAY;AACjC;AACA,cAAc,cAAc,QAAQ,QAAQ,UAAU,aAAa,YAAY,gBAAgB;;
|
|
1
|
+
{"version":3,"file":"bridge.d.mts","sources":["../src/bridge/statsOverlay.ts","../src/bridge/createBridge.ts","../src/bridge/promptBox.ts","../src/bridge.ts"],"mappings":";;AAAA,KAAK,UAAU;AACf;AACA;AACA;AACA;AACA;AACA,KAAK,WAAW;AAChB;AACA;AACA;AACA,cAAc,oBAAoB,EAAE,WAAW;AAc/C,KAAK,YAAY;AACjB,kBAAkB,QAAQ,CAAC,MAAM,SAAS,UAAU;AACpD;AACA;AACA;AACA,cAAc,iBAAiB,QAAQ,MAAM;AAC7C;AACA;AACA,aAAa,OAAO,CAAC,WAAW;AAChC,MAAM,YAAY;;AC5BlB,KAAK,YAAY;AACjB;AACA,eAAe,KAAK;AACpB;AACA;AACA,WAAW,MAAM;AACjB,eAAe,MAAM;AACrB,YAAY,WAAW;AACvB;AACA,KAAK,WAAW,SAAS,YAAY;AACrC,KAAK,cAAc,WAAW,WAAW,cAAc,YAAY;AACnE,KAAK,WAAW;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ,CAAC,MAAM,SAAS,UAAU;AAC7C;AACA;AACA,KAAK,YAAY;AACjB;AACA;AACA,KAAK,gBAAgB;AACrB;AACA;AACA;AACA;AACA;AACA,KAAK,eAAe;AACpB;AACA,WAAW,MAAM;AACjB;AACA,KAAK,WAAW;AAChB;AACA;AACA;AACA;AACA,KAAK,UAAU;AACf;AACA;AACA,KAAK,QAAQ;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK,aAAa;AAClB;AACA;AACA;AACA;AACA,iBAAiB,WAAW,sBAAsB,cAAc;AAChE,gBAAgB,WAAW;AAC3B;AACA;AACA,QAAQ,OAAO,CAAC,YAAY;AAC5B,8CAA8C,OAAO,CAAC,gBAAgB;AACtE;AACA;AACA,QAAQ,OAAO,CAAC,MAAM;AACtB,uBAAuB,MAAM;AAC7B;AACA,QAAQ,OAAO,CAAC,eAAe;AAC/B,wBAAwB,WAAW,YAAY,WAAW,GAAG,UAAU;AACvE,aAAa,OAAO,CAAC,QAAQ;AAC7B,mBAAmB,QAAQ;AAC3B;AACA,YAAY,OAAO;AACnB,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AAEA,cAAc,aAAa,EAAE,WAAW;;ACrFxC,KAAK,YAAY;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,qBAAqB,EAAE,YAAY;AACjD,KAAK,gBAAgB;AACrB,aAAa,OAAO,CAAC,YAAY;AACjC;AACA,cAAc,cAAc,QAAQ,QAAQ,UAAU,aAAa,YAAY,gBAAgB;;ACvC/F,KAAK,aAAa;AAClB;AACA,uBAAuB,gBAAgB;AACvC;AACA;AACA,cAAc,iBAAiB,QAAQ,aAAa;AACpD,cAAc,gBAAgB,gCAAgC,aAAa,KAAK,aAAa","names":[]}
|
package/dist/bridge.d.ts
CHANGED
package/dist/bridge.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bridge.d.ts","sources":["../src/bridge/statsOverlay.ts","../src/bridge/createBridge.ts","../src/bridge/promptBox.ts","../src/bridge.ts"],"mappings":";;AAAA,KAAK,UAAU;AACf;AACA;AACA;AACA;AACA;AACA,KAAK,WAAW;AAChB;AACA;AACA;AACA,cAAc,oBAAoB,EAAE,WAAW;AAc/C,KAAK,YAAY;AACjB,kBAAkB,QAAQ,CAAC,MAAM,SAAS,UAAU;AACpD;AACA;AACA;AACA,cAAc,iBAAiB,QAAQ,MAAM;AAC7C;AACA;AACA,aAAa,OAAO,CAAC,WAAW;AAChC,MAAM,YAAY;;AC5BlB,KAAK,YAAY;AACjB;AACA,eAAe,KAAK;AACpB;AACA;AACA,WAAW,MAAM;AACjB,eAAe,MAAM;AACrB,YAAY,WAAW;AACvB;AACA,KAAK,WAAW,SAAS,YAAY;AACrC,KAAK,cAAc,WAAW,WAAW,cAAc,YAAY;AACnE,KAAK,WAAW;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ,CAAC,MAAM,SAAS,UAAU;AAC7C;AACA;AACA,KAAK,YAAY;AACjB;AACA;AACA,KAAK,gBAAgB;AACrB;AACA;AACA;AACA;AACA;AACA,KAAK,eAAe;AACpB;AACA,WAAW,MAAM;AACjB;AACA,KAAK,WAAW;AAChB;AACA;AACA;AACA;AACA,KAAK,UAAU;AACf;AACA;AACA,KAAK,QAAQ;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK,aAAa;AAClB;AACA;AACA;AACA;AACA,iBAAiB,WAAW,sBAAsB,cAAc;AAChE,gBAAgB,WAAW;AAC3B;AACA;AACA,QAAQ,OAAO,CAAC,YAAY;AAC5B,8CAA8C,OAAO,CAAC,gBAAgB;AACtE;AACA;AACA,QAAQ,OAAO,CAAC,MAAM;AACtB,uBAAuB,MAAM;AAC7B;AACA,QAAQ,OAAO,CAAC,eAAe;AAC/B,wBAAwB,WAAW,YAAY,WAAW,GAAG,UAAU;AACvE,aAAa,OAAO,CAAC,QAAQ;AAC7B,mBAAmB,QAAQ;AAC3B;AACA,YAAY,OAAO;AACnB,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AAEA,cAAc,aAAa,EAAE,WAAW;;ACrFxC,KAAK,YAAY;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,qBAAqB,EAAE,YAAY;AACjD,KAAK,gBAAgB;AACrB,aAAa,OAAO,CAAC,YAAY;AACjC;AACA,cAAc,cAAc,QAAQ,QAAQ,UAAU,aAAa,YAAY,gBAAgB;;
|
|
1
|
+
{"version":3,"file":"bridge.d.ts","sources":["../src/bridge/statsOverlay.ts","../src/bridge/createBridge.ts","../src/bridge/promptBox.ts","../src/bridge.ts"],"mappings":";;AAAA,KAAK,UAAU;AACf;AACA;AACA;AACA;AACA;AACA,KAAK,WAAW;AAChB;AACA;AACA;AACA,cAAc,oBAAoB,EAAE,WAAW;AAc/C,KAAK,YAAY;AACjB,kBAAkB,QAAQ,CAAC,MAAM,SAAS,UAAU;AACpD;AACA;AACA;AACA,cAAc,iBAAiB,QAAQ,MAAM;AAC7C;AACA;AACA,aAAa,OAAO,CAAC,WAAW;AAChC,MAAM,YAAY;;AC5BlB,KAAK,YAAY;AACjB;AACA,eAAe,KAAK;AACpB;AACA;AACA,WAAW,MAAM;AACjB,eAAe,MAAM;AACrB,YAAY,WAAW;AACvB;AACA,KAAK,WAAW,SAAS,YAAY;AACrC,KAAK,cAAc,WAAW,WAAW,cAAc,YAAY;AACnE,KAAK,WAAW;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ,CAAC,MAAM,SAAS,UAAU;AAC7C;AACA;AACA,KAAK,YAAY;AACjB;AACA;AACA,KAAK,gBAAgB;AACrB;AACA;AACA;AACA;AACA;AACA,KAAK,eAAe;AACpB;AACA,WAAW,MAAM;AACjB;AACA,KAAK,WAAW;AAChB;AACA;AACA;AACA;AACA,KAAK,UAAU;AACf;AACA;AACA,KAAK,QAAQ;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK,aAAa;AAClB;AACA;AACA;AACA;AACA,iBAAiB,WAAW,sBAAsB,cAAc;AAChE,gBAAgB,WAAW;AAC3B;AACA;AACA,QAAQ,OAAO,CAAC,YAAY;AAC5B,8CAA8C,OAAO,CAAC,gBAAgB;AACtE;AACA;AACA,QAAQ,OAAO,CAAC,MAAM;AACtB,uBAAuB,MAAM;AAC7B;AACA,QAAQ,OAAO,CAAC,eAAe;AAC/B,wBAAwB,WAAW,YAAY,WAAW,GAAG,UAAU;AACvE,aAAa,OAAO,CAAC,QAAQ;AAC7B,mBAAmB,QAAQ;AAC3B;AACA,YAAY,OAAO;AACnB,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AAEA,cAAc,aAAa,EAAE,WAAW;;ACrFxC,KAAK,YAAY;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,qBAAqB,EAAE,YAAY;AACjD,KAAK,gBAAgB;AACrB,aAAa,OAAO,CAAC,YAAY;AACjC;AACA,cAAc,cAAc,QAAQ,QAAQ,UAAU,aAAa,YAAY,gBAAgB;;ACvC/F,KAAK,aAAa;AAClB;AACA,uBAAuB,gBAAgB;AACvC;AACA;AACA,cAAc,iBAAiB,QAAQ,aAAa;AACpD,cAAc,gBAAgB,gCAAgC,aAAa,KAAK,aAAa","names":[]}
|
package/dist/bridge.global.js
CHANGED
|
@@ -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
|
-
`,s=(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},l="obelism-content-bridge",d="#d58a1f",c=(e="")=>`${e}[${t}]{cursor:pointer;transition:outline-color .15s}${e}[${t}]:hover{outline:2px dashed ${d};outline-offset:2px}${e}[${t}][data-cms-selected]{outline:2px solid ${d};outline-offset:2px}`,p={features:[],selectedUid:null,prompting:!1,canUndo:!1,unsaved:!1,saving:!1,publishing:!1,selecting:!1,stats:{},statsVisible:!1},g=()=>{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)}}}},u=()=>Promise.reject(Error("Save and publish in the visual editor itself")),h=()=>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")),view:h,applyJson:h,openForm:(e,t={})=>(queueMicrotask(()=>t.onError?.("Only while signed in to edit on the site")),{close:()=>{}}),pages:h,openPage:()=>{},undo:()=>{},save:u,publish:u,signOut:()=>{},select:()=>{},setSelecting:()=>{}},m=e=>"number"==typeof e&&Number.isFinite(e)&&e>=0,f=e=>`[${t}="${e.replace(/["\\]/g,"\\$&")}"]`,v=(e,t)=>{let r=g();e.on("saved",()=>r.emit("saved",{})),e.on("published",()=>r.emit("published",{}));let o=!1;return{isEditing:e.isEditing,mode:e.isEditing?"editor":null,entryId:e.entryId,environment:t.get(n),on:(t,n)=>("update"!==t||o||(o=!0,e.on("update",e=>{let t=e?.entry;t&&r.emit("update",{entry:t,selectedUid:null})})),r.on(t,n)),getState:()=>p,...b,destroy:()=>{}}},y={open:"Edit with a prompt",placeholder:"Describe a change, e.g. “make the heading shorter”",send:"Apply",undo:"Undo",close:"Close",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"},x={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"/>',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"/>',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"/>'},w=`
|
|
25
|
+
`,s=(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},l="obelism-content-bridge",d="#d58a1f",c=(e="")=>`${e}[${t}]{cursor:pointer;transition:outline-color .15s}${e}[${t}]:hover{outline:2px dashed ${d};outline-offset:2px}${e}[${t}][data-cms-selected]{outline:2px solid ${d};outline-offset:2px}`,p={features:[],selectedUid:null,prompting:!1,canUndo:!1,unsaved:!1,saving:!1,publishing:!1,selecting:!1,stats:{},statsVisible:!1},g=()=>{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)}}}},u=()=>Promise.reject(Error("Save and publish in the visual editor itself")),h=()=>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")),view:h,applyJson:h,openForm:(e,t={})=>(queueMicrotask(()=>t.onError?.("Only while signed in to edit on the site")),{close:()=>{}}),pages:h,openPage:()=>{},undo:()=>{},save:u,publish:u,signOut:()=>{},select:()=>{},setSelecting:()=>{}},m=e=>"number"==typeof e&&Number.isFinite(e)&&e>=0,f=e=>`[${t}="${e.replace(/["\\]/g,"\\$&")}"]`,v=(e,t)=>{let r=g();e.on("saved",()=>r.emit("saved",{})),e.on("published",()=>r.emit("published",{}));let o=!1;return{isEditing:e.isEditing,mode:e.isEditing?"editor":null,entryId:e.entryId,environment:t.get(n),on:(t,n)=>("update"!==t||o||(o=!0,e.on("update",e=>{let t=e?.entry;t&&r.emit("update",{entry:t,selectedUid:null})})),r.on(t,n)),getState:()=>p,...b,destroy:()=>{}}},y={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"},x={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"/>',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"/>'},w=`
|
|
26
26
|
:host { all: initial; }
|
|
27
27
|
* { box-sizing: border-box; font: inherit; color: inherit; margin: 0; }
|
|
28
28
|
.root {
|
|
@@ -233,4 +233,4 @@ button.chip:disabled { opacity: .5; }
|
|
|
233
233
|
.empty { padding: 8px 12px; color: rgb(var(--theme-foreground-muted-rgb)); }
|
|
234
234
|
.empty.error { color: var(--theme-error); }
|
|
235
235
|
[hidden] { display: none !important; }
|
|
236
|
-
`,k=(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},E=(e,t)=>{let r=k(e,"span",{className:"icon"});return r.setAttribute("aria-hidden","true"),r.innerHTML=`<svg viewBox="0 0 24 24">${x[t]}</svg>`,r},C=(e,t,r={})=>{let n={...y,...r.labels},o=k(e,"div");o.setAttribute("data-obelism-content-prompt","");let a=o.attachShadow({mode:"open"}),i="site"===t.mode,s=k(e,"span",{textContent:n.open}),l=k(e,"button",{className:"pill",type:"button"},s,k(e,"span",{className:"mark",textContent:"⁜"})),d=k(e,"span",{className:"pill compact"},`${n.viewingDrafts} \xb7 `),c=k(e,"button",{className:"link",type:"button",textContent:n.signOut});d.appendChild(c);let p=k(e,"p",{className:"status"});p.setAttribute("role","status");let g=k(e,"textarea",{placeholder:n.placeholder,rows:1});g.setAttribute("aria-label",n.open);let u=k(e,"div",{className:"form"}),h=E(e,"page"),b=E(e,"block"),m=k(e,"span"),f=k(e,"button",{type:"button",title:n.clearBlock});f.setAttribute("aria-label",n.clearBlock),f.appendChild(E(e,"close"));let v=k(e,"span",{className:"chip scope"},h,b,m,f),x=k(e,"button",{className:"action chip",type:"button"},E(e,"undo"),n.undo),C=t=>{let r=k(e,"button",{type:"button",textContent:t});return r.setAttribute("aria-pressed","false"),r},S=C(n.modePrompt),A=C(n.form),L=k(e,"span",{className:"modes"},S,A);L.setAttribute("role","group"),L.setAttribute("aria-label",n.modes);let N=k(e,"button",{className:"action chip",type:"button"},E(e,"newPage"),n.newPage),U=k(e,"button",{type:"button",title:n.newPageCancel});U.setAttribute("aria-label",n.newPageCancel),U.appendChild(E(e,"close"));let P=k(e,"span",{className:"chip scope"},E(e,"newPage"),k(e,"span",{textContent:n.newPage}),U),I=k(e,"input",{type:"text",placeholder:n.pathPlaceholder,autocomplete:"off",spellcheck:!1}),$=k(e,"label",{className:"path"},k(e,"span",{textContent:n.path}),I),M=k(e,"button",{className:"close icon-button",type:"button",title:n.close},E(e,"close"));M.setAttribute("aria-label",n.close);let O=k(e,"button",{className:"action primary icon-button",type:"submit"},k(e,"span",{className:"visually-hidden",textContent:n.send}),E(e,"send"));O.title=n.send;let T=k(e,"span",{className:"divider"}),j=k(e,"div",{className:"toolbar"},v,P,L,x,N,k(e,"span",{className:"spacer"}),M,T,O),R=k(e,"span",{textContent:n.pages}),D=k(e,"button",{className:"chip page-chip",type:"button",title:n.pages},E(e,"page"),R,E(e,"chevrons"));D.setAttribute("aria-haspopup","listbox"),D.setAttribute("aria-expanded","false"),D.setAttribute("aria-controls","obelism-pages");let z=k(e,"input",{type:"text",placeholder:n.pagesSearch,autocomplete:"off",spellcheck:!1});z.setAttribute("role","combobox"),z.setAttribute("aria-label",n.pagesSearch),z.setAttribute("aria-autocomplete","list"),z.setAttribute("aria-expanded","true"),z.setAttribute("aria-controls","obelism-pages");let F=k(e,"ul",{className:"options",id:"obelism-pages"});F.setAttribute("role","listbox"),F.setAttribute("aria-label",n.pages);let q=k(e,"p",{className:"empty"}),B=k(e,"div",{className:"pages"},k(e,"label",{className:"search"},E(e,"search"),z),F,q),V=k(e,"span",{className:"unsaved"});V.appendChild(k(e,"span",{className:"dot"})),V.appendChild(e.createTextNode(n.unsaved));let Y=k(e,"button",{className:"link",type:"button",textContent:n.signOut}),H=k(e,"button",{className:"action chip",type:"button",textContent:n.save}),W=k(e,"button",{className:"action chip",type:"button",textContent:n.publish}),_=k(e,"div",{className:"footer"},D,V,k(e,"span",{className:"spacer"}),Y,H,W),J=k(e,"form",{className:"panel"},p,$,g,u,j,B,_),X=k(e,"div",{className:"root"},k(e,"div",{className:"bar"},l,d),J);a.append(k(e,"style",{textContent:w}),X);let Z=!1,K=!1,G=null,Q=!1,ee=null,et=!1,er=!1,en=null,eo=null,ea=null,ei=0,es=e=>({text:e instanceof Error?e.message:String(e),error:!0}),el=e=>{let r=e.features.includes("prompt"),o=e.saving||e.publishing,a=e.prompting||o;X.hidden=!r&&!i,l.hidden=Z||!r,d.hidden=r||!i,J.hidden=!Z||!r;let c=i&&e.features.includes("create"),y=i&&null===t.entryId,w=y&&c;c||(K=!1),w&&(K=!0),(K||y||!i)&&(Q=!1);let k=Z&&r&&Q;k&&!ee?ep():!k&&ee&&eg(),s.textContent=w?n.newPage:n.open,U.hidden=w,v.hidden=K,P.hidden=!K,N.hidden=K||Q||!c,N.disabled=a,$.hidden=!K||er,I.disabled=a,g.hidden=Q||er,u.hidden=!Q||er,u.classList.toggle("loading",et),j.hidden=er,B.hidden=!er,g.placeholder=K?n.newPagePlaceholder:n.placeholder,m.textContent=e.selectedUid?n.scopeBlock:n.scopeEntry,f.hidden=!e.selectedUid,h.hidden=!!e.selectedUid,b.hidden=!e.selectedUid,L.hidden=!i||K||y||!e.features.includes("form"),S.setAttribute("aria-pressed",String(!Q)),A.setAttribute("aria-pressed",String(Q)),L.querySelectorAll("button").forEach(e=>{e.disabled=a}),x.hidden=K||!e.canUndo,x.disabled=a,O.hidden=Q,T.hidden=Q,O.disabled=a||""===g.value.trim()||K&&""===I.value.trim(),g.disabled=a,H.hidden=!e.features.includes("save")||y,H.disabled=a||!e.unsaved,H.textContent=e.saving?n.saving:n.save,W.hidden=!e.features.includes("publish")||y,W.disabled=a,W.textContent=e.publishing?n.publishing:n.publish,Y.hidden=!i,_.hidden=!i,V.hidden=!e.unsaved,D.hidden=!i,D.setAttribute("aria-expanded",String(er)),R.textContent=en?.find(({entryId:e})=>e===t.entryId)?.name??n.pages;let E=Q&&et&&!er,C=e.prompting||E,M=e.prompting?K?n.creating:n.working:E?n.formLoading:G?.text??(!i||K||er||e.selectedUid?"":n.selectHint);p.textContent=M,p.hidden=!M,p.className=`status${C?" working":""}${!a&&!E&&G?.error?" error":""}`},ed=()=>el(t.getState()),ec=()=>{g.style.height="auto",g.style.height=`${g.scrollHeight}px`},ep=()=>{et=!0,u.classList.add("loading");let e=t.openForm(u,{title:n.formTitle,onReady:()=>{ee===e&&(et=!1,G=null,ed())},onError:t=>{ee===e&&(et=!1,G={text:t,error:!0},ed())}});ee=e},eg=()=>{ee?.close(),ee=null,et=!1},eu=e=>{Q!==e&&(Q=e,G=null,ed(),Q||g.focus())},eh=async()=>{if(Q)return;let e=g.value.trim();if(e&&!t.getState().prompting){G=null;try{if(K){let r=I.value.trim();if(!r)return I.focus();await t.createPage(r,e),en=null,eo=null,G={text:n.created,error:!1}}else{let{summary:r}=await t.prompt(e);G={text:r,error:!1}}g.value="",ec()}catch(e){G=es(e)}ed(),g.focus()}},eb=()=>(eo??(eo=t.pages().then(e=>{en=e,ea=null,ef(),ed()},e=>{eo=null,ea=es(e).text,ef()})),eo),em=()=>{let e=z.value.trim().toLowerCase();return(en??[]).filter(t=>!e||t.name.toLowerCase().includes(e)||t.url.toLowerCase().includes(e)||`/${t.path}`.toLowerCase().includes(e))},ef=()=>{let r=em();ei=Math.max(0,Math.min(ei,r.length-1)),F.textContent="",r.forEach((r,o)=>{let a=r.entryId===t.entryId,i=k(e,"li",{className:`option${o===ei?" active":""}`,id:`obelism-page-${o}`},k(e,"span",{className:"option-text"},k(e,"span",{textContent:r.name}),k(e,"span",{className:"option-path",textContent:r.url})));if(i.setAttribute("role","option"),i.setAttribute("aria-selected",String(o===ei)),"published"!==r.status&&i.appendChild(k(e,"span",{className:"badge",textContent:"draft"===r.status?n.pageDraft:n.pageChanged})),a){i.setAttribute("aria-current","page");let t=E(e,"check");t.removeAttribute("aria-hidden"),t.setAttribute("role","img"),t.setAttribute("aria-label",n.pageCurrent),i.appendChild(t)}i.addEventListener("click",()=>ey(r)),F.appendChild(i)});let o=F.children[ei];o?(z.setAttribute("aria-activedescendant",o.id),o.scrollIntoView?.({block:"nearest"})):z.removeAttribute("aria-activedescendant"),q.textContent=(ea??(en?"":n.pagesLoading))||(0===r.length?n.pagesEmpty:""),q.hidden=!q.textContent,q.className=`empty${ea?" error":""}`},ev=e=>{G=null,(er=e)&&(z.value="",ei=Math.max(0,(en??[]).findIndex(({entryId:e})=>e===t.entryId)),eb(),ef()),ed(),(er?z:D).focus()},ey=e=>{if(e.entryId===t.entryId)return ev(!1);t.openPage(e)},ex=e=>{(Z=e)||(er=!1),ed(),i&&t.setSelecting(Z&&!K),Z&&i&&eb()},ew=e=>{K=e,G=null,t.setSelecting(Z&&!K),K&&t.select(null),ed(),(K?I:g).focus()},ek=async e=>{G=null;try{await t[e](),G={text:"save"===e?n.saved:n.published,error:!1}}catch(e){G=es(e)}ed()};l.addEventListener("click",()=>{ex(!0),Q||(K?I:g).focus()}),M.addEventListener("click",()=>ex(!1)),H.addEventListener("click",()=>void ek("save")),W.addEventListener("click",()=>void ek("publish")),Y.addEventListener("click",()=>t.signOut()),c.addEventListener("click",()=>t.signOut()),f.addEventListener("click",()=>t.select(null)),N.addEventListener("click",()=>ew(!0)),U.addEventListener("click",()=>ew(!1)),S.addEventListener("click",()=>eu(!1)),A.addEventListener("click",()=>eu(!0)),D.addEventListener("click",()=>ev(!er)),I.addEventListener("input",ed),I.addEventListener("keydown",e=>{"Enter"!==e.key||e.isComposing?"Escape"===e.key&&ex(!1):(e.preventDefault(),g.focus())}),z.addEventListener("input",()=>{ei=0,ef()}),z.addEventListener("keydown",e=>{let t=F.children.length;if("ArrowDown"===e.key||"ArrowUp"===e.key){if(e.preventDefault(),0===t)return;ei=(ei+("ArrowDown"===e.key?1:-1)+t)%t,ef()}else if("Enter"!==e.key||e.isComposing)"Escape"===e.key&&(e.preventDefault(),ev(!1));else{e.preventDefault();let t=em()[ei];t&&ey(t)}}),x.addEventListener("click",()=>{G=null,t.undo()}),J.addEventListener("submit",e=>{e.preventDefault(),eh()}),g.addEventListener("input",()=>{ec(),ed()}),g.addEventListener("keydown",e=>{"Enter"!==e.key||e.shiftKey||e.isComposing?"Escape"===e.key&&ex(!1):(e.preventDefault(),eh())});let eE=t.on("change",el);return ed(),e.body.appendChild(o),()=>{eE(),eg(),o.remove()}},S="https://content.obelism.studio",A=(e,t)=>JSON.stringify(e)===JSON.stringify(t),L=Symbol.for("@obelism/content/bridge"),N=v({isEditing:!1,entryId:null,on:()=>{}},new URLSearchParams),U=({url:e,prompt:d=!0,pagePath:u}={})=>{let h;if("u"<typeof window)return N;let y=window;if(y[L])return y[L];if(y.ObelismBridge)h=v(y.ObelismBridge,new URLSearchParams(y.location.search));else{let v=(h=((e,r)=>{let d=new URLSearchParams(e.location.search),u=e.parent!==e&&d.has("cms_preview"),h=g(),v=[],y={...p,selecting:!0},x=e=>{y={...y,...e},h.emit("change",y)},w={isEditing:u,mode:u?"editor":null,entryId:d.get("cms_entry"),environment:d.get(n),on:h.on,getState:()=>y,...b,destroy:()=>{v.splice(0).forEach(e=>e())}};if(!u)return w;let k=e.document,E=(t,n={})=>{e.parent.postMessage({source:l,type:t,...n},r)},C=k.createElement("style");C.textContent=c(),k.head.appendChild(C),v.push(()=>C.remove());let S=(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(f(e));r&&(r.setAttribute("data-cms-selected",""),t&&r.scrollIntoView({behavior:"smooth",block:"center"}))},A=e=>{let r=e.target,n=r?.closest?.(`[${t}]`);if(!n)return;e.preventDefault(),e.stopPropagation();let o=n.getAttribute(t);S(o,!1),E("select",{uid:o})};k.addEventListener("click",A,!0),v.push(()=>k.removeEventListener("click",A,!0));let L=()=>E("ready",{url:e.location.href}),N=new Map,U=0,P=e=>{let t=N.get(e);return t?(clearTimeout(t.timer),N.delete(e),0===N.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_${++U}`,o=void 0===t.uid?y.selectedUid:t.uid;return new Promise((e,t)=>{let a=setTimeout(()=>{P(n)?.reject(Error("The editor did not answer in time"))},12e4);N.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=>{S(e,!1),E("select",{uid:e})};let I=null;v.push(()=>I?.destroy()),v.push(()=>{for(let e of N.keys())P(e)?.reject(Error("The bridge was destroyed"))});let $=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(()=>S(n.selectedUid,!1)),I?.refresh();else if("select"===n.type)S(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??{};m(e)&&m(o)&&m(a)&&m(i)&&(t[r]={clicks:e,clickers:o,viewers:a,rate:i})}return t})(n.stats),statsVisible:!1!==n.visible}),(I||Object.keys(y.stats).length)&&(I??(I=((e,{selector:t,onSelect:r,labels:n})=>{let l=e.document,d={...o,...n},c=l.createElement("div");c.setAttribute("data-obelism-stats","");let p=c.attachShadow({mode:"open"}),g=l.createElement("style");g.textContent=i;let u=l.createElement("div");u.className="layer",p.append(g,u),l.body.appendChild(c);let h={},b=!1,m=null,f=()=>{if(m=null,u.replaceChildren(),u.hidden=!b,!b)return;let n=e.innerHeight;for(let[o,i]of Object.entries(h)){let c=l.querySelector(t(o));if(!c)continue;let p=c.getBoundingClientRect();if(!p.width&&!p.height||p.bottom<0||p.top>n)continue;let g=l.createElement("button");g.type="button",g.className="badge",g.dataset.uid=o,g.textContent=a(d.clicked,{rate:Math.round(100*i.rate)}),g.title=a(d.title,{clickers:i.clickers,viewers:i.viewers,clicks:i.clicks});let{place:h,top:b,left:m}=s(p,e.innerWidth);g.dataset.place=h,g.style.top=`${b}px`,g.style.left=`${m}px`,g.addEventListener("click",()=>r(o)),u.appendChild(g)}},v=()=>{null===m&&b&&(m=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(l.body,{childList:!0,subtree:!0}),{update(t,r){h=t,b=r,null!==m&&(e.cancelAnimationFrame?.(m),m=null),f()},refresh:v,destroy(){null!==m&&e.cancelAnimationFrame?.(m),e.removeEventListener("scroll",v,{capture:!0}),e.removeEventListener("resize",v),x?.disconnect(),c.remove()}}})(e,{selector:f,onSelect:e=>w.select(e)})),I.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=P(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",$),v.push(()=>e.removeEventListener("message",$)),"loading"===k.readyState?(k.addEventListener("DOMContentLoaded",L,{once:!0}),v.push(()=>k.removeEventListener("DOMContentLoaded",L))):L(),w})(y,new URL(e||S).origin)).isEditing||y.parent!==y?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})(y.document);if(v&&(h=((e,n,{pagePath:o=e=>`/${e}`}={})=>{let a=e.document,i=g(),s=[],d=new Map,u=[],h=new Set,b=null,m=null,v=-1/0,y=new Map,x=p,w=e=>{x={...x,...e},i.emit("change",x)},k=()=>w({unsaved:[...d.values()].some(({content:e,saved:t})=>!A(e,t)),canUndo:u.length>0}),E=async(t,r)=>{let o=await e.fetch(`${n}/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 o.json().catch(()=>({}));if(401===o.status)throw w({features:[]}),Error("You were signed out. Sign in again to edit.");if(!o.ok)throw Error("string"==typeof a.error?a.error:`Obelism Content answered ${o.status}`);return a},C=()=>a.querySelector(`[${r}]`)?.getAttribute(r)??null,S=e=>{let t=e?a.querySelector(f(e)):null;return t?.closest(`[${r}]`)?.getAttribute(r)??C()},L=()=>{if(!b)return;let e=b.space.locales.map(({code:e})=>e),t=a.documentElement.lang;if(e.includes(t))return t;let r=t.split("-")[0]??"";return e.includes(r)?r:b.space.defaultLocale},N=new Map,U=async e=>{let t=d.get(e);if(t)return t;let r=N.get(e);return r||(r=E(`entries/${encodeURIComponent(e)}`).then(t=>{let r=d.get(e)??{content:t.content,saved:t.content,revision:t.draftRevision};return d.set(e,r),r}).finally(()=>N.delete(e)),N.set(e,r)),r},P=e=>{let t=void 0===e?x.selectedUid:e,r=S(t);if(!r)throw Error("Nothing on this page is marked as an entry: add editable(entry)");return{uid:t,entryId:r}},I=e=>{a.querySelectorAll("[data-cms-selected]").forEach(e=>{e.removeAttribute("data-cms-selected")}),x.selectedUid!==e&&w({selectedUid:e}),e&&a.querySelector(f(e))?.setAttribute("data-cms-selected","")},$=async t=>{if(0===i.listeners.update.size)return;let r=d.get(t)?.content,{entry:n}=await E(`entries/${encodeURIComponent(t)}/preview`,{content:r,locale:L()});i.emit("update",{entry:n,selectedUid:x.selectedUid}),e.requestAnimationFrame(()=>I(x.selectedUid))},M=e=>console.error("[@obelism/content bridge]",e),O=t=>{i.emit(t,{}),0===i.listeners.update.size&&e.location.reload()},T=async()=>{for(let[e,t]of d){if(A(t.content,t.saved))continue;let{draftRevision:r}=await E(`entries/${encodeURIComponent(e)}/save`,{content:t.content,baseRevision:t.revision});t.saved=t.content,t.revision=r,h.add(e)}u.length=0,v=-1/0,k()},j={isEditing:!0,mode:"site",get entryId(){return C()},environment:null,on:i.on,getState:()=>x,async prompt(e,t={}){let r=e.trim();if(!r)throw Error("Say what to change");if(!x.features.includes("prompt"))throw Error("You may not edit content here");let{uid:n,entryId:o}=P(t.uid);w({prompting:!0});try{let e=await U(o),t=await E(`entries/${encodeURIComponent(o)}/prompt`,{prompt:r,content:e.content,locale:L(),uid:n});return u.push({entryId:o,content:e.content}),v=-1/0,e.content=t.content,k(),await $(o),{summary:t.summary}}finally{w({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(!x.features.includes("create"))throw Error("You may not add pages here");if(x.unsaved)throw Error("Save or undo your changes before adding a page");w({prompting:!0});try{let r=await E("entries",{path:t,prompt:n,locale:L(),from:C()}),a=o(r.path,L()??"");return e.location.assign(a),{summary:r.summary,entryId:r.entryId,path:r.path,url:a}}finally{w({prompting:!1})}},async view(e={}){let{uid:t,entryId:r}=P(e.uid),n=await U(r),{view:o}=await E(`entries/${encodeURIComponent(r)}/view`,{content:n.content,locale:L(),uid:t});return o},async applyJson(e,t={}){if(!x.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}=P(t.uid);w({prompting:!0});try{let t=await U(n),o=await E(`entries/${encodeURIComponent(n)}/apply`,{changes:e,content:t.content,locale:L(),uid:r});return A(o.content,t.content)||(u.push({entryId:n,content:t.content}),v=-1/0,t.content=o.content,k(),await $(n)),{changed:o.changed??[],...o.view&&{view:o.view}}}finally{w({prompting:!1})}},openForm(t,r={}){let{title:n="Content form",onReady:o,onError:a}=r;m?.();let s=!1,c=null,p=null,g=()=>{},h=e=>{s||a?.(e instanceof Error?e.message:String(e))},b=()=>{s||(s=!0,g(),c?.destroy(),m===b&&(m=null))};m=b;let f=()=>{if(s||!c)return;let e=S(x.selectedUid);if(!e)return;let t=d.get(e);if(!t)return void U(e).then(f,h);let r={entryId:e,content:t.content,locale:L(),selectedUid:x.selectedUid};p&&p.entryId===r.entryId&&p.content===r.content&&p.locale===r.locale&&p.selectedUid===r.selectedUid||(p=r,c.show(r))},w=(e,t)=>{let r=t??p?.entryId,n=void 0===r?void 0:d.get(r);if(s||void 0===r||!n||A(e,n.content))return;let o=Date.now();o-v>=1e3&&u.push({entryId:r,content:n.content}),v=o,n.content=e,p?.entryId===r&&(p={...p,content:e}),k(),clearTimeout(y.get(r)),y.set(r,setTimeout(()=>{y.delete(r),$(r).catch(M)},300))};return(async()=>{if(!x.features.includes("form"))throw Error("You may not edit content here");await U(P(void 0).entryId);let{url:r}=await E("form",{});s||(c=((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 d=!1,c=null,p=()=>{d&&c&&s.contentWindow?.postMessage({source:l,type:"content",...c},i)},g=setTimeout(()=>{d||o.onError("The form did not open")},3e4),u=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)d=!0,clearTimeout(g),o.onReady(),p();else{let e;"change"!==t.type||!(e=t.content)||"object"!=typeof e||Array.isArray(e)?"error"===t.type&&o.onError("string"==typeof t.message&&t.message?t.message:"The form failed"):o.onChange(t.content,"string"==typeof t.entryId?t.entryId:void 0)}};return e.addEventListener("message",u),t.appendChild(s),{show(e){c=e,p()},destroy(){clearTimeout(g),e.removeEventListener("message",u),s.remove()}}})(e,t,"string"==typeof r?r:"",n,{onReady:()=>o?.(),onChange:w,onError:e=>a?.(e)}),g=i.on("change",f),f())})().catch(h),{close:b}},async pages(){let{pages:e}=await E("pages"),t=[L(),b?.space.defaultLocale];return e.flatMap(e=>{let r=t.find(t=>void 0!==t&&void 0!==e.paths[t])??Object.keys(e.paths)[0],n=void 0===r?void 0:e.paths[r];return void 0===r||void 0===n?[]:[{entryId:e.entryId,name:e.name,contentType:e.contentType,status:e.status,path:n,url:o(n,r)}]})},openPage(t){(!x.unsaved||e.confirm("Leave this page and lose the changes you have not saved?"))&&(d.clear(),u.length=0,k(),e.location.assign(t.url))},undo(){let e=u.pop(),t=e&&d.get(e.entryId);e&&t&&(v=-1/0,t.content=e.content,k(),$(e.entryId).catch(M))},async save(){if(!x.features.includes("save"))throw Error("You may not edit content here");w({saving:!0});try{await T()}finally{w({saving:!1})}O("saved")},async publish(){if(!x.features.includes("publish"))throw Error("You may not publish here");w({publishing:!0});try{await T();let e=C(),t=h.size>0?[...h]: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 E(`entries/${encodeURIComponent(e)}/publish`,{}),h.delete(e)}finally{w({publishing:!1})}O("published")},signOut(){if(x.unsaved&&!e.confirm("Sign out and lose the changes you have not saved?"))return;d.clear(),k();let t=e.location.pathname+e.location.search;e.location.href=`${n}/logout?return_to=${encodeURIComponent(t)}`},select(e){I(e)},setSelecting(e){e?a.documentElement.setAttribute("data-cms-selecting",""):a.documentElement.removeAttribute("data-cms-selecting"),w({selecting:e})},destroy(){m?.(),y.forEach(e=>clearTimeout(e)),y.clear(),s.splice(0).forEach(e=>e())}},R=a.createElement("style");R.textContent=c("html[data-cms-selecting] "),a.head.appendChild(R),s.push(()=>R.remove()),s.push(()=>a.documentElement.removeAttribute("data-cms-selecting"));let D=e=>{if(!x.selecting)return;let r=e.target,n=r?.closest?.(`[${t}]`);n&&(e.preventDefault(),e.stopPropagation(),I(n.getAttribute(t)))};a.addEventListener("click",D,!0),s.push(()=>a.removeEventListener("click",D,!0));let z=e=>{x.unsaved&&(e.preventDefault(),e.returnValue="")};return e.addEventListener("beforeunload",z),s.push(()=>e.removeEventListener("beforeunload",z)),E("session").then(e=>{b=e,w({features:e.features})}).catch(e=>console.error("[@obelism/content bridge]",e)),j})(y,v,{pagePath:u})),h.isEditing&&d){let e=C(y.document,h,!0===d?{}:d),t=h.destroy;h.destroy=()=>{e(),t()}}}return y[L]=h,h};(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:C}}();
|
|
236
|
+
`,k=(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},E=(e,t)=>{let r=k(e,"span",{className:"icon"});return r.setAttribute("aria-hidden","true"),r.innerHTML=`<svg viewBox="0 0 24 24">${x[t]}</svg>`,r},C=(e,t,r={})=>{let n={...y,...r.labels},o=k(e,"div");o.setAttribute("data-obelism-content-prompt","");let a=o.attachShadow({mode:"open"}),i="site"===t.mode,s=k(e,"span",{textContent:n.open}),l=k(e,"button",{className:"pill",type:"button"},s,k(e,"span",{className:"mark",textContent:"⁜"})),d=k(e,"span",{className:"pill compact"},`${n.viewingDrafts} \xb7 `),c=k(e,"button",{className:"link",type:"button",textContent:n.signOut});d.appendChild(c);let p=k(e,"p",{className:"status"});p.setAttribute("role","status");let g=k(e,"textarea",{placeholder:n.placeholder,rows:1});g.setAttribute("aria-label",n.open);let u=k(e,"div",{className:"form"}),h=E(e,"page"),b=E(e,"block"),m=k(e,"span"),f=k(e,"button",{type:"button",title:n.clearBlock});f.setAttribute("aria-label",n.clearBlock),f.appendChild(E(e,"close"));let v=k(e,"span",{className:"chip scope"},h,b,m,f),x=k(e,"button",{className:"action chip",type:"button"},E(e,"undo"),n.undo),C=t=>{let r=k(e,"button",{type:"button",textContent:t});return r.setAttribute("aria-pressed","false"),r},A=C(n.modePrompt),S=C(n.form),L=k(e,"span",{className:"modes"},A,S);L.setAttribute("role","group"),L.setAttribute("aria-label",n.modes);let N=k(e,"button",{className:"action chip",type:"button"},E(e,"newPage"),n.newPage),U=k(e,"button",{type:"button",title:n.newPageCancel});U.setAttribute("aria-label",n.newPageCancel),U.appendChild(E(e,"close"));let P=k(e,"span",{className:"chip scope"},E(e,"newPage"),k(e,"span",{textContent:n.newPage}),U),I=k(e,"input",{type:"text",placeholder:n.pathPlaceholder,autocomplete:"off",spellcheck:!1}),$=k(e,"label",{className:"path"},k(e,"span",{textContent:n.path}),I),M=k(e,"button",{className:"close icon-button",type:"button",title:n.close},E(e,"close"));M.setAttribute("aria-label",n.close);let O=E(e,"minimize"),T=E(e,"expand"),z=k(e,"button",{className:"icon-button",type:"button"},O,T),j=k(e,"button",{className:"action primary icon-button",type:"submit"},k(e,"span",{className:"visually-hidden",textContent:n.send}),E(e,"send"));j.title=n.send;let R=k(e,"span",{className:"divider"}),D=k(e,"div",{className:"toolbar"},v,P,L,x,N,k(e,"span",{className:"spacer"}),z,M,R,j),F=k(e,"span",{textContent:n.pages}),q=k(e,"button",{className:"chip page-chip",type:"button",title:n.pages},E(e,"page"),F,E(e,"chevrons"));q.setAttribute("aria-haspopup","listbox"),q.setAttribute("aria-expanded","false"),q.setAttribute("aria-controls","obelism-pages");let B=k(e,"input",{type:"text",placeholder:n.pagesSearch,autocomplete:"off",spellcheck:!1});B.setAttribute("role","combobox"),B.setAttribute("aria-label",n.pagesSearch),B.setAttribute("aria-autocomplete","list"),B.setAttribute("aria-expanded","true"),B.setAttribute("aria-controls","obelism-pages");let V=k(e,"ul",{className:"options",id:"obelism-pages"});V.setAttribute("role","listbox"),V.setAttribute("aria-label",n.pages);let Y=k(e,"p",{className:"empty"}),H=k(e,"div",{className:"pages"},k(e,"label",{className:"search"},E(e,"search"),B),V,Y),W=k(e,"span",{className:"unsaved"});W.appendChild(k(e,"span",{className:"dot"})),W.appendChild(e.createTextNode(n.unsaved));let _=k(e,"button",{className:"link",type:"button",textContent:n.signOut}),J=k(e,"button",{className:"action chip",type:"button",textContent:n.save}),X=k(e,"button",{className:"action chip",type:"button",textContent:n.publish}),Z=k(e,"div",{className:"footer"},q,W,k(e,"span",{className:"spacer"}),_,J,X),K=k(e,"form",{className:"panel"},p,$,g,u,D,H,Z),G=k(e,"div",{className:"root"},k(e,"div",{className:"bar"},l,d),K);a.append(k(e,"style",{textContent:w}),G);let Q=!1,ee=!1,et=!1,er=null,en=!1,eo=null,ea=!1,ei=!1,es=null,el=null,ed=null,ec=0,ep=e=>({text:e instanceof Error?e.message:String(e),error:!0}),eg=e=>{let r=e.features.includes("prompt"),o=e.saving||e.publishing,a=e.prompting||o;G.hidden=!r&&!i,l.hidden=Q||!r,d.hidden=r||!i,K.hidden=!Q||!r;let c=i&&e.features.includes("create"),y=i&&null===t.entryId,w=y&&c;c||(et=!1),w&&(et=!0),(et||y||!i)&&(en=!1);let k=Q&&r&&en;k&&!eo?eb():!k&&eo&&em(),s.textContent=w?n.newPage:n.open,U.hidden=w,v.hidden=et,P.hidden=!et,N.hidden=et||en||!c,N.disabled=a,ee&&(ei=!1),$.hidden=!et||ei||ee,I.disabled=a,g.hidden=en||ei||ee,u.hidden=!en||ei||ee,u.classList.toggle("loading",ea),D.hidden=ei,H.hidden=!ei,g.placeholder=et?n.newPagePlaceholder:n.placeholder,m.textContent=e.selectedUid?n.scopeBlock:n.scopeEntry,f.hidden=!e.selectedUid,h.hidden=!!e.selectedUid,b.hidden=!e.selectedUid,L.hidden=!i||et||y||!e.features.includes("form"),A.setAttribute("aria-pressed",String(!en)),S.setAttribute("aria-pressed",String(en)),L.querySelectorAll("button").forEach(e=>{e.disabled=a}),x.hidden=et||!e.canUndo,x.disabled=a,j.hidden=en||ee,R.hidden=en||ee;let E=ee?n.expand:n.minimize;z.title=E,z.setAttribute("aria-label",E),z.setAttribute("aria-expanded",String(!ee)),O.hidden=ee,T.hidden=!ee,j.disabled=a||""===g.value.trim()||et&&""===I.value.trim(),g.disabled=a,J.hidden=!e.features.includes("save")||y,J.disabled=a||!e.unsaved,J.textContent=e.saving?n.saving:n.save,X.hidden=!e.features.includes("publish")||y,X.disabled=a,X.textContent=e.publishing?n.publishing:n.publish,_.hidden=!i,Z.hidden=!i,W.hidden=!e.unsaved,q.hidden=!i,q.setAttribute("aria-expanded",String(ei)),F.textContent=es?.find(({entryId:e})=>e===t.entryId)?.name??n.pages;let C=en&&ea&&!ei,M=e.prompting||C,B=e.prompting?et?n.creating:n.working:C?n.formLoading:er?.text??(!i||et||ei||e.selectedUid?"":n.selectHint);p.textContent=B,p.hidden=!B||ee,p.className=`status${M?" working":""}${!a&&!C&&er?.error?" error":""}`},eu=()=>eg(t.getState()),eh=()=>{g.style.height="auto",g.style.height=`${g.scrollHeight}px`},eb=()=>{ea=!0,u.classList.add("loading");let e=t.openForm(u,{title:n.formTitle,onReady:()=>{eo===e&&(ea=!1,er=null,eu())},onError:t=>{eo===e&&(ea=!1,er={text:t,error:!0},eu())}});eo=e},em=()=>{eo?.close(),eo=null,ea=!1},ef=e=>{en!==e&&(en=e,er=null,eu(),en||g.focus())},ev=async()=>{if(en)return;let e=g.value.trim();if(e&&!t.getState().prompting){er=null;try{if(et){let r=I.value.trim();if(!r)return I.focus();await t.createPage(r,e),es=null,el=null,er={text:n.created,error:!1}}else{let{summary:r}=await t.prompt(e);er={text:r,error:!1}}g.value="",eh()}catch(e){er=ep(e)}eu(),g.focus()}},ey=()=>(el??(el=t.pages().then(e=>{es=e,ed=null,ew(),eu()},e=>{el=null,ed=ep(e).text,ew()})),el),ex=()=>{let e=B.value.trim().toLowerCase();return(es??[]).filter(t=>!e||t.name.toLowerCase().includes(e)||t.url.toLowerCase().includes(e)||`/${t.path}`.toLowerCase().includes(e))},ew=()=>{let r=ex();ec=Math.max(0,Math.min(ec,r.length-1)),V.textContent="",r.forEach((r,o)=>{let a=r.entryId===t.entryId,i=k(e,"li",{className:`option${o===ec?" active":""}`,id:`obelism-page-${o}`},k(e,"span",{className:"option-text"},k(e,"span",{textContent:r.name}),k(e,"span",{className:"option-path",textContent:r.url})));if(i.setAttribute("role","option"),i.setAttribute("aria-selected",String(o===ec)),"published"!==r.status&&i.appendChild(k(e,"span",{className:"badge",textContent:"draft"===r.status?n.pageDraft:n.pageChanged})),a){i.setAttribute("aria-current","page");let t=E(e,"check");t.removeAttribute("aria-hidden"),t.setAttribute("role","img"),t.setAttribute("aria-label",n.pageCurrent),i.appendChild(t)}i.addEventListener("click",()=>eE(r)),V.appendChild(i)});let o=V.children[ec];o?(B.setAttribute("aria-activedescendant",o.id),o.scrollIntoView?.({block:"nearest"})):B.removeAttribute("aria-activedescendant"),Y.textContent=(ed??(es?"":n.pagesLoading))||(0===r.length?n.pagesEmpty:""),Y.hidden=!Y.textContent,Y.className=`empty${ed?" error":""}`},ek=e=>{er=null,(ei=e)&&(B.value="",ec=Math.max(0,(es??[]).findIndex(({entryId:e})=>e===t.entryId)),ey(),ew()),eu(),(ei?B:q).focus()},eE=e=>{if(e.entryId===t.entryId)return ek(!1);t.openPage(e)},eC=e=>{(Q=e)||(ei=!1,ee=!1),eu(),i&&t.setSelecting(Q&&!et),Q&&i&&ey()},eA=e=>{et=e,er=null,t.setSelecting(Q&&!et),et&&t.select(null),eu(),(et?I:g).focus()},eS=async e=>{er=null;try{await t[e](),er={text:"save"===e?n.saved:n.published,error:!1}}catch(e){er=ep(e)}eu()};l.addEventListener("click",()=>{eC(!0),en||(et?I:g).focus()}),M.addEventListener("click",()=>eC(!1)),z.addEventListener("click",()=>{ee=!ee,eu(),ee||(en?z:g).focus()}),J.addEventListener("click",()=>void eS("save")),X.addEventListener("click",()=>void eS("publish")),_.addEventListener("click",()=>t.signOut()),c.addEventListener("click",()=>t.signOut()),f.addEventListener("click",()=>t.select(null)),N.addEventListener("click",()=>eA(!0)),U.addEventListener("click",()=>eA(!1)),A.addEventListener("click",()=>ef(!1)),S.addEventListener("click",()=>ef(!0)),q.addEventListener("click",()=>ek(!ei)),I.addEventListener("input",eu),I.addEventListener("keydown",e=>{"Enter"!==e.key||e.isComposing?"Escape"===e.key&&eC(!1):(e.preventDefault(),g.focus())}),B.addEventListener("input",()=>{ec=0,ew()}),B.addEventListener("keydown",e=>{let t=V.children.length;if("ArrowDown"===e.key||"ArrowUp"===e.key){if(e.preventDefault(),0===t)return;ec=(ec+("ArrowDown"===e.key?1:-1)+t)%t,ew()}else if("Enter"!==e.key||e.isComposing)"Escape"===e.key&&(e.preventDefault(),ek(!1));else{e.preventDefault();let t=ex()[ec];t&&eE(t)}}),x.addEventListener("click",()=>{er=null,t.undo()}),K.addEventListener("submit",e=>{e.preventDefault(),ev()}),g.addEventListener("input",()=>{eh(),eu()}),g.addEventListener("keydown",e=>{"Enter"!==e.key||e.shiftKey||e.isComposing?"Escape"===e.key&&eC(!1):(e.preventDefault(),ev())});let eL=t.on("change",eg);return eu(),e.body.appendChild(o),()=>{eL(),em(),o.remove()}},A="https://content.obelism.studio",S=(e,t)=>JSON.stringify(e)===JSON.stringify(t),L=Symbol.for("@obelism/content/bridge"),N=v({isEditing:!1,entryId:null,on:()=>{}},new URLSearchParams),U=({url:e,prompt:d=!0,pagePath:u}={})=>{let h;if("u"<typeof window)return N;let y=window;if(y[L])return y[L];if(y.ObelismBridge)h=v(y.ObelismBridge,new URLSearchParams(y.location.search));else{let v=(h=((e,r)=>{let d=new URLSearchParams(e.location.search),u=e.parent!==e&&d.has("cms_preview"),h=g(),v=[],y={...p,selecting:!0},x=e=>{y={...y,...e},h.emit("change",y)},w={isEditing:u,mode:u?"editor":null,entryId:d.get("cms_entry"),environment:d.get(n),on:h.on,getState:()=>y,...b,destroy:()=>{v.splice(0).forEach(e=>e())}};if(!u)return w;let k=e.document,E=(t,n={})=>{e.parent.postMessage({source:l,type:t,...n},r)},C=k.createElement("style");C.textContent=c(),k.head.appendChild(C),v.push(()=>C.remove());let A=(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(f(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);A(o,!1),E("select",{uid:o})};k.addEventListener("click",S,!0),v.push(()=>k.removeEventListener("click",S,!0));let L=()=>E("ready",{url:e.location.href}),N=new Map,U=0,P=e=>{let t=N.get(e);return t?(clearTimeout(t.timer),N.delete(e),0===N.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_${++U}`,o=void 0===t.uid?y.selectedUid:t.uid;return new Promise((e,t)=>{let a=setTimeout(()=>{P(n)?.reject(Error("The editor did not answer in time"))},12e4);N.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=>{A(e,!1),E("select",{uid:e})};let I=null;v.push(()=>I?.destroy()),v.push(()=>{for(let e of N.keys())P(e)?.reject(Error("The bridge was destroyed"))});let $=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(()=>A(n.selectedUid,!1)),I?.refresh();else if("select"===n.type)A(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??{};m(e)&&m(o)&&m(a)&&m(i)&&(t[r]={clicks:e,clickers:o,viewers:a,rate:i})}return t})(n.stats),statsVisible:!1!==n.visible}),(I||Object.keys(y.stats).length)&&(I??(I=((e,{selector:t,onSelect:r,labels:n})=>{let l=e.document,d={...o,...n},c=l.createElement("div");c.setAttribute("data-obelism-stats","");let p=c.attachShadow({mode:"open"}),g=l.createElement("style");g.textContent=i;let u=l.createElement("div");u.className="layer",p.append(g,u),l.body.appendChild(c);let h={},b=!1,m=null,f=()=>{if(m=null,u.replaceChildren(),u.hidden=!b,!b)return;let n=e.innerHeight;for(let[o,i]of Object.entries(h)){let c=l.querySelector(t(o));if(!c)continue;let p=c.getBoundingClientRect();if(!p.width&&!p.height||p.bottom<0||p.top>n)continue;let g=l.createElement("button");g.type="button",g.className="badge",g.dataset.uid=o,g.textContent=a(d.clicked,{rate:Math.round(100*i.rate)}),g.title=a(d.title,{clickers:i.clickers,viewers:i.viewers,clicks:i.clicks});let{place:h,top:b,left:m}=s(p,e.innerWidth);g.dataset.place=h,g.style.top=`${b}px`,g.style.left=`${m}px`,g.addEventListener("click",()=>r(o)),u.appendChild(g)}},v=()=>{null===m&&b&&(m=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(l.body,{childList:!0,subtree:!0}),{update(t,r){h=t,b=r,null!==m&&(e.cancelAnimationFrame?.(m),m=null),f()},refresh:v,destroy(){null!==m&&e.cancelAnimationFrame?.(m),e.removeEventListener("scroll",v,{capture:!0}),e.removeEventListener("resize",v),x?.disconnect(),c.remove()}}})(e,{selector:f,onSelect:e=>w.select(e)})),I.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=P(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",$),v.push(()=>e.removeEventListener("message",$)),"loading"===k.readyState?(k.addEventListener("DOMContentLoaded",L,{once:!0}),v.push(()=>k.removeEventListener("DOMContentLoaded",L))):L(),w})(y,new URL(e||A).origin)).isEditing||y.parent!==y?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})(y.document);if(v&&(h=((e,n,{pagePath:o=e=>`/${e}`}={})=>{let a=e.document,i=g(),s=[],d=new Map,u=[],h=new Set,b=null,m=null,v=-1/0,y=new Map,x=p,w=e=>{x={...x,...e},i.emit("change",x)},k=()=>w({unsaved:[...d.values()].some(({content:e,saved:t})=>!S(e,t)),canUndo:u.length>0}),E=async(t,r)=>{let o=await e.fetch(`${n}/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 o.json().catch(()=>({}));if(401===o.status)throw w({features:[]}),Error("You were signed out. Sign in again to edit.");if(!o.ok)throw Error("string"==typeof a.error?a.error:`Obelism Content answered ${o.status}`);return a},C=()=>a.querySelector(`[${r}]`)?.getAttribute(r)??null,A=e=>{let t=e?a.querySelector(f(e)):null;return t?.closest(`[${r}]`)?.getAttribute(r)??C()},L=()=>{if(!b)return;let e=b.space.locales.map(({code:e})=>e),t=a.documentElement.lang;if(e.includes(t))return t;let r=t.split("-")[0]??"";return e.includes(r)?r:b.space.defaultLocale},N=new Map,U=async e=>{let t=d.get(e);if(t)return t;let r=N.get(e);return r||(r=E(`entries/${encodeURIComponent(e)}`).then(t=>{let r=d.get(e)??{content:t.content,saved:t.content,revision:t.draftRevision};return d.set(e,r),r}).finally(()=>N.delete(e)),N.set(e,r)),r},P=e=>{let t=void 0===e?x.selectedUid:e,r=A(t);if(!r)throw Error("Nothing on this page is marked as an entry: add editable(entry)");return{uid:t,entryId:r}},I=e=>{a.querySelectorAll("[data-cms-selected]").forEach(e=>{e.removeAttribute("data-cms-selected")}),x.selectedUid!==e&&w({selectedUid:e}),e&&a.querySelector(f(e))?.setAttribute("data-cms-selected","")},$=async t=>{if(0===i.listeners.update.size)return;let r=d.get(t)?.content,{entry:n}=await E(`entries/${encodeURIComponent(t)}/preview`,{content:r,locale:L()});i.emit("update",{entry:n,selectedUid:x.selectedUid}),e.requestAnimationFrame(()=>I(x.selectedUid))},M=e=>console.error("[@obelism/content bridge]",e),O=t=>{i.emit(t,{}),0===i.listeners.update.size&&e.location.reload()},T=async()=>{for(let[e,t]of d){if(S(t.content,t.saved))continue;let{draftRevision:r}=await E(`entries/${encodeURIComponent(e)}/save`,{content:t.content,baseRevision:t.revision});t.saved=t.content,t.revision=r,h.add(e)}u.length=0,v=-1/0,k()},z={isEditing:!0,mode:"site",get entryId(){return C()},environment:null,on:i.on,getState:()=>x,async prompt(e,t={}){let r=e.trim();if(!r)throw Error("Say what to change");if(!x.features.includes("prompt"))throw Error("You may not edit content here");let{uid:n,entryId:o}=P(t.uid);w({prompting:!0});try{let e=await U(o),t=await E(`entries/${encodeURIComponent(o)}/prompt`,{prompt:r,content:e.content,locale:L(),uid:n});return u.push({entryId:o,content:e.content}),v=-1/0,e.content=t.content,k(),await $(o),{summary:t.summary}}finally{w({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(!x.features.includes("create"))throw Error("You may not add pages here");if(x.unsaved)throw Error("Save or undo your changes before adding a page");w({prompting:!0});try{let r=await E("entries",{path:t,prompt:n,locale:L(),from:C()}),a=o(r.path,L()??"");return e.location.assign(a),{summary:r.summary,entryId:r.entryId,path:r.path,url:a}}finally{w({prompting:!1})}},async view(e={}){let{uid:t,entryId:r}=P(e.uid),n=await U(r),{view:o}=await E(`entries/${encodeURIComponent(r)}/view`,{content:n.content,locale:L(),uid:t});return o},async applyJson(e,t={}){if(!x.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}=P(t.uid);w({prompting:!0});try{let t=await U(n),o=await E(`entries/${encodeURIComponent(n)}/apply`,{changes:e,content:t.content,locale:L(),uid:r});return S(o.content,t.content)||(u.push({entryId:n,content:t.content}),v=-1/0,t.content=o.content,k(),await $(n)),{changed:o.changed??[],...o.view&&{view:o.view}}}finally{w({prompting:!1})}},openForm(t,r={}){let{title:n="Content form",onReady:o,onError:a}=r;m?.();let s=!1,c=null,p=null,g=()=>{},h=e=>{s||a?.(e instanceof Error?e.message:String(e))},b=()=>{s||(s=!0,g(),c?.destroy(),m===b&&(m=null))};m=b;let f=()=>{if(s||!c)return;let e=A(x.selectedUid);if(!e)return;let t=d.get(e);if(!t)return void U(e).then(f,h);let r={entryId:e,content:t.content,locale:L(),selectedUid:x.selectedUid};p&&p.entryId===r.entryId&&p.content===r.content&&p.locale===r.locale&&p.selectedUid===r.selectedUid||(p=r,c.show(r))},w=(e,t)=>{let r=t??p?.entryId,n=void 0===r?void 0:d.get(r);if(s||void 0===r||!n||S(e,n.content))return;let o=Date.now();o-v>=1e3&&u.push({entryId:r,content:n.content}),v=o,n.content=e,p?.entryId===r&&(p={...p,content:e}),k(),clearTimeout(y.get(r)),y.set(r,setTimeout(()=>{y.delete(r),$(r).catch(M)},300))};return(async()=>{if(!x.features.includes("form"))throw Error("You may not edit content here");await U(P(void 0).entryId);let{url:r}=await E("form",{});s||(c=((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 d=!1,c=null,p=()=>{d&&c&&s.contentWindow?.postMessage({source:l,type:"content",...c},i)},g=setTimeout(()=>{d||o.onError("The form did not open")},3e4),u=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)d=!0,clearTimeout(g),o.onReady(),p();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",u),t.appendChild(s),{show(e){c=e,p()},destroy(){clearTimeout(g),e.removeEventListener("message",u),s.remove()}}})(e,t,"string"==typeof r?r:"",n,{onReady:()=>o?.(),onChange:w,onError:e=>a?.(e)}),g=i.on("change",f),f())})().catch(h),{close:b}},async pages(){let{pages:e}=await E("pages"),t=[L(),b?.space.defaultLocale];return e.flatMap(e=>{let r=t.find(t=>void 0!==t&&void 0!==e.paths[t])??Object.keys(e.paths)[0],n=void 0===r?void 0:e.paths[r];return void 0===r||void 0===n?[]:[{entryId:e.entryId,name:e.name,contentType:e.contentType,status:e.status,path:n,url:o(n,r)}]})},openPage(t){(!x.unsaved||e.confirm("Leave this page and lose the changes you have not saved?"))&&(d.clear(),u.length=0,k(),e.location.assign(t.url))},undo(){let e=u.pop(),t=e&&d.get(e.entryId);e&&t&&(v=-1/0,t.content=e.content,k(),$(e.entryId).catch(M))},async save(){if(!x.features.includes("save"))throw Error("You may not edit content here");w({saving:!0});try{await T()}finally{w({saving:!1})}O("saved")},async publish(){if(!x.features.includes("publish"))throw Error("You may not publish here");w({publishing:!0});try{await T();let e=C(),t=h.size>0?[...h]: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 E(`entries/${encodeURIComponent(e)}/publish`,{}),h.delete(e)}finally{w({publishing:!1})}O("published")},signOut(){if(x.unsaved&&!e.confirm("Sign out and lose the changes you have not saved?"))return;d.clear(),k();let t=e.location.pathname+e.location.search;e.location.href=`${n}/logout?return_to=${encodeURIComponent(t)}`},select(e){I(e)},setSelecting(e){e?a.documentElement.setAttribute("data-cms-selecting",""):a.documentElement.removeAttribute("data-cms-selecting"),w({selecting:e})},destroy(){m?.(),y.forEach(e=>clearTimeout(e)),y.clear(),s.splice(0).forEach(e=>e())}},j=a.createElement("style");j.textContent=c("html[data-cms-selecting] "),a.head.appendChild(j),s.push(()=>j.remove()),s.push(()=>a.documentElement.removeAttribute("data-cms-selecting"));let R=e=>{if(!x.selecting)return;let r=e.target,n=r?.closest?.(`[${t}]`);n&&(e.preventDefault(),e.stopPropagation(),I(n.getAttribute(t)))};a.addEventListener("click",R,!0),s.push(()=>a.removeEventListener("click",R,!0));let D=e=>{x.unsaved&&(e.preventDefault(),e.returnValue="")};return e.addEventListener("beforeunload",D),s.push(()=>e.removeEventListener("beforeunload",D)),E("session").then(e=>{b=e,w({features:e.features})}).catch(e=>console.error("[@obelism/content bridge]",e)),z})(y,v,{pagePath:u})),h.isEditing&&d){let e=C(y.document,h,!0===d?{}:d),t=h.destroy;h.destroy=()=>{e(),t()}}}return y[L]=h,h};(e=window).ObelismBridge=U((e=>{let t=e?.dataset.url,r=t||A;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:C}}();
|
package/dist/bridge.js
CHANGED
|
@@ -503,6 +503,8 @@ const DEFAULT_PROMPT_LABELS = {
|
|
|
503
503
|
send: 'Apply',
|
|
504
504
|
undo: 'Undo',
|
|
505
505
|
close: 'Close',
|
|
506
|
+
minimize: 'Minimize, to see the page',
|
|
507
|
+
expand: 'Expand',
|
|
506
508
|
scopeEntry: 'Whole page',
|
|
507
509
|
scopeBlock: 'Selected block',
|
|
508
510
|
clearBlock: 'Edit the whole page instead',
|
|
@@ -544,6 +546,8 @@ const ICONS = {
|
|
|
544
546
|
block: '<rect width="18" height="18" x="3" y="3" rx="2"/><path d="M7 8h10"/><path d="M7 12h6"/>',
|
|
545
547
|
undo: '<path d="M9 14 4 9l5-5"/><path d="M4 9h10.5a5.5 5.5 0 0 1 0 11H11"/>',
|
|
546
548
|
close: '<path d="M18 6 6 18"/><path d="m6 6 12 12"/>',
|
|
549
|
+
minimize: '<path d="m6 9 6 6 6-6"/>',
|
|
550
|
+
expand: '<path d="m18 15-6-6-6 6"/>',
|
|
547
551
|
chevrons: '<path d="m7 15 5 5 5-5"/><path d="m7 9 5-5 5 5"/>',
|
|
548
552
|
search: '<circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/>',
|
|
549
553
|
check: '<path d="M20 6 9 17l-5-5"/>',
|
|
@@ -896,6 +900,14 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
896
900
|
title: labels.close
|
|
897
901
|
}, icon(doc, 'close'));
|
|
898
902
|
close.setAttribute('aria-label', labels.close);
|
|
903
|
+
// Minimized, only the toolbar and footer show, so a short page stays in
|
|
904
|
+
// view; the form stays mounted (and its edits) meanwhile.
|
|
905
|
+
const minimizeIcon = icon(doc, 'minimize');
|
|
906
|
+
const expandIcon = icon(doc, 'expand');
|
|
907
|
+
const minimize = element(doc, 'button', {
|
|
908
|
+
className: 'icon-button',
|
|
909
|
+
type: 'button'
|
|
910
|
+
}, minimizeIcon, expandIcon);
|
|
899
911
|
const send = element(doc, 'button', {
|
|
900
912
|
className: 'action primary icon-button',
|
|
901
913
|
type: 'submit'
|
|
@@ -911,7 +923,7 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
911
923
|
className: 'toolbar'
|
|
912
924
|
}, scope, newScope, modes, undo, newPage, element(doc, 'span', {
|
|
913
925
|
className: 'spacer'
|
|
914
|
-
}), close, divider, send);
|
|
926
|
+
}), minimize, close, divider, send);
|
|
915
927
|
// The pages (on the site): a chip naming this page, opening a search
|
|
916
928
|
// and a list of every page in place of the prompt.
|
|
917
929
|
const pageChipText = element(doc, 'span', {
|
|
@@ -989,6 +1001,7 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
989
1001
|
textContent: CSS
|
|
990
1002
|
}), root);
|
|
991
1003
|
let open = false;
|
|
1004
|
+
let minimized = false;
|
|
992
1005
|
let creating = false;
|
|
993
1006
|
let message = null;
|
|
994
1007
|
// Form mode, and the form while mounted: a fresh one (and one-time
|
|
@@ -1033,10 +1046,11 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1033
1046
|
newScope.hidden = !creating;
|
|
1034
1047
|
newPage.hidden = creating || form || !canCreate;
|
|
1035
1048
|
newPage.disabled = busy;
|
|
1036
|
-
|
|
1049
|
+
if (minimized) picking = false;
|
|
1050
|
+
pathRow.hidden = !creating || picking || minimized;
|
|
1037
1051
|
pathInput.disabled = busy;
|
|
1038
|
-
input.hidden = form || picking;
|
|
1039
|
-
formBox.hidden = !form || picking;
|
|
1052
|
+
input.hidden = form || picking || minimized;
|
|
1053
|
+
formBox.hidden = !form || picking || minimized;
|
|
1040
1054
|
formBox.classList.toggle('loading', formLoading);
|
|
1041
1055
|
toolbar.hidden = picking;
|
|
1042
1056
|
pagesSection.hidden = !picking;
|
|
@@ -1055,8 +1069,14 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1055
1069
|
undo.hidden = creating || !state.canUndo;
|
|
1056
1070
|
undo.disabled = busy;
|
|
1057
1071
|
// The form applies edits as they are made.
|
|
1058
|
-
send.hidden = form;
|
|
1059
|
-
divider.hidden = form;
|
|
1072
|
+
send.hidden = form || minimized;
|
|
1073
|
+
divider.hidden = form || minimized;
|
|
1074
|
+
const toggleLabel = minimized ? labels.expand : labels.minimize;
|
|
1075
|
+
minimize.title = toggleLabel;
|
|
1076
|
+
minimize.setAttribute('aria-label', toggleLabel);
|
|
1077
|
+
minimize.setAttribute('aria-expanded', String(!minimized));
|
|
1078
|
+
minimizeIcon.hidden = minimized;
|
|
1079
|
+
expandIcon.hidden = !minimized;
|
|
1060
1080
|
send.disabled = busy || input.value.trim() === '' || creating && pathInput.value.trim() === '';
|
|
1061
1081
|
input.disabled = busy;
|
|
1062
1082
|
save.hidden = !state.features.includes('save') || pageless;
|
|
@@ -1075,7 +1095,7 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1075
1095
|
const working = state.prompting || loadingForm;
|
|
1076
1096
|
const note = state.prompting ? creating ? labels.creating : labels.working : loadingForm ? labels.formLoading : message?.text ?? (site && !creating && !picking && !state.selectedUid ? labels.selectHint : '');
|
|
1077
1097
|
status.textContent = note;
|
|
1078
|
-
status.hidden = !note;
|
|
1098
|
+
status.hidden = !note || minimized;
|
|
1079
1099
|
status.className = `status${working ? ' working' : ''}${!busy && !loadingForm && message?.error ? ' error' : ''}`;
|
|
1080
1100
|
};
|
|
1081
1101
|
const refresh = ()=>render(bridge.getState());
|
|
@@ -1238,7 +1258,10 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1238
1258
|
};
|
|
1239
1259
|
const setOpen = (next)=>{
|
|
1240
1260
|
open = next;
|
|
1241
|
-
if (!open)
|
|
1261
|
+
if (!open) {
|
|
1262
|
+
picking = false;
|
|
1263
|
+
minimized = false;
|
|
1264
|
+
}
|
|
1242
1265
|
refresh();
|
|
1243
1266
|
if (site) bridge.setSelecting(open && !creating);
|
|
1244
1267
|
if (open && site) void fetchPages();
|
|
@@ -1269,6 +1292,11 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1269
1292
|
if (!form) (creating ? pathInput : input).focus();
|
|
1270
1293
|
});
|
|
1271
1294
|
close.addEventListener('click', ()=>setOpen(false));
|
|
1295
|
+
minimize.addEventListener('click', ()=>{
|
|
1296
|
+
minimized = !minimized;
|
|
1297
|
+
refresh();
|
|
1298
|
+
if (!minimized) (form ? minimize : input).focus();
|
|
1299
|
+
});
|
|
1272
1300
|
save.addEventListener('click', ()=>void store('save'));
|
|
1273
1301
|
publish.addEventListener('click', ()=>void store('publish'));
|
|
1274
1302
|
signOut.addEventListener('click', ()=>bridge.signOut());
|
|
@@ -1346,8 +1374,9 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1346
1374
|
// Messages are only exchanged with the URL's origin, and only with the
|
|
1347
1375
|
// iframe's window:
|
|
1348
1376
|
// - form → bridge: { source: 'obelism-content-form', type: 'ready' |
|
|
1349
|
-
// 'change' | 'error', content?, message? } —
|
|
1350
|
-
// entry content after an edit
|
|
1377
|
+
// 'change' | 'error' | 'height', content?, message?, height? } —
|
|
1378
|
+
// `change` carries the whole entry content after an edit, `height` the
|
|
1379
|
+
// form's own height in px, which the iframe takes (up to 60vh)
|
|
1351
1380
|
// - bridge → form: { source: 'obelism-content-bridge', type: 'content',
|
|
1352
1381
|
// entryId, content, locale, selectedUid }
|
|
1353
1382
|
const FORM_SOURCE = 'obelism-content-form';
|
|
@@ -1395,6 +1424,13 @@ const mountFormFrame = (win, container, url, title, handlers)=>{
|
|
|
1395
1424
|
post();
|
|
1396
1425
|
} else if (data.type === 'change' && isObject(data.content)) {
|
|
1397
1426
|
handlers.onChange(data.content, typeof data.entryId === 'string' ? data.entryId : undefined);
|
|
1427
|
+
} else if (data.type === 'height') {
|
|
1428
|
+
const height = data.height;
|
|
1429
|
+
if (typeof height === 'number' && Number.isFinite(height)) {
|
|
1430
|
+
// A short page's form is short; a long one scrolls inside.
|
|
1431
|
+
const px = Math.round(Math.min(Math.max(height, 80), 4000));
|
|
1432
|
+
iframe.style.height = `min(${px}px, 60vh)`;
|
|
1433
|
+
}
|
|
1398
1434
|
} else if (data.type === 'error') {
|
|
1399
1435
|
handlers.onError(typeof data.message === 'string' && data.message ? data.message : 'The form failed');
|
|
1400
1436
|
}
|
package/dist/bridge.mjs
CHANGED
|
@@ -501,6 +501,8 @@ const DEFAULT_PROMPT_LABELS = {
|
|
|
501
501
|
send: 'Apply',
|
|
502
502
|
undo: 'Undo',
|
|
503
503
|
close: 'Close',
|
|
504
|
+
minimize: 'Minimize, to see the page',
|
|
505
|
+
expand: 'Expand',
|
|
504
506
|
scopeEntry: 'Whole page',
|
|
505
507
|
scopeBlock: 'Selected block',
|
|
506
508
|
clearBlock: 'Edit the whole page instead',
|
|
@@ -542,6 +544,8 @@ const ICONS = {
|
|
|
542
544
|
block: '<rect width="18" height="18" x="3" y="3" rx="2"/><path d="M7 8h10"/><path d="M7 12h6"/>',
|
|
543
545
|
undo: '<path d="M9 14 4 9l5-5"/><path d="M4 9h10.5a5.5 5.5 0 0 1 0 11H11"/>',
|
|
544
546
|
close: '<path d="M18 6 6 18"/><path d="m6 6 12 12"/>',
|
|
547
|
+
minimize: '<path d="m6 9 6 6 6-6"/>',
|
|
548
|
+
expand: '<path d="m18 15-6-6-6 6"/>',
|
|
545
549
|
chevrons: '<path d="m7 15 5 5 5-5"/><path d="m7 9 5-5 5 5"/>',
|
|
546
550
|
search: '<circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/>',
|
|
547
551
|
check: '<path d="M20 6 9 17l-5-5"/>',
|
|
@@ -894,6 +898,14 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
894
898
|
title: labels.close
|
|
895
899
|
}, icon(doc, 'close'));
|
|
896
900
|
close.setAttribute('aria-label', labels.close);
|
|
901
|
+
// Minimized, only the toolbar and footer show, so a short page stays in
|
|
902
|
+
// view; the form stays mounted (and its edits) meanwhile.
|
|
903
|
+
const minimizeIcon = icon(doc, 'minimize');
|
|
904
|
+
const expandIcon = icon(doc, 'expand');
|
|
905
|
+
const minimize = element(doc, 'button', {
|
|
906
|
+
className: 'icon-button',
|
|
907
|
+
type: 'button'
|
|
908
|
+
}, minimizeIcon, expandIcon);
|
|
897
909
|
const send = element(doc, 'button', {
|
|
898
910
|
className: 'action primary icon-button',
|
|
899
911
|
type: 'submit'
|
|
@@ -909,7 +921,7 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
909
921
|
className: 'toolbar'
|
|
910
922
|
}, scope, newScope, modes, undo, newPage, element(doc, 'span', {
|
|
911
923
|
className: 'spacer'
|
|
912
|
-
}), close, divider, send);
|
|
924
|
+
}), minimize, close, divider, send);
|
|
913
925
|
// The pages (on the site): a chip naming this page, opening a search
|
|
914
926
|
// and a list of every page in place of the prompt.
|
|
915
927
|
const pageChipText = element(doc, 'span', {
|
|
@@ -987,6 +999,7 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
987
999
|
textContent: CSS
|
|
988
1000
|
}), root);
|
|
989
1001
|
let open = false;
|
|
1002
|
+
let minimized = false;
|
|
990
1003
|
let creating = false;
|
|
991
1004
|
let message = null;
|
|
992
1005
|
// Form mode, and the form while mounted: a fresh one (and one-time
|
|
@@ -1031,10 +1044,11 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1031
1044
|
newScope.hidden = !creating;
|
|
1032
1045
|
newPage.hidden = creating || form || !canCreate;
|
|
1033
1046
|
newPage.disabled = busy;
|
|
1034
|
-
|
|
1047
|
+
if (minimized) picking = false;
|
|
1048
|
+
pathRow.hidden = !creating || picking || minimized;
|
|
1035
1049
|
pathInput.disabled = busy;
|
|
1036
|
-
input.hidden = form || picking;
|
|
1037
|
-
formBox.hidden = !form || picking;
|
|
1050
|
+
input.hidden = form || picking || minimized;
|
|
1051
|
+
formBox.hidden = !form || picking || minimized;
|
|
1038
1052
|
formBox.classList.toggle('loading', formLoading);
|
|
1039
1053
|
toolbar.hidden = picking;
|
|
1040
1054
|
pagesSection.hidden = !picking;
|
|
@@ -1053,8 +1067,14 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1053
1067
|
undo.hidden = creating || !state.canUndo;
|
|
1054
1068
|
undo.disabled = busy;
|
|
1055
1069
|
// The form applies edits as they are made.
|
|
1056
|
-
send.hidden = form;
|
|
1057
|
-
divider.hidden = form;
|
|
1070
|
+
send.hidden = form || minimized;
|
|
1071
|
+
divider.hidden = form || minimized;
|
|
1072
|
+
const toggleLabel = minimized ? labels.expand : labels.minimize;
|
|
1073
|
+
minimize.title = toggleLabel;
|
|
1074
|
+
minimize.setAttribute('aria-label', toggleLabel);
|
|
1075
|
+
minimize.setAttribute('aria-expanded', String(!minimized));
|
|
1076
|
+
minimizeIcon.hidden = minimized;
|
|
1077
|
+
expandIcon.hidden = !minimized;
|
|
1058
1078
|
send.disabled = busy || input.value.trim() === '' || creating && pathInput.value.trim() === '';
|
|
1059
1079
|
input.disabled = busy;
|
|
1060
1080
|
save.hidden = !state.features.includes('save') || pageless;
|
|
@@ -1073,7 +1093,7 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1073
1093
|
const working = state.prompting || loadingForm;
|
|
1074
1094
|
const note = state.prompting ? creating ? labels.creating : labels.working : loadingForm ? labels.formLoading : message?.text ?? (site && !creating && !picking && !state.selectedUid ? labels.selectHint : '');
|
|
1075
1095
|
status.textContent = note;
|
|
1076
|
-
status.hidden = !note;
|
|
1096
|
+
status.hidden = !note || minimized;
|
|
1077
1097
|
status.className = `status${working ? ' working' : ''}${!busy && !loadingForm && message?.error ? ' error' : ''}`;
|
|
1078
1098
|
};
|
|
1079
1099
|
const refresh = ()=>render(bridge.getState());
|
|
@@ -1236,7 +1256,10 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1236
1256
|
};
|
|
1237
1257
|
const setOpen = (next)=>{
|
|
1238
1258
|
open = next;
|
|
1239
|
-
if (!open)
|
|
1259
|
+
if (!open) {
|
|
1260
|
+
picking = false;
|
|
1261
|
+
minimized = false;
|
|
1262
|
+
}
|
|
1240
1263
|
refresh();
|
|
1241
1264
|
if (site) bridge.setSelecting(open && !creating);
|
|
1242
1265
|
if (open && site) void fetchPages();
|
|
@@ -1267,6 +1290,11 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1267
1290
|
if (!form) (creating ? pathInput : input).focus();
|
|
1268
1291
|
});
|
|
1269
1292
|
close.addEventListener('click', ()=>setOpen(false));
|
|
1293
|
+
minimize.addEventListener('click', ()=>{
|
|
1294
|
+
minimized = !minimized;
|
|
1295
|
+
refresh();
|
|
1296
|
+
if (!minimized) (form ? minimize : input).focus();
|
|
1297
|
+
});
|
|
1270
1298
|
save.addEventListener('click', ()=>void store('save'));
|
|
1271
1299
|
publish.addEventListener('click', ()=>void store('publish'));
|
|
1272
1300
|
signOut.addEventListener('click', ()=>bridge.signOut());
|
|
@@ -1344,8 +1372,9 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1344
1372
|
// Messages are only exchanged with the URL's origin, and only with the
|
|
1345
1373
|
// iframe's window:
|
|
1346
1374
|
// - form → bridge: { source: 'obelism-content-form', type: 'ready' |
|
|
1347
|
-
// 'change' | 'error', content?, message? } —
|
|
1348
|
-
// entry content after an edit
|
|
1375
|
+
// 'change' | 'error' | 'height', content?, message?, height? } —
|
|
1376
|
+
// `change` carries the whole entry content after an edit, `height` the
|
|
1377
|
+
// form's own height in px, which the iframe takes (up to 60vh)
|
|
1349
1378
|
// - bridge → form: { source: 'obelism-content-bridge', type: 'content',
|
|
1350
1379
|
// entryId, content, locale, selectedUid }
|
|
1351
1380
|
const FORM_SOURCE = 'obelism-content-form';
|
|
@@ -1393,6 +1422,13 @@ const mountFormFrame = (win, container, url, title, handlers)=>{
|
|
|
1393
1422
|
post();
|
|
1394
1423
|
} else if (data.type === 'change' && isObject(data.content)) {
|
|
1395
1424
|
handlers.onChange(data.content, typeof data.entryId === 'string' ? data.entryId : undefined);
|
|
1425
|
+
} else if (data.type === 'height') {
|
|
1426
|
+
const height = data.height;
|
|
1427
|
+
if (typeof height === 'number' && Number.isFinite(height)) {
|
|
1428
|
+
// A short page's form is short; a long one scrolls inside.
|
|
1429
|
+
const px = Math.round(Math.min(Math.max(height, 80), 4000));
|
|
1430
|
+
iframe.style.height = `min(${px}px, 60vh)`;
|
|
1431
|
+
}
|
|
1396
1432
|
} else if (data.type === 'error') {
|
|
1397
1433
|
handlers.onError(typeof data.message === 'string' && data.message ? data.message : 'The form failed');
|
|
1398
1434
|
}
|
package/dist/index.js
CHANGED
|
@@ -186,7 +186,10 @@ class ContentClient {
|
|
|
186
186
|
headers: {
|
|
187
187
|
...headersToObject(merged.headers),
|
|
188
188
|
Accept: 'application/json',
|
|
189
|
-
|
|
189
|
+
// Not `Authorization`: Cloudflare never caches a request that
|
|
190
|
+
// carries it, and this header lets the API answer a delivery
|
|
191
|
+
// token from its edge cache.
|
|
192
|
+
'Obelism-Token': this.#token
|
|
190
193
|
},
|
|
191
194
|
signal: merged.signal ? AbortSignal.any([
|
|
192
195
|
merged.signal,
|
package/dist/index.mjs
CHANGED
|
@@ -184,7 +184,10 @@ class ContentClient {
|
|
|
184
184
|
headers: {
|
|
185
185
|
...headersToObject(merged.headers),
|
|
186
186
|
Accept: 'application/json',
|
|
187
|
-
|
|
187
|
+
// Not `Authorization`: Cloudflare never caches a request that
|
|
188
|
+
// carries it, and this header lets the API answer a delivery
|
|
189
|
+
// token from its edge cache.
|
|
190
|
+
'Obelism-Token': this.#token
|
|
188
191
|
},
|
|
189
192
|
signal: merged.signal ? AbortSignal.any([
|
|
190
193
|
merged.signal,
|
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.
|
|
4
|
+
"version": "0.16.0",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cms",
|
|
7
7
|
"headless-cms",
|