@dotcms/uve 1.6.0-next.27 → 1.6.0-next.36

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.
@@ -81,3 +81,26 @@ export declare const CUSTOM_NO_COMPONENT = "CustomNoComponent";
81
81
  * @internal
82
82
  */
83
83
  export declare const DOT_SECTION_ID_PREFIX = "dot-section-";
84
+ /**
85
+ * Window flag set by `@dotcms/analytics` when content analytics is initialized
86
+ * and active on the page.
87
+ *
88
+ * @important This value is intentionally duplicated from `@dotcms/analytics`
89
+ * (`ANALYTICS_WINDOWS_ACTIVE_KEY` in dot-analytics.constants.ts). The SDKs read
90
+ * it in live mode to decide whether to keep the minimal contentlet attributes
91
+ * Analytics depends on. Both constants MUST stay in sync.
92
+ *
93
+ * @internal
94
+ */
95
+ export declare const ANALYTICS_ACTIVE_WINDOW_KEY = "__dotAnalyticsActive__";
96
+ /**
97
+ * Event dispatched by `@dotcms/analytics` once analytics is ready. The SDKs
98
+ * listen for it so live-mode contentlets can re-render with the attributes
99
+ * Analytics needs, regardless of initialization order.
100
+ *
101
+ * @important Kept in sync with the `dotcms:analytics:ready` event dispatched by
102
+ * `@dotcms/analytics` (initializeContentAnalytics).
103
+ *
104
+ * @internal
105
+ */
106
+ export declare const ANALYTICS_READY_EVENT = "dotcms:analytics:ready";
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Sentinel values for the placeholder contentlet used when the UVE represents
3
+ * an empty container (e.g. hover / selection without a real contentlet).
4
+ *
5
+ * @internal
6
+ */
7
+ export declare const TEMP_EMPTY_CONTENTLET: "TEMP_EMPTY_CONTENTLET";
8
+ /**
9
+ * Placeholder `contentType` for {@link TEMP_EMPTY_CONTENTLET}.
10
+ *
11
+ * @internal
12
+ */
13
+ export declare const TEMP_EMPTY_CONTENTLET_TYPE: "TEMP_EMPTY_CONTENTLET_TYPE";
@@ -26,15 +26,22 @@ export declare function onPageReload(callback: UVEEventHandler): {
26
26
  event: UVEEventType;
27
27
  };
28
28
  /**
29
- * Subscribes to request bounds events in the UVE editor
29
+ * The single bounds-sync channel. Observes the iframe document and
30
+ * every `[data-dot-object="container"]` with a single ResizeObserver,
31
+ * debounces the trailing edge by {@link AUTO_BOUNDS_DEBOUNCE_MS}ms, and
32
+ * emits the full `getDotCMSPageBounds(...)` payload whenever the layout
33
+ * settles. Also listens on `scroll` (since scrolling moves contentlets
34
+ * without changing layout) and on `UVE_FLUSH_BOUNDS` (the editor's
35
+ * "give me bounds NOW, skip the debounce" message used during drag).
36
+ *
37
+ * Re-runs `querySelectorAll` and the observer wiring whenever a
38
+ * MutationObserver detects child changes that touch container nodes,
39
+ * so containers that mount/unmount after page-load are picked up
40
+ * automatically.
30
41
  *
31
- * @param {UVEEventHandler} callback - Function to be called when bounds are requested
32
- * @returns {Object} Object containing unsubscribe function and event type
33
- * @returns {Function} .unsubscribe - Function to remove the event listener
34
- * @returns {UVEEventType} .event - The event type being subscribed to
35
42
  * @internal
36
43
  */
37
- export declare function onRequestBounds(callback: UVEEventHandler): {
44
+ export declare function onAutoBounds(callback: UVEEventHandler): {
38
45
  unsubscribe: () => void;
39
46
  event: UVEEventType;
40
47
  };
@@ -66,9 +73,15 @@ export declare function onScrollToSection(callback: UVEEventHandler): {
66
73
  event: UVEEventType;
67
74
  };
68
75
  /**
69
- * Subscribes to contentlet hover events in the UVE editor
76
+ * Subscribes to contentlet hover events in the UVE editor.
70
77
  *
71
- * @param {UVEEventHandler} callback - Function to be called when a contentlet is hovered
78
+ * The callback is invoked with a payload while the pointer is over a
79
+ * DotCMS element, and once with `null` when the pointer leaves the last
80
+ * reported element (transitions onto dead space). The editor uses the
81
+ * `null` signal to clear the hover overlay so it doesn't linger over
82
+ * areas that no longer have a contentlet under the pointer.
83
+ *
84
+ * @param {UVEEventHandler} callback - Function to be called when hover state changes
72
85
  * @returns {Object} Object containing unsubscribe function and event type
73
86
  * @returns {Function} .unsubscribe - Function to remove the event listener
74
87
  * @returns {UVEEventType} .event - The event type being subscribed to
@@ -78,3 +91,18 @@ export declare function onContentletHovered(callback: UVEEventHandler): {
78
91
  unsubscribe: () => void;
79
92
  event: UVEEventType;
80
93
  };
94
+ /**
95
+ * Subscribes to contentlet click events in the UVE editor.
96
+ *
97
+ * The editor's hover overlay is `pointer-events: none` so wheel events pass
98
+ * through to the iframe. We detect the user's selection click here instead and
99
+ * post it back to the editor.
100
+ *
101
+ * @param {UVEEventHandler} callback - Function to be called when a contentlet is clicked
102
+ * @returns {Object} Object containing unsubscribe function and event type
103
+ * @internal
104
+ */
105
+ export declare function onContentletClicked(callback: UVEEventHandler): {
106
+ unsubscribe: () => void;
107
+ event: UVEEventType;
108
+ };
@@ -1,2 +1,3 @@
1
1
  export * from './constants';
2
+ export * from './contentlet-sentinel.constants';
2
3
  export * from './tinymce.config';
package/src/internal.d.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  export * from './internal/index';
2
2
  export * from './lib/core/core.utils';
3
- export * from './lib/dom/document-height-observer';
4
3
  export * from './lib/dom/dom.utils';
5
4
  export * from './lib/editor/internal';
6
5
  export { defineStyleEditorSchema, normalizeForm, registerStyleEditorSchemas } from './lib/style-editor/internal';
@@ -1,5 +1,5 @@
1
1
  import { DotCMSBasicContentlet, DotCMSColumnContainer, DotCMSPageAsset, DotPageAssetLayoutColumn, EditableContainerData } from '@dotcms/types';
2
- import { DotCMSContainerBound, DotCMSContentletBound, DotContainerAttributes, DotContentletAttributes } from '@dotcms/types/internal';
2
+ import { DotAnalyticsContentletAttributes, DotCMSContainerBound, DotCMSContentletBound, DotContainerAttributes, DotContentletAttributes } from '@dotcms/types/internal';
3
3
  /**
4
4
  * Calculates the bounding information for each page element within the given containers.
5
5
  *
@@ -152,6 +152,28 @@ export declare const getColumnPositionClasses: (column: DotPageAssetLayoutColumn
152
152
  * @returns {DotContentletAttributes} The dotCMS data attributes
153
153
  */
154
154
  export declare function getDotContentletAttributes(contentlet: DotCMSBasicContentlet, container: string): DotContentletAttributes;
155
+ /**
156
+ *
157
+ * Returns the minimal set of contentlet data attributes required by DotCMS
158
+ * Analytics (impression & click tracking) to identify a contentlet.
159
+ *
160
+ * Used in live mode where the full editor metadata is stripped but Analytics
161
+ * still needs to resolve the contentlet behind an impression/click.
162
+ *
163
+ * @param {DotCMSBasicContentlet} contentlet - The contentlet to get the attributes for
164
+ * @returns {DotAnalyticsContentletAttributes} The Analytics-required data attributes
165
+ */
166
+ export declare function getAnalyticsContentletAttributes(contentlet: DotCMSBasicContentlet): DotAnalyticsContentletAttributes;
167
+ /**
168
+ *
169
+ * Checks whether DotCMS Analytics is initialized and active on the page.
170
+ *
171
+ * The SDKs use this in live mode to decide whether to keep the minimal
172
+ * contentlet attributes Analytics depends on.
173
+ *
174
+ * @returns {boolean} `true` when analytics is active, otherwise `false`
175
+ */
176
+ export declare function isDotAnalyticsActive(): boolean;
155
177
  /**
156
178
  *
157
179
  *
@@ -203,3 +225,40 @@ export declare const getContentletsInContainer: (dotCMSPageAsset: DotCMSPageAsse
203
225
  * // Returns: { 'data-dot-object': 'container', 'data-dot-identifier': 'cont1', ... }
204
226
  */
205
227
  export declare function getDotContainerAttributes({ uuid, identifier, acceptTypes, maxContentlets }: EditableContainerData): DotContainerAttributes;
228
+ /**
229
+ * Read a contentlet's dataset attributes off a DOM element and return a
230
+ * normalized contentlet object. Mirrors the shape consumed by the editor's
231
+ * SET_BOUNDS and CONTENTLET_CLICKED events. Optionally parses the
232
+ * `dotStyleProperties` JSON when present.
233
+ */
234
+ export declare function readContentletDataset(element: HTMLElement): {
235
+ dotStyleProperties?: any;
236
+ identifier: string | undefined;
237
+ title: string | undefined;
238
+ inode: string | undefined;
239
+ contentType: string | undefined;
240
+ baseType: string | undefined;
241
+ widgetTitle: string | undefined;
242
+ onNumberOfPages: string | undefined;
243
+ };
244
+ /**
245
+ * Returns Zone.js's *unpatched* native `addEventListener` / `removeEventListener`
246
+ * bound to `target`, falling back to the standard methods when Zone.js is absent.
247
+ *
248
+ * UVE reuses a single iframe and rewrites it with `document.open()/write()/close()`
249
+ * on every in-editor navigation. When Zone.js is loaded inside that iframe it runs
250
+ * in global-events mode: one native "gateway" listener per (target, eventType)
251
+ * plus a JS-level task list stored on the target node. `document.open()` tears down
252
+ * the native gateway on the persistent `window`/`document` nodes, but the task list
253
+ * survives on them, so Zone sees "already registered" on re-init and skips
254
+ * re-installing the native gateway — the listener silently goes dead after the
255
+ * first navigation.
256
+ *
257
+ * Hover/click dodge this by binding to `document.documentElement`, a node that
258
+ * `write()` recreates fresh. `scroll`/`message` (on `window`) and
259
+ * `DOMContentLoaded` (on `document`) can't: none of them fire on `<html>`, so
260
+ * there is no fresh node to rebind to. Going through Zone's native (untracked)
261
+ * methods sidesteps the dedup entirely, so the listener rebinds cleanly after
262
+ * every rewrite.
263
+ */
264
+ export declare function getNativeEventBinder<T extends Window | Document>(target: T): Pick<T, 'addEventListener' | 'removeEventListener'>;
@@ -51,34 +51,6 @@ export declare function setClientIsReady(config?: DotCMSPageResponse): void;
51
51
  export declare function listenBlockEditorInlineEvent(): {
52
52
  destroyListenBlockEditorInlineEvent: () => void;
53
53
  };
54
- /**
55
- * Returns whether iframe height must be synchronized via postMessage.
56
- *
57
- * Same-origin parents can measure iframe content directly, so they do not need
58
- * child-driven height reporting. Cross-origin parents cannot access the iframe
59
- * DOM, so they still need the reporter fallback.
60
- */
61
- export declare function shouldReportIframeHeightToParent(): boolean;
62
- /**
63
- * Reports the iframe document height to the parent UVE shell via postMessage.
64
- *
65
- * Uses ResizeObserver on <html> for viewport/font/image-driven size changes, and
66
- * MutationObserver on <body> to catch DOM removals (e.g. contentlets deleted by
67
- * the editor) that shrink the page without triggering a resize event.
68
- *
69
- * Measurement reads `document.documentElement.offsetHeight` — the actual rendered
70
- * height of the <html> element after layout. `scrollHeight` is intentionally avoided
71
- * because it does not reliably decrease when content is removed from the DOM.
72
- *
73
- * Height sends are coalesced to at most one per double-requestAnimationFrame pair
74
- * so they always run after layout and paint have settled.
75
- *
76
- * @returns {{ destroyHeightReporter: () => void }} Cleanup function that removes
77
- * all listeners and disconnects the observers.
78
- */
79
- export declare function reportIframeHeight(): {
80
- destroyHeightReporter: () => void;
81
- };
82
54
  /**
83
55
  * Injects UVE editor styles for empty containers and contentlets into the page.
84
56
  * Provides visual placeholders so editors can identify and interact with empty areas.
@@ -1,18 +0,0 @@
1
- export interface ObserveDocumentHeightOptions {
2
- onHeightChange: (height: number) => void;
3
- documentRef?: Document;
4
- windowRef?: Window;
5
- debounceMs?: number;
6
- }
7
- export interface DocumentHeightObserverHandle {
8
- destroy: () => void;
9
- }
10
- /**
11
- * Observes rendered document height changes and notifies the caller after layout settles.
12
- *
13
- * Uses ResizeObserver on <html> for layout/viewport-driven changes and MutationObserver
14
- * on <body> to catch DOM additions/removals that may shrink the page without a resize.
15
- * Measurement reads `body.offsetHeight`, which tracks actual content height and
16
- * decreases correctly after DOM removals, unaffected by CSS min-height on the html element.
17
- */
18
- export declare function observeDocumentHeight({ onHeightChange, documentRef, windowRef, debounceMs }: ObserveDocumentHeightOptions): DocumentHeightObserverHandle;