cms-renderer 0.6.10 → 0.6.11
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/dist/lib/block-renderer.d.ts +27 -8
- package/dist/lib/block-renderer.js +409 -109
- package/dist/lib/block-renderer.js.map +1 -1
- package/dist/lib/client-editable-block.d.ts +5 -2
- package/dist/lib/client-editable-block.js +53 -11
- package/dist/lib/client-editable-block.js.map +1 -1
- package/dist/lib/custom-schemas.js.map +1 -1
- package/dist/lib/parametric-route.d.ts +7 -3
- package/dist/lib/parametric-route.js +411 -135
- package/dist/lib/parametric-route.js.map +1 -1
- package/dist/lib/renderer.js +411 -135
- package/dist/lib/renderer.js.map +1 -1
- package/package.json +1 -1
|
@@ -46,6 +46,15 @@ declare function walkReactNode(node: React__default.ReactNode, visitors: WalkVis
|
|
|
46
46
|
key?: React__default.Key | null;
|
|
47
47
|
inSvg?: boolean;
|
|
48
48
|
}): React__default.ReactNode;
|
|
49
|
+
type ContentMatch = {
|
|
50
|
+
contentPath: string;
|
|
51
|
+
value: string;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Extracts all string values from a content object with their paths.
|
|
55
|
+
* Returns a Map where keys are string values and values are arrays of content paths.
|
|
56
|
+
*/
|
|
57
|
+
declare function extractContentValues(content: Record<string, unknown>, basePath?: string[]): Map<string, ContentMatch[]>;
|
|
49
58
|
/**
|
|
50
59
|
* Renders the shared CMS edit-mode styles and click-routing script.
|
|
51
60
|
* Place this once at the top of your page when edit_mode is active.
|
|
@@ -79,20 +88,30 @@ interface BlockRendererProps {
|
|
|
79
88
|
*/
|
|
80
89
|
path?: string;
|
|
81
90
|
}
|
|
91
|
+
/**
|
|
92
|
+
* Returns true if each segment of `path` matches the corresponding segment in
|
|
93
|
+
* `pattern`, where a pattern segment wrapped in `{…}` or `(…)` is a wildcard.
|
|
94
|
+
*/
|
|
95
|
+
declare function pathMatchesPattern(path: string, pattern: string): boolean;
|
|
96
|
+
/**
|
|
97
|
+
* Resolves the component for `blockType` from the registry.
|
|
98
|
+
*
|
|
99
|
+
* When `path` is provided, keys of the form `"/{pattern} BlockType"` are
|
|
100
|
+
* checked first. The first key whose path pattern matches the current path
|
|
101
|
+
* and whose block-type suffix matches `blockType` wins. Falls back to a
|
|
102
|
+
* direct `registry[blockType]` lookup.
|
|
103
|
+
*/
|
|
104
|
+
declare function resolveComponent(registry: Partial<BlockComponentRegistry>, blockType: string, path?: string): BlockComponentRegistry[string] | undefined;
|
|
82
105
|
/**
|
|
83
106
|
* Renders a single block by dispatching to the appropriate component.
|
|
84
107
|
*
|
|
85
108
|
* Uses the ComponentMap pattern: the block's `type` field determines which
|
|
86
109
|
* component renders the block's `content`.
|
|
87
110
|
*
|
|
88
|
-
* In editable mode,
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
* - Portals the BlockToolbar into the component's root element
|
|
92
|
-
*
|
|
93
|
-
* Render CmsEditableInit once at the page level to include the shared styles
|
|
94
|
-
* and click-routing script.
|
|
111
|
+
* In editable mode, renders a hidden sentinel before the component. The shared
|
|
112
|
+
* CMS overlay script uses that sentinel to stamp attributes on the component's
|
|
113
|
+
* root element without adding a layout-affecting wrapper.
|
|
95
114
|
*/
|
|
96
115
|
declare function BlockRenderer({ block, registry, disableEditable, routeParams, path, }: BlockRendererProps): React__default.JSX.Element | null;
|
|
97
116
|
|
|
98
|
-
export { BlockRenderer, CmsEditableInit, walkReactNode };
|
|
117
|
+
export { BlockRenderer, CmsEditableInit, extractContentValues, pathMatchesPattern, resolveComponent, walkReactNode };
|
|
@@ -1,6 +1,390 @@
|
|
|
1
1
|
// lib/block-renderer.tsx
|
|
2
2
|
import React from "react";
|
|
3
|
-
|
|
3
|
+
|
|
4
|
+
// lib/cms-overlay-script.ts
|
|
5
|
+
function generateCmsOverlayScript(cmsParentOrigin) {
|
|
6
|
+
return `
|
|
7
|
+
(function() {
|
|
8
|
+
if (window.__cmsOverlayInitialized) return;
|
|
9
|
+
window.__cmsOverlayInitialized = true;
|
|
10
|
+
|
|
11
|
+
var CMS_PARENT_ORIGIN = ${JSON.stringify(cmsParentOrigin)};
|
|
12
|
+
|
|
13
|
+
var style = document.createElement('style');
|
|
14
|
+
style.setAttribute('data-cms-overlay', '');
|
|
15
|
+
style.textContent = \`
|
|
16
|
+
[data-cms-editable] {
|
|
17
|
+
cursor: pointer;
|
|
18
|
+
border-radius: 2px;
|
|
19
|
+
}
|
|
20
|
+
[data-cms-editable]:hover {
|
|
21
|
+
outline: 2px solid #3b82f6;
|
|
22
|
+
outline-offset: 2px;
|
|
23
|
+
}
|
|
24
|
+
#cms-overlay-root {
|
|
25
|
+
position: fixed;
|
|
26
|
+
top: 0;
|
|
27
|
+
left: 0;
|
|
28
|
+
width: 0;
|
|
29
|
+
height: 0;
|
|
30
|
+
pointer-events: none;
|
|
31
|
+
z-index: 99998;
|
|
32
|
+
}
|
|
33
|
+
#cms-overlay-root > * {
|
|
34
|
+
pointer-events: auto;
|
|
35
|
+
}
|
|
36
|
+
.cms-block-outline {
|
|
37
|
+
position: fixed;
|
|
38
|
+
border: 2px solid #3b82f6;
|
|
39
|
+
border-radius: 4px;
|
|
40
|
+
pointer-events: none;
|
|
41
|
+
z-index: 99997;
|
|
42
|
+
transition: all 0.15s ease;
|
|
43
|
+
}
|
|
44
|
+
.cms-block-outline.cms-outline-selected {
|
|
45
|
+
border-color: #2563eb;
|
|
46
|
+
border-width: 3px;
|
|
47
|
+
}
|
|
48
|
+
.cms-block-cursor {
|
|
49
|
+
position: fixed;
|
|
50
|
+
width: 22px;
|
|
51
|
+
height: 22px;
|
|
52
|
+
background: radial-gradient(circle, #fff 5px, #000 5px);
|
|
53
|
+
border-radius: 50%;
|
|
54
|
+
pointer-events: none;
|
|
55
|
+
z-index: 99999;
|
|
56
|
+
transform: translate(-50%, -50%);
|
|
57
|
+
opacity: 0;
|
|
58
|
+
transition: opacity 0.1s ease;
|
|
59
|
+
}
|
|
60
|
+
.cms-block-cursor.cms-cursor-visible {
|
|
61
|
+
opacity: 1;
|
|
62
|
+
}
|
|
63
|
+
.cms-block-toolbar {
|
|
64
|
+
position: fixed;
|
|
65
|
+
display: flex;
|
|
66
|
+
gap: 4px;
|
|
67
|
+
background: #1f2937;
|
|
68
|
+
border-radius: 6px;
|
|
69
|
+
padding: 4px;
|
|
70
|
+
box-shadow: 0 4px 12px rgba(0,0,0,0.25);
|
|
71
|
+
z-index: 99999;
|
|
72
|
+
pointer-events: none;
|
|
73
|
+
opacity: 0;
|
|
74
|
+
transform: scale(0.9) translateY(4px);
|
|
75
|
+
transition: opacity 0.15s ease, transform 0.15s ease;
|
|
76
|
+
}
|
|
77
|
+
.cms-block-toolbar.cms-toolbar-visible {
|
|
78
|
+
opacity: 1;
|
|
79
|
+
transform: scale(1) translateY(0);
|
|
80
|
+
pointer-events: auto;
|
|
81
|
+
}
|
|
82
|
+
.cms-block-toolbar button {
|
|
83
|
+
display: flex;
|
|
84
|
+
align-items: center;
|
|
85
|
+
justify-content: center;
|
|
86
|
+
width: 28px;
|
|
87
|
+
height: 28px;
|
|
88
|
+
border: none;
|
|
89
|
+
background: transparent;
|
|
90
|
+
color: #9ca3af;
|
|
91
|
+
border-radius: 4px;
|
|
92
|
+
cursor: pointer;
|
|
93
|
+
transition: background 0.15s ease, color 0.15s ease;
|
|
94
|
+
}
|
|
95
|
+
.cms-block-toolbar button:hover {
|
|
96
|
+
background: #374151;
|
|
97
|
+
color: #fff;
|
|
98
|
+
}
|
|
99
|
+
.cms-block-toolbar button.delete:hover {
|
|
100
|
+
background: #dc2626;
|
|
101
|
+
color: #fff;
|
|
102
|
+
}
|
|
103
|
+
.cms-block-toolbar button:disabled {
|
|
104
|
+
opacity: 0.4;
|
|
105
|
+
cursor: not-allowed;
|
|
106
|
+
}
|
|
107
|
+
.cms-block-toolbar button:disabled:hover {
|
|
108
|
+
background: transparent;
|
|
109
|
+
color: #9ca3af;
|
|
110
|
+
}
|
|
111
|
+
.cms-block-toolbar svg {
|
|
112
|
+
width: 16px;
|
|
113
|
+
height: 16px;
|
|
114
|
+
}
|
|
115
|
+
\`;
|
|
116
|
+
document.head.appendChild(style);
|
|
117
|
+
|
|
118
|
+
function stampBlockElements() {
|
|
119
|
+
var sentinels = document.querySelectorAll('[data-cms-sentinel]');
|
|
120
|
+
sentinels.forEach(function(sentinel) {
|
|
121
|
+
var blockEl = sentinel.nextElementSibling;
|
|
122
|
+
if (!blockEl) return;
|
|
123
|
+
|
|
124
|
+
var blockId = sentinel.getAttribute('data-block-id');
|
|
125
|
+
var blockType = sentinel.getAttribute('data-block-type');
|
|
126
|
+
|
|
127
|
+
blockEl.setAttribute('data-cms-block', '');
|
|
128
|
+
blockEl.setAttribute('data-block-id', blockId);
|
|
129
|
+
blockEl.setAttribute('data-block-type', blockType);
|
|
130
|
+
blockEl.setAttribute('data-cms-editable', '');
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
stampBlockElements();
|
|
135
|
+
|
|
136
|
+
var stampObserver = new MutationObserver(function(mutations) {
|
|
137
|
+
var needsStamp = mutations.some(function(m) {
|
|
138
|
+
return m.addedNodes.length > 0;
|
|
139
|
+
});
|
|
140
|
+
if (needsStamp) stampBlockElements();
|
|
141
|
+
});
|
|
142
|
+
stampObserver.observe(document.body, { childList: true, subtree: true });
|
|
143
|
+
|
|
144
|
+
var overlayRoot = document.createElement('div');
|
|
145
|
+
overlayRoot.id = 'cms-overlay-root';
|
|
146
|
+
document.body.appendChild(overlayRoot);
|
|
147
|
+
|
|
148
|
+
var cursor = document.createElement('div');
|
|
149
|
+
cursor.className = 'cms-block-cursor';
|
|
150
|
+
overlayRoot.appendChild(cursor);
|
|
151
|
+
|
|
152
|
+
var outline = document.createElement('div');
|
|
153
|
+
outline.className = 'cms-block-outline';
|
|
154
|
+
outline.style.display = 'none';
|
|
155
|
+
overlayRoot.appendChild(outline);
|
|
156
|
+
|
|
157
|
+
var selectedOutline = document.createElement('div');
|
|
158
|
+
selectedOutline.className = 'cms-block-outline cms-outline-selected';
|
|
159
|
+
selectedOutline.style.display = 'none';
|
|
160
|
+
overlayRoot.appendChild(selectedOutline);
|
|
161
|
+
|
|
162
|
+
var toolbar = document.createElement('div');
|
|
163
|
+
toolbar.className = 'cms-block-toolbar';
|
|
164
|
+
toolbar.setAttribute('data-cms-toolbar', '');
|
|
165
|
+
toolbar.innerHTML = \`
|
|
166
|
+
<button class="move-up" title="Move up">
|
|
167
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
168
|
+
<path d="M18 15l-6-6-6 6"/>
|
|
169
|
+
</svg>
|
|
170
|
+
</button>
|
|
171
|
+
<button class="move-down" title="Move down">
|
|
172
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
173
|
+
<path d="M6 9l6 6 6-6"/>
|
|
174
|
+
</svg>
|
|
175
|
+
</button>
|
|
176
|
+
<button class="delete" title="Delete">
|
|
177
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
178
|
+
<path d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/>
|
|
179
|
+
</svg>
|
|
180
|
+
</button>
|
|
181
|
+
\`;
|
|
182
|
+
overlayRoot.appendChild(toolbar);
|
|
183
|
+
|
|
184
|
+
var currentBlockId = null;
|
|
185
|
+
var toolbarVisible = false;
|
|
186
|
+
var selectedBlockId = null;
|
|
187
|
+
|
|
188
|
+
function postToParent(message) {
|
|
189
|
+
if (!CMS_PARENT_ORIGIN || !window.parent || window.parent === window) {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
window.parent.postMessage(message, CMS_PARENT_ORIGIN);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
function sendReadySignal() {
|
|
196
|
+
postToParent({ type: 'cms-preview-ready' });
|
|
197
|
+
}
|
|
198
|
+
sendReadySignal();
|
|
199
|
+
// The preview iframe can execute before the admin listener is attached.
|
|
200
|
+
setTimeout(sendReadySignal, 500);
|
|
201
|
+
setTimeout(sendReadySignal, 1500);
|
|
202
|
+
|
|
203
|
+
function getBlockElement(blockId) {
|
|
204
|
+
return document.querySelector('[data-block-id="' + blockId + '"]');
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function getAllBlocks() {
|
|
208
|
+
return Array.from(document.querySelectorAll('[data-cms-block]'));
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function getBlockIndex(blockId) {
|
|
212
|
+
var blocks = getAllBlocks();
|
|
213
|
+
for (var i = 0; i < blocks.length; i++) {
|
|
214
|
+
if (blocks[i].getAttribute('data-block-id') === blockId) return i;
|
|
215
|
+
}
|
|
216
|
+
return -1;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
function updateOutline(el, outlineEl) {
|
|
220
|
+
if (!el) {
|
|
221
|
+
outlineEl.style.display = 'none';
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
var rect = el.getBoundingClientRect();
|
|
225
|
+
outlineEl.style.display = 'block';
|
|
226
|
+
outlineEl.style.top = rect.top + 'px';
|
|
227
|
+
outlineEl.style.left = rect.left + 'px';
|
|
228
|
+
outlineEl.style.width = rect.width + 'px';
|
|
229
|
+
outlineEl.style.height = rect.height + 'px';
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
function positionToolbar(x, y) {
|
|
233
|
+
var rect = toolbar.getBoundingClientRect();
|
|
234
|
+
var top = Math.max(4, y - rect.height - 12);
|
|
235
|
+
var left = Math.max(4, Math.min(x - rect.width / 2, window.innerWidth - rect.width - 4));
|
|
236
|
+
toolbar.style.top = top + 'px';
|
|
237
|
+
toolbar.style.left = left + 'px';
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
function showToolbar(x, y, blockId) {
|
|
241
|
+
currentBlockId = blockId;
|
|
242
|
+
toolbarVisible = true;
|
|
243
|
+
positionToolbar(x, y);
|
|
244
|
+
toolbar.classList.add('cms-toolbar-visible');
|
|
245
|
+
|
|
246
|
+
var index = getBlockIndex(blockId);
|
|
247
|
+
var total = getAllBlocks().length;
|
|
248
|
+
toolbar.querySelector('.move-up').disabled = index <= 0;
|
|
249
|
+
toolbar.querySelector('.move-down').disabled = index >= total - 1;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
function hideToolbar() {
|
|
253
|
+
toolbarVisible = false;
|
|
254
|
+
toolbar.classList.remove('cms-toolbar-visible');
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
function showCursor(x, y) {
|
|
258
|
+
cursor.style.top = y + 'px';
|
|
259
|
+
cursor.style.left = x + 'px';
|
|
260
|
+
cursor.classList.add('cms-cursor-visible');
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
function hideCursor() {
|
|
264
|
+
cursor.classList.remove('cms-cursor-visible');
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
document.addEventListener('mouseover', function(e) {
|
|
268
|
+
if (toolbarVisible) return;
|
|
269
|
+
var block = e.target.closest('[data-cms-block]');
|
|
270
|
+
if (block) {
|
|
271
|
+
updateOutline(block, outline);
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
document.addEventListener('mouseout', function(e) {
|
|
276
|
+
var block = e.target.closest('[data-cms-block]');
|
|
277
|
+
var related = e.relatedTarget ? e.relatedTarget.closest('[data-cms-block]') : null;
|
|
278
|
+
if (block && block !== related) {
|
|
279
|
+
outline.style.display = 'none';
|
|
280
|
+
hideCursor();
|
|
281
|
+
}
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
document.addEventListener('mousemove', function(e) {
|
|
285
|
+
if (toolbarVisible) return;
|
|
286
|
+
var block = e.target.closest('[data-cms-block]');
|
|
287
|
+
if (block) {
|
|
288
|
+
showCursor(e.clientX, e.clientY);
|
|
289
|
+
}
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
document.addEventListener('contextmenu', function(e) {
|
|
293
|
+
if (e.target.closest('[data-cms-toolbar]')) return;
|
|
294
|
+
var block = e.target.closest('[data-cms-block]');
|
|
295
|
+
if (block) {
|
|
296
|
+
if (toolbarVisible) return;
|
|
297
|
+
e.preventDefault();
|
|
298
|
+
hideCursor();
|
|
299
|
+
outline.style.display = 'none';
|
|
300
|
+
var blockId = block.getAttribute('data-block-id');
|
|
301
|
+
showToolbar(e.clientX, e.clientY, blockId);
|
|
302
|
+
}
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
document.addEventListener('click', function(e) {
|
|
306
|
+
if (toolbarVisible && !e.target.closest('[data-cms-toolbar]')) {
|
|
307
|
+
var block = e.target.closest('[data-cms-block]');
|
|
308
|
+
if (!block || block.getAttribute('data-block-id') !== currentBlockId) {
|
|
309
|
+
hideToolbar();
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
if (e.target.closest('[data-cms-toolbar]')) return;
|
|
314
|
+
|
|
315
|
+
var editable = e.target.closest('[data-cms-editable]');
|
|
316
|
+
if (editable) {
|
|
317
|
+
postToParent({
|
|
318
|
+
type: 'cms-editable-click',
|
|
319
|
+
blockId: editable.getAttribute('data-block-id'),
|
|
320
|
+
blockType: editable.getAttribute('data-block-type'),
|
|
321
|
+
contentPath: editable.getAttribute('data-content-path')
|
|
322
|
+
});
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
var block = e.target.closest('[data-cms-block]');
|
|
327
|
+
if (block) {
|
|
328
|
+
postToParent({
|
|
329
|
+
type: 'cms-editable-click',
|
|
330
|
+
blockId: block.getAttribute('data-block-id'),
|
|
331
|
+
blockType: block.getAttribute('data-block-type'),
|
|
332
|
+
contentPath: null
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
toolbar.querySelector('.move-up').addEventListener('click', function() {
|
|
338
|
+
if (!currentBlockId) return;
|
|
339
|
+
postToParent({ type: 'cms-block-move', blockId: currentBlockId, direction: 'up' });
|
|
340
|
+
hideToolbar();
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
toolbar.querySelector('.move-down').addEventListener('click', function() {
|
|
344
|
+
if (!currentBlockId) return;
|
|
345
|
+
postToParent({ type: 'cms-block-move', blockId: currentBlockId, direction: 'down' });
|
|
346
|
+
hideToolbar();
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
toolbar.querySelector('.delete').addEventListener('click', function() {
|
|
350
|
+
if (!currentBlockId) return;
|
|
351
|
+
postToParent({ type: 'cms-block-delete', blockId: currentBlockId });
|
|
352
|
+
hideToolbar();
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
window.addEventListener('scroll', function() {
|
|
356
|
+
hideCursor();
|
|
357
|
+
hideToolbar();
|
|
358
|
+
if (selectedBlockId) {
|
|
359
|
+
var el = getBlockElement(selectedBlockId);
|
|
360
|
+
updateOutline(el, selectedOutline);
|
|
361
|
+
}
|
|
362
|
+
}, { passive: true, capture: true });
|
|
363
|
+
|
|
364
|
+
window.addEventListener('resize', function() {
|
|
365
|
+
if (selectedBlockId) {
|
|
366
|
+
var el = getBlockElement(selectedBlockId);
|
|
367
|
+
updateOutline(el, selectedOutline);
|
|
368
|
+
}
|
|
369
|
+
}, { passive: true });
|
|
370
|
+
|
|
371
|
+
window.addEventListener('message', function(e) {
|
|
372
|
+
if (CMS_PARENT_ORIGIN && e.origin !== CMS_PARENT_ORIGIN) return;
|
|
373
|
+
if (e.source !== window.parent) return;
|
|
374
|
+
|
|
375
|
+
if (e.data && e.data.type === 'cms-select-block') {
|
|
376
|
+
selectedBlockId = e.data.blockId || null;
|
|
377
|
+
if (selectedBlockId) {
|
|
378
|
+
var el = getBlockElement(selectedBlockId);
|
|
379
|
+
updateOutline(el, selectedOutline);
|
|
380
|
+
} else {
|
|
381
|
+
selectedOutline.style.display = 'none';
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
});
|
|
385
|
+
})();
|
|
386
|
+
`;
|
|
387
|
+
}
|
|
4
388
|
|
|
5
389
|
// lib/cms-post-message.ts
|
|
6
390
|
var CMS_PARENT_ORIGIN_PARAM = "cms_parent_origin";
|
|
@@ -128,112 +512,15 @@ function CmsEditableInit({
|
|
|
128
512
|
cmsUrl,
|
|
129
513
|
cmsParentOrigin
|
|
130
514
|
}) {
|
|
131
|
-
const
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
cursor: pointer;
|
|
138
|
-
border-radius: 2px;
|
|
139
|
-
}
|
|
140
|
-
[data-cms-editable]:hover {
|
|
141
|
-
outline: 2px solid #3b82f6;
|
|
142
|
-
outline-offset: 2px;
|
|
143
|
-
}
|
|
144
|
-
.cms-block-toolbar {
|
|
145
|
-
position: fixed;
|
|
146
|
-
display: flex;
|
|
147
|
-
gap: 4px;
|
|
148
|
-
background: #1f2937;
|
|
149
|
-
border-radius: 6px;
|
|
150
|
-
padding: 4px;
|
|
151
|
-
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
|
152
|
-
transition: opacity 0.15s ease;
|
|
153
|
-
z-index: 99999;
|
|
154
|
-
pointer-events: auto;
|
|
155
|
-
}
|
|
156
|
-
.cms-block-toolbar button {
|
|
157
|
-
display: flex;
|
|
158
|
-
align-items: center;
|
|
159
|
-
justify-content: center;
|
|
160
|
-
width: 28px;
|
|
161
|
-
height: 28px;
|
|
162
|
-
border: none;
|
|
163
|
-
background: transparent;
|
|
164
|
-
color: #9ca3af;
|
|
165
|
-
border-radius: 4px;
|
|
166
|
-
cursor: pointer;
|
|
167
|
-
transition: background 0.15s ease, color 0.15s ease;
|
|
168
|
-
}
|
|
169
|
-
.cms-block-toolbar button:hover {
|
|
170
|
-
background: #374151;
|
|
171
|
-
color: #fff;
|
|
172
|
-
}
|
|
173
|
-
.cms-block-toolbar button.delete:hover {
|
|
174
|
-
background: #dc2626;
|
|
175
|
-
color: #fff;
|
|
176
|
-
}
|
|
177
|
-
.cms-block-toolbar button:disabled {
|
|
178
|
-
opacity: 0.4;
|
|
179
|
-
cursor: not-allowed;
|
|
180
|
-
}
|
|
181
|
-
.cms-block-toolbar button:disabled:hover {
|
|
182
|
-
background: transparent;
|
|
183
|
-
color: #9ca3af;
|
|
184
|
-
}
|
|
185
|
-
.cms-block-toolbar svg {
|
|
186
|
-
width: 16px;
|
|
187
|
-
height: 16px;
|
|
188
|
-
}
|
|
189
|
-
` }),
|
|
190
|
-
/* @__PURE__ */ jsx(
|
|
191
|
-
"script",
|
|
192
|
-
{
|
|
193
|
-
dangerouslySetInnerHTML: {
|
|
194
|
-
__html: `
|
|
195
|
-
(function() {
|
|
196
|
-
var cmsParentOrigin = ${cmsParentOriginJson};
|
|
197
|
-
if (!window.__cmsEditableInitialized) {
|
|
198
|
-
window.__cmsEditableInitialized = true;
|
|
199
|
-
|
|
200
|
-
document.addEventListener('click', function(e) {
|
|
201
|
-
if (e.target.closest('.cms-block-toolbar')) return;
|
|
202
|
-
|
|
203
|
-
var editableTarget = e.target.closest('[data-cms-editable]');
|
|
204
|
-
if (editableTarget) {
|
|
205
|
-
var message = {
|
|
206
|
-
type: 'cms-editable-click',
|
|
207
|
-
blockId: editableTarget.getAttribute('data-block-id'),
|
|
208
|
-
blockType: editableTarget.getAttribute('data-block-type'),
|
|
209
|
-
contentPath: editableTarget.getAttribute('data-content-path')
|
|
210
|
-
};
|
|
211
|
-
if (cmsParentOrigin && window.parent && window.parent !== window) {
|
|
212
|
-
window.parent.postMessage(message, cmsParentOrigin);
|
|
213
|
-
}
|
|
214
|
-
return;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
var blockTarget = e.target.closest('[data-cms-block]');
|
|
218
|
-
if (blockTarget) {
|
|
219
|
-
var message = {
|
|
220
|
-
type: 'cms-editable-click',
|
|
221
|
-
blockId: blockTarget.getAttribute('data-block-id'),
|
|
222
|
-
blockType: blockTarget.getAttribute('data-block-type'),
|
|
223
|
-
contentPath: null
|
|
224
|
-
};
|
|
225
|
-
if (cmsParentOrigin && window.parent && window.parent !== window) {
|
|
226
|
-
window.parent.postMessage(message, cmsParentOrigin);
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
});
|
|
230
|
-
}
|
|
231
|
-
})();
|
|
232
|
-
`
|
|
233
|
-
}
|
|
515
|
+
const targetOrigin = getCmsParentTargetOrigin(cmsUrl, cmsParentOrigin) ?? "";
|
|
516
|
+
return /* @__PURE__ */ jsx(
|
|
517
|
+
"script",
|
|
518
|
+
{
|
|
519
|
+
dangerouslySetInnerHTML: {
|
|
520
|
+
__html: generateCmsOverlayScript(targetOrigin)
|
|
234
521
|
}
|
|
235
|
-
|
|
236
|
-
|
|
522
|
+
}
|
|
523
|
+
);
|
|
237
524
|
}
|
|
238
525
|
function pathMatchesPattern(path, pattern) {
|
|
239
526
|
const pathSegs = path.split("/").filter(Boolean);
|
|
@@ -284,13 +571,26 @@ function BlockRenderer({
|
|
|
284
571
|
if (disableEditable) {
|
|
285
572
|
return component;
|
|
286
573
|
}
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
574
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
575
|
+
/* @__PURE__ */ jsx(
|
|
576
|
+
"span",
|
|
577
|
+
{
|
|
578
|
+
"data-cms-sentinel": "",
|
|
579
|
+
"data-block-id": block.id,
|
|
580
|
+
"data-block-type": block.type,
|
|
581
|
+
style: { display: "none" },
|
|
582
|
+
"aria-hidden": "true"
|
|
583
|
+
}
|
|
584
|
+
),
|
|
585
|
+
component
|
|
586
|
+
] });
|
|
290
587
|
}
|
|
291
588
|
export {
|
|
292
589
|
BlockRenderer,
|
|
293
590
|
CmsEditableInit,
|
|
591
|
+
extractContentValues,
|
|
592
|
+
pathMatchesPattern,
|
|
593
|
+
resolveComponent,
|
|
294
594
|
walkReactNode
|
|
295
595
|
};
|
|
296
596
|
//# sourceMappingURL=block-renderer.js.map
|