@cmssy/react 0.16.0 → 0.17.1

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/client.cjs CHANGED
@@ -44,22 +44,37 @@ var PROTOCOL_VERSION = 2;
44
44
 
45
45
  // src/bridge/messages.ts
46
46
  function normalizeOrigin(origin) {
47
- if (origin === "*") return "*";
47
+ const trimmed = origin.trim();
48
+ if (trimmed === "*") return "*";
48
49
  try {
49
- return new URL(origin).origin;
50
+ return new URL(trimmed).origin;
50
51
  } catch {
51
- return origin;
52
+ return trimmed;
52
53
  }
53
54
  }
54
55
  function postToEditor(target, editorOrigin, message) {
55
56
  target.postMessage(message, normalizeOrigin(editorOrigin));
56
57
  }
58
+ function isOriginAllowed(origin, allowed) {
59
+ const list = Array.isArray(allowed) ? allowed : [allowed];
60
+ const actual = normalizeOrigin(origin);
61
+ return list.some((candidate) => {
62
+ const expected = normalizeOrigin(candidate);
63
+ return expected === "*" || expected === actual;
64
+ });
65
+ }
66
+ function resolveInitialTarget(editorOrigin) {
67
+ const list = (Array.isArray(editorOrigin) ? editorOrigin : [editorOrigin]).map((origin) => normalizeOrigin(origin));
68
+ if (list.includes("*")) return "*";
69
+ if (list.length === 1) return list[0];
70
+ const referrerOrigin = typeof document !== "undefined" && document.referrer ? normalizeOrigin(document.referrer) : "";
71
+ return list.find((origin) => origin === referrerOrigin) ?? list[0];
72
+ }
57
73
  function isObject(value) {
58
74
  return typeof value === "object" && value !== null && !Array.isArray(value);
59
75
  }
60
76
  function parseEditorMessage(data, origin, expectedOrigin) {
61
- const expected = normalizeOrigin(expectedOrigin);
62
- if (expected !== "*" && origin !== expected) return null;
77
+ if (!isOriginAllowed(origin, expectedOrigin)) return null;
63
78
  if (!isObject(data)) return null;
64
79
  switch (data.type) {
65
80
  case "cmssy:select":
@@ -74,6 +89,8 @@ function parseEditorMessage(data, origin, expectedOrigin) {
74
89
  blockId: data.blockId,
75
90
  content: data.content,
76
91
  protocolVersion: PROTOCOL_VERSION,
92
+ ...isObject(data.style) ? { style: data.style } : {},
93
+ ...isObject(data.advanced) ? { advanced: data.advanced } : {},
77
94
  ...typeof data.layoutPosition === "string" ? { layoutPosition: data.layoutPosition } : {}
78
95
  } : null;
79
96
  case "cmssy:parent-ready":
@@ -85,6 +102,8 @@ function parseEditorMessage(data, origin, expectedOrigin) {
85
102
  blockId: data.blockId,
86
103
  blockType: data.blockType,
87
104
  content: data.content,
105
+ ...isObject(data.style) ? { style: data.style } : {},
106
+ ...isObject(data.advanced) ? { advanced: data.advanced } : {},
88
107
  index: data.index
89
108
  } : null;
90
109
  case "cmssy:reorder":
@@ -148,6 +167,8 @@ function collectLayoutBlocks(rects, pageIds) {
148
167
  }
149
168
  function useEditBridge(page, config) {
150
169
  const [patches, setPatches] = react.useState({});
170
+ const [patchesStyle, setPatchesStyle] = react.useState({});
171
+ const [patchesAdvanced, setPatchesAdvanced] = react.useState({});
151
172
  const [selected, setSelected] = react.useState(null);
152
173
  const [inserted, setInserted] = react.useState([]);
153
174
  const [order, setOrder] = react.useState(null);
@@ -157,6 +178,8 @@ function useEditBridge(page, config) {
157
178
  const blocksKey = blocks.map((b) => `${b.id}:${b.type}`).join("|");
158
179
  react.useEffect(() => {
159
180
  setPatches({});
181
+ setPatchesStyle({});
182
+ setPatchesAdvanced({});
160
183
  setSelected(null);
161
184
  setInserted([]);
162
185
  setOrder(null);
@@ -166,7 +189,9 @@ function useEditBridge(page, config) {
166
189
  react.useEffect(() => {
167
190
  if (typeof window === "undefined" || window.parent === window) return;
168
191
  const { editorOrigin } = config;
169
- if (editorOrigin === "*" && typeof console !== "undefined") {
192
+ let postTarget = resolveInitialTarget(editorOrigin);
193
+ const isWildcard = Array.isArray(editorOrigin) ? editorOrigin.includes("*") : editorOrigin === "*";
194
+ if (isWildcard && typeof console !== "undefined") {
170
195
  console.warn(
171
196
  "[cmssy] editorOrigin '*' disables origin checks - dev only, do not use in production"
172
197
  );
@@ -175,7 +200,7 @@ function useEditBridge(page, config) {
175
200
  try {
176
201
  const rects = collectRects();
177
202
  const pageIds = new Set(blocks.map((b) => b.id));
178
- postToEditor(window.parent, editorOrigin, {
203
+ postToEditor(window.parent, postTarget, {
179
204
  type: "cmssy:ready",
180
205
  protocolVersion: PROTOCOL_VERSION,
181
206
  blocks: [
@@ -203,12 +228,28 @@ function useEditBridge(page, config) {
203
228
  editorOrigin
204
229
  );
205
230
  if (!message) return;
231
+ postTarget = event.origin;
206
232
  if (message.type === "cmssy:patch") {
207
233
  if (message.layoutPosition !== void 0) return;
208
234
  setPatches((prev) => ({
209
235
  ...prev,
210
236
  [message.blockId]: { ...prev[message.blockId], ...message.content }
211
237
  }));
238
+ if (message.style) {
239
+ setPatchesStyle((prev) => ({
240
+ ...prev,
241
+ [message.blockId]: { ...prev[message.blockId], ...message.style }
242
+ }));
243
+ }
244
+ if (message.advanced) {
245
+ setPatchesAdvanced((prev) => ({
246
+ ...prev,
247
+ [message.blockId]: {
248
+ ...prev[message.blockId],
249
+ ...message.advanced
250
+ }
251
+ }));
252
+ }
212
253
  } else if (message.type === "cmssy:select") {
213
254
  setSelected(message.blockId);
214
255
  selectedIdRef.current = message.blockId;
@@ -219,6 +260,8 @@ function useEditBridge(page, config) {
219
260
  blockId: message.blockId,
220
261
  blockType: message.blockType,
221
262
  content: message.content,
263
+ style: message.style,
264
+ advanced: message.advanced,
222
265
  index: message.index
223
266
  });
224
267
  return next;
@@ -243,7 +286,7 @@ function useEditBridge(page, config) {
243
286
  const r = el.getBoundingClientRect();
244
287
  const layoutPosition = el.getAttribute("data-layout-position");
245
288
  try {
246
- postToEditor(window.parent, editorOrigin, {
289
+ postToEditor(window.parent, postTarget, {
247
290
  type: "cmssy:click",
248
291
  blockId: id,
249
292
  rect: { x: r.x, y: r.y, width: r.width, height: r.height },
@@ -268,7 +311,7 @@ function useEditBridge(page, config) {
268
311
  if (!el) return;
269
312
  const r = el.getBoundingClientRect();
270
313
  try {
271
- postToEditor(window.parent, editorOrigin, {
314
+ postToEditor(window.parent, postTarget, {
272
315
  type: "cmssy:bounds",
273
316
  blockId: id,
274
317
  rect: { x: r.x, y: r.y, width: r.width, height: r.height }
@@ -295,7 +338,15 @@ function useEditBridge(page, config) {
295
338
  window.removeEventListener("resize", emitSelectedBounds);
296
339
  };
297
340
  }, [config.editorOrigin, pageId, blocksKey]);
298
- return { patches, selected, inserted, order, removed };
341
+ return {
342
+ patches,
343
+ patchesStyle,
344
+ patchesAdvanced,
345
+ selected,
346
+ inserted,
347
+ order,
348
+ removed
349
+ };
299
350
  }
300
351
  var MOVE_MIME = "application/x-cmssy-move";
301
352
  function visible(el) {
@@ -350,7 +401,9 @@ function useDragAgent(config) {
350
401
  react.useEffect(() => {
351
402
  if (typeof window === "undefined" || window.parent === window) return;
352
403
  const { editorOrigin } = config;
353
- if (editorOrigin === "*" && typeof console !== "undefined") {
404
+ let postTarget = resolveInitialTarget(editorOrigin);
405
+ const isWildcard = Array.isArray(editorOrigin) ? editorOrigin.includes("*") : editorOrigin === "*";
406
+ if (isWildcard && typeof console !== "undefined") {
354
407
  console.warn(
355
408
  "[cmssy] editorOrigin '*' disables origin checks - dev only, do not use in production"
356
409
  );
@@ -386,7 +439,7 @@ function useDragAgent(config) {
386
439
  updateDropY(null);
387
440
  resolver.invalidate();
388
441
  try {
389
- postToEditor(window.parent, editorOrigin, {
442
+ postToEditor(window.parent, postTarget, {
390
443
  type: "cmssy:move",
391
444
  protocolVersion: PROTOCOL_VERSION,
392
445
  blockId,
@@ -408,6 +461,7 @@ function useDragAgent(config) {
408
461
  editorOrigin
409
462
  );
410
463
  if (!message) return;
464
+ postTarget = event.origin;
411
465
  if (message.type === "cmssy:drag-over") {
412
466
  const edge = 64;
413
467
  const step = 20;
@@ -419,7 +473,7 @@ function useDragAgent(config) {
419
473
  const { index, y } = resolver.resolve(message.y);
420
474
  updateDropY(y);
421
475
  try {
422
- postToEditor(window.parent, editorOrigin, {
476
+ postToEditor(window.parent, postTarget, {
423
477
  type: "cmssy:drag-index",
424
478
  protocolVersion: PROTOCOL_VERSION,
425
479
  index
@@ -504,6 +558,8 @@ function CmssyBlock({
504
558
  defaultLocale,
505
559
  blockMap,
506
560
  patchedContent,
561
+ patchedStyle,
562
+ patchedAdvanced,
507
563
  editable,
508
564
  layoutPosition,
509
565
  context
@@ -511,6 +567,8 @@ function CmssyBlock({
511
567
  const Component = Object.hasOwn(blockMap, block.type) ? blockMap[block.type] : void 0;
512
568
  const base = getBlockContentForLanguage(block.content, locale, defaultLocale);
513
569
  const content = patchedContent ? { ...base, ...patchedContent } : base;
570
+ const style = patchedStyle ? { ...asBucket(block.style), ...patchedStyle } : asBucket(block.style);
571
+ const advanced = patchedAdvanced ? { ...asBucket(block.advanced), ...patchedAdvanced } : asBucket(block.advanced);
514
572
  return /* @__PURE__ */ jsxRuntime.jsx(
515
573
  "div",
516
574
  {
@@ -521,8 +579,8 @@ function CmssyBlock({
521
579
  style: Component ? void 0 : { display: "none" },
522
580
  children: Component ? react.createElement(Component, {
523
581
  content,
524
- style: asBucket(block.style),
525
- advanced: asBucket(block.advanced),
582
+ style,
583
+ advanced,
526
584
  context
527
585
  }) : /* @__PURE__ */ jsxRuntime.jsx(UnknownBlock, { type: block.type })
528
586
  }
@@ -581,10 +639,7 @@ function EditableBlocks({
581
639
  }),
582
640
  [edit, blocks, category]
583
641
  );
584
- const { patches, inserted, order, removed } = useEditBridge(
585
- page,
586
- bridgeConfig
587
- );
642
+ const { patches, patchesStyle, patchesAdvanced, inserted, order, removed } = useEditBridge(page, bridgeConfig);
588
643
  const { dropY } = useDragAgent(bridgeConfig);
589
644
  const renderBlocks = react.useMemo(() => {
590
645
  const removedSet = new Set(removed);
@@ -595,7 +650,9 @@ function EditableBlocks({
595
650
  merged.splice(at, 0, {
596
651
  id: ins.blockId,
597
652
  type: ins.blockType,
598
- content: ins.content
653
+ content: ins.content,
654
+ style: ins.style,
655
+ advanced: ins.advanced
599
656
  });
600
657
  }
601
658
  if (order) {
@@ -615,6 +672,8 @@ function EditableBlocks({
615
672
  locale,
616
673
  defaultLocale,
617
674
  patchedContent: patches[block.id],
675
+ patchedStyle: patchesStyle[block.id],
676
+ patchedAdvanced: patchesAdvanced[block.id],
618
677
  blockMap,
619
678
  editable: true,
620
679
  context
package/dist/client.d.cts CHANGED
@@ -1,11 +1,11 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { B as BlockSchema, a as BlockMeta, C as CmssyPageData, b as BlockDefinition, c as CmssyFormDefinition, d as CmssyLayoutGroup, e as CmssyLocaleContext, f as CmssyCart, g as CmssyOrder, h as CmssyProduct } from './commerce-queries-D9lXIaCQ.cjs';
3
- export { i as CmssyCartDiscount, j as CmssyCartItem, k as CmssyCartItemSnapshot, l as CmssyOrderItem, m as CmssyProductVariant } from './commerce-queries-D9lXIaCQ.cjs';
2
+ import { B as BlockSchema, a as BlockMeta, C as CmssyPageData, b as BlockDefinition, c as CmssyFormDefinition, d as CmssyLayoutGroup, e as CmssyLocaleContext, f as CmssyCart, g as CmssyOrder, h as CmssyProduct } from './commerce-queries-CxUeiT52.cjs';
3
+ export { i as CmssyCartDiscount, j as CmssyCartItem, k as CmssyCartItemSnapshot, l as CmssyOrderItem, m as CmssyProductVariant } from './commerce-queries-CxUeiT52.cjs';
4
4
  import { ReactNode } from 'react';
5
5
  import '@cmssy/types';
6
6
 
7
7
  interface EditBridgeConfig {
8
- editorOrigin: string;
8
+ editorOrigin: string | string[];
9
9
  schemas?: Record<string, BlockSchema>;
10
10
  blockMeta?: Record<string, BlockMeta>;
11
11
  }
@@ -14,10 +14,14 @@ interface InsertedBlock {
14
14
  blockId: string;
15
15
  blockType: string;
16
16
  content: Record<string, unknown>;
17
+ style?: Record<string, unknown>;
18
+ advanced?: Record<string, unknown>;
17
19
  index: number;
18
20
  }
19
21
  interface EditBridgeState {
20
22
  patches: PatchMap;
23
+ patchesStyle: PatchMap;
24
+ patchesAdvanced: PatchMap;
21
25
  selected: string | null;
22
26
  inserted: InsertedBlock[];
23
27
  order: string[] | null;
package/dist/client.d.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { B as BlockSchema, a as BlockMeta, C as CmssyPageData, b as BlockDefinition, c as CmssyFormDefinition, d as CmssyLayoutGroup, e as CmssyLocaleContext, f as CmssyCart, g as CmssyOrder, h as CmssyProduct } from './commerce-queries-D9lXIaCQ.js';
3
- export { i as CmssyCartDiscount, j as CmssyCartItem, k as CmssyCartItemSnapshot, l as CmssyOrderItem, m as CmssyProductVariant } from './commerce-queries-D9lXIaCQ.js';
2
+ import { B as BlockSchema, a as BlockMeta, C as CmssyPageData, b as BlockDefinition, c as CmssyFormDefinition, d as CmssyLayoutGroup, e as CmssyLocaleContext, f as CmssyCart, g as CmssyOrder, h as CmssyProduct } from './commerce-queries-CxUeiT52.js';
3
+ export { i as CmssyCartDiscount, j as CmssyCartItem, k as CmssyCartItemSnapshot, l as CmssyOrderItem, m as CmssyProductVariant } from './commerce-queries-CxUeiT52.js';
4
4
  import { ReactNode } from 'react';
5
5
  import '@cmssy/types';
6
6
 
7
7
  interface EditBridgeConfig {
8
- editorOrigin: string;
8
+ editorOrigin: string | string[];
9
9
  schemas?: Record<string, BlockSchema>;
10
10
  blockMeta?: Record<string, BlockMeta>;
11
11
  }
@@ -14,10 +14,14 @@ interface InsertedBlock {
14
14
  blockId: string;
15
15
  blockType: string;
16
16
  content: Record<string, unknown>;
17
+ style?: Record<string, unknown>;
18
+ advanced?: Record<string, unknown>;
17
19
  index: number;
18
20
  }
19
21
  interface EditBridgeState {
20
22
  patches: PatchMap;
23
+ patchesStyle: PatchMap;
24
+ patchesAdvanced: PatchMap;
21
25
  selected: string | null;
22
26
  inserted: InsertedBlock[];
23
27
  order: string[] | null;
package/dist/client.js CHANGED
@@ -42,22 +42,37 @@ var PROTOCOL_VERSION = 2;
42
42
 
43
43
  // src/bridge/messages.ts
44
44
  function normalizeOrigin(origin) {
45
- if (origin === "*") return "*";
45
+ const trimmed = origin.trim();
46
+ if (trimmed === "*") return "*";
46
47
  try {
47
- return new URL(origin).origin;
48
+ return new URL(trimmed).origin;
48
49
  } catch {
49
- return origin;
50
+ return trimmed;
50
51
  }
51
52
  }
52
53
  function postToEditor(target, editorOrigin, message) {
53
54
  target.postMessage(message, normalizeOrigin(editorOrigin));
54
55
  }
56
+ function isOriginAllowed(origin, allowed) {
57
+ const list = Array.isArray(allowed) ? allowed : [allowed];
58
+ const actual = normalizeOrigin(origin);
59
+ return list.some((candidate) => {
60
+ const expected = normalizeOrigin(candidate);
61
+ return expected === "*" || expected === actual;
62
+ });
63
+ }
64
+ function resolveInitialTarget(editorOrigin) {
65
+ const list = (Array.isArray(editorOrigin) ? editorOrigin : [editorOrigin]).map((origin) => normalizeOrigin(origin));
66
+ if (list.includes("*")) return "*";
67
+ if (list.length === 1) return list[0];
68
+ const referrerOrigin = typeof document !== "undefined" && document.referrer ? normalizeOrigin(document.referrer) : "";
69
+ return list.find((origin) => origin === referrerOrigin) ?? list[0];
70
+ }
55
71
  function isObject(value) {
56
72
  return typeof value === "object" && value !== null && !Array.isArray(value);
57
73
  }
58
74
  function parseEditorMessage(data, origin, expectedOrigin) {
59
- const expected = normalizeOrigin(expectedOrigin);
60
- if (expected !== "*" && origin !== expected) return null;
75
+ if (!isOriginAllowed(origin, expectedOrigin)) return null;
61
76
  if (!isObject(data)) return null;
62
77
  switch (data.type) {
63
78
  case "cmssy:select":
@@ -72,6 +87,8 @@ function parseEditorMessage(data, origin, expectedOrigin) {
72
87
  blockId: data.blockId,
73
88
  content: data.content,
74
89
  protocolVersion: PROTOCOL_VERSION,
90
+ ...isObject(data.style) ? { style: data.style } : {},
91
+ ...isObject(data.advanced) ? { advanced: data.advanced } : {},
75
92
  ...typeof data.layoutPosition === "string" ? { layoutPosition: data.layoutPosition } : {}
76
93
  } : null;
77
94
  case "cmssy:parent-ready":
@@ -83,6 +100,8 @@ function parseEditorMessage(data, origin, expectedOrigin) {
83
100
  blockId: data.blockId,
84
101
  blockType: data.blockType,
85
102
  content: data.content,
103
+ ...isObject(data.style) ? { style: data.style } : {},
104
+ ...isObject(data.advanced) ? { advanced: data.advanced } : {},
86
105
  index: data.index
87
106
  } : null;
88
107
  case "cmssy:reorder":
@@ -146,6 +165,8 @@ function collectLayoutBlocks(rects, pageIds) {
146
165
  }
147
166
  function useEditBridge(page, config) {
148
167
  const [patches, setPatches] = useState({});
168
+ const [patchesStyle, setPatchesStyle] = useState({});
169
+ const [patchesAdvanced, setPatchesAdvanced] = useState({});
149
170
  const [selected, setSelected] = useState(null);
150
171
  const [inserted, setInserted] = useState([]);
151
172
  const [order, setOrder] = useState(null);
@@ -155,6 +176,8 @@ function useEditBridge(page, config) {
155
176
  const blocksKey = blocks.map((b) => `${b.id}:${b.type}`).join("|");
156
177
  useEffect(() => {
157
178
  setPatches({});
179
+ setPatchesStyle({});
180
+ setPatchesAdvanced({});
158
181
  setSelected(null);
159
182
  setInserted([]);
160
183
  setOrder(null);
@@ -164,7 +187,9 @@ function useEditBridge(page, config) {
164
187
  useEffect(() => {
165
188
  if (typeof window === "undefined" || window.parent === window) return;
166
189
  const { editorOrigin } = config;
167
- if (editorOrigin === "*" && typeof console !== "undefined") {
190
+ let postTarget = resolveInitialTarget(editorOrigin);
191
+ const isWildcard = Array.isArray(editorOrigin) ? editorOrigin.includes("*") : editorOrigin === "*";
192
+ if (isWildcard && typeof console !== "undefined") {
168
193
  console.warn(
169
194
  "[cmssy] editorOrigin '*' disables origin checks - dev only, do not use in production"
170
195
  );
@@ -173,7 +198,7 @@ function useEditBridge(page, config) {
173
198
  try {
174
199
  const rects = collectRects();
175
200
  const pageIds = new Set(blocks.map((b) => b.id));
176
- postToEditor(window.parent, editorOrigin, {
201
+ postToEditor(window.parent, postTarget, {
177
202
  type: "cmssy:ready",
178
203
  protocolVersion: PROTOCOL_VERSION,
179
204
  blocks: [
@@ -201,12 +226,28 @@ function useEditBridge(page, config) {
201
226
  editorOrigin
202
227
  );
203
228
  if (!message) return;
229
+ postTarget = event.origin;
204
230
  if (message.type === "cmssy:patch") {
205
231
  if (message.layoutPosition !== void 0) return;
206
232
  setPatches((prev) => ({
207
233
  ...prev,
208
234
  [message.blockId]: { ...prev[message.blockId], ...message.content }
209
235
  }));
236
+ if (message.style) {
237
+ setPatchesStyle((prev) => ({
238
+ ...prev,
239
+ [message.blockId]: { ...prev[message.blockId], ...message.style }
240
+ }));
241
+ }
242
+ if (message.advanced) {
243
+ setPatchesAdvanced((prev) => ({
244
+ ...prev,
245
+ [message.blockId]: {
246
+ ...prev[message.blockId],
247
+ ...message.advanced
248
+ }
249
+ }));
250
+ }
210
251
  } else if (message.type === "cmssy:select") {
211
252
  setSelected(message.blockId);
212
253
  selectedIdRef.current = message.blockId;
@@ -217,6 +258,8 @@ function useEditBridge(page, config) {
217
258
  blockId: message.blockId,
218
259
  blockType: message.blockType,
219
260
  content: message.content,
261
+ style: message.style,
262
+ advanced: message.advanced,
220
263
  index: message.index
221
264
  });
222
265
  return next;
@@ -241,7 +284,7 @@ function useEditBridge(page, config) {
241
284
  const r = el.getBoundingClientRect();
242
285
  const layoutPosition = el.getAttribute("data-layout-position");
243
286
  try {
244
- postToEditor(window.parent, editorOrigin, {
287
+ postToEditor(window.parent, postTarget, {
245
288
  type: "cmssy:click",
246
289
  blockId: id,
247
290
  rect: { x: r.x, y: r.y, width: r.width, height: r.height },
@@ -266,7 +309,7 @@ function useEditBridge(page, config) {
266
309
  if (!el) return;
267
310
  const r = el.getBoundingClientRect();
268
311
  try {
269
- postToEditor(window.parent, editorOrigin, {
312
+ postToEditor(window.parent, postTarget, {
270
313
  type: "cmssy:bounds",
271
314
  blockId: id,
272
315
  rect: { x: r.x, y: r.y, width: r.width, height: r.height }
@@ -293,7 +336,15 @@ function useEditBridge(page, config) {
293
336
  window.removeEventListener("resize", emitSelectedBounds);
294
337
  };
295
338
  }, [config.editorOrigin, pageId, blocksKey]);
296
- return { patches, selected, inserted, order, removed };
339
+ return {
340
+ patches,
341
+ patchesStyle,
342
+ patchesAdvanced,
343
+ selected,
344
+ inserted,
345
+ order,
346
+ removed
347
+ };
297
348
  }
298
349
  var MOVE_MIME = "application/x-cmssy-move";
299
350
  function visible(el) {
@@ -348,7 +399,9 @@ function useDragAgent(config) {
348
399
  useEffect(() => {
349
400
  if (typeof window === "undefined" || window.parent === window) return;
350
401
  const { editorOrigin } = config;
351
- if (editorOrigin === "*" && typeof console !== "undefined") {
402
+ let postTarget = resolveInitialTarget(editorOrigin);
403
+ const isWildcard = Array.isArray(editorOrigin) ? editorOrigin.includes("*") : editorOrigin === "*";
404
+ if (isWildcard && typeof console !== "undefined") {
352
405
  console.warn(
353
406
  "[cmssy] editorOrigin '*' disables origin checks - dev only, do not use in production"
354
407
  );
@@ -384,7 +437,7 @@ function useDragAgent(config) {
384
437
  updateDropY(null);
385
438
  resolver.invalidate();
386
439
  try {
387
- postToEditor(window.parent, editorOrigin, {
440
+ postToEditor(window.parent, postTarget, {
388
441
  type: "cmssy:move",
389
442
  protocolVersion: PROTOCOL_VERSION,
390
443
  blockId,
@@ -406,6 +459,7 @@ function useDragAgent(config) {
406
459
  editorOrigin
407
460
  );
408
461
  if (!message) return;
462
+ postTarget = event.origin;
409
463
  if (message.type === "cmssy:drag-over") {
410
464
  const edge = 64;
411
465
  const step = 20;
@@ -417,7 +471,7 @@ function useDragAgent(config) {
417
471
  const { index, y } = resolver.resolve(message.y);
418
472
  updateDropY(y);
419
473
  try {
420
- postToEditor(window.parent, editorOrigin, {
474
+ postToEditor(window.parent, postTarget, {
421
475
  type: "cmssy:drag-index",
422
476
  protocolVersion: PROTOCOL_VERSION,
423
477
  index
@@ -502,6 +556,8 @@ function CmssyBlock({
502
556
  defaultLocale,
503
557
  blockMap,
504
558
  patchedContent,
559
+ patchedStyle,
560
+ patchedAdvanced,
505
561
  editable,
506
562
  layoutPosition,
507
563
  context
@@ -509,6 +565,8 @@ function CmssyBlock({
509
565
  const Component = Object.hasOwn(blockMap, block.type) ? blockMap[block.type] : void 0;
510
566
  const base = getBlockContentForLanguage(block.content, locale, defaultLocale);
511
567
  const content = patchedContent ? { ...base, ...patchedContent } : base;
568
+ const style = patchedStyle ? { ...asBucket(block.style), ...patchedStyle } : asBucket(block.style);
569
+ const advanced = patchedAdvanced ? { ...asBucket(block.advanced), ...patchedAdvanced } : asBucket(block.advanced);
512
570
  return /* @__PURE__ */ jsx(
513
571
  "div",
514
572
  {
@@ -519,8 +577,8 @@ function CmssyBlock({
519
577
  style: Component ? void 0 : { display: "none" },
520
578
  children: Component ? createElement(Component, {
521
579
  content,
522
- style: asBucket(block.style),
523
- advanced: asBucket(block.advanced),
580
+ style,
581
+ advanced,
524
582
  context
525
583
  }) : /* @__PURE__ */ jsx(UnknownBlock, { type: block.type })
526
584
  }
@@ -579,10 +637,7 @@ function EditableBlocks({
579
637
  }),
580
638
  [edit, blocks, category]
581
639
  );
582
- const { patches, inserted, order, removed } = useEditBridge(
583
- page,
584
- bridgeConfig
585
- );
640
+ const { patches, patchesStyle, patchesAdvanced, inserted, order, removed } = useEditBridge(page, bridgeConfig);
586
641
  const { dropY } = useDragAgent(bridgeConfig);
587
642
  const renderBlocks = useMemo(() => {
588
643
  const removedSet = new Set(removed);
@@ -593,7 +648,9 @@ function EditableBlocks({
593
648
  merged.splice(at, 0, {
594
649
  id: ins.blockId,
595
650
  type: ins.blockType,
596
- content: ins.content
651
+ content: ins.content,
652
+ style: ins.style,
653
+ advanced: ins.advanced
597
654
  });
598
655
  }
599
656
  if (order) {
@@ -613,6 +670,8 @@ function EditableBlocks({
613
670
  locale,
614
671
  defaultLocale,
615
672
  patchedContent: patches[block.id],
673
+ patchedStyle: patchesStyle[block.id],
674
+ patchedAdvanced: patchesAdvanced[block.id],
616
675
  blockMap,
617
676
  editable: true,
618
677
  context
@@ -288,6 +288,8 @@ interface PatchMessage {
288
288
  protocolVersion: number;
289
289
  blockId: string;
290
290
  content: Record<string, unknown>;
291
+ style?: Record<string, unknown>;
292
+ advanced?: Record<string, unknown>;
291
293
  layoutPosition?: string;
292
294
  }
293
295
  interface ParentReadyMessage {
@@ -300,6 +302,8 @@ interface InsertMessage {
300
302
  blockId: string;
301
303
  blockType: string;
302
304
  content: Record<string, unknown>;
305
+ style?: Record<string, unknown>;
306
+ advanced?: Record<string, unknown>;
303
307
  index: number;
304
308
  }
305
309
  interface ReorderMessage {
@@ -288,6 +288,8 @@ interface PatchMessage {
288
288
  protocolVersion: number;
289
289
  blockId: string;
290
290
  content: Record<string, unknown>;
291
+ style?: Record<string, unknown>;
292
+ advanced?: Record<string, unknown>;
291
293
  layoutPosition?: string;
292
294
  }
293
295
  interface ParentReadyMessage {
@@ -300,6 +302,8 @@ interface InsertMessage {
300
302
  blockId: string;
301
303
  blockType: string;
302
304
  content: Record<string, unknown>;
305
+ style?: Record<string, unknown>;
306
+ advanced?: Record<string, unknown>;
303
307
  index: number;
304
308
  }
305
309
  interface ReorderMessage {
package/dist/index.cjs CHANGED
@@ -239,22 +239,30 @@ function isProtocolCompatible(version) {
239
239
 
240
240
  // src/bridge/messages.ts
241
241
  function normalizeOrigin(origin) {
242
- if (origin === "*") return "*";
242
+ const trimmed = origin.trim();
243
+ if (trimmed === "*") return "*";
243
244
  try {
244
- return new URL(origin).origin;
245
+ return new URL(trimmed).origin;
245
246
  } catch {
246
- return origin;
247
+ return trimmed;
247
248
  }
248
249
  }
249
250
  function postToEditor(target, editorOrigin, message) {
250
251
  target.postMessage(message, normalizeOrigin(editorOrigin));
251
252
  }
253
+ function isOriginAllowed(origin, allowed) {
254
+ const list = Array.isArray(allowed) ? allowed : [allowed];
255
+ const actual = normalizeOrigin(origin);
256
+ return list.some((candidate) => {
257
+ const expected = normalizeOrigin(candidate);
258
+ return expected === "*" || expected === actual;
259
+ });
260
+ }
252
261
  function isObject(value) {
253
262
  return typeof value === "object" && value !== null && !Array.isArray(value);
254
263
  }
255
264
  function parseEditorMessage(data, origin, expectedOrigin) {
256
- const expected = normalizeOrigin(expectedOrigin);
257
- if (expected !== "*" && origin !== expected) return null;
265
+ if (!isOriginAllowed(origin, expectedOrigin)) return null;
258
266
  if (!isObject(data)) return null;
259
267
  switch (data.type) {
260
268
  case "cmssy:select":
@@ -269,6 +277,8 @@ function parseEditorMessage(data, origin, expectedOrigin) {
269
277
  blockId: data.blockId,
270
278
  content: data.content,
271
279
  protocolVersion: PROTOCOL_VERSION,
280
+ ...isObject(data.style) ? { style: data.style } : {},
281
+ ...isObject(data.advanced) ? { advanced: data.advanced } : {},
272
282
  ...typeof data.layoutPosition === "string" ? { layoutPosition: data.layoutPosition } : {}
273
283
  } : null;
274
284
  case "cmssy:parent-ready":
@@ -280,6 +290,8 @@ function parseEditorMessage(data, origin, expectedOrigin) {
280
290
  blockId: data.blockId,
281
291
  blockType: data.blockType,
282
292
  content: data.content,
293
+ ...isObject(data.style) ? { style: data.style } : {},
294
+ ...isObject(data.advanced) ? { advanced: data.advanced } : {},
283
295
  index: data.index
284
296
  } : null;
285
297
  case "cmssy:reorder":
@@ -745,23 +757,23 @@ function createCmssyClient(input) {
745
757
  return {
746
758
  config,
747
759
  resolveWorkspaceId: resolveWorkspaceId2,
748
- query(document, variables = {}, options) {
760
+ query(document2, variables = {}, options) {
749
761
  return graphqlRequest(
750
762
  config,
751
- document,
763
+ document2,
752
764
  variables,
753
765
  options,
754
766
  "graphql operation"
755
767
  );
756
768
  },
757
- async queryScoped(document, variables = {}, options = {}) {
769
+ async queryScoped(document2, variables = {}, options = {}) {
758
770
  const { workspaceId: provided, headers, ...rest } = options;
759
771
  const workspaceId = provided ?? await resolveWorkspaceId2({ ...rest, headers });
760
772
  const hasWorkspaceId = variables.workspaceId !== void 0 && variables.workspaceId !== null;
761
- const scopedVariables = /\$workspaceId\b/.test(document) && !hasWorkspaceId ? { ...variables, workspaceId } : variables;
773
+ const scopedVariables = /\$workspaceId\b/.test(document2) && !hasWorkspaceId ? { ...variables, workspaceId } : variables;
762
774
  return graphqlRequest(
763
775
  config,
764
- document,
776
+ document2,
765
777
  scopedVariables,
766
778
  { ...rest, headers: { ...headers, "x-workspace-id": workspaceId } },
767
779
  "graphql operation"
@@ -899,6 +911,8 @@ function CmssyBlock({
899
911
  defaultLocale,
900
912
  blockMap,
901
913
  patchedContent,
914
+ patchedStyle,
915
+ patchedAdvanced,
902
916
  editable,
903
917
  layoutPosition,
904
918
  context
@@ -906,6 +920,8 @@ function CmssyBlock({
906
920
  const Component = Object.hasOwn(blockMap, block.type) ? blockMap[block.type] : void 0;
907
921
  const base = getBlockContentForLanguage(block.content, locale, defaultLocale);
908
922
  const content = patchedContent ? { ...base, ...patchedContent } : base;
923
+ const style = patchedStyle ? { ...asBucket(block.style), ...patchedStyle } : asBucket(block.style);
924
+ const advanced = patchedAdvanced ? { ...asBucket(block.advanced), ...patchedAdvanced } : asBucket(block.advanced);
909
925
  return /* @__PURE__ */ jsxRuntime.jsx(
910
926
  "div",
911
927
  {
@@ -916,8 +932,8 @@ function CmssyBlock({
916
932
  style: Component ? void 0 : { display: "none" },
917
933
  children: Component ? react.createElement(Component, {
918
934
  content,
919
- style: asBucket(block.style),
920
- advanced: asBucket(block.advanced),
935
+ style,
936
+ advanced,
921
937
  context
922
938
  }) : /* @__PURE__ */ jsxRuntime.jsx(UnknownBlock, { type: block.type })
923
939
  }
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { F as FieldDefinition, C as CmssyPageData, b as BlockDefinition, c as CmssyFormDefinition, n as CmssyBlockAuthContext, o as CmssyBlockWorkspace, d as CmssyLayoutGroup, E as EditorToAppMessage, A as AppToEditorMessage, p as FetchLike, q as CmssyClientConfig, r as CmssySiteConfig, R as RawBlock, e as CmssyLocaleContext, s as BlockMap, t as CmssyBlockContext } from './commerce-queries-D9lXIaCQ.cjs';
2
- export { a as BlockMeta, u as BlockRect, B as BlockSchema, v as BoundsMessage, w as BuildBlockContextExtra, x as ClickMessage, y as CmssyBlockMember, z as CmssyBranding, f as CmssyCart, i as CmssyCartDiscount, j as CmssyCartItem, k as CmssyCartItemSnapshot, D as CmssyFormField, G as CmssyFormSettings, H as CmssyFormSubmitResponse, I as CmssyLocalizedValue, J as CmssyModelDefinition, K as CmssyModelRecord, g as CmssyOrder, L as CmssyPageMeta, M as CmssyPageSummary, h as CmssyProduct, m as CmssyProductVariant, N as CmssyRecordList, O as DEFAULT_CMSSY_API_URL, P as FORM_QUERY, Q as FetchLikeResponse, S as FetchPageOptions, T as MODEL_DEFINITIONS_QUERY, U as MODEL_RECORDS_QUERY, V as PROTOCOL_VERSION, W as ParentReadyMessage, X as PatchMessage, Y as RawLayoutBlock, Z as ReadyMessage, _ as SITE_CONFIG_QUERY, $ as SUBMIT_FORM_MUTATION, a0 as SelectMessage, a1 as SubmitFormInput, a2 as blocksToMeta, a3 as blocksToSchemas, a4 as buildBlockContext, a5 as buildBlockMap, a6 as defineBlock, a7 as fetchLayouts, a8 as fetchPage, a9 as fetchPageById, aa as fetchPageMeta, ab as fetchPages, ac as isProtocolCompatible, ad as normalizeSlug, ae as resolveApiUrl, af as resolvePublicUrl } from './commerce-queries-D9lXIaCQ.cjs';
1
+ import { F as FieldDefinition, C as CmssyPageData, b as BlockDefinition, c as CmssyFormDefinition, n as CmssyBlockAuthContext, o as CmssyBlockWorkspace, d as CmssyLayoutGroup, E as EditorToAppMessage, A as AppToEditorMessage, p as FetchLike, q as CmssyClientConfig, r as CmssySiteConfig, R as RawBlock, e as CmssyLocaleContext, s as BlockMap, t as CmssyBlockContext } from './commerce-queries-CxUeiT52.cjs';
2
+ export { a as BlockMeta, u as BlockRect, B as BlockSchema, v as BoundsMessage, w as BuildBlockContextExtra, x as ClickMessage, y as CmssyBlockMember, z as CmssyBranding, f as CmssyCart, i as CmssyCartDiscount, j as CmssyCartItem, k as CmssyCartItemSnapshot, D as CmssyFormField, G as CmssyFormSettings, H as CmssyFormSubmitResponse, I as CmssyLocalizedValue, J as CmssyModelDefinition, K as CmssyModelRecord, g as CmssyOrder, L as CmssyPageMeta, M as CmssyPageSummary, h as CmssyProduct, m as CmssyProductVariant, N as CmssyRecordList, O as DEFAULT_CMSSY_API_URL, P as FORM_QUERY, Q as FetchLikeResponse, S as FetchPageOptions, T as MODEL_DEFINITIONS_QUERY, U as MODEL_RECORDS_QUERY, V as PROTOCOL_VERSION, W as ParentReadyMessage, X as PatchMessage, Y as RawLayoutBlock, Z as ReadyMessage, _ as SITE_CONFIG_QUERY, $ as SUBMIT_FORM_MUTATION, a0 as SelectMessage, a1 as SubmitFormInput, a2 as blocksToMeta, a3 as blocksToSchemas, a4 as buildBlockContext, a5 as buildBlockMap, a6 as defineBlock, a7 as fetchLayouts, a8 as fetchPage, a9 as fetchPageById, aa as fetchPageMeta, ab as fetchPages, ac as isProtocolCompatible, ad as normalizeSlug, ae as resolveApiUrl, af as resolvePublicUrl } from './commerce-queries-CxUeiT52.cjs';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
  export { FieldCondition, FieldConditionGroup, FieldConditionLogic, FieldType, evaluateFieldConditionGroup } from '@cmssy/types';
5
5
  import 'react';
@@ -68,7 +68,7 @@ interface PostTarget {
68
68
  }
69
69
  declare function normalizeOrigin(origin: string): string;
70
70
  declare function postToEditor(target: PostTarget, editorOrigin: string, message: AppToEditorMessage): void;
71
- declare function parseEditorMessage(data: unknown, origin: string, expectedOrigin: string): EditorToAppMessage | null;
71
+ declare function parseEditorMessage(data: unknown, origin: string, expectedOrigin: string | string[]): EditorToAppMessage | null;
72
72
 
73
73
  declare function getBlockContentForLanguage(content: unknown, locale: string, defaultLocale?: string, availableLocales?: string[]): Record<string, unknown>;
74
74
 
@@ -135,11 +135,13 @@ interface CmssyBlockProps {
135
135
  defaultLocale: string;
136
136
  blockMap: BlockMap;
137
137
  patchedContent?: Record<string, unknown>;
138
+ patchedStyle?: Record<string, unknown>;
139
+ patchedAdvanced?: Record<string, unknown>;
138
140
  editable?: boolean;
139
141
  layoutPosition?: string;
140
142
  context?: CmssyBlockContext;
141
143
  }
142
- declare function CmssyBlock({ block, locale, defaultLocale, blockMap, patchedContent, editable, layoutPosition, context, }: CmssyBlockProps): react_jsx_runtime.JSX.Element;
144
+ declare function CmssyBlock({ block, locale, defaultLocale, blockMap, patchedContent, patchedStyle, patchedAdvanced, editable, layoutPosition, context, }: CmssyBlockProps): react_jsx_runtime.JSX.Element;
143
145
 
144
146
  interface UnknownBlockProps {
145
147
  type: string;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { F as FieldDefinition, C as CmssyPageData, b as BlockDefinition, c as CmssyFormDefinition, n as CmssyBlockAuthContext, o as CmssyBlockWorkspace, d as CmssyLayoutGroup, E as EditorToAppMessage, A as AppToEditorMessage, p as FetchLike, q as CmssyClientConfig, r as CmssySiteConfig, R as RawBlock, e as CmssyLocaleContext, s as BlockMap, t as CmssyBlockContext } from './commerce-queries-D9lXIaCQ.js';
2
- export { a as BlockMeta, u as BlockRect, B as BlockSchema, v as BoundsMessage, w as BuildBlockContextExtra, x as ClickMessage, y as CmssyBlockMember, z as CmssyBranding, f as CmssyCart, i as CmssyCartDiscount, j as CmssyCartItem, k as CmssyCartItemSnapshot, D as CmssyFormField, G as CmssyFormSettings, H as CmssyFormSubmitResponse, I as CmssyLocalizedValue, J as CmssyModelDefinition, K as CmssyModelRecord, g as CmssyOrder, L as CmssyPageMeta, M as CmssyPageSummary, h as CmssyProduct, m as CmssyProductVariant, N as CmssyRecordList, O as DEFAULT_CMSSY_API_URL, P as FORM_QUERY, Q as FetchLikeResponse, S as FetchPageOptions, T as MODEL_DEFINITIONS_QUERY, U as MODEL_RECORDS_QUERY, V as PROTOCOL_VERSION, W as ParentReadyMessage, X as PatchMessage, Y as RawLayoutBlock, Z as ReadyMessage, _ as SITE_CONFIG_QUERY, $ as SUBMIT_FORM_MUTATION, a0 as SelectMessage, a1 as SubmitFormInput, a2 as blocksToMeta, a3 as blocksToSchemas, a4 as buildBlockContext, a5 as buildBlockMap, a6 as defineBlock, a7 as fetchLayouts, a8 as fetchPage, a9 as fetchPageById, aa as fetchPageMeta, ab as fetchPages, ac as isProtocolCompatible, ad as normalizeSlug, ae as resolveApiUrl, af as resolvePublicUrl } from './commerce-queries-D9lXIaCQ.js';
1
+ import { F as FieldDefinition, C as CmssyPageData, b as BlockDefinition, c as CmssyFormDefinition, n as CmssyBlockAuthContext, o as CmssyBlockWorkspace, d as CmssyLayoutGroup, E as EditorToAppMessage, A as AppToEditorMessage, p as FetchLike, q as CmssyClientConfig, r as CmssySiteConfig, R as RawBlock, e as CmssyLocaleContext, s as BlockMap, t as CmssyBlockContext } from './commerce-queries-CxUeiT52.js';
2
+ export { a as BlockMeta, u as BlockRect, B as BlockSchema, v as BoundsMessage, w as BuildBlockContextExtra, x as ClickMessage, y as CmssyBlockMember, z as CmssyBranding, f as CmssyCart, i as CmssyCartDiscount, j as CmssyCartItem, k as CmssyCartItemSnapshot, D as CmssyFormField, G as CmssyFormSettings, H as CmssyFormSubmitResponse, I as CmssyLocalizedValue, J as CmssyModelDefinition, K as CmssyModelRecord, g as CmssyOrder, L as CmssyPageMeta, M as CmssyPageSummary, h as CmssyProduct, m as CmssyProductVariant, N as CmssyRecordList, O as DEFAULT_CMSSY_API_URL, P as FORM_QUERY, Q as FetchLikeResponse, S as FetchPageOptions, T as MODEL_DEFINITIONS_QUERY, U as MODEL_RECORDS_QUERY, V as PROTOCOL_VERSION, W as ParentReadyMessage, X as PatchMessage, Y as RawLayoutBlock, Z as ReadyMessage, _ as SITE_CONFIG_QUERY, $ as SUBMIT_FORM_MUTATION, a0 as SelectMessage, a1 as SubmitFormInput, a2 as blocksToMeta, a3 as blocksToSchemas, a4 as buildBlockContext, a5 as buildBlockMap, a6 as defineBlock, a7 as fetchLayouts, a8 as fetchPage, a9 as fetchPageById, aa as fetchPageMeta, ab as fetchPages, ac as isProtocolCompatible, ad as normalizeSlug, ae as resolveApiUrl, af as resolvePublicUrl } from './commerce-queries-CxUeiT52.js';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
  export { FieldCondition, FieldConditionGroup, FieldConditionLogic, FieldType, evaluateFieldConditionGroup } from '@cmssy/types';
5
5
  import 'react';
@@ -68,7 +68,7 @@ interface PostTarget {
68
68
  }
69
69
  declare function normalizeOrigin(origin: string): string;
70
70
  declare function postToEditor(target: PostTarget, editorOrigin: string, message: AppToEditorMessage): void;
71
- declare function parseEditorMessage(data: unknown, origin: string, expectedOrigin: string): EditorToAppMessage | null;
71
+ declare function parseEditorMessage(data: unknown, origin: string, expectedOrigin: string | string[]): EditorToAppMessage | null;
72
72
 
73
73
  declare function getBlockContentForLanguage(content: unknown, locale: string, defaultLocale?: string, availableLocales?: string[]): Record<string, unknown>;
74
74
 
@@ -135,11 +135,13 @@ interface CmssyBlockProps {
135
135
  defaultLocale: string;
136
136
  blockMap: BlockMap;
137
137
  patchedContent?: Record<string, unknown>;
138
+ patchedStyle?: Record<string, unknown>;
139
+ patchedAdvanced?: Record<string, unknown>;
138
140
  editable?: boolean;
139
141
  layoutPosition?: string;
140
142
  context?: CmssyBlockContext;
141
143
  }
142
- declare function CmssyBlock({ block, locale, defaultLocale, blockMap, patchedContent, editable, layoutPosition, context, }: CmssyBlockProps): react_jsx_runtime.JSX.Element;
144
+ declare function CmssyBlock({ block, locale, defaultLocale, blockMap, patchedContent, patchedStyle, patchedAdvanced, editable, layoutPosition, context, }: CmssyBlockProps): react_jsx_runtime.JSX.Element;
143
145
 
144
146
  interface UnknownBlockProps {
145
147
  type: string;
package/dist/index.js CHANGED
@@ -237,22 +237,30 @@ function isProtocolCompatible(version) {
237
237
 
238
238
  // src/bridge/messages.ts
239
239
  function normalizeOrigin(origin) {
240
- if (origin === "*") return "*";
240
+ const trimmed = origin.trim();
241
+ if (trimmed === "*") return "*";
241
242
  try {
242
- return new URL(origin).origin;
243
+ return new URL(trimmed).origin;
243
244
  } catch {
244
- return origin;
245
+ return trimmed;
245
246
  }
246
247
  }
247
248
  function postToEditor(target, editorOrigin, message) {
248
249
  target.postMessage(message, normalizeOrigin(editorOrigin));
249
250
  }
251
+ function isOriginAllowed(origin, allowed) {
252
+ const list = Array.isArray(allowed) ? allowed : [allowed];
253
+ const actual = normalizeOrigin(origin);
254
+ return list.some((candidate) => {
255
+ const expected = normalizeOrigin(candidate);
256
+ return expected === "*" || expected === actual;
257
+ });
258
+ }
250
259
  function isObject(value) {
251
260
  return typeof value === "object" && value !== null && !Array.isArray(value);
252
261
  }
253
262
  function parseEditorMessage(data, origin, expectedOrigin) {
254
- const expected = normalizeOrigin(expectedOrigin);
255
- if (expected !== "*" && origin !== expected) return null;
263
+ if (!isOriginAllowed(origin, expectedOrigin)) return null;
256
264
  if (!isObject(data)) return null;
257
265
  switch (data.type) {
258
266
  case "cmssy:select":
@@ -267,6 +275,8 @@ function parseEditorMessage(data, origin, expectedOrigin) {
267
275
  blockId: data.blockId,
268
276
  content: data.content,
269
277
  protocolVersion: PROTOCOL_VERSION,
278
+ ...isObject(data.style) ? { style: data.style } : {},
279
+ ...isObject(data.advanced) ? { advanced: data.advanced } : {},
270
280
  ...typeof data.layoutPosition === "string" ? { layoutPosition: data.layoutPosition } : {}
271
281
  } : null;
272
282
  case "cmssy:parent-ready":
@@ -278,6 +288,8 @@ function parseEditorMessage(data, origin, expectedOrigin) {
278
288
  blockId: data.blockId,
279
289
  blockType: data.blockType,
280
290
  content: data.content,
291
+ ...isObject(data.style) ? { style: data.style } : {},
292
+ ...isObject(data.advanced) ? { advanced: data.advanced } : {},
281
293
  index: data.index
282
294
  } : null;
283
295
  case "cmssy:reorder":
@@ -743,23 +755,23 @@ function createCmssyClient(input) {
743
755
  return {
744
756
  config,
745
757
  resolveWorkspaceId: resolveWorkspaceId2,
746
- query(document, variables = {}, options) {
758
+ query(document2, variables = {}, options) {
747
759
  return graphqlRequest(
748
760
  config,
749
- document,
761
+ document2,
750
762
  variables,
751
763
  options,
752
764
  "graphql operation"
753
765
  );
754
766
  },
755
- async queryScoped(document, variables = {}, options = {}) {
767
+ async queryScoped(document2, variables = {}, options = {}) {
756
768
  const { workspaceId: provided, headers, ...rest } = options;
757
769
  const workspaceId = provided ?? await resolveWorkspaceId2({ ...rest, headers });
758
770
  const hasWorkspaceId = variables.workspaceId !== void 0 && variables.workspaceId !== null;
759
- const scopedVariables = /\$workspaceId\b/.test(document) && !hasWorkspaceId ? { ...variables, workspaceId } : variables;
771
+ const scopedVariables = /\$workspaceId\b/.test(document2) && !hasWorkspaceId ? { ...variables, workspaceId } : variables;
760
772
  return graphqlRequest(
761
773
  config,
762
- document,
774
+ document2,
763
775
  scopedVariables,
764
776
  { ...rest, headers: { ...headers, "x-workspace-id": workspaceId } },
765
777
  "graphql operation"
@@ -897,6 +909,8 @@ function CmssyBlock({
897
909
  defaultLocale,
898
910
  blockMap,
899
911
  patchedContent,
912
+ patchedStyle,
913
+ patchedAdvanced,
900
914
  editable,
901
915
  layoutPosition,
902
916
  context
@@ -904,6 +918,8 @@ function CmssyBlock({
904
918
  const Component = Object.hasOwn(blockMap, block.type) ? blockMap[block.type] : void 0;
905
919
  const base = getBlockContentForLanguage(block.content, locale, defaultLocale);
906
920
  const content = patchedContent ? { ...base, ...patchedContent } : base;
921
+ const style = patchedStyle ? { ...asBucket(block.style), ...patchedStyle } : asBucket(block.style);
922
+ const advanced = patchedAdvanced ? { ...asBucket(block.advanced), ...patchedAdvanced } : asBucket(block.advanced);
907
923
  return /* @__PURE__ */ jsx(
908
924
  "div",
909
925
  {
@@ -914,8 +930,8 @@ function CmssyBlock({
914
930
  style: Component ? void 0 : { display: "none" },
915
931
  children: Component ? createElement(Component, {
916
932
  content,
917
- style: asBucket(block.style),
918
- advanced: asBucket(block.advanced),
933
+ style,
934
+ advanced,
919
935
  context
920
936
  }) : /* @__PURE__ */ jsx(UnknownBlock, { type: block.type })
921
937
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cmssy/react",
3
- "version": "0.16.0",
3
+ "version": "0.17.1",
4
4
  "description": "React blocks, renderers, data client and editor bridge for cmssy headless sites",
5
5
  "keywords": [
6
6
  "cmssy",