@obelism/content 0.12.0 → 0.13.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 +17 -0
- package/dist/bin/content.js +2 -1
- package/dist/bridge.d.mts +40 -1
- package/dist/bridge.d.mts.map +1 -1
- package/dist/bridge.d.ts +40 -1
- package/dist/bridge.d.ts.map +1 -1
- package/dist/bridge.global.js +59 -3
- package/dist/bridge.js +671 -34
- package/dist/bridge.mjs +671 -34
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/site.js +5 -1
- package/dist/site.mjs +5 -1
- package/dist/{types-hmpsikmo.d.ts → types-m3j4tltp.d.ts} +2 -2
- package/dist/{types-hmpsikmo.d.ts.map → types-m3j4tltp.d.ts.map} +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -155,6 +155,22 @@ 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 **JSON**. JSON shows the
|
|
159
|
+
page, or the selected block, as the language model sees it (one locale, rich
|
|
160
|
+
text as Markdown, blocks with `_uid` and `_type`), with the changes that
|
|
161
|
+
aren't saved yet: change it by hand, or tweak what a prompt just made, and
|
|
162
|
+
apply it (Ctrl/Cmd + Enter). It is checked like a prompt's answer, lands in
|
|
163
|
+
the unsaved changes and undoes the same way. A chip under the prompt names
|
|
164
|
+
the page and opens every page of the space, drafts included, to go to one
|
|
165
|
+
(at `pagePath`, in the page's language when it has a path there):
|
|
166
|
+
|
|
167
|
+
```ts
|
|
168
|
+
const view = await bridge.view() // or { uid } for a block
|
|
169
|
+
const { changed } = await bridge.applyJson({ ...view, title: 'Pricing' })
|
|
170
|
+
const pages = await bridge.pages() // { entryId, name, status, path, url }[]
|
|
171
|
+
bridge.openPage(pages[0]) // asks first when changes aren't saved
|
|
172
|
+
```
|
|
173
|
+
|
|
158
174
|
The CMS runs prompts on Workers AI. To use your own model, set a prompt
|
|
159
175
|
endpoint under Space settings → Prompt editing and answer it with
|
|
160
176
|
`createPromptHandler` (it verifies the signed request; you call the model):
|
|
@@ -333,6 +349,7 @@ npx @obelism/content types --file content/content-model.json # from the model f
|
|
|
333
349
|
Pages and data become `Entry<{ …fields }, 'apiId'>`, blocks
|
|
334
350
|
`Block<{ …fields }, 'apiId'>`, named after the apiId (`blogPost` →
|
|
335
351
|
`BlogPost`), with `ContentEntry` and `ContentBlock` as the unions of them.
|
|
352
|
+
Content type and field descriptions become JSDoc, so editors show them.
|
|
336
353
|
Each field is typed by what the delivery API answers with its defaults (one
|
|
337
354
|
locale, rich text as a document), and `| null` when empty:
|
|
338
355
|
|
package/dist/bin/content.js
CHANGED
|
@@ -549,7 +549,8 @@ const union = (members)=>[
|
|
|
549
549
|
const list = (type, multiple)=>multiple ? type.includes(' | ') ? `(${type})[]` : `${type}[]` : type;
|
|
550
550
|
// `unknown` (a json field) holds null already.
|
|
551
551
|
const nullable = (type)=>type === 'unknown' ? type : `${type} | null`;
|
|
552
|
-
|
|
552
|
+
// JSDoc, so editors show it on hover.
|
|
553
|
+
const comment = (text, indent)=>`${indent}/** ${text.replace(/\s+/g, ' ').trim().replace(/\*\//g, '*\\/')} */\n`;
|
|
553
554
|
const generateTypes = (model)=>{
|
|
554
555
|
const types = model.contentTypes;
|
|
555
556
|
const blockTypes = types.filter(({ kind })=>kind === 'block');
|
package/dist/bridge.d.mts
CHANGED
|
@@ -54,6 +54,18 @@ type CreatePageResult = {
|
|
|
54
54
|
path: string;
|
|
55
55
|
url: string;
|
|
56
56
|
};
|
|
57
|
+
type ApplyJsonResult = {
|
|
58
|
+
changed: string[];
|
|
59
|
+
view?: Record<string, unknown> | undefined;
|
|
60
|
+
};
|
|
61
|
+
type SitePage = {
|
|
62
|
+
entryId: string;
|
|
63
|
+
name: string;
|
|
64
|
+
contentType: string;
|
|
65
|
+
status: 'draft' | 'published' | 'changed';
|
|
66
|
+
path: string;
|
|
67
|
+
url: string;
|
|
68
|
+
};
|
|
57
69
|
type ContentBridge = {
|
|
58
70
|
readonly isEditing: boolean;
|
|
59
71
|
readonly mode: 'editor' | 'site' | null;
|
|
@@ -65,6 +77,14 @@ type ContentBridge = {
|
|
|
65
77
|
uid?: string | null;
|
|
66
78
|
}): Promise<PromptResult>;
|
|
67
79
|
createPage(path: string, prompt: string): Promise<CreatePageResult>;
|
|
80
|
+
view(options?: {
|
|
81
|
+
uid?: string | null | undefined;
|
|
82
|
+
}): Promise<Record<string, unknown>>;
|
|
83
|
+
applyJson(changes: Record<string, unknown>, options?: {
|
|
84
|
+
uid?: string | null | undefined;
|
|
85
|
+
}): Promise<ApplyJsonResult>;
|
|
86
|
+
pages(): Promise<SitePage[]>;
|
|
87
|
+
openPage(page: SitePage): void;
|
|
68
88
|
undo(): void;
|
|
69
89
|
save(): Promise<void>;
|
|
70
90
|
publish(): Promise<void>;
|
|
@@ -102,6 +122,25 @@ type PromptLabels = {
|
|
|
102
122
|
pathPlaceholder: string;
|
|
103
123
|
creating: string;
|
|
104
124
|
created: string;
|
|
125
|
+
modes: string;
|
|
126
|
+
modePrompt: string;
|
|
127
|
+
modeJson: string;
|
|
128
|
+
json: string;
|
|
129
|
+
jsonLoading: string;
|
|
130
|
+
jsonReload: string;
|
|
131
|
+
jsonKept: string;
|
|
132
|
+
jsonInvalidAt: string;
|
|
133
|
+
jsonInvalid: string;
|
|
134
|
+
jsonNotObject: string;
|
|
135
|
+
applied: string;
|
|
136
|
+
unchanged: string;
|
|
137
|
+
pages: string;
|
|
138
|
+
pagesSearch: string;
|
|
139
|
+
pagesLoading: string;
|
|
140
|
+
pagesEmpty: string;
|
|
141
|
+
pageCurrent: string;
|
|
142
|
+
pageDraft: string;
|
|
143
|
+
pageChanged: string;
|
|
105
144
|
};
|
|
106
145
|
declare const DEFAULT_PROMPT_LABELS: PromptLabels;
|
|
107
146
|
type PromptBoxOptions = {
|
|
@@ -118,5 +157,5 @@ declare const peekContentBridge: () => ContentBridge | null;
|
|
|
118
157
|
declare const getContentBridge: ({ url, prompt, pagePath, }?: BridgeOptions) => ContentBridge;
|
|
119
158
|
|
|
120
159
|
export { DEFAULT_PROMPT_LABELS, DEFAULT_STATS_LABELS, INITIAL_STATE, getContentBridge, mountPromptBox, mountStatsOverlay, peekContentBridge };
|
|
121
|
-
export type { BlockStats, BridgeEvent, BridgeEvents, BridgeListener, BridgeOptions, BridgeState, ContentBridge, CreatePageResult, PromptBoxOptions, PromptLabels, PromptResult, StatsLabels, StatsOverlay };
|
|
160
|
+
export type { ApplyJsonResult, BlockStats, BridgeEvent, BridgeEvents, BridgeListener, BridgeOptions, BridgeState, ContentBridge, CreatePageResult, PromptBoxOptions, PromptLabels, PromptResult, SitePage, StatsLabels, StatsOverlay };
|
|
122
161
|
//# 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,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,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,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;;AC5ExC,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;AACA;AACA;AACA;AACA;AACA,cAAc,qBAAqB,EAAE,YAAY;AACjD,KAAK,gBAAgB;AACrB,aAAa,OAAO,CAAC,YAAY;AACjC;AAEA,cAAc,cAAc,QAAQ,QAAQ,UAAU,aAAa,YAAY,gBAAgB;;AC7C/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
|
@@ -54,6 +54,18 @@ type CreatePageResult = {
|
|
|
54
54
|
path: string;
|
|
55
55
|
url: string;
|
|
56
56
|
};
|
|
57
|
+
type ApplyJsonResult = {
|
|
58
|
+
changed: string[];
|
|
59
|
+
view?: Record<string, unknown> | undefined;
|
|
60
|
+
};
|
|
61
|
+
type SitePage = {
|
|
62
|
+
entryId: string;
|
|
63
|
+
name: string;
|
|
64
|
+
contentType: string;
|
|
65
|
+
status: 'draft' | 'published' | 'changed';
|
|
66
|
+
path: string;
|
|
67
|
+
url: string;
|
|
68
|
+
};
|
|
57
69
|
type ContentBridge = {
|
|
58
70
|
readonly isEditing: boolean;
|
|
59
71
|
readonly mode: 'editor' | 'site' | null;
|
|
@@ -65,6 +77,14 @@ type ContentBridge = {
|
|
|
65
77
|
uid?: string | null;
|
|
66
78
|
}): Promise<PromptResult>;
|
|
67
79
|
createPage(path: string, prompt: string): Promise<CreatePageResult>;
|
|
80
|
+
view(options?: {
|
|
81
|
+
uid?: string | null | undefined;
|
|
82
|
+
}): Promise<Record<string, unknown>>;
|
|
83
|
+
applyJson(changes: Record<string, unknown>, options?: {
|
|
84
|
+
uid?: string | null | undefined;
|
|
85
|
+
}): Promise<ApplyJsonResult>;
|
|
86
|
+
pages(): Promise<SitePage[]>;
|
|
87
|
+
openPage(page: SitePage): void;
|
|
68
88
|
undo(): void;
|
|
69
89
|
save(): Promise<void>;
|
|
70
90
|
publish(): Promise<void>;
|
|
@@ -102,6 +122,25 @@ type PromptLabels = {
|
|
|
102
122
|
pathPlaceholder: string;
|
|
103
123
|
creating: string;
|
|
104
124
|
created: string;
|
|
125
|
+
modes: string;
|
|
126
|
+
modePrompt: string;
|
|
127
|
+
modeJson: string;
|
|
128
|
+
json: string;
|
|
129
|
+
jsonLoading: string;
|
|
130
|
+
jsonReload: string;
|
|
131
|
+
jsonKept: string;
|
|
132
|
+
jsonInvalidAt: string;
|
|
133
|
+
jsonInvalid: string;
|
|
134
|
+
jsonNotObject: string;
|
|
135
|
+
applied: string;
|
|
136
|
+
unchanged: string;
|
|
137
|
+
pages: string;
|
|
138
|
+
pagesSearch: string;
|
|
139
|
+
pagesLoading: string;
|
|
140
|
+
pagesEmpty: string;
|
|
141
|
+
pageCurrent: string;
|
|
142
|
+
pageDraft: string;
|
|
143
|
+
pageChanged: string;
|
|
105
144
|
};
|
|
106
145
|
declare const DEFAULT_PROMPT_LABELS: PromptLabels;
|
|
107
146
|
type PromptBoxOptions = {
|
|
@@ -118,5 +157,5 @@ declare const peekContentBridge: () => ContentBridge | null;
|
|
|
118
157
|
declare const getContentBridge: ({ url, prompt, pagePath, }?: BridgeOptions) => ContentBridge;
|
|
119
158
|
|
|
120
159
|
export { DEFAULT_PROMPT_LABELS, DEFAULT_STATS_LABELS, INITIAL_STATE, getContentBridge, mountPromptBox, mountStatsOverlay, peekContentBridge };
|
|
121
|
-
export type { BlockStats, BridgeEvent, BridgeEvents, BridgeListener, BridgeOptions, BridgeState, ContentBridge, CreatePageResult, PromptBoxOptions, PromptLabels, PromptResult, StatsLabels, StatsOverlay };
|
|
160
|
+
export type { ApplyJsonResult, BlockStats, BridgeEvent, BridgeEvents, BridgeListener, BridgeOptions, BridgeState, ContentBridge, CreatePageResult, PromptBoxOptions, PromptLabels, PromptResult, SitePage, StatsLabels, StatsOverlay };
|
|
122
161
|
//# 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,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,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,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;;AC5ExC,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;AACA;AACA;AACA;AACA;AACA,cAAc,qBAAqB,EAAE,YAAY;AACjD,KAAK,gBAAgB;AACrB,aAAa,OAAO,CAAC,YAAY;AACjC;AAEA,cAAc,cAAc,QAAQ,QAAQ,UAAU,aAAa,YAAY,gBAAgB;;AC7C/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",a={clicked:"{rate}% clicked",title:"{clickers} of {viewers} visitors of its page clicked it in the last 30 days ({clicks} clicks)"},o=(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
|
+
`,l=(e,t)=>e.height>=64?{place:"inside",top:Math.max(e.top,0)+8,left:e.right-8}:e.right+8+140<=t?{place:"beside",top:e.top+e.height/2,left:e.right+8}:{place:"above",top:e.top-4,left:e.right},s="#d58a1f",d=(e="")=>`${e}[${t}]{cursor:pointer;transition:outline-color .15s}${e}[${t}]:hover{outline:2px dashed ${s};outline-offset:2px}${e}[${t}][data-cms-selected]{outline:2px solid ${s};outline-offset:2px}`,c={features:[],selectedUid:null,prompting:!1,canUndo:!1,unsaved:!1,saving:!1,publishing:!1,selecting:!1,stats:{},statsVisible:!1},p=()=>{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)}}}},g=()=>Promise.reject(Error("Save and publish in the visual editor itself")),u=()=>Promise.reject(Error("Only while signed in to edit on the site")),h={prompt:()=>Promise.reject(Error("Prompts only work inside the visual editor")),createPage:()=>Promise.reject(Error("New pages are made on the site itself")),view:u,applyJson:u,pages:u,openPage:()=>{},undo:()=>{},save:g,publish:g,signOut:()=>{},select:()=>{},setSelecting:()=>{}},b=e=>"number"==typeof e&&Number.isFinite(e)&&e>=0,m=e=>`[${t}="${e.replace(/["\\]/g,"\\$&")}"]`,f=(e,t)=>{let r=p();e.on("saved",()=>r.emit("saved",{})),e.on("published",()=>r.emit("published",{}));let a=!1;return{isEditing:e.isEditing,mode:e.isEditing?"editor":null,entryId:e.entryId,environment:t.get(n),on:(t,n)=>("update"!==t||a||(a=!0,e.on("update",e=>{let t=e?.entry;t&&r.emit("update",{entry:t,selectedUid:null})})),r.on(t,n)),getState:()=>c,...h,destroy:()=>{}}},v={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",modeJson:"JSON",json:"The content as JSON",jsonLoading:"Loading the JSON…",jsonReload:"Reload the JSON",jsonKept:"Kept your unapplied JSON. Reload to see the current content.",jsonInvalidAt:"Not valid JSON at line {line}, column {column}",jsonInvalid:"Not valid JSON",jsonNotObject:'The JSON has to be an object of fields, like { "title": … }',applied:"Applied",unchanged:"Nothing changed",pages:"Pages",pagesSearch:"Find a page",pagesLoading:"Loading pages…",pagesEmpty:"No pages match",pageCurrent:"This page",pageDraft:"Draft",pageChanged:"Changed"},y={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"/>',reload:'<path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"/><path d="M21 3v5h-5"/><path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"/><path d="M8 16H3v5"/>',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"/>'},x=`
|
|
26
26
|
:host { all: initial; }
|
|
27
27
|
* { box-sizing: border-box; font: inherit; color: inherit; margin: 0; }
|
|
28
28
|
.root {
|
|
@@ -119,6 +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
|
+
/* JSON: a plain code editor, taller, scrolling instead of wrapping. */
|
|
123
|
+
textarea.code {
|
|
124
|
+
height: 40vh; min-height: 160px; max-height: 50vh; overflow: auto; resize: vertical;
|
|
125
|
+
white-space: pre; overflow-wrap: normal; tab-size: 2;
|
|
126
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, 'Liberation Mono', monospace;
|
|
127
|
+
font-size: 13px; line-height: 1.55;
|
|
128
|
+
}
|
|
122
129
|
/* New page: where it goes, above what it is for. */
|
|
123
130
|
.path {
|
|
124
131
|
display: flex; align-items: center; gap: 10px; padding: 16px 22px 0;
|
|
@@ -162,6 +169,21 @@ button.chip:disabled { opacity: .5; }
|
|
|
162
169
|
.icon-button.primary { background: rgb(var(--theme-accent-rgb)); color: #fff; }
|
|
163
170
|
.icon-button.primary:hover:not(:disabled) { background: rgb(var(--theme-accent-rgb)); color: #fff; opacity: .88; }
|
|
164
171
|
.icon-button.primary:disabled { opacity: .35; }
|
|
172
|
+
/* Prompt or JSON: two small pills in one track. */
|
|
173
|
+
.modes {
|
|
174
|
+
display: inline-flex; flex: none; gap: 2px; padding: 2px; border-radius: var(--border-radius-pill);
|
|
175
|
+
border: 1px solid rgb(var(--theme-border-rgb) / .2); background: rgb(var(--theme-background-actions-rgb) / .6);
|
|
176
|
+
}
|
|
177
|
+
.modes button {
|
|
178
|
+
height: 28px; padding: 0 12px; border-radius: var(--border-radius-pill); font-size: 13px;
|
|
179
|
+
color: rgb(var(--theme-foreground-muted-rgb));
|
|
180
|
+
transition: background-color .25s var(--ease-roll), color .25s var(--ease-roll);
|
|
181
|
+
}
|
|
182
|
+
.modes button:hover { color: rgb(var(--theme-foreground-rgb)); }
|
|
183
|
+
.modes button[aria-pressed='true'] {
|
|
184
|
+
background: rgb(var(--theme-background-alt-rgb)); color: rgb(var(--theme-foreground-rgb));
|
|
185
|
+
box-shadow: 0 1px 2px rgb(var(--color-black-rgb) / .08);
|
|
186
|
+
}
|
|
165
187
|
.divider { width: 1px; height: 20px; background: rgb(var(--theme-border-rgb) / .3); margin: 0 4px; }
|
|
166
188
|
|
|
167
189
|
/* On the site: storing the draft, and the way out. */
|
|
@@ -178,5 +200,39 @@ button.chip:disabled { opacity: .5; }
|
|
|
178
200
|
display: inline-block; width: 7px; height: 7px; border-radius: 50%;
|
|
179
201
|
background: rgb(var(--theme-accent-rgb)); margin-right: 8px;
|
|
180
202
|
}
|
|
203
|
+
|
|
204
|
+
/* The pages: a search above a list, in place of the prompt while open. */
|
|
205
|
+
.page-chip { min-width: 0; max-width: 50%; gap: 6px; }
|
|
206
|
+
.page-chip > span:not(.icon) { overflow: hidden; text-overflow: ellipsis; }
|
|
207
|
+
.page-chip .icon:last-child { color: rgb(var(--theme-foreground-muted-rgb)); margin-right: -4px; }
|
|
208
|
+
.page-chip .icon:last-child svg { width: 14px; height: 14px; }
|
|
209
|
+
.pages { display: grid; gap: 8px; padding: 16px 12px 12px; }
|
|
210
|
+
.search {
|
|
211
|
+
display: flex; align-items: center; gap: 8px; height: 38px; padding: 0 14px; margin: 0 4px;
|
|
212
|
+
border: 1px solid rgb(var(--theme-border-rgb) / .25); border-radius: var(--border-radius-pill);
|
|
213
|
+
background: rgb(var(--theme-background-actions-rgb) / .45); color: rgb(var(--theme-foreground-muted-rgb));
|
|
214
|
+
transition: border-color .25s var(--ease-roll);
|
|
215
|
+
}
|
|
216
|
+
.search:focus-within { border-color: rgb(var(--theme-accent-rgb)); }
|
|
217
|
+
.search input { flex: 1; min-width: 0; height: 100%; border: 0; outline: 0; background: transparent; color: rgb(var(--theme-foreground-rgb)); }
|
|
218
|
+
.search input::placeholder { color: rgb(var(--theme-foreground-muted-rgb)); }
|
|
219
|
+
.options { list-style: none; padding: 0; max-height: min(300px, 40vh); overflow-y: auto; display: grid; gap: 2px; }
|
|
220
|
+
.option {
|
|
221
|
+
display: flex; align-items: center; gap: 10px; padding: 8px 12px; border-radius: 12px; cursor: pointer;
|
|
222
|
+
transition: background-color .15s var(--ease-roll);
|
|
223
|
+
}
|
|
224
|
+
.option:hover, .option.active { background: rgb(var(--theme-background-actions-rgb) / .7); }
|
|
225
|
+
.option-text { flex: 1; min-width: 0; display: grid; }
|
|
226
|
+
.option-text > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
227
|
+
.option-path { font-size: 12px; color: rgb(var(--theme-foreground-muted-rgb)); }
|
|
228
|
+
.badge {
|
|
229
|
+
flex: none; font-size: 12px; padding: 1px 8px; border-radius: var(--border-radius-pill);
|
|
230
|
+
border: 1px solid rgb(var(--theme-border-rgb) / .3); color: rgb(var(--theme-foreground-muted-rgb));
|
|
231
|
+
}
|
|
232
|
+
.option .icon { color: rgb(var(--theme-accent-rgb)); }
|
|
233
|
+
.empty { padding: 8px 12px; color: rgb(var(--theme-foreground-muted-rgb)); }
|
|
234
|
+
.empty.error { color: var(--theme-error); }
|
|
181
235
|
[hidden] { display: none !important; }
|
|
182
|
-
`,x=(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},w=(e,t)=>{let r=x(e,"span",{className:"icon"});return r.setAttribute("aria-hidden","true"),r.innerHTML=`<svg viewBox="0 0 24 24">${v[t]}</svg>`,r},k=(e,t,r={})=>{let n={...f,...r.labels},o=x(e,"div");o.setAttribute("data-obelism-content-prompt","");let a=o.attachShadow({mode:"open"}),i="site"===t.mode,s=x(e,"span",{textContent:n.open}),l=x(e,"button",{className:"pill",type:"button"},s,x(e,"span",{className:"mark",textContent:"⁜"})),d=x(e,"span",{className:"pill compact"},`${n.viewingDrafts} \xb7 `),c=x(e,"button",{className:"link",type:"button",textContent:n.signOut});d.appendChild(c);let p=x(e,"p",{className:"status"});p.setAttribute("role","status");let g=x(e,"textarea",{placeholder:n.placeholder,rows:1});g.setAttribute("aria-label",n.open);let u=w(e,"page"),h=w(e,"block"),b=x(e,"span"),m=x(e,"button",{type:"button",title:n.clearBlock});m.setAttribute("aria-label",n.clearBlock),m.appendChild(w(e,"close"));let v=x(e,"span",{className:"chip scope"},u,h,b,m),k=x(e,"button",{className:"action chip",type:"button"},w(e,"undo"),n.undo),E=x(e,"button",{className:"action chip",type:"button"},w(e,"newPage"),n.newPage),S=x(e,"button",{type:"button",title:n.newPageCancel});S.setAttribute("aria-label",n.newPageCancel),S.appendChild(w(e,"close"));let C=x(e,"span",{className:"chip scope"},w(e,"newPage"),x(e,"span",{textContent:n.newPage}),S),N=x(e,"input",{type:"text",placeholder:n.pathPlaceholder,autocomplete:"off",spellcheck:!1}),L=x(e,"label",{className:"path"},x(e,"span",{textContent:n.path}),N),U=x(e,"button",{className:"close icon-button",type:"button",title:n.close},w(e,"close"));U.setAttribute("aria-label",n.close);let P=x(e,"button",{className:"action primary icon-button",type:"submit"},x(e,"span",{className:"visually-hidden",textContent:n.send}),w(e,"send"));P.title=n.send;let $=x(e,"span",{className:"unsaved"});$.appendChild(x(e,"span",{className:"dot"})),$.appendChild(e.createTextNode(n.unsaved));let A=x(e,"button",{className:"link",type:"button",textContent:n.signOut}),O=x(e,"button",{className:"action chip",type:"button",textContent:n.save}),I=x(e,"button",{className:"action chip",type:"button",textContent:n.publish}),M=x(e,"div",{className:"footer"},$,x(e,"span",{className:"spacer"}),A,O,I),j=x(e,"form",{className:"panel"},p,L,g,x(e,"div",{className:"toolbar"},v,C,k,E,x(e,"span",{className:"spacer"}),U,x(e,"span",{className:"divider"}),P),M),z=x(e,"div",{className:"root"},x(e,"div",{className:"bar"},l,d),j);a.append(x(e,"style",{textContent:y}),z);let R=!1,B=!1,D=null,T=e=>{let r=e.features.includes("prompt"),o=e.saving||e.publishing,a=e.prompting||o;z.hidden=!r&&!i,l.hidden=R||!r,d.hidden=r||!i,j.hidden=!R||!r;let c=i&&e.features.includes("create"),f=i&&null===t.entryId,y=f&&c;c||(B=!1),y&&(B=!0),s.textContent=y?n.newPage:n.open,S.hidden=y,v.hidden=B,C.hidden=!B,E.hidden=B||!c,E.disabled=a,L.hidden=!B,N.disabled=a,g.placeholder=B?n.newPagePlaceholder:n.placeholder,b.textContent=e.selectedUid?n.scopeBlock:n.scopeEntry,m.hidden=!e.selectedUid,u.hidden=!!e.selectedUid,h.hidden=!e.selectedUid,k.hidden=B||!e.canUndo,k.disabled=a,P.disabled=a||""===g.value.trim()||B&&""===N.value.trim(),g.disabled=a,O.hidden=!e.features.includes("save")||f,O.disabled=a||!e.unsaved,O.textContent=e.saving?n.saving:n.save,I.hidden=!e.features.includes("publish")||f,I.disabled=a,I.textContent=e.publishing?n.publishing:n.publish,A.hidden=!i,M.hidden=!i,$.hidden=!e.unsaved;let x=e.prompting?B?n.creating:n.working:D?.text??(!i||B||e.selectedUid?"":n.selectHint);p.textContent=x,p.hidden=!x,p.className=`status${e.prompting?" working":""}${!a&&D?.error?" error":""}`},q=()=>T(t.getState()),V=()=>{g.style.height="auto",g.style.height=`${g.scrollHeight}px`},H=async()=>{let e=g.value.trim();if(e&&!t.getState().prompting){D=null;try{if(B){let r=N.value.trim();if(!r)return N.focus();await t.createPage(r,e),D={text:n.created,error:!1}}else{let{summary:r}=await t.prompt(e);D={text:r,error:!1}}g.value="",V()}catch(e){D={text:e instanceof Error?e.message:String(e),error:!0}}q(),g.focus()}},F=e=>{R=e,q(),i&&t.setSelecting(R&&!B)},Y=e=>{B=e,D=null,t.setSelecting(R&&!B),B&&t.select(null),q(),(B?N:g).focus()},_=async e=>{D=null;try{await t[e](),D={text:"save"===e?n.saved:n.published,error:!1}}catch(e){D={text:e instanceof Error?e.message:String(e),error:!0}}q()};l.addEventListener("click",()=>{F(!0),(B?N:g).focus()}),U.addEventListener("click",()=>F(!1)),O.addEventListener("click",()=>void _("save")),I.addEventListener("click",()=>void _("publish")),A.addEventListener("click",()=>t.signOut()),c.addEventListener("click",()=>t.signOut()),m.addEventListener("click",()=>t.select(null)),E.addEventListener("click",()=>Y(!0)),S.addEventListener("click",()=>Y(!1)),N.addEventListener("input",q),N.addEventListener("keydown",e=>{"Enter"!==e.key||e.isComposing?"Escape"===e.key&&F(!1):(e.preventDefault(),g.focus())}),k.addEventListener("click",()=>{D=null,t.undo()}),j.addEventListener("submit",e=>{e.preventDefault(),H()}),g.addEventListener("input",()=>{V(),q()}),g.addEventListener("keydown",e=>{"Enter"!==e.key||e.shiftKey||e.isComposing?"Escape"===e.key&&F(!1):(e.preventDefault(),H())});let W=t.on("change",T);return q(),e.body.appendChild(o),()=>{W(),o.remove()}},E="https://content.obelism.studio",S=(e,t)=>JSON.stringify(e)===JSON.stringify(t),C=Symbol.for("@obelism/content/bridge"),N=m({isEditing:!1,entryId:null,on:()=>{}},new URLSearchParams),L=({url:e,prompt:l=!0,pagePath:g}={})=>{let f;if("u"<typeof window)return N;let v=window;if(v[C])return v[C];if(v.ObelismBridge)f=m(v.ObelismBridge,new URLSearchParams(v.location.search));else{let m=(f=((e,r)=>{let l=new URLSearchParams(e.location.search),g=e.parent!==e&&l.has("cms_preview"),m=p(),f=[],v={...c,selecting:!0},y=e=>{v={...v,...e},m.emit("change",v)},x={isEditing:g,mode:g?"editor":null,entryId:l.get("cms_entry"),environment:l.get(n),on:m.on,getState:()=>v,...u,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(b(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 o=n.getAttribute(t);S(o,!1),k("select",{uid:o})};w.addEventListener("click",C,!0),f.push(()=>w.removeEventListener("click",C,!0));let N=()=>k("ready",{url:e.location.href}),L=new Map,U=0,P=e=>{let t=L.get(e);return t?(clearTimeout(t.timer),L.delete(e),0===L.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_${++U}`,o=void 0===t.uid?v.selectedUid:t.uid;return new Promise((e,t)=>{let a=setTimeout(()=>{P(n)?.reject(Error("The editor did not answer in time"))},12e4);L.set(n,{resolve:e,reject:t,timer:a}),y({prompting:!0}),k("prompt",{id:n,prompt:r,uid:o})})},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 L.keys())P(e)?.reject(Error("The bridge was destroyed"))});let A=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)m.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)m.emit(n.type,{}),0===m.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:o,viewers:a,rate:i}=n??{};h(e)&&h(o)&&h(a)&&h(i)&&(t[r]={clicks:e,clickers:o,viewers:a,rate:i})}return t})(n.stats),statsVisible:!1!==n.visible}),($||Object.keys(v.stats).length)&&($??($=((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:b,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",A),f.push(()=>e.removeEventListener("message",A)),"loading"===w.readyState?(w.addEventListener("DOMContentLoaded",N,{once:!0}),f.push(()=>w.removeEventListener("DOMContentLoaded",N))):N(),x})(v,new URL(e||E).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(m&&(f=((e,n,{pagePath:o=e=>`/${e}`}={})=>{let a=e.document,i=p(),s=[],l=new Map,g=[],u=new Set,h=null,m=c,f=e=>{m={...m,...e},i.emit("change",m)},v=()=>f({unsaved:[...l.values()].some(({content:e,saved:t})=>!S(e,t)),canUndo:g.length>0}),y=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 f({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},x=()=>a.querySelector(`[${r}]`)?.getAttribute(r)??null,w=()=>{if(!h)return;let e=h.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:h.space.defaultLocale},k=async e=>{let t=l.get(e);if(t)return t;let r=await y(`entries/${encodeURIComponent(e)}`),n={content:r.content,saved:r.content,revision:r.draftRevision};return l.set(e,n),n},E=e=>{a.querySelectorAll("[data-cms-selected]").forEach(e=>{e.removeAttribute("data-cms-selected")}),m.selectedUid!==e&&f({selectedUid:e}),e&&a.querySelector(b(e))?.setAttribute("data-cms-selected","")},C=async t=>{if(0===i.listeners.update.size)return;let r=l.get(t)?.content,{entry:n}=await y(`entries/${encodeURIComponent(t)}/preview`,{content:r,locale:w()});i.emit("update",{entry:n,selectedUid:m.selectedUid}),e.requestAnimationFrame(()=>E(m.selectedUid))},N=t=>{i.emit(t,{}),0===i.listeners.update.size&&e.location.reload()},L=async()=>{for(let[e,t]of l){if(S(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()},U={isEditing:!0,mode:"site",get entryId(){return x()},environment:null,on:i.on,getState:()=>m,async prompt(e,t={}){let n,o=e.trim();if(!o)throw Error("Say what to change");if(!m.features.includes("prompt"))throw Error("You may not edit content here");let i=void 0===t.uid?m.selectedUid:t.uid,s=(n=i?a.querySelector(b(i)):null,n?.closest(`[${r}]`)?.getAttribute(r)??x());if(!s)throw Error("Nothing on this page is marked as an entry: add editable(entry)");f({prompting:!0});try{let e=await k(s),t=await y(`entries/${encodeURIComponent(s)}/prompt`,{prompt:o,content:e.content,locale:w(),uid:i});return g.push({entryId:s,content:e.content}),e.content=t.content,v(),await C(s),{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(!m.features.includes("create"))throw Error("You may not add pages here");if(m.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()}),a=o(r.path,w()??"");return e.location.assign(a),{summary:r.summary,entryId:r.entryId,path:r.path,url:a}}finally{f({prompting:!1})}},undo(){let e=g.pop(),t=e&&l.get(e.entryId);e&&t&&(t.content=e.content,v(),C(e.entryId).catch(e=>console.error("[@obelism/content bridge]",e)))},async save(){if(!m.features.includes("save"))throw Error("You may not edit content here");f({saving:!0});try{await L()}finally{f({saving:!1})}N("saved")},async publish(){if(!m.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})}N("published")},signOut(){if(m.unsaved&&!e.confirm("Sign out and lose the changes you have not saved?"))return;l.clear(),v();let t=e.location.pathname+e.location.search;e.location.href=`${n}/logout?return_to=${encodeURIComponent(t)}`},select(e){E(e)},setSelecting(e){e?a.documentElement.setAttribute("data-cms-selecting",""):a.documentElement.removeAttribute("data-cms-selecting"),f({selecting:e})},destroy(){s.splice(0).forEach(e=>e())}},P=a.createElement("style");P.textContent=d("html[data-cms-selecting] "),a.head.appendChild(P),s.push(()=>P.remove()),s.push(()=>a.documentElement.removeAttribute("data-cms-selecting"));let $=e=>{if(!m.selecting)return;let r=e.target,n=r?.closest?.(`[${t}]`);n&&(e.preventDefault(),e.stopPropagation(),E(n.getAttribute(t)))};a.addEventListener("click",$,!0),s.push(()=>a.removeEventListener("click",$,!0));let A=e=>{m.unsaved&&(e.preventDefault(),e.returnValue="")};return e.addEventListener("beforeunload",A),s.push(()=>e.removeEventListener("beforeunload",A)),y("session").then(e=>{h=e,f({features:e.features})}).catch(e=>console.error("[@obelism/content bridge]",e)),U})(v,m,{pagePath:g})),f.isEditing&&l){let e=k(v.document,f,!0===l?{}:l),t=f.destroy;f.destroy=()=>{e(),t()}}}return v[C]=f,f};(e=window).ObelismBridge=L((e=>{let t=e?.dataset.url,r=t||E;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:k}}();
|
|
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}}();
|