-
Notifications
You must be signed in to change notification settings - Fork 1
/
webform_tracking.js
166 lines (150 loc) · 4.72 KB
/
webform_tracking.js
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
(function($) {
Drupal.behaviors.webform_tracking = {
extra_parameters: {
"source" : "s",
"medium" : "m",
"version" : "v",
"other" : "o",
"term" : "t",
"campaign" : "c",
"refsid" : "refsid",
},
google_analytics: {
"source" : "utm_source",
"medium" : "utm_medium",
"term" : "utm_term",
"version" : "utm_content",
"campaign" : "utm_campaign",
},
attach: function(context) {
// Run only once per page-load.
if (context !== document) {
return;
}
// Run only with consent.
var dnt = window.navigator.doNotTrack;
var respect_dnt = Drupal.settings.webform_tracking.respect_dnt;
if ((dnt === "yes" || dnt == "1") && respect_dnt) {
return;
}
var event = Drupal.settings.webform_tracking.wait_for_event;
if (event) {
document.addEventListener(event, this.run.bind(this), false);
}
else {
this.run();
}
},
// Get white listed parameters.
extract_parameters: function(parameters) {
var data = {};
var map = this.extra_parameters;
for (var key in map) {
var candidates = [key, map[key], this.google_analytics[key]];
// Take first candidate key with a value.
for (var i = 0, l = candidates.length; i < l; i++) {
var value = parameters[candidates[i]];
if (value) {
data[key] = value;
break;
}
}
}
return data;
},
// Adds the URL to a history array (if needed).
history_add: function(history, url) {
var length = history.length;
if (length) {
// Only add new values (ignore page refreshes).
if (history[history.length-1] != url) {
history.push(url);
}
}
else {
length = history.push(url);
}
// Truncate the array if it gets too big.
if (length > 10) {
// We keep:
// [0] is the entry page
// [-3] might be the last page before the form == referer
// [-2] might be the form
// [-1] might be the forms /done page
// 10 is an arbitrary value, you just might want to avoid
// calling the array functions below on every request if not
// necessary.
history = [history[0]];
$.merge(history, history.slice(-3));
}
},
run: function() {
var cookie_data;
try {
cookie_data = JSON.parse($.cookie('webform_tracking') || '{}');
} catch(err) {
cookie_data = {};
}
var tracking_data = $.extend({
history: [],
tags: [],
}, cookie_data);
var parameters = this.get_url_parameters();
var base_url = Drupal.settings.webform_tracking.base_url;
tracking_data.user_id = tracking_data.user_id || this.new_user_id();
// tags
var tags = tracking_data.tags || [];
if (typeof parameters['tag'] !== 'undefined') {
$.merge(tags, parameters['tag'].split(','));
}
tracking_data.tags = this.sort_unique(tags);
// extra parameters
$.extend(tracking_data, this.extract_parameters(parameters));
// If the referer does not start with $base_url, it's external but we
// only take the first external referer to avoid problems with off-site
// redirects (e.g. in payment forms).
// if no referer is send, check if we got one via the GET-parameters
if (typeof tracking_data['external_referer'] === 'undefined') {
if (document.referrer.indexOf(base_url) !== 0) {
tracking_data['external_referer'] = document.referrer;
}
else if (typeof parameters['external_referer'] !== 'undefined' && parameters['external_referer'].indexOf(base_url) !== 0) {
tracking_data['external_referer'] = parameters['external_referer'];
}
}
// history
this.history_add(tracking_data.history, window.location.href);
$.cookie('webform_tracking', JSON.stringify(tracking_data), {path: '/'});
},
get_url_parameters: function() {
var parameters = {};
var variables = window.location.search.substring(1).split('&');
for (var i = 0; i < variables.length; i++) {
var parameter = variables[i].split('=');
parameters[parameter[0]] = parameter[1];
};
return parameters;
},
new_user_id: function() {
// http://x443.wordpress.com/2012/03/18/adler32-checksum-in-javascript/
var adler32 = function(a,b,c,d,e,f) {
for (b=65521,c=1,d=e=0;f=a.charCodeAt(e++); d=(d+c)%b) c=(c+f)%b;
return(d<<16)|c
}
return adler32(String(Math.random() + Date.now()));
},
sort_unique: function(array) {
if (!array.length) {
return array;
}
array = array.sort(function (a, b) { return a - b; });
var result = [array[0]];
for (var i = 1; i < array.length; i++) {
if (array[i-1] !== array[i]) {
result.push(array[i]);
}
}
return result;
}
}
})(jQuery);