-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathanalytics.js
More file actions
118 lines (99 loc) · 3.81 KB
/
Copy pathanalytics.js
File metadata and controls
118 lines (99 loc) · 3.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// Don't send analytics events more often than defined here. I.e. search-as-you-type implementation should fire
// an analytics event after a pause this long occures
const SEARCH_ANALYTICS_DEBOUNCE_TIME = 2500;
/**
* Custom function for external analytics collection
*/
let externalAnalyticsCallback = null;
export function setExternalAnalyticsCallback(cb) {
externalAnalyticsCallback = cb;
}
function callExternalAnalyticsCallback(data) {
if (externalAnalyticsCallback) {
externalAnalyticsCallback(data);
}
}
/**
* Possibility to disable analytics altogether
*/
let collectAnalytics = true;
export function setCollectAnalytics(collect) {
collectAnalytics = collect;
}
/**
* Send info on search results to analytics
*/
let sendSearchStatsTimeout = null;
let previousKeyword = null;
let searchStatsSent = false; // If a search result is clicked within the SEARCH_ANALYTICS_DEBOUNCE_TIME, send search stats from onLinkClick
export function sendSearchStats(client, keyword, numberOfResults, processingTimeMs) {
if (collectAnalytics === false) return;
const action = 'search';
if (sendSearchStatsTimeout) {
clearTimeout(sendSearchStatsTimeout);
}
sendSearchStatsTimeout = setTimeout(() => {
// Don't send if keyword not changed (i.e. filters changed)
if (keyword !== previousKeyword) {
client.sendStatsEvent(action, keyword, {numberOfResults});
callExternalAnalyticsCallback({action, keyword, numberOfResults, processingTimeMs});
previousKeyword = keyword;
searchStatsSent = true;
}
}, SEARCH_ANALYTICS_DEBOUNCE_TIME);
}
/**
* Add click trackers to search result links
*/
export function addClickTrackers(client, linkArray, searchResults) {
if (linkArray && linkArray.length > 0) {
for (let i=0; i<linkArray.length; i++) {
// Enter pressed when link is active
linkArray[i].addEventListener('keyup', (e) => {
if (e.keyCode === 13) {
onLinkClick(e, client, searchResults);
}
});
// Link clicked with mouse / tapped on mobile
linkArray[i].addEventListener('pointerdown', (e) => {
// Ignore right clicks
if (e.button && e.buttons && e.button === e.buttons) {
return;
}
onLinkClick(e, client, searchResults);
});
}
}
}
function onLinkClick(e, client, searchResults) {
if (collectAnalytics === false) return;
// Support data attributes in parent and grandparent elements
const documentId = e.target.getAttribute('data-analytics-click') ||
e.target.parentNode.getAttribute('data-analytics-click') ||
e.target.parentNode.parentNode.getAttribute('data-analytics-click');
const position = getDocumentPosition(client.getSettings().paging.pageSize, searchResults, documentId);
const keyword = client.getSettings().keyword;
client.sendStatsEvent('click', keyword, {documentId, position});
callExternalAnalyticsCallback({action: 'click', keyword, documentId, position});
// Search stats were not sent within SEARCH_ANALYTICS_DEBOUNCE_TIME
if (searchStatsSent === false) {
const numberOfResults = searchResults ? searchResults.total_hits : 0;
const processingTimeMs = searchResults ? searchResults.processing_time_ms : 0;
client.sendStatsEvent('search', keyword, {numberOfResults});
callExternalAnalyticsCallback({action: 'search', keyword, numberOfResults, processingTimeMs});
}
}
export function getDocumentPosition(pageSize, searchResults, docid) {
if (searchResults && searchResults.hits) {
// Calculate offset if the user is not on results page 1
const currentPage = searchResults.page || 1;
const offset = (currentPage - 1) * pageSize;
// Find document's position in results array
for (let i=0; i<searchResults.hits.length; i++) {
if (searchResults.hits[i].id === docid) {
return offset + (i+1);
}
}
}
return 0;
}