@coframe/sdk 1.1.40 → 1.1.42
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/pkg/cf.cjs.js +382 -24
- package/dist/pkg/cf.esm.mjs +382 -24
- package/dist/pkg/types/index.d.ts +5 -0
- package/dist/pkg/types/react.d.ts +5 -0
- package/dist/pkg/types/server.d.ts +5 -0
- package/package.json +1 -1
package/dist/pkg/cf.cjs.js
CHANGED
|
@@ -1105,6 +1105,9 @@ let waitingForCookies = false;
|
|
|
1105
1105
|
const setWaitingForCookies = (value) => {
|
|
1106
1106
|
waitingForCookies = value;
|
|
1107
1107
|
};
|
|
1108
|
+
function isWaitingForCookies() {
|
|
1109
|
+
return waitingForCookies;
|
|
1110
|
+
}
|
|
1108
1111
|
let frameActivated = false;
|
|
1109
1112
|
const setFrameActivated = (value) => {
|
|
1110
1113
|
frameActivated = value;
|
|
@@ -1125,7 +1128,7 @@ function warnEventsNotSent() {
|
|
|
1125
1128
|
}
|
|
1126
1129
|
}
|
|
1127
1130
|
|
|
1128
|
-
const SDK_VERSION = '2.
|
|
1131
|
+
const SDK_VERSION = '2.9.0';
|
|
1129
1132
|
const queuedEvents = [];
|
|
1130
1133
|
const queuedMonitoringEvents = [];
|
|
1131
1134
|
const queuedSessions = [];
|
|
@@ -1230,7 +1233,7 @@ function flushQueuedEvents(projectId) {
|
|
|
1230
1233
|
queuedSessions.length = 0;
|
|
1231
1234
|
}
|
|
1232
1235
|
}
|
|
1233
|
-
function queueEvent(coframe, sessionInfo) {
|
|
1236
|
+
function queueEvent(coframe, sessionInfo, heatmap) {
|
|
1234
1237
|
const { projectId, sessionId, eventType, orgId, userToken } = sessionInfo;
|
|
1235
1238
|
const data = {
|
|
1236
1239
|
type: eventType,
|
|
@@ -1242,13 +1245,19 @@ function queueEvent(coframe, sessionInfo) {
|
|
|
1242
1245
|
user_token: userToken,
|
|
1243
1246
|
};
|
|
1244
1247
|
const seg = sessionInfo.personalizationHeaders;
|
|
1245
|
-
const metadata = seg
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1248
|
+
const metadata = seg
|
|
1249
|
+
? { personalization_headers: { ...seg } }
|
|
1250
|
+
: {};
|
|
1251
|
+
if (heatmap === null || heatmap === void 0 ? void 0 : heatmap.hm)
|
|
1252
|
+
metadata.hm = heatmap.hm;
|
|
1253
|
+
data.content =
|
|
1254
|
+
eventType === 'page_view'
|
|
1255
|
+
? {
|
|
1256
|
+
universal_selector: {},
|
|
1257
|
+
metadata,
|
|
1258
|
+
screen_size: { width: window.innerWidth, height: window.innerHeight },
|
|
1259
|
+
}
|
|
1260
|
+
: { metadata, ...heatmap === null || heatmap === void 0 ? void 0 : heatmap.content };
|
|
1252
1261
|
queueEventForBatchedSending(coframe, data);
|
|
1253
1262
|
}
|
|
1254
1263
|
function queueVariantViewEvent(coframe, { projectId, sessionId, orgId, userToken, experimentId, variantId, }) {
|
|
@@ -1263,7 +1272,7 @@ function queueVariantViewEvent(coframe, { projectId, sessionId, orgId, userToken
|
|
|
1263
1272
|
user_token: userToken,
|
|
1264
1273
|
});
|
|
1265
1274
|
}
|
|
1266
|
-
function sendPageEngagementEvent(coframe, eventType, event, { projectId, sessionId, duration = 0, userToken, personalizationHeaders, }) {
|
|
1275
|
+
function sendPageEngagementEvent(coframe, eventType, event, { projectId, sessionId, orgId, duration = 0, userToken, personalizationHeaders, collect, }) {
|
|
1267
1276
|
var _a;
|
|
1268
1277
|
if (event
|
|
1269
1278
|
.composedPath()
|
|
@@ -1286,6 +1295,7 @@ function sendPageEngagementEvent(coframe, eventType, event, { projectId, session
|
|
|
1286
1295
|
session_id: sessionId,
|
|
1287
1296
|
time: new Date(),
|
|
1288
1297
|
url: getCurrentPageUrl(),
|
|
1298
|
+
org_id: orgId,
|
|
1289
1299
|
user_token: userToken,
|
|
1290
1300
|
content: {
|
|
1291
1301
|
universal_selector: getSelector(targetElement, {
|
|
@@ -1308,7 +1318,10 @@ function sendPageEngagementEvent(coframe, eventType, event, { projectId, session
|
|
|
1308
1318
|
}),
|
|
1309
1319
|
},
|
|
1310
1320
|
};
|
|
1311
|
-
|
|
1321
|
+
const isConversion = Boolean(metricIds === null || metricIds === void 0 ? void 0 : metricIds.length);
|
|
1322
|
+
if (!(collect === null || collect === void 0 ? void 0 : collect(data, realEventTarget, event, isConversion))) {
|
|
1323
|
+
queueEventForBatchedSending(coframe, data, isConversion);
|
|
1324
|
+
}
|
|
1312
1325
|
const processingDuration = performance.now() - startTime;
|
|
1313
1326
|
if (coframe.status) {
|
|
1314
1327
|
if (!coframe.status.events) {
|
|
@@ -3382,6 +3395,235 @@ function notifyEventsFlushed() {
|
|
|
3382
3395
|
}
|
|
3383
3396
|
}
|
|
3384
3397
|
|
|
3398
|
+
const DEFAULT_BLOCK_SELECTOR = '[data-cf-block],.cf-block';
|
|
3399
|
+
const INTERACTIVE_SELECTOR = 'a,button,input,select,textarea,label,summary,[href],[onclick],[contenteditable],[tabindex]:not([tabindex="-1"]),[role=button],[role=link],[role=tab],[role=checkbox],[role=menuitem]';
|
|
3400
|
+
const HOLD_MS = 1000;
|
|
3401
|
+
const RAGE_WINDOW_MS = 700;
|
|
3402
|
+
const RAGE_RADIUS_PX = 30;
|
|
3403
|
+
const RAGE_CLICKS = 3;
|
|
3404
|
+
let enabled = false;
|
|
3405
|
+
let allPages = false;
|
|
3406
|
+
let coframe = null;
|
|
3407
|
+
let blockSelector = DEFAULT_BLOCK_SELECTOR;
|
|
3408
|
+
const held = [];
|
|
3409
|
+
let recent = [];
|
|
3410
|
+
let lastActivity = 0;
|
|
3411
|
+
let observer = null;
|
|
3412
|
+
let pageView = '';
|
|
3413
|
+
let maxDepth = 0;
|
|
3414
|
+
let engagedMs = 0;
|
|
3415
|
+
let visibleSince = null;
|
|
3416
|
+
let navigated = false;
|
|
3417
|
+
function meta(name) {
|
|
3418
|
+
const tag = document.querySelector(`meta[name="coframe:${name}"]`);
|
|
3419
|
+
return (tag === null || tag === void 0 ? void 0 : tag.getAttribute('content')) || undefined;
|
|
3420
|
+
}
|
|
3421
|
+
function heatmapActive() {
|
|
3422
|
+
return enabled && (allPages || !!meta('page'));
|
|
3423
|
+
}
|
|
3424
|
+
function pageFields(withHeight) {
|
|
3425
|
+
const fields = {
|
|
3426
|
+
page: meta('page'),
|
|
3427
|
+
ver: meta('version'),
|
|
3428
|
+
variant: meta('variant'),
|
|
3429
|
+
row: meta('row'),
|
|
3430
|
+
};
|
|
3431
|
+
if (withHeight)
|
|
3432
|
+
fields.doc_h = document.documentElement.scrollHeight;
|
|
3433
|
+
return fields;
|
|
3434
|
+
}
|
|
3435
|
+
function round3(value) {
|
|
3436
|
+
return Math.round(Math.min(1, Math.max(0, value)) * 1000) / 1000;
|
|
3437
|
+
}
|
|
3438
|
+
function markActivity() {
|
|
3439
|
+
lastActivity = Date.now();
|
|
3440
|
+
}
|
|
3441
|
+
function viewportBottom() {
|
|
3442
|
+
return Math.round(window.scrollY + window.innerHeight);
|
|
3443
|
+
}
|
|
3444
|
+
function restartCounters(depth) {
|
|
3445
|
+
maxDepth = depth;
|
|
3446
|
+
engagedMs = 0;
|
|
3447
|
+
visibleSince = document.hidden ? null : Date.now();
|
|
3448
|
+
}
|
|
3449
|
+
function syncPageView() {
|
|
3450
|
+
if (!coframe || coframe.sessionId === pageView)
|
|
3451
|
+
return;
|
|
3452
|
+
pageView = coframe.sessionId;
|
|
3453
|
+
if (navigated)
|
|
3454
|
+
navigated = false;
|
|
3455
|
+
else
|
|
3456
|
+
restartCounters(viewportBottom());
|
|
3457
|
+
}
|
|
3458
|
+
function onScroll() {
|
|
3459
|
+
markActivity();
|
|
3460
|
+
syncPageView();
|
|
3461
|
+
maxDepth = Math.max(maxDepth, viewportBottom());
|
|
3462
|
+
}
|
|
3463
|
+
function onVisibility() {
|
|
3464
|
+
if (document.hidden) {
|
|
3465
|
+
if (visibleSince !== null)
|
|
3466
|
+
engagedMs += Date.now() - visibleSince;
|
|
3467
|
+
visibleSince = null;
|
|
3468
|
+
releaseHeldClicks();
|
|
3469
|
+
}
|
|
3470
|
+
else if (visibleSince === null) {
|
|
3471
|
+
visibleSince = Date.now();
|
|
3472
|
+
}
|
|
3473
|
+
}
|
|
3474
|
+
function readBlockSelector(selector) {
|
|
3475
|
+
if (typeof selector !== 'string' || !selector)
|
|
3476
|
+
return DEFAULT_BLOCK_SELECTOR;
|
|
3477
|
+
try {
|
|
3478
|
+
document.createElement('div').matches(selector);
|
|
3479
|
+
return selector;
|
|
3480
|
+
}
|
|
3481
|
+
catch (_a) {
|
|
3482
|
+
return DEFAULT_BLOCK_SELECTOR;
|
|
3483
|
+
}
|
|
3484
|
+
}
|
|
3485
|
+
function startHeatmaps(target, project) {
|
|
3486
|
+
var _a, _b;
|
|
3487
|
+
const settings = (_a = project === null || project === void 0 ? void 0 : project.settings) === null || _a === void 0 ? void 0 : _a.heatmaps;
|
|
3488
|
+
if (enabled || !(settings === null || settings === void 0 ? void 0 : settings.enabled))
|
|
3489
|
+
return;
|
|
3490
|
+
enabled = true;
|
|
3491
|
+
allPages = !!settings.all_pages;
|
|
3492
|
+
blockSelector = readBlockSelector((_b = project.settings.session_replay) === null || _b === void 0 ? void 0 : _b.block_selector);
|
|
3493
|
+
coframe = target;
|
|
3494
|
+
syncPageView();
|
|
3495
|
+
document.addEventListener('scroll', onScroll, {
|
|
3496
|
+
capture: true,
|
|
3497
|
+
passive: true,
|
|
3498
|
+
});
|
|
3499
|
+
document.addEventListener('visibilitychange', onVisibility);
|
|
3500
|
+
window.addEventListener('pagehide', releaseHeldClicks);
|
|
3501
|
+
window.addEventListener('beforeunload', releaseHeldClicks);
|
|
3502
|
+
}
|
|
3503
|
+
function leaveFields() {
|
|
3504
|
+
if (!heatmapActive())
|
|
3505
|
+
return undefined;
|
|
3506
|
+
syncPageView();
|
|
3507
|
+
if (navigated)
|
|
3508
|
+
return undefined;
|
|
3509
|
+
return {
|
|
3510
|
+
content: {
|
|
3511
|
+
scroll_depth: Math.max(maxDepth, viewportBottom()),
|
|
3512
|
+
'duration-ms': Math.round(engagedMs + (visibleSince === null ? 0 : Date.now() - visibleSince)),
|
|
3513
|
+
},
|
|
3514
|
+
hm: pageFields(true),
|
|
3515
|
+
};
|
|
3516
|
+
}
|
|
3517
|
+
function pageLeaveFields() {
|
|
3518
|
+
if (!enabled)
|
|
3519
|
+
return undefined;
|
|
3520
|
+
const fields = leaveFields();
|
|
3521
|
+
restartCounters(0);
|
|
3522
|
+
navigated = true;
|
|
3523
|
+
return fields;
|
|
3524
|
+
}
|
|
3525
|
+
function watchMutations() {
|
|
3526
|
+
if (observer || typeof MutationObserver !== 'function')
|
|
3527
|
+
return;
|
|
3528
|
+
observer = new MutationObserver(markActivity);
|
|
3529
|
+
observer.observe(document.documentElement, {
|
|
3530
|
+
attributes: true,
|
|
3531
|
+
characterData: true,
|
|
3532
|
+
childList: true,
|
|
3533
|
+
subtree: true,
|
|
3534
|
+
});
|
|
3535
|
+
}
|
|
3536
|
+
function settle(click) {
|
|
3537
|
+
const index = held.indexOf(click);
|
|
3538
|
+
if (index < 0)
|
|
3539
|
+
return;
|
|
3540
|
+
held.splice(index, 1);
|
|
3541
|
+
if (click.hm.kind !== 'rage') {
|
|
3542
|
+
const dead = click.candidate &&
|
|
3543
|
+
lastActivity < click.t &&
|
|
3544
|
+
document.activeElement === click.focused &&
|
|
3545
|
+
location.href === click.href;
|
|
3546
|
+
click.hm.kind = dead ? 'dead' : 'click';
|
|
3547
|
+
}
|
|
3548
|
+
if (coframe)
|
|
3549
|
+
queueEventForBatchedSending(coframe, click.data);
|
|
3550
|
+
if (observer && !held.some((h) => h.candidate)) {
|
|
3551
|
+
observer.disconnect();
|
|
3552
|
+
observer = null;
|
|
3553
|
+
}
|
|
3554
|
+
}
|
|
3555
|
+
function releaseHeldClicks() {
|
|
3556
|
+
for (const click of held.splice(0)) {
|
|
3557
|
+
if (click.hm.kind === undefined)
|
|
3558
|
+
click.hm.kind = null;
|
|
3559
|
+
if (coframe)
|
|
3560
|
+
queueEventForBatchedSending(coframe, click.data);
|
|
3561
|
+
}
|
|
3562
|
+
if (observer) {
|
|
3563
|
+
observer.disconnect();
|
|
3564
|
+
observer = null;
|
|
3565
|
+
}
|
|
3566
|
+
}
|
|
3567
|
+
function copyKey(node, id) {
|
|
3568
|
+
const items = [];
|
|
3569
|
+
for (let at = node; at; at = at.parentElement) {
|
|
3570
|
+
const item = at.getAttribute('data-el-item');
|
|
3571
|
+
if (item)
|
|
3572
|
+
items.unshift(item);
|
|
3573
|
+
}
|
|
3574
|
+
return items.length ? `${id}~${items.join('.')}` : id;
|
|
3575
|
+
}
|
|
3576
|
+
function collectClick(data, target, event, isConversion) {
|
|
3577
|
+
if (!target.closest || target.closest(blockSelector))
|
|
3578
|
+
return false;
|
|
3579
|
+
const content = data.content;
|
|
3580
|
+
const position = content.position;
|
|
3581
|
+
const hm = pageFields(true);
|
|
3582
|
+
const anchor = target.closest('[data-el]');
|
|
3583
|
+
if (anchor) {
|
|
3584
|
+
const id = anchor.getAttribute('data-el');
|
|
3585
|
+
hm.el = id ? copyKey(anchor, id) : undefined;
|
|
3586
|
+
const rect = anchor.getBoundingClientRect();
|
|
3587
|
+
if (rect.width > 0 && rect.height > 0) {
|
|
3588
|
+
hm.fx = round3((event.clientX - rect.left) / rect.width);
|
|
3589
|
+
hm.fy = round3((event.clientY - rect.top) / rect.height);
|
|
3590
|
+
}
|
|
3591
|
+
}
|
|
3592
|
+
content.metadata = {
|
|
3593
|
+
...content.metadata,
|
|
3594
|
+
hm,
|
|
3595
|
+
};
|
|
3596
|
+
const now = Date.now();
|
|
3597
|
+
const click = {
|
|
3598
|
+
data,
|
|
3599
|
+
hm,
|
|
3600
|
+
x: position.x,
|
|
3601
|
+
y: position.y,
|
|
3602
|
+
t: now,
|
|
3603
|
+
candidate: !target.closest(INTERACTIVE_SELECTOR),
|
|
3604
|
+
focused: document.activeElement,
|
|
3605
|
+
href: location.href,
|
|
3606
|
+
};
|
|
3607
|
+
recent = recent.filter((r) => now - r.t <= RAGE_WINDOW_MS);
|
|
3608
|
+
recent.push(click);
|
|
3609
|
+
const cluster = recent.filter((r) => Math.abs(r.x - click.x) <= RAGE_RADIUS_PX &&
|
|
3610
|
+
Math.abs(r.y - click.y) <= RAGE_RADIUS_PX);
|
|
3611
|
+
if (cluster.length >= RAGE_CLICKS) {
|
|
3612
|
+
for (const r of cluster)
|
|
3613
|
+
r.hm.kind = 'rage';
|
|
3614
|
+
}
|
|
3615
|
+
if (isConversion) {
|
|
3616
|
+
if (hm.kind === undefined)
|
|
3617
|
+
hm.kind = null;
|
|
3618
|
+
return false;
|
|
3619
|
+
}
|
|
3620
|
+
held.push(click);
|
|
3621
|
+
if (click.candidate)
|
|
3622
|
+
watchMutations();
|
|
3623
|
+
setTimeout(() => settle(click), HOLD_MS);
|
|
3624
|
+
return true;
|
|
3625
|
+
}
|
|
3626
|
+
|
|
3385
3627
|
function startSession(Coframe, cookiesEnabled, executionStartTime, personalizationHeaders, sessionContext, pageUrl = getCurrentPageUrl()) {
|
|
3386
3628
|
const sessionPayload = [
|
|
3387
3629
|
Coframe,
|
|
@@ -3408,7 +3650,7 @@ function startSession(Coframe, cookiesEnabled, executionStartTime, personalizati
|
|
|
3408
3650
|
orgId: Coframe.orgId,
|
|
3409
3651
|
userToken: Coframe.userToken,
|
|
3410
3652
|
personalizationHeaders,
|
|
3411
|
-
});
|
|
3653
|
+
}, heatmapActive() ? { hm: pageFields(false) } : undefined);
|
|
3412
3654
|
}
|
|
3413
3655
|
function reportInitTiming(Coframe, project, integrationStartTime, executionStartTime) {
|
|
3414
3656
|
var _a;
|
|
@@ -3641,20 +3883,15 @@ function setupListeners(Coframe, executionStartTime) {
|
|
|
3641
3883
|
sendPageEngagementEvent(Coframe, 'click', event, {
|
|
3642
3884
|
projectId: Coframe.projectId,
|
|
3643
3885
|
sessionId: Coframe.sessionId,
|
|
3886
|
+
orgId: Coframe.orgId,
|
|
3644
3887
|
userToken: Coframe.userToken,
|
|
3645
3888
|
personalizationHeaders: Coframe.personalizationHeaders,
|
|
3889
|
+
collect: heatmapActive() ? collectClick : undefined,
|
|
3646
3890
|
});
|
|
3647
3891
|
};
|
|
3648
3892
|
document.addEventListener('click', handleClick, true);
|
|
3649
3893
|
const handleEventFlush = debounce((eventType) => {
|
|
3650
|
-
|
|
3651
|
-
projectId: Coframe.projectId,
|
|
3652
|
-
sessionId: Coframe.sessionId,
|
|
3653
|
-
eventType: eventType,
|
|
3654
|
-
orgId: Coframe.orgId,
|
|
3655
|
-
userToken: Coframe.userToken,
|
|
3656
|
-
personalizationHeaders: Coframe.personalizationHeaders,
|
|
3657
|
-
});
|
|
3894
|
+
queueLeaveEvent(Coframe, eventType, eventType === 'tab_show' ? undefined : leaveFields());
|
|
3658
3895
|
flushQueuedEvents(Coframe.projectId);
|
|
3659
3896
|
notifyEventsFlushed();
|
|
3660
3897
|
}, 1);
|
|
@@ -3666,11 +3903,27 @@ function setupListeners(Coframe, executionStartTime) {
|
|
|
3666
3903
|
handleEventFlush(eventType);
|
|
3667
3904
|
});
|
|
3668
3905
|
}
|
|
3906
|
+
function queueLeaveEvent(Coframe, eventType, fields) {
|
|
3907
|
+
queueEvent(Coframe, {
|
|
3908
|
+
projectId: Coframe.projectId,
|
|
3909
|
+
sessionId: Coframe.sessionId,
|
|
3910
|
+
eventType,
|
|
3911
|
+
orgId: Coframe.orgId,
|
|
3912
|
+
userToken: Coframe.userToken,
|
|
3913
|
+
personalizationHeaders: Coframe.personalizationHeaders,
|
|
3914
|
+
}, fields);
|
|
3915
|
+
}
|
|
3916
|
+
function sendPageLeave(Coframe) {
|
|
3917
|
+
const fields = pageLeaveFields();
|
|
3918
|
+
if (fields)
|
|
3919
|
+
queueLeaveEvent(Coframe, 'page_leave', fields);
|
|
3920
|
+
}
|
|
3669
3921
|
function setupTracking(Coframe, projectResult, previewVariantId, executionStartTime, nonce, waitForCookiesEnabled, onConsentChange) {
|
|
3670
3922
|
var _a, _b;
|
|
3671
3923
|
const logger = Coframe.logger;
|
|
3672
3924
|
const { project } = projectResult;
|
|
3673
3925
|
setTrackOnlyActivatedFrames(!!((_a = project === null || project === void 0 ? void 0 : project.settings) === null || _a === void 0 ? void 0 : _a.track_only_activated_frames));
|
|
3926
|
+
startHeatmaps(Coframe, project);
|
|
3674
3927
|
const analytics = createTreatmentAnalytics(Coframe, previewVariantId);
|
|
3675
3928
|
setupListeners(Coframe, executionStartTime);
|
|
3676
3929
|
const managedAnalyticsCallback = (_b = project === null || project === void 0 ? void 0 : project.settings) === null || _b === void 0 ? void 0 : _b.analytics_callback;
|
|
@@ -3786,6 +4039,7 @@ function setupSPANavigation(Coframe, project, config, previewVariantId, isSessio
|
|
|
3786
4039
|
let navigationAbortController = null;
|
|
3787
4040
|
observeUrlChanges(false, async (newPageUrl, _oldPageUrl) => {
|
|
3788
4041
|
var _a;
|
|
4042
|
+
sendPageLeave(Coframe);
|
|
3789
4043
|
if (navigationAbortController)
|
|
3790
4044
|
navigationAbortController.abort();
|
|
3791
4045
|
navigationAbortController = new AbortController();
|
|
@@ -3934,11 +4188,90 @@ async function modifyPage(Coframe, configResult, projectResult, analytics) {
|
|
|
3934
4188
|
setupFlushInterval(Coframe);
|
|
3935
4189
|
}
|
|
3936
4190
|
|
|
4191
|
+
function readClientCommand() {
|
|
4192
|
+
try {
|
|
4193
|
+
const cmd = findLastCmd((c) => typeof c.cookiesEnabled === 'boolean');
|
|
4194
|
+
if (!cmd)
|
|
4195
|
+
return undefined;
|
|
4196
|
+
return cmd.cookiesEnabled === true ? 'granted' : 'denied';
|
|
4197
|
+
}
|
|
4198
|
+
catch (_a) {
|
|
4199
|
+
return undefined;
|
|
4200
|
+
}
|
|
4201
|
+
}
|
|
4202
|
+
function readOneTrust() {
|
|
4203
|
+
var _a;
|
|
4204
|
+
try {
|
|
4205
|
+
const { OnetrustActiveGroups: groups, OneTrust } = window;
|
|
4206
|
+
if (typeof groups !== 'string' && OneTrust === undefined)
|
|
4207
|
+
return undefined;
|
|
4208
|
+
if (typeof groups === 'string' && groups.split(',').indexOf('C0002') !== -1)
|
|
4209
|
+
return 'granted';
|
|
4210
|
+
return ((_a = OneTrust === null || OneTrust === void 0 ? void 0 : OneTrust.IsAlertBoxClosed) === null || _a === void 0 ? void 0 : _a.call(OneTrust)) === true ? 'denied' : 'pending';
|
|
4211
|
+
}
|
|
4212
|
+
catch (_b) {
|
|
4213
|
+
return undefined;
|
|
4214
|
+
}
|
|
4215
|
+
}
|
|
4216
|
+
function readCookiebot() {
|
|
4217
|
+
var _a;
|
|
4218
|
+
try {
|
|
4219
|
+
const { Cookiebot } = window;
|
|
4220
|
+
if (Cookiebot === undefined)
|
|
4221
|
+
return undefined;
|
|
4222
|
+
if (((_a = Cookiebot.consent) === null || _a === void 0 ? void 0 : _a.statistics) === true)
|
|
4223
|
+
return 'granted';
|
|
4224
|
+
return Cookiebot.hasResponse === true ? 'denied' : 'pending';
|
|
4225
|
+
}
|
|
4226
|
+
catch (_b) {
|
|
4227
|
+
return undefined;
|
|
4228
|
+
}
|
|
4229
|
+
}
|
|
4230
|
+
function readConsentMode() {
|
|
4231
|
+
var _a;
|
|
4232
|
+
try {
|
|
4233
|
+
const { dataLayer } = window;
|
|
4234
|
+
if (!Array.isArray(dataLayer))
|
|
4235
|
+
return undefined;
|
|
4236
|
+
let update;
|
|
4237
|
+
let defaultGranted = false;
|
|
4238
|
+
let defaultDenied = false;
|
|
4239
|
+
for (let i = 0; i < dataLayer.length; i++) {
|
|
4240
|
+
const entry = dataLayer[i];
|
|
4241
|
+
if (entry === null ||
|
|
4242
|
+
typeof entry !== 'object' ||
|
|
4243
|
+
entry[0] !== 'consent' ||
|
|
4244
|
+
(entry[1] !== 'default' && entry[1] !== 'update')) {
|
|
4245
|
+
continue;
|
|
4246
|
+
}
|
|
4247
|
+
const storage = (_a = entry[2]) === null || _a === void 0 ? void 0 : _a.analytics_storage;
|
|
4248
|
+
if (storage !== 'granted' && storage !== 'denied')
|
|
4249
|
+
continue;
|
|
4250
|
+
if (entry[1] === 'update')
|
|
4251
|
+
update = storage;
|
|
4252
|
+
else if (storage === 'denied')
|
|
4253
|
+
defaultDenied = true;
|
|
4254
|
+
else
|
|
4255
|
+
defaultGranted = true;
|
|
4256
|
+
}
|
|
4257
|
+
if (update !== undefined)
|
|
4258
|
+
return update;
|
|
4259
|
+
if (defaultDenied)
|
|
4260
|
+
return 'pending';
|
|
4261
|
+
return defaultGranted ? 'granted' : undefined;
|
|
4262
|
+
}
|
|
4263
|
+
catch (_b) {
|
|
4264
|
+
return undefined;
|
|
4265
|
+
}
|
|
4266
|
+
}
|
|
4267
|
+
|
|
3937
4268
|
let startRequested = false;
|
|
3938
4269
|
let replayScriptUrl;
|
|
3939
4270
|
const COMPILED_REPLAY_SCRIPT_URL = `${"https://edge.cofra.me"}/replay/latest.js`;
|
|
3940
4271
|
const CONSENT_POLL_MS = 100;
|
|
3941
4272
|
const CONSENT_WAIT_MS = 5000;
|
|
4273
|
+
const CONSENT_DETECT_WAIT_MS = 10000;
|
|
4274
|
+
const EXPLICIT_CONSENT_WAIT_MS = 60000;
|
|
3942
4275
|
function configureReplayScriptUrl(url) {
|
|
3943
4276
|
replayScriptUrl = (url === null || url === void 0 ? void 0 : url.trim()) || undefined;
|
|
3944
4277
|
}
|
|
@@ -3949,8 +4282,25 @@ function readReplayConsent() {
|
|
|
3949
4282
|
return { state: 'denied', reason: 'gpc' };
|
|
3950
4283
|
}
|
|
3951
4284
|
const shopify = window.Shopify;
|
|
3952
|
-
if (shopify === undefined)
|
|
3953
|
-
|
|
4285
|
+
if (shopify === undefined) {
|
|
4286
|
+
const readers = [
|
|
4287
|
+
[readClientCommand, 'client'],
|
|
4288
|
+
[readOneTrust, 'onetrust'],
|
|
4289
|
+
[readCookiebot, 'cookiebot'],
|
|
4290
|
+
[readConsentMode, 'consent_mode'],
|
|
4291
|
+
];
|
|
4292
|
+
for (let i = 0; i < readers.length; i++) {
|
|
4293
|
+
const [read, source] = readers[i];
|
|
4294
|
+
const signal = read();
|
|
4295
|
+
if (signal === 'granted')
|
|
4296
|
+
return { state: 'allowed', source };
|
|
4297
|
+
if (signal === 'denied')
|
|
4298
|
+
return { state: 'denied', reason: 'consent_denied' };
|
|
4299
|
+
if (signal === 'pending')
|
|
4300
|
+
return { state: 'pending', detected: true };
|
|
4301
|
+
}
|
|
4302
|
+
return { state: 'pending', detected: isWaitingForCookies() };
|
|
4303
|
+
}
|
|
3954
4304
|
const customerPrivacy = shopify.customerPrivacy;
|
|
3955
4305
|
const analyticsProcessingAllowed = customerPrivacy === null || customerPrivacy === void 0 ? void 0 : customerPrivacy.analyticsProcessingAllowed;
|
|
3956
4306
|
if (typeof analyticsProcessingAllowed === 'function') {
|
|
@@ -4052,11 +4402,14 @@ function startReplayIfEnabled(coframe, project, nonce) {
|
|
|
4052
4402
|
const settings = (_a = project.settings) === null || _a === void 0 ? void 0 : _a.session_replay;
|
|
4053
4403
|
if ((settings === null || settings === void 0 ? void 0 : settings.enabled) !== true ||
|
|
4054
4404
|
typeof CompressionStream !== 'function' ||
|
|
4055
|
-
!shouldSendEvents(
|
|
4405
|
+
!shouldSendEvents({
|
|
4406
|
+
ignoreConsent: window.Shopify === undefined,
|
|
4407
|
+
}) ||
|
|
4056
4408
|
startRequested) {
|
|
4057
4409
|
return;
|
|
4058
4410
|
}
|
|
4059
4411
|
startRequested = true;
|
|
4412
|
+
const isShopify = window.Shopify !== undefined;
|
|
4060
4413
|
let waited = 0;
|
|
4061
4414
|
const decide = () => {
|
|
4062
4415
|
var _a;
|
|
@@ -4067,7 +4420,12 @@ function startReplayIfEnabled(coframe, project, nonce) {
|
|
|
4067
4420
|
else if (consent.state === 'denied') {
|
|
4068
4421
|
reportReplaySkipped(coframe, consent.reason);
|
|
4069
4422
|
}
|
|
4070
|
-
else if (
|
|
4423
|
+
else if (!isShopify &&
|
|
4424
|
+
consent.detected !== true &&
|
|
4425
|
+
waited >= CONSENT_DETECT_WAIT_MS) {
|
|
4426
|
+
reportReplaySkipped(coframe, 'consent_not_configured');
|
|
4427
|
+
}
|
|
4428
|
+
else if (waited >= (isShopify ? CONSENT_WAIT_MS : EXPLICIT_CONSENT_WAIT_MS)) {
|
|
4071
4429
|
reportReplaySkipped(coframe, 'consent_unavailable');
|
|
4072
4430
|
}
|
|
4073
4431
|
else {
|
package/dist/pkg/cf.esm.mjs
CHANGED
|
@@ -1103,6 +1103,9 @@ let waitingForCookies = false;
|
|
|
1103
1103
|
const setWaitingForCookies = (value) => {
|
|
1104
1104
|
waitingForCookies = value;
|
|
1105
1105
|
};
|
|
1106
|
+
function isWaitingForCookies() {
|
|
1107
|
+
return waitingForCookies;
|
|
1108
|
+
}
|
|
1106
1109
|
let frameActivated = false;
|
|
1107
1110
|
const setFrameActivated = (value) => {
|
|
1108
1111
|
frameActivated = value;
|
|
@@ -1123,7 +1126,7 @@ function warnEventsNotSent() {
|
|
|
1123
1126
|
}
|
|
1124
1127
|
}
|
|
1125
1128
|
|
|
1126
|
-
const SDK_VERSION = '2.
|
|
1129
|
+
const SDK_VERSION = '2.9.0';
|
|
1127
1130
|
const queuedEvents = [];
|
|
1128
1131
|
const queuedMonitoringEvents = [];
|
|
1129
1132
|
const queuedSessions = [];
|
|
@@ -1228,7 +1231,7 @@ function flushQueuedEvents(projectId) {
|
|
|
1228
1231
|
queuedSessions.length = 0;
|
|
1229
1232
|
}
|
|
1230
1233
|
}
|
|
1231
|
-
function queueEvent(coframe, sessionInfo) {
|
|
1234
|
+
function queueEvent(coframe, sessionInfo, heatmap) {
|
|
1232
1235
|
const { projectId, sessionId, eventType, orgId, userToken } = sessionInfo;
|
|
1233
1236
|
const data = {
|
|
1234
1237
|
type: eventType,
|
|
@@ -1240,13 +1243,19 @@ function queueEvent(coframe, sessionInfo) {
|
|
|
1240
1243
|
user_token: userToken,
|
|
1241
1244
|
};
|
|
1242
1245
|
const seg = sessionInfo.personalizationHeaders;
|
|
1243
|
-
const metadata = seg
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1246
|
+
const metadata = seg
|
|
1247
|
+
? { personalization_headers: { ...seg } }
|
|
1248
|
+
: {};
|
|
1249
|
+
if (heatmap === null || heatmap === void 0 ? void 0 : heatmap.hm)
|
|
1250
|
+
metadata.hm = heatmap.hm;
|
|
1251
|
+
data.content =
|
|
1252
|
+
eventType === 'page_view'
|
|
1253
|
+
? {
|
|
1254
|
+
universal_selector: {},
|
|
1255
|
+
metadata,
|
|
1256
|
+
screen_size: { width: window.innerWidth, height: window.innerHeight },
|
|
1257
|
+
}
|
|
1258
|
+
: { metadata, ...heatmap === null || heatmap === void 0 ? void 0 : heatmap.content };
|
|
1250
1259
|
queueEventForBatchedSending(coframe, data);
|
|
1251
1260
|
}
|
|
1252
1261
|
function queueVariantViewEvent(coframe, { projectId, sessionId, orgId, userToken, experimentId, variantId, }) {
|
|
@@ -1261,7 +1270,7 @@ function queueVariantViewEvent(coframe, { projectId, sessionId, orgId, userToken
|
|
|
1261
1270
|
user_token: userToken,
|
|
1262
1271
|
});
|
|
1263
1272
|
}
|
|
1264
|
-
function sendPageEngagementEvent(coframe, eventType, event, { projectId, sessionId, duration = 0, userToken, personalizationHeaders, }) {
|
|
1273
|
+
function sendPageEngagementEvent(coframe, eventType, event, { projectId, sessionId, orgId, duration = 0, userToken, personalizationHeaders, collect, }) {
|
|
1265
1274
|
var _a;
|
|
1266
1275
|
if (event
|
|
1267
1276
|
.composedPath()
|
|
@@ -1284,6 +1293,7 @@ function sendPageEngagementEvent(coframe, eventType, event, { projectId, session
|
|
|
1284
1293
|
session_id: sessionId,
|
|
1285
1294
|
time: new Date(),
|
|
1286
1295
|
url: getCurrentPageUrl(),
|
|
1296
|
+
org_id: orgId,
|
|
1287
1297
|
user_token: userToken,
|
|
1288
1298
|
content: {
|
|
1289
1299
|
universal_selector: getSelector(targetElement, {
|
|
@@ -1306,7 +1316,10 @@ function sendPageEngagementEvent(coframe, eventType, event, { projectId, session
|
|
|
1306
1316
|
}),
|
|
1307
1317
|
},
|
|
1308
1318
|
};
|
|
1309
|
-
|
|
1319
|
+
const isConversion = Boolean(metricIds === null || metricIds === void 0 ? void 0 : metricIds.length);
|
|
1320
|
+
if (!(collect === null || collect === void 0 ? void 0 : collect(data, realEventTarget, event, isConversion))) {
|
|
1321
|
+
queueEventForBatchedSending(coframe, data, isConversion);
|
|
1322
|
+
}
|
|
1310
1323
|
const processingDuration = performance.now() - startTime;
|
|
1311
1324
|
if (coframe.status) {
|
|
1312
1325
|
if (!coframe.status.events) {
|
|
@@ -3380,6 +3393,235 @@ function notifyEventsFlushed() {
|
|
|
3380
3393
|
}
|
|
3381
3394
|
}
|
|
3382
3395
|
|
|
3396
|
+
const DEFAULT_BLOCK_SELECTOR = '[data-cf-block],.cf-block';
|
|
3397
|
+
const INTERACTIVE_SELECTOR = 'a,button,input,select,textarea,label,summary,[href],[onclick],[contenteditable],[tabindex]:not([tabindex="-1"]),[role=button],[role=link],[role=tab],[role=checkbox],[role=menuitem]';
|
|
3398
|
+
const HOLD_MS = 1000;
|
|
3399
|
+
const RAGE_WINDOW_MS = 700;
|
|
3400
|
+
const RAGE_RADIUS_PX = 30;
|
|
3401
|
+
const RAGE_CLICKS = 3;
|
|
3402
|
+
let enabled = false;
|
|
3403
|
+
let allPages = false;
|
|
3404
|
+
let coframe = null;
|
|
3405
|
+
let blockSelector = DEFAULT_BLOCK_SELECTOR;
|
|
3406
|
+
const held = [];
|
|
3407
|
+
let recent = [];
|
|
3408
|
+
let lastActivity = 0;
|
|
3409
|
+
let observer = null;
|
|
3410
|
+
let pageView = '';
|
|
3411
|
+
let maxDepth = 0;
|
|
3412
|
+
let engagedMs = 0;
|
|
3413
|
+
let visibleSince = null;
|
|
3414
|
+
let navigated = false;
|
|
3415
|
+
function meta(name) {
|
|
3416
|
+
const tag = document.querySelector(`meta[name="coframe:${name}"]`);
|
|
3417
|
+
return (tag === null || tag === void 0 ? void 0 : tag.getAttribute('content')) || undefined;
|
|
3418
|
+
}
|
|
3419
|
+
function heatmapActive() {
|
|
3420
|
+
return enabled && (allPages || !!meta('page'));
|
|
3421
|
+
}
|
|
3422
|
+
function pageFields(withHeight) {
|
|
3423
|
+
const fields = {
|
|
3424
|
+
page: meta('page'),
|
|
3425
|
+
ver: meta('version'),
|
|
3426
|
+
variant: meta('variant'),
|
|
3427
|
+
row: meta('row'),
|
|
3428
|
+
};
|
|
3429
|
+
if (withHeight)
|
|
3430
|
+
fields.doc_h = document.documentElement.scrollHeight;
|
|
3431
|
+
return fields;
|
|
3432
|
+
}
|
|
3433
|
+
function round3(value) {
|
|
3434
|
+
return Math.round(Math.min(1, Math.max(0, value)) * 1000) / 1000;
|
|
3435
|
+
}
|
|
3436
|
+
function markActivity() {
|
|
3437
|
+
lastActivity = Date.now();
|
|
3438
|
+
}
|
|
3439
|
+
function viewportBottom() {
|
|
3440
|
+
return Math.round(window.scrollY + window.innerHeight);
|
|
3441
|
+
}
|
|
3442
|
+
function restartCounters(depth) {
|
|
3443
|
+
maxDepth = depth;
|
|
3444
|
+
engagedMs = 0;
|
|
3445
|
+
visibleSince = document.hidden ? null : Date.now();
|
|
3446
|
+
}
|
|
3447
|
+
function syncPageView() {
|
|
3448
|
+
if (!coframe || coframe.sessionId === pageView)
|
|
3449
|
+
return;
|
|
3450
|
+
pageView = coframe.sessionId;
|
|
3451
|
+
if (navigated)
|
|
3452
|
+
navigated = false;
|
|
3453
|
+
else
|
|
3454
|
+
restartCounters(viewportBottom());
|
|
3455
|
+
}
|
|
3456
|
+
function onScroll() {
|
|
3457
|
+
markActivity();
|
|
3458
|
+
syncPageView();
|
|
3459
|
+
maxDepth = Math.max(maxDepth, viewportBottom());
|
|
3460
|
+
}
|
|
3461
|
+
function onVisibility() {
|
|
3462
|
+
if (document.hidden) {
|
|
3463
|
+
if (visibleSince !== null)
|
|
3464
|
+
engagedMs += Date.now() - visibleSince;
|
|
3465
|
+
visibleSince = null;
|
|
3466
|
+
releaseHeldClicks();
|
|
3467
|
+
}
|
|
3468
|
+
else if (visibleSince === null) {
|
|
3469
|
+
visibleSince = Date.now();
|
|
3470
|
+
}
|
|
3471
|
+
}
|
|
3472
|
+
function readBlockSelector(selector) {
|
|
3473
|
+
if (typeof selector !== 'string' || !selector)
|
|
3474
|
+
return DEFAULT_BLOCK_SELECTOR;
|
|
3475
|
+
try {
|
|
3476
|
+
document.createElement('div').matches(selector);
|
|
3477
|
+
return selector;
|
|
3478
|
+
}
|
|
3479
|
+
catch (_a) {
|
|
3480
|
+
return DEFAULT_BLOCK_SELECTOR;
|
|
3481
|
+
}
|
|
3482
|
+
}
|
|
3483
|
+
function startHeatmaps(target, project) {
|
|
3484
|
+
var _a, _b;
|
|
3485
|
+
const settings = (_a = project === null || project === void 0 ? void 0 : project.settings) === null || _a === void 0 ? void 0 : _a.heatmaps;
|
|
3486
|
+
if (enabled || !(settings === null || settings === void 0 ? void 0 : settings.enabled))
|
|
3487
|
+
return;
|
|
3488
|
+
enabled = true;
|
|
3489
|
+
allPages = !!settings.all_pages;
|
|
3490
|
+
blockSelector = readBlockSelector((_b = project.settings.session_replay) === null || _b === void 0 ? void 0 : _b.block_selector);
|
|
3491
|
+
coframe = target;
|
|
3492
|
+
syncPageView();
|
|
3493
|
+
document.addEventListener('scroll', onScroll, {
|
|
3494
|
+
capture: true,
|
|
3495
|
+
passive: true,
|
|
3496
|
+
});
|
|
3497
|
+
document.addEventListener('visibilitychange', onVisibility);
|
|
3498
|
+
window.addEventListener('pagehide', releaseHeldClicks);
|
|
3499
|
+
window.addEventListener('beforeunload', releaseHeldClicks);
|
|
3500
|
+
}
|
|
3501
|
+
function leaveFields() {
|
|
3502
|
+
if (!heatmapActive())
|
|
3503
|
+
return undefined;
|
|
3504
|
+
syncPageView();
|
|
3505
|
+
if (navigated)
|
|
3506
|
+
return undefined;
|
|
3507
|
+
return {
|
|
3508
|
+
content: {
|
|
3509
|
+
scroll_depth: Math.max(maxDepth, viewportBottom()),
|
|
3510
|
+
'duration-ms': Math.round(engagedMs + (visibleSince === null ? 0 : Date.now() - visibleSince)),
|
|
3511
|
+
},
|
|
3512
|
+
hm: pageFields(true),
|
|
3513
|
+
};
|
|
3514
|
+
}
|
|
3515
|
+
function pageLeaveFields() {
|
|
3516
|
+
if (!enabled)
|
|
3517
|
+
return undefined;
|
|
3518
|
+
const fields = leaveFields();
|
|
3519
|
+
restartCounters(0);
|
|
3520
|
+
navigated = true;
|
|
3521
|
+
return fields;
|
|
3522
|
+
}
|
|
3523
|
+
function watchMutations() {
|
|
3524
|
+
if (observer || typeof MutationObserver !== 'function')
|
|
3525
|
+
return;
|
|
3526
|
+
observer = new MutationObserver(markActivity);
|
|
3527
|
+
observer.observe(document.documentElement, {
|
|
3528
|
+
attributes: true,
|
|
3529
|
+
characterData: true,
|
|
3530
|
+
childList: true,
|
|
3531
|
+
subtree: true,
|
|
3532
|
+
});
|
|
3533
|
+
}
|
|
3534
|
+
function settle(click) {
|
|
3535
|
+
const index = held.indexOf(click);
|
|
3536
|
+
if (index < 0)
|
|
3537
|
+
return;
|
|
3538
|
+
held.splice(index, 1);
|
|
3539
|
+
if (click.hm.kind !== 'rage') {
|
|
3540
|
+
const dead = click.candidate &&
|
|
3541
|
+
lastActivity < click.t &&
|
|
3542
|
+
document.activeElement === click.focused &&
|
|
3543
|
+
location.href === click.href;
|
|
3544
|
+
click.hm.kind = dead ? 'dead' : 'click';
|
|
3545
|
+
}
|
|
3546
|
+
if (coframe)
|
|
3547
|
+
queueEventForBatchedSending(coframe, click.data);
|
|
3548
|
+
if (observer && !held.some((h) => h.candidate)) {
|
|
3549
|
+
observer.disconnect();
|
|
3550
|
+
observer = null;
|
|
3551
|
+
}
|
|
3552
|
+
}
|
|
3553
|
+
function releaseHeldClicks() {
|
|
3554
|
+
for (const click of held.splice(0)) {
|
|
3555
|
+
if (click.hm.kind === undefined)
|
|
3556
|
+
click.hm.kind = null;
|
|
3557
|
+
if (coframe)
|
|
3558
|
+
queueEventForBatchedSending(coframe, click.data);
|
|
3559
|
+
}
|
|
3560
|
+
if (observer) {
|
|
3561
|
+
observer.disconnect();
|
|
3562
|
+
observer = null;
|
|
3563
|
+
}
|
|
3564
|
+
}
|
|
3565
|
+
function copyKey(node, id) {
|
|
3566
|
+
const items = [];
|
|
3567
|
+
for (let at = node; at; at = at.parentElement) {
|
|
3568
|
+
const item = at.getAttribute('data-el-item');
|
|
3569
|
+
if (item)
|
|
3570
|
+
items.unshift(item);
|
|
3571
|
+
}
|
|
3572
|
+
return items.length ? `${id}~${items.join('.')}` : id;
|
|
3573
|
+
}
|
|
3574
|
+
function collectClick(data, target, event, isConversion) {
|
|
3575
|
+
if (!target.closest || target.closest(blockSelector))
|
|
3576
|
+
return false;
|
|
3577
|
+
const content = data.content;
|
|
3578
|
+
const position = content.position;
|
|
3579
|
+
const hm = pageFields(true);
|
|
3580
|
+
const anchor = target.closest('[data-el]');
|
|
3581
|
+
if (anchor) {
|
|
3582
|
+
const id = anchor.getAttribute('data-el');
|
|
3583
|
+
hm.el = id ? copyKey(anchor, id) : undefined;
|
|
3584
|
+
const rect = anchor.getBoundingClientRect();
|
|
3585
|
+
if (rect.width > 0 && rect.height > 0) {
|
|
3586
|
+
hm.fx = round3((event.clientX - rect.left) / rect.width);
|
|
3587
|
+
hm.fy = round3((event.clientY - rect.top) / rect.height);
|
|
3588
|
+
}
|
|
3589
|
+
}
|
|
3590
|
+
content.metadata = {
|
|
3591
|
+
...content.metadata,
|
|
3592
|
+
hm,
|
|
3593
|
+
};
|
|
3594
|
+
const now = Date.now();
|
|
3595
|
+
const click = {
|
|
3596
|
+
data,
|
|
3597
|
+
hm,
|
|
3598
|
+
x: position.x,
|
|
3599
|
+
y: position.y,
|
|
3600
|
+
t: now,
|
|
3601
|
+
candidate: !target.closest(INTERACTIVE_SELECTOR),
|
|
3602
|
+
focused: document.activeElement,
|
|
3603
|
+
href: location.href,
|
|
3604
|
+
};
|
|
3605
|
+
recent = recent.filter((r) => now - r.t <= RAGE_WINDOW_MS);
|
|
3606
|
+
recent.push(click);
|
|
3607
|
+
const cluster = recent.filter((r) => Math.abs(r.x - click.x) <= RAGE_RADIUS_PX &&
|
|
3608
|
+
Math.abs(r.y - click.y) <= RAGE_RADIUS_PX);
|
|
3609
|
+
if (cluster.length >= RAGE_CLICKS) {
|
|
3610
|
+
for (const r of cluster)
|
|
3611
|
+
r.hm.kind = 'rage';
|
|
3612
|
+
}
|
|
3613
|
+
if (isConversion) {
|
|
3614
|
+
if (hm.kind === undefined)
|
|
3615
|
+
hm.kind = null;
|
|
3616
|
+
return false;
|
|
3617
|
+
}
|
|
3618
|
+
held.push(click);
|
|
3619
|
+
if (click.candidate)
|
|
3620
|
+
watchMutations();
|
|
3621
|
+
setTimeout(() => settle(click), HOLD_MS);
|
|
3622
|
+
return true;
|
|
3623
|
+
}
|
|
3624
|
+
|
|
3383
3625
|
function startSession(Coframe, cookiesEnabled, executionStartTime, personalizationHeaders, sessionContext, pageUrl = getCurrentPageUrl()) {
|
|
3384
3626
|
const sessionPayload = [
|
|
3385
3627
|
Coframe,
|
|
@@ -3406,7 +3648,7 @@ function startSession(Coframe, cookiesEnabled, executionStartTime, personalizati
|
|
|
3406
3648
|
orgId: Coframe.orgId,
|
|
3407
3649
|
userToken: Coframe.userToken,
|
|
3408
3650
|
personalizationHeaders,
|
|
3409
|
-
});
|
|
3651
|
+
}, heatmapActive() ? { hm: pageFields(false) } : undefined);
|
|
3410
3652
|
}
|
|
3411
3653
|
function reportInitTiming(Coframe, project, integrationStartTime, executionStartTime) {
|
|
3412
3654
|
var _a;
|
|
@@ -3639,20 +3881,15 @@ function setupListeners(Coframe, executionStartTime) {
|
|
|
3639
3881
|
sendPageEngagementEvent(Coframe, 'click', event, {
|
|
3640
3882
|
projectId: Coframe.projectId,
|
|
3641
3883
|
sessionId: Coframe.sessionId,
|
|
3884
|
+
orgId: Coframe.orgId,
|
|
3642
3885
|
userToken: Coframe.userToken,
|
|
3643
3886
|
personalizationHeaders: Coframe.personalizationHeaders,
|
|
3887
|
+
collect: heatmapActive() ? collectClick : undefined,
|
|
3644
3888
|
});
|
|
3645
3889
|
};
|
|
3646
3890
|
document.addEventListener('click', handleClick, true);
|
|
3647
3891
|
const handleEventFlush = debounce((eventType) => {
|
|
3648
|
-
|
|
3649
|
-
projectId: Coframe.projectId,
|
|
3650
|
-
sessionId: Coframe.sessionId,
|
|
3651
|
-
eventType: eventType,
|
|
3652
|
-
orgId: Coframe.orgId,
|
|
3653
|
-
userToken: Coframe.userToken,
|
|
3654
|
-
personalizationHeaders: Coframe.personalizationHeaders,
|
|
3655
|
-
});
|
|
3892
|
+
queueLeaveEvent(Coframe, eventType, eventType === 'tab_show' ? undefined : leaveFields());
|
|
3656
3893
|
flushQueuedEvents(Coframe.projectId);
|
|
3657
3894
|
notifyEventsFlushed();
|
|
3658
3895
|
}, 1);
|
|
@@ -3664,11 +3901,27 @@ function setupListeners(Coframe, executionStartTime) {
|
|
|
3664
3901
|
handleEventFlush(eventType);
|
|
3665
3902
|
});
|
|
3666
3903
|
}
|
|
3904
|
+
function queueLeaveEvent(Coframe, eventType, fields) {
|
|
3905
|
+
queueEvent(Coframe, {
|
|
3906
|
+
projectId: Coframe.projectId,
|
|
3907
|
+
sessionId: Coframe.sessionId,
|
|
3908
|
+
eventType,
|
|
3909
|
+
orgId: Coframe.orgId,
|
|
3910
|
+
userToken: Coframe.userToken,
|
|
3911
|
+
personalizationHeaders: Coframe.personalizationHeaders,
|
|
3912
|
+
}, fields);
|
|
3913
|
+
}
|
|
3914
|
+
function sendPageLeave(Coframe) {
|
|
3915
|
+
const fields = pageLeaveFields();
|
|
3916
|
+
if (fields)
|
|
3917
|
+
queueLeaveEvent(Coframe, 'page_leave', fields);
|
|
3918
|
+
}
|
|
3667
3919
|
function setupTracking(Coframe, projectResult, previewVariantId, executionStartTime, nonce, waitForCookiesEnabled, onConsentChange) {
|
|
3668
3920
|
var _a, _b;
|
|
3669
3921
|
const logger = Coframe.logger;
|
|
3670
3922
|
const { project } = projectResult;
|
|
3671
3923
|
setTrackOnlyActivatedFrames(!!((_a = project === null || project === void 0 ? void 0 : project.settings) === null || _a === void 0 ? void 0 : _a.track_only_activated_frames));
|
|
3924
|
+
startHeatmaps(Coframe, project);
|
|
3672
3925
|
const analytics = createTreatmentAnalytics(Coframe, previewVariantId);
|
|
3673
3926
|
setupListeners(Coframe, executionStartTime);
|
|
3674
3927
|
const managedAnalyticsCallback = (_b = project === null || project === void 0 ? void 0 : project.settings) === null || _b === void 0 ? void 0 : _b.analytics_callback;
|
|
@@ -3784,6 +4037,7 @@ function setupSPANavigation(Coframe, project, config, previewVariantId, isSessio
|
|
|
3784
4037
|
let navigationAbortController = null;
|
|
3785
4038
|
observeUrlChanges(false, async (newPageUrl, _oldPageUrl) => {
|
|
3786
4039
|
var _a;
|
|
4040
|
+
sendPageLeave(Coframe);
|
|
3787
4041
|
if (navigationAbortController)
|
|
3788
4042
|
navigationAbortController.abort();
|
|
3789
4043
|
navigationAbortController = new AbortController();
|
|
@@ -3932,11 +4186,90 @@ async function modifyPage(Coframe, configResult, projectResult, analytics) {
|
|
|
3932
4186
|
setupFlushInterval(Coframe);
|
|
3933
4187
|
}
|
|
3934
4188
|
|
|
4189
|
+
function readClientCommand() {
|
|
4190
|
+
try {
|
|
4191
|
+
const cmd = findLastCmd((c) => typeof c.cookiesEnabled === 'boolean');
|
|
4192
|
+
if (!cmd)
|
|
4193
|
+
return undefined;
|
|
4194
|
+
return cmd.cookiesEnabled === true ? 'granted' : 'denied';
|
|
4195
|
+
}
|
|
4196
|
+
catch (_a) {
|
|
4197
|
+
return undefined;
|
|
4198
|
+
}
|
|
4199
|
+
}
|
|
4200
|
+
function readOneTrust() {
|
|
4201
|
+
var _a;
|
|
4202
|
+
try {
|
|
4203
|
+
const { OnetrustActiveGroups: groups, OneTrust } = window;
|
|
4204
|
+
if (typeof groups !== 'string' && OneTrust === undefined)
|
|
4205
|
+
return undefined;
|
|
4206
|
+
if (typeof groups === 'string' && groups.split(',').indexOf('C0002') !== -1)
|
|
4207
|
+
return 'granted';
|
|
4208
|
+
return ((_a = OneTrust === null || OneTrust === void 0 ? void 0 : OneTrust.IsAlertBoxClosed) === null || _a === void 0 ? void 0 : _a.call(OneTrust)) === true ? 'denied' : 'pending';
|
|
4209
|
+
}
|
|
4210
|
+
catch (_b) {
|
|
4211
|
+
return undefined;
|
|
4212
|
+
}
|
|
4213
|
+
}
|
|
4214
|
+
function readCookiebot() {
|
|
4215
|
+
var _a;
|
|
4216
|
+
try {
|
|
4217
|
+
const { Cookiebot } = window;
|
|
4218
|
+
if (Cookiebot === undefined)
|
|
4219
|
+
return undefined;
|
|
4220
|
+
if (((_a = Cookiebot.consent) === null || _a === void 0 ? void 0 : _a.statistics) === true)
|
|
4221
|
+
return 'granted';
|
|
4222
|
+
return Cookiebot.hasResponse === true ? 'denied' : 'pending';
|
|
4223
|
+
}
|
|
4224
|
+
catch (_b) {
|
|
4225
|
+
return undefined;
|
|
4226
|
+
}
|
|
4227
|
+
}
|
|
4228
|
+
function readConsentMode() {
|
|
4229
|
+
var _a;
|
|
4230
|
+
try {
|
|
4231
|
+
const { dataLayer } = window;
|
|
4232
|
+
if (!Array.isArray(dataLayer))
|
|
4233
|
+
return undefined;
|
|
4234
|
+
let update;
|
|
4235
|
+
let defaultGranted = false;
|
|
4236
|
+
let defaultDenied = false;
|
|
4237
|
+
for (let i = 0; i < dataLayer.length; i++) {
|
|
4238
|
+
const entry = dataLayer[i];
|
|
4239
|
+
if (entry === null ||
|
|
4240
|
+
typeof entry !== 'object' ||
|
|
4241
|
+
entry[0] !== 'consent' ||
|
|
4242
|
+
(entry[1] !== 'default' && entry[1] !== 'update')) {
|
|
4243
|
+
continue;
|
|
4244
|
+
}
|
|
4245
|
+
const storage = (_a = entry[2]) === null || _a === void 0 ? void 0 : _a.analytics_storage;
|
|
4246
|
+
if (storage !== 'granted' && storage !== 'denied')
|
|
4247
|
+
continue;
|
|
4248
|
+
if (entry[1] === 'update')
|
|
4249
|
+
update = storage;
|
|
4250
|
+
else if (storage === 'denied')
|
|
4251
|
+
defaultDenied = true;
|
|
4252
|
+
else
|
|
4253
|
+
defaultGranted = true;
|
|
4254
|
+
}
|
|
4255
|
+
if (update !== undefined)
|
|
4256
|
+
return update;
|
|
4257
|
+
if (defaultDenied)
|
|
4258
|
+
return 'pending';
|
|
4259
|
+
return defaultGranted ? 'granted' : undefined;
|
|
4260
|
+
}
|
|
4261
|
+
catch (_b) {
|
|
4262
|
+
return undefined;
|
|
4263
|
+
}
|
|
4264
|
+
}
|
|
4265
|
+
|
|
3935
4266
|
let startRequested = false;
|
|
3936
4267
|
let replayScriptUrl;
|
|
3937
4268
|
const COMPILED_REPLAY_SCRIPT_URL = `${"https://edge.cofra.me"}/replay/latest.js`;
|
|
3938
4269
|
const CONSENT_POLL_MS = 100;
|
|
3939
4270
|
const CONSENT_WAIT_MS = 5000;
|
|
4271
|
+
const CONSENT_DETECT_WAIT_MS = 10000;
|
|
4272
|
+
const EXPLICIT_CONSENT_WAIT_MS = 60000;
|
|
3940
4273
|
function configureReplayScriptUrl(url) {
|
|
3941
4274
|
replayScriptUrl = (url === null || url === void 0 ? void 0 : url.trim()) || undefined;
|
|
3942
4275
|
}
|
|
@@ -3947,8 +4280,25 @@ function readReplayConsent() {
|
|
|
3947
4280
|
return { state: 'denied', reason: 'gpc' };
|
|
3948
4281
|
}
|
|
3949
4282
|
const shopify = window.Shopify;
|
|
3950
|
-
if (shopify === undefined)
|
|
3951
|
-
|
|
4283
|
+
if (shopify === undefined) {
|
|
4284
|
+
const readers = [
|
|
4285
|
+
[readClientCommand, 'client'],
|
|
4286
|
+
[readOneTrust, 'onetrust'],
|
|
4287
|
+
[readCookiebot, 'cookiebot'],
|
|
4288
|
+
[readConsentMode, 'consent_mode'],
|
|
4289
|
+
];
|
|
4290
|
+
for (let i = 0; i < readers.length; i++) {
|
|
4291
|
+
const [read, source] = readers[i];
|
|
4292
|
+
const signal = read();
|
|
4293
|
+
if (signal === 'granted')
|
|
4294
|
+
return { state: 'allowed', source };
|
|
4295
|
+
if (signal === 'denied')
|
|
4296
|
+
return { state: 'denied', reason: 'consent_denied' };
|
|
4297
|
+
if (signal === 'pending')
|
|
4298
|
+
return { state: 'pending', detected: true };
|
|
4299
|
+
}
|
|
4300
|
+
return { state: 'pending', detected: isWaitingForCookies() };
|
|
4301
|
+
}
|
|
3952
4302
|
const customerPrivacy = shopify.customerPrivacy;
|
|
3953
4303
|
const analyticsProcessingAllowed = customerPrivacy === null || customerPrivacy === void 0 ? void 0 : customerPrivacy.analyticsProcessingAllowed;
|
|
3954
4304
|
if (typeof analyticsProcessingAllowed === 'function') {
|
|
@@ -4050,11 +4400,14 @@ function startReplayIfEnabled(coframe, project, nonce) {
|
|
|
4050
4400
|
const settings = (_a = project.settings) === null || _a === void 0 ? void 0 : _a.session_replay;
|
|
4051
4401
|
if ((settings === null || settings === void 0 ? void 0 : settings.enabled) !== true ||
|
|
4052
4402
|
typeof CompressionStream !== 'function' ||
|
|
4053
|
-
!shouldSendEvents(
|
|
4403
|
+
!shouldSendEvents({
|
|
4404
|
+
ignoreConsent: window.Shopify === undefined,
|
|
4405
|
+
}) ||
|
|
4054
4406
|
startRequested) {
|
|
4055
4407
|
return;
|
|
4056
4408
|
}
|
|
4057
4409
|
startRequested = true;
|
|
4410
|
+
const isShopify = window.Shopify !== undefined;
|
|
4058
4411
|
let waited = 0;
|
|
4059
4412
|
const decide = () => {
|
|
4060
4413
|
var _a;
|
|
@@ -4065,7 +4418,12 @@ function startReplayIfEnabled(coframe, project, nonce) {
|
|
|
4065
4418
|
else if (consent.state === 'denied') {
|
|
4066
4419
|
reportReplaySkipped(coframe, consent.reason);
|
|
4067
4420
|
}
|
|
4068
|
-
else if (
|
|
4421
|
+
else if (!isShopify &&
|
|
4422
|
+
consent.detected !== true &&
|
|
4423
|
+
waited >= CONSENT_DETECT_WAIT_MS) {
|
|
4424
|
+
reportReplaySkipped(coframe, 'consent_not_configured');
|
|
4425
|
+
}
|
|
4426
|
+
else if (waited >= (isShopify ? CONSENT_WAIT_MS : EXPLICIT_CONSENT_WAIT_MS)) {
|
|
4069
4427
|
reportReplaySkipped(coframe, 'consent_unavailable');
|
|
4070
4428
|
}
|
|
4071
4429
|
else {
|
|
@@ -144,6 +144,10 @@ interface Metric {
|
|
|
144
144
|
selector: SelectorCondition;
|
|
145
145
|
js_binder?: string;
|
|
146
146
|
}
|
|
147
|
+
interface HeatmapSettings {
|
|
148
|
+
enabled: boolean;
|
|
149
|
+
all_pages?: boolean;
|
|
150
|
+
}
|
|
147
151
|
interface ProjectSettings {
|
|
148
152
|
mutation_observer_active: boolean;
|
|
149
153
|
track_only_activated_frames?: boolean;
|
|
@@ -152,6 +156,7 @@ interface ProjectSettings {
|
|
|
152
156
|
bot_score_threshold?: number;
|
|
153
157
|
analytics_callback?: AnalyticsCallback;
|
|
154
158
|
session_replay?: SessionReplaySettings | null;
|
|
159
|
+
heatmaps?: HeatmapSettings | null;
|
|
155
160
|
}
|
|
156
161
|
interface Project {
|
|
157
162
|
org_id: string;
|
|
@@ -164,6 +164,10 @@ interface Metric {
|
|
|
164
164
|
selector: SelectorCondition;
|
|
165
165
|
js_binder?: string;
|
|
166
166
|
}
|
|
167
|
+
interface HeatmapSettings {
|
|
168
|
+
enabled: boolean;
|
|
169
|
+
all_pages?: boolean;
|
|
170
|
+
}
|
|
167
171
|
interface ProjectSettings {
|
|
168
172
|
mutation_observer_active: boolean;
|
|
169
173
|
track_only_activated_frames?: boolean;
|
|
@@ -172,6 +176,7 @@ interface ProjectSettings {
|
|
|
172
176
|
bot_score_threshold?: number;
|
|
173
177
|
analytics_callback?: AnalyticsCallback;
|
|
174
178
|
session_replay?: SessionReplaySettings | null;
|
|
179
|
+
heatmaps?: HeatmapSettings | null;
|
|
175
180
|
}
|
|
176
181
|
interface Project {
|
|
177
182
|
org_id: string;
|
|
@@ -110,6 +110,10 @@ interface Metric {
|
|
|
110
110
|
selector: SelectorCondition;
|
|
111
111
|
js_binder?: string;
|
|
112
112
|
}
|
|
113
|
+
interface HeatmapSettings {
|
|
114
|
+
enabled: boolean;
|
|
115
|
+
all_pages?: boolean;
|
|
116
|
+
}
|
|
113
117
|
interface ProjectSettings {
|
|
114
118
|
mutation_observer_active: boolean;
|
|
115
119
|
track_only_activated_frames?: boolean;
|
|
@@ -118,6 +122,7 @@ interface ProjectSettings {
|
|
|
118
122
|
bot_score_threshold?: number;
|
|
119
123
|
analytics_callback?: AnalyticsCallback;
|
|
120
124
|
session_replay?: SessionReplaySettings | null;
|
|
125
|
+
heatmaps?: HeatmapSettings | null;
|
|
121
126
|
}
|
|
122
127
|
interface Project {
|
|
123
128
|
org_id: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coframe/sdk",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.42",
|
|
4
4
|
"description": "Coframe optimizes your website using generative AI to deliver maximum impact to your audience and allow your site to improve itself as you sleep. Learn more at coframe.com.",
|
|
5
5
|
"main": "dist/pkg/cf.cjs.js",
|
|
6
6
|
"module": "dist/pkg/cf.esm.mjs",
|