@dotcms/analytics 1.2.1 → 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/lib/core/dot-analytics.content.d.ts +1 -1
- package/lib/core/dot-analytics.content.js +10 -11
- package/lib/core/plugin/identity/dot-analytics.identity.activity-tracker.d.ts +1 -1
- package/lib/core/plugin/identity/dot-analytics.identity.activity-tracker.js +8 -10
- package/lib/core/plugin/impression/dot-analytics.impression-tracker.js +2 -2
- package/lib/core/shared/constants/dot-analytics.constants.d.ts +29 -3
- package/lib/core/shared/constants/dot-analytics.constants.js +23 -21
- package/lib/core/shared/queue/dot-analytics.queue.utils.js +22 -22
- package/lib/core/shared/utils/dot-analytics.utils.js +69 -72
- package/lib/react/hook/useRouterTracker.js +12 -12
- package/package.json +1 -1
- package/uve/src/internal/constants.js +3 -8
- package/uve/src/internal/events.js +33 -31
- package/uve/src/lib/dom/dom.utils.js +46 -52
package/README.md
CHANGED
|
@@ -247,7 +247,7 @@ The `impressions` option controls automatic tracking of content visibility:
|
|
|
247
247
|
|
|
248
248
|
**How it works:**
|
|
249
249
|
|
|
250
|
-
- ✅ Tracks contentlets marked with `dotcms-
|
|
250
|
+
- ✅ Tracks contentlets marked with `dotcms-contentlet` class and `data-dot-*` attributes (e.g., `data-dot-identifier`, `data-dot-inode`, `data-dot-type`)
|
|
251
251
|
- ✅ Uses Intersection Observer API for high performance and battery efficiency
|
|
252
252
|
- ✅ Only fires when element is ≥50% visible for ≥750ms (configurable)
|
|
253
253
|
- ✅ Only tracks during active tab (respects page visibility)
|
|
@@ -299,7 +299,7 @@ The `clicks` option controls automatic tracking of user interactions with conten
|
|
|
299
299
|
**How it works:**
|
|
300
300
|
|
|
301
301
|
- ✅ Tracks clicks on `<a>` and `<button>` elements within contentlets
|
|
302
|
-
- ✅ Contentlets must be marked with `dotcms-
|
|
302
|
+
- ✅ Contentlets must be marked with `dotcms-contentlet` class and `data-dot-*` attributes (e.g., `data-dot-identifier`, `data-dot-inode`, `data-dot-type`)
|
|
303
303
|
- ✅ Captures semantic attributes (`href`, `aria-label`, `data-*`) and excludes CSS classes
|
|
304
304
|
- ✅ Throttles rapid clicks to prevent duplicate tracking (300ms fixed)
|
|
305
305
|
- ✅ One click event per interaction
|
|
@@ -341,7 +341,7 @@ The `attributes` array captures additional semantic data in `'key:value'` string
|
|
|
341
341
|
- `class` - Already captured as top-level property
|
|
342
342
|
- `id` - Already captured as top-level property
|
|
343
343
|
- `href` - Already captured as top-level property
|
|
344
|
-
- `data-dot
|
|
344
|
+
- `data-dot-*` - Internal SDK attributes (e.g., `data-dot-identifier`, `data-dot-inode`, `data-dot-type`)
|
|
345
345
|
|
|
346
346
|
**Example: Enable click tracking**
|
|
347
347
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ANALYTICS_WINDOWS_ACTIVE_KEY, ANALYTICS_WINDOWS_CLEANUP_KEY } from '
|
|
1
|
+
import { ANALYTICS_WINDOWS_ACTIVE_KEY, ANALYTICS_WINDOWS_CLEANUP_KEY } from './shared/constants/dot-analytics.constants';
|
|
2
2
|
import { DotCMSAnalytics, DotCMSAnalyticsConfig } from './shared/models';
|
|
3
3
|
declare global {
|
|
4
4
|
interface Window {
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import { Analytics as l } from "analytics";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { dotAnalyticsEnricherPlugin as m } from "./plugin/enricher/dot-analytics.enricher.plugin.js";
|
|
2
|
+
import { dotAnalyticsClickPlugin as d } from "./plugin/click/dot-analytics.click.plugin.js";
|
|
3
|
+
import { dotAnalyticsEnricherPlugin as y } from "./plugin/enricher/dot-analytics.enricher.plugin.js";
|
|
5
4
|
import { dotAnalyticsIdentityPlugin as u } from "./plugin/identity/dot-analytics.identity.plugin.js";
|
|
6
|
-
import { dotAnalyticsImpressionPlugin as
|
|
5
|
+
import { dotAnalyticsImpressionPlugin as m } from "./plugin/impression/dot-analytics.impression.plugin.js";
|
|
7
6
|
import { dotAnalytics as A } from "./plugin/main/dot-analytics.plugin.js";
|
|
8
|
-
import { DotCMSPredefinedEventType as f } from "./shared/constants/dot-analytics.constants.js";
|
|
7
|
+
import { ANALYTICS_WINDOWS_ACTIVE_KEY as a, ANALYTICS_WINDOWS_CLEANUP_KEY as p, DotCMSPredefinedEventType as f } from "./shared/constants/dot-analytics.constants.js";
|
|
9
8
|
import { validateAnalyticsConfig as C, getEnhancedTrackingPlugins as w } from "./shared/utils/dot-analytics.utils.js";
|
|
10
9
|
import { cleanupActivityTracking as g } from "./plugin/identity/dot-analytics.identity.activity-tracker.js";
|
|
11
|
-
const
|
|
10
|
+
const T = (t) => {
|
|
12
11
|
const e = C(t);
|
|
13
12
|
if (e)
|
|
14
13
|
return console.error(
|
|
@@ -16,8 +15,8 @@ const _ = (t) => {
|
|
|
16
15
|
), typeof window < "u" && (window[a] = !1), null;
|
|
17
16
|
const s = w(
|
|
18
17
|
t,
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
m,
|
|
19
|
+
d
|
|
21
20
|
), i = l({
|
|
22
21
|
app: "dotAnalytics",
|
|
23
22
|
debug: t.debug,
|
|
@@ -26,13 +25,13 @@ const _ = (t) => {
|
|
|
26
25
|
// Inject identity context
|
|
27
26
|
...s,
|
|
28
27
|
//Track content impressions & clicks (conditionally loaded)
|
|
29
|
-
|
|
28
|
+
y(),
|
|
30
29
|
// Enrich and clean payload with page, device, utm data and custom data
|
|
31
30
|
A(t)
|
|
32
31
|
// Send events to server
|
|
33
32
|
]
|
|
34
33
|
}), r = () => g();
|
|
35
|
-
return typeof window < "u" && (window.addEventListener("beforeunload", r), window[
|
|
34
|
+
return typeof window < "u" && (window.addEventListener("beforeunload", r), window[p] = r, window[a] = !0, window.dispatchEvent(new CustomEvent("dotcms:analytics:ready"))), {
|
|
36
35
|
/**
|
|
37
36
|
* Track a page view.
|
|
38
37
|
* Session activity is automatically updated by the identity plugin.
|
|
@@ -80,5 +79,5 @@ const _ = (t) => {
|
|
|
80
79
|
};
|
|
81
80
|
};
|
|
82
81
|
export {
|
|
83
|
-
|
|
82
|
+
T as initializeContentAnalytics
|
|
84
83
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ANALYTICS_WINDOWS_ACTIVE_KEY, ANALYTICS_WINDOWS_CLEANUP_KEY } from '
|
|
1
|
+
import { ANALYTICS_WINDOWS_ACTIVE_KEY, ANALYTICS_WINDOWS_CLEANUP_KEY } from '../../shared/constants';
|
|
2
2
|
import { DotCMSAnalyticsConfig } from '../../shared/models';
|
|
3
3
|
declare global {
|
|
4
4
|
interface Window {
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { ANALYTICS_WINDOWS_ACTIVE_KEY as a, ANALYTICS_WINDOWS_CLEANUP_KEY as o } from "
|
|
2
|
-
import { DEFAULT_SESSION_TIMEOUT_MINUTES as r, ACTIVITY_EVENTS as l } from "../../shared/constants/dot-analytics.constants.js";
|
|
1
|
+
import { ANALYTICS_WINDOWS_ACTIVE_KEY as a, ANALYTICS_WINDOWS_CLEANUP_KEY as o, DEFAULT_SESSION_TIMEOUT_MINUTES as r, ACTIVITY_EVENTS as l } from "../../shared/constants/dot-analytics.constants.js";
|
|
3
2
|
class v {
|
|
4
3
|
constructor() {
|
|
5
4
|
this.activityListeners = [], this.lastActivityTime = Date.now(), this.inactivityTimer = null, this.isThrottled = !1, this.config = null, this.ACTIVITY_THROTTLE_MS = 1e3;
|
|
@@ -11,8 +10,7 @@ class v {
|
|
|
11
10
|
updateActivityTime() {
|
|
12
11
|
this.lastActivityTime = Date.now(), this.inactivityTimer && clearTimeout(this.inactivityTimer), this.inactivityTimer = setTimeout(
|
|
13
12
|
() => {
|
|
14
|
-
|
|
15
|
-
(i = this.config) != null && i.debug && console.warn("DotCMS Analytics [Activity]: User became inactive after timeout"), this.inactivityTimer = null;
|
|
13
|
+
this.config?.debug && console.warn("DotCMS Analytics [Activity]: User became inactive after timeout"), this.inactivityTimer = null;
|
|
16
14
|
},
|
|
17
15
|
r * 60 * 1e3
|
|
18
16
|
);
|
|
@@ -53,15 +51,15 @@ class v {
|
|
|
53
51
|
this.activityListeners.forEach((i) => i()), this.activityListeners = [], this.inactivityTimer && (clearTimeout(this.inactivityTimer), this.inactivityTimer = null), this.config = null;
|
|
54
52
|
}
|
|
55
53
|
}
|
|
56
|
-
const t = new v(),
|
|
54
|
+
const t = new v(), T = () => {
|
|
57
55
|
t.updateSessionActivity();
|
|
58
|
-
},
|
|
56
|
+
}, d = (e) => {
|
|
59
57
|
t.initialize(e);
|
|
60
|
-
},
|
|
58
|
+
}, u = () => {
|
|
61
59
|
t.cleanup(), typeof window < "u" && (window[a] = !1, window[o] = void 0, window.dispatchEvent(new CustomEvent("dotcms:analytics:cleanup")));
|
|
62
60
|
};
|
|
63
61
|
export {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
62
|
+
u as cleanupActivityTracking,
|
|
63
|
+
d as initializeActivityTracking,
|
|
64
|
+
T as updateSessionActivity
|
|
67
65
|
};
|
|
@@ -78,7 +78,7 @@ class E {
|
|
|
78
78
|
this.logger.debug(`Skipping element ${r} (${o})`);
|
|
79
79
|
continue;
|
|
80
80
|
}
|
|
81
|
-
this.elementImpressionStates.has(r) || (n.dataset.
|
|
81
|
+
this.elementImpressionStates.has(r) || (n.dataset.dotDomIndex || (n.dataset.dotDomIndex = String(s)), this.observer.observe(n), this.elementImpressionStates.set(r, {
|
|
82
82
|
timer: null,
|
|
83
83
|
visibleSince: null,
|
|
84
84
|
tracked: this.hasBeenTrackedInSession(r),
|
|
@@ -150,7 +150,7 @@ class E {
|
|
|
150
150
|
trackAndSendImpression(e, i) {
|
|
151
151
|
const t = this.elementImpressionStates.get(e);
|
|
152
152
|
if (!t) return;
|
|
153
|
-
const s = t.visibleSince ? Date.now() - t.visibleSince : 0, n = I(i), r = d(i), o = parseInt(i.dataset.
|
|
153
|
+
const s = t.visibleSince ? Date.now() - t.visibleSince : 0, n = I(i), r = d(i), o = parseInt(i.dataset.dotDomIndex || "-1", 10), h = {
|
|
154
154
|
content: {
|
|
155
155
|
identifier: n.identifier,
|
|
156
156
|
inode: n.inode,
|
|
@@ -127,6 +127,32 @@ export declare const CLICKABLE_ELEMENTS_SELECTOR = "a, button";
|
|
|
127
127
|
*/
|
|
128
128
|
export declare const IMPRESSION_SESSION_KEY = "dot_analytics_impressions";
|
|
129
129
|
/**
|
|
130
|
-
*
|
|
131
|
-
|
|
132
|
-
|
|
130
|
+
* Window property key for analytics active state
|
|
131
|
+
* Used to track if analytics is initialized and active
|
|
132
|
+
*/
|
|
133
|
+
export declare const ANALYTICS_WINDOWS_ACTIVE_KEY = "__dotAnalyticsActive__";
|
|
134
|
+
/**
|
|
135
|
+
* Window property key for analytics cleanup function
|
|
136
|
+
* Used to store the cleanup function for analytics instance
|
|
137
|
+
*/
|
|
138
|
+
export declare const ANALYTICS_WINDOWS_CLEANUP_KEY = "__dotAnalyticsCleanup__";
|
|
139
|
+
/**
|
|
140
|
+
* CSS class selector for contentlet elements
|
|
141
|
+
*
|
|
142
|
+
* @important This constant is intentionally duplicated in @dotcms/react SDK
|
|
143
|
+
* (core-web/libs/sdk/react/src/lib/next/components/Contentlet/Contentlet.tsx).
|
|
144
|
+
* Both constants MUST have the same value ('dotcms-contentlet') for analytics
|
|
145
|
+
* tracking to work correctly with React-rendered contentlets.
|
|
146
|
+
*
|
|
147
|
+
* This duplication is intentional to maintain SDK independence:
|
|
148
|
+
* - @dotcms/analytics can be used standalone without React
|
|
149
|
+
* - @dotcms/react can be used without analytics
|
|
150
|
+
* - When both are used together, they must share the same class name
|
|
151
|
+
*
|
|
152
|
+
* If you need to change this value, you MUST update it in both locations:
|
|
153
|
+
* 1. This file (analytics SDK)
|
|
154
|
+
* 2. Contentlet.tsx in React SDK
|
|
155
|
+
*
|
|
156
|
+
* @see core-web/libs/sdk/react/src/lib/next/components/Contentlet/Contentlet.tsx
|
|
157
|
+
*/
|
|
158
|
+
export declare const CONTENTLET_CLASS = "dotcms-contentlet";
|
|
@@ -3,18 +3,18 @@ const I = "/api/v1/analytics/content/event", c = {
|
|
|
3
3
|
CONTENT_IMPRESSION: "content_impression",
|
|
4
4
|
CONTENT_CLICK: "content_click",
|
|
5
5
|
CONVERSION: "conversion"
|
|
6
|
-
},
|
|
6
|
+
}, o = [
|
|
7
7
|
"utm_source",
|
|
8
8
|
"utm_medium",
|
|
9
9
|
"utm_campaign",
|
|
10
10
|
"utm_term",
|
|
11
11
|
"utm_content"
|
|
12
|
-
],
|
|
13
|
-
eventBatchSize:
|
|
12
|
+
], s = 30, e = "dot_analytics_session_id", N = "dot_analytics_user_id", _ = 15, E = 5e3, A = ["click"], L = {
|
|
13
|
+
eventBatchSize: _,
|
|
14
14
|
// Max events per batch - auto-sends when reached
|
|
15
|
-
flushInterval:
|
|
15
|
+
flushInterval: E
|
|
16
16
|
// Time between flushes - sends whatever is queued
|
|
17
|
-
},
|
|
17
|
+
}, O = [
|
|
18
18
|
"title",
|
|
19
19
|
"url",
|
|
20
20
|
"path",
|
|
@@ -23,30 +23,32 @@ const I = "/api/v1/analytics/content/event", c = {
|
|
|
23
23
|
"width",
|
|
24
24
|
"height",
|
|
25
25
|
"referrer"
|
|
26
|
-
], t = 0.5,
|
|
26
|
+
], t = 0.5, n = 750, T = 100, S = 100, i = 250, C = {
|
|
27
27
|
visibilityThreshold: t,
|
|
28
|
-
dwellMs:
|
|
29
|
-
maxNodes:
|
|
28
|
+
dwellMs: n,
|
|
29
|
+
maxNodes: T,
|
|
30
30
|
throttleMs: S
|
|
31
|
-
}, U = "content_impression",
|
|
31
|
+
}, U = "content_impression", D = "content_click", M = 300, a = "a, button", R = "__dotAnalyticsActive__", l = "__dotAnalyticsCleanup__", r = "dotcms-contentlet";
|
|
32
32
|
export {
|
|
33
|
-
|
|
34
|
-
a as ANALYTICS_CONTENTLET_CLASS,
|
|
33
|
+
A as ACTIVITY_EVENTS,
|
|
35
34
|
I as ANALYTICS_ENDPOINT,
|
|
36
|
-
|
|
37
|
-
R as
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
O as ANALYTICS_JS_DEFAULT_PROPERTIES,
|
|
36
|
+
R as ANALYTICS_WINDOWS_ACTIVE_KEY,
|
|
37
|
+
l as ANALYTICS_WINDOWS_CLEANUP_KEY,
|
|
38
|
+
a as CLICKABLE_ELEMENTS_SELECTOR,
|
|
39
|
+
D as CLICK_EVENT_TYPE,
|
|
40
|
+
r as CONTENTLET_CLASS,
|
|
41
|
+
M as DEFAULT_CLICK_THROTTLE_MS,
|
|
40
42
|
C as DEFAULT_IMPRESSION_CONFIG,
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
43
|
+
n as DEFAULT_IMPRESSION_DWELL_MS,
|
|
44
|
+
T as DEFAULT_IMPRESSION_MAX_NODES,
|
|
45
|
+
i as DEFAULT_IMPRESSION_MUTATION_OBSERVER_DEBOUNCE_MS,
|
|
44
46
|
S as DEFAULT_IMPRESSION_THROTTLE_MS,
|
|
45
47
|
t as DEFAULT_IMPRESSION_VISIBILITY_THRESHOLD,
|
|
46
|
-
|
|
47
|
-
|
|
48
|
+
L as DEFAULT_QUEUE_CONFIG,
|
|
49
|
+
s as DEFAULT_SESSION_TIMEOUT_MINUTES,
|
|
48
50
|
c as DotCMSPredefinedEventType,
|
|
49
|
-
|
|
51
|
+
o as EXPECTED_UTM_KEYS,
|
|
50
52
|
U as IMPRESSION_EVENT_TYPE,
|
|
51
53
|
e as SESSION_STORAGE_KEY,
|
|
52
54
|
N as USER_ID_KEY
|
|
@@ -3,20 +3,20 @@ import v from "@analytics/router-utils";
|
|
|
3
3
|
import { DEFAULT_QUEUE_CONFIG as y } from "../constants/dot-analytics.constants.js";
|
|
4
4
|
import { sendAnalyticsEvent as b } from "../http/dot-analytics.http.js";
|
|
5
5
|
import { createPluginLogger as w } from "../utils/dot-analytics.utils.js";
|
|
6
|
-
const L = (
|
|
7
|
-
const i = w("Queue",
|
|
8
|
-
let
|
|
6
|
+
const L = (u) => {
|
|
7
|
+
const i = w("Queue", u);
|
|
8
|
+
let t = null, n = null, o = !1, d = !1, f = typeof window < "u" ? window.location.pathname : "";
|
|
9
9
|
const a = {
|
|
10
10
|
...y,
|
|
11
|
-
...typeof
|
|
12
|
-
}, g = (
|
|
11
|
+
...typeof u.queue == "object" ? u.queue : {}
|
|
12
|
+
}, g = (e, s) => {
|
|
13
13
|
if (!n) return;
|
|
14
|
-
i.debug(`Sending batch of ${
|
|
15
|
-
events:
|
|
16
|
-
keepalive:
|
|
17
|
-
}), b({ context: n, events:
|
|
14
|
+
i.debug(`Sending batch of ${e.length} event(s)`, {
|
|
15
|
+
events: e,
|
|
16
|
+
keepalive: o
|
|
17
|
+
}), b({ context: n, events: e }, u, o);
|
|
18
18
|
}, l = () => {
|
|
19
|
-
!
|
|
19
|
+
!t || t.size() === 0 || !n || (i.info(`Flushing ${t.size()} events (page hidden/unload)`), o = !0, t.flush(!0));
|
|
20
20
|
}, c = () => {
|
|
21
21
|
if (i.debug("handleVisibilityChange", document.visibilityState), document.visibilityState === "hidden") {
|
|
22
22
|
if (d) {
|
|
@@ -31,9 +31,9 @@ const L = (o) => {
|
|
|
31
31
|
* Initialize the queue with smart batching
|
|
32
32
|
*/
|
|
33
33
|
initialize: () => {
|
|
34
|
-
|
|
35
|
-
(
|
|
36
|
-
g(
|
|
34
|
+
t = m(
|
|
35
|
+
(e, s) => {
|
|
36
|
+
g(e);
|
|
37
37
|
},
|
|
38
38
|
{
|
|
39
39
|
max: a.eventBatchSize,
|
|
@@ -41,8 +41,8 @@ const L = (o) => {
|
|
|
41
41
|
throttle: !1
|
|
42
42
|
// Always false - enables both batch size and interval triggers
|
|
43
43
|
}
|
|
44
|
-
), typeof window < "u" && typeof document < "u" && (document.addEventListener("visibilitychange", c), window.addEventListener("pagehide", l), v((
|
|
45
|
-
d = !0, f =
|
|
44
|
+
), typeof window < "u" && typeof document < "u" && (document.addEventListener("visibilitychange", c), window.addEventListener("pagehide", l), v((e) => {
|
|
45
|
+
d = !0, f = e, i.debug(`SPA navigation detected (${f})`), setTimeout(() => {
|
|
46
46
|
d = !1;
|
|
47
47
|
}, 100);
|
|
48
48
|
}));
|
|
@@ -53,25 +53,25 @@ const L = (o) => {
|
|
|
53
53
|
* - Sends immediately when eventBatchSize reached (with throttle: false)
|
|
54
54
|
* - Sends pending events every flushInterval
|
|
55
55
|
*/
|
|
56
|
-
enqueue: (
|
|
57
|
-
if (n = s, !
|
|
58
|
-
const r =
|
|
56
|
+
enqueue: (e, s) => {
|
|
57
|
+
if (n = s, !t) return;
|
|
58
|
+
const r = t.size() + 1, p = a.eventBatchSize, h = r >= p;
|
|
59
59
|
i.debug(
|
|
60
60
|
`Event added. Queue size: ${r}/${p}${h ? " (full, sending...)" : ""}`,
|
|
61
|
-
{ eventType:
|
|
62
|
-
),
|
|
61
|
+
{ eventType: e.event_type, event: e }
|
|
62
|
+
), t.push(e);
|
|
63
63
|
},
|
|
64
64
|
/**
|
|
65
65
|
* Get queue size for debugging
|
|
66
66
|
* Returns the number of events in smartQueue
|
|
67
67
|
*/
|
|
68
|
-
size: () =>
|
|
68
|
+
size: () => t?.size() ?? 0,
|
|
69
69
|
/**
|
|
70
70
|
* Clean up queue resources
|
|
71
71
|
* Flushes remaining events and cleans up listeners
|
|
72
72
|
*/
|
|
73
73
|
cleanup: () => {
|
|
74
|
-
l(), typeof window < "u" && typeof document < "u" && (document.removeEventListener("visibilitychange", c), window.removeEventListener("pagehide", l)),
|
|
74
|
+
l(), typeof window < "u" && typeof document < "u" && (document.removeEventListener("visibilitychange", c), window.removeEventListener("pagehide", l)), t = null, n = null, o = !1;
|
|
75
75
|
}
|
|
76
76
|
};
|
|
77
77
|
};
|
|
@@ -1,16 +1,14 @@
|
|
|
1
|
-
import { ANALYTICS_JS_DEFAULT_PROPERTIES as
|
|
1
|
+
import { ANALYTICS_JS_DEFAULT_PROPERTIES as _, SESSION_STORAGE_KEY as g, DEFAULT_SESSION_TIMEOUT_MINUTES as p, USER_ID_KEY as m, DEFAULT_IMPRESSION_MUTATION_OBSERVER_DEBOUNCE_MS as T, EXPECTED_UTM_KEYS as D, CONTENTLET_CLASS as h } from "../constants/dot-analytics.constants.js";
|
|
2
2
|
import { DotLogger as E } from "../dot-analytics.logger.js";
|
|
3
|
-
|
|
4
|
-
function Y(t) {
|
|
5
|
-
var n, s;
|
|
3
|
+
function $(t) {
|
|
6
4
|
const e = [];
|
|
7
|
-
return
|
|
5
|
+
return t.siteAuth?.trim() || e.push('"siteAuth"'), t.server?.trim() || e.push('"server"'), e.length > 0 ? e : null;
|
|
8
6
|
}
|
|
9
|
-
let
|
|
10
|
-
const
|
|
7
|
+
let d = null, u = null;
|
|
8
|
+
const l = (t) => {
|
|
11
9
|
const e = Date.now(), n = Math.random().toString(36).substr(2, 9), s = Math.random().toString(36).substr(2, 9);
|
|
12
10
|
return `${t}_${e}_${n}${s}`;
|
|
13
|
-
},
|
|
11
|
+
}, f = {
|
|
14
12
|
getItem: (t) => {
|
|
15
13
|
try {
|
|
16
14
|
return localStorage.getItem(t);
|
|
@@ -25,10 +23,10 @@ const g = (t) => {
|
|
|
25
23
|
console.warn(`DotCMS Analytics [Core]: Could not save ${t} to localStorage`);
|
|
26
24
|
}
|
|
27
25
|
}
|
|
28
|
-
},
|
|
29
|
-
let t =
|
|
30
|
-
return t || (t =
|
|
31
|
-
},
|
|
26
|
+
}, I = () => {
|
|
27
|
+
let t = f.getItem(m);
|
|
28
|
+
return t || (t = l("user"), f.setItem(m, t)), t;
|
|
29
|
+
}, y = (t) => {
|
|
32
30
|
const e = new Date(t), n = /* @__PURE__ */ new Date(), s = new Date(
|
|
33
31
|
e.getUTCFullYear(),
|
|
34
32
|
e.getUTCMonth(),
|
|
@@ -38,14 +36,14 @@ const g = (t) => {
|
|
|
38
36
|
}, v = () => {
|
|
39
37
|
const t = Date.now();
|
|
40
38
|
if (typeof window > "u")
|
|
41
|
-
return
|
|
39
|
+
return l("session_fallback");
|
|
42
40
|
try {
|
|
43
|
-
const e = sessionStorage.getItem(
|
|
41
|
+
const e = sessionStorage.getItem(g);
|
|
44
42
|
if (e) {
|
|
45
|
-
const { sessionId: r, startTime: o, lastActivity: a } = JSON.parse(e), i = !
|
|
43
|
+
const { sessionId: r, startTime: o, lastActivity: a } = JSON.parse(e), i = !y(o), c = t - a < p * 60 * 1e3;
|
|
46
44
|
if (i && c)
|
|
47
45
|
return sessionStorage.setItem(
|
|
48
|
-
|
|
46
|
+
g,
|
|
49
47
|
JSON.stringify({
|
|
50
48
|
sessionId: r,
|
|
51
49
|
startTime: o,
|
|
@@ -53,39 +51,39 @@ const g = (t) => {
|
|
|
53
51
|
})
|
|
54
52
|
), r;
|
|
55
53
|
}
|
|
56
|
-
const n =
|
|
54
|
+
const n = l("session"), s = {
|
|
57
55
|
sessionId: n,
|
|
58
56
|
startTime: t,
|
|
59
57
|
lastActivity: t
|
|
60
58
|
};
|
|
61
|
-
return sessionStorage.setItem(
|
|
59
|
+
return sessionStorage.setItem(g, JSON.stringify(s)), n;
|
|
62
60
|
} catch {
|
|
63
|
-
return
|
|
61
|
+
return l("session_fallback");
|
|
64
62
|
}
|
|
65
|
-
},
|
|
66
|
-
const e = v(), n =
|
|
63
|
+
}, P = (t) => {
|
|
64
|
+
const e = v(), n = I(), s = C();
|
|
67
65
|
return {
|
|
68
66
|
site_auth: t.siteAuth,
|
|
69
67
|
session_id: e,
|
|
70
68
|
user_id: n,
|
|
71
69
|
device: s
|
|
72
70
|
};
|
|
73
|
-
},
|
|
71
|
+
}, w = () => d || (d = {
|
|
74
72
|
user_language: navigator.language,
|
|
75
73
|
doc_encoding: document.characterSet || document.charset,
|
|
76
74
|
screen_resolution: typeof screen < "u" && screen.width && screen.height ? `${screen.width}x${screen.height}` : ""
|
|
77
|
-
},
|
|
78
|
-
const t =
|
|
75
|
+
}, d), C = () => {
|
|
76
|
+
const t = w(), e = window.innerWidth || document.documentElement.clientWidth || 0, n = window.innerHeight || document.documentElement.clientHeight || 0;
|
|
79
77
|
return {
|
|
80
78
|
screen_resolution: t.screen_resolution ?? "",
|
|
81
79
|
language: t.user_language ?? "",
|
|
82
80
|
viewport_width: String(e),
|
|
83
81
|
viewport_height: String(n)
|
|
84
82
|
};
|
|
85
|
-
},
|
|
83
|
+
}, A = (t) => {
|
|
86
84
|
const e = t.search;
|
|
87
|
-
if (
|
|
88
|
-
return
|
|
85
|
+
if (u && u.search === e)
|
|
86
|
+
return u.params;
|
|
89
87
|
const n = new URLSearchParams(e), s = {};
|
|
90
88
|
return D.forEach((r) => {
|
|
91
89
|
const o = n.get(r);
|
|
@@ -93,25 +91,25 @@ const g = (t) => {
|
|
|
93
91
|
const a = r.replace("utm_", "");
|
|
94
92
|
s[a] = o;
|
|
95
93
|
}
|
|
96
|
-
}),
|
|
97
|
-
},
|
|
94
|
+
}), u = { search: e, params: s }, s;
|
|
95
|
+
}, O = () => {
|
|
98
96
|
try {
|
|
99
97
|
const t = (/* @__PURE__ */ new Date()).getTimezoneOffset(), e = t > 0 ? "-" : "+", n = Math.abs(t), s = Math.floor(n / 60), r = n % 60;
|
|
100
98
|
return `${e}${s.toString().padStart(2, "0")}:${r.toString().padStart(2, "0")}`;
|
|
101
99
|
} catch {
|
|
102
100
|
return "+00:00";
|
|
103
101
|
}
|
|
104
|
-
},
|
|
102
|
+
}, N = () => {
|
|
105
103
|
try {
|
|
106
|
-
const t = /* @__PURE__ */ new Date(), e =
|
|
104
|
+
const t = /* @__PURE__ */ new Date(), e = O(), n = t.getFullYear(), s = (t.getMonth() + 1).toString().padStart(2, "0"), r = t.getDate().toString().padStart(2, "0"), o = t.getHours().toString().padStart(2, "0"), a = t.getMinutes().toString().padStart(2, "0"), i = t.getSeconds().toString().padStart(2, "0");
|
|
107
105
|
return `${n}-${s}-${r}T${o}:${a}:${i}${e}`;
|
|
108
106
|
} catch {
|
|
109
107
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
110
108
|
}
|
|
111
|
-
},
|
|
112
|
-
const n =
|
|
109
|
+
}, R = (t, e = typeof window < "u" ? window.location : {}) => {
|
|
110
|
+
const n = N(), s = w(), { properties: r } = t, o = {};
|
|
113
111
|
Object.keys(r).forEach((c) => {
|
|
114
|
-
|
|
112
|
+
_.includes(c) || (o[c] = r[c]);
|
|
115
113
|
});
|
|
116
114
|
const a = {
|
|
117
115
|
url: e.href,
|
|
@@ -121,8 +119,8 @@ const g = (t) => {
|
|
|
121
119
|
doc_search: e.search,
|
|
122
120
|
doc_host: e.hostname,
|
|
123
121
|
doc_path: e.pathname,
|
|
124
|
-
title: r.title ??
|
|
125
|
-
}, i =
|
|
122
|
+
title: r.title ?? document?.title
|
|
123
|
+
}, i = A(e);
|
|
126
124
|
return {
|
|
127
125
|
...t,
|
|
128
126
|
page: a,
|
|
@@ -132,36 +130,35 @@ const g = (t) => {
|
|
|
132
130
|
local_time: n
|
|
133
131
|
};
|
|
134
132
|
};
|
|
135
|
-
function
|
|
133
|
+
function b(t, e) {
|
|
136
134
|
let n = 0;
|
|
137
135
|
return (...s) => {
|
|
138
136
|
const r = Date.now();
|
|
139
137
|
r - n >= e && (t(...s), n = r);
|
|
140
138
|
};
|
|
141
139
|
}
|
|
142
|
-
function
|
|
143
|
-
return t.dataset.
|
|
140
|
+
function x(t) {
|
|
141
|
+
return t.dataset.dotIdentifier || null;
|
|
144
142
|
}
|
|
145
|
-
function
|
|
143
|
+
function Y(t) {
|
|
146
144
|
return {
|
|
147
|
-
identifier: t.dataset.
|
|
148
|
-
inode: t.dataset.
|
|
149
|
-
contentType: t.dataset.
|
|
150
|
-
title: t.dataset.
|
|
151
|
-
baseType: t.dataset.
|
|
145
|
+
identifier: t.dataset.dotIdentifier || "",
|
|
146
|
+
inode: t.dataset.dotInode || "",
|
|
147
|
+
contentType: t.dataset.dotType || "",
|
|
148
|
+
title: t.dataset.dotTitle || "",
|
|
149
|
+
baseType: t.dataset.dotBasetype || ""
|
|
152
150
|
};
|
|
153
151
|
}
|
|
154
|
-
const
|
|
155
|
-
const n =
|
|
152
|
+
const B = 100, M = () => typeof window < "u" && typeof document < "u", F = () => Array.from(document.querySelectorAll(`.${h}`)), k = (t, e = T) => {
|
|
153
|
+
const n = b(t, e), s = new MutationObserver((r) => {
|
|
156
154
|
r.some((a) => a.addedNodes.length === 0 && a.removedNodes.length === 0 ? !1 : [
|
|
157
155
|
...Array.from(a.addedNodes),
|
|
158
156
|
...Array.from(a.removedNodes)
|
|
159
157
|
].some((c) => {
|
|
160
|
-
var f, m;
|
|
161
158
|
if (c.nodeType !== Node.ELEMENT_NODE)
|
|
162
159
|
return !1;
|
|
163
|
-
const
|
|
164
|
-
return
|
|
160
|
+
const S = c;
|
|
161
|
+
return S.classList?.contains(h) ? !0 : S.querySelector?.(`.${h}`) !== null;
|
|
165
162
|
})) && n();
|
|
166
163
|
});
|
|
167
164
|
return s.observe(document.body, {
|
|
@@ -170,33 +167,33 @@ const z = 100, U = () => typeof window < "u" && typeof document < "u", H = () =>
|
|
|
170
167
|
attributes: !1,
|
|
171
168
|
characterData: !1
|
|
172
169
|
}), s;
|
|
173
|
-
},
|
|
174
|
-
|
|
175
|
-
},
|
|
170
|
+
}, z = (t) => {
|
|
171
|
+
M() && (window.addEventListener("beforeunload", t), window.addEventListener("pagehide", t));
|
|
172
|
+
}, H = (t, e) => {
|
|
176
173
|
const n = e.logLevel ?? (e.debug ? "debug" : "warn");
|
|
177
174
|
return new E("Analytics", t, n);
|
|
178
|
-
},
|
|
175
|
+
}, J = (t, e, n) => [
|
|
179
176
|
t.impressions && e(t),
|
|
180
177
|
t.clicks && n(t)
|
|
181
178
|
].filter(Boolean);
|
|
182
179
|
export {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
180
|
+
B as INITIAL_SCAN_DELAY_MS,
|
|
181
|
+
k as createContentletObserver,
|
|
182
|
+
H as createPluginLogger,
|
|
183
|
+
b as createThrottle,
|
|
184
|
+
R as enrichPagePayloadOptimized,
|
|
185
|
+
Y as extractContentletData,
|
|
186
|
+
x as extractContentletIdentifier,
|
|
187
|
+
A as extractUTMParameters,
|
|
188
|
+
F as findContentlets,
|
|
189
|
+
l as generateSecureId,
|
|
190
|
+
P as getAnalyticsContext,
|
|
191
|
+
C as getDeviceDataForContext,
|
|
192
|
+
J as getEnhancedTrackingPlugins,
|
|
193
|
+
N as getLocalTime,
|
|
197
194
|
v as getSessionId,
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
195
|
+
I as getUserId,
|
|
196
|
+
M as isBrowser,
|
|
197
|
+
z as setupPluginCleanup,
|
|
198
|
+
$ as validateAnalyticsConfig
|
|
202
199
|
};
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import { usePathname as
|
|
2
|
-
import { useRef as
|
|
3
|
-
import { getUVEState as
|
|
1
|
+
import { usePathname as s, useSearchParams as u } from "next/navigation";
|
|
2
|
+
import { useRef as c, useEffect as a } from "react";
|
|
3
|
+
import { getUVEState as m } from "../../../uve/src/lib/core/core.utils.js";
|
|
4
4
|
import "../../../uve/src/internal/constants.js";
|
|
5
|
-
const
|
|
6
|
-
function
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
if (!
|
|
5
|
+
const p = (t, e) => `${t}${e?.toString() ? "?" + e.toString() : ""}`;
|
|
6
|
+
function l(t, e = !1) {
|
|
7
|
+
const r = c(null), o = s(), n = u();
|
|
8
|
+
a(() => {
|
|
9
|
+
if (!t) return;
|
|
10
10
|
const i = (f) => {
|
|
11
|
-
|
|
11
|
+
m() || f !== r.current && (r.current = f, t.pageView());
|
|
12
12
|
};
|
|
13
|
-
|
|
14
|
-
}, [
|
|
13
|
+
e && console.info("DotCMS Analytics [React]: using Next.js App Router tracking"), i(p(o, n));
|
|
14
|
+
}, [t, o, n, e]);
|
|
15
15
|
}
|
|
16
16
|
export {
|
|
17
|
-
|
|
17
|
+
l as useRouterTracker
|
|
18
18
|
};
|
package/package.json
CHANGED
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
import { UVEEventType as
|
|
2
|
-
import { onContentletHovered as
|
|
3
|
-
|
|
4
|
-
const N = "__dotAnalyticsActive__", T = "__dotAnalyticsCleanup";
|
|
5
|
-
export {
|
|
6
|
-
N as ANALYTICS_WINDOWS_ACTIVE_KEY,
|
|
7
|
-
T as ANALYTICS_WINDOWS_CLEANUP_KEY
|
|
8
|
-
};
|
|
1
|
+
import { UVEEventType as n } from "../../../types/src/lib/editor/public.js";
|
|
2
|
+
import { onContentletHovered as r, onIframeScroll as o, onRequestBounds as t, onPageReload as E, onContentChanges as u } from "./events.js";
|
|
3
|
+
n.CONTENT_CHANGES + "", n.PAGE_RELOAD + "", n.REQUEST_BOUNDS + "", n.IFRAME_SCROLL + "", n.CONTENTLET_HOVERED + "";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { UVEEventType as a } from "../../../types/src/lib/editor/public.js";
|
|
2
2
|
import { __DOTCMS_UVE_EVENT__ as s } from "../../../types/src/lib/events/internal.js";
|
|
3
|
-
import { findDotCMSElement as
|
|
4
|
-
function
|
|
3
|
+
import { findDotCMSElement as u, findDotCMSVTLData as C, getClosestDotCMSContainerData as g, getDotCMSPageBounds as N } from "../lib/dom/dom.utils.js";
|
|
4
|
+
function O(o) {
|
|
5
5
|
const t = (n) => {
|
|
6
6
|
n.data.name === s.UVE_SET_PAGE_DATA && o(n.data.payload);
|
|
7
7
|
};
|
|
@@ -12,7 +12,7 @@ function U(o) {
|
|
|
12
12
|
event: a.CONTENT_CHANGES
|
|
13
13
|
};
|
|
14
14
|
}
|
|
15
|
-
function
|
|
15
|
+
function p(o) {
|
|
16
16
|
const t = (n) => {
|
|
17
17
|
n.data.name === s.UVE_RELOAD_PAGE && o();
|
|
18
18
|
};
|
|
@@ -23,12 +23,12 @@ function V(o) {
|
|
|
23
23
|
event: a.PAGE_RELOAD
|
|
24
24
|
};
|
|
25
25
|
}
|
|
26
|
-
function
|
|
26
|
+
function b(o) {
|
|
27
27
|
const t = (n) => {
|
|
28
28
|
if (n.data.name === s.UVE_REQUEST_BOUNDS) {
|
|
29
29
|
const e = Array.from(
|
|
30
30
|
document.querySelectorAll('[data-dot-object="container"]')
|
|
31
|
-
), i =
|
|
31
|
+
), i = N(e);
|
|
32
32
|
o(i);
|
|
33
33
|
}
|
|
34
34
|
};
|
|
@@ -39,7 +39,7 @@ function I(o) {
|
|
|
39
39
|
event: a.REQUEST_BOUNDS
|
|
40
40
|
};
|
|
41
41
|
}
|
|
42
|
-
function
|
|
42
|
+
function S(o) {
|
|
43
43
|
const t = (n) => {
|
|
44
44
|
if (n.data.name === s.UVE_SCROLL_INSIDE_IFRAME) {
|
|
45
45
|
const e = n.data.direction;
|
|
@@ -53,12 +53,11 @@ function Y(o) {
|
|
|
53
53
|
event: a.IFRAME_SCROLL
|
|
54
54
|
};
|
|
55
55
|
}
|
|
56
|
-
function
|
|
56
|
+
function M(o) {
|
|
57
57
|
const t = (n) => {
|
|
58
|
-
|
|
59
|
-
const e = M(n.target);
|
|
58
|
+
const e = u(n.target);
|
|
60
59
|
if (!e) return;
|
|
61
|
-
const { x: i, y:
|
|
60
|
+
const { x: i, y: d, width: r, height: E } = e.getBoundingClientRect(), c = e.dataset?.dotObject === "container", T = {
|
|
62
61
|
identifier: "TEMP_EMPTY_CONTENTLET",
|
|
63
62
|
title: "TEMP_EMPTY_CONTENTLET",
|
|
64
63
|
contentType: "TEMP_EMPTY_CONTENTLET_TYPE",
|
|
@@ -66,29 +65,32 @@ function B(o) {
|
|
|
66
65
|
widgetTitle: "TEMP_EMPTY_CONTENTLET",
|
|
67
66
|
baseType: "TEMP_EMPTY_CONTENTLET",
|
|
68
67
|
onNumberOfPages: 1
|
|
69
|
-
},
|
|
70
|
-
identifier:
|
|
71
|
-
title:
|
|
72
|
-
inode:
|
|
73
|
-
contentType:
|
|
74
|
-
baseType:
|
|
75
|
-
widgetTitle:
|
|
76
|
-
onNumberOfPages:
|
|
77
|
-
|
|
68
|
+
}, l = {
|
|
69
|
+
identifier: e.dataset?.dotIdentifier,
|
|
70
|
+
title: e.dataset?.dotTitle,
|
|
71
|
+
inode: e.dataset?.dotInode,
|
|
72
|
+
contentType: e.dataset?.dotType,
|
|
73
|
+
baseType: e.dataset?.dotBasetype,
|
|
74
|
+
widgetTitle: e.dataset?.dotWidgetTitle,
|
|
75
|
+
onNumberOfPages: e.dataset?.dotOnNumberOfPages,
|
|
76
|
+
...e.dataset?.dotStyleProperties && {
|
|
77
|
+
dotStyleProperties: JSON.parse(e.dataset.dotStyleProperties)
|
|
78
|
+
}
|
|
79
|
+
}, m = C(e), _ = {
|
|
78
80
|
container: (
|
|
79
81
|
// Here extract dot-container from contentlet if it is Headless
|
|
80
82
|
// or search in parent container if it is VTL
|
|
81
|
-
|
|
83
|
+
e.dataset?.dotContainer ? JSON.parse(e.dataset?.dotContainer) : g(e)
|
|
82
84
|
),
|
|
83
|
-
contentlet:
|
|
84
|
-
vtlFiles:
|
|
85
|
+
contentlet: c ? T : l,
|
|
86
|
+
vtlFiles: m
|
|
85
87
|
};
|
|
86
88
|
o({
|
|
87
89
|
x: i,
|
|
88
|
-
y:
|
|
89
|
-
width:
|
|
90
|
-
height:
|
|
91
|
-
payload:
|
|
90
|
+
y: d,
|
|
91
|
+
width: r,
|
|
92
|
+
height: E,
|
|
93
|
+
payload: _
|
|
92
94
|
});
|
|
93
95
|
};
|
|
94
96
|
return document.addEventListener("pointermove", t), {
|
|
@@ -99,9 +101,9 @@ function B(o) {
|
|
|
99
101
|
};
|
|
100
102
|
}
|
|
101
103
|
export {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
104
|
+
O as onContentChanges,
|
|
105
|
+
M as onContentletHovered,
|
|
106
|
+
S as onIframeScroll,
|
|
107
|
+
p as onPageReload,
|
|
108
|
+
b as onRequestBounds
|
|
107
109
|
};
|
|
@@ -1,80 +1,74 @@
|
|
|
1
1
|
import "../../internal/constants.js";
|
|
2
|
-
function
|
|
3
|
-
return t.map((
|
|
4
|
-
const
|
|
5
|
-
|
|
2
|
+
function c(t) {
|
|
3
|
+
return t.map((n) => {
|
|
4
|
+
const e = n.getBoundingClientRect(), o = Array.from(
|
|
5
|
+
n.querySelectorAll('[data-dot-object="contentlet"]')
|
|
6
6
|
);
|
|
7
7
|
return {
|
|
8
|
-
x:
|
|
9
|
-
y:
|
|
10
|
-
width:
|
|
11
|
-
height:
|
|
8
|
+
x: e.x,
|
|
9
|
+
y: e.y,
|
|
10
|
+
width: e.width,
|
|
11
|
+
height: e.height,
|
|
12
12
|
payload: JSON.stringify({
|
|
13
|
-
container:
|
|
13
|
+
container: a(n)
|
|
14
14
|
}),
|
|
15
|
-
contentlets:
|
|
15
|
+
contentlets: d(e, o)
|
|
16
16
|
};
|
|
17
17
|
});
|
|
18
18
|
}
|
|
19
|
-
function
|
|
20
|
-
return
|
|
21
|
-
|
|
22
|
-
const n = o.getBoundingClientRect();
|
|
19
|
+
function d(t, n) {
|
|
20
|
+
return n.map((e) => {
|
|
21
|
+
const o = e.getBoundingClientRect();
|
|
23
22
|
return {
|
|
24
23
|
x: 0,
|
|
25
|
-
y:
|
|
26
|
-
width:
|
|
27
|
-
height:
|
|
24
|
+
y: o.y - t.y,
|
|
25
|
+
width: o.width,
|
|
26
|
+
height: o.height,
|
|
28
27
|
payload: JSON.stringify({
|
|
29
|
-
container:
|
|
28
|
+
container: e.dataset?.dotContainer ? JSON.parse(e.dataset?.dotContainer) : r(e),
|
|
30
29
|
contentlet: {
|
|
31
|
-
identifier:
|
|
32
|
-
title:
|
|
33
|
-
inode:
|
|
34
|
-
contentType:
|
|
30
|
+
identifier: e.dataset?.dotIdentifier,
|
|
31
|
+
title: e.dataset?.dotTitle,
|
|
32
|
+
inode: e.dataset?.dotInode,
|
|
33
|
+
contentType: e.dataset?.dotType
|
|
35
34
|
}
|
|
36
35
|
})
|
|
37
36
|
};
|
|
38
37
|
});
|
|
39
38
|
}
|
|
40
|
-
function
|
|
41
|
-
var a, o, n, d;
|
|
39
|
+
function a(t) {
|
|
42
40
|
return {
|
|
43
|
-
acceptTypes:
|
|
44
|
-
identifier:
|
|
45
|
-
maxContentlets:
|
|
46
|
-
uuid:
|
|
41
|
+
acceptTypes: t.dataset?.dotAcceptTypes || "",
|
|
42
|
+
identifier: t.dataset?.dotIdentifier || "",
|
|
43
|
+
maxContentlets: t.dataset?.maxContentlets || "",
|
|
44
|
+
uuid: t.dataset?.dotUuid || ""
|
|
47
45
|
};
|
|
48
46
|
}
|
|
49
|
-
function
|
|
50
|
-
const
|
|
51
|
-
return
|
|
47
|
+
function r(t) {
|
|
48
|
+
const n = t.closest('[data-dot-object="container"]');
|
|
49
|
+
return n ? a(n) : (console.warn("No container found for the contentlet"), null);
|
|
52
50
|
}
|
|
53
|
-
function
|
|
54
|
-
var o, n, d;
|
|
51
|
+
function i(t) {
|
|
55
52
|
if (!t) return null;
|
|
56
|
-
const
|
|
57
|
-
return
|
|
58
|
-
|
|
59
|
-
|
|
53
|
+
const n = t.querySelector('[data-dot-object="empty-content"]');
|
|
54
|
+
return t?.dataset?.dotObject === "contentlet" || // The container inside Headless components have a span with the data-dot-object="container" attribute
|
|
55
|
+
t?.dataset?.dotObject === "container" && n || // The container inside Traditional have no content inside
|
|
56
|
+
t?.dataset?.dotObject === "container" && t.children.length === 0 ? t : i(t?.parentElement);
|
|
60
57
|
}
|
|
61
|
-
function
|
|
62
|
-
const
|
|
58
|
+
function u(t) {
|
|
59
|
+
const n = t.querySelectorAll(
|
|
63
60
|
'[data-dot-object="vtl-file"]'
|
|
64
61
|
);
|
|
65
|
-
return
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
name: (d = o.dataset) == null ? void 0 : d.dotUrl
|
|
70
|
-
};
|
|
71
|
-
}) : null;
|
|
62
|
+
return n.length ? Array.from(n).map((e) => ({
|
|
63
|
+
inode: e.dataset?.dotInode,
|
|
64
|
+
name: e.dataset?.dotUrl
|
|
65
|
+
})) : null;
|
|
72
66
|
}
|
|
73
67
|
export {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
68
|
+
i as findDotCMSElement,
|
|
69
|
+
u as findDotCMSVTLData,
|
|
70
|
+
r as getClosestDotCMSContainerData,
|
|
71
|
+
a as getDotCMSContainerData,
|
|
72
|
+
d as getDotCMSContentletsBound,
|
|
73
|
+
c as getDotCMSPageBounds
|
|
80
74
|
};
|