@obelism/content 0.19.1 → 0.20.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 +26 -0
- package/dist/bridge.d.mts +11 -2
- package/dist/bridge.d.mts.map +1 -1
- package/dist/bridge.d.ts +11 -2
- package/dist/bridge.d.ts.map +1 -1
- package/dist/bridge.global.js +17 -4
- package/dist/bridge.js +246 -27
- package/dist/bridge.mjs +246 -27
- 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;
|
|
@@ -542,7 +659,11 @@ const DEFAULT_PROMPT_LABELS = {
|
|
|
542
659
|
addProductPage: 'Add a product page',
|
|
543
660
|
addingProductPage: 'Making the product page…',
|
|
544
661
|
addedProductPage: 'Opening the product page…',
|
|
545
|
-
productPageHint: 'This product has no page yet. Add one for what the store doesn’t say.'
|
|
662
|
+
productPageHint: 'This product has no page yet. Add one for what the store doesn’t say.',
|
|
663
|
+
addCollectionPage: 'Add a collection page',
|
|
664
|
+
addingCollectionPage: 'Making the collection page…',
|
|
665
|
+
addedCollectionPage: 'Opening the collection page…',
|
|
666
|
+
collectionPageHint: 'This collection has no page yet. Add one for what goes around its products.'
|
|
546
667
|
};
|
|
547
668
|
const SIDE_KEY = 'obelism-content-prompt-side';
|
|
548
669
|
// How far the pointer moves before it drags the box, not clicks it.
|
|
@@ -687,7 +808,20 @@ textarea::placeholder { color: rgb(var(--theme-foreground-muted-rgb)); }
|
|
|
687
808
|
display: block; width: 100%; height: min(560px, 60vh); border: none; border-radius: 12px;
|
|
688
809
|
background: rgb(var(--theme-background-actions-rgb) / .45);
|
|
689
810
|
}
|
|
690
|
-
|
|
811
|
+
/* Loading, it keeps the form's own height, the spinner in the middle,
|
|
812
|
+
whatever the form says meanwhile; the frame shows once the form does. */
|
|
813
|
+
.form.loading { position: relative; height: calc(min(560px, 60vh) + 12px); }
|
|
814
|
+
.form.loading iframe { position: absolute; visibility: hidden; }
|
|
815
|
+
.form-loader {
|
|
816
|
+
position: absolute; inset: 12px 12px 0; display: flex; align-items: center; justify-content: center;
|
|
817
|
+
gap: 10px; border-radius: 12px; color: rgb(var(--theme-foreground-muted-rgb));
|
|
818
|
+
background: rgb(var(--theme-background-actions-rgb) / .45);
|
|
819
|
+
}
|
|
820
|
+
.form-loader::before {
|
|
821
|
+
content: ''; width: 16px; height: 16px; flex: none; border-radius: 50%;
|
|
822
|
+
border: 2px solid rgb(var(--theme-border-rgb) / .3); border-top-color: rgb(var(--theme-accent-rgb));
|
|
823
|
+
animation: spin .7s linear infinite;
|
|
824
|
+
}
|
|
691
825
|
/* New page: where it goes, above what it is for. */
|
|
692
826
|
.path {
|
|
693
827
|
display: flex; align-items: center; gap: 10px; padding: 16px 22px 0;
|
|
@@ -860,9 +994,14 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
860
994
|
});
|
|
861
995
|
input.setAttribute('aria-label', labels.open);
|
|
862
996
|
// Form mode (on the site): the CMS's form, mounted while shown.
|
|
997
|
+
const formLoader = element(doc, 'div', {
|
|
998
|
+
className: 'form-loader',
|
|
999
|
+
textContent: labels.formLoading
|
|
1000
|
+
});
|
|
1001
|
+
formLoader.setAttribute('role', 'status');
|
|
863
1002
|
const formBox = element(doc, 'div', {
|
|
864
1003
|
className: 'form'
|
|
865
|
-
});
|
|
1004
|
+
}, formLoader);
|
|
866
1005
|
// What the prompt acts on: the whole page, or the selected block with a
|
|
867
1006
|
// way back to the page.
|
|
868
1007
|
const pageIcon = icon(doc, 'page');
|
|
@@ -903,8 +1042,9 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
903
1042
|
className: 'action chip',
|
|
904
1043
|
type: 'button'
|
|
905
1044
|
}, icon(doc, 'newPage'), labels.newPage);
|
|
906
|
-
// A product the site marks (editableProduct
|
|
907
|
-
//
|
|
1045
|
+
// A product (collection) the site marks (editableProduct,
|
|
1046
|
+
// editableCollection) without a page of its own: one click makes its
|
|
1047
|
+
// page, which the page then shows.
|
|
908
1048
|
const addProduct = element(doc, 'button', {
|
|
909
1049
|
className: 'action chip product',
|
|
910
1050
|
type: 'button'
|
|
@@ -1158,8 +1298,20 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1158
1298
|
// A page of the site that isn't an entry (no `editable(entry)`, like a
|
|
1159
1299
|
// hand-written /about) has nothing to edit: only New page.
|
|
1160
1300
|
const pageless = site && bridge.entryId === null;
|
|
1161
|
-
// …unless it shows a product: then Add a product
|
|
1162
|
-
|
|
1301
|
+
// …unless it shows a product (collection): then Add a product
|
|
1302
|
+
// (collection) page first.
|
|
1303
|
+
const shopHere = !pageless || !canCreate ? null : bridge.product ? 'product' : bridge.collection ? 'collection' : null;
|
|
1304
|
+
const productHere = shopHere !== null;
|
|
1305
|
+
const shopCopy = shopHere === 'collection' ? {
|
|
1306
|
+
add: labels.addCollectionPage,
|
|
1307
|
+
adding: labels.addingCollectionPage,
|
|
1308
|
+
hint: labels.collectionPageHint
|
|
1309
|
+
} : {
|
|
1310
|
+
add: labels.addProductPage,
|
|
1311
|
+
adding: labels.addingProductPage,
|
|
1312
|
+
hint: labels.productPageHint
|
|
1313
|
+
};
|
|
1314
|
+
addProduct.lastChild.textContent = shopCopy.add;
|
|
1163
1315
|
const onlyNew = pageless && canCreate && !productHere;
|
|
1164
1316
|
if (!canCreate) creating = false;
|
|
1165
1317
|
if (onlyNew) creating = true;
|
|
@@ -1169,7 +1321,7 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1169
1321
|
if (showForm && !formHandle) mountForm();
|
|
1170
1322
|
else if (!showForm && formHandle) unmountForm();
|
|
1171
1323
|
const offerProduct = productHere && !creating;
|
|
1172
|
-
pillText.textContent = offerProduct ?
|
|
1324
|
+
pillText.textContent = offerProduct ? shopCopy.add : onlyNew ? labels.newPage : labels.open;
|
|
1173
1325
|
cancelNew.hidden = onlyNew;
|
|
1174
1326
|
scope.hidden = creating || offerProduct;
|
|
1175
1327
|
newScope.hidden = !creating;
|
|
@@ -1183,6 +1335,7 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1183
1335
|
input.hidden = form || picking || minimized || offerProduct;
|
|
1184
1336
|
formBox.hidden = !form || picking || minimized;
|
|
1185
1337
|
formBox.classList.toggle('loading', formLoading);
|
|
1338
|
+
formLoader.hidden = !formLoading;
|
|
1186
1339
|
toolbar.hidden = picking;
|
|
1187
1340
|
pagesSection.hidden = !picking;
|
|
1188
1341
|
input.placeholder = creating ? labels.newPagePlaceholder : labels.placeholder;
|
|
@@ -1223,8 +1376,9 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1223
1376
|
pageChip.setAttribute('aria-expanded', String(picking));
|
|
1224
1377
|
pageChipText.textContent = pages?.find(({ entryId })=>entryId === bridge.entryId)?.name ?? labels.pages;
|
|
1225
1378
|
const loadingForm = form && formLoading && !picking;
|
|
1226
|
-
const working = state.prompting
|
|
1227
|
-
|
|
1379
|
+
const working = state.prompting;
|
|
1380
|
+
// A form opening says so in its own place.
|
|
1381
|
+
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 : '');
|
|
1228
1382
|
status.textContent = note;
|
|
1229
1383
|
status.hidden = !note || minimized;
|
|
1230
1384
|
status.className = `status${working ? ' working' : ''}${!busy && !loadingForm && message?.error ? ' error' : ''}`;
|
|
@@ -1447,11 +1601,19 @@ const mountPromptBox = (doc, bridge, options = {})=>{
|
|
|
1447
1601
|
message = null;
|
|
1448
1602
|
try {
|
|
1449
1603
|
// The bridge reloads the page; this shows until it does.
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1604
|
+
if (bridge.product) {
|
|
1605
|
+
await bridge.createProductPage();
|
|
1606
|
+
message = {
|
|
1607
|
+
text: labels.addedProductPage,
|
|
1608
|
+
error: false
|
|
1609
|
+
};
|
|
1610
|
+
} else {
|
|
1611
|
+
await bridge.createCollectionPage();
|
|
1612
|
+
message = {
|
|
1613
|
+
text: labels.addedCollectionPage,
|
|
1614
|
+
error: false
|
|
1615
|
+
};
|
|
1616
|
+
}
|
|
1455
1617
|
} catch (error) {
|
|
1456
1618
|
message = failure(error);
|
|
1457
1619
|
}
|
|
@@ -1648,7 +1810,7 @@ const FORM_BURST_MS = 1000;
|
|
|
1648
1810
|
// How long the page waits for the form's edits to settle before it shows
|
|
1649
1811
|
// them.
|
|
1650
1812
|
const FORM_RENDER_MS = 300;
|
|
1651
|
-
const createSiteBridge = (win, basePath, { pagePath = (path)=>`/${path}`, productPath: ownProductPath } = {})=>{
|
|
1813
|
+
const createSiteBridge = (win, basePath, { pagePath = (path)=>`/${path}`, productPath: ownProductPath, collectionPath: ownCollectionPath } = {})=>{
|
|
1652
1814
|
const doc = win.document;
|
|
1653
1815
|
const emitter = createEmitter();
|
|
1654
1816
|
const cleanup = [];
|
|
@@ -1659,6 +1821,7 @@ const createSiteBridge = (win, basePath, { pagePath = (path)=>`/${path}`, produc
|
|
|
1659
1821
|
const touched = new Set();
|
|
1660
1822
|
let session = null;
|
|
1661
1823
|
const productPath = (handle, locale)=>ownProductPath ? ownProductPath(handle, locale) : (session?.productPath ?? '/products/{handle}').replaceAll('{handle}', encodeURIComponent(handle));
|
|
1824
|
+
const collectionPath = (handle, locale)=>ownCollectionPath ? ownCollectionPath(handle, locale) : (session?.collectionPath ?? '/collections/{handle}').replaceAll('{handle}', encodeURIComponent(handle));
|
|
1662
1825
|
// The open form's, if any; and when the form last changed content, for
|
|
1663
1826
|
// undo steps (-Infinity: the next edit starts a new step).
|
|
1664
1827
|
let closeForm = null;
|
|
@@ -1713,6 +1876,16 @@ const createSiteBridge = (win, basePath, { pagePath = (path)=>`/${path}`, produc
|
|
|
1713
1876
|
handle
|
|
1714
1877
|
} : null;
|
|
1715
1878
|
};
|
|
1879
|
+
// The collection the page shows (editableCollection), if it marks one.
|
|
1880
|
+
const pageCollection = ()=>{
|
|
1881
|
+
const element = doc.querySelector(`[${COLLECTION_ATTRIBUTE}]`);
|
|
1882
|
+
const id = element?.getAttribute(COLLECTION_ATTRIBUTE);
|
|
1883
|
+
const handle = element?.getAttribute(COLLECTION_HANDLE_ATTRIBUTE);
|
|
1884
|
+
return id && handle ? {
|
|
1885
|
+
id,
|
|
1886
|
+
handle
|
|
1887
|
+
} : null;
|
|
1888
|
+
};
|
|
1716
1889
|
const entryFor = (uid)=>{
|
|
1717
1890
|
const block = uid ? doc.querySelector(blockSelector(uid)) : null;
|
|
1718
1891
|
return block?.closest(`[${ENTRY_ATTRIBUTE}]`)?.getAttribute(ENTRY_ATTRIBUTE) ?? pageEntryId();
|
|
@@ -1823,6 +1996,9 @@ const createSiteBridge = (win, basePath, { pagePath = (path)=>`/${path}`, produc
|
|
|
1823
1996
|
get product () {
|
|
1824
1997
|
return pageProduct();
|
|
1825
1998
|
},
|
|
1999
|
+
get collection () {
|
|
2000
|
+
return pageCollection();
|
|
2001
|
+
},
|
|
1826
2002
|
environment: null,
|
|
1827
2003
|
on: emitter.on,
|
|
1828
2004
|
getState: ()=>state,
|
|
@@ -1920,6 +2096,34 @@ const createSiteBridge = (win, basePath, { pagePath = (path)=>`/${path}`, produc
|
|
|
1920
2096
|
});
|
|
1921
2097
|
}
|
|
1922
2098
|
},
|
|
2099
|
+
async createCollectionPage (collection = pageCollection() ?? undefined) {
|
|
2100
|
+
if (!collection) {
|
|
2101
|
+
throw new Error('Nothing on this page is marked as a collection: add editableCollection(collection)');
|
|
2102
|
+
}
|
|
2103
|
+
if (!has('create')) throw new Error('You may not add pages here');
|
|
2104
|
+
if (state.unsaved) {
|
|
2105
|
+
throw new Error('Save or undo your changes before adding a page');
|
|
2106
|
+
}
|
|
2107
|
+
setState({
|
|
2108
|
+
prompting: true
|
|
2109
|
+
});
|
|
2110
|
+
try {
|
|
2111
|
+
const made = await api('collection-pages', {
|
|
2112
|
+
collection: {
|
|
2113
|
+
id: collection.id,
|
|
2114
|
+
handle: collection.handle
|
|
2115
|
+
}
|
|
2116
|
+
});
|
|
2117
|
+
// The site's collection route finds its page now (drafts, while
|
|
2118
|
+
// editing): show it.
|
|
2119
|
+
win.location.reload();
|
|
2120
|
+
return made;
|
|
2121
|
+
} finally{
|
|
2122
|
+
setState({
|
|
2123
|
+
prompting: false
|
|
2124
|
+
});
|
|
2125
|
+
}
|
|
2126
|
+
},
|
|
1923
2127
|
async view (options = {}) {
|
|
1924
2128
|
const { uid, entryId } = target(options.uid);
|
|
1925
2129
|
const entry = await load(entryId);
|
|
@@ -2073,8 +2277,9 @@ const createSiteBridge = (win, basePath, { pagePath = (path)=>`/${path}`, produc
|
|
|
2073
2277
|
contentType: page.contentType,
|
|
2074
2278
|
status: page.status,
|
|
2075
2279
|
path,
|
|
2076
|
-
url: page.product ? productPath(page.product.handle, code) : pagePath(path, code),
|
|
2077
|
-
product: page.product ?? null
|
|
2280
|
+
url: page.product ? productPath(page.product.handle, code) : page.collection ? collectionPath(page.collection.handle, code) : pagePath(path, code),
|
|
2281
|
+
product: page.product ?? null,
|
|
2282
|
+
collection: page.collection ?? null
|
|
2078
2283
|
}
|
|
2079
2284
|
];
|
|
2080
2285
|
});
|
|
@@ -2219,7 +2424,7 @@ const peekContentBridge = ()=>typeof window === 'undefined' ? null : window[KEY]
|
|
|
2219
2424
|
// if (bridge.isEditing) bridge.on('update', ({ entry }) => render(entry))
|
|
2220
2425
|
//
|
|
2221
2426
|
// The first call's options win: there is one bridge per page.
|
|
2222
|
-
const getContentBridge = ({ url, prompt = true, pagePath, productPath } = {})=>{
|
|
2427
|
+
const getContentBridge = ({ url, prompt = true, pagePath, productPath, collectionPath } = {})=>{
|
|
2223
2428
|
if (typeof window === 'undefined') return SERVER_BRIDGE;
|
|
2224
2429
|
const win = window;
|
|
2225
2430
|
if (win[KEY]) return win[KEY];
|
|
@@ -2233,12 +2438,26 @@ const getContentBridge = ({ url, prompt = true, pagePath, productPath } = {})=>{
|
|
|
2233
2438
|
const sitePath = bridge.isEditing || win.parent !== win ? null : readSiteEditing(win.document);
|
|
2234
2439
|
if (sitePath) bridge = createSiteBridge(win, sitePath, {
|
|
2235
2440
|
pagePath,
|
|
2236
|
-
productPath
|
|
2441
|
+
productPath,
|
|
2442
|
+
collectionPath
|
|
2237
2443
|
});
|
|
2238
2444
|
if (bridge.isEditing && prompt) {
|
|
2239
|
-
const
|
|
2445
|
+
const doc = win.document;
|
|
2446
|
+
let unmount = ()=>{};
|
|
2447
|
+
let destroyed = false;
|
|
2448
|
+
const mount = ()=>{
|
|
2449
|
+
if (destroyed) return;
|
|
2450
|
+
unmount = mountPromptBox(doc, bridge, prompt === true ? {} : prompt);
|
|
2451
|
+
};
|
|
2452
|
+
// A script tag in <head> runs before there is a body to mount into.
|
|
2453
|
+
if (doc.body) mount();
|
|
2454
|
+
else doc.addEventListener('DOMContentLoaded', mount, {
|
|
2455
|
+
once: true
|
|
2456
|
+
});
|
|
2240
2457
|
const destroy = bridge.destroy;
|
|
2241
2458
|
bridge.destroy = ()=>{
|
|
2459
|
+
destroyed = true;
|
|
2460
|
+
doc.removeEventListener('DOMContentLoaded', mount);
|
|
2242
2461
|
unmount();
|
|
2243
2462
|
destroy();
|
|
2244
2463
|
};
|
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 };
|
|
@@ -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,11 +98,14 @@ const readPreviewParams = (input)=>{
|
|
|
84
98
|
};
|
|
85
99
|
};
|
|
86
100
|
|
|
101
|
+
exports.COLLECTION_ATTRIBUTE = COLLECTION_ATTRIBUTE;
|
|
102
|
+
exports.COLLECTION_HANDLE_ATTRIBUTE = COLLECTION_HANDLE_ATTRIBUTE;
|
|
87
103
|
exports.ENTRY_ATTRIBUTE = ENTRY_ATTRIBUTE;
|
|
88
104
|
exports.PREVIEW_PARAMS = PREVIEW_PARAMS;
|
|
89
105
|
exports.PRODUCT_ATTRIBUTE = PRODUCT_ATTRIBUTE;
|
|
90
106
|
exports.PRODUCT_HANDLE_ATTRIBUTE = PRODUCT_HANDLE_ATTRIBUTE;
|
|
91
107
|
exports.UID_ATTRIBUTE = UID_ATTRIBUTE;
|
|
92
108
|
exports.editable = editable;
|
|
109
|
+
exports.editableCollection = editableCollection;
|
|
93
110
|
exports.editableProduct = editableProduct;
|
|
94
111
|
exports.readPreviewParams = readPreviewParams;
|