@journium/js 1.2.3 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AutocaptureTracker.d.ts +5 -0
- package/dist/AutocaptureTracker.d.ts.map +1 -1
- package/dist/JourniumAnalytics.d.ts.map +1 -1
- package/dist/PageviewTracker.d.ts +2 -1
- package/dist/PageviewTracker.d.ts.map +1 -1
- package/dist/index.cjs +200 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +7 -2
- package/dist/index.mjs +200 -28
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +200 -28
- package/dist/index.umd.js.map +1 -1
- package/dist/journium.js +200 -28
- package/dist/journium.js.map +1 -1
- package/dist/journium.min.js +1 -1
- package/dist/journium.min.js.map +1 -1
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/package.json +2 -2
|
@@ -27,6 +27,11 @@ export declare class AutocaptureTracker {
|
|
|
27
27
|
private getElementType;
|
|
28
28
|
private getElementText;
|
|
29
29
|
private getElementsChain;
|
|
30
|
+
private extractSemanticClasses;
|
|
31
|
+
private isHashLike;
|
|
32
|
+
private getVisibleTextContent;
|
|
33
|
+
private getElementState;
|
|
34
|
+
private findInteractiveAncestor;
|
|
30
35
|
private isSafeInputType;
|
|
31
36
|
}
|
|
32
37
|
//# sourceMappingURL=AutocaptureTracker.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AutocaptureTracker.d.ts","sourceRoot":"","sources":["../src/AutocaptureTracker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAa,kBAAkB,
|
|
1
|
+
{"version":3,"file":"AutocaptureTracker.d.ts","sourceRoot":"","sources":["../src/AutocaptureTracker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAa,kBAAkB,EAA6B,MAAM,gBAAgB,CAAC;AAE1F;;GAEG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,SAAS,CAAyC;IAC1D,OAAO,CAAC,QAAQ,CAAkB;gBAEtB,MAAM,EAAE,cAAc,EAAE,OAAO,GAAE,kBAAuB;IAgBpE;;OAEG;IACH,aAAa,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI;IA4BhD,KAAK,IAAI,IAAI;IAwBb,IAAI,IAAI,IAAI;IAcZ,OAAO,CAAC,gBAAgB;IAiBxB,OAAO,CAAC,qBAAqB;IAgB7B,OAAO,CAAC,qBAAqB;IAgB7B,OAAO,CAAC,wBAAwB;IA6BhC,OAAO,CAAC,mBAAmB;IA2B3B,OAAO,CAAC,aAAa;IAKrB,OAAO,CAAC,oBAAoB;IA2G5B,OAAO,CAAC,iBAAiB;IAsBzB,OAAO,CAAC,kBAAkB;IAuC1B,OAAO,CAAC,cAAc;IActB,OAAO,CAAC,cAAc;IAqDtB,OAAO,CAAC,gBAAgB;IAqFxB,OAAO,CAAC,sBAAsB;IA0B9B,OAAO,CAAC,UAAU;IAOlB,OAAO,CAAC,qBAAqB;IAiB7B,OAAO,CAAC,eAAe;IA2BvB,OAAO,CAAC,uBAAuB;IAgB/B,OAAO,CAAC,eAAe;CAKxB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JourniumAnalytics.d.ts","sourceRoot":"","sources":["../src/JourniumAnalytics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAiD,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"JourniumAnalytics.d.ts","sourceRoot":"","sources":["../src/JourniumAnalytics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAiD,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAMrH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,kBAAkB,CAAkB;IAC5C,OAAO,CAAC,wBAAwB,CAAC,CAAa;gBAElC,MAAM,EAAE,cAAc;IAqBlC,OAAO,CAAC,sBAAsB;IAsB9B,OAAO,CAAC,yBAAyB;IAiBjC,qDAAqD;IACrD,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAIhE,wFAAwF;IACxF,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAIxE,oEAAoE;IACpE,KAAK,IAAI,IAAI;IAIb,0EAA0E;IAC1E,eAAe,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAI3D;;;;OAIG;IACH,gBAAgB,IAAI,IAAI;IA6BxB,yEAAyE;IACzE,eAAe,IAAI,IAAI;IAMvB;;;OAGG;IACH,OAAO,CAAC,yBAAyB;IAoCjC;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAiC3B,qEAAqE;IAC/D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5B,0EAA0E;IAC1E,mBAAmB;IAInB;;OAEG;IACH,eAAe,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,IAAI,GAAG,MAAM,IAAI;IAI9E,wGAAwG;IACxG,OAAO,IAAI,IAAI;CAQhB;AAED,+EAA+E;AAC/E,eAAO,MAAM,IAAI,GAAI,QAAQ,cAAc,KAAG,iBAS7C,CAAC;;mBAT2B,cAAc,KAAG,iBAAiB;;AAW/D,wBAAwB"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { PageviewProperties } from '@journium/core';
|
|
1
2
|
import { JourniumClient } from './JourniumClient';
|
|
2
3
|
export declare class PageviewTracker {
|
|
3
4
|
private client;
|
|
@@ -6,7 +7,7 @@ export declare class PageviewTracker {
|
|
|
6
7
|
private originalReplaceState;
|
|
7
8
|
private popStateHandler;
|
|
8
9
|
constructor(client: JourniumClient);
|
|
9
|
-
capturePageview(customProperties?:
|
|
10
|
+
capturePageview(customProperties?: PageviewProperties): void;
|
|
10
11
|
/**
|
|
11
12
|
* Start automatic autocapture for pageviews
|
|
12
13
|
* @param captureInitialPageview - whether to fire a $pageview immediately on start (default: true).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PageviewTracker.d.ts","sourceRoot":"","sources":["../src/PageviewTracker.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"PageviewTracker.d.ts","sourceRoot":"","sources":["../src/PageviewTracker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAA4C,MAAM,gBAAgB,CAAC;AAC9F,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,iBAAiB,CAAgD;IACzE,OAAO,CAAC,oBAAoB,CAAmD;IAC/E,OAAO,CAAC,eAAe,CAA6B;gBAExC,MAAM,EAAE,cAAc;IAIlC,eAAe,CAAC,gBAAgB,GAAE,kBAAuB,GAAG,IAAI;IAoBhE;;;;;;OAMG;IACH,yBAAyB,CAAC,sBAAsB,GAAE,OAAc,EAAE,YAAY,GAAE,OAAc,GAAG,IAAI;IA8BrG;;;OAGG;IACH,eAAe,IAAI,IAAI;CAmBxB"}
|
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
// @journium/js@1.3.1 is replaced at build time by @rollup/plugin-replace
|
|
4
|
+
const SDK_VERSION = '@journium/js@1.3.1';
|
|
5
|
+
|
|
3
6
|
/**
|
|
4
7
|
* uuidv7: A JavaScript implementation of UUID version 7
|
|
5
8
|
*
|
|
@@ -940,6 +943,7 @@ class JourniumClient {
|
|
|
940
943
|
Logger.setDebug((_a = this.effectiveOptions.debug) !== null && _a !== void 0 ? _a : false);
|
|
941
944
|
}
|
|
942
945
|
buildIdentityProperties(userProperties = {}) {
|
|
946
|
+
var _a, _b;
|
|
943
947
|
const identity = this.identityManager.getIdentity();
|
|
944
948
|
const userAgentInfo = this.identityManager.getUserAgentInfo();
|
|
945
949
|
return {
|
|
@@ -950,7 +954,7 @@ class JourniumClient {
|
|
|
950
954
|
$current_url: typeof window !== 'undefined' ? window.location.href : '',
|
|
951
955
|
$pathname: typeof window !== 'undefined' ? window.location.pathname : '',
|
|
952
956
|
...userAgentInfo,
|
|
953
|
-
$
|
|
957
|
+
$sdk_version: (_b = (_a = this.config.options) === null || _a === void 0 ? void 0 : _a._sdkVersion) !== null && _b !== void 0 ? _b : 'unknown',
|
|
954
958
|
$platform: 'web',
|
|
955
959
|
...userProperties,
|
|
956
960
|
};
|
|
@@ -1091,8 +1095,10 @@ class PageviewTracker {
|
|
|
1091
1095
|
$host: url.host,
|
|
1092
1096
|
$pathname: url.pathname,
|
|
1093
1097
|
$search: url.search,
|
|
1094
|
-
$
|
|
1098
|
+
$page_title: getPageTitle(),
|
|
1095
1099
|
$referrer: getReferrer(),
|
|
1100
|
+
$previous_url: this.lastUrl || '',
|
|
1101
|
+
$previous_pathname: this.lastUrl ? new URL(this.lastUrl).pathname : '',
|
|
1096
1102
|
...customProperties,
|
|
1097
1103
|
};
|
|
1098
1104
|
this.client.track('$pageview', properties);
|
|
@@ -1167,6 +1173,8 @@ class AutocaptureTracker {
|
|
|
1167
1173
|
ignoreClasses: ['journium-ignore'],
|
|
1168
1174
|
ignoreElements: ['script', 'style', 'noscript'],
|
|
1169
1175
|
captureContentText: true,
|
|
1176
|
+
dataAttributePrefixes: ['jrnm-'],
|
|
1177
|
+
dataAttributeNames: ['data-testid', 'data-track'],
|
|
1170
1178
|
...options,
|
|
1171
1179
|
};
|
|
1172
1180
|
}
|
|
@@ -1188,6 +1196,8 @@ class AutocaptureTracker {
|
|
|
1188
1196
|
ignoreClasses: ['journium-ignore'],
|
|
1189
1197
|
ignoreElements: ['script', 'style', 'noscript'],
|
|
1190
1198
|
captureContentText: true,
|
|
1199
|
+
dataAttributePrefixes: ['jrnm-'],
|
|
1200
|
+
dataAttributeNames: ['data-testid', 'data-track'],
|
|
1191
1201
|
...options,
|
|
1192
1202
|
};
|
|
1193
1203
|
// Restart if it was active before
|
|
@@ -1225,15 +1235,14 @@ class AutocaptureTracker {
|
|
|
1225
1235
|
}
|
|
1226
1236
|
addClickListener() {
|
|
1227
1237
|
const clickListener = (event) => {
|
|
1228
|
-
|
|
1238
|
+
var _a;
|
|
1239
|
+
const rawTarget = event.target;
|
|
1240
|
+
const target = (_a = this.findInteractiveAncestor(rawTarget)) !== null && _a !== void 0 ? _a : rawTarget;
|
|
1229
1241
|
if (this.shouldIgnoreElement(target)) {
|
|
1230
1242
|
return;
|
|
1231
1243
|
}
|
|
1232
1244
|
const properties = this.getElementProperties(target, 'click');
|
|
1233
|
-
this.client.track('$autocapture',
|
|
1234
|
-
$event_type: 'click',
|
|
1235
|
-
...properties,
|
|
1236
|
-
});
|
|
1245
|
+
this.client.track('$autocapture', properties);
|
|
1237
1246
|
};
|
|
1238
1247
|
document.addEventListener('click', clickListener, true);
|
|
1239
1248
|
this.listeners.set('click', clickListener);
|
|
@@ -1245,10 +1254,7 @@ class AutocaptureTracker {
|
|
|
1245
1254
|
return;
|
|
1246
1255
|
}
|
|
1247
1256
|
const properties = this.getFormProperties(target, 'submit');
|
|
1248
|
-
this.client.track('$autocapture',
|
|
1249
|
-
$event_type: 'submit',
|
|
1250
|
-
...properties,
|
|
1251
|
-
});
|
|
1257
|
+
this.client.track('$autocapture', properties);
|
|
1252
1258
|
};
|
|
1253
1259
|
document.addEventListener('submit', submitListener, true);
|
|
1254
1260
|
this.listeners.set('submit', submitListener);
|
|
@@ -1260,10 +1266,7 @@ class AutocaptureTracker {
|
|
|
1260
1266
|
return;
|
|
1261
1267
|
}
|
|
1262
1268
|
const properties = this.getInputProperties(target, 'change');
|
|
1263
|
-
this.client.track('$autocapture',
|
|
1264
|
-
$event_type: 'change',
|
|
1265
|
-
...properties,
|
|
1266
|
-
});
|
|
1269
|
+
this.client.track('$autocapture', properties);
|
|
1267
1270
|
};
|
|
1268
1271
|
document.addEventListener('change', changeListener, true);
|
|
1269
1272
|
this.listeners.set('change', changeListener);
|
|
@@ -1282,6 +1285,12 @@ class AutocaptureTracker {
|
|
|
1282
1285
|
$event_type: 'text_selection',
|
|
1283
1286
|
$selected_text: selectedText.substring(0, 200), // Limit text length
|
|
1284
1287
|
$selection_length: selectedText.length,
|
|
1288
|
+
$current_url: window.location.href,
|
|
1289
|
+
$host: window.location.host,
|
|
1290
|
+
$pathname: window.location.pathname,
|
|
1291
|
+
$search: window.location.search,
|
|
1292
|
+
$page_title: document.title,
|
|
1293
|
+
$referrer: document.referrer,
|
|
1285
1294
|
});
|
|
1286
1295
|
};
|
|
1287
1296
|
document.addEventListener('mouseup', selectionListener);
|
|
@@ -1316,6 +1325,7 @@ class AutocaptureTracker {
|
|
|
1316
1325
|
}
|
|
1317
1326
|
getElementProperties(element, eventType) {
|
|
1318
1327
|
const properties = {
|
|
1328
|
+
$event_type: eventType,
|
|
1319
1329
|
$element_tag: element.tagName.toLowerCase(),
|
|
1320
1330
|
$element_type: this.getElementType(element),
|
|
1321
1331
|
};
|
|
@@ -1325,6 +1335,7 @@ class AutocaptureTracker {
|
|
|
1325
1335
|
}
|
|
1326
1336
|
if (element.className) {
|
|
1327
1337
|
properties.$element_classes = Array.from(element.classList);
|
|
1338
|
+
properties.$element_semantic_classes = this.extractSemanticClasses(element.classList);
|
|
1328
1339
|
}
|
|
1329
1340
|
// Element attributes
|
|
1330
1341
|
const relevantAttributes = ['name', 'role', 'aria-label', 'data-testid', 'data-track'];
|
|
@@ -1334,11 +1345,39 @@ class AutocaptureTracker {
|
|
|
1334
1345
|
properties[`$element_${attr.replace('-', '_')}`] = value;
|
|
1335
1346
|
}
|
|
1336
1347
|
});
|
|
1348
|
+
// Configurable data-* attribute capture
|
|
1349
|
+
const prefixes = this.options.dataAttributePrefixes || ['jrnm-'];
|
|
1350
|
+
const exactNames = new Set(this.options.dataAttributeNames || ['data-testid', 'data-track']);
|
|
1351
|
+
const relevantSet = new Set(relevantAttributes);
|
|
1352
|
+
let dataAttrCount = 0;
|
|
1353
|
+
for (let i = 0; i < element.attributes.length && dataAttrCount < 10; i++) {
|
|
1354
|
+
const attr = element.attributes.item(i);
|
|
1355
|
+
if (!attr || !attr.name.startsWith('data-'))
|
|
1356
|
+
continue;
|
|
1357
|
+
if (relevantSet.has(attr.name))
|
|
1358
|
+
continue;
|
|
1359
|
+
const suffix = attr.name.slice(5); // strip 'data-'
|
|
1360
|
+
const matchesPrefix = prefixes.some(p => suffix.startsWith(p));
|
|
1361
|
+
const matchesName = exactNames.has(attr.name);
|
|
1362
|
+
if (matchesPrefix || matchesName) {
|
|
1363
|
+
const propName = `$attr_${attr.name.replace(/-/g, '_')}`;
|
|
1364
|
+
properties[propName] = attr.value;
|
|
1365
|
+
dataAttrCount++;
|
|
1366
|
+
}
|
|
1367
|
+
}
|
|
1368
|
+
// Link href as first-class property
|
|
1369
|
+
if (element.tagName.toLowerCase() === 'a') {
|
|
1370
|
+
const href = element.getAttribute('href');
|
|
1371
|
+
if (href) {
|
|
1372
|
+
properties.$element_href = href;
|
|
1373
|
+
}
|
|
1374
|
+
}
|
|
1337
1375
|
// Element content
|
|
1338
1376
|
if (this.options.captureContentText) {
|
|
1339
|
-
const
|
|
1340
|
-
if (
|
|
1341
|
-
properties.$element_text = text.substring(0, 200); // Limit text length
|
|
1377
|
+
const result = this.getElementText(element);
|
|
1378
|
+
if (result && result.source) {
|
|
1379
|
+
properties.$element_text = result.text.substring(0, 200); // Limit text length
|
|
1380
|
+
properties.$element_text_source = result.source;
|
|
1342
1381
|
}
|
|
1343
1382
|
}
|
|
1344
1383
|
// Elements chain data
|
|
@@ -1348,6 +1387,11 @@ class AutocaptureTracker {
|
|
|
1348
1387
|
properties.$elements_chain_elements = elementsChain.elements;
|
|
1349
1388
|
properties.$elements_chain_texts = elementsChain.texts;
|
|
1350
1389
|
properties.$elements_chain_ids = elementsChain.ids;
|
|
1390
|
+
// Element state
|
|
1391
|
+
const elementState = this.getElementState(element);
|
|
1392
|
+
if (elementState) {
|
|
1393
|
+
properties.$element_state = elementState;
|
|
1394
|
+
}
|
|
1351
1395
|
// Position information
|
|
1352
1396
|
const rect = element.getBoundingClientRect();
|
|
1353
1397
|
properties.$element_position = {
|
|
@@ -1363,10 +1407,13 @@ class AutocaptureTracker {
|
|
|
1363
1407
|
properties.$parent_id = element.parentElement.id;
|
|
1364
1408
|
}
|
|
1365
1409
|
}
|
|
1366
|
-
// URL
|
|
1410
|
+
// URL and page context
|
|
1367
1411
|
properties.$current_url = window.location.href;
|
|
1368
1412
|
properties.$host = window.location.host;
|
|
1369
1413
|
properties.$pathname = window.location.pathname;
|
|
1414
|
+
properties.$search = window.location.search;
|
|
1415
|
+
properties.$page_title = document.title;
|
|
1416
|
+
properties.$referrer = document.referrer;
|
|
1370
1417
|
return properties;
|
|
1371
1418
|
}
|
|
1372
1419
|
getFormProperties(form, eventType) {
|
|
@@ -1429,19 +1476,50 @@ class AutocaptureTracker {
|
|
|
1429
1476
|
return tag;
|
|
1430
1477
|
}
|
|
1431
1478
|
getElementText(element) {
|
|
1432
|
-
var _a, _b;
|
|
1433
|
-
|
|
1434
|
-
if (['button', 'a'].includes(element.tagName.toLowerCase())) {
|
|
1435
|
-
return ((_a = element.textContent) === null || _a === void 0 ? void 0 : _a.trim()) || '';
|
|
1436
|
-
}
|
|
1479
|
+
var _a, _b, _c, _d, _e;
|
|
1480
|
+
const tag = element.tagName.toLowerCase();
|
|
1437
1481
|
// For inputs, get placeholder or label
|
|
1438
|
-
if (
|
|
1482
|
+
if (tag === 'input') {
|
|
1439
1483
|
const input = element;
|
|
1440
|
-
|
|
1484
|
+
const text = input.placeholder || input.value || '';
|
|
1485
|
+
return text ? { text, source: 'content' } : null;
|
|
1486
|
+
}
|
|
1487
|
+
// For buttons and links, use fallback chain
|
|
1488
|
+
if (['button', 'a'].includes(tag)) {
|
|
1489
|
+
// 1. Visible text content (excluding SVG title/desc which aren't rendered)
|
|
1490
|
+
const visibleText = this.getVisibleTextContent(element);
|
|
1491
|
+
if (visibleText) {
|
|
1492
|
+
return { text: visibleText, source: 'content' };
|
|
1493
|
+
}
|
|
1494
|
+
// 2. aria-label
|
|
1495
|
+
const ariaLabel = (_a = element.getAttribute('aria-label')) === null || _a === void 0 ? void 0 : _a.trim();
|
|
1496
|
+
if (ariaLabel) {
|
|
1497
|
+
return { text: ariaLabel, source: 'aria-label' };
|
|
1498
|
+
}
|
|
1499
|
+
// 3. title
|
|
1500
|
+
const title = (_b = element.getAttribute('title')) === null || _b === void 0 ? void 0 : _b.trim();
|
|
1501
|
+
if (title) {
|
|
1502
|
+
return { text: title, source: 'title' };
|
|
1503
|
+
}
|
|
1504
|
+
// 4. First <img> child's alt
|
|
1505
|
+
const img = element.querySelector('img');
|
|
1506
|
+
if ((_c = img === null || img === void 0 ? void 0 : img.alt) === null || _c === void 0 ? void 0 : _c.trim()) {
|
|
1507
|
+
return { text: img.alt.trim(), source: 'alt' };
|
|
1508
|
+
}
|
|
1509
|
+
// 5. First <svg> child's <title> element
|
|
1510
|
+
const svg = element.querySelector('svg');
|
|
1511
|
+
const svgTitle = svg === null || svg === void 0 ? void 0 : svg.querySelector('title');
|
|
1512
|
+
if ((_d = svgTitle === null || svgTitle === void 0 ? void 0 : svgTitle.textContent) === null || _d === void 0 ? void 0 : _d.trim()) {
|
|
1513
|
+
return { text: svgTitle.textContent.trim(), source: 'svg-title' };
|
|
1514
|
+
}
|
|
1515
|
+
return null;
|
|
1441
1516
|
}
|
|
1442
1517
|
// For other elements, get text content but limit it
|
|
1443
|
-
const text = ((
|
|
1444
|
-
|
|
1518
|
+
const text = ((_e = element.textContent) === null || _e === void 0 ? void 0 : _e.trim()) || '';
|
|
1519
|
+
if (!text)
|
|
1520
|
+
return null;
|
|
1521
|
+
const truncated = text.length > 50 ? text.substring(0, 47) + '...' : text;
|
|
1522
|
+
return { text: truncated, source: 'content' };
|
|
1445
1523
|
}
|
|
1446
1524
|
getElementsChain(element) {
|
|
1447
1525
|
var _a;
|
|
@@ -1515,6 +1593,92 @@ class AutocaptureTracker {
|
|
|
1515
1593
|
ids: ids.reverse()
|
|
1516
1594
|
};
|
|
1517
1595
|
}
|
|
1596
|
+
extractSemanticClasses(classList) {
|
|
1597
|
+
const results = new Set();
|
|
1598
|
+
for (let i = 0; i < classList.length; i++) {
|
|
1599
|
+
const cls = classList.item(i);
|
|
1600
|
+
if (!cls)
|
|
1601
|
+
continue;
|
|
1602
|
+
const parts = cls.split('__');
|
|
1603
|
+
if (parts.length >= 3) {
|
|
1604
|
+
// CSS module pattern: Module__hash__name → take last segment
|
|
1605
|
+
const last = parts[parts.length - 1];
|
|
1606
|
+
if (last)
|
|
1607
|
+
results.add(last);
|
|
1608
|
+
}
|
|
1609
|
+
else if (parts.length === 2) {
|
|
1610
|
+
// 2-part __ class (e.g., Module__hash) → drop, no semantic name
|
|
1611
|
+
continue;
|
|
1612
|
+
}
|
|
1613
|
+
else {
|
|
1614
|
+
// Single-part class — keep unless it looks like a hash
|
|
1615
|
+
if (!this.isHashLike(cls)) {
|
|
1616
|
+
results.add(cls);
|
|
1617
|
+
}
|
|
1618
|
+
}
|
|
1619
|
+
}
|
|
1620
|
+
return Array.from(results);
|
|
1621
|
+
}
|
|
1622
|
+
isHashLike(value) {
|
|
1623
|
+
// Hash-like: alphanumeric, 5-10 chars, contains both letters and digits
|
|
1624
|
+
return /^[a-zA-Z0-9]{5,10}$/.test(value)
|
|
1625
|
+
&& /[a-zA-Z]/.test(value)
|
|
1626
|
+
&& /[0-9]/.test(value);
|
|
1627
|
+
}
|
|
1628
|
+
getVisibleTextContent(element) {
|
|
1629
|
+
let text = '';
|
|
1630
|
+
for (let i = 0; i < element.childNodes.length; i++) {
|
|
1631
|
+
const child = element.childNodes.item(i);
|
|
1632
|
+
if (!child)
|
|
1633
|
+
continue;
|
|
1634
|
+
if (child.nodeType === Node.TEXT_NODE) {
|
|
1635
|
+
text += child.textContent || '';
|
|
1636
|
+
}
|
|
1637
|
+
else if (child.nodeType === Node.ELEMENT_NODE) {
|
|
1638
|
+
const el = child;
|
|
1639
|
+
if (el.tagName.toLowerCase() !== 'svg') {
|
|
1640
|
+
text += this.getVisibleTextContent(el);
|
|
1641
|
+
}
|
|
1642
|
+
}
|
|
1643
|
+
}
|
|
1644
|
+
return text.trim();
|
|
1645
|
+
}
|
|
1646
|
+
getElementState(element) {
|
|
1647
|
+
const state = {};
|
|
1648
|
+
// DOM properties
|
|
1649
|
+
if (element.disabled === true) {
|
|
1650
|
+
state.disabled = true;
|
|
1651
|
+
}
|
|
1652
|
+
else if (element.getAttribute('aria-disabled') === 'true') {
|
|
1653
|
+
state.disabled = true;
|
|
1654
|
+
}
|
|
1655
|
+
if (element.checked === true) {
|
|
1656
|
+
state.checked = true;
|
|
1657
|
+
}
|
|
1658
|
+
else if (element.getAttribute('aria-checked') === 'true') {
|
|
1659
|
+
state.checked = true;
|
|
1660
|
+
}
|
|
1661
|
+
if (element.getAttribute('aria-selected') === 'true') {
|
|
1662
|
+
state.selected = true;
|
|
1663
|
+
}
|
|
1664
|
+
if (element.getAttribute('aria-expanded') === 'true') {
|
|
1665
|
+
state.expanded = true;
|
|
1666
|
+
}
|
|
1667
|
+
return Object.keys(state).length > 0 ? state : null;
|
|
1668
|
+
}
|
|
1669
|
+
findInteractiveAncestor(element) {
|
|
1670
|
+
const interactiveTags = ['button', 'a', 'input', 'select', 'textarea'];
|
|
1671
|
+
let current = element;
|
|
1672
|
+
while (current && current !== document.body) {
|
|
1673
|
+
if (interactiveTags.includes(current.tagName.toLowerCase()) ||
|
|
1674
|
+
current.getAttribute('role') === 'button' ||
|
|
1675
|
+
current.getAttribute('role') === 'link') {
|
|
1676
|
+
return current;
|
|
1677
|
+
}
|
|
1678
|
+
current = current.parentElement;
|
|
1679
|
+
}
|
|
1680
|
+
return null;
|
|
1681
|
+
}
|
|
1518
1682
|
isSafeInputType(type) {
|
|
1519
1683
|
// Don't capture values for sensitive input types
|
|
1520
1684
|
const sensitiveTypes = ['password', 'email', 'tel', 'credit-card-number'];
|
|
@@ -1701,6 +1865,14 @@ class JourniumAnalytics {
|
|
|
1701
1865
|
}
|
|
1702
1866
|
/** Create and return a new JourniumAnalytics instance for the given config. */
|
|
1703
1867
|
const init = (config) => {
|
|
1868
|
+
var _a;
|
|
1869
|
+
// Set SDK version if not already set by a framework SDK (React, Next.js, Angular)
|
|
1870
|
+
if (!((_a = config.options) === null || _a === void 0 ? void 0 : _a._sdkVersion)) {
|
|
1871
|
+
config = {
|
|
1872
|
+
...config,
|
|
1873
|
+
options: { ...config.options, _sdkVersion: SDK_VERSION },
|
|
1874
|
+
};
|
|
1875
|
+
}
|
|
1704
1876
|
return new JourniumAnalytics(config);
|
|
1705
1877
|
};
|
|
1706
1878
|
|