@obelism/content 0.19.2 → 0.21.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 +36 -0
- package/dist/bridge.d.mts +14 -2
- package/dist/bridge.d.mts.map +1 -1
- package/dist/bridge.d.ts +14 -2
- package/dist/bridge.d.ts.map +1 -1
- package/dist/bridge.global.js +5 -5
- package/dist/bridge.js +245 -31
- package/dist/bridge.mjs +245 -31
- package/dist/index.d.mts +9 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.mjs +1 -1
- package/dist/{preview-jcmxxj92.mjs → preview-fu3qtgfx.mjs} +15 -1
- package/dist/{preview-ijk3ixwb.js → preview-ooq8w3jv.js} +17 -0
- package/dist/site.js +6 -1
- package/dist/site.mjs +6 -1
- package/package.json +1 -1
package/dist/bridge.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { P as PREVIEW_PARAMS, U as UID_ATTRIBUTE, E as ENTRY_ATTRIBUTE, a as
|
|
1
|
+
import { P as PREVIEW_PARAMS, U as UID_ATTRIBUTE, E as ENTRY_ATTRIBUTE, C as COLLECTION_ATTRIBUTE, a as COLLECTION_HANDLE_ATTRIBUTE, b as PRODUCT_ATTRIBUTE, c as PRODUCT_HANDLE_ATTRIBUTE } from './preview-fu3qtgfx.mjs';
|
|
2
2
|
import { SITE_EDITING_COOKIE, SITE_REQUEST_HEADER } from './site.mjs';
|
|
3
3
|
import { n as normalizeUrl, D as DEFAULT_URL } from './config-c6qktlz6.mjs';
|
|
4
4
|
|
|
@@ -10,7 +10,7 @@ import { n as normalizeUrl, D as DEFAULT_URL } from './config-c6qktlz6.mjs';
|
|
|
10
10
|
//
|
|
11
11
|
// Sites tag a block's clickable element with `data-numbers-id={block._uid}`
|
|
12
12
|
// and load Obelism numbers' script; the CMS reads the rates from numbers
|
|
13
|
-
// (the CMS's content/docs/guides/
|
|
13
|
+
// (the CMS's content/docs/guides/canvas.mdx, "Click rates").
|
|
14
14
|
const DEFAULT_STATS_LABELS = {
|
|
15
15
|
clicked: '{rate}% clicked',
|
|
16
16
|
title: '{clickers} of {viewers} visitors of its page clicked it in the last 30 days ({clicks} clicks)'
|
|
@@ -163,6 +163,91 @@ const mountStatsOverlay = (win, { selector, onSelect, labels: labelOverrides })=
|
|
|
163
163
|
};
|
|
164
164
|
};
|
|
165
165
|
|
|
166
|
+
// Content's canvas shows a whole page in a frame as tall as the page, so the
|
|
167
|
+
// frame is the page's height, not the screen's. Sizes in viewport-height
|
|
168
|
+
// units (`vh`, `svh`, `lvh`, `dvh`) would follow it: a `100vh` hero makes
|
|
169
|
+
// the page taller, the canvas makes the frame taller, and the hero grows
|
|
170
|
+
// again. The editor sends the height the frame stands for (`viewport`), and
|
|
171
|
+
// this rewrites those units in the page's stylesheets as pixels of that
|
|
172
|
+
// height. Stylesheets from another origin can't be read and keep theirs.
|
|
173
|
+
const UNIT = /(-?\d*\.?\d+)(?:s|l|d)?vh\b/g;
|
|
174
|
+
// A value with its viewport-height units as pixels of `height`, or null when
|
|
175
|
+
// it has none.
|
|
176
|
+
const freezeValue = (value, height)=>{
|
|
177
|
+
UNIT.lastIndex = 0;
|
|
178
|
+
if (!UNIT.test(value)) return null;
|
|
179
|
+
return value.replace(UNIT, (_, amount)=>`${Math.round(Number(amount) * height / 100 * 100) / 100}px`);
|
|
180
|
+
};
|
|
181
|
+
const freezeStyle = (style, height)=>{
|
|
182
|
+
for(let index = 0; index < style.length; index++){
|
|
183
|
+
const property = style.item(index);
|
|
184
|
+
const frozen = freezeValue(style.getPropertyValue(property), height);
|
|
185
|
+
if (frozen !== null) {
|
|
186
|
+
style.setProperty(property, frozen, style.getPropertyPriority(property));
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
// Style rules, and those inside @media, @supports and @layer blocks.
|
|
191
|
+
const freezeRules = (rules, height)=>{
|
|
192
|
+
for (const rule of Array.from(rules)){
|
|
193
|
+
const { style, cssRules } = rule;
|
|
194
|
+
if (style) freezeStyle(style, height);
|
|
195
|
+
if (cssRules) freezeRules(cssRules, height);
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
const createViewportUnits = (doc)=>{
|
|
199
|
+
const done = new WeakSet();
|
|
200
|
+
let height = null;
|
|
201
|
+
let observer = null;
|
|
202
|
+
let scheduled = false;
|
|
203
|
+
const freezeSheets = ()=>{
|
|
204
|
+
if (height === null) return;
|
|
205
|
+
for (const sheet of Array.from(doc.styleSheets)){
|
|
206
|
+
if (done.has(sheet)) continue;
|
|
207
|
+
let rules;
|
|
208
|
+
try {
|
|
209
|
+
rules = sheet.cssRules;
|
|
210
|
+
} catch {
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
done.add(sheet);
|
|
214
|
+
freezeRules(rules, height);
|
|
215
|
+
}
|
|
216
|
+
doc.querySelectorAll('[style*="vh"]').forEach((element)=>{
|
|
217
|
+
freezeStyle(element.style, height);
|
|
218
|
+
});
|
|
219
|
+
};
|
|
220
|
+
return {
|
|
221
|
+
freeze (next) {
|
|
222
|
+
// Once: the frame stands for one screen size until it reloads.
|
|
223
|
+
if (height !== null || !(next > 0)) return;
|
|
224
|
+
height = next;
|
|
225
|
+
freezeSheets();
|
|
226
|
+
const View = doc.defaultView?.MutationObserver;
|
|
227
|
+
if (!View) return;
|
|
228
|
+
// Once per frame, however much the page changes in it.
|
|
229
|
+
observer = new View(()=>{
|
|
230
|
+
if (scheduled) return;
|
|
231
|
+
scheduled = true;
|
|
232
|
+
const run = ()=>{
|
|
233
|
+
scheduled = false;
|
|
234
|
+
freezeSheets();
|
|
235
|
+
};
|
|
236
|
+
if (doc.defaultView?.requestAnimationFrame) {
|
|
237
|
+
doc.defaultView.requestAnimationFrame(run);
|
|
238
|
+
} else run();
|
|
239
|
+
});
|
|
240
|
+
observer.observe(doc.documentElement, {
|
|
241
|
+
childList: true,
|
|
242
|
+
subtree: true
|
|
243
|
+
});
|
|
244
|
+
},
|
|
245
|
+
destroy () {
|
|
246
|
+
observer?.disconnect();
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
};
|
|
250
|
+
|
|
166
251
|
// The site's half of the visual editor (the CMS's public/bridge.js, as a
|
|
167
252
|
// module). Inside the editor's iframe it outlines blocks, tells the editor
|
|
168
253
|
// which one was clicked, hands the editor's live, unsaved entry to listeners
|
|
@@ -171,10 +256,10 @@ const mountStatsOverlay = (win, { selector, onSelect, labels: labelOverrides })=
|
|
|
171
256
|
// Messages are only exchanged with the CMS origin, and only with the parent
|
|
172
257
|
// window:
|
|
173
258
|
// - site → editor: { source: 'obelism-content-bridge', type: 'ready' |
|
|
174
|
-
// 'select' | 'prompt' | 'undo', uid?, id?, prompt? }
|
|
259
|
+
// 'size' | 'select' | 'prompt' | 'undo', uid?, id?, prompt?, height? }
|
|
175
260
|
// - editor → site: { source: 'obelism-content-editor', type: 'connect' |
|
|
176
261
|
// 'update' | 'select' | 'saved' | 'published' | 'features' |
|
|
177
|
-
// 'promptResult' | 'promptState' | 'stats', … }
|
|
262
|
+
// 'promptResult' | 'promptState' | 'stats' | 'viewport', … }
|
|
178
263
|
const BRIDGE_SOURCE = 'obelism-content-bridge';
|
|
179
264
|
const EDITOR_SOURCE = 'obelism-content-editor';
|
|
180
265
|
// How long a prompt may take before it counts as failed.
|
|
@@ -228,6 +313,7 @@ const INERT_METHODS = {
|
|
|
228
313
|
prompt: inertPrompt,
|
|
229
314
|
createPage: ()=>Promise.reject(new Error('New pages are made on the site itself')),
|
|
230
315
|
createProductPage: ()=>Promise.reject(new Error('Product pages are made on the site itself')),
|
|
316
|
+
createCollectionPage: ()=>Promise.reject(new Error('Collection pages are made on the site itself')),
|
|
231
317
|
view: onlyWhileEditingSite,
|
|
232
318
|
applyJson: onlyWhileEditingSite,
|
|
233
319
|
openForm: (_container, options = {})=>{
|
|
@@ -286,6 +372,7 @@ const createBridge = (win, cmsOrigin)=>{
|
|
|
286
372
|
entryId: params.get(PREVIEW_PARAMS.entry),
|
|
287
373
|
environment: params.get(PREVIEW_PARAMS.environment),
|
|
288
374
|
product: null,
|
|
375
|
+
collection: null,
|
|
289
376
|
on: emitter.on,
|
|
290
377
|
getState: ()=>state,
|
|
291
378
|
...INERT_METHODS,
|
|
@@ -340,9 +427,32 @@ const createBridge = (win, cmsOrigin)=>{
|
|
|
340
427
|
};
|
|
341
428
|
doc.addEventListener('click', onClick, true);
|
|
342
429
|
cleanup.push(()=>doc.removeEventListener('click', onClick, true));
|
|
343
|
-
|
|
344
|
-
|
|
430
|
+
// The page's height, which an editor on another origin can't read: the
|
|
431
|
+
// canvas makes its frame as tall as the page. With `ready`, and as `size`
|
|
432
|
+
// whenever it changes.
|
|
433
|
+
const pageHeight = ()=>Math.ceil(Math.max(doc.documentElement.scrollHeight, doc.body?.scrollHeight ?? 0));
|
|
434
|
+
let sentHeight = 0;
|
|
435
|
+
const ready = ()=>{
|
|
436
|
+
sentHeight = pageHeight();
|
|
437
|
+
send('ready', {
|
|
438
|
+
url: win.location.href,
|
|
439
|
+
height: sentHeight
|
|
345
440
|
});
|
|
441
|
+
};
|
|
442
|
+
const Observer = win.ResizeObserver;
|
|
443
|
+
if (typeof Observer === 'function') {
|
|
444
|
+
const observer = new Observer(()=>{
|
|
445
|
+
const height = pageHeight();
|
|
446
|
+
if (height === sentHeight) return;
|
|
447
|
+
sentHeight = height;
|
|
448
|
+
send('size', {
|
|
449
|
+
height
|
|
450
|
+
});
|
|
451
|
+
});
|
|
452
|
+
observer.observe(doc.documentElement);
|
|
453
|
+
if (doc.body) observer.observe(doc.body);
|
|
454
|
+
cleanup.push(()=>observer.disconnect());
|
|
455
|
+
}
|
|
346
456
|
// Prompts waiting for the editor's answer, by id.
|
|
347
457
|
const pending = new Map();
|
|
348
458
|
let nextId = 0;
|
|
@@ -406,6 +516,8 @@ const createBridge = (win, cmsOrigin)=>{
|
|
|
406
516
|
settle(id)?.reject(new Error('The bridge was destroyed'));
|
|
407
517
|
}
|
|
408
518
|
});
|
|
519
|
+
const viewportUnits = createViewportUnits(doc);
|
|
520
|
+
cleanup.push(()=>viewportUnits.destroy());
|
|
409
521
|
const onMessage = (event)=>{
|
|
410
522
|
if (event.origin !== cmsOrigin || event.source !== win.parent) return;
|
|
411
523
|
const data = event.data;
|
|
@@ -438,6 +550,10 @@ const createBridge = (win, cmsOrigin)=>{
|
|
|
438
550
|
statsVisible: data.visible !== false
|
|
439
551
|
});
|
|
440
552
|
showStats();
|
|
553
|
+
} else if (data.type === 'viewport' && typeof data.height === 'number') {
|
|
554
|
+
// The canvas: the frame is as tall as the page (`size`), so `vh`
|
|
555
|
+
// sizes are fixed at the screen height it stands for.
|
|
556
|
+
viewportUnits.freeze(data.height);
|
|
441
557
|
} else if (data.type === 'promptState') {
|
|
442
558
|
setState({
|
|
443
559
|
canUndo: data.canUndo === true
|
|
@@ -479,6 +595,7 @@ const wrapScriptBridge = (script, params)=>{
|
|
|
479
595
|
entryId: script.entryId,
|
|
480
596
|
environment: params.get(PREVIEW_PARAMS.environment),
|
|
481
597
|
product: null,
|
|
598
|
+
collection: null,
|
|
482
599
|
on: (event, listener)=>{
|
|
483
600
|
if (event === 'update' && !forwardingUpdates) {
|
|
484
601
|
forwardingUpdates = true;
|
|
@@ -507,6 +624,7 @@ const DEFAULT_PROMPT_LABELS = {
|
|
|
507
624
|
minimize: 'Minimize, to see the page',
|
|
508
625
|
expand: 'Expand',
|
|
509
626
|
scopeEntry: 'Whole page',
|
|
627
|
+
scopeNoPage: 'Whole page',
|
|
510
628
|
scopeBlock: 'Selected block',
|
|
511
629
|
clearBlock: 'Edit the whole page instead',
|
|
512
630
|
working: 'Working on it…',
|
|
@@ -542,7 +660,11 @@ const DEFAULT_PROMPT_LABELS = {
|
|
|
542
660
|
addProductPage: 'Add a product page',
|
|
543
661
|
addingProductPage: 'Making the product page…',
|
|
544
662
|
addedProductPage: 'Opening the product page…',
|
|
545
|
-
productPageHint: 'This product has no page yet. Add one for what the store doesn’t say.'
|
|
663
|
+
productPageHint: 'This product has no page yet. Add one for what the store doesn’t say.',
|
|
664
|
+
addCollectionPage: 'Add a collection page',
|
|
665
|
+
addingCollectionPage: 'Making the collection page…',
|
|
666
|
+
addedCollectionPage: 'Opening the collection page…',
|
|
667
|
+
collectionPageHint: 'This collection has no page yet. Add one for what goes around its products.'
|
|
546
668
|
};
|
|
547
669
|
const SIDE_KEY = 'obelism-content-prompt-side';
|
|
548
670
|
// How far the pointer moves before it drags the box, not clicks it.
|
|
@@ -632,7 +754,7 @@ button:disabled { cursor: not-allowed; }
|
|
|
632
754
|
button:focus-visible { outline: 2px solid rgb(var(--theme-accent-rgb)); outline-offset: 2px; }
|
|
633
755
|
|
|
634
756
|
/* Closed: one floating pill that reads like an empty field, with the mark. */
|
|
635
|
-
.bar { display: flex; justify-content: center; }
|
|
757
|
+
.bar { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 8px; }
|
|
636
758
|
.pill {
|
|
637
759
|
display: flex; align-items: center; gap: 12px; width: min(560px, 100%); height: 56px;
|
|
638
760
|
padding: 0 22px 0 26px; border-radius: var(--border-radius-pill);
|
|
@@ -763,7 +885,7 @@ button.chip:disabled { opacity: .5; }
|
|
|
763
885
|
|
|
764
886
|
/* On the site: storing the draft, and the way out. */
|
|
765
887
|
.footer {
|
|
766
|
-
display: flex; align-items: center; gap: 8px; padding: 10px 12px 10px 22px;
|
|
888
|
+
display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 10px 12px 10px 22px;
|
|
767
889
|
border-top: 1px solid rgb(var(--theme-border-rgb) / .2);
|
|
768
890
|
background: rgb(var(--theme-background-actions-rgb) / .45);
|
|
769
891
|
}
|
|
@@ -921,8 +1043,9 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
921
1043
|
className: 'action chip',
|
|
922
1044
|
type: 'button'
|
|
923
1045
|
}, icon(doc, 'newPage'), labels.newPage);
|
|
924
|
-
// A product the site marks (editableProduct
|
|
925
|
-
//
|
|
1046
|
+
// A product (collection) the site marks (editableProduct,
|
|
1047
|
+
// editableCollection) without a page of its own: one click makes its
|
|
1048
|
+
// page, which the page then shows.
|
|
926
1049
|
const addProduct = element(doc, 'button', {
|
|
927
1050
|
className: 'action chip product',
|
|
928
1051
|
type: 'button'
|
|
@@ -1017,6 +1140,16 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1017
1140
|
}, element(doc, 'label', {
|
|
1018
1141
|
className: 'search'
|
|
1019
1142
|
}, icon(doc, 'search'), search), optionList, pagesNote);
|
|
1143
|
+
// The page's own controls (`actions`), in the footer while open and next
|
|
1144
|
+
// to the pill while closed.
|
|
1145
|
+
const actionsInFooter = element(doc, 'slot');
|
|
1146
|
+
actionsInFooter.name = 'actions-footer';
|
|
1147
|
+
const actionsInBar = element(doc, 'slot');
|
|
1148
|
+
actionsInBar.name = 'actions-bar';
|
|
1149
|
+
if (options.actions) {
|
|
1150
|
+
options.actions.slot = 'actions-bar';
|
|
1151
|
+
host.appendChild(options.actions);
|
|
1152
|
+
}
|
|
1020
1153
|
const unsaved = element(doc, 'span', {
|
|
1021
1154
|
className: 'unsaved'
|
|
1022
1155
|
});
|
|
@@ -1043,7 +1176,7 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1043
1176
|
className: 'footer'
|
|
1044
1177
|
}, pageChip, unsaved, element(doc, 'span', {
|
|
1045
1178
|
className: 'spacer'
|
|
1046
|
-
}), signOut, save, publish);
|
|
1179
|
+
}), actionsInFooter, signOut, save, publish);
|
|
1047
1180
|
const panel = element(doc, 'form', {
|
|
1048
1181
|
className: 'panel'
|
|
1049
1182
|
}, status, pathRow, input, formBox, toolbar, pagesSection, footer);
|
|
@@ -1051,7 +1184,7 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1051
1184
|
className: 'root'
|
|
1052
1185
|
}, element(doc, 'div', {
|
|
1053
1186
|
className: 'bar'
|
|
1054
|
-
}, pill, viewing), panel);
|
|
1187
|
+
}, pill, viewing, actionsInBar), panel);
|
|
1055
1188
|
shadow.append(element(doc, 'style', {
|
|
1056
1189
|
textContent: CSS
|
|
1057
1190
|
}), root);
|
|
@@ -1080,7 +1213,7 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1080
1213
|
dragged = false;
|
|
1081
1214
|
if (event.button !== 0 || !event.isPrimary) return;
|
|
1082
1215
|
const target = event.target;
|
|
1083
|
-
const control = target.closest('button, input, textarea, iframe, a, label, .pages, .form');
|
|
1216
|
+
const control = target.closest('button, input, textarea, select, iframe, a, label, .pages, .form');
|
|
1084
1217
|
if (control && control !== pill) return;
|
|
1085
1218
|
const { left, right } = root.getBoundingClientRect();
|
|
1086
1219
|
drag = {
|
|
@@ -1176,8 +1309,20 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1176
1309
|
// A page of the site that isn't an entry (no `editable(entry)`, like a
|
|
1177
1310
|
// hand-written /about) has nothing to edit: only New page.
|
|
1178
1311
|
const pageless = site && bridge.entryId === null;
|
|
1179
|
-
// …unless it shows a product: then Add a product
|
|
1180
|
-
|
|
1312
|
+
// …unless it shows a product (collection): then Add a product
|
|
1313
|
+
// (collection) page first.
|
|
1314
|
+
const shopHere = !pageless || !canCreate ? null : bridge.product ? 'product' : bridge.collection ? 'collection' : null;
|
|
1315
|
+
const productHere = shopHere !== null;
|
|
1316
|
+
const shopCopy = shopHere === 'collection' ? {
|
|
1317
|
+
add: labels.addCollectionPage,
|
|
1318
|
+
adding: labels.addingCollectionPage,
|
|
1319
|
+
hint: labels.collectionPageHint
|
|
1320
|
+
} : {
|
|
1321
|
+
add: labels.addProductPage,
|
|
1322
|
+
adding: labels.addingProductPage,
|
|
1323
|
+
hint: labels.productPageHint
|
|
1324
|
+
};
|
|
1325
|
+
addProduct.lastChild.textContent = shopCopy.add;
|
|
1181
1326
|
const onlyNew = pageless && canCreate && !productHere;
|
|
1182
1327
|
if (!canCreate) creating = false;
|
|
1183
1328
|
if (onlyNew) creating = true;
|
|
@@ -1187,7 +1332,7 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1187
1332
|
if (showForm && !formHandle) mountForm();
|
|
1188
1333
|
else if (!showForm && formHandle) unmountForm();
|
|
1189
1334
|
const offerProduct = productHere && !creating;
|
|
1190
|
-
pillText.textContent = offerProduct ?
|
|
1335
|
+
pillText.textContent = offerProduct ? shopCopy.add : onlyNew ? labels.newPage : labels.open;
|
|
1191
1336
|
cancelNew.hidden = onlyNew;
|
|
1192
1337
|
scope.hidden = creating || offerProduct;
|
|
1193
1338
|
newScope.hidden = !creating;
|
|
@@ -1205,7 +1350,7 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1205
1350
|
toolbar.hidden = picking;
|
|
1206
1351
|
pagesSection.hidden = !picking;
|
|
1207
1352
|
input.placeholder = creating ? labels.newPagePlaceholder : labels.placeholder;
|
|
1208
|
-
scopeText.textContent = state.selectedUid ? labels.scopeBlock : labels.scopeEntry;
|
|
1353
|
+
scopeText.textContent = state.selectedUid ? labels.scopeBlock : pageless ? labels.scopeNoPage : labels.scopeEntry;
|
|
1209
1354
|
clearBlock.hidden = !state.selectedUid;
|
|
1210
1355
|
pageIcon.hidden = !!state.selectedUid;
|
|
1211
1356
|
blockIcon.hidden = !state.selectedUid;
|
|
@@ -1235,7 +1380,11 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1235
1380
|
publish.hidden = !state.features.includes('publish') || pageless;
|
|
1236
1381
|
publish.disabled = busy;
|
|
1237
1382
|
publish.textContent = state.publishing ? labels.publishing : labels.publish;
|
|
1238
|
-
signOut.hidden = !site;
|
|
1383
|
+
signOut.hidden = !site || options.signOut === false;
|
|
1384
|
+
pillSignOut.hidden = options.signOut === false;
|
|
1385
|
+
if (options.actions) {
|
|
1386
|
+
options.actions.slot = open && available ? 'actions-footer' : 'actions-bar';
|
|
1387
|
+
}
|
|
1239
1388
|
footer.hidden = !site;
|
|
1240
1389
|
unsaved.hidden = !state.unsaved;
|
|
1241
1390
|
pageChip.hidden = !site;
|
|
@@ -1244,7 +1393,7 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1244
1393
|
const loadingForm = form && formLoading && !picking;
|
|
1245
1394
|
const working = state.prompting;
|
|
1246
1395
|
// A form opening says so in its own place.
|
|
1247
|
-
const note = state.prompting ? creating ? labels.creating : offerProduct ?
|
|
1396
|
+
const note = state.prompting ? creating ? labels.creating : offerProduct ? shopCopy.adding : labels.working : loadingForm ? '' : message?.text ?? (offerProduct ? shopCopy.hint : site && !creating && !picking && !state.selectedUid ? labels.selectHint : '');
|
|
1248
1397
|
status.textContent = note;
|
|
1249
1398
|
status.hidden = !note || minimized;
|
|
1250
1399
|
status.className = `status${working ? ' working' : ''}${!busy && !loadingForm && message?.error ? ' error' : ''}`;
|
|
@@ -1467,11 +1616,19 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1467
1616
|
message = null;
|
|
1468
1617
|
try {
|
|
1469
1618
|
// The bridge reloads the page; this shows until it does.
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1619
|
+
if (bridge.product) {
|
|
1620
|
+
await bridge.createProductPage();
|
|
1621
|
+
message = {
|
|
1622
|
+
text: labels.addedProductPage,
|
|
1623
|
+
error: false
|
|
1624
|
+
};
|
|
1625
|
+
} else {
|
|
1626
|
+
await bridge.createCollectionPage();
|
|
1627
|
+
message = {
|
|
1628
|
+
text: labels.addedCollectionPage,
|
|
1629
|
+
error: false
|
|
1630
|
+
};
|
|
1631
|
+
}
|
|
1475
1632
|
} catch (error) {
|
|
1476
1633
|
message = failure(error);
|
|
1477
1634
|
}
|
|
@@ -1668,7 +1825,7 @@ const FORM_BURST_MS = 1000;
|
|
|
1668
1825
|
// How long the page waits for the form's edits to settle before it shows
|
|
1669
1826
|
// them.
|
|
1670
1827
|
const FORM_RENDER_MS = 300;
|
|
1671
|
-
const createSiteBridge = (win, basePath, { pagePath = (path)=>`/${path}`, productPath: ownProductPath } = {})=>{
|
|
1828
|
+
const createSiteBridge = (win, basePath, { pagePath = (path)=>`/${path}`, productPath: ownProductPath, collectionPath: ownCollectionPath } = {})=>{
|
|
1672
1829
|
const doc = win.document;
|
|
1673
1830
|
const emitter = createEmitter();
|
|
1674
1831
|
const cleanup = [];
|
|
@@ -1679,6 +1836,7 @@ const createSiteBridge = (win, basePath, { pagePath = (path)=>`/${path}`, produc
|
|
|
1679
1836
|
const touched = new Set();
|
|
1680
1837
|
let session = null;
|
|
1681
1838
|
const productPath = (handle, locale)=>ownProductPath ? ownProductPath(handle, locale) : (session?.productPath ?? '/products/{handle}').replaceAll('{handle}', encodeURIComponent(handle));
|
|
1839
|
+
const collectionPath = (handle, locale)=>ownCollectionPath ? ownCollectionPath(handle, locale) : (session?.collectionPath ?? '/collections/{handle}').replaceAll('{handle}', encodeURIComponent(handle));
|
|
1682
1840
|
// The open form's, if any; and when the form last changed content, for
|
|
1683
1841
|
// undo steps (-Infinity: the next edit starts a new step).
|
|
1684
1842
|
let closeForm = null;
|
|
@@ -1733,6 +1891,16 @@ const createSiteBridge = (win, basePath, { pagePath = (path)=>`/${path}`, produc
|
|
|
1733
1891
|
handle
|
|
1734
1892
|
} : null;
|
|
1735
1893
|
};
|
|
1894
|
+
// The collection the page shows (editableCollection), if it marks one.
|
|
1895
|
+
const pageCollection = ()=>{
|
|
1896
|
+
const element = doc.querySelector(`[${COLLECTION_ATTRIBUTE}]`);
|
|
1897
|
+
const id = element?.getAttribute(COLLECTION_ATTRIBUTE);
|
|
1898
|
+
const handle = element?.getAttribute(COLLECTION_HANDLE_ATTRIBUTE);
|
|
1899
|
+
return id && handle ? {
|
|
1900
|
+
id,
|
|
1901
|
+
handle
|
|
1902
|
+
} : null;
|
|
1903
|
+
};
|
|
1736
1904
|
const entryFor = (uid)=>{
|
|
1737
1905
|
const block = uid ? doc.querySelector(blockSelector(uid)) : null;
|
|
1738
1906
|
return block?.closest(`[${ENTRY_ATTRIBUTE}]`)?.getAttribute(ENTRY_ATTRIBUTE) ?? pageEntryId();
|
|
@@ -1843,6 +2011,9 @@ const createSiteBridge = (win, basePath, { pagePath = (path)=>`/${path}`, produc
|
|
|
1843
2011
|
get product () {
|
|
1844
2012
|
return pageProduct();
|
|
1845
2013
|
},
|
|
2014
|
+
get collection () {
|
|
2015
|
+
return pageCollection();
|
|
2016
|
+
},
|
|
1846
2017
|
environment: null,
|
|
1847
2018
|
on: emitter.on,
|
|
1848
2019
|
getState: ()=>state,
|
|
@@ -1940,6 +2111,34 @@ const createSiteBridge = (win, basePath, { pagePath = (path)=>`/${path}`, produc
|
|
|
1940
2111
|
});
|
|
1941
2112
|
}
|
|
1942
2113
|
},
|
|
2114
|
+
async createCollectionPage (collection = pageCollection() ?? undefined) {
|
|
2115
|
+
if (!collection) {
|
|
2116
|
+
throw new Error('Nothing on this page is marked as a collection: add editableCollection(collection)');
|
|
2117
|
+
}
|
|
2118
|
+
if (!has('create')) throw new Error('You may not add pages here');
|
|
2119
|
+
if (state.unsaved) {
|
|
2120
|
+
throw new Error('Save or undo your changes before adding a page');
|
|
2121
|
+
}
|
|
2122
|
+
setState({
|
|
2123
|
+
prompting: true
|
|
2124
|
+
});
|
|
2125
|
+
try {
|
|
2126
|
+
const made = await api('collection-pages', {
|
|
2127
|
+
collection: {
|
|
2128
|
+
id: collection.id,
|
|
2129
|
+
handle: collection.handle
|
|
2130
|
+
}
|
|
2131
|
+
});
|
|
2132
|
+
// The site's collection route finds its page now (drafts, while
|
|
2133
|
+
// editing): show it.
|
|
2134
|
+
win.location.reload();
|
|
2135
|
+
return made;
|
|
2136
|
+
} finally{
|
|
2137
|
+
setState({
|
|
2138
|
+
prompting: false
|
|
2139
|
+
});
|
|
2140
|
+
}
|
|
2141
|
+
},
|
|
1943
2142
|
async view (options = {}) {
|
|
1944
2143
|
const { uid, entryId } = target(options.uid);
|
|
1945
2144
|
const entry = await load(entryId);
|
|
@@ -2093,8 +2292,9 @@ const createSiteBridge = (win, basePath, { pagePath = (path)=>`/${path}`, produc
|
|
|
2093
2292
|
contentType: page.contentType,
|
|
2094
2293
|
status: page.status,
|
|
2095
2294
|
path,
|
|
2096
|
-
url: page.product ? productPath(page.product.handle, code) : pagePath(path, code),
|
|
2097
|
-
product: page.product ?? null
|
|
2295
|
+
url: page.product ? productPath(page.product.handle, code) : page.collection ? collectionPath(page.collection.handle, code) : pagePath(path, code),
|
|
2296
|
+
product: page.product ?? null,
|
|
2297
|
+
collection: page.collection ?? null
|
|
2098
2298
|
}
|
|
2099
2299
|
];
|
|
2100
2300
|
});
|
|
@@ -2239,7 +2439,7 @@ const peekContentBridge = ()=>typeof window === 'undefined' ? null : window[KEY]
|
|
|
2239
2439
|
// if (bridge.isEditing) bridge.on('update', ({ entry }) => render(entry))
|
|
2240
2440
|
//
|
|
2241
2441
|
// The first call's options win: there is one bridge per page.
|
|
2242
|
-
const getContentBridge = ({ url, prompt = true, pagePath, productPath } = {})=>{
|
|
2442
|
+
const getContentBridge = ({ url, prompt = true, pagePath, productPath, collectionPath } = {})=>{
|
|
2243
2443
|
if (typeof window === 'undefined') return SERVER_BRIDGE;
|
|
2244
2444
|
const win = window;
|
|
2245
2445
|
if (win[KEY]) return win[KEY];
|
|
@@ -2253,12 +2453,26 @@ const getContentBridge = ({ url, prompt = true, pagePath, productPath } = {})=>{
|
|
|
2253
2453
|
const sitePath = bridge.isEditing || win.parent !== win ? null : readSiteEditing(win.document);
|
|
2254
2454
|
if (sitePath) bridge = createSiteBridge(win, sitePath, {
|
|
2255
2455
|
pagePath,
|
|
2256
|
-
productPath
|
|
2456
|
+
productPath,
|
|
2457
|
+
collectionPath
|
|
2257
2458
|
});
|
|
2258
2459
|
if (bridge.isEditing && prompt) {
|
|
2259
|
-
const
|
|
2460
|
+
const doc = win.document;
|
|
2461
|
+
let unmount = ()=>{};
|
|
2462
|
+
let destroyed = false;
|
|
2463
|
+
const mount = ()=>{
|
|
2464
|
+
if (destroyed) return;
|
|
2465
|
+
unmount = mountPromptBox(doc, bridge, prompt === true ? {} : prompt);
|
|
2466
|
+
};
|
|
2467
|
+
// A script tag in <head> runs before there is a body to mount into.
|
|
2468
|
+
if (doc.body) mount();
|
|
2469
|
+
else doc.addEventListener('DOMContentLoaded', mount, {
|
|
2470
|
+
once: true
|
|
2471
|
+
});
|
|
2260
2472
|
const destroy = bridge.destroy;
|
|
2261
2473
|
bridge.destroy = ()=>{
|
|
2474
|
+
destroyed = true;
|
|
2475
|
+
doc.removeEventListener('DOMContentLoaded', mount);
|
|
2262
2476
|
unmount();
|
|
2263
2477
|
destroy();
|
|
2264
2478
|
};
|
package/dist/index.d.mts
CHANGED
|
@@ -80,6 +80,14 @@ declare const editableProduct: (product: {
|
|
|
80
80
|
id: string;
|
|
81
81
|
handle: string;
|
|
82
82
|
} | null | undefined) => EditableProduct;
|
|
83
|
+
type EditableCollection = {
|
|
84
|
+
'data-cms-collection'?: string;
|
|
85
|
+
'data-cms-collection-handle'?: string;
|
|
86
|
+
};
|
|
87
|
+
declare const editableCollection: (collection: {
|
|
88
|
+
id: string;
|
|
89
|
+
handle: string;
|
|
90
|
+
} | null | undefined) => EditableCollection;
|
|
83
91
|
|
|
84
92
|
declare class ContentApiError extends Error {
|
|
85
93
|
readonly status: number;
|
|
@@ -195,6 +203,6 @@ type SitemapOptions = LocalizedUrlOptions & {
|
|
|
195
203
|
};
|
|
196
204
|
declare const sitemapXml: (entries: Iterable<Page>, { exclude, ...options }: SitemapOptions) => string;
|
|
197
205
|
|
|
198
|
-
export { Asset, Block, ContentApiError, ContentClient, DEFAULT_URL, ENTRY_ATTRIBUTE, Entry, EntryList, EntryStub, IMPROVE_BLOCK, ImproveBlock, Link, LinkTarget, ModelFile, PREVIEW_PARAMS, PRODUCT_ATTRIBUTE, PRODUCT_HANDLE_ATTRIBUTE, Redirect, RedirectList, RichTextFormat, RichTextNode, SAFE_HREF, SHOPIFY_STOREFRONT_API_VERSION, ShopifyItem, ShopifyStorefrontError, UID_ATTRIBUTE, alternateLinks, editable, editableProduct, escapeHtml, fetchShopifyCollection, fetchShopifyProducts, headingLevel, imageSrcSet, imageUrl, isImproveBlock, linkHref, pickImproveVariant, readPreviewParams, richTextToHtml, richTextToPlainText, sitemapXml };
|
|
206
|
+
export { Asset, Block, ContentApiError, ContentClient, DEFAULT_URL, ENTRY_ATTRIBUTE, Entry, EntryList, EntryStub, IMPROVE_BLOCK, ImproveBlock, Link, LinkTarget, ModelFile, PREVIEW_PARAMS, PRODUCT_ATTRIBUTE, PRODUCT_HANDLE_ATTRIBUTE, Redirect, RedirectList, RichTextFormat, RichTextNode, SAFE_HREF, SHOPIFY_STOREFRONT_API_VERSION, ShopifyItem, ShopifyStorefrontError, UID_ATTRIBUTE, alternateLinks, editable, editableCollection, editableProduct, escapeHtml, fetchShopifyCollection, fetchShopifyProducts, headingLevel, imageSrcSet, imageUrl, isImproveBlock, linkHref, pickImproveVariant, readPreviewParams, richTextToHtml, richTextToPlainText, sitemapXml };
|
|
199
207
|
export type { AlternateLink, ContentClientOptions, EntriesQuery, ImageTransform, LinkHrefOptions, LocalizedUrlOptions, PageLookup, PreviewParams, RedirectsQuery, RequestOptions, RichTextHtmlOptions, ShopifyCollection, ShopifyImage, ShopifyMoney, ShopifyProduct, ShopifyStorefrontOptions, SitemapOptions };
|
|
200
208
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","sources":["../src/client.ts","../src/config.ts","../src/editable.ts","../src/errors.ts","../src/images.ts","../src/improve.ts","../src/links.ts","../src/preview.ts","../src/shopify.ts","../src/richText.ts","../src/sitemap.ts"],"mappings":";;;AACA,KAAK,oBAAoB;AACzB;AACA;AACA;AACA;AACA,eAAe,cAAc;AAC7B;AACA,WAAW,WAAW;AACtB,mBAAmB,KAAK;AACxB;AACA,KAAK,cAAc;AACnB;AACA;AACA,eAAe,cAAc;AAC7B,WAAW,WAAW;AACtB;AACA,KAAK,gBAAgB;AACrB,KAAK,YAAY,GAAG,cAAc;AAClC;AACA;AACA,aAAa,MAAM,SAAS,gBAAgB,YAAY,gBAAgB;AACxE;AACA;AACA;AACA;AACA,KAAK,cAAc;AACnB;AACA;AACA;AACA,WAAW,WAAW;AACtB;AACA,KAAK,UAAU,gBAAgB,KAAK,GAAG,KAAK;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,aAAa;AAC3B;AACA;AACA,2FAA2F,oBAAoB;AAC/G,6BAA6B,KAAK,GAAG,KAAK,0BAA0B,cAAc,KAAK,OAAO;AAC9F,8BAA8B,KAAK,GAAG,KAAK,0BAA0B,cAAc,KAAK,OAAO,CAAC,UAAU;AAC1G,oDAAoD,cAAc,KAAK,OAAO,CAAC,YAAY;AAC3F,4BAA4B,IAAI,CAAC,cAAc,YAAY,cAAc,CAAC,QAAQ;AAClF,8BAA8B,KAAK,GAAG,KAAK,wBAAwB,cAAc,KAAK,OAAO;AAC7F,gCAAgC,KAAK,GAAG,KAAK,wEAAwE,YAAY,KAAK,OAAO,CAAC,SAAS;AACvJ,mCAAmC,KAAK,GAAG,KAAK,UAAU,IAAI,CAAC,YAAY,wBAAwB,OAAO;AAC1G,iCAAiC,KAAK,GAAG,KAAK,UAAU,IAAI,CAAC,YAAY,YAAY,cAAc;AACnG,gCAAgC,IAAI,CAAC,cAAc,cAAc,OAAO,CAAC,SAAS;AAClF;;ACtDA,cAAc,WAAW;;ACAzB,cAAc,aAAa;AAC3B,cAAc,eAAe;AAC7B,cAAc,iBAAiB;AAC/B,cAAc,wBAAwB;
|
|
1
|
+
{"version":3,"file":"index.d.mts","sources":["../src/client.ts","../src/config.ts","../src/editable.ts","../src/errors.ts","../src/images.ts","../src/improve.ts","../src/links.ts","../src/preview.ts","../src/shopify.ts","../src/richText.ts","../src/sitemap.ts"],"mappings":"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","names":[]}
|
package/dist/index.d.ts
CHANGED
|
@@ -80,6 +80,14 @@ declare const editableProduct: (product: {
|
|
|
80
80
|
id: string;
|
|
81
81
|
handle: string;
|
|
82
82
|
} | null | undefined) => EditableProduct;
|
|
83
|
+
type EditableCollection = {
|
|
84
|
+
'data-cms-collection'?: string;
|
|
85
|
+
'data-cms-collection-handle'?: string;
|
|
86
|
+
};
|
|
87
|
+
declare const editableCollection: (collection: {
|
|
88
|
+
id: string;
|
|
89
|
+
handle: string;
|
|
90
|
+
} | null | undefined) => EditableCollection;
|
|
83
91
|
|
|
84
92
|
declare class ContentApiError extends Error {
|
|
85
93
|
readonly status: number;
|
|
@@ -195,6 +203,6 @@ type SitemapOptions = LocalizedUrlOptions & {
|
|
|
195
203
|
};
|
|
196
204
|
declare const sitemapXml: (entries: Iterable<Page>, { exclude, ...options }: SitemapOptions) => string;
|
|
197
205
|
|
|
198
|
-
export { Asset, Block, ContentApiError, ContentClient, DEFAULT_URL, ENTRY_ATTRIBUTE, Entry, EntryList, EntryStub, IMPROVE_BLOCK, ImproveBlock, Link, LinkTarget, ModelFile, PREVIEW_PARAMS, PRODUCT_ATTRIBUTE, PRODUCT_HANDLE_ATTRIBUTE, Redirect, RedirectList, RichTextFormat, RichTextNode, SAFE_HREF, SHOPIFY_STOREFRONT_API_VERSION, ShopifyItem, ShopifyStorefrontError, UID_ATTRIBUTE, alternateLinks, editable, editableProduct, escapeHtml, fetchShopifyCollection, fetchShopifyProducts, headingLevel, imageSrcSet, imageUrl, isImproveBlock, linkHref, pickImproveVariant, readPreviewParams, richTextToHtml, richTextToPlainText, sitemapXml };
|
|
206
|
+
export { Asset, Block, ContentApiError, ContentClient, DEFAULT_URL, ENTRY_ATTRIBUTE, Entry, EntryList, EntryStub, IMPROVE_BLOCK, ImproveBlock, Link, LinkTarget, ModelFile, PREVIEW_PARAMS, PRODUCT_ATTRIBUTE, PRODUCT_HANDLE_ATTRIBUTE, Redirect, RedirectList, RichTextFormat, RichTextNode, SAFE_HREF, SHOPIFY_STOREFRONT_API_VERSION, ShopifyItem, ShopifyStorefrontError, UID_ATTRIBUTE, alternateLinks, editable, editableCollection, editableProduct, escapeHtml, fetchShopifyCollection, fetchShopifyProducts, headingLevel, imageSrcSet, imageUrl, isImproveBlock, linkHref, pickImproveVariant, readPreviewParams, richTextToHtml, richTextToPlainText, sitemapXml };
|
|
199
207
|
export type { AlternateLink, ContentClientOptions, EntriesQuery, ImageTransform, LinkHrefOptions, LocalizedUrlOptions, PageLookup, PreviewParams, RedirectsQuery, RequestOptions, RichTextHtmlOptions, ShopifyCollection, ShopifyImage, ShopifyMoney, ShopifyProduct, ShopifyStorefrontOptions, SitemapOptions };
|
|
200
208
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sources":["../src/client.ts","../src/config.ts","../src/editable.ts","../src/errors.ts","../src/images.ts","../src/improve.ts","../src/links.ts","../src/preview.ts","../src/shopify.ts","../src/richText.ts","../src/sitemap.ts"],"mappings":";;;AACA,KAAK,oBAAoB;AACzB;AACA;AACA;AACA;AACA,eAAe,cAAc;AAC7B;AACA,WAAW,WAAW;AACtB,mBAAmB,KAAK;AACxB;AACA,KAAK,cAAc;AACnB;AACA;AACA,eAAe,cAAc;AAC7B,WAAW,WAAW;AACtB;AACA,KAAK,gBAAgB;AACrB,KAAK,YAAY,GAAG,cAAc;AAClC;AACA;AACA,aAAa,MAAM,SAAS,gBAAgB,YAAY,gBAAgB;AACxE;AACA;AACA;AACA;AACA,KAAK,cAAc;AACnB;AACA;AACA;AACA,WAAW,WAAW;AACtB;AACA,KAAK,UAAU,gBAAgB,KAAK,GAAG,KAAK;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,aAAa;AAC3B;AACA;AACA,2FAA2F,oBAAoB;AAC/G,6BAA6B,KAAK,GAAG,KAAK,0BAA0B,cAAc,KAAK,OAAO;AAC9F,8BAA8B,KAAK,GAAG,KAAK,0BAA0B,cAAc,KAAK,OAAO,CAAC,UAAU;AAC1G,oDAAoD,cAAc,KAAK,OAAO,CAAC,YAAY;AAC3F,4BAA4B,IAAI,CAAC,cAAc,YAAY,cAAc,CAAC,QAAQ;AAClF,8BAA8B,KAAK,GAAG,KAAK,wBAAwB,cAAc,KAAK,OAAO;AAC7F,gCAAgC,KAAK,GAAG,KAAK,wEAAwE,YAAY,KAAK,OAAO,CAAC,SAAS;AACvJ,mCAAmC,KAAK,GAAG,KAAK,UAAU,IAAI,CAAC,YAAY,wBAAwB,OAAO;AAC1G,iCAAiC,KAAK,GAAG,KAAK,UAAU,IAAI,CAAC,YAAY,YAAY,cAAc;AACnG,gCAAgC,IAAI,CAAC,cAAc,cAAc,OAAO,CAAC,SAAS;AAClF;;ACtDA,cAAc,WAAW;;ACAzB,cAAc,aAAa;AAC3B,cAAc,eAAe;AAC7B,cAAc,iBAAiB;AAC/B,cAAc,wBAAwB;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sources":["../src/client.ts","../src/config.ts","../src/editable.ts","../src/errors.ts","../src/images.ts","../src/improve.ts","../src/links.ts","../src/preview.ts","../src/shopify.ts","../src/richText.ts","../src/sitemap.ts"],"mappings":"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","names":[]}
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
2
2
|
|
|
3
3
|
var config = require('./config-ci2hxmas.js');
|
|
4
|
-
var preview = require('./preview-
|
|
4
|
+
var preview = require('./preview-ooq8w3jv.js');
|
|
5
5
|
|
|
6
6
|
// A response from the API that wasn't a success. `message` is the API's own
|
|
7
7
|
// `error` text when it sent one.
|
|
@@ -513,6 +513,7 @@ exports.PRODUCT_ATTRIBUTE = preview.PRODUCT_ATTRIBUTE;
|
|
|
513
513
|
exports.PRODUCT_HANDLE_ATTRIBUTE = preview.PRODUCT_HANDLE_ATTRIBUTE;
|
|
514
514
|
exports.UID_ATTRIBUTE = preview.UID_ATTRIBUTE;
|
|
515
515
|
exports.editable = preview.editable;
|
|
516
|
+
exports.editableCollection = preview.editableCollection;
|
|
516
517
|
exports.editableProduct = preview.editableProduct;
|
|
517
518
|
exports.readPreviewParams = preview.readPreviewParams;
|
|
518
519
|
exports.ContentApiError = ContentApiError;
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as normalizeUrl, a as DEFAULT_TIMEOUT, b as DELIVERY_PATH, D as DEFAULT_URL } from './config-c6qktlz6.mjs';
|
|
2
|
-
export { E as ENTRY_ATTRIBUTE, P as PREVIEW_PARAMS,
|
|
2
|
+
export { E as ENTRY_ATTRIBUTE, P as PREVIEW_PARAMS, b as PRODUCT_ATTRIBUTE, c as PRODUCT_HANDLE_ATTRIBUTE, U as UID_ATTRIBUTE, e as editable, d as editableCollection, f as editableProduct, r as readPreviewParams } from './preview-fu3qtgfx.mjs';
|
|
3
3
|
|
|
4
4
|
// A response from the API that wasn't a success. `message` is the API's own
|
|
5
5
|
// `error` text when it sent one.
|
|
@@ -2,6 +2,8 @@ const UID_ATTRIBUTE = 'data-cms-uid';
|
|
|
2
2
|
const ENTRY_ATTRIBUTE = 'data-cms-entry';
|
|
3
3
|
const PRODUCT_ATTRIBUTE = 'data-cms-product';
|
|
4
4
|
const PRODUCT_HANDLE_ATTRIBUTE = 'data-cms-product-handle';
|
|
5
|
+
const COLLECTION_ATTRIBUTE = 'data-cms-collection';
|
|
6
|
+
const COLLECTION_HANDLE_ATTRIBUTE = 'data-cms-collection-handle';
|
|
5
7
|
// The attribute that lets editors select a block on the page, in the visual
|
|
6
8
|
// editor and on the site. Spread it on the block's outermost element:
|
|
7
9
|
//
|
|
@@ -36,6 +38,18 @@ const editableProduct = (product)=>product?.id ? {
|
|
|
36
38
|
'data-cms-product': product.id,
|
|
37
39
|
'data-cms-product-handle': product.handle
|
|
38
40
|
} : {};
|
|
41
|
+
// The Shopify collection a page shows, on a collection route: editing on the
|
|
42
|
+
// site then offers "Add a collection page" when the page has no collection
|
|
43
|
+
// page yet (no `editable(entry)`), and makes one for this collection.
|
|
44
|
+
//
|
|
45
|
+
// <main {...editableCollection(collection)} {...editable(page)}>…</main>
|
|
46
|
+
//
|
|
47
|
+
// `collection` is the store's (its GID and handle), from the Storefront API
|
|
48
|
+
// or a Shopify field.
|
|
49
|
+
const editableCollection = (collection)=>collection?.id ? {
|
|
50
|
+
'data-cms-collection': collection.id,
|
|
51
|
+
'data-cms-collection-handle': collection.handle
|
|
52
|
+
} : {};
|
|
39
53
|
|
|
40
54
|
// The visual editor loads the site in an iframe at the environment's preview
|
|
41
55
|
// URL plus the entry's path, with these parameters added. `cms_token` is a
|
|
@@ -84,4 +98,4 @@ const readPreviewParams = (input)=>{
|
|
|
84
98
|
};
|
|
85
99
|
};
|
|
86
100
|
|
|
87
|
-
export { ENTRY_ATTRIBUTE as E, PREVIEW_PARAMS as P, UID_ATTRIBUTE as U,
|
|
101
|
+
export { COLLECTION_ATTRIBUTE as C, ENTRY_ATTRIBUTE as E, PREVIEW_PARAMS as P, UID_ATTRIBUTE as U, COLLECTION_HANDLE_ATTRIBUTE as a, PRODUCT_ATTRIBUTE as b, PRODUCT_HANDLE_ATTRIBUTE as c, editableCollection as d, editable as e, editableProduct as f, readPreviewParams as r };
|