@obelism/content 0.13.0 → 0.14.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 +20 -10
- package/dist/bridge.d.mts +13 -11
- package/dist/bridge.d.mts.map +1 -1
- package/dist/bridge.d.ts +13 -11
- package/dist/bridge.d.ts.map +1 -1
- package/dist/bridge.global.js +10 -12
- package/dist/bridge.js +302 -323
- package/dist/bridge.mjs +302 -323
- package/dist/site.js +5 -0
- package/dist/site.mjs +5 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -155,22 +155,32 @@ getContentBridge({ pagePath: (path, locale) => `/${locale}/${path}` })
|
|
|
155
155
|
await bridge.createPage('/pricing', 'Our plans, for agencies') // or your own UI
|
|
156
156
|
```
|
|
157
157
|
|
|
158
|
-
There the box also switches between **Prompt** and **
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
158
|
+
There the box also switches between **Prompt** and **Form**. Form shows the
|
|
159
|
+
CMS's own form for the page — or for the entry around the selected block —
|
|
160
|
+
right in the box: the fields, and blocks as cards to open and add,
|
|
161
|
+
as in the dashboard. Edits apply as you make them: they land in the unsaved
|
|
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. A chip under the prompt names the page and
|
|
164
|
+
opens every page of the space, drafts included, to go to one (at
|
|
165
|
+
`pagePath`, in the page's language when it has a path there):
|
|
166
166
|
|
|
167
167
|
```ts
|
|
168
|
-
const
|
|
169
|
-
|
|
168
|
+
const form = bridge.openForm(element, { onReady, onError }) // an iframe
|
|
169
|
+
form.close()
|
|
170
170
|
const pages = await bridge.pages() // { entryId, name, status, path, url }[]
|
|
171
171
|
bridge.openPage(pages[0]) // asks first when changes aren't saved
|
|
172
172
|
```
|
|
173
173
|
|
|
174
|
+
The form needs `createSiteEditing`'s `/cms/api/form`, which gets the CMS
|
|
175
|
+
page a one-time address. For the raw content instead, as a language model
|
|
176
|
+
sees it (one locale, rich text as Markdown, blocks with `_uid` and
|
|
177
|
+
`_type`), there is JSON:
|
|
178
|
+
|
|
179
|
+
```ts
|
|
180
|
+
const view = await bridge.view() // or { uid } for a block
|
|
181
|
+
const { changed } = await bridge.applyJson({ ...view, title: 'Pricing' })
|
|
182
|
+
```
|
|
183
|
+
|
|
174
184
|
The CMS runs prompts on Workers AI. To use your own model, set a prompt
|
|
175
185
|
endpoint under Space settings → Prompt editing and answer it with
|
|
176
186
|
`createPromptHandler` (it verifies the signed request; you call the model):
|
package/dist/bridge.d.mts
CHANGED
|
@@ -58,6 +58,14 @@ type ApplyJsonResult = {
|
|
|
58
58
|
changed: string[];
|
|
59
59
|
view?: Record<string, unknown> | undefined;
|
|
60
60
|
};
|
|
61
|
+
type FormOptions = {
|
|
62
|
+
title?: string | undefined;
|
|
63
|
+
onReady?: (() => void) | undefined;
|
|
64
|
+
onError?: ((message: string) => void) | undefined;
|
|
65
|
+
};
|
|
66
|
+
type FormHandle = {
|
|
67
|
+
close(): void;
|
|
68
|
+
};
|
|
61
69
|
type SitePage = {
|
|
62
70
|
entryId: string;
|
|
63
71
|
name: string;
|
|
@@ -83,6 +91,7 @@ type ContentBridge = {
|
|
|
83
91
|
applyJson(changes: Record<string, unknown>, options?: {
|
|
84
92
|
uid?: string | null | undefined;
|
|
85
93
|
}): Promise<ApplyJsonResult>;
|
|
94
|
+
openForm(container: HTMLElement, options?: FormOptions): FormHandle;
|
|
86
95
|
pages(): Promise<SitePage[]>;
|
|
87
96
|
openPage(page: SitePage): void;
|
|
88
97
|
undo(): void;
|
|
@@ -124,16 +133,9 @@ type PromptLabels = {
|
|
|
124
133
|
created: string;
|
|
125
134
|
modes: string;
|
|
126
135
|
modePrompt: string;
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
jsonReload: string;
|
|
131
|
-
jsonKept: string;
|
|
132
|
-
jsonInvalidAt: string;
|
|
133
|
-
jsonInvalid: string;
|
|
134
|
-
jsonNotObject: string;
|
|
135
|
-
applied: string;
|
|
136
|
-
unchanged: string;
|
|
136
|
+
form: string;
|
|
137
|
+
formTitle: string;
|
|
138
|
+
formLoading: string;
|
|
137
139
|
pages: string;
|
|
138
140
|
pagesSearch: string;
|
|
139
141
|
pagesLoading: string;
|
|
@@ -157,5 +159,5 @@ declare const peekContentBridge: () => ContentBridge | null;
|
|
|
157
159
|
declare const getContentBridge: ({ url, prompt, pagePath, }?: BridgeOptions) => ContentBridge;
|
|
158
160
|
|
|
159
161
|
export { DEFAULT_PROMPT_LABELS, DEFAULT_STATS_LABELS, INITIAL_STATE, getContentBridge, mountPromptBox, mountStatsOverlay, peekContentBridge };
|
|
160
|
-
export type { ApplyJsonResult, BlockStats, BridgeEvent, BridgeEvents, BridgeListener, BridgeOptions, BridgeState, ContentBridge, CreatePageResult, PromptBoxOptions, PromptLabels, PromptResult, SitePage, StatsLabels, StatsOverlay };
|
|
162
|
+
export type { ApplyJsonResult, BlockStats, BridgeEvent, BridgeEvents, BridgeListener, BridgeOptions, BridgeState, ContentBridge, CreatePageResult, FormHandle, FormOptions, PromptBoxOptions, PromptLabels, PromptResult, SitePage, StatsLabels, StatsOverlay };
|
|
161
163
|
//# sourceMappingURL=bridge.d.mts.map
|
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,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,aAAa,OAAO,CAAC,QAAQ;AAC7B,mBAAmB,QAAQ;AAC3B;AACA,YAAY,OAAO;AACnB,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AAEA,cAAc,aAAa,EAAE,WAAW;;
|
|
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;;ACrC/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
|
@@ -58,6 +58,14 @@ type ApplyJsonResult = {
|
|
|
58
58
|
changed: string[];
|
|
59
59
|
view?: Record<string, unknown> | undefined;
|
|
60
60
|
};
|
|
61
|
+
type FormOptions = {
|
|
62
|
+
title?: string | undefined;
|
|
63
|
+
onReady?: (() => void) | undefined;
|
|
64
|
+
onError?: ((message: string) => void) | undefined;
|
|
65
|
+
};
|
|
66
|
+
type FormHandle = {
|
|
67
|
+
close(): void;
|
|
68
|
+
};
|
|
61
69
|
type SitePage = {
|
|
62
70
|
entryId: string;
|
|
63
71
|
name: string;
|
|
@@ -83,6 +91,7 @@ type ContentBridge = {
|
|
|
83
91
|
applyJson(changes: Record<string, unknown>, options?: {
|
|
84
92
|
uid?: string | null | undefined;
|
|
85
93
|
}): Promise<ApplyJsonResult>;
|
|
94
|
+
openForm(container: HTMLElement, options?: FormOptions): FormHandle;
|
|
86
95
|
pages(): Promise<SitePage[]>;
|
|
87
96
|
openPage(page: SitePage): void;
|
|
88
97
|
undo(): void;
|
|
@@ -124,16 +133,9 @@ type PromptLabels = {
|
|
|
124
133
|
created: string;
|
|
125
134
|
modes: string;
|
|
126
135
|
modePrompt: string;
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
jsonReload: string;
|
|
131
|
-
jsonKept: string;
|
|
132
|
-
jsonInvalidAt: string;
|
|
133
|
-
jsonInvalid: string;
|
|
134
|
-
jsonNotObject: string;
|
|
135
|
-
applied: string;
|
|
136
|
-
unchanged: string;
|
|
136
|
+
form: string;
|
|
137
|
+
formTitle: string;
|
|
138
|
+
formLoading: string;
|
|
137
139
|
pages: string;
|
|
138
140
|
pagesSearch: string;
|
|
139
141
|
pagesLoading: string;
|
|
@@ -157,5 +159,5 @@ declare const peekContentBridge: () => ContentBridge | null;
|
|
|
157
159
|
declare const getContentBridge: ({ url, prompt, pagePath, }?: BridgeOptions) => ContentBridge;
|
|
158
160
|
|
|
159
161
|
export { DEFAULT_PROMPT_LABELS, DEFAULT_STATS_LABELS, INITIAL_STATE, getContentBridge, mountPromptBox, mountStatsOverlay, peekContentBridge };
|
|
160
|
-
export type { ApplyJsonResult, BlockStats, BridgeEvent, BridgeEvents, BridgeListener, BridgeOptions, BridgeState, ContentBridge, CreatePageResult, PromptBoxOptions, PromptLabels, PromptResult, SitePage, StatsLabels, StatsOverlay };
|
|
162
|
+
export type { ApplyJsonResult, BlockStats, BridgeEvent, BridgeEvents, BridgeListener, BridgeOptions, BridgeState, ContentBridge, CreatePageResult, FormHandle, FormOptions, PromptBoxOptions, PromptLabels, PromptResult, SitePage, StatsLabels, StatsOverlay };
|
|
161
163
|
//# sourceMappingURL=bridge.d.ts.map
|
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,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,aAAa,OAAO,CAAC,QAAQ;AAC7B,mBAAmB,QAAQ;AAC3B;AACA,YAAY,OAAO;AACnB,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AAEA,cAAc,aAAa,EAAE,WAAW;;
|
|
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;;ACrC/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
|
@@ -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="cms_environment",
|
|
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="cms_environment",o={clicked:"{rate}% clicked",title:"{clickers} of {viewers} visitors of its page clicked it in the last 30 days ({clicks} clicks)"},a=(e,t)=>e.replace(/\{(\w+)\}/g,(e,r)=>r in t?String(t[r]):e),i=`
|
|
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
|
+
`,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=`
|
|
26
26
|
:host { all: initial; }
|
|
27
27
|
* { box-sizing: border-box; font: inherit; color: inherit; margin: 0; }
|
|
28
28
|
.root {
|
|
@@ -119,13 +119,13 @@ textarea {
|
|
|
119
119
|
font-size: 16px; line-height: 1.6; color: rgb(var(--theme-foreground-rgb));
|
|
120
120
|
}
|
|
121
121
|
textarea::placeholder { color: rgb(var(--theme-foreground-muted-rgb)); }
|
|
122
|
-
/*
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
font-size: 13px; line-height: 1.55;
|
|
122
|
+
/* Form: the CMS's entry form, edited live. */
|
|
123
|
+
.form { padding: 12px 12px 0; }
|
|
124
|
+
.form iframe {
|
|
125
|
+
display: block; width: 100%; height: min(560px, 60vh); border: none; border-radius: 12px;
|
|
126
|
+
background: rgb(var(--theme-background-actions-rgb) / .45);
|
|
128
127
|
}
|
|
128
|
+
.form.loading iframe { visibility: hidden; }
|
|
129
129
|
/* New page: where it goes, above what it is for. */
|
|
130
130
|
.path {
|
|
131
131
|
display: flex; align-items: center; gap: 10px; padding: 16px 22px 0;
|
|
@@ -169,7 +169,7 @@ button.chip:disabled { opacity: .5; }
|
|
|
169
169
|
.icon-button.primary { background: rgb(var(--theme-accent-rgb)); color: #fff; }
|
|
170
170
|
.icon-button.primary:hover:not(:disabled) { background: rgb(var(--theme-accent-rgb)); color: #fff; opacity: .88; }
|
|
171
171
|
.icon-button.primary:disabled { opacity: .35; }
|
|
172
|
-
/* Prompt or
|
|
172
|
+
/* Prompt or Form: two small pills in one track. */
|
|
173
173
|
.modes {
|
|
174
174
|
display: inline-flex; flex: none; gap: 2px; padding: 2px; border-radius: var(--border-radius-pill);
|
|
175
175
|
border: 1px solid rgb(var(--theme-border-rgb) / .2); background: rgb(var(--theme-background-actions-rgb) / .6);
|
|
@@ -233,6 +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
|
-
`,w=(e,t,r={},...n)=>{let a=e.createElement(t);for(let t of(Object.assign(a,r),n))a.appendChild("string"==typeof t?e.createTextNode(t):t);return a},k=(e,t)=>{let r=w(e,"span",{className:"icon"});return r.setAttribute("aria-hidden","true"),r.innerHTML=`<svg viewBox="0 0 24 24">${y[t]}</svg>`,r},E=(e,t,r={})=>{let n,a={...v,...r.labels},o=w(e,"div");o.setAttribute("data-obelism-content-prompt","");let i=o.attachShadow({mode:"open"}),l="site"===t.mode,s=w(e,"span",{textContent:a.open}),d=w(e,"button",{className:"pill",type:"button"},s,w(e,"span",{className:"mark",textContent:"⁜"})),c=w(e,"span",{className:"pill compact"},`${a.viewingDrafts} \xb7 `),p=w(e,"button",{className:"link",type:"button",textContent:a.signOut});c.appendChild(p);let g=w(e,"p",{className:"status"});g.setAttribute("role","status");let u=w(e,"textarea",{placeholder:a.placeholder,rows:1});u.setAttribute("aria-label",a.open);let h=w(e,"textarea",{className:"code",spellcheck:!1,autocomplete:"off"});h.setAttribute("aria-label",a.json),h.setAttribute("autocapitalize","off");let b=k(e,"page"),m=k(e,"block"),f=w(e,"span"),y=w(e,"button",{type:"button",title:a.clearBlock});y.setAttribute("aria-label",a.clearBlock),y.appendChild(k(e,"close"));let E=w(e,"span",{className:"chip scope"},b,m,f,y),S=w(e,"button",{className:"action chip",type:"button"},k(e,"undo"),a.undo),C=t=>{let r=w(e,"button",{type:"button",textContent:t});return r.setAttribute("aria-pressed","false"),r},N=C(a.modePrompt),A=C(a.modeJson),L=w(e,"span",{className:"modes"},N,A);L.setAttribute("role","group"),L.setAttribute("aria-label",a.modes);let P=w(e,"button",{className:"icon-button",type:"button",title:a.jsonReload},k(e,"reload"));P.setAttribute("aria-label",a.jsonReload);let $=w(e,"button",{className:"action chip",type:"button"},k(e,"newPage"),a.newPage),O=w(e,"button",{type:"button",title:a.newPageCancel});O.setAttribute("aria-label",a.newPageCancel),O.appendChild(k(e,"close"));let U=w(e,"span",{className:"chip scope"},k(e,"newPage"),w(e,"span",{textContent:a.newPage}),O),j=w(e,"input",{type:"text",placeholder:a.pathPlaceholder,autocomplete:"off",spellcheck:!1}),I=w(e,"label",{className:"path"},w(e,"span",{textContent:a.path}),j),M=w(e,"button",{className:"close icon-button",type:"button",title:a.close},k(e,"close"));M.setAttribute("aria-label",a.close);let R=w(e,"button",{className:"action primary icon-button",type:"submit"},w(e,"span",{className:"visually-hidden",textContent:a.send}),k(e,"send"));R.title=a.send;let z=w(e,"div",{className:"toolbar"},E,U,L,S,$,w(e,"span",{className:"spacer"}),P,M,w(e,"span",{className:"divider"}),R),D=w(e,"span",{textContent:a.pages}),T=w(e,"button",{className:"chip page-chip",type:"button",title:a.pages},k(e,"page"),D,k(e,"chevrons"));T.setAttribute("aria-haspopup","listbox"),T.setAttribute("aria-expanded","false"),T.setAttribute("aria-controls","obelism-pages");let J=w(e,"input",{type:"text",placeholder:a.pagesSearch,autocomplete:"off",spellcheck:!1});J.setAttribute("role","combobox"),J.setAttribute("aria-label",a.pagesSearch),J.setAttribute("aria-autocomplete","list"),J.setAttribute("aria-expanded","true"),J.setAttribute("aria-controls","obelism-pages");let q=w(e,"ul",{className:"options",id:"obelism-pages"});q.setAttribute("role","listbox"),q.setAttribute("aria-label",a.pages);let B=w(e,"p",{className:"empty"}),V=w(e,"div",{className:"pages"},w(e,"label",{className:"search"},k(e,"search"),J),q,B),F=w(e,"span",{className:"unsaved"});F.appendChild(w(e,"span",{className:"dot"})),F.appendChild(e.createTextNode(a.unsaved));let H=w(e,"button",{className:"link",type:"button",textContent:a.signOut}),K=w(e,"button",{className:"action chip",type:"button",textContent:a.save}),Y=w(e,"button",{className:"action chip",type:"button",textContent:a.publish}),W=w(e,"div",{className:"footer"},T,F,w(e,"span",{className:"spacer"}),H,K,Y),_=w(e,"form",{className:"panel"},g,I,u,h,z,V,W),X=w(e,"div",{className:"root"},w(e,"div",{className:"bar"},d,c),_);i.append(w(e,"style",{textContent:x}),X);let Z=!1,G=!1,Q=null,ee=!1,et="",er=null,en=!1,ea=0,eo=!1,ei=null,el=null,es=null,ed=0,ec=e=>({text:e instanceof Error?e.message:String(e),error:!0}),ep=e=>{let r=e.features.includes("prompt"),o=e.saving||e.publishing,i=e.prompting||o;X.hidden=!r&&!l,d.hidden=Z||!r,c.hidden=r||!l,_.hidden=!Z||!r;let p=l&&e.features.includes("create"),v=l&&null===t.entryId,x=v&&p;p||(G=!1),x&&(G=!0),(G||v)&&(ee=!1),s.textContent=x?a.newPage:a.open,O.hidden=x,E.hidden=G,U.hidden=!G,$.hidden=G||ee||!p,$.disabled=i,I.hidden=!G||eo,j.disabled=i,u.hidden=ee||eo,h.hidden=!ee||eo,z.hidden=eo,V.hidden=!eo,u.placeholder=G?a.newPagePlaceholder:a.placeholder;let w=ee?er:e.selectedUid;f.textContent=w?a.scopeBlock:a.scopeEntry,y.hidden=!e.selectedUid,b.hidden=!!w,m.hidden=!w,L.hidden=!l||G||v,N.setAttribute("aria-pressed",String(!ee)),A.setAttribute("aria-pressed",String(ee)),L.querySelectorAll("button").forEach(e=>{e.disabled=i||en}),P.hidden=!ee,P.disabled=i||en,S.hidden=G||!e.canUndo,S.disabled=i||en;let k=ee?h.value:u.value;R.disabled=i||en||""===k.trim()||G&&""===j.value.trim(),u.disabled=i,h.disabled=i||en,K.hidden=!e.features.includes("save")||v,K.disabled=i||!e.unsaved,K.textContent=e.saving?a.saving:a.save,Y.hidden=!e.features.includes("publish")||v,Y.disabled=i,Y.textContent=e.publishing?a.publishing:a.publish,H.hidden=!l,W.hidden=!l,F.hidden=!e.unsaved,T.hidden=!l,T.setAttribute("aria-expanded",String(eo)),D.textContent=ei?.find(({entryId:e})=>e===t.entryId)?.name??a.pages;let C=e.prompting||en,M=e.prompting?G?a.creating:a.working:en?a.jsonLoading:Q?.text??(!l||G||eo||e.selectedUid?"":a.selectHint);g.textContent=M,g.hidden=!M,g.className=`status${C?" working":""}${!i&&!en&&Q?.error?" error":""}`,Z&&ee&&!eo&&e.selectedUid!==n&&(n=e.selectedUid,queueMicrotask(()=>void eh(!1)))},eg=()=>ep(t.getState()),eu=()=>{u.style.height="auto",u.style.height=`${u.scrollHeight}px`},eh=async e=>{let r=t.getState().selectedUid;if(n=r,!e&&h.value!==et)return Q={text:a.jsonKept,error:!1},eg(),!1;let o=++ea;en=!0,Q=null,eg();try{let e=await t.view({uid:r});if(o!==ea)return!1;return h.value=et=`${JSON.stringify(e,null,2)}
|
|
237
|
-
`,h.scrollTop=0,er=r,!0}catch(e){return o===ea&&(Q=ec(e)),!1}finally{o===ea&&(en=!1,eg())}},eb=()=>{n=void 0,eg()},em=e=>{ee!==e&&(ee=e,Q=null,eb(),(ee?h:u).focus())},ef=async()=>{let e,r=h.value;if(r.trim()&&!t.getState().prompting&&!en){try{e=JSON.parse(r)}catch(t){let e=((e,t)=>{let r=(e=>{let t=0,r=()=>{throw t},n=()=>{for(;t<e.length&&" \n\r".includes(e[t]);)t++},a=()=>{for(t++;t<e.length;){let n=e[t];if('"'===n)return void t++;if("\\"===n){let n=e[t+1]??"";"u"===n&&/^[\da-f]{4}$/i.test(e.slice(t+2,t+6))?t+=6:""!==n&&'"\\/bfnrt'.includes(n)?t+=2:(t++,r())}else n<" "?r():t++}r()},o=(a,o)=>{if(t++,n(),e[t]===a)return void t++;for(;;){if(o(),n(),e[t]===a)return void t++;","!==e[t]&&r(),t++}},i=()=>{n();let l=e[t]??"";if("{"===l)return o("}",()=>{n(),'"'!==e[t]&&r(),a(),n(),":"!==e[t]&&r(),t++,i()});if("["===l)return o("]",i);if('"'===l)return a();for(let r of["true","false","null"])if(e.startsWith(r,t)){t+=r.length;return}let s=/^-?(0|[1-9]\d*)(\.\d+)?([eE][+-]?\d+)?/.exec(e.slice(t));if(!s)return r();t+=s[0].length};try{return i(),n(),t<e.length&&r(),-1}catch(t){if("number"!=typeof t)throw t;return Math.min(t,e.length)}})(e);if(r<0){let e=t instanceof Error?t.message:String(t);return{text:`${a.jsonInvalid}: ${e}`}}let n=e.slice(0,r),o=n.split("\n").length,i=r-n.lastIndexOf("\n");return{text:a.jsonInvalidAt.replace("{line}",String(o)).replace("{column}",String(i)),offset:r}})(r,t);Q={text:e.text,error:!0},eg(),h.focus(),void 0!==e.offset&&h.setSelectionRange(e.offset,e.offset);return}if(!e||"object"!=typeof e||Array.isArray(e))return Q={text:a.jsonNotObject,error:!0},eg();Q=null;try{let{changed:r,view:n}=await t.applyJson(e,{uid:er});n&&(++ea,h.value=et=`${JSON.stringify(n,null,2)}
|
|
238
|
-
`),(n||await eh(!0))&&(Q={text:r.length>0?a.applied:a.unchanged,error:!1})}catch(e){Q=ec(e)}eg(),h.focus()}},ev=async()=>{if(ee)return ef();let e=u.value.trim();if(e&&!t.getState().prompting){Q=null;try{if(G){let r=j.value.trim();if(!r)return j.focus();await t.createPage(r,e),ei=null,el=null,Q={text:a.created,error:!1}}else{let{summary:r}=await t.prompt(e);Q={text:r,error:!1}}u.value="",eu()}catch(e){Q=ec(e)}eg(),u.focus()}},ey=()=>(el??(el=t.pages().then(e=>{ei=e,es=null,ew(),eg()},e=>{el=null,es=ec(e).text,ew()})),el),ex=()=>{let e=J.value.trim().toLowerCase();return(ei??[]).filter(t=>!e||t.name.toLowerCase().includes(e)||t.url.toLowerCase().includes(e)||`/${t.path}`.toLowerCase().includes(e))},ew=()=>{let r=ex();ed=Math.max(0,Math.min(ed,r.length-1)),q.textContent="",r.forEach((r,n)=>{let o=r.entryId===t.entryId,i=w(e,"li",{className:`option${n===ed?" active":""}`,id:`obelism-page-${n}`},w(e,"span",{className:"option-text"},w(e,"span",{textContent:r.name}),w(e,"span",{className:"option-path",textContent:r.url})));if(i.setAttribute("role","option"),i.setAttribute("aria-selected",String(n===ed)),"published"!==r.status&&i.appendChild(w(e,"span",{className:"badge",textContent:"draft"===r.status?a.pageDraft:a.pageChanged})),o){i.setAttribute("aria-current","page");let t=k(e,"check");t.removeAttribute("aria-hidden"),t.setAttribute("role","img"),t.setAttribute("aria-label",a.pageCurrent),i.appendChild(t)}i.addEventListener("click",()=>eE(r)),q.appendChild(i)});let n=q.children[ed];n?(J.setAttribute("aria-activedescendant",n.id),n.scrollIntoView?.({block:"nearest"})):J.removeAttribute("aria-activedescendant"),B.textContent=(es??(ei?"":a.pagesLoading))||(0===r.length?a.pagesEmpty:""),B.hidden=!B.textContent,B.className=`empty${es?" error":""}`},ek=e=>{Q=null,(eo=e)&&(J.value="",ed=Math.max(0,(ei??[]).findIndex(({entryId:e})=>e===t.entryId)),ey(),ew()),eg(),(eo?J:T).focus()},eE=e=>{if(e.entryId===t.entryId)return ek(!1);t.openPage(e)},eS=e=>{(Z=e)||(eo=!1),eg(),l&&t.setSelecting(Z&&!G),Z&&l&&ey(),Z&&ee&&eb()},eC=e=>{G=e,Q=null,t.setSelecting(Z&&!G),G&&t.select(null),eg(),(G?j:u).focus()},eN=async e=>{Q=null;try{await t[e](),Q={text:"save"===e?a.saved:a.published,error:!1}}catch(e){Q=ec(e)}eg()};d.addEventListener("click",()=>{eS(!0),(G?j:ee?h:u).focus()}),M.addEventListener("click",()=>eS(!1)),K.addEventListener("click",()=>void eN("save")),Y.addEventListener("click",()=>void eN("publish")),H.addEventListener("click",()=>t.signOut()),p.addEventListener("click",()=>t.signOut()),y.addEventListener("click",()=>t.select(null)),$.addEventListener("click",()=>eC(!0)),O.addEventListener("click",()=>eC(!1)),N.addEventListener("click",()=>em(!1)),A.addEventListener("click",()=>em(!0)),P.addEventListener("click",()=>{eh(!0),h.focus()}),T.addEventListener("click",()=>ek(!eo)),j.addEventListener("input",eg),j.addEventListener("keydown",e=>{"Enter"!==e.key||e.isComposing?"Escape"===e.key&&eS(!1):(e.preventDefault(),u.focus())}),J.addEventListener("input",()=>{ed=0,ew()}),J.addEventListener("keydown",e=>{let t=q.children.length;if("ArrowDown"===e.key||"ArrowUp"===e.key){if(e.preventDefault(),0===t)return;ed=(ed+("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()[ed];t&&eE(t)}}),S.addEventListener("click",()=>{Q=null,t.undo(),ee&&eb()}),_.addEventListener("submit",e=>{e.preventDefault(),ev()}),u.addEventListener("input",()=>{eu(),eg()}),u.addEventListener("keydown",e=>{"Enter"!==e.key||e.shiftKey||e.isComposing?"Escape"===e.key&&eS(!1):(e.preventDefault(),ev())}),h.addEventListener("input",eg),h.addEventListener("keydown",t=>{if("Enter"===t.key&&(t.ctrlKey||t.metaKey)&&!t.isComposing)t.preventDefault(),ev();else if("Tab"!==t.key||t.shiftKey||t.ctrlKey||t.metaKey||t.altKey)"Escape"===t.key&&eS(!1);else{t.preventDefault();let r=!1;try{r=e.execCommand("insertText",!1," ")}catch{}r||h.setRangeText(" ",h.selectionStart,h.selectionEnd,"end"),eg()}});let eA=t.on("change",ep);return eg(),e.body.appendChild(o),()=>{eA(),o.remove()}},S="https://content.obelism.studio",C=(e,t)=>JSON.stringify(e)===JSON.stringify(t),N=Symbol.for("@obelism/content/bridge"),A=f({isEditing:!1,entryId:null,on:()=>{}},new URLSearchParams),L=({url:e,prompt:s=!0,pagePath:g}={})=>{let u;if("u"<typeof window)return A;let v=window;if(v[N])return v[N];if(v.ObelismBridge)u=f(v.ObelismBridge,new URLSearchParams(v.location.search));else{let f=(u=((e,r)=>{let s=new URLSearchParams(e.location.search),g=e.parent!==e&&s.has("cms_preview"),u=p(),f=[],v={...c,selecting:!0},y=e=>{v={...v,...e},u.emit("change",v)},x={isEditing:g,mode:g?"editor":null,entryId:s.get("cms_entry"),environment:s.get(n),on:u.on,getState:()=>v,...h,destroy:()=>{f.splice(0).forEach(e=>e())}};if(!g)return x;let w=e.document,k=(t,n={})=>{e.parent.postMessage({source:"obelism-content-bridge",type:t,...n},r)},E=w.createElement("style");E.textContent=d(),w.head.appendChild(E),f.push(()=>E.remove());let S=(e,t)=>{if(w.querySelectorAll("[data-cms-selected]").forEach(e=>{e.removeAttribute("data-cms-selected")}),v.selectedUid!==(e??null)&&y({selectedUid:e??null}),!e)return;let r=w.querySelector(m(e));r&&(r.setAttribute("data-cms-selected",""),t&&r.scrollIntoView({behavior:"smooth",block:"center"}))},C=e=>{let r=e.target,n=r?.closest?.(`[${t}]`);if(!n)return;e.preventDefault(),e.stopPropagation();let a=n.getAttribute(t);S(a,!1),k("select",{uid:a})};w.addEventListener("click",C,!0),f.push(()=>w.removeEventListener("click",C,!0));let N=()=>k("ready",{url:e.location.href}),A=new Map,L=0,P=e=>{let t=A.get(e);return t?(clearTimeout(t.timer),A.delete(e),0===A.size&&y({prompting:!1}),t):null};x.prompt=(e,t={})=>{let r=e.trim();if(!r)return Promise.reject(Error("Say what to change"));if(!v.features.includes("prompt"))return Promise.reject(Error("The editor does not offer prompts here"));let n=`prompt_${++L}`,a=void 0===t.uid?v.selectedUid:t.uid;return new Promise((e,t)=>{let o=setTimeout(()=>{P(n)?.reject(Error("The editor did not answer in time"))},12e4);A.set(n,{resolve:e,reject:t,timer:o}),y({prompting:!0}),k("prompt",{id:n,prompt:r,uid:a})})},x.undo=()=>k("undo"),x.select=e=>{S(e,!1),k("select",{uid:e})};let $=null;f.push(()=>$?.destroy()),f.push(()=>{for(let e of A.keys())P(e)?.reject(Error("The bridge was destroyed"))});let O=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)N();else if("update"===n.type&&n.entry)u.emit("update",{entry:n.entry,selectedUid:n.selectedUid??null}),e.requestAnimationFrame(()=>S(n.selectedUid,!1)),$?.refresh();else if("select"===n.type)S(n.uid,!0);else if("saved"===n.type||"published"===n.type)u.emit(n.type,{}),0===u.listeners.update.size&&e.location.reload();else if("features"===n.type&&Array.isArray(n.features))y({features:n.features.filter(e=>"string"==typeof e)});else if("stats"===n.type)y({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:a,viewers:o,rate:i}=n??{};b(e)&&b(a)&&b(o)&&b(i)&&(t[r]={clicks:e,clickers:a,viewers:o,rate:i})}return t})(n.stats),statsVisible:!1!==n.visible}),($||Object.keys(v.stats).length)&&($??($=((e,{selector:t,onSelect:r,labels:n})=>{let s=e.document,d={...a,...n},c=s.createElement("div");c.setAttribute("data-obelism-stats","");let p=c.attachShadow({mode:"open"}),g=s.createElement("style");g.textContent=i;let u=s.createElement("div");u.className="layer",p.append(g,u),s.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[a,i]of Object.entries(h)){let c=s.querySelector(t(a));if(!c)continue;let p=c.getBoundingClientRect();if(!p.width&&!p.height||p.bottom<0||p.top>n)continue;let g=s.createElement("button");g.type="button",g.className="badge",g.dataset.uid=a,g.textContent=o(d.clicked,{rate:Math.round(100*i.rate)}),g.title=o(d.title,{clickers:i.clickers,viewers:i.viewers,clicks:i.clicks});let{place:h,top:b,left:m}=l(p,e.innerWidth);g.dataset.place=h,g.style.top=`${b}px`,g.style.left=`${m}px`,g.addEventListener("click",()=>r(a)),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(s.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:m,onSelect:e=>x.select(e)})),$.update(v.stats,v.statsVisible));else if("promptState"===n.type)y({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",O),f.push(()=>e.removeEventListener("message",O)),"loading"===w.readyState?(w.addEventListener("DOMContentLoaded",N,{once:!0}),f.push(()=>w.removeEventListener("DOMContentLoaded",N))):N(),x})(v,new URL(e||S).origin)).isEditing||v.parent!==v?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})(v.document);if(f&&(u=((e,n,{pagePath:a=e=>`/${e}`}={})=>{let o=e.document,i=p(),l=[],s=new Map,g=[],u=new Set,h=null,b=c,f=e=>{b={...b,...e},i.emit("change",b)},v=()=>f({unsaved:[...s.values()].some(({content:e,saved:t})=>!C(e,t)),canUndo:g.length>0}),y=async(t,r)=>{let a=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)}),o=await a.json().catch(()=>({}));if(401===a.status)throw f({features:[]}),Error("You were signed out. Sign in again to edit.");if(!a.ok)throw Error("string"==typeof o.error?o.error:`Obelism Content answered ${a.status}`);return o},x=()=>o.querySelector(`[${r}]`)?.getAttribute(r)??null,w=()=>{if(!h)return;let e=h.space.locales.map(({code:e})=>e),t=o.documentElement.lang;if(e.includes(t))return t;let r=t.split("-")[0]??"";return e.includes(r)?r:h.space.defaultLocale},k=async e=>{let t=s.get(e);if(t)return t;let r=await y(`entries/${encodeURIComponent(e)}`),n={content:r.content,saved:r.content,revision:r.draftRevision};return s.set(e,n),n},E=e=>{let t,n=void 0===e?b.selectedUid:e,a=(t=n?o.querySelector(m(n)):null,t?.closest(`[${r}]`)?.getAttribute(r)??x());if(!a)throw Error("Nothing on this page is marked as an entry: add editable(entry)");return{uid:n,entryId:a}},S=e=>{o.querySelectorAll("[data-cms-selected]").forEach(e=>{e.removeAttribute("data-cms-selected")}),b.selectedUid!==e&&f({selectedUid:e}),e&&o.querySelector(m(e))?.setAttribute("data-cms-selected","")},N=async t=>{if(0===i.listeners.update.size)return;let r=s.get(t)?.content,{entry:n}=await y(`entries/${encodeURIComponent(t)}/preview`,{content:r,locale:w()});i.emit("update",{entry:n,selectedUid:b.selectedUid}),e.requestAnimationFrame(()=>S(b.selectedUid))},A=t=>{i.emit(t,{}),0===i.listeners.update.size&&e.location.reload()},L=async()=>{for(let[e,t]of s){if(C(t.content,t.saved))continue;let{draftRevision:r}=await y(`entries/${encodeURIComponent(e)}/save`,{content:t.content,baseRevision:t.revision});t.saved=t.content,t.revision=r,u.add(e)}g.length=0,v()},P={isEditing:!0,mode:"site",get entryId(){return x()},environment:null,on:i.on,getState:()=>b,async prompt(e,t={}){let r=e.trim();if(!r)throw Error("Say what to change");if(!b.features.includes("prompt"))throw Error("You may not edit content here");let{uid:n,entryId:a}=E(t.uid);f({prompting:!0});try{let e=await k(a),t=await y(`entries/${encodeURIComponent(a)}/prompt`,{prompt:r,content:e.content,locale:w(),uid:n});return g.push({entryId:a,content:e.content}),e.content=t.content,v(),await N(a),{summary:t.summary}}finally{f({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(!b.features.includes("create"))throw Error("You may not add pages here");if(b.unsaved)throw Error("Save or undo your changes before adding a page");f({prompting:!0});try{let r=await y("entries",{path:t,prompt:n,locale:w(),from:x()}),o=a(r.path,w()??"");return e.location.assign(o),{summary:r.summary,entryId:r.entryId,path:r.path,url:o}}finally{f({prompting:!1})}},async view(e={}){let{uid:t,entryId:r}=E(e.uid),n=await k(r),{view:a}=await y(`entries/${encodeURIComponent(r)}/view`,{content:n.content,locale:w(),uid:t});return a},async applyJson(e,t={}){if(!b.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}=E(t.uid);f({prompting:!0});try{let t=await k(n),a=await y(`entries/${encodeURIComponent(n)}/apply`,{changes:e,content:t.content,locale:w(),uid:r});return C(a.content,t.content)||(g.push({entryId:n,content:t.content}),t.content=a.content,v(),await N(n)),{changed:a.changed??[],...a.view&&{view:a.view}}}finally{f({prompting:!1})}},async pages(){let{pages:e}=await y("pages"),t=[w(),h?.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:a(n,r)}]})},openPage(t){(!b.unsaved||e.confirm("Leave this page and lose the changes you have not saved?"))&&(s.clear(),g.length=0,v(),e.location.assign(t.url))},undo(){let e=g.pop(),t=e&&s.get(e.entryId);e&&t&&(t.content=e.content,v(),N(e.entryId).catch(e=>console.error("[@obelism/content bridge]",e)))},async save(){if(!b.features.includes("save"))throw Error("You may not edit content here");f({saving:!0});try{await L()}finally{f({saving:!1})}A("saved")},async publish(){if(!b.features.includes("publish"))throw Error("You may not publish here");f({publishing:!0});try{await L();let e=x(),t=u.size>0?[...u]: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 y(`entries/${encodeURIComponent(e)}/publish`,{}),u.delete(e)}finally{f({publishing:!1})}A("published")},signOut(){if(b.unsaved&&!e.confirm("Sign out and lose the changes you have not saved?"))return;s.clear(),v();let t=e.location.pathname+e.location.search;e.location.href=`${n}/logout?return_to=${encodeURIComponent(t)}`},select(e){S(e)},setSelecting(e){e?o.documentElement.setAttribute("data-cms-selecting",""):o.documentElement.removeAttribute("data-cms-selecting"),f({selecting:e})},destroy(){l.splice(0).forEach(e=>e())}},$=o.createElement("style");$.textContent=d("html[data-cms-selecting] "),o.head.appendChild($),l.push(()=>$.remove()),l.push(()=>o.documentElement.removeAttribute("data-cms-selecting"));let O=e=>{if(!b.selecting)return;let r=e.target,n=r?.closest?.(`[${t}]`);n&&(e.preventDefault(),e.stopPropagation(),S(n.getAttribute(t)))};o.addEventListener("click",O,!0),l.push(()=>o.removeEventListener("click",O,!0));let U=e=>{b.unsaved&&(e.preventDefault(),e.returnValue="")};return e.addEventListener("beforeunload",U),l.push(()=>e.removeEventListener("beforeunload",U)),y("session").then(e=>{h=e,f({features:e.features})}).catch(e=>console.error("[@obelism/content bridge]",e)),P})(v,f,{pagePath:g})),u.isEditing&&s){let e=E(v.document,u,!0===s?{}:s),t=u.destroy;u.destroy=()=>{e(),t()}}}return v[N]=u,u};(e=window).ObelismBridge=L((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:L,mountPromptBox:E}}();
|
|
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}}();
|