mixpanel-browser 2.45.0 → 2.47.0
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/.github/workflows/tests.yml +1 -1
- package/CHANGELOG.md +11 -1
- package/README.md +1 -1
- package/build.sh +2 -0
- package/dist/mixpanel.amd.js +229 -73
- package/dist/mixpanel.cjs.js +229 -73
- package/dist/mixpanel.globals.js +229 -73
- package/dist/mixpanel.min.js +104 -101
- package/dist/mixpanel.umd.js +229 -73
- package/doc/readme.io/javascript-full-api-reference.md +3 -55
- package/doc/template.md +1 -1
- package/package.json +5 -5
- package/src/config.js +1 -1
- package/src/mixpanel-core.js +103 -16
- package/src/mixpanel-people.js +29 -27
- package/src/mixpanel-persistence.js +0 -7
- package/src/request-batcher.js +50 -1
- package/src/utils.js +47 -21
package/src/mixpanel-core.js
CHANGED
|
@@ -57,6 +57,7 @@ var NOOP_FUNC = function() {};
|
|
|
57
57
|
/** @const */ var PRIMARY_INSTANCE_NAME = 'mixpanel';
|
|
58
58
|
/** @const */ var PAYLOAD_TYPE_BASE64 = 'base64';
|
|
59
59
|
/** @const */ var PAYLOAD_TYPE_JSON = 'json';
|
|
60
|
+
/** @const */ var DEVICE_ID_PREFIX = '$device:';
|
|
60
61
|
|
|
61
62
|
|
|
62
63
|
/*
|
|
@@ -98,6 +99,9 @@ var DEFAULT_CONFIG = {
|
|
|
98
99
|
'cookie_domain': '',
|
|
99
100
|
'cookie_name': '',
|
|
100
101
|
'loaded': NOOP_FUNC,
|
|
102
|
+
'track_marketing': true,
|
|
103
|
+
'track_pageview': false,
|
|
104
|
+
'skip_first_touch_marketing': false,
|
|
101
105
|
'store_google': true,
|
|
102
106
|
'save_referrer': true,
|
|
103
107
|
'test': false,
|
|
@@ -164,6 +168,25 @@ var create_mplib = function(token, config, name) {
|
|
|
164
168
|
instance['people'] = new MixpanelPeople();
|
|
165
169
|
instance['people']._init(instance);
|
|
166
170
|
|
|
171
|
+
if (!instance.get_config('skip_first_touch_marketing')) {
|
|
172
|
+
// We need null UTM params in the object because
|
|
173
|
+
// UTM parameters act as a tuple. If any UTM param
|
|
174
|
+
// is present, then we set all UTM params including
|
|
175
|
+
// empty ones together
|
|
176
|
+
var utm_params = _.info.campaignParams(null);
|
|
177
|
+
var initial_utm_params = {};
|
|
178
|
+
var has_utm = false;
|
|
179
|
+
_.each(utm_params, function(utm_value, utm_key) {
|
|
180
|
+
initial_utm_params['initial_' + utm_key] = utm_value;
|
|
181
|
+
if (utm_value) {
|
|
182
|
+
has_utm = true;
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
if (has_utm) {
|
|
186
|
+
instance['people'].set_once(initial_utm_params);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
167
190
|
// if any instance on the page has debug = true, we set the
|
|
168
191
|
// global debug to be true
|
|
169
192
|
Config.DEBUG = Config.DEBUG || instance.get_config('debug');
|
|
@@ -195,7 +218,7 @@ var create_mplib = function(token, config, name) {
|
|
|
195
218
|
* mixpanel.library_name.track(...);
|
|
196
219
|
*
|
|
197
220
|
* @param {String} token Your Mixpanel API token
|
|
198
|
-
* @param {Object} [config] A dictionary of config options to override. <a href="https://github.com/mixpanel/mixpanel-js/blob/
|
|
221
|
+
* @param {Object} [config] A dictionary of config options to override. <a href="https://github.com/mixpanel/mixpanel-js/blob/v2.46.0/src/mixpanel-core.js#L88-L127">See a list of default config options</a>.
|
|
199
222
|
* @param {String} [name] The name for the new mixpanel instance that you want created
|
|
200
223
|
*/
|
|
201
224
|
MixpanelLib.prototype.init = function (token, config, name) {
|
|
@@ -233,7 +256,7 @@ MixpanelLib.prototype._init = function(token, config, name) {
|
|
|
233
256
|
// default to JSON payload for standard mixpanel.com API hosts
|
|
234
257
|
if (!('api_payload_format' in config)) {
|
|
235
258
|
var api_host = config['api_host'] || DEFAULT_CONFIG['api_host'];
|
|
236
|
-
if (api_host.match(/\.mixpanel\.com
|
|
259
|
+
if (api_host.match(/\.mixpanel\.com/)) {
|
|
237
260
|
variable_features['api_payload_format'] = PAYLOAD_TYPE_JSON;
|
|
238
261
|
}
|
|
239
262
|
}
|
|
@@ -304,10 +327,14 @@ MixpanelLib.prototype._init = function(token, config, name) {
|
|
|
304
327
|
// or the device id if something was already stored
|
|
305
328
|
// in the persitence
|
|
306
329
|
this.register_once({
|
|
307
|
-
'distinct_id': uuid,
|
|
330
|
+
'distinct_id': DEVICE_ID_PREFIX + uuid,
|
|
308
331
|
'$device_id': uuid
|
|
309
332
|
}, '');
|
|
310
333
|
}
|
|
334
|
+
|
|
335
|
+
if (this.get_config('track_pageview')) {
|
|
336
|
+
this.track_pageview();
|
|
337
|
+
}
|
|
311
338
|
};
|
|
312
339
|
|
|
313
340
|
// Private methods
|
|
@@ -321,7 +348,7 @@ MixpanelLib.prototype._loaded = function() {
|
|
|
321
348
|
MixpanelLib.prototype._set_default_superprops = function() {
|
|
322
349
|
this['persistence'].update_search_keyword(document.referrer);
|
|
323
350
|
if (this.get_config('store_google')) {
|
|
324
|
-
this
|
|
351
|
+
this.register(_.info.campaignParams(), {persistent: false});
|
|
325
352
|
}
|
|
326
353
|
if (this.get_config('save_referrer')) {
|
|
327
354
|
this['persistence'].update_referrer_info(document.referrer);
|
|
@@ -803,6 +830,10 @@ MixpanelLib.prototype.track = addOptOutCheckMixpanelLib(function(event_name, pro
|
|
|
803
830
|
|
|
804
831
|
this._set_default_superprops();
|
|
805
832
|
|
|
833
|
+
var marketing_properties = this.get_config('track_marketing')
|
|
834
|
+
? _.info.marketingParams()
|
|
835
|
+
: {};
|
|
836
|
+
|
|
806
837
|
// note: extend writes to the first object, so lets make sure we
|
|
807
838
|
// don't write to the persistence properties object and info
|
|
808
839
|
// properties object by passing in a new object
|
|
@@ -811,6 +842,7 @@ MixpanelLib.prototype.track = addOptOutCheckMixpanelLib(function(event_name, pro
|
|
|
811
842
|
properties = _.extend(
|
|
812
843
|
{},
|
|
813
844
|
_.info.properties(),
|
|
845
|
+
marketing_properties,
|
|
814
846
|
this['persistence'].properties(),
|
|
815
847
|
this.unpersisted_superprops,
|
|
816
848
|
properties
|
|
@@ -971,17 +1003,54 @@ MixpanelLib.prototype.get_group = function (group_key, group_id) {
|
|
|
971
1003
|
};
|
|
972
1004
|
|
|
973
1005
|
/**
|
|
974
|
-
* Track
|
|
1006
|
+
* Track a default Mixpanel page view event, which includes extra default event properties to
|
|
1007
|
+
* improve page view data. The `config.track_pageview` option for <a href="#mixpanelinit">mixpanel.init()</a>
|
|
1008
|
+
* may be turned on for tracking page loads automatically.
|
|
975
1009
|
*
|
|
976
|
-
*
|
|
977
|
-
*
|
|
1010
|
+
* ### Usage
|
|
1011
|
+
*
|
|
1012
|
+
* // track a default $mp_web_page_view event
|
|
1013
|
+
* mixpanel.track_pageview();
|
|
1014
|
+
*
|
|
1015
|
+
* // track a page view event with additional event properties
|
|
1016
|
+
* mixpanel.track_pageview({'ab_test_variant': 'card-layout-b'});
|
|
1017
|
+
*
|
|
1018
|
+
* // example approach to track page views on different page types as event properties
|
|
1019
|
+
* mixpanel.track_pageview({'page': 'pricing'});
|
|
1020
|
+
* mixpanel.track_pageview({'page': 'homepage'});
|
|
1021
|
+
*
|
|
1022
|
+
* // UNCOMMON: Tracking a page view event with a custom event_name option. NOT expected to be used for
|
|
1023
|
+
* // individual pages on the same site or product. Use cases for custom event_name may be page
|
|
1024
|
+
* // views on different products or internal applications that are considered completely separate
|
|
1025
|
+
* mixpanel.track_pageview({'page': 'customer-search'}, {'event_name': '[internal] Admin Page View'});
|
|
1026
|
+
*
|
|
1027
|
+
* @param {Object} [properties] An optional set of additional properties to send with the page view event
|
|
1028
|
+
* @param {Object} [options] Page view tracking options
|
|
1029
|
+
* @param {String} [options.event_name] - Alternate name for the tracking event
|
|
1030
|
+
* @returns {Boolean|Object} If the tracking request was successfully initiated/queued, an object
|
|
1031
|
+
* with the tracking payload sent to the API server is returned; otherwise false.
|
|
978
1032
|
*/
|
|
979
|
-
MixpanelLib.prototype.track_pageview = function(
|
|
980
|
-
if (
|
|
981
|
-
|
|
1033
|
+
MixpanelLib.prototype.track_pageview = addOptOutCheckMixpanelLib(function(properties, options) {
|
|
1034
|
+
if (typeof properties !== 'object') {
|
|
1035
|
+
properties = {};
|
|
982
1036
|
}
|
|
983
|
-
|
|
984
|
-
|
|
1037
|
+
options = options || {};
|
|
1038
|
+
var event_name = options['event_name'] || '$mp_web_page_view';
|
|
1039
|
+
|
|
1040
|
+
var default_page_properties = _.extend(
|
|
1041
|
+
_.info.mpPageViewProperties(),
|
|
1042
|
+
_.info.campaignParams(),
|
|
1043
|
+
_.info.clickParams()
|
|
1044
|
+
);
|
|
1045
|
+
|
|
1046
|
+
var event_properties = _.extend(
|
|
1047
|
+
{},
|
|
1048
|
+
default_page_properties,
|
|
1049
|
+
properties
|
|
1050
|
+
);
|
|
1051
|
+
|
|
1052
|
+
return this.track(event_name, event_properties);
|
|
1053
|
+
});
|
|
985
1054
|
|
|
986
1055
|
/**
|
|
987
1056
|
* Track clicks on a set of document elements. Selector must be a
|
|
@@ -1230,7 +1299,15 @@ MixpanelLib.prototype.identify = function(
|
|
|
1230
1299
|
// _unset_callback:function A callback to be run if and when the People unset queue is flushed
|
|
1231
1300
|
|
|
1232
1301
|
var previous_distinct_id = this.get_distinct_id();
|
|
1233
|
-
|
|
1302
|
+
if (new_distinct_id && previous_distinct_id !== new_distinct_id) {
|
|
1303
|
+
// we allow the following condition if previous distinct_id is same as new_distinct_id
|
|
1304
|
+
// so that you can force flush people updates for anonymous profiles.
|
|
1305
|
+
if (typeof new_distinct_id === 'string' && new_distinct_id.indexOf(DEVICE_ID_PREFIX) === 0) {
|
|
1306
|
+
this.report_error('distinct_id cannot have $device: prefix');
|
|
1307
|
+
return -1;
|
|
1308
|
+
}
|
|
1309
|
+
this.register({'$user_id': new_distinct_id});
|
|
1310
|
+
}
|
|
1234
1311
|
|
|
1235
1312
|
if (!this.get_property('$device_id')) {
|
|
1236
1313
|
// The persisted distinct id might not actually be a device id at all
|
|
@@ -1271,7 +1348,7 @@ MixpanelLib.prototype.reset = function() {
|
|
|
1271
1348
|
this._flags.identify_called = false;
|
|
1272
1349
|
var uuid = _.UUID();
|
|
1273
1350
|
this.register_once({
|
|
1274
|
-
'distinct_id': uuid,
|
|
1351
|
+
'distinct_id': DEVICE_ID_PREFIX + uuid,
|
|
1275
1352
|
'$device_id': uuid
|
|
1276
1353
|
}, '');
|
|
1277
1354
|
};
|
|
@@ -1396,8 +1473,8 @@ MixpanelLib.prototype.name_tag = function(name_tag) {
|
|
|
1396
1473
|
* // batching or retry mechanisms.
|
|
1397
1474
|
* api_transport: 'XHR'
|
|
1398
1475
|
*
|
|
1399
|
-
* //
|
|
1400
|
-
* batch_requests:
|
|
1476
|
+
* // request-batching/queueing/retry
|
|
1477
|
+
* batch_requests: true,
|
|
1401
1478
|
*
|
|
1402
1479
|
* // maximum number of events/updates to send in a single
|
|
1403
1480
|
* // network request
|
|
@@ -1469,10 +1546,20 @@ MixpanelLib.prototype.name_tag = function(name_tag) {
|
|
|
1469
1546
|
* // secure, meaning they will only be transmitted over https
|
|
1470
1547
|
* secure_cookie: false
|
|
1471
1548
|
*
|
|
1549
|
+
* // disables enriching user profiles with first touch marketing data
|
|
1550
|
+
* skip_first_touch_marketing: false
|
|
1551
|
+
*
|
|
1472
1552
|
* // the amount of time track_links will
|
|
1473
1553
|
* // wait for Mixpanel's servers to respond
|
|
1474
1554
|
* track_links_timeout: 300
|
|
1475
1555
|
*
|
|
1556
|
+
* // adds any UTM parameters and click IDs present on the page to any events fired
|
|
1557
|
+
* track_marketing: true
|
|
1558
|
+
*
|
|
1559
|
+
* // enables automatic page view tracking using default page view events through
|
|
1560
|
+
* // the track_pageview() method
|
|
1561
|
+
* track_pageview: false
|
|
1562
|
+
*
|
|
1476
1563
|
* // if you set upgrade to be true, the library will check for
|
|
1477
1564
|
* // a cookie from our old js library and import super
|
|
1478
1565
|
* // properties from it, then the old cookie is deleted
|
package/src/mixpanel-people.js
CHANGED
|
@@ -244,24 +244,25 @@ MixpanelPeople.prototype.union = addOptOutCheckMixpanelPeople(function(list_name
|
|
|
244
244
|
});
|
|
245
245
|
|
|
246
246
|
/*
|
|
247
|
-
* Record that you have charged the current user a certain amount
|
|
248
|
-
* of money. Charges recorded with track_charge() will appear in the
|
|
249
|
-
* Mixpanel revenue report.
|
|
250
|
-
*
|
|
251
|
-
* ### Usage:
|
|
252
|
-
*
|
|
253
|
-
* // charge a user $50
|
|
254
|
-
* mixpanel.people.track_charge(50);
|
|
255
|
-
*
|
|
256
|
-
* // charge a user $30.50 on the 2nd of january
|
|
257
|
-
* mixpanel.people.track_charge(30.50, {
|
|
258
|
-
* '$time': new Date('jan 1 2012')
|
|
259
|
-
* });
|
|
260
|
-
*
|
|
261
|
-
* @param {Number} amount The amount of money charged to the current user
|
|
262
|
-
* @param {Object} [properties] An associative array of properties associated with the charge
|
|
263
|
-
* @param {Function} [callback] If provided, the callback will be called when the server responds
|
|
264
|
-
|
|
247
|
+
* Record that you have charged the current user a certain amount
|
|
248
|
+
* of money. Charges recorded with track_charge() will appear in the
|
|
249
|
+
* Mixpanel revenue report.
|
|
250
|
+
*
|
|
251
|
+
* ### Usage:
|
|
252
|
+
*
|
|
253
|
+
* // charge a user $50
|
|
254
|
+
* mixpanel.people.track_charge(50);
|
|
255
|
+
*
|
|
256
|
+
* // charge a user $30.50 on the 2nd of january
|
|
257
|
+
* mixpanel.people.track_charge(30.50, {
|
|
258
|
+
* '$time': new Date('jan 1 2012')
|
|
259
|
+
* });
|
|
260
|
+
*
|
|
261
|
+
* @param {Number} amount The amount of money charged to the current user
|
|
262
|
+
* @param {Object} [properties] An associative array of properties associated with the charge
|
|
263
|
+
* @param {Function} [callback] If provided, the callback will be called when the server responds
|
|
264
|
+
* @deprecated
|
|
265
|
+
*/
|
|
265
266
|
MixpanelPeople.prototype.track_charge = addOptOutCheckMixpanelPeople(function(amount, properties, callback) {
|
|
266
267
|
if (!_.isNumber(amount)) {
|
|
267
268
|
amount = parseFloat(amount);
|
|
@@ -277,15 +278,16 @@ MixpanelPeople.prototype.track_charge = addOptOutCheckMixpanelPeople(function(am
|
|
|
277
278
|
});
|
|
278
279
|
|
|
279
280
|
/*
|
|
280
|
-
* Permanently clear all revenue report transactions from the
|
|
281
|
-
* current user's people analytics profile.
|
|
282
|
-
*
|
|
283
|
-
* ### Usage:
|
|
284
|
-
*
|
|
285
|
-
* mixpanel.people.clear_charges();
|
|
286
|
-
*
|
|
287
|
-
* @param {Function} [callback] If provided, the callback will be called after tracking the event.
|
|
288
|
-
|
|
281
|
+
* Permanently clear all revenue report transactions from the
|
|
282
|
+
* current user's people analytics profile.
|
|
283
|
+
*
|
|
284
|
+
* ### Usage:
|
|
285
|
+
*
|
|
286
|
+
* mixpanel.people.clear_charges();
|
|
287
|
+
*
|
|
288
|
+
* @param {Function} [callback] If provided, the callback will be called after tracking the event.
|
|
289
|
+
* @deprecated
|
|
290
|
+
*/
|
|
289
291
|
MixpanelPeople.prototype.clear_charges = function(callback) {
|
|
290
292
|
return this.set('$transactions', [], callback);
|
|
291
293
|
};
|
|
@@ -219,13 +219,6 @@ MixpanelPersistence.prototype.unregister = function(prop) {
|
|
|
219
219
|
}
|
|
220
220
|
};
|
|
221
221
|
|
|
222
|
-
MixpanelPersistence.prototype.update_campaign_params = function() {
|
|
223
|
-
if (!this.campaign_params_saved) {
|
|
224
|
-
this.register_once(_.info.campaignParams());
|
|
225
|
-
this.campaign_params_saved = true;
|
|
226
|
-
}
|
|
227
|
-
};
|
|
228
|
-
|
|
229
222
|
MixpanelPersistence.prototype.update_search_keyword = function(referrer) {
|
|
230
223
|
this.register(_.info.searchInfo(referrer));
|
|
231
224
|
};
|
package/src/request-batcher.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import Config from './config';
|
|
1
2
|
import { RequestQueue } from './request-queue';
|
|
2
3
|
import { console_with_prefix, _ } from './utils'; // eslint-disable-line camelcase
|
|
3
4
|
|
|
@@ -30,6 +31,9 @@ var RequestBatcher = function(storageKey, options) {
|
|
|
30
31
|
|
|
31
32
|
this.stopped = !this.libConfig['batch_autostart'];
|
|
32
33
|
this.consecutiveRemovalFailures = 0;
|
|
34
|
+
|
|
35
|
+
// extra client-side dedupe
|
|
36
|
+
this.itemIdsSentSuccessfully = {};
|
|
33
37
|
};
|
|
34
38
|
|
|
35
39
|
/**
|
|
@@ -122,7 +126,34 @@ RequestBatcher.prototype.flush = function(options) {
|
|
|
122
126
|
payload = this.beforeSendHook(payload);
|
|
123
127
|
}
|
|
124
128
|
if (payload) {
|
|
125
|
-
|
|
129
|
+
// mp_sent_by_lib_version prop captures which lib version actually
|
|
130
|
+
// sends each event (regardless of which version originally queued
|
|
131
|
+
// it for sending)
|
|
132
|
+
if (payload['event'] && payload['properties']) {
|
|
133
|
+
payload['properties'] = _.extend(
|
|
134
|
+
{},
|
|
135
|
+
payload['properties'],
|
|
136
|
+
{'mp_sent_by_lib_version': Config.LIB_VERSION}
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
var addPayload = true;
|
|
140
|
+
var itemId = item['id'];
|
|
141
|
+
if (itemId) {
|
|
142
|
+
if ((this.itemIdsSentSuccessfully[itemId] || 0) > 5) {
|
|
143
|
+
this.reportError('[dupe] item ID sent too many times, not sending', {
|
|
144
|
+
item: item,
|
|
145
|
+
batchSize: batch.length,
|
|
146
|
+
timesSent: this.itemIdsSentSuccessfully[itemId]
|
|
147
|
+
});
|
|
148
|
+
addPayload = false;
|
|
149
|
+
}
|
|
150
|
+
} else {
|
|
151
|
+
this.reportError('[dupe] found item with no ID', {item: item});
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (addPayload) {
|
|
155
|
+
dataForRequest.push(payload);
|
|
156
|
+
}
|
|
126
157
|
}
|
|
127
158
|
transformedItems[item['id']] = payload;
|
|
128
159
|
}, this);
|
|
@@ -205,6 +236,24 @@ RequestBatcher.prototype.flush = function(options) {
|
|
|
205
236
|
}
|
|
206
237
|
}, this)
|
|
207
238
|
);
|
|
239
|
+
|
|
240
|
+
// client-side dedupe
|
|
241
|
+
_.each(batch, _.bind(function(item) {
|
|
242
|
+
var itemId = item['id'];
|
|
243
|
+
if (itemId) {
|
|
244
|
+
this.itemIdsSentSuccessfully[itemId] = this.itemIdsSentSuccessfully[itemId] || 0;
|
|
245
|
+
this.itemIdsSentSuccessfully[itemId]++;
|
|
246
|
+
if (this.itemIdsSentSuccessfully[itemId] > 5) {
|
|
247
|
+
this.reportError('[dupe] item ID sent too many times', {
|
|
248
|
+
item: item,
|
|
249
|
+
batchSize: batch.length,
|
|
250
|
+
timesSent: this.itemIdsSentSuccessfully[itemId]
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
} else {
|
|
254
|
+
this.reportError('[dupe] found item with no ID while removing', {item: item});
|
|
255
|
+
}
|
|
256
|
+
}, this));
|
|
208
257
|
}
|
|
209
258
|
|
|
210
259
|
} catch(err) {
|
package/src/utils.js
CHANGED
|
@@ -830,20 +830,24 @@ _.utf8Encode = function(string) {
|
|
|
830
830
|
|
|
831
831
|
_.UUID = (function() {
|
|
832
832
|
|
|
833
|
-
// Time
|
|
834
|
-
// 1*new Date() is a cross browser version of Date.now()
|
|
833
|
+
// Time-based entropy
|
|
835
834
|
var T = function() {
|
|
836
|
-
var
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
835
|
+
var time = 1 * new Date(); // cross-browser version of Date.now()
|
|
836
|
+
var ticks;
|
|
837
|
+
if (win.performance && win.performance.now) {
|
|
838
|
+
ticks = win.performance.now();
|
|
839
|
+
} else {
|
|
840
|
+
// fall back to busy loop
|
|
841
|
+
ticks = 0;
|
|
842
|
+
|
|
843
|
+
// this while loop figures how many browser ticks go by
|
|
844
|
+
// before 1*new Date() returns a new number, ie the amount
|
|
845
|
+
// of ticks that go by per millisecond
|
|
846
|
+
while (time == 1 * new Date()) {
|
|
847
|
+
ticks++;
|
|
848
|
+
}
|
|
844
849
|
}
|
|
845
|
-
|
|
846
|
-
return d.toString(16) + i.toString(16);
|
|
850
|
+
return time.toString(16) + Math.floor(ticks).toString(16);
|
|
847
851
|
};
|
|
848
852
|
|
|
849
853
|
// Math.Random entropy
|
|
@@ -1410,21 +1414,42 @@ _.dom_query = (function() {
|
|
|
1410
1414
|
};
|
|
1411
1415
|
})();
|
|
1412
1416
|
|
|
1417
|
+
var CAMPAIGN_KEYWORDS = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_content', 'utm_term'];
|
|
1418
|
+
var CLICK_IDS = ['dclid', 'fbclid', 'gclid', 'ko_click_id', 'li_fat_id', 'msclkid', 'ttclid', 'twclid', 'wbraid'];
|
|
1419
|
+
|
|
1413
1420
|
_.info = {
|
|
1414
|
-
campaignParams: function() {
|
|
1415
|
-
var
|
|
1416
|
-
kw = '',
|
|
1421
|
+
campaignParams: function(default_value) {
|
|
1422
|
+
var kw = '',
|
|
1417
1423
|
params = {};
|
|
1418
|
-
_.each(
|
|
1424
|
+
_.each(CAMPAIGN_KEYWORDS, function(kwkey) {
|
|
1419
1425
|
kw = _.getQueryParam(document.URL, kwkey);
|
|
1420
1426
|
if (kw.length) {
|
|
1421
1427
|
params[kwkey] = kw;
|
|
1428
|
+
} else if (default_value !== undefined) {
|
|
1429
|
+
params[kwkey] = default_value;
|
|
1422
1430
|
}
|
|
1423
1431
|
});
|
|
1424
1432
|
|
|
1425
1433
|
return params;
|
|
1426
1434
|
},
|
|
1427
1435
|
|
|
1436
|
+
clickParams: function() {
|
|
1437
|
+
var id = '',
|
|
1438
|
+
params = {};
|
|
1439
|
+
_.each(CLICK_IDS, function(idkey) {
|
|
1440
|
+
id = _.getQueryParam(document.URL, idkey);
|
|
1441
|
+
if (id.length) {
|
|
1442
|
+
params[idkey] = id;
|
|
1443
|
+
}
|
|
1444
|
+
});
|
|
1445
|
+
|
|
1446
|
+
return params;
|
|
1447
|
+
},
|
|
1448
|
+
|
|
1449
|
+
marketingParams: function() {
|
|
1450
|
+
return _.extend(_.info.campaignParams(), _.info.clickParams());
|
|
1451
|
+
},
|
|
1452
|
+
|
|
1428
1453
|
searchEngine: function(referrer) {
|
|
1429
1454
|
if (referrer.search('https?://(.*)google.([^/?]*)') === 0) {
|
|
1430
1455
|
return 'google';
|
|
@@ -1621,12 +1646,13 @@ _.info = {
|
|
|
1621
1646
|
});
|
|
1622
1647
|
},
|
|
1623
1648
|
|
|
1624
|
-
|
|
1649
|
+
mpPageViewProperties: function() {
|
|
1625
1650
|
return _.strip_empty_properties({
|
|
1626
|
-
'
|
|
1627
|
-
'
|
|
1628
|
-
'
|
|
1629
|
-
'
|
|
1651
|
+
'current_page_title': document.title,
|
|
1652
|
+
'current_domain': win.location.hostname,
|
|
1653
|
+
'current_url_path': win.location.pathname,
|
|
1654
|
+
'current_url_protocol': win.location.protocol,
|
|
1655
|
+
'current_url_search': win.location.search
|
|
1630
1656
|
});
|
|
1631
1657
|
}
|
|
1632
1658
|
};
|