@dotcms/uve 26.9.3-1 → 26.9.3-1-next.2649

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dotcms/uve",
3
- "version": "26.09.03-01",
3
+ "version": "26.9.3-1-next.2649",
4
4
  "description": "Official JavaScript library for interacting with Universal Visual Editor (UVE)",
5
5
  "repository": {
6
6
  "type": "git",
package/public.cjs.js CHANGED
@@ -46,6 +46,24 @@ function getDotCMSPageBounds(containers) {
46
46
  };
47
47
  });
48
48
  }
49
+ /**
50
+ * Whether the current user may edit the contentlet described by `dataset`.
51
+ *
52
+ * Reads `data-dot-can-edit`, which the Velocity container renderer stamps on
53
+ * every contentlet in EDIT mode from a WRITE-level permission check against the
54
+ * contentlet instance.
55
+ *
56
+ * **Fails open** — only the literal `"false"` denies. Headless and SDK-rendered
57
+ * pages build their own wrappers and never emit the attribute, so treating a
58
+ * missing value as denied would disable every edit affordance on all of them.
59
+ *
60
+ * Shared by the hover/click payload and the bounds payload so both carry the
61
+ * same answer; the bounds payload re-anchors the current selection on every
62
+ * layout change, and omitting the permission there silently reopens the gates.
63
+ */
64
+ function readCanEditFromDataset(dataset) {
65
+ return dataset?.['dotCanEdit'] !== 'false';
66
+ }
49
67
  /**
50
68
  * Calculates the bounding information for each contentlet inside a container.
51
69
  *
@@ -75,7 +93,8 @@ function getDotCMSContentletsBound(containerRect, contentlets) {
75
93
  identifier: contentlet.dataset?.['dotIdentifier'],
76
94
  title: contentlet.dataset?.['dotTitle'],
77
95
  inode: contentlet.dataset?.['dotInode'],
78
- contentType: contentlet.dataset?.['dotType']
96
+ contentType: contentlet.dataset?.['dotType'],
97
+ canEdit: readCanEditFromDataset(contentlet.dataset)
79
98
  }
80
99
  })
81
100
  };
@@ -252,6 +271,11 @@ function getDotContentletAttributes(contentlet, container) {
252
271
  'data-dot-type': contentlet?.contentType,
253
272
  'data-dot-container': container,
254
273
  'data-dot-on-number-of-pages': contentlet?.['onNumberOfPages'] || '1',
274
+ // Mirrors `data-dot-can-edit` from the Velocity renderer so the editor
275
+ // reads one attribute on both surfaces. Fails open: an older dotCMS
276
+ // release does not return `canEdit`, and the editor must behave as it
277
+ // does today rather than lock the user out.
278
+ 'data-dot-can-edit': String(contentlet?.canEdit !== false),
255
279
  ...(contentlet?.dotStyleProperties && {
256
280
  'data-dot-style-properties': JSON.stringify(contentlet.dotStyleProperties)
257
281
  })
@@ -393,6 +417,13 @@ function getDotContainerAttributes({
393
417
  * normalized contentlet object. Mirrors the shape consumed by the editor's
394
418
  * SET_BOUNDS and CONTENTLET_CLICKED events. Optionally parses the
395
419
  * `dotStyleProperties` JSON when present.
420
+ *
421
+ * `canEdit` reflects `data-dot-can-edit`, which the Velocity container renderer
422
+ * stamps on every contentlet in EDIT mode from a WRITE-level permission check
423
+ * against the contentlet instance. It **fails open**: only the literal `"false"`
424
+ * denies. Headless and SDK-rendered pages build their own wrappers and never
425
+ * emit the attribute, so treating a missing value as denied would disable every
426
+ * edit affordance on all of them.
396
427
  */
397
428
  function readContentletDataset(element) {
398
429
  const dataset = element.dataset ?? {};
@@ -404,6 +435,7 @@ function readContentletDataset(element) {
404
435
  baseType: dataset['dotBasetype'],
405
436
  widgetTitle: dataset['dotWidgetTitle'],
406
437
  onNumberOfPages: dataset['dotOnNumberOfPages'],
438
+ canEdit: readCanEditFromDataset(dataset),
407
439
  ...(dataset['dotStyleProperties'] && {
408
440
  dotStyleProperties: JSON.parse(dataset['dotStyleProperties'])
409
441
  })
package/public.esm.js CHANGED
@@ -44,6 +44,24 @@ function getDotCMSPageBounds(containers) {
44
44
  };
45
45
  });
46
46
  }
47
+ /**
48
+ * Whether the current user may edit the contentlet described by `dataset`.
49
+ *
50
+ * Reads `data-dot-can-edit`, which the Velocity container renderer stamps on
51
+ * every contentlet in EDIT mode from a WRITE-level permission check against the
52
+ * contentlet instance.
53
+ *
54
+ * **Fails open** — only the literal `"false"` denies. Headless and SDK-rendered
55
+ * pages build their own wrappers and never emit the attribute, so treating a
56
+ * missing value as denied would disable every edit affordance on all of them.
57
+ *
58
+ * Shared by the hover/click payload and the bounds payload so both carry the
59
+ * same answer; the bounds payload re-anchors the current selection on every
60
+ * layout change, and omitting the permission there silently reopens the gates.
61
+ */
62
+ function readCanEditFromDataset(dataset) {
63
+ return dataset?.['dotCanEdit'] !== 'false';
64
+ }
47
65
  /**
48
66
  * Calculates the bounding information for each contentlet inside a container.
49
67
  *
@@ -73,7 +91,8 @@ function getDotCMSContentletsBound(containerRect, contentlets) {
73
91
  identifier: contentlet.dataset?.['dotIdentifier'],
74
92
  title: contentlet.dataset?.['dotTitle'],
75
93
  inode: contentlet.dataset?.['dotInode'],
76
- contentType: contentlet.dataset?.['dotType']
94
+ contentType: contentlet.dataset?.['dotType'],
95
+ canEdit: readCanEditFromDataset(contentlet.dataset)
77
96
  }
78
97
  })
79
98
  };
@@ -250,6 +269,11 @@ function getDotContentletAttributes(contentlet, container) {
250
269
  'data-dot-type': contentlet?.contentType,
251
270
  'data-dot-container': container,
252
271
  'data-dot-on-number-of-pages': contentlet?.['onNumberOfPages'] || '1',
272
+ // Mirrors `data-dot-can-edit` from the Velocity renderer so the editor
273
+ // reads one attribute on both surfaces. Fails open: an older dotCMS
274
+ // release does not return `canEdit`, and the editor must behave as it
275
+ // does today rather than lock the user out.
276
+ 'data-dot-can-edit': String(contentlet?.canEdit !== false),
253
277
  ...(contentlet?.dotStyleProperties && {
254
278
  'data-dot-style-properties': JSON.stringify(contentlet.dotStyleProperties)
255
279
  })
@@ -391,6 +415,13 @@ function getDotContainerAttributes({
391
415
  * normalized contentlet object. Mirrors the shape consumed by the editor's
392
416
  * SET_BOUNDS and CONTENTLET_CLICKED events. Optionally parses the
393
417
  * `dotStyleProperties` JSON when present.
418
+ *
419
+ * `canEdit` reflects `data-dot-can-edit`, which the Velocity container renderer
420
+ * stamps on every contentlet in EDIT mode from a WRITE-level permission check
421
+ * against the contentlet instance. It **fails open**: only the literal `"false"`
422
+ * denies. Headless and SDK-rendered pages build their own wrappers and never
423
+ * emit the attribute, so treating a missing value as denied would disable every
424
+ * edit affordance on all of them.
394
425
  */
395
426
  function readContentletDataset(element) {
396
427
  const dataset = element.dataset ?? {};
@@ -402,6 +433,7 @@ function readContentletDataset(element) {
402
433
  baseType: dataset['dotBasetype'],
403
434
  widgetTitle: dataset['dotWidgetTitle'],
404
435
  onNumberOfPages: dataset['dotOnNumberOfPages'],
436
+ canEdit: readCanEditFromDataset(dataset),
405
437
  ...(dataset['dotStyleProperties'] && {
406
438
  dotStyleProperties: JSON.parse(dataset['dotStyleProperties'])
407
439
  })
@@ -230,6 +230,13 @@ export declare function getDotContainerAttributes({ uuid, identifier, acceptType
230
230
  * normalized contentlet object. Mirrors the shape consumed by the editor's
231
231
  * SET_BOUNDS and CONTENTLET_CLICKED events. Optionally parses the
232
232
  * `dotStyleProperties` JSON when present.
233
+ *
234
+ * `canEdit` reflects `data-dot-can-edit`, which the Velocity container renderer
235
+ * stamps on every contentlet in EDIT mode from a WRITE-level permission check
236
+ * against the contentlet instance. It **fails open**: only the literal `"false"`
237
+ * denies. Headless and SDK-rendered pages build their own wrappers and never
238
+ * emit the attribute, so treating a missing value as denied would disable every
239
+ * edit affordance on all of them.
233
240
  */
234
241
  export declare function readContentletDataset(element: HTMLElement): {
235
242
  dotStyleProperties?: any;
@@ -240,6 +247,7 @@ export declare function readContentletDataset(element: HTMLElement): {
240
247
  baseType: string | undefined;
241
248
  widgetTitle: string | undefined;
242
249
  onNumberOfPages: string | undefined;
250
+ canEdit: boolean;
243
251
  };
244
252
  /**
245
253
  * Returns Zone.js's *unpatched* native `addEventListener` / `removeEventListener`