mixpanel-browser 2.63.0 → 2.64.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/CHANGELOG.md +4 -0
- package/dist/mixpanel-core.cjs.js +252 -40
- package/dist/mixpanel-recorder.js +1 -1
- package/dist/mixpanel-recorder.min.js +1 -1
- package/dist/mixpanel-recorder.min.js.map +1 -1
- package/dist/mixpanel-with-async-recorder.cjs.js +252 -40
- package/dist/mixpanel-with-recorder.js +273 -61
- package/dist/mixpanel-with-recorder.min.js +1 -1
- package/dist/mixpanel.amd.js +273 -61
- package/dist/mixpanel.cjs.js +273 -61
- package/dist/mixpanel.globals.js +252 -40
- package/dist/mixpanel.min.js +149 -143
- package/dist/mixpanel.module.js +273 -61
- package/dist/mixpanel.umd.js +273 -61
- package/package.json +1 -1
- package/src/autocapture/index.js +4 -3
- package/src/autocapture/utils.js +4 -0
- package/src/config.js +1 -1
- package/src/flags/index.js +191 -0
- package/src/mixpanel-core.js +24 -3
package/dist/mixpanel.amd.js
CHANGED
|
@@ -13944,7 +13944,7 @@ define((function () { 'use strict';
|
|
|
13944
13944
|
|
|
13945
13945
|
var Config = {
|
|
13946
13946
|
DEBUG: false,
|
|
13947
|
-
LIB_VERSION: '2.
|
|
13947
|
+
LIB_VERSION: '2.64.0'
|
|
13948
13948
|
};
|
|
13949
13949
|
|
|
13950
13950
|
/* eslint camelcase: "off", eqeqeq: "off" */
|
|
@@ -16103,7 +16103,7 @@ define((function () { 'use strict';
|
|
|
16103
16103
|
};
|
|
16104
16104
|
}
|
|
16105
16105
|
|
|
16106
|
-
var logger$
|
|
16106
|
+
var logger$6 = console_with_prefix('lock');
|
|
16107
16107
|
|
|
16108
16108
|
/**
|
|
16109
16109
|
* SharedLock: a mutex built on HTML5 localStorage, to ensure that only one browser
|
|
@@ -16155,7 +16155,7 @@ define((function () { 'use strict';
|
|
|
16155
16155
|
|
|
16156
16156
|
var delay = function(cb) {
|
|
16157
16157
|
if (new Date().getTime() - startTime > timeoutMS) {
|
|
16158
|
-
logger$
|
|
16158
|
+
logger$6.error('Timeout waiting for mutex on ' + key + '; clearing lock. [' + i + ']');
|
|
16159
16159
|
storage.removeItem(keyZ);
|
|
16160
16160
|
storage.removeItem(keyY);
|
|
16161
16161
|
loop();
|
|
@@ -16298,7 +16298,7 @@ define((function () { 'use strict';
|
|
|
16298
16298
|
}, this));
|
|
16299
16299
|
};
|
|
16300
16300
|
|
|
16301
|
-
var logger$
|
|
16301
|
+
var logger$5 = console_with_prefix('batch');
|
|
16302
16302
|
|
|
16303
16303
|
/**
|
|
16304
16304
|
* RequestQueue: queue for batching API requests with localStorage backup for retries.
|
|
@@ -16327,7 +16327,7 @@ define((function () { 'use strict';
|
|
|
16327
16327
|
timeoutMS: options.sharedLockTimeoutMS,
|
|
16328
16328
|
});
|
|
16329
16329
|
}
|
|
16330
|
-
this.reportError = options.errorReporter || _.bind(logger$
|
|
16330
|
+
this.reportError = options.errorReporter || _.bind(logger$5.error, logger$5);
|
|
16331
16331
|
|
|
16332
16332
|
this.pid = options.pid || null; // pass pid to test out storage lock contention scenarios
|
|
16333
16333
|
|
|
@@ -16660,7 +16660,7 @@ define((function () { 'use strict';
|
|
|
16660
16660
|
// maximum interval between request retries after exponential backoff
|
|
16661
16661
|
var MAX_RETRY_INTERVAL_MS = 10 * 60 * 1000; // 10 minutes
|
|
16662
16662
|
|
|
16663
|
-
var logger$
|
|
16663
|
+
var logger$4 = console_with_prefix('batch');
|
|
16664
16664
|
|
|
16665
16665
|
/**
|
|
16666
16666
|
* RequestBatcher: manages the queueing, flushing, retry etc of requests of one
|
|
@@ -16788,7 +16788,7 @@ define((function () { 'use strict';
|
|
|
16788
16788
|
*/
|
|
16789
16789
|
RequestBatcher.prototype.flush = function(options) {
|
|
16790
16790
|
if (this.requestInProgress) {
|
|
16791
|
-
logger$
|
|
16791
|
+
logger$4.log('Flush: Request already in progress');
|
|
16792
16792
|
return PromisePolyfill.resolve();
|
|
16793
16793
|
}
|
|
16794
16794
|
|
|
@@ -16965,7 +16965,7 @@ define((function () { 'use strict';
|
|
|
16965
16965
|
if (options.unloading) {
|
|
16966
16966
|
requestOptions.transport = 'sendBeacon';
|
|
16967
16967
|
}
|
|
16968
|
-
logger$
|
|
16968
|
+
logger$4.log('MIXPANEL REQUEST:', dataForRequest);
|
|
16969
16969
|
return this.sendRequestPromise(dataForRequest, requestOptions).then(batchSendCallback);
|
|
16970
16970
|
}, this))
|
|
16971
16971
|
.catch(_.bind(function(err) {
|
|
@@ -16978,7 +16978,7 @@ define((function () { 'use strict';
|
|
|
16978
16978
|
* Log error to global logger and optional user-defined logger.
|
|
16979
16979
|
*/
|
|
16980
16980
|
RequestBatcher.prototype.reportError = function(msg, err) {
|
|
16981
|
-
logger$
|
|
16981
|
+
logger$4.error.apply(logger$4.error, arguments);
|
|
16982
16982
|
if (this.errorReporter) {
|
|
16983
16983
|
try {
|
|
16984
16984
|
if (!(err instanceof Error)) {
|
|
@@ -16986,7 +16986,7 @@ define((function () { 'use strict';
|
|
|
16986
16986
|
}
|
|
16987
16987
|
this.errorReporter(msg, err);
|
|
16988
16988
|
} catch(err) {
|
|
16989
|
-
logger$
|
|
16989
|
+
logger$4.error(err);
|
|
16990
16990
|
}
|
|
16991
16991
|
}
|
|
16992
16992
|
};
|
|
@@ -17002,7 +17002,7 @@ define((function () { 'use strict';
|
|
|
17002
17002
|
|
|
17003
17003
|
var RECORD_ENQUEUE_THROTTLE_MS = 250;
|
|
17004
17004
|
|
|
17005
|
-
var logger$
|
|
17005
|
+
var logger$3 = console_with_prefix('recorder');
|
|
17006
17006
|
var CompressionStream = win['CompressionStream'];
|
|
17007
17007
|
|
|
17008
17008
|
var RECORDER_BATCHER_LIB_CONFIG = {
|
|
@@ -17139,14 +17139,14 @@ define((function () { 'use strict';
|
|
|
17139
17139
|
}
|
|
17140
17140
|
|
|
17141
17141
|
if (this._stopRecording !== null) {
|
|
17142
|
-
logger$
|
|
17142
|
+
logger$3.log('Recording already in progress, skipping startRecording.');
|
|
17143
17143
|
return;
|
|
17144
17144
|
}
|
|
17145
17145
|
|
|
17146
17146
|
this.recordMaxMs = this.getConfig('record_max_ms');
|
|
17147
17147
|
if (this.recordMaxMs > MAX_RECORDING_MS) {
|
|
17148
17148
|
this.recordMaxMs = MAX_RECORDING_MS;
|
|
17149
|
-
logger$
|
|
17149
|
+
logger$3.critical('record_max_ms cannot be greater than ' + MAX_RECORDING_MS + 'ms. Capping value.');
|
|
17150
17150
|
}
|
|
17151
17151
|
|
|
17152
17152
|
if (!this.maxExpires) {
|
|
@@ -17156,7 +17156,7 @@ define((function () { 'use strict';
|
|
|
17156
17156
|
this.recordMinMs = this.getConfig('record_min_ms');
|
|
17157
17157
|
if (this.recordMinMs > MAX_VALUE_FOR_MIN_RECORDING_MS) {
|
|
17158
17158
|
this.recordMinMs = MAX_VALUE_FOR_MIN_RECORDING_MS;
|
|
17159
|
-
logger$
|
|
17159
|
+
logger$3.critical('record_min_ms cannot be greater than ' + MAX_VALUE_FOR_MIN_RECORDING_MS + 'ms. Capping value.');
|
|
17160
17160
|
}
|
|
17161
17161
|
|
|
17162
17162
|
if (!this.replayStartTime) {
|
|
@@ -17440,14 +17440,14 @@ define((function () { 'use strict';
|
|
|
17440
17440
|
|
|
17441
17441
|
|
|
17442
17442
|
SessionRecording.prototype.reportError = function(msg, err) {
|
|
17443
|
-
logger$
|
|
17443
|
+
logger$3.error.apply(logger$3.error, arguments);
|
|
17444
17444
|
try {
|
|
17445
17445
|
if (!err && !(msg instanceof Error)) {
|
|
17446
17446
|
msg = new Error(msg);
|
|
17447
17447
|
}
|
|
17448
17448
|
this.getConfig('error_reporter')(msg, err);
|
|
17449
17449
|
} catch(err) {
|
|
17450
|
-
logger$
|
|
17450
|
+
logger$3.error(err);
|
|
17451
17451
|
}
|
|
17452
17452
|
};
|
|
17453
17453
|
|
|
@@ -17543,7 +17543,7 @@ define((function () { 'use strict';
|
|
|
17543
17543
|
.catch(this.handleError.bind(this));
|
|
17544
17544
|
};
|
|
17545
17545
|
|
|
17546
|
-
var logger$
|
|
17546
|
+
var logger$2 = console_with_prefix('recorder');
|
|
17547
17547
|
|
|
17548
17548
|
/**
|
|
17549
17549
|
* Recorder API: bundles rrweb and and exposes methods to start and stop recordings.
|
|
@@ -17559,7 +17559,7 @@ define((function () { 'use strict';
|
|
|
17559
17559
|
*/
|
|
17560
17560
|
this.recordingRegistry = new RecordingRegistry({
|
|
17561
17561
|
mixpanelInstance: this.mixpanelInstance,
|
|
17562
|
-
errorReporter: logger$
|
|
17562
|
+
errorReporter: logger$2.error,
|
|
17563
17563
|
sharedLockStorage: sharedLockStorage
|
|
17564
17564
|
});
|
|
17565
17565
|
this._flushInactivePromise = this.recordingRegistry.flushInactiveRecordings();
|
|
@@ -17570,17 +17570,17 @@ define((function () { 'use strict';
|
|
|
17570
17570
|
MixpanelRecorder.prototype.startRecording = function(options) {
|
|
17571
17571
|
options = options || {};
|
|
17572
17572
|
if (this.activeRecording && !this.activeRecording.isRrwebStopped()) {
|
|
17573
|
-
logger$
|
|
17573
|
+
logger$2.log('Recording already in progress, skipping startRecording.');
|
|
17574
17574
|
return;
|
|
17575
17575
|
}
|
|
17576
17576
|
|
|
17577
17577
|
var onIdleTimeout = function () {
|
|
17578
|
-
logger$
|
|
17578
|
+
logger$2.log('Idle timeout reached, restarting recording.');
|
|
17579
17579
|
this.resetRecording();
|
|
17580
17580
|
}.bind(this);
|
|
17581
17581
|
|
|
17582
17582
|
var onMaxLengthReached = function () {
|
|
17583
|
-
logger$
|
|
17583
|
+
logger$2.log('Max recording length reached, stopping recording.');
|
|
17584
17584
|
this.resetRecording();
|
|
17585
17585
|
}.bind(this);
|
|
17586
17586
|
|
|
@@ -17643,7 +17643,7 @@ define((function () { 'use strict';
|
|
|
17643
17643
|
} else if (startNewIfInactive) {
|
|
17644
17644
|
return this.startRecording({shouldStopBatcher: false});
|
|
17645
17645
|
} else {
|
|
17646
|
-
logger$
|
|
17646
|
+
logger$2.log('No resumable recording found.');
|
|
17647
17647
|
return null;
|
|
17648
17648
|
}
|
|
17649
17649
|
}.bind(this));
|
|
@@ -17701,7 +17701,7 @@ define((function () { 'use strict';
|
|
|
17701
17701
|
'href', 'name', 'role', 'title', 'type'
|
|
17702
17702
|
];
|
|
17703
17703
|
|
|
17704
|
-
var logger = console_with_prefix('autocapture');
|
|
17704
|
+
var logger$1 = console_with_prefix('autocapture');
|
|
17705
17705
|
|
|
17706
17706
|
|
|
17707
17707
|
function getClasses(el) {
|
|
@@ -17787,6 +17787,7 @@ define((function () { 'use strict';
|
|
|
17787
17787
|
var blockSelectors = config.blockSelectors || [];
|
|
17788
17788
|
var captureTextContent = config.captureTextContent || false;
|
|
17789
17789
|
var captureExtraAttrs = config.captureExtraAttrs || [];
|
|
17790
|
+
var capturedForHeatMap = config.capturedForHeatMap || false;
|
|
17790
17791
|
|
|
17791
17792
|
// convert array to set every time, as the config may have changed
|
|
17792
17793
|
var blockAttrsSet = {};
|
|
@@ -17865,6 +17866,9 @@ define((function () { 'use strict';
|
|
|
17865
17866
|
props['$' + prop] = ev[prop];
|
|
17866
17867
|
}
|
|
17867
17868
|
});
|
|
17869
|
+
if (capturedForHeatMap) {
|
|
17870
|
+
props['$captured_for_heatmap'] = true;
|
|
17871
|
+
}
|
|
17868
17872
|
target = guessRealClickTarget(ev);
|
|
17869
17873
|
}
|
|
17870
17874
|
// prioritize text content from "real" click target if different from original target
|
|
@@ -17959,7 +17963,7 @@ define((function () { 'use strict';
|
|
|
17959
17963
|
return false;
|
|
17960
17964
|
}
|
|
17961
17965
|
} catch (err) {
|
|
17962
|
-
logger.critical('Error while checking element in allowElementCallback', err);
|
|
17966
|
+
logger$1.critical('Error while checking element in allowElementCallback', err);
|
|
17963
17967
|
return false;
|
|
17964
17968
|
}
|
|
17965
17969
|
}
|
|
@@ -17976,7 +17980,7 @@ define((function () { 'use strict';
|
|
|
17976
17980
|
return true;
|
|
17977
17981
|
}
|
|
17978
17982
|
} catch (err) {
|
|
17979
|
-
logger.critical('Error while checking selector: ' + sel, err);
|
|
17983
|
+
logger$1.critical('Error while checking selector: ' + sel, err);
|
|
17980
17984
|
}
|
|
17981
17985
|
}
|
|
17982
17986
|
return false;
|
|
@@ -17991,7 +17995,7 @@ define((function () { 'use strict';
|
|
|
17991
17995
|
return true;
|
|
17992
17996
|
}
|
|
17993
17997
|
} catch (err) {
|
|
17994
|
-
logger.critical('Error while checking element in blockElementCallback', err);
|
|
17998
|
+
logger$1.critical('Error while checking element in blockElementCallback', err);
|
|
17995
17999
|
return true;
|
|
17996
18000
|
}
|
|
17997
18001
|
}
|
|
@@ -18005,7 +18009,7 @@ define((function () { 'use strict';
|
|
|
18005
18009
|
return true;
|
|
18006
18010
|
}
|
|
18007
18011
|
} catch (err) {
|
|
18008
|
-
logger.critical('Error while checking selector: ' + sel, err);
|
|
18012
|
+
logger$1.critical('Error while checking selector: ' + sel, err);
|
|
18009
18013
|
}
|
|
18010
18014
|
}
|
|
18011
18015
|
}
|
|
@@ -18211,22 +18215,22 @@ define((function () { 'use strict';
|
|
|
18211
18215
|
var CONFIG_TRACK_SCROLL = 'scroll';
|
|
18212
18216
|
var CONFIG_TRACK_SUBMIT = 'submit';
|
|
18213
18217
|
|
|
18214
|
-
var CONFIG_DEFAULTS = {};
|
|
18215
|
-
CONFIG_DEFAULTS[CONFIG_ALLOW_SELECTORS] = [];
|
|
18216
|
-
CONFIG_DEFAULTS[CONFIG_ALLOW_URL_REGEXES] = [];
|
|
18217
|
-
CONFIG_DEFAULTS[CONFIG_BLOCK_ATTRS] = [];
|
|
18218
|
-
CONFIG_DEFAULTS[CONFIG_BLOCK_ELEMENT_CALLBACK] = null;
|
|
18219
|
-
CONFIG_DEFAULTS[CONFIG_BLOCK_SELECTORS] = [];
|
|
18220
|
-
CONFIG_DEFAULTS[CONFIG_BLOCK_URL_REGEXES] = [];
|
|
18221
|
-
CONFIG_DEFAULTS[CONFIG_CAPTURE_EXTRA_ATTRS] = [];
|
|
18222
|
-
CONFIG_DEFAULTS[CONFIG_CAPTURE_TEXT_CONTENT] = false;
|
|
18223
|
-
CONFIG_DEFAULTS[CONFIG_SCROLL_CAPTURE_ALL] = false;
|
|
18224
|
-
CONFIG_DEFAULTS[CONFIG_SCROLL_CHECKPOINTS] = [25, 50, 75, 100];
|
|
18225
|
-
CONFIG_DEFAULTS[CONFIG_TRACK_CLICK] = true;
|
|
18226
|
-
CONFIG_DEFAULTS[CONFIG_TRACK_INPUT] = true;
|
|
18227
|
-
CONFIG_DEFAULTS[CONFIG_TRACK_PAGEVIEW] = PAGEVIEW_OPTION_FULL_URL;
|
|
18228
|
-
CONFIG_DEFAULTS[CONFIG_TRACK_SCROLL] = true;
|
|
18229
|
-
CONFIG_DEFAULTS[CONFIG_TRACK_SUBMIT] = true;
|
|
18218
|
+
var CONFIG_DEFAULTS$1 = {};
|
|
18219
|
+
CONFIG_DEFAULTS$1[CONFIG_ALLOW_SELECTORS] = [];
|
|
18220
|
+
CONFIG_DEFAULTS$1[CONFIG_ALLOW_URL_REGEXES] = [];
|
|
18221
|
+
CONFIG_DEFAULTS$1[CONFIG_BLOCK_ATTRS] = [];
|
|
18222
|
+
CONFIG_DEFAULTS$1[CONFIG_BLOCK_ELEMENT_CALLBACK] = null;
|
|
18223
|
+
CONFIG_DEFAULTS$1[CONFIG_BLOCK_SELECTORS] = [];
|
|
18224
|
+
CONFIG_DEFAULTS$1[CONFIG_BLOCK_URL_REGEXES] = [];
|
|
18225
|
+
CONFIG_DEFAULTS$1[CONFIG_CAPTURE_EXTRA_ATTRS] = [];
|
|
18226
|
+
CONFIG_DEFAULTS$1[CONFIG_CAPTURE_TEXT_CONTENT] = false;
|
|
18227
|
+
CONFIG_DEFAULTS$1[CONFIG_SCROLL_CAPTURE_ALL] = false;
|
|
18228
|
+
CONFIG_DEFAULTS$1[CONFIG_SCROLL_CHECKPOINTS] = [25, 50, 75, 100];
|
|
18229
|
+
CONFIG_DEFAULTS$1[CONFIG_TRACK_CLICK] = true;
|
|
18230
|
+
CONFIG_DEFAULTS$1[CONFIG_TRACK_INPUT] = true;
|
|
18231
|
+
CONFIG_DEFAULTS$1[CONFIG_TRACK_PAGEVIEW] = PAGEVIEW_OPTION_FULL_URL;
|
|
18232
|
+
CONFIG_DEFAULTS$1[CONFIG_TRACK_SCROLL] = true;
|
|
18233
|
+
CONFIG_DEFAULTS$1[CONFIG_TRACK_SUBMIT] = true;
|
|
18230
18234
|
|
|
18231
18235
|
var DEFAULT_PROPS = {
|
|
18232
18236
|
'$mp_autocapture': true
|
|
@@ -18247,7 +18251,7 @@ define((function () { 'use strict';
|
|
|
18247
18251
|
|
|
18248
18252
|
Autocapture.prototype.init = function() {
|
|
18249
18253
|
if (!minDOMApisSupported()) {
|
|
18250
|
-
logger.critical('Autocapture unavailable: missing required DOM APIs');
|
|
18254
|
+
logger$1.critical('Autocapture unavailable: missing required DOM APIs');
|
|
18251
18255
|
return;
|
|
18252
18256
|
}
|
|
18253
18257
|
|
|
@@ -18264,10 +18268,10 @@ define((function () { 'use strict';
|
|
|
18264
18268
|
// Autocapture is completely off
|
|
18265
18269
|
return {};
|
|
18266
18270
|
} else if (_.isObject(autocaptureConfig)) {
|
|
18267
|
-
return _.extend({}, CONFIG_DEFAULTS, autocaptureConfig);
|
|
18271
|
+
return _.extend({}, CONFIG_DEFAULTS$1, autocaptureConfig);
|
|
18268
18272
|
} else {
|
|
18269
18273
|
// Autocapture config is non-object truthy value, return default
|
|
18270
|
-
return CONFIG_DEFAULTS;
|
|
18274
|
+
return CONFIG_DEFAULTS$1;
|
|
18271
18275
|
}
|
|
18272
18276
|
};
|
|
18273
18277
|
|
|
@@ -18291,7 +18295,7 @@ define((function () { 'use strict';
|
|
|
18291
18295
|
break;
|
|
18292
18296
|
}
|
|
18293
18297
|
} catch (err) {
|
|
18294
|
-
logger.critical('Error while checking block URL regex: ' + allowRegex, err);
|
|
18298
|
+
logger$1.critical('Error while checking block URL regex: ' + allowRegex, err);
|
|
18295
18299
|
return true;
|
|
18296
18300
|
}
|
|
18297
18301
|
}
|
|
@@ -18312,7 +18316,7 @@ define((function () { 'use strict';
|
|
|
18312
18316
|
return true;
|
|
18313
18317
|
}
|
|
18314
18318
|
} catch (err) {
|
|
18315
|
-
logger.critical('Error while checking block URL regex: ' + blockUrlRegexes[i], err);
|
|
18319
|
+
logger$1.critical('Error while checking block URL regex: ' + blockUrlRegexes[i], err);
|
|
18316
18320
|
return true;
|
|
18317
18321
|
}
|
|
18318
18322
|
}
|
|
@@ -18341,7 +18345,8 @@ define((function () { 'use strict';
|
|
|
18341
18345
|
blockElementCallback: this.getConfig(CONFIG_BLOCK_ELEMENT_CALLBACK),
|
|
18342
18346
|
blockSelectors: this.getConfig(CONFIG_BLOCK_SELECTORS),
|
|
18343
18347
|
captureExtraAttrs: this.getConfig(CONFIG_CAPTURE_EXTRA_ATTRS),
|
|
18344
|
-
captureTextContent: this.getConfig(CONFIG_CAPTURE_TEXT_CONTENT)
|
|
18348
|
+
captureTextContent: this.getConfig(CONFIG_CAPTURE_TEXT_CONTENT),
|
|
18349
|
+
capturedForHeatMap: mpEventName === MP_EV_CLICK && !this.getConfig(CONFIG_TRACK_CLICK) && this.mp.is_recording_heatmap_data(),
|
|
18345
18350
|
});
|
|
18346
18351
|
if (props) {
|
|
18347
18352
|
_.extend(props, DEFAULT_PROPS);
|
|
@@ -18352,13 +18357,13 @@ define((function () { 'use strict';
|
|
|
18352
18357
|
Autocapture.prototype.initClickTracking = function() {
|
|
18353
18358
|
win.removeEventListener(EV_CLICK, this.listenerClick);
|
|
18354
18359
|
|
|
18355
|
-
if (!this.getConfig(CONFIG_TRACK_CLICK)) {
|
|
18360
|
+
if (!this.getConfig(CONFIG_TRACK_CLICK) && !this.mp.get_config('record_heatmap_data')) {
|
|
18356
18361
|
return;
|
|
18357
18362
|
}
|
|
18358
|
-
logger.log('Initializing click tracking');
|
|
18363
|
+
logger$1.log('Initializing click tracking');
|
|
18359
18364
|
|
|
18360
18365
|
this.listenerClick = win.addEventListener(EV_CLICK, function(ev) {
|
|
18361
|
-
if (!this.getConfig(CONFIG_TRACK_CLICK)) {
|
|
18366
|
+
if (!this.getConfig(CONFIG_TRACK_CLICK) && !this.mp.is_recording_heatmap_data()) {
|
|
18362
18367
|
return;
|
|
18363
18368
|
}
|
|
18364
18369
|
this.trackDomEvent(ev, MP_EV_CLICK);
|
|
@@ -18371,7 +18376,7 @@ define((function () { 'use strict';
|
|
|
18371
18376
|
if (!this.getConfig(CONFIG_TRACK_INPUT)) {
|
|
18372
18377
|
return;
|
|
18373
18378
|
}
|
|
18374
|
-
logger.log('Initializing input tracking');
|
|
18379
|
+
logger$1.log('Initializing input tracking');
|
|
18375
18380
|
|
|
18376
18381
|
this.listenerChange = win.addEventListener(EV_CHANGE, function(ev) {
|
|
18377
18382
|
if (!this.getConfig(CONFIG_TRACK_INPUT)) {
|
|
@@ -18389,7 +18394,7 @@ define((function () { 'use strict';
|
|
|
18389
18394
|
if (!this.pageviewTrackingConfig()) {
|
|
18390
18395
|
return;
|
|
18391
18396
|
}
|
|
18392
|
-
logger.log('Initializing pageview tracking');
|
|
18397
|
+
logger$1.log('Initializing pageview tracking');
|
|
18393
18398
|
|
|
18394
18399
|
var previousTrackedUrl = '';
|
|
18395
18400
|
var tracked = false;
|
|
@@ -18444,7 +18449,7 @@ define((function () { 'use strict';
|
|
|
18444
18449
|
}
|
|
18445
18450
|
if (didPathChange) {
|
|
18446
18451
|
this.lastScrollCheckpoint = 0;
|
|
18447
|
-
logger.log('Path change: re-initializing scroll depth checkpoints');
|
|
18452
|
+
logger$1.log('Path change: re-initializing scroll depth checkpoints');
|
|
18448
18453
|
}
|
|
18449
18454
|
}
|
|
18450
18455
|
}.bind(this)));
|
|
@@ -18456,7 +18461,7 @@ define((function () { 'use strict';
|
|
|
18456
18461
|
if (!this.getConfig(CONFIG_TRACK_SCROLL)) {
|
|
18457
18462
|
return;
|
|
18458
18463
|
}
|
|
18459
|
-
logger.log('Initializing scroll tracking');
|
|
18464
|
+
logger$1.log('Initializing scroll tracking');
|
|
18460
18465
|
this.lastScrollCheckpoint = 0;
|
|
18461
18466
|
|
|
18462
18467
|
this.listenerScroll = win.addEventListener(EV_SCROLLEND, safewrap(function() {
|
|
@@ -18493,7 +18498,7 @@ define((function () { 'use strict';
|
|
|
18493
18498
|
}
|
|
18494
18499
|
}
|
|
18495
18500
|
} catch (err) {
|
|
18496
|
-
logger.critical('Error while calculating scroll percentage', err);
|
|
18501
|
+
logger$1.critical('Error while calculating scroll percentage', err);
|
|
18497
18502
|
}
|
|
18498
18503
|
if (shouldTrack) {
|
|
18499
18504
|
this.mp.track(MP_EV_SCROLL, props);
|
|
@@ -18507,7 +18512,7 @@ define((function () { 'use strict';
|
|
|
18507
18512
|
if (!this.getConfig(CONFIG_TRACK_SUBMIT)) {
|
|
18508
18513
|
return;
|
|
18509
18514
|
}
|
|
18510
|
-
logger.log('Initializing submit tracking');
|
|
18515
|
+
logger$1.log('Initializing submit tracking');
|
|
18511
18516
|
|
|
18512
18517
|
this.listenerSubmit = win.addEventListener(EV_SUBMIT, function(ev) {
|
|
18513
18518
|
if (!this.getConfig(CONFIG_TRACK_SUBMIT)) {
|
|
@@ -18520,6 +18525,193 @@ define((function () { 'use strict';
|
|
|
18520
18525
|
// TODO integrate error_reporter from mixpanel instance
|
|
18521
18526
|
safewrapClass(Autocapture);
|
|
18522
18527
|
|
|
18528
|
+
var fetch = win['fetch'];
|
|
18529
|
+
var logger = console_with_prefix('flags');
|
|
18530
|
+
|
|
18531
|
+
var FLAGS_CONFIG_KEY = 'flags';
|
|
18532
|
+
|
|
18533
|
+
var CONFIG_CONTEXT = 'context';
|
|
18534
|
+
var CONFIG_DEFAULTS = {};
|
|
18535
|
+
CONFIG_DEFAULTS[CONFIG_CONTEXT] = {};
|
|
18536
|
+
|
|
18537
|
+
/**
|
|
18538
|
+
* FeatureFlagManager: support for Mixpanel's feature flagging product
|
|
18539
|
+
* @constructor
|
|
18540
|
+
*/
|
|
18541
|
+
var FeatureFlagManager = function(initOptions) {
|
|
18542
|
+
this.getMpConfig = initOptions.getConfigFunc;
|
|
18543
|
+
this.getDistinctId = initOptions.getDistinctIdFunc;
|
|
18544
|
+
this.track = initOptions.trackingFunc;
|
|
18545
|
+
};
|
|
18546
|
+
|
|
18547
|
+
FeatureFlagManager.prototype.init = function() {
|
|
18548
|
+
if (!minApisSupported()) {
|
|
18549
|
+
logger.critical('Feature Flags unavailable: missing minimum required APIs');
|
|
18550
|
+
return;
|
|
18551
|
+
}
|
|
18552
|
+
|
|
18553
|
+
this.flags = null;
|
|
18554
|
+
this.fetchFlags();
|
|
18555
|
+
|
|
18556
|
+
this.trackedFeatures = new Set();
|
|
18557
|
+
};
|
|
18558
|
+
|
|
18559
|
+
FeatureFlagManager.prototype.getFullConfig = function() {
|
|
18560
|
+
var ffConfig = this.getMpConfig(FLAGS_CONFIG_KEY);
|
|
18561
|
+
if (!ffConfig) {
|
|
18562
|
+
// flags are completely off
|
|
18563
|
+
return {};
|
|
18564
|
+
} else if (_.isObject(ffConfig)) {
|
|
18565
|
+
return _.extend({}, CONFIG_DEFAULTS, ffConfig);
|
|
18566
|
+
} else {
|
|
18567
|
+
// config is non-object truthy value, return default
|
|
18568
|
+
return CONFIG_DEFAULTS;
|
|
18569
|
+
}
|
|
18570
|
+
};
|
|
18571
|
+
|
|
18572
|
+
FeatureFlagManager.prototype.getConfig = function(key) {
|
|
18573
|
+
return this.getFullConfig()[key];
|
|
18574
|
+
};
|
|
18575
|
+
|
|
18576
|
+
FeatureFlagManager.prototype.isEnabled = function() {
|
|
18577
|
+
return !!this.getMpConfig(FLAGS_CONFIG_KEY);
|
|
18578
|
+
};
|
|
18579
|
+
|
|
18580
|
+
FeatureFlagManager.prototype.areFeaturesReady = function() {
|
|
18581
|
+
if (!this.isEnabled()) {
|
|
18582
|
+
logger.error('Feature Flags not enabled');
|
|
18583
|
+
}
|
|
18584
|
+
return !!this.flags;
|
|
18585
|
+
};
|
|
18586
|
+
|
|
18587
|
+
FeatureFlagManager.prototype.fetchFlags = function() {
|
|
18588
|
+
if (!this.isEnabled()) {
|
|
18589
|
+
return;
|
|
18590
|
+
}
|
|
18591
|
+
|
|
18592
|
+
var distinctId = this.getDistinctId();
|
|
18593
|
+
logger.log('Fetching flags for distinct ID: ' + distinctId);
|
|
18594
|
+
var reqParams = {
|
|
18595
|
+
'context': _.extend({'distinct_id': distinctId}, this.getConfig(CONFIG_CONTEXT))
|
|
18596
|
+
};
|
|
18597
|
+
this.fetchPromise = win['fetch'](this.getMpConfig('api_host') + '/' + this.getMpConfig('api_routes')['flags'], {
|
|
18598
|
+
'method': 'POST',
|
|
18599
|
+
'headers': {
|
|
18600
|
+
'Authorization': 'Basic ' + btoa(this.getMpConfig('token') + ':'),
|
|
18601
|
+
'Content-Type': 'application/octet-stream'
|
|
18602
|
+
},
|
|
18603
|
+
'body': JSON.stringify(reqParams)
|
|
18604
|
+
}).then(function(response) {
|
|
18605
|
+
return response.json().then(function(responseBody) {
|
|
18606
|
+
var responseFlags = responseBody['flags'];
|
|
18607
|
+
if (!responseFlags) {
|
|
18608
|
+
throw new Error('No flags in API response');
|
|
18609
|
+
}
|
|
18610
|
+
var flags = new Map();
|
|
18611
|
+
_.each(responseFlags, function(data, key) {
|
|
18612
|
+
flags.set(key, {
|
|
18613
|
+
'key': data['variant_key'],
|
|
18614
|
+
'data': data['variant_value']
|
|
18615
|
+
});
|
|
18616
|
+
});
|
|
18617
|
+
this.flags = flags;
|
|
18618
|
+
}.bind(this)).catch(function(error) {
|
|
18619
|
+
logger.error(error);
|
|
18620
|
+
});
|
|
18621
|
+
}.bind(this)).catch(function() {});
|
|
18622
|
+
};
|
|
18623
|
+
|
|
18624
|
+
FeatureFlagManager.prototype.getFeature = function(featureName, fallback) {
|
|
18625
|
+
if (!this.fetchPromise) {
|
|
18626
|
+
return new Promise(function(resolve) {
|
|
18627
|
+
logger.critical('Feature Flags not initialized');
|
|
18628
|
+
resolve(fallback);
|
|
18629
|
+
});
|
|
18630
|
+
}
|
|
18631
|
+
|
|
18632
|
+
return this.fetchPromise.then(function() {
|
|
18633
|
+
return this.getFeatureSync(featureName, fallback);
|
|
18634
|
+
}.bind(this)).catch(function(error) {
|
|
18635
|
+
logger.error(error);
|
|
18636
|
+
return fallback;
|
|
18637
|
+
});
|
|
18638
|
+
};
|
|
18639
|
+
|
|
18640
|
+
FeatureFlagManager.prototype.getFeatureSync = function(featureName, fallback) {
|
|
18641
|
+
if (!this.areFeaturesReady()) {
|
|
18642
|
+
logger.log('Flags not loaded yet');
|
|
18643
|
+
return fallback;
|
|
18644
|
+
}
|
|
18645
|
+
var feature = this.flags.get(featureName);
|
|
18646
|
+
if (!feature) {
|
|
18647
|
+
logger.log('No flag found: "' + featureName + '"');
|
|
18648
|
+
return fallback;
|
|
18649
|
+
}
|
|
18650
|
+
this.trackFeatureCheck(featureName, feature);
|
|
18651
|
+
return feature;
|
|
18652
|
+
};
|
|
18653
|
+
|
|
18654
|
+
FeatureFlagManager.prototype.getFeatureData = function(featureName, fallbackValue) {
|
|
18655
|
+
return this.getFeature(featureName, {'data': fallbackValue}).then(function(feature) {
|
|
18656
|
+
return feature['data'];
|
|
18657
|
+
}).catch(function(error) {
|
|
18658
|
+
logger.error(error);
|
|
18659
|
+
return fallbackValue;
|
|
18660
|
+
});
|
|
18661
|
+
};
|
|
18662
|
+
|
|
18663
|
+
FeatureFlagManager.prototype.getFeatureDataSync = function(featureName, fallbackValue) {
|
|
18664
|
+
return this.getFeatureSync(featureName, {'data': fallbackValue})['data'];
|
|
18665
|
+
};
|
|
18666
|
+
|
|
18667
|
+
FeatureFlagManager.prototype.isFeatureEnabled = function(featureName, fallbackValue) {
|
|
18668
|
+
return this.getFeatureData(featureName).then(function() {
|
|
18669
|
+
return this.isFeatureEnabledSync(featureName, fallbackValue);
|
|
18670
|
+
}.bind(this)).catch(function(error) {
|
|
18671
|
+
logger.error(error);
|
|
18672
|
+
return fallbackValue;
|
|
18673
|
+
});
|
|
18674
|
+
};
|
|
18675
|
+
|
|
18676
|
+
FeatureFlagManager.prototype.isFeatureEnabledSync = function(featureName, fallbackValue) {
|
|
18677
|
+
fallbackValue = fallbackValue || false;
|
|
18678
|
+
var val = this.getFeatureDataSync(featureName, fallbackValue);
|
|
18679
|
+
if (val !== true && val !== false) {
|
|
18680
|
+
logger.error('Feature flag "' + featureName + '" value: ' + val + ' is not a boolean; returning fallback value: ' + fallbackValue);
|
|
18681
|
+
val = fallbackValue;
|
|
18682
|
+
}
|
|
18683
|
+
return val;
|
|
18684
|
+
};
|
|
18685
|
+
|
|
18686
|
+
FeatureFlagManager.prototype.trackFeatureCheck = function(featureName, feature) {
|
|
18687
|
+
if (this.trackedFeatures.has(featureName)) {
|
|
18688
|
+
return;
|
|
18689
|
+
}
|
|
18690
|
+
this.trackedFeatures.add(featureName);
|
|
18691
|
+
this.track('$experiment_started', {
|
|
18692
|
+
'Experiment name': featureName,
|
|
18693
|
+
'Variant name': feature['key'],
|
|
18694
|
+
'$experiment_type': 'feature_flag'
|
|
18695
|
+
});
|
|
18696
|
+
};
|
|
18697
|
+
|
|
18698
|
+
function minApisSupported() {
|
|
18699
|
+
return !!fetch &&
|
|
18700
|
+
typeof Promise !== 'undefined' &&
|
|
18701
|
+
typeof Map !== 'undefined' &&
|
|
18702
|
+
typeof Set !== 'undefined';
|
|
18703
|
+
}
|
|
18704
|
+
|
|
18705
|
+
safewrapClass(FeatureFlagManager);
|
|
18706
|
+
|
|
18707
|
+
FeatureFlagManager.prototype['are_features_ready'] = FeatureFlagManager.prototype.areFeaturesReady;
|
|
18708
|
+
FeatureFlagManager.prototype['get_feature'] = FeatureFlagManager.prototype.getFeature;
|
|
18709
|
+
FeatureFlagManager.prototype['get_feature_data'] = FeatureFlagManager.prototype.getFeatureData;
|
|
18710
|
+
FeatureFlagManager.prototype['get_feature_data_sync'] = FeatureFlagManager.prototype.getFeatureDataSync;
|
|
18711
|
+
FeatureFlagManager.prototype['get_feature_sync'] = FeatureFlagManager.prototype.getFeatureSync;
|
|
18712
|
+
FeatureFlagManager.prototype['is_feature_enabled'] = FeatureFlagManager.prototype.isFeatureEnabled;
|
|
18713
|
+
FeatureFlagManager.prototype['is_feature_enabled_sync'] = FeatureFlagManager.prototype.isFeatureEnabledSync;
|
|
18714
|
+
|
|
18523
18715
|
/* eslint camelcase: "off" */
|
|
18524
18716
|
|
|
18525
18717
|
|
|
@@ -19924,10 +20116,11 @@ define((function () { 'use strict';
|
|
|
19924
20116
|
}
|
|
19925
20117
|
|
|
19926
20118
|
var DEFAULT_API_ROUTES = {
|
|
19927
|
-
'track':
|
|
20119
|
+
'track': 'track/',
|
|
19928
20120
|
'engage': 'engage/',
|
|
19929
20121
|
'groups': 'groups/',
|
|
19930
|
-
'record': 'record/'
|
|
20122
|
+
'record': 'record/',
|
|
20123
|
+
'flags': 'flags/'
|
|
19931
20124
|
};
|
|
19932
20125
|
|
|
19933
20126
|
/*
|
|
@@ -19945,6 +20138,7 @@ define((function () { 'use strict';
|
|
|
19945
20138
|
'cross_site_cookie': false,
|
|
19946
20139
|
'cross_subdomain_cookie': true,
|
|
19947
20140
|
'error_reporter': NOOP_FUNC,
|
|
20141
|
+
'flags': false,
|
|
19948
20142
|
'persistence': 'cookie',
|
|
19949
20143
|
'persistence_name': '',
|
|
19950
20144
|
'cookie_domain': '',
|
|
@@ -19985,6 +20179,7 @@ define((function () { 'use strict';
|
|
|
19985
20179
|
'record_block_selector': 'img, video',
|
|
19986
20180
|
'record_canvas': false,
|
|
19987
20181
|
'record_collect_fonts': false,
|
|
20182
|
+
'record_heatmap_data': false,
|
|
19988
20183
|
'record_idle_timeout_ms': 30 * 60 * 1000, // 30 minutes
|
|
19989
20184
|
'record_mask_text_class': new RegExp('^(mp-mask|fs-mask|amp-mask|rr-mask|ph-mask)$'),
|
|
19990
20185
|
'record_mask_text_selector': '*',
|
|
@@ -20200,6 +20395,14 @@ define((function () { 'use strict';
|
|
|
20200
20395
|
}, '');
|
|
20201
20396
|
}
|
|
20202
20397
|
|
|
20398
|
+
this.flags = new FeatureFlagManager({
|
|
20399
|
+
getConfigFunc: _.bind(this.get_config, this),
|
|
20400
|
+
getDistinctIdFunc: _.bind(this.get_distinct_id, this),
|
|
20401
|
+
trackingFunc: _.bind(this.track, this)
|
|
20402
|
+
});
|
|
20403
|
+
this.flags.init();
|
|
20404
|
+
this['flags'] = this.flags;
|
|
20405
|
+
|
|
20203
20406
|
this.autocapture = new Autocapture(this);
|
|
20204
20407
|
this.autocapture.init();
|
|
20205
20408
|
|
|
@@ -20325,6 +20528,10 @@ define((function () { 'use strict';
|
|
|
20325
20528
|
}
|
|
20326
20529
|
};
|
|
20327
20530
|
|
|
20531
|
+
MixpanelLib.prototype.is_recording_heatmap_data = function () {
|
|
20532
|
+
return this._get_session_replay_id() && this.get_config('record_heatmap_data');
|
|
20533
|
+
};
|
|
20534
|
+
|
|
20328
20535
|
MixpanelLib.prototype.get_session_recording_properties = function () {
|
|
20329
20536
|
var props = {};
|
|
20330
20537
|
var replay_id = this._get_session_replay_id();
|
|
@@ -21406,6 +21613,11 @@ define((function () { 'use strict';
|
|
|
21406
21613
|
'$anon_distinct_id': previous_distinct_id
|
|
21407
21614
|
}, {skip_hooks: true});
|
|
21408
21615
|
}
|
|
21616
|
+
|
|
21617
|
+
// check feature flags again if distinct id has changed
|
|
21618
|
+
if (new_distinct_id !== previous_distinct_id) {
|
|
21619
|
+
this.flags.fetchFlags();
|
|
21620
|
+
}
|
|
21409
21621
|
};
|
|
21410
21622
|
|
|
21411
21623
|
/**
|
|
@@ -21680,7 +21892,7 @@ define((function () { 'use strict';
|
|
|
21680
21892
|
}
|
|
21681
21893
|
Config.DEBUG = Config.DEBUG || this.get_config('debug');
|
|
21682
21894
|
|
|
21683
|
-
if ('autocapture' in config && this.autocapture) {
|
|
21895
|
+
if (('autocapture' in config || 'record_heatmap_data' in config) && this.autocapture) {
|
|
21684
21896
|
this.autocapture.init();
|
|
21685
21897
|
}
|
|
21686
21898
|
}
|