cryptique-sdk 1.1.7 → 1.1.9
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/lib/cjs/index.js +170 -20
- package/lib/esm/index.js +170 -20
- package/lib/umd/index.js +170 -20
- package/package.json +1 -1
package/lib/cjs/index.js
CHANGED
|
@@ -6063,6 +6063,30 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
|
|
|
6063
6063
|
}
|
|
6064
6064
|
}
|
|
6065
6065
|
|
|
6066
|
+
// Build auto_event_data for custom events (heatmap/position context when possible)
|
|
6067
|
+
let customAutoEventData = {};
|
|
6068
|
+
if (typeof window !== 'undefined' && window.document) {
|
|
6069
|
+
const scrollX = window.scrollX != null ? window.scrollX : window.pageXOffset;
|
|
6070
|
+
const scrollY = window.scrollY != null ? window.scrollY : window.pageYOffset;
|
|
6071
|
+
const docHeight = Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
|
|
6072
|
+
const docWidth = Math.max(document.body.scrollWidth, document.documentElement.scrollWidth);
|
|
6073
|
+
customAutoEventData = {
|
|
6074
|
+
scroll_x: scrollX,
|
|
6075
|
+
scroll_y: scrollY,
|
|
6076
|
+
document_height: docHeight,
|
|
6077
|
+
document_width: docWidth
|
|
6078
|
+
};
|
|
6079
|
+
const srcEvent = options.sourceEvent;
|
|
6080
|
+
if (srcEvent && typeof srcEvent === 'object' && (srcEvent.pageX != null || srcEvent.clientX != null)) {
|
|
6081
|
+
customAutoEventData.page_x = srcEvent.pageX != null ? srcEvent.pageX : (srcEvent.clientX + (window.scrollX || window.pageXOffset || 0));
|
|
6082
|
+
customAutoEventData.page_y = srcEvent.pageY != null ? srcEvent.pageY : (srcEvent.clientY + (window.scrollY || window.pageYOffset || 0));
|
|
6083
|
+
customAutoEventData.click_coordinates = {
|
|
6084
|
+
x: srcEvent.clientX != null ? srcEvent.clientX : srcEvent.pageX - (window.scrollX || window.pageXOffset || 0),
|
|
6085
|
+
y: srcEvent.clientY != null ? srcEvent.clientY : srcEvent.pageY - (window.scrollY || window.pageYOffset || 0)
|
|
6086
|
+
};
|
|
6087
|
+
}
|
|
6088
|
+
}
|
|
6089
|
+
|
|
6066
6090
|
// Prepare event data
|
|
6067
6091
|
const eventData = {
|
|
6068
6092
|
event_type: 'custom',
|
|
@@ -6072,6 +6096,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
|
|
|
6072
6096
|
user_id: userId,
|
|
6073
6097
|
// Only include user-provided properties in custom_properties (filtered)
|
|
6074
6098
|
custom_properties: filteredProperties,
|
|
6099
|
+
auto_event_data: customAutoEventData,
|
|
6075
6100
|
// Page context and screen/viewport data go in page_data (not custom_properties)
|
|
6076
6101
|
page_data: {
|
|
6077
6102
|
current_url: window.location.href,
|
|
@@ -6886,7 +6911,18 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
|
|
|
6886
6911
|
if (element === lastClickElement && now - lastClickTime < 1000) {
|
|
6887
6912
|
clickCount++;
|
|
6888
6913
|
if (clickCount >= 3) {
|
|
6914
|
+
const scrollX = window.scrollX != null ? window.scrollX : window.pageXOffset;
|
|
6915
|
+
const scrollY = window.scrollY != null ? window.scrollY : window.pageYOffset;
|
|
6916
|
+
const docHeight = Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
|
|
6917
|
+
const docWidth = Math.max(document.body.scrollWidth, document.documentElement.scrollWidth);
|
|
6889
6918
|
EventsManager.trackAutoEvent('rage_click', {
|
|
6919
|
+
click_coordinates: { x: event.clientX, y: event.clientY },
|
|
6920
|
+
page_x: event.pageX,
|
|
6921
|
+
page_y: event.pageY,
|
|
6922
|
+
scroll_x: scrollX,
|
|
6923
|
+
scroll_y: scrollY,
|
|
6924
|
+
document_height: docHeight,
|
|
6925
|
+
document_width: docWidth,
|
|
6890
6926
|
click_count: clickCount,
|
|
6891
6927
|
time_span: now - lastClickTime,
|
|
6892
6928
|
element_area: element.offsetWidth * element.offsetHeight,
|
|
@@ -6903,11 +6939,15 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
|
|
|
6903
6939
|
const isInteractive = isInteractiveElement(element);
|
|
6904
6940
|
|
|
6905
6941
|
if (!isInteractive) {
|
|
6906
|
-
// Capture coordinates before setTimeout
|
|
6942
|
+
// Capture coordinates and page context before setTimeout (for heatmaps)
|
|
6907
6943
|
const clickX = event.clientX;
|
|
6908
6944
|
const clickY = event.clientY;
|
|
6909
6945
|
const clickElement = element;
|
|
6910
|
-
|
|
6946
|
+
const scrollX = window.scrollX != null ? window.scrollX : window.pageXOffset;
|
|
6947
|
+
const scrollY = window.scrollY != null ? window.scrollY : window.pageYOffset;
|
|
6948
|
+
const docHeight = Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
|
|
6949
|
+
const docWidth = Math.max(document.body.scrollWidth, document.documentElement.scrollWidth);
|
|
6950
|
+
|
|
6911
6951
|
// Mark this click as potentially dead
|
|
6912
6952
|
const clickId = `${now}_${Math.random().toString(36).substr(2, 9)}`;
|
|
6913
6953
|
pendingDeadClicks.set(clickId, {
|
|
@@ -6917,7 +6957,13 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
|
|
|
6917
6957
|
timestamp: now,
|
|
6918
6958
|
url: window.location.href,
|
|
6919
6959
|
clickX,
|
|
6920
|
-
clickY
|
|
6960
|
+
clickY,
|
|
6961
|
+
page_x: event.pageX,
|
|
6962
|
+
page_y: event.pageY,
|
|
6963
|
+
scroll_x: scrollX,
|
|
6964
|
+
scroll_y: scrollY,
|
|
6965
|
+
document_height: docHeight,
|
|
6966
|
+
document_width: docWidth
|
|
6921
6967
|
});
|
|
6922
6968
|
|
|
6923
6969
|
// Check after 1 second if navigation occurred or if it's still a dead click
|
|
@@ -6931,6 +6977,12 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
|
|
|
6931
6977
|
|
|
6932
6978
|
EventsManager.trackAutoEvent('dead_click', {
|
|
6933
6979
|
click_coordinates: { x: pendingClick.clickX, y: pendingClick.clickY },
|
|
6980
|
+
page_x: pendingClick.page_x,
|
|
6981
|
+
page_y: pendingClick.page_y,
|
|
6982
|
+
scroll_x: pendingClick.scroll_x,
|
|
6983
|
+
scroll_y: pendingClick.scroll_y,
|
|
6984
|
+
document_height: pendingClick.document_height,
|
|
6985
|
+
document_width: pendingClick.document_width,
|
|
6934
6986
|
element_area: clickElement.offsetWidth * clickElement.offsetHeight,
|
|
6935
6987
|
element_category: pendingClick.elementCategory,
|
|
6936
6988
|
element_has_onclick: !!clickElement.onclick,
|
|
@@ -6946,9 +6998,19 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
|
|
|
6946
6998
|
}, 1000);
|
|
6947
6999
|
}
|
|
6948
7000
|
|
|
6949
|
-
// Track regular click with enhanced data
|
|
7001
|
+
// Track regular click with enhanced data (viewport + page-relative for heatmaps)
|
|
7002
|
+
const scrollX = window.scrollX != null ? window.scrollX : window.pageXOffset;
|
|
7003
|
+
const scrollY = window.scrollY != null ? window.scrollY : window.pageYOffset;
|
|
7004
|
+
const docHeight = Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
|
|
7005
|
+
const docWidth = Math.max(document.body.scrollWidth, document.documentElement.scrollWidth);
|
|
6950
7006
|
EventsManager.trackAutoEvent('element_click', {
|
|
6951
7007
|
click_coordinates: { x: event.clientX, y: event.clientY },
|
|
7008
|
+
page_x: event.pageX,
|
|
7009
|
+
page_y: event.pageY,
|
|
7010
|
+
scroll_x: scrollX,
|
|
7011
|
+
scroll_y: scrollY,
|
|
7012
|
+
document_height: docHeight,
|
|
7013
|
+
document_width: docWidth,
|
|
6952
7014
|
double_click: event.detail === 2,
|
|
6953
7015
|
element_category: elementCategory
|
|
6954
7016
|
}, elementData).catch(err => {
|
|
@@ -6973,15 +7035,22 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
|
|
|
6973
7035
|
clearTimeout(scrollTimeout);
|
|
6974
7036
|
|
|
6975
7037
|
scrollTimeout = setTimeout(() => {
|
|
6976
|
-
const
|
|
6977
|
-
|
|
7038
|
+
const maxScroll = Math.max(document.body.scrollHeight, document.documentElement.scrollHeight) - window.innerHeight;
|
|
7039
|
+
const scrollDepth = maxScroll <= 0 ? 100 : Math.round((window.scrollY / maxScroll) * 100);
|
|
7040
|
+
|
|
6978
7041
|
if (scrollDepth > maxScrollDepth) {
|
|
6979
7042
|
maxScrollDepth = scrollDepth;
|
|
6980
|
-
|
|
7043
|
+
const scrollX = window.scrollX != null ? window.scrollX : window.pageXOffset;
|
|
7044
|
+
const docHeight = Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
|
|
7045
|
+
const docWidth = Math.max(document.body.scrollWidth, document.documentElement.scrollWidth);
|
|
6981
7046
|
EventsManager.trackAutoEvent('page_scroll', {
|
|
6982
7047
|
scroll_depth: scrollDepth,
|
|
6983
7048
|
max_scroll_reached: maxScrollDepth,
|
|
6984
|
-
scroll_position: window.scrollY
|
|
7049
|
+
scroll_position: window.scrollY,
|
|
7050
|
+
scroll_x: scrollX,
|
|
7051
|
+
scroll_y: window.scrollY,
|
|
7052
|
+
document_height: docHeight,
|
|
7053
|
+
document_width: docWidth
|
|
6985
7054
|
}).catch(err => {
|
|
6986
7055
|
console.error('❌ [AutoEvents] Failed to track page_scroll:', err);
|
|
6987
7056
|
});
|
|
@@ -6999,10 +7068,24 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
|
|
|
6999
7068
|
document.addEventListener('submit', (event) => {
|
|
7000
7069
|
const form = event.target;
|
|
7001
7070
|
if (form.tagName === 'FORM') {
|
|
7071
|
+
const scrollX = window.scrollX != null ? window.scrollX : window.pageXOffset;
|
|
7072
|
+
const scrollY = window.scrollY != null ? window.scrollY : window.pageYOffset;
|
|
7073
|
+
const docHeight = Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
|
|
7074
|
+
const docWidth = Math.max(document.body.scrollWidth, document.documentElement.scrollWidth);
|
|
7075
|
+
const rect = form.getBoundingClientRect();
|
|
7076
|
+
const pageX = rect.left + scrollX;
|
|
7077
|
+
const pageY = rect.top + scrollY;
|
|
7002
7078
|
EventsManager.trackAutoEvent('form_submit', {
|
|
7003
7079
|
form_id: form.id || null,
|
|
7004
7080
|
form_action: form.action || null,
|
|
7005
|
-
form_method: form.method || 'get'
|
|
7081
|
+
form_method: form.method || 'get',
|
|
7082
|
+
scroll_x: scrollX,
|
|
7083
|
+
scroll_y: scrollY,
|
|
7084
|
+
document_height: docHeight,
|
|
7085
|
+
document_width: docWidth,
|
|
7086
|
+
page_x: pageX,
|
|
7087
|
+
page_y: pageY,
|
|
7088
|
+
click_coordinates: { x: event.clientX != null ? event.clientX : rect.left + rect.width / 2, y: event.clientY != null ? event.clientY : rect.top + rect.height / 2 }
|
|
7006
7089
|
}, {
|
|
7007
7090
|
element_tag_name: 'form',
|
|
7008
7091
|
element_id: form.id || null,
|
|
@@ -7011,8 +7094,8 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
|
|
|
7011
7094
|
element_type: form.method || 'get', // FIX: Added element_type (form method)
|
|
7012
7095
|
element_text: form.textContent?.trim().substring(0, 100) || null, // FIX: Added element_text
|
|
7013
7096
|
element_position: { // FIX: Added element_position
|
|
7014
|
-
x: event.clientX ||
|
|
7015
|
-
y: event.clientY ||
|
|
7097
|
+
x: event.clientX || rect.left,
|
|
7098
|
+
y: event.clientY || rect.top,
|
|
7016
7099
|
width: form.offsetWidth || 0,
|
|
7017
7100
|
height: form.offsetHeight || 0
|
|
7018
7101
|
}
|
|
@@ -7024,10 +7107,24 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
|
|
|
7024
7107
|
document.addEventListener('focus', (event) => {
|
|
7025
7108
|
const element = event.target;
|
|
7026
7109
|
if (element.tagName === 'INPUT' || element.tagName === 'TEXTAREA' || element.tagName === 'SELECT') {
|
|
7110
|
+
const scrollX = window.scrollX != null ? window.scrollX : window.pageXOffset;
|
|
7111
|
+
const scrollY = window.scrollY != null ? window.scrollY : window.pageYOffset;
|
|
7112
|
+
const docHeight = Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
|
|
7113
|
+
const docWidth = Math.max(document.body.scrollWidth, document.documentElement.scrollWidth);
|
|
7114
|
+
const rect = element.getBoundingClientRect();
|
|
7115
|
+
const pageX = rect.left + scrollX;
|
|
7116
|
+
const pageY = rect.top + scrollY;
|
|
7027
7117
|
EventsManager.trackAutoEvent('form_focus', {
|
|
7028
7118
|
field_name: element.name || null,
|
|
7029
7119
|
field_type: element.type || null,
|
|
7030
|
-
field_id: element.id || null
|
|
7120
|
+
field_id: element.id || null,
|
|
7121
|
+
scroll_x: scrollX,
|
|
7122
|
+
scroll_y: scrollY,
|
|
7123
|
+
document_height: docHeight,
|
|
7124
|
+
document_width: docWidth,
|
|
7125
|
+
page_x: pageX,
|
|
7126
|
+
page_y: pageY,
|
|
7127
|
+
click_coordinates: { x: event.clientX != null ? event.clientX : rect.left + rect.width / 2, y: event.clientY != null ? event.clientY : rect.top + rect.height / 2 }
|
|
7031
7128
|
}, {
|
|
7032
7129
|
element_tag_name: element.tagName.toLowerCase(),
|
|
7033
7130
|
element_id: element.id || null,
|
|
@@ -7036,8 +7133,8 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
|
|
|
7036
7133
|
element_type: element.type || null,
|
|
7037
7134
|
element_text: element.value ? element.value.toString().trim().substring(0, 100) : null, // FIX: Added element_text (value for form fields)
|
|
7038
7135
|
element_position: { // FIX: Added element_position
|
|
7039
|
-
x: event.clientX
|
|
7040
|
-
y: event.clientY
|
|
7136
|
+
x: event.clientX != null ? event.clientX : rect.left,
|
|
7137
|
+
y: event.clientY != null ? event.clientY : rect.top,
|
|
7041
7138
|
width: element.offsetWidth || 0,
|
|
7042
7139
|
height: element.offsetHeight || 0
|
|
7043
7140
|
}
|
|
@@ -7050,23 +7147,54 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
|
|
|
7050
7147
|
* Setup media tracking
|
|
7051
7148
|
*/
|
|
7052
7149
|
setupMediaTracking() {
|
|
7150
|
+
function getPageContext() {
|
|
7151
|
+
const scrollX = window.scrollX != null ? window.scrollX : window.pageXOffset;
|
|
7152
|
+
const scrollY = window.scrollY != null ? window.scrollY : window.pageYOffset;
|
|
7153
|
+
const docHeight = Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
|
|
7154
|
+
const docWidth = Math.max(document.body.scrollWidth, document.documentElement.scrollWidth);
|
|
7155
|
+
return { scrollX, scrollY, docHeight, docWidth };
|
|
7156
|
+
}
|
|
7053
7157
|
['video', 'audio'].forEach(mediaType => {
|
|
7054
7158
|
document.addEventListener('play', (event) => {
|
|
7055
7159
|
if (event.target.tagName.toLowerCase() === mediaType) {
|
|
7160
|
+
const el = event.target;
|
|
7161
|
+
const { scrollX, scrollY, docHeight, docWidth } = getPageContext();
|
|
7162
|
+
const rect = el.getBoundingClientRect();
|
|
7163
|
+
const pageX = rect.left + scrollX;
|
|
7164
|
+
const pageY = rect.top + scrollY;
|
|
7056
7165
|
EventsManager.trackAutoEvent('media_play', {
|
|
7057
7166
|
media_type: mediaType,
|
|
7058
|
-
media_src:
|
|
7059
|
-
media_duration:
|
|
7167
|
+
media_src: el.src || null,
|
|
7168
|
+
media_duration: el.duration || null,
|
|
7169
|
+
scroll_x: scrollX,
|
|
7170
|
+
scroll_y: scrollY,
|
|
7171
|
+
document_height: docHeight,
|
|
7172
|
+
document_width: docWidth,
|
|
7173
|
+
page_x: pageX,
|
|
7174
|
+
page_y: pageY,
|
|
7175
|
+
click_coordinates: { x: rect.left + rect.width / 2, y: rect.top + rect.height / 2 }
|
|
7060
7176
|
});
|
|
7061
7177
|
}
|
|
7062
7178
|
}, true);
|
|
7063
7179
|
|
|
7064
7180
|
document.addEventListener('pause', (event) => {
|
|
7065
7181
|
if (event.target.tagName.toLowerCase() === mediaType) {
|
|
7182
|
+
const el = event.target;
|
|
7183
|
+
const { scrollX, scrollY, docHeight, docWidth } = getPageContext();
|
|
7184
|
+
const rect = el.getBoundingClientRect();
|
|
7185
|
+
const pageX = rect.left + scrollX;
|
|
7186
|
+
const pageY = rect.top + scrollY;
|
|
7066
7187
|
EventsManager.trackAutoEvent('media_pause', {
|
|
7067
7188
|
media_type: mediaType,
|
|
7068
|
-
media_current_time:
|
|
7069
|
-
media_duration:
|
|
7189
|
+
media_current_time: el.currentTime || null,
|
|
7190
|
+
media_duration: el.duration || null,
|
|
7191
|
+
scroll_x: scrollX,
|
|
7192
|
+
scroll_y: scrollY,
|
|
7193
|
+
document_height: docHeight,
|
|
7194
|
+
document_width: docWidth,
|
|
7195
|
+
page_x: pageX,
|
|
7196
|
+
page_y: pageY,
|
|
7197
|
+
click_coordinates: { x: rect.left + rect.width / 2, y: rect.top + rect.height / 2 }
|
|
7070
7198
|
});
|
|
7071
7199
|
}
|
|
7072
7200
|
}, true);
|
|
@@ -7148,11 +7276,33 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
|
|
|
7148
7276
|
focus_offset: selection.focusOffset || null
|
|
7149
7277
|
};
|
|
7150
7278
|
|
|
7151
|
-
// Get page context
|
|
7279
|
+
// Get page context and selection position for heatmaps
|
|
7280
|
+
const scrollX = window.scrollX != null ? window.scrollX : window.pageXOffset;
|
|
7281
|
+
const scrollY = window.scrollY != null ? window.scrollY : window.pageYOffset;
|
|
7282
|
+
const docHeight = Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
|
|
7283
|
+
const docWidth = Math.max(document.body.scrollWidth, document.documentElement.scrollWidth);
|
|
7284
|
+
let pageX = null;
|
|
7285
|
+
let pageY = null;
|
|
7286
|
+
if (range) {
|
|
7287
|
+
try {
|
|
7288
|
+
const selRect = range.getBoundingClientRect();
|
|
7289
|
+
if (selRect.width > 0 || selRect.height > 0) {
|
|
7290
|
+
pageX = selRect.left + scrollX;
|
|
7291
|
+
pageY = selRect.top + scrollY;
|
|
7292
|
+
}
|
|
7293
|
+
} catch (e) { /* getBoundingClientRect can throw in some edge cases */ }
|
|
7294
|
+
}
|
|
7152
7295
|
const pageData = {
|
|
7153
7296
|
page_url: window.location.href,
|
|
7154
7297
|
page_title: document.title,
|
|
7155
|
-
page_path: window.location.pathname
|
|
7298
|
+
page_path: window.location.pathname,
|
|
7299
|
+
scroll_x: scrollX,
|
|
7300
|
+
scroll_y: scrollY,
|
|
7301
|
+
document_height: docHeight,
|
|
7302
|
+
document_width: docWidth,
|
|
7303
|
+
page_x: pageX,
|
|
7304
|
+
page_y: pageY,
|
|
7305
|
+
click_coordinates: pageX != null && pageY != null ? { x: pageX - scrollX, y: pageY - scrollY } : null
|
|
7156
7306
|
};
|
|
7157
7307
|
|
|
7158
7308
|
EventsManager.trackAutoEvent('text_selection', {
|
package/lib/esm/index.js
CHANGED
|
@@ -6061,6 +6061,30 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
|
|
|
6061
6061
|
}
|
|
6062
6062
|
}
|
|
6063
6063
|
|
|
6064
|
+
// Build auto_event_data for custom events (heatmap/position context when possible)
|
|
6065
|
+
let customAutoEventData = {};
|
|
6066
|
+
if (typeof window !== 'undefined' && window.document) {
|
|
6067
|
+
const scrollX = window.scrollX != null ? window.scrollX : window.pageXOffset;
|
|
6068
|
+
const scrollY = window.scrollY != null ? window.scrollY : window.pageYOffset;
|
|
6069
|
+
const docHeight = Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
|
|
6070
|
+
const docWidth = Math.max(document.body.scrollWidth, document.documentElement.scrollWidth);
|
|
6071
|
+
customAutoEventData = {
|
|
6072
|
+
scroll_x: scrollX,
|
|
6073
|
+
scroll_y: scrollY,
|
|
6074
|
+
document_height: docHeight,
|
|
6075
|
+
document_width: docWidth
|
|
6076
|
+
};
|
|
6077
|
+
const srcEvent = options.sourceEvent;
|
|
6078
|
+
if (srcEvent && typeof srcEvent === 'object' && (srcEvent.pageX != null || srcEvent.clientX != null)) {
|
|
6079
|
+
customAutoEventData.page_x = srcEvent.pageX != null ? srcEvent.pageX : (srcEvent.clientX + (window.scrollX || window.pageXOffset || 0));
|
|
6080
|
+
customAutoEventData.page_y = srcEvent.pageY != null ? srcEvent.pageY : (srcEvent.clientY + (window.scrollY || window.pageYOffset || 0));
|
|
6081
|
+
customAutoEventData.click_coordinates = {
|
|
6082
|
+
x: srcEvent.clientX != null ? srcEvent.clientX : srcEvent.pageX - (window.scrollX || window.pageXOffset || 0),
|
|
6083
|
+
y: srcEvent.clientY != null ? srcEvent.clientY : srcEvent.pageY - (window.scrollY || window.pageYOffset || 0)
|
|
6084
|
+
};
|
|
6085
|
+
}
|
|
6086
|
+
}
|
|
6087
|
+
|
|
6064
6088
|
// Prepare event data
|
|
6065
6089
|
const eventData = {
|
|
6066
6090
|
event_type: 'custom',
|
|
@@ -6070,6 +6094,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
|
|
|
6070
6094
|
user_id: userId,
|
|
6071
6095
|
// Only include user-provided properties in custom_properties (filtered)
|
|
6072
6096
|
custom_properties: filteredProperties,
|
|
6097
|
+
auto_event_data: customAutoEventData,
|
|
6073
6098
|
// Page context and screen/viewport data go in page_data (not custom_properties)
|
|
6074
6099
|
page_data: {
|
|
6075
6100
|
current_url: window.location.href,
|
|
@@ -6884,7 +6909,18 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
|
|
|
6884
6909
|
if (element === lastClickElement && now - lastClickTime < 1000) {
|
|
6885
6910
|
clickCount++;
|
|
6886
6911
|
if (clickCount >= 3) {
|
|
6912
|
+
const scrollX = window.scrollX != null ? window.scrollX : window.pageXOffset;
|
|
6913
|
+
const scrollY = window.scrollY != null ? window.scrollY : window.pageYOffset;
|
|
6914
|
+
const docHeight = Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
|
|
6915
|
+
const docWidth = Math.max(document.body.scrollWidth, document.documentElement.scrollWidth);
|
|
6887
6916
|
EventsManager.trackAutoEvent('rage_click', {
|
|
6917
|
+
click_coordinates: { x: event.clientX, y: event.clientY },
|
|
6918
|
+
page_x: event.pageX,
|
|
6919
|
+
page_y: event.pageY,
|
|
6920
|
+
scroll_x: scrollX,
|
|
6921
|
+
scroll_y: scrollY,
|
|
6922
|
+
document_height: docHeight,
|
|
6923
|
+
document_width: docWidth,
|
|
6888
6924
|
click_count: clickCount,
|
|
6889
6925
|
time_span: now - lastClickTime,
|
|
6890
6926
|
element_area: element.offsetWidth * element.offsetHeight,
|
|
@@ -6901,11 +6937,15 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
|
|
|
6901
6937
|
const isInteractive = isInteractiveElement(element);
|
|
6902
6938
|
|
|
6903
6939
|
if (!isInteractive) {
|
|
6904
|
-
// Capture coordinates before setTimeout
|
|
6940
|
+
// Capture coordinates and page context before setTimeout (for heatmaps)
|
|
6905
6941
|
const clickX = event.clientX;
|
|
6906
6942
|
const clickY = event.clientY;
|
|
6907
6943
|
const clickElement = element;
|
|
6908
|
-
|
|
6944
|
+
const scrollX = window.scrollX != null ? window.scrollX : window.pageXOffset;
|
|
6945
|
+
const scrollY = window.scrollY != null ? window.scrollY : window.pageYOffset;
|
|
6946
|
+
const docHeight = Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
|
|
6947
|
+
const docWidth = Math.max(document.body.scrollWidth, document.documentElement.scrollWidth);
|
|
6948
|
+
|
|
6909
6949
|
// Mark this click as potentially dead
|
|
6910
6950
|
const clickId = `${now}_${Math.random().toString(36).substr(2, 9)}`;
|
|
6911
6951
|
pendingDeadClicks.set(clickId, {
|
|
@@ -6915,7 +6955,13 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
|
|
|
6915
6955
|
timestamp: now,
|
|
6916
6956
|
url: window.location.href,
|
|
6917
6957
|
clickX,
|
|
6918
|
-
clickY
|
|
6958
|
+
clickY,
|
|
6959
|
+
page_x: event.pageX,
|
|
6960
|
+
page_y: event.pageY,
|
|
6961
|
+
scroll_x: scrollX,
|
|
6962
|
+
scroll_y: scrollY,
|
|
6963
|
+
document_height: docHeight,
|
|
6964
|
+
document_width: docWidth
|
|
6919
6965
|
});
|
|
6920
6966
|
|
|
6921
6967
|
// Check after 1 second if navigation occurred or if it's still a dead click
|
|
@@ -6929,6 +6975,12 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
|
|
|
6929
6975
|
|
|
6930
6976
|
EventsManager.trackAutoEvent('dead_click', {
|
|
6931
6977
|
click_coordinates: { x: pendingClick.clickX, y: pendingClick.clickY },
|
|
6978
|
+
page_x: pendingClick.page_x,
|
|
6979
|
+
page_y: pendingClick.page_y,
|
|
6980
|
+
scroll_x: pendingClick.scroll_x,
|
|
6981
|
+
scroll_y: pendingClick.scroll_y,
|
|
6982
|
+
document_height: pendingClick.document_height,
|
|
6983
|
+
document_width: pendingClick.document_width,
|
|
6932
6984
|
element_area: clickElement.offsetWidth * clickElement.offsetHeight,
|
|
6933
6985
|
element_category: pendingClick.elementCategory,
|
|
6934
6986
|
element_has_onclick: !!clickElement.onclick,
|
|
@@ -6944,9 +6996,19 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
|
|
|
6944
6996
|
}, 1000);
|
|
6945
6997
|
}
|
|
6946
6998
|
|
|
6947
|
-
// Track regular click with enhanced data
|
|
6999
|
+
// Track regular click with enhanced data (viewport + page-relative for heatmaps)
|
|
7000
|
+
const scrollX = window.scrollX != null ? window.scrollX : window.pageXOffset;
|
|
7001
|
+
const scrollY = window.scrollY != null ? window.scrollY : window.pageYOffset;
|
|
7002
|
+
const docHeight = Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
|
|
7003
|
+
const docWidth = Math.max(document.body.scrollWidth, document.documentElement.scrollWidth);
|
|
6948
7004
|
EventsManager.trackAutoEvent('element_click', {
|
|
6949
7005
|
click_coordinates: { x: event.clientX, y: event.clientY },
|
|
7006
|
+
page_x: event.pageX,
|
|
7007
|
+
page_y: event.pageY,
|
|
7008
|
+
scroll_x: scrollX,
|
|
7009
|
+
scroll_y: scrollY,
|
|
7010
|
+
document_height: docHeight,
|
|
7011
|
+
document_width: docWidth,
|
|
6950
7012
|
double_click: event.detail === 2,
|
|
6951
7013
|
element_category: elementCategory
|
|
6952
7014
|
}, elementData).catch(err => {
|
|
@@ -6971,15 +7033,22 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
|
|
|
6971
7033
|
clearTimeout(scrollTimeout);
|
|
6972
7034
|
|
|
6973
7035
|
scrollTimeout = setTimeout(() => {
|
|
6974
|
-
const
|
|
6975
|
-
|
|
7036
|
+
const maxScroll = Math.max(document.body.scrollHeight, document.documentElement.scrollHeight) - window.innerHeight;
|
|
7037
|
+
const scrollDepth = maxScroll <= 0 ? 100 : Math.round((window.scrollY / maxScroll) * 100);
|
|
7038
|
+
|
|
6976
7039
|
if (scrollDepth > maxScrollDepth) {
|
|
6977
7040
|
maxScrollDepth = scrollDepth;
|
|
6978
|
-
|
|
7041
|
+
const scrollX = window.scrollX != null ? window.scrollX : window.pageXOffset;
|
|
7042
|
+
const docHeight = Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
|
|
7043
|
+
const docWidth = Math.max(document.body.scrollWidth, document.documentElement.scrollWidth);
|
|
6979
7044
|
EventsManager.trackAutoEvent('page_scroll', {
|
|
6980
7045
|
scroll_depth: scrollDepth,
|
|
6981
7046
|
max_scroll_reached: maxScrollDepth,
|
|
6982
|
-
scroll_position: window.scrollY
|
|
7047
|
+
scroll_position: window.scrollY,
|
|
7048
|
+
scroll_x: scrollX,
|
|
7049
|
+
scroll_y: window.scrollY,
|
|
7050
|
+
document_height: docHeight,
|
|
7051
|
+
document_width: docWidth
|
|
6983
7052
|
}).catch(err => {
|
|
6984
7053
|
console.error('❌ [AutoEvents] Failed to track page_scroll:', err);
|
|
6985
7054
|
});
|
|
@@ -6997,10 +7066,24 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
|
|
|
6997
7066
|
document.addEventListener('submit', (event) => {
|
|
6998
7067
|
const form = event.target;
|
|
6999
7068
|
if (form.tagName === 'FORM') {
|
|
7069
|
+
const scrollX = window.scrollX != null ? window.scrollX : window.pageXOffset;
|
|
7070
|
+
const scrollY = window.scrollY != null ? window.scrollY : window.pageYOffset;
|
|
7071
|
+
const docHeight = Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
|
|
7072
|
+
const docWidth = Math.max(document.body.scrollWidth, document.documentElement.scrollWidth);
|
|
7073
|
+
const rect = form.getBoundingClientRect();
|
|
7074
|
+
const pageX = rect.left + scrollX;
|
|
7075
|
+
const pageY = rect.top + scrollY;
|
|
7000
7076
|
EventsManager.trackAutoEvent('form_submit', {
|
|
7001
7077
|
form_id: form.id || null,
|
|
7002
7078
|
form_action: form.action || null,
|
|
7003
|
-
form_method: form.method || 'get'
|
|
7079
|
+
form_method: form.method || 'get',
|
|
7080
|
+
scroll_x: scrollX,
|
|
7081
|
+
scroll_y: scrollY,
|
|
7082
|
+
document_height: docHeight,
|
|
7083
|
+
document_width: docWidth,
|
|
7084
|
+
page_x: pageX,
|
|
7085
|
+
page_y: pageY,
|
|
7086
|
+
click_coordinates: { x: event.clientX != null ? event.clientX : rect.left + rect.width / 2, y: event.clientY != null ? event.clientY : rect.top + rect.height / 2 }
|
|
7004
7087
|
}, {
|
|
7005
7088
|
element_tag_name: 'form',
|
|
7006
7089
|
element_id: form.id || null,
|
|
@@ -7009,8 +7092,8 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
|
|
|
7009
7092
|
element_type: form.method || 'get', // FIX: Added element_type (form method)
|
|
7010
7093
|
element_text: form.textContent?.trim().substring(0, 100) || null, // FIX: Added element_text
|
|
7011
7094
|
element_position: { // FIX: Added element_position
|
|
7012
|
-
x: event.clientX ||
|
|
7013
|
-
y: event.clientY ||
|
|
7095
|
+
x: event.clientX || rect.left,
|
|
7096
|
+
y: event.clientY || rect.top,
|
|
7014
7097
|
width: form.offsetWidth || 0,
|
|
7015
7098
|
height: form.offsetHeight || 0
|
|
7016
7099
|
}
|
|
@@ -7022,10 +7105,24 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
|
|
|
7022
7105
|
document.addEventListener('focus', (event) => {
|
|
7023
7106
|
const element = event.target;
|
|
7024
7107
|
if (element.tagName === 'INPUT' || element.tagName === 'TEXTAREA' || element.tagName === 'SELECT') {
|
|
7108
|
+
const scrollX = window.scrollX != null ? window.scrollX : window.pageXOffset;
|
|
7109
|
+
const scrollY = window.scrollY != null ? window.scrollY : window.pageYOffset;
|
|
7110
|
+
const docHeight = Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
|
|
7111
|
+
const docWidth = Math.max(document.body.scrollWidth, document.documentElement.scrollWidth);
|
|
7112
|
+
const rect = element.getBoundingClientRect();
|
|
7113
|
+
const pageX = rect.left + scrollX;
|
|
7114
|
+
const pageY = rect.top + scrollY;
|
|
7025
7115
|
EventsManager.trackAutoEvent('form_focus', {
|
|
7026
7116
|
field_name: element.name || null,
|
|
7027
7117
|
field_type: element.type || null,
|
|
7028
|
-
field_id: element.id || null
|
|
7118
|
+
field_id: element.id || null,
|
|
7119
|
+
scroll_x: scrollX,
|
|
7120
|
+
scroll_y: scrollY,
|
|
7121
|
+
document_height: docHeight,
|
|
7122
|
+
document_width: docWidth,
|
|
7123
|
+
page_x: pageX,
|
|
7124
|
+
page_y: pageY,
|
|
7125
|
+
click_coordinates: { x: event.clientX != null ? event.clientX : rect.left + rect.width / 2, y: event.clientY != null ? event.clientY : rect.top + rect.height / 2 }
|
|
7029
7126
|
}, {
|
|
7030
7127
|
element_tag_name: element.tagName.toLowerCase(),
|
|
7031
7128
|
element_id: element.id || null,
|
|
@@ -7034,8 +7131,8 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
|
|
|
7034
7131
|
element_type: element.type || null,
|
|
7035
7132
|
element_text: element.value ? element.value.toString().trim().substring(0, 100) : null, // FIX: Added element_text (value for form fields)
|
|
7036
7133
|
element_position: { // FIX: Added element_position
|
|
7037
|
-
x: event.clientX
|
|
7038
|
-
y: event.clientY
|
|
7134
|
+
x: event.clientX != null ? event.clientX : rect.left,
|
|
7135
|
+
y: event.clientY != null ? event.clientY : rect.top,
|
|
7039
7136
|
width: element.offsetWidth || 0,
|
|
7040
7137
|
height: element.offsetHeight || 0
|
|
7041
7138
|
}
|
|
@@ -7048,23 +7145,54 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
|
|
|
7048
7145
|
* Setup media tracking
|
|
7049
7146
|
*/
|
|
7050
7147
|
setupMediaTracking() {
|
|
7148
|
+
function getPageContext() {
|
|
7149
|
+
const scrollX = window.scrollX != null ? window.scrollX : window.pageXOffset;
|
|
7150
|
+
const scrollY = window.scrollY != null ? window.scrollY : window.pageYOffset;
|
|
7151
|
+
const docHeight = Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
|
|
7152
|
+
const docWidth = Math.max(document.body.scrollWidth, document.documentElement.scrollWidth);
|
|
7153
|
+
return { scrollX, scrollY, docHeight, docWidth };
|
|
7154
|
+
}
|
|
7051
7155
|
['video', 'audio'].forEach(mediaType => {
|
|
7052
7156
|
document.addEventListener('play', (event) => {
|
|
7053
7157
|
if (event.target.tagName.toLowerCase() === mediaType) {
|
|
7158
|
+
const el = event.target;
|
|
7159
|
+
const { scrollX, scrollY, docHeight, docWidth } = getPageContext();
|
|
7160
|
+
const rect = el.getBoundingClientRect();
|
|
7161
|
+
const pageX = rect.left + scrollX;
|
|
7162
|
+
const pageY = rect.top + scrollY;
|
|
7054
7163
|
EventsManager.trackAutoEvent('media_play', {
|
|
7055
7164
|
media_type: mediaType,
|
|
7056
|
-
media_src:
|
|
7057
|
-
media_duration:
|
|
7165
|
+
media_src: el.src || null,
|
|
7166
|
+
media_duration: el.duration || null,
|
|
7167
|
+
scroll_x: scrollX,
|
|
7168
|
+
scroll_y: scrollY,
|
|
7169
|
+
document_height: docHeight,
|
|
7170
|
+
document_width: docWidth,
|
|
7171
|
+
page_x: pageX,
|
|
7172
|
+
page_y: pageY,
|
|
7173
|
+
click_coordinates: { x: rect.left + rect.width / 2, y: rect.top + rect.height / 2 }
|
|
7058
7174
|
});
|
|
7059
7175
|
}
|
|
7060
7176
|
}, true);
|
|
7061
7177
|
|
|
7062
7178
|
document.addEventListener('pause', (event) => {
|
|
7063
7179
|
if (event.target.tagName.toLowerCase() === mediaType) {
|
|
7180
|
+
const el = event.target;
|
|
7181
|
+
const { scrollX, scrollY, docHeight, docWidth } = getPageContext();
|
|
7182
|
+
const rect = el.getBoundingClientRect();
|
|
7183
|
+
const pageX = rect.left + scrollX;
|
|
7184
|
+
const pageY = rect.top + scrollY;
|
|
7064
7185
|
EventsManager.trackAutoEvent('media_pause', {
|
|
7065
7186
|
media_type: mediaType,
|
|
7066
|
-
media_current_time:
|
|
7067
|
-
media_duration:
|
|
7187
|
+
media_current_time: el.currentTime || null,
|
|
7188
|
+
media_duration: el.duration || null,
|
|
7189
|
+
scroll_x: scrollX,
|
|
7190
|
+
scroll_y: scrollY,
|
|
7191
|
+
document_height: docHeight,
|
|
7192
|
+
document_width: docWidth,
|
|
7193
|
+
page_x: pageX,
|
|
7194
|
+
page_y: pageY,
|
|
7195
|
+
click_coordinates: { x: rect.left + rect.width / 2, y: rect.top + rect.height / 2 }
|
|
7068
7196
|
});
|
|
7069
7197
|
}
|
|
7070
7198
|
}, true);
|
|
@@ -7146,11 +7274,33 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
|
|
|
7146
7274
|
focus_offset: selection.focusOffset || null
|
|
7147
7275
|
};
|
|
7148
7276
|
|
|
7149
|
-
// Get page context
|
|
7277
|
+
// Get page context and selection position for heatmaps
|
|
7278
|
+
const scrollX = window.scrollX != null ? window.scrollX : window.pageXOffset;
|
|
7279
|
+
const scrollY = window.scrollY != null ? window.scrollY : window.pageYOffset;
|
|
7280
|
+
const docHeight = Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
|
|
7281
|
+
const docWidth = Math.max(document.body.scrollWidth, document.documentElement.scrollWidth);
|
|
7282
|
+
let pageX = null;
|
|
7283
|
+
let pageY = null;
|
|
7284
|
+
if (range) {
|
|
7285
|
+
try {
|
|
7286
|
+
const selRect = range.getBoundingClientRect();
|
|
7287
|
+
if (selRect.width > 0 || selRect.height > 0) {
|
|
7288
|
+
pageX = selRect.left + scrollX;
|
|
7289
|
+
pageY = selRect.top + scrollY;
|
|
7290
|
+
}
|
|
7291
|
+
} catch (e) { /* getBoundingClientRect can throw in some edge cases */ }
|
|
7292
|
+
}
|
|
7150
7293
|
const pageData = {
|
|
7151
7294
|
page_url: window.location.href,
|
|
7152
7295
|
page_title: document.title,
|
|
7153
|
-
page_path: window.location.pathname
|
|
7296
|
+
page_path: window.location.pathname,
|
|
7297
|
+
scroll_x: scrollX,
|
|
7298
|
+
scroll_y: scrollY,
|
|
7299
|
+
document_height: docHeight,
|
|
7300
|
+
document_width: docWidth,
|
|
7301
|
+
page_x: pageX,
|
|
7302
|
+
page_y: pageY,
|
|
7303
|
+
click_coordinates: pageX != null && pageY != null ? { x: pageX - scrollX, y: pageY - scrollY } : null
|
|
7154
7304
|
};
|
|
7155
7305
|
|
|
7156
7306
|
EventsManager.trackAutoEvent('text_selection', {
|
package/lib/umd/index.js
CHANGED
|
@@ -6067,6 +6067,30 @@
|
|
|
6067
6067
|
}
|
|
6068
6068
|
}
|
|
6069
6069
|
|
|
6070
|
+
// Build auto_event_data for custom events (heatmap/position context when possible)
|
|
6071
|
+
let customAutoEventData = {};
|
|
6072
|
+
if (typeof window !== 'undefined' && window.document) {
|
|
6073
|
+
const scrollX = window.scrollX != null ? window.scrollX : window.pageXOffset;
|
|
6074
|
+
const scrollY = window.scrollY != null ? window.scrollY : window.pageYOffset;
|
|
6075
|
+
const docHeight = Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
|
|
6076
|
+
const docWidth = Math.max(document.body.scrollWidth, document.documentElement.scrollWidth);
|
|
6077
|
+
customAutoEventData = {
|
|
6078
|
+
scroll_x: scrollX,
|
|
6079
|
+
scroll_y: scrollY,
|
|
6080
|
+
document_height: docHeight,
|
|
6081
|
+
document_width: docWidth
|
|
6082
|
+
};
|
|
6083
|
+
const srcEvent = options.sourceEvent;
|
|
6084
|
+
if (srcEvent && typeof srcEvent === 'object' && (srcEvent.pageX != null || srcEvent.clientX != null)) {
|
|
6085
|
+
customAutoEventData.page_x = srcEvent.pageX != null ? srcEvent.pageX : (srcEvent.clientX + (window.scrollX || window.pageXOffset || 0));
|
|
6086
|
+
customAutoEventData.page_y = srcEvent.pageY != null ? srcEvent.pageY : (srcEvent.clientY + (window.scrollY || window.pageYOffset || 0));
|
|
6087
|
+
customAutoEventData.click_coordinates = {
|
|
6088
|
+
x: srcEvent.clientX != null ? srcEvent.clientX : srcEvent.pageX - (window.scrollX || window.pageXOffset || 0),
|
|
6089
|
+
y: srcEvent.clientY != null ? srcEvent.clientY : srcEvent.pageY - (window.scrollY || window.pageYOffset || 0)
|
|
6090
|
+
};
|
|
6091
|
+
}
|
|
6092
|
+
}
|
|
6093
|
+
|
|
6070
6094
|
// Prepare event data
|
|
6071
6095
|
const eventData = {
|
|
6072
6096
|
event_type: 'custom',
|
|
@@ -6076,6 +6100,7 @@
|
|
|
6076
6100
|
user_id: userId,
|
|
6077
6101
|
// Only include user-provided properties in custom_properties (filtered)
|
|
6078
6102
|
custom_properties: filteredProperties,
|
|
6103
|
+
auto_event_data: customAutoEventData,
|
|
6079
6104
|
// Page context and screen/viewport data go in page_data (not custom_properties)
|
|
6080
6105
|
page_data: {
|
|
6081
6106
|
current_url: window.location.href,
|
|
@@ -6890,7 +6915,18 @@
|
|
|
6890
6915
|
if (element === lastClickElement && now - lastClickTime < 1000) {
|
|
6891
6916
|
clickCount++;
|
|
6892
6917
|
if (clickCount >= 3) {
|
|
6918
|
+
const scrollX = window.scrollX != null ? window.scrollX : window.pageXOffset;
|
|
6919
|
+
const scrollY = window.scrollY != null ? window.scrollY : window.pageYOffset;
|
|
6920
|
+
const docHeight = Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
|
|
6921
|
+
const docWidth = Math.max(document.body.scrollWidth, document.documentElement.scrollWidth);
|
|
6893
6922
|
EventsManager.trackAutoEvent('rage_click', {
|
|
6923
|
+
click_coordinates: { x: event.clientX, y: event.clientY },
|
|
6924
|
+
page_x: event.pageX,
|
|
6925
|
+
page_y: event.pageY,
|
|
6926
|
+
scroll_x: scrollX,
|
|
6927
|
+
scroll_y: scrollY,
|
|
6928
|
+
document_height: docHeight,
|
|
6929
|
+
document_width: docWidth,
|
|
6894
6930
|
click_count: clickCount,
|
|
6895
6931
|
time_span: now - lastClickTime,
|
|
6896
6932
|
element_area: element.offsetWidth * element.offsetHeight,
|
|
@@ -6907,11 +6943,15 @@
|
|
|
6907
6943
|
const isInteractive = isInteractiveElement(element);
|
|
6908
6944
|
|
|
6909
6945
|
if (!isInteractive) {
|
|
6910
|
-
// Capture coordinates before setTimeout
|
|
6946
|
+
// Capture coordinates and page context before setTimeout (for heatmaps)
|
|
6911
6947
|
const clickX = event.clientX;
|
|
6912
6948
|
const clickY = event.clientY;
|
|
6913
6949
|
const clickElement = element;
|
|
6914
|
-
|
|
6950
|
+
const scrollX = window.scrollX != null ? window.scrollX : window.pageXOffset;
|
|
6951
|
+
const scrollY = window.scrollY != null ? window.scrollY : window.pageYOffset;
|
|
6952
|
+
const docHeight = Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
|
|
6953
|
+
const docWidth = Math.max(document.body.scrollWidth, document.documentElement.scrollWidth);
|
|
6954
|
+
|
|
6915
6955
|
// Mark this click as potentially dead
|
|
6916
6956
|
const clickId = `${now}_${Math.random().toString(36).substr(2, 9)}`;
|
|
6917
6957
|
pendingDeadClicks.set(clickId, {
|
|
@@ -6921,7 +6961,13 @@
|
|
|
6921
6961
|
timestamp: now,
|
|
6922
6962
|
url: window.location.href,
|
|
6923
6963
|
clickX,
|
|
6924
|
-
clickY
|
|
6964
|
+
clickY,
|
|
6965
|
+
page_x: event.pageX,
|
|
6966
|
+
page_y: event.pageY,
|
|
6967
|
+
scroll_x: scrollX,
|
|
6968
|
+
scroll_y: scrollY,
|
|
6969
|
+
document_height: docHeight,
|
|
6970
|
+
document_width: docWidth
|
|
6925
6971
|
});
|
|
6926
6972
|
|
|
6927
6973
|
// Check after 1 second if navigation occurred or if it's still a dead click
|
|
@@ -6935,6 +6981,12 @@
|
|
|
6935
6981
|
|
|
6936
6982
|
EventsManager.trackAutoEvent('dead_click', {
|
|
6937
6983
|
click_coordinates: { x: pendingClick.clickX, y: pendingClick.clickY },
|
|
6984
|
+
page_x: pendingClick.page_x,
|
|
6985
|
+
page_y: pendingClick.page_y,
|
|
6986
|
+
scroll_x: pendingClick.scroll_x,
|
|
6987
|
+
scroll_y: pendingClick.scroll_y,
|
|
6988
|
+
document_height: pendingClick.document_height,
|
|
6989
|
+
document_width: pendingClick.document_width,
|
|
6938
6990
|
element_area: clickElement.offsetWidth * clickElement.offsetHeight,
|
|
6939
6991
|
element_category: pendingClick.elementCategory,
|
|
6940
6992
|
element_has_onclick: !!clickElement.onclick,
|
|
@@ -6950,9 +7002,19 @@
|
|
|
6950
7002
|
}, 1000);
|
|
6951
7003
|
}
|
|
6952
7004
|
|
|
6953
|
-
// Track regular click with enhanced data
|
|
7005
|
+
// Track regular click with enhanced data (viewport + page-relative for heatmaps)
|
|
7006
|
+
const scrollX = window.scrollX != null ? window.scrollX : window.pageXOffset;
|
|
7007
|
+
const scrollY = window.scrollY != null ? window.scrollY : window.pageYOffset;
|
|
7008
|
+
const docHeight = Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
|
|
7009
|
+
const docWidth = Math.max(document.body.scrollWidth, document.documentElement.scrollWidth);
|
|
6954
7010
|
EventsManager.trackAutoEvent('element_click', {
|
|
6955
7011
|
click_coordinates: { x: event.clientX, y: event.clientY },
|
|
7012
|
+
page_x: event.pageX,
|
|
7013
|
+
page_y: event.pageY,
|
|
7014
|
+
scroll_x: scrollX,
|
|
7015
|
+
scroll_y: scrollY,
|
|
7016
|
+
document_height: docHeight,
|
|
7017
|
+
document_width: docWidth,
|
|
6956
7018
|
double_click: event.detail === 2,
|
|
6957
7019
|
element_category: elementCategory
|
|
6958
7020
|
}, elementData).catch(err => {
|
|
@@ -6977,15 +7039,22 @@
|
|
|
6977
7039
|
clearTimeout(scrollTimeout);
|
|
6978
7040
|
|
|
6979
7041
|
scrollTimeout = setTimeout(() => {
|
|
6980
|
-
const
|
|
6981
|
-
|
|
7042
|
+
const maxScroll = Math.max(document.body.scrollHeight, document.documentElement.scrollHeight) - window.innerHeight;
|
|
7043
|
+
const scrollDepth = maxScroll <= 0 ? 100 : Math.round((window.scrollY / maxScroll) * 100);
|
|
7044
|
+
|
|
6982
7045
|
if (scrollDepth > maxScrollDepth) {
|
|
6983
7046
|
maxScrollDepth = scrollDepth;
|
|
6984
|
-
|
|
7047
|
+
const scrollX = window.scrollX != null ? window.scrollX : window.pageXOffset;
|
|
7048
|
+
const docHeight = Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
|
|
7049
|
+
const docWidth = Math.max(document.body.scrollWidth, document.documentElement.scrollWidth);
|
|
6985
7050
|
EventsManager.trackAutoEvent('page_scroll', {
|
|
6986
7051
|
scroll_depth: scrollDepth,
|
|
6987
7052
|
max_scroll_reached: maxScrollDepth,
|
|
6988
|
-
scroll_position: window.scrollY
|
|
7053
|
+
scroll_position: window.scrollY,
|
|
7054
|
+
scroll_x: scrollX,
|
|
7055
|
+
scroll_y: window.scrollY,
|
|
7056
|
+
document_height: docHeight,
|
|
7057
|
+
document_width: docWidth
|
|
6989
7058
|
}).catch(err => {
|
|
6990
7059
|
console.error('❌ [AutoEvents] Failed to track page_scroll:', err);
|
|
6991
7060
|
});
|
|
@@ -7003,10 +7072,24 @@
|
|
|
7003
7072
|
document.addEventListener('submit', (event) => {
|
|
7004
7073
|
const form = event.target;
|
|
7005
7074
|
if (form.tagName === 'FORM') {
|
|
7075
|
+
const scrollX = window.scrollX != null ? window.scrollX : window.pageXOffset;
|
|
7076
|
+
const scrollY = window.scrollY != null ? window.scrollY : window.pageYOffset;
|
|
7077
|
+
const docHeight = Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
|
|
7078
|
+
const docWidth = Math.max(document.body.scrollWidth, document.documentElement.scrollWidth);
|
|
7079
|
+
const rect = form.getBoundingClientRect();
|
|
7080
|
+
const pageX = rect.left + scrollX;
|
|
7081
|
+
const pageY = rect.top + scrollY;
|
|
7006
7082
|
EventsManager.trackAutoEvent('form_submit', {
|
|
7007
7083
|
form_id: form.id || null,
|
|
7008
7084
|
form_action: form.action || null,
|
|
7009
|
-
form_method: form.method || 'get'
|
|
7085
|
+
form_method: form.method || 'get',
|
|
7086
|
+
scroll_x: scrollX,
|
|
7087
|
+
scroll_y: scrollY,
|
|
7088
|
+
document_height: docHeight,
|
|
7089
|
+
document_width: docWidth,
|
|
7090
|
+
page_x: pageX,
|
|
7091
|
+
page_y: pageY,
|
|
7092
|
+
click_coordinates: { x: event.clientX != null ? event.clientX : rect.left + rect.width / 2, y: event.clientY != null ? event.clientY : rect.top + rect.height / 2 }
|
|
7010
7093
|
}, {
|
|
7011
7094
|
element_tag_name: 'form',
|
|
7012
7095
|
element_id: form.id || null,
|
|
@@ -7015,8 +7098,8 @@
|
|
|
7015
7098
|
element_type: form.method || 'get', // FIX: Added element_type (form method)
|
|
7016
7099
|
element_text: form.textContent?.trim().substring(0, 100) || null, // FIX: Added element_text
|
|
7017
7100
|
element_position: { // FIX: Added element_position
|
|
7018
|
-
x: event.clientX ||
|
|
7019
|
-
y: event.clientY ||
|
|
7101
|
+
x: event.clientX || rect.left,
|
|
7102
|
+
y: event.clientY || rect.top,
|
|
7020
7103
|
width: form.offsetWidth || 0,
|
|
7021
7104
|
height: form.offsetHeight || 0
|
|
7022
7105
|
}
|
|
@@ -7028,10 +7111,24 @@
|
|
|
7028
7111
|
document.addEventListener('focus', (event) => {
|
|
7029
7112
|
const element = event.target;
|
|
7030
7113
|
if (element.tagName === 'INPUT' || element.tagName === 'TEXTAREA' || element.tagName === 'SELECT') {
|
|
7114
|
+
const scrollX = window.scrollX != null ? window.scrollX : window.pageXOffset;
|
|
7115
|
+
const scrollY = window.scrollY != null ? window.scrollY : window.pageYOffset;
|
|
7116
|
+
const docHeight = Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
|
|
7117
|
+
const docWidth = Math.max(document.body.scrollWidth, document.documentElement.scrollWidth);
|
|
7118
|
+
const rect = element.getBoundingClientRect();
|
|
7119
|
+
const pageX = rect.left + scrollX;
|
|
7120
|
+
const pageY = rect.top + scrollY;
|
|
7031
7121
|
EventsManager.trackAutoEvent('form_focus', {
|
|
7032
7122
|
field_name: element.name || null,
|
|
7033
7123
|
field_type: element.type || null,
|
|
7034
|
-
field_id: element.id || null
|
|
7124
|
+
field_id: element.id || null,
|
|
7125
|
+
scroll_x: scrollX,
|
|
7126
|
+
scroll_y: scrollY,
|
|
7127
|
+
document_height: docHeight,
|
|
7128
|
+
document_width: docWidth,
|
|
7129
|
+
page_x: pageX,
|
|
7130
|
+
page_y: pageY,
|
|
7131
|
+
click_coordinates: { x: event.clientX != null ? event.clientX : rect.left + rect.width / 2, y: event.clientY != null ? event.clientY : rect.top + rect.height / 2 }
|
|
7035
7132
|
}, {
|
|
7036
7133
|
element_tag_name: element.tagName.toLowerCase(),
|
|
7037
7134
|
element_id: element.id || null,
|
|
@@ -7040,8 +7137,8 @@
|
|
|
7040
7137
|
element_type: element.type || null,
|
|
7041
7138
|
element_text: element.value ? element.value.toString().trim().substring(0, 100) : null, // FIX: Added element_text (value for form fields)
|
|
7042
7139
|
element_position: { // FIX: Added element_position
|
|
7043
|
-
x: event.clientX
|
|
7044
|
-
y: event.clientY
|
|
7140
|
+
x: event.clientX != null ? event.clientX : rect.left,
|
|
7141
|
+
y: event.clientY != null ? event.clientY : rect.top,
|
|
7045
7142
|
width: element.offsetWidth || 0,
|
|
7046
7143
|
height: element.offsetHeight || 0
|
|
7047
7144
|
}
|
|
@@ -7054,23 +7151,54 @@
|
|
|
7054
7151
|
* Setup media tracking
|
|
7055
7152
|
*/
|
|
7056
7153
|
setupMediaTracking() {
|
|
7154
|
+
function getPageContext() {
|
|
7155
|
+
const scrollX = window.scrollX != null ? window.scrollX : window.pageXOffset;
|
|
7156
|
+
const scrollY = window.scrollY != null ? window.scrollY : window.pageYOffset;
|
|
7157
|
+
const docHeight = Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
|
|
7158
|
+
const docWidth = Math.max(document.body.scrollWidth, document.documentElement.scrollWidth);
|
|
7159
|
+
return { scrollX, scrollY, docHeight, docWidth };
|
|
7160
|
+
}
|
|
7057
7161
|
['video', 'audio'].forEach(mediaType => {
|
|
7058
7162
|
document.addEventListener('play', (event) => {
|
|
7059
7163
|
if (event.target.tagName.toLowerCase() === mediaType) {
|
|
7164
|
+
const el = event.target;
|
|
7165
|
+
const { scrollX, scrollY, docHeight, docWidth } = getPageContext();
|
|
7166
|
+
const rect = el.getBoundingClientRect();
|
|
7167
|
+
const pageX = rect.left + scrollX;
|
|
7168
|
+
const pageY = rect.top + scrollY;
|
|
7060
7169
|
EventsManager.trackAutoEvent('media_play', {
|
|
7061
7170
|
media_type: mediaType,
|
|
7062
|
-
media_src:
|
|
7063
|
-
media_duration:
|
|
7171
|
+
media_src: el.src || null,
|
|
7172
|
+
media_duration: el.duration || null,
|
|
7173
|
+
scroll_x: scrollX,
|
|
7174
|
+
scroll_y: scrollY,
|
|
7175
|
+
document_height: docHeight,
|
|
7176
|
+
document_width: docWidth,
|
|
7177
|
+
page_x: pageX,
|
|
7178
|
+
page_y: pageY,
|
|
7179
|
+
click_coordinates: { x: rect.left + rect.width / 2, y: rect.top + rect.height / 2 }
|
|
7064
7180
|
});
|
|
7065
7181
|
}
|
|
7066
7182
|
}, true);
|
|
7067
7183
|
|
|
7068
7184
|
document.addEventListener('pause', (event) => {
|
|
7069
7185
|
if (event.target.tagName.toLowerCase() === mediaType) {
|
|
7186
|
+
const el = event.target;
|
|
7187
|
+
const { scrollX, scrollY, docHeight, docWidth } = getPageContext();
|
|
7188
|
+
const rect = el.getBoundingClientRect();
|
|
7189
|
+
const pageX = rect.left + scrollX;
|
|
7190
|
+
const pageY = rect.top + scrollY;
|
|
7070
7191
|
EventsManager.trackAutoEvent('media_pause', {
|
|
7071
7192
|
media_type: mediaType,
|
|
7072
|
-
media_current_time:
|
|
7073
|
-
media_duration:
|
|
7193
|
+
media_current_time: el.currentTime || null,
|
|
7194
|
+
media_duration: el.duration || null,
|
|
7195
|
+
scroll_x: scrollX,
|
|
7196
|
+
scroll_y: scrollY,
|
|
7197
|
+
document_height: docHeight,
|
|
7198
|
+
document_width: docWidth,
|
|
7199
|
+
page_x: pageX,
|
|
7200
|
+
page_y: pageY,
|
|
7201
|
+
click_coordinates: { x: rect.left + rect.width / 2, y: rect.top + rect.height / 2 }
|
|
7074
7202
|
});
|
|
7075
7203
|
}
|
|
7076
7204
|
}, true);
|
|
@@ -7152,11 +7280,33 @@
|
|
|
7152
7280
|
focus_offset: selection.focusOffset || null
|
|
7153
7281
|
};
|
|
7154
7282
|
|
|
7155
|
-
// Get page context
|
|
7283
|
+
// Get page context and selection position for heatmaps
|
|
7284
|
+
const scrollX = window.scrollX != null ? window.scrollX : window.pageXOffset;
|
|
7285
|
+
const scrollY = window.scrollY != null ? window.scrollY : window.pageYOffset;
|
|
7286
|
+
const docHeight = Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
|
|
7287
|
+
const docWidth = Math.max(document.body.scrollWidth, document.documentElement.scrollWidth);
|
|
7288
|
+
let pageX = null;
|
|
7289
|
+
let pageY = null;
|
|
7290
|
+
if (range) {
|
|
7291
|
+
try {
|
|
7292
|
+
const selRect = range.getBoundingClientRect();
|
|
7293
|
+
if (selRect.width > 0 || selRect.height > 0) {
|
|
7294
|
+
pageX = selRect.left + scrollX;
|
|
7295
|
+
pageY = selRect.top + scrollY;
|
|
7296
|
+
}
|
|
7297
|
+
} catch (e) { /* getBoundingClientRect can throw in some edge cases */ }
|
|
7298
|
+
}
|
|
7156
7299
|
const pageData = {
|
|
7157
7300
|
page_url: window.location.href,
|
|
7158
7301
|
page_title: document.title,
|
|
7159
|
-
page_path: window.location.pathname
|
|
7302
|
+
page_path: window.location.pathname,
|
|
7303
|
+
scroll_x: scrollX,
|
|
7304
|
+
scroll_y: scrollY,
|
|
7305
|
+
document_height: docHeight,
|
|
7306
|
+
document_width: docWidth,
|
|
7307
|
+
page_x: pageX,
|
|
7308
|
+
page_y: pageY,
|
|
7309
|
+
click_coordinates: pageX != null && pageY != null ? { x: pageX - scrollX, y: pageY - scrollY } : null
|
|
7160
7310
|
};
|
|
7161
7311
|
|
|
7162
7312
|
EventsManager.trackAutoEvent('text_selection', {
|
package/package.json
CHANGED