mixpanel-browser 2.67.0 → 2.68.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.
@@ -13944,7 +13944,7 @@ define((function () { 'use strict';
13944
13944
 
13945
13945
  var Config = {
13946
13946
  DEBUG: false,
13947
- LIB_VERSION: '2.67.0'
13947
+ LIB_VERSION: '2.68.0'
13948
13948
  };
13949
13949
 
13950
13950
  /* eslint camelcase: "off", eqeqeq: "off" */
@@ -18229,6 +18229,38 @@ define((function () { 'use strict';
18229
18229
  return true;
18230
18230
  }
18231
18231
 
18232
+ /** @const */ var DEFAULT_RAGE_CLICK_THRESHOLD_PX = 30;
18233
+ /** @const */ var DEFAULT_RAGE_CLICK_TIMEOUT_MS = 1000;
18234
+ /** @const */ var DEFAULT_RAGE_CLICK_CLICK_COUNT = 4;
18235
+
18236
+ function RageClickTracker() {
18237
+ this.clicks = [];
18238
+ }
18239
+
18240
+ RageClickTracker.prototype.isRageClick = function(x, y, options) {
18241
+ options = options || {};
18242
+ var thresholdPx = options['threshold_px'] || DEFAULT_RAGE_CLICK_THRESHOLD_PX;
18243
+ var timeoutMs = options['timeout_ms'] || DEFAULT_RAGE_CLICK_TIMEOUT_MS;
18244
+ var clickCount = options['click_count'] || DEFAULT_RAGE_CLICK_CLICK_COUNT;
18245
+ var timestamp = Date.now();
18246
+
18247
+ var lastClick = this.clicks[this.clicks.length - 1];
18248
+ if (
18249
+ lastClick &&
18250
+ timestamp - lastClick.timestamp < timeoutMs &&
18251
+ Math.sqrt(Math.pow(x - lastClick.x, 2) + Math.pow(y - lastClick.y, 2)) < thresholdPx
18252
+ ) {
18253
+ this.clicks.push({ x: x, y: y, timestamp: timestamp });
18254
+ if (this.clicks.length >= clickCount) {
18255
+ this.clicks = [];
18256
+ return true;
18257
+ }
18258
+ } else {
18259
+ this.clicks = [{ x: x, y: y, timestamp: timestamp }];
18260
+ }
18261
+ return false;
18262
+ };
18263
+
18232
18264
  var AUTOCAPTURE_CONFIG_KEY = 'autocapture';
18233
18265
  var LEGACY_PAGEVIEW_CONFIG_KEY = 'track_pageview';
18234
18266
 
@@ -18250,6 +18282,7 @@ define((function () { 'use strict';
18250
18282
  var CONFIG_TRACK_CLICK = 'click';
18251
18283
  var CONFIG_TRACK_INPUT = 'input';
18252
18284
  var CONFIG_TRACK_PAGEVIEW = 'pageview';
18285
+ var CONFIG_TRACK_RAGE_CLICK = 'rage_click';
18253
18286
  var CONFIG_TRACK_SCROLL = 'scroll';
18254
18287
  var CONFIG_TRACK_SUBMIT = 'submit';
18255
18288
 
@@ -18267,6 +18300,7 @@ define((function () { 'use strict';
18267
18300
  CONFIG_DEFAULTS$1[CONFIG_TRACK_CLICK] = true;
18268
18301
  CONFIG_DEFAULTS$1[CONFIG_TRACK_INPUT] = true;
18269
18302
  CONFIG_DEFAULTS$1[CONFIG_TRACK_PAGEVIEW] = PAGEVIEW_OPTION_FULL_URL;
18303
+ CONFIG_DEFAULTS$1[CONFIG_TRACK_RAGE_CLICK] = true;
18270
18304
  CONFIG_DEFAULTS$1[CONFIG_TRACK_SCROLL] = true;
18271
18305
  CONFIG_DEFAULTS$1[CONFIG_TRACK_SUBMIT] = true;
18272
18306
 
@@ -18276,6 +18310,7 @@ define((function () { 'use strict';
18276
18310
 
18277
18311
  var MP_EV_CLICK = '$mp_click';
18278
18312
  var MP_EV_INPUT = '$mp_input_change';
18313
+ var MP_EV_RAGE_CLICK = '$mp_rage_click';
18279
18314
  var MP_EV_SCROLL = '$mp_scroll';
18280
18315
  var MP_EV_SUBMIT = '$mp_submit';
18281
18316
 
@@ -18298,6 +18333,7 @@ define((function () { 'use strict';
18298
18333
  this.initInputTracking();
18299
18334
  this.initScrollTracking();
18300
18335
  this.initSubmitTracking();
18336
+ this.initRageClickTracking();
18301
18337
  };
18302
18338
 
18303
18339
  Autocapture.prototype.getFullConfig = function() {
@@ -18376,6 +18412,11 @@ define((function () { 'use strict';
18376
18412
  return;
18377
18413
  }
18378
18414
 
18415
+ var isCapturedForHeatMap = this.mp.is_recording_heatmap_data() && (
18416
+ (mpEventName === MP_EV_CLICK && !this.getConfig(CONFIG_TRACK_CLICK)) ||
18417
+ (mpEventName === MP_EV_RAGE_CLICK && !this._getRageClickConfig())
18418
+ );
18419
+
18379
18420
  var props = getPropsForDOMEvent(ev, {
18380
18421
  allowElementCallback: this.getConfig(CONFIG_ALLOW_ELEMENT_CALLBACK),
18381
18422
  allowSelectors: this.getConfig(CONFIG_ALLOW_SELECTORS),
@@ -18384,7 +18425,7 @@ define((function () { 'use strict';
18384
18425
  blockSelectors: this.getConfig(CONFIG_BLOCK_SELECTORS),
18385
18426
  captureExtraAttrs: this.getConfig(CONFIG_CAPTURE_EXTRA_ATTRS),
18386
18427
  captureTextContent: this.getConfig(CONFIG_CAPTURE_TEXT_CONTENT),
18387
- capturedForHeatMap: mpEventName === MP_EV_CLICK && !this.getConfig(CONFIG_TRACK_CLICK) && this.mp.is_recording_heatmap_data(),
18428
+ capturedForHeatMap: isCapturedForHeatMap,
18388
18429
  });
18389
18430
  if (props) {
18390
18431
  _.extend(props, DEFAULT_PROPS);
@@ -18392,6 +18433,24 @@ define((function () { 'use strict';
18392
18433
  }
18393
18434
  };
18394
18435
 
18436
+ Autocapture.prototype._getRageClickConfig = function() {
18437
+ var config = this.getConfig(CONFIG_TRACK_RAGE_CLICK);
18438
+
18439
+ if (!config) {
18440
+ return null; // rage click tracking disabled
18441
+ }
18442
+
18443
+ if (config === true) {
18444
+ return {}; // use defaults
18445
+ }
18446
+
18447
+ if (typeof config === 'object') {
18448
+ return config; // use custom configuration
18449
+ }
18450
+
18451
+ return {}; // fallback to defaults for any other truthy value
18452
+ };
18453
+
18395
18454
  Autocapture.prototype.initClickTracking = function() {
18396
18455
  win.removeEventListener(EV_CLICK, this.listenerClick);
18397
18456
 
@@ -18493,6 +18552,36 @@ define((function () { 'use strict';
18493
18552
  }.bind(this)));
18494
18553
  };
18495
18554
 
18555
+ Autocapture.prototype.initRageClickTracking = function() {
18556
+ win.removeEventListener(EV_CLICK, this.listenerRageClick);
18557
+
18558
+ var rageClickConfig = this._getRageClickConfig();
18559
+ if (!rageClickConfig && !this.mp.get_config('record_heatmap_data')) {
18560
+ return;
18561
+ }
18562
+
18563
+ logger$1.log('Initializing rage click tracking');
18564
+ if (!this._rageClickTracker) {
18565
+ this._rageClickTracker = new RageClickTracker();
18566
+ }
18567
+
18568
+ this.listenerRageClick = function(ev) {
18569
+ var currentRageClickConfig = this._getRageClickConfig();
18570
+ if (!currentRageClickConfig && !this.mp.is_recording_heatmap_data()) {
18571
+ return;
18572
+ }
18573
+
18574
+ if (this.currentUrlBlocked()) {
18575
+ return;
18576
+ }
18577
+
18578
+ if (this._rageClickTracker.isRageClick(ev['pageX'], ev['pageY'], currentRageClickConfig)) {
18579
+ this.trackDomEvent(ev, MP_EV_RAGE_CLICK);
18580
+ }
18581
+ }.bind(this);
18582
+ win.addEventListener(EV_CLICK, this.listenerRageClick);
18583
+ };
18584
+
18496
18585
  Autocapture.prototype.initScrollTracking = function() {
18497
18586
  win.removeEventListener(EV_SCROLLEND, this.listenerScroll);
18498
18587
 
@@ -18579,6 +18668,7 @@ define((function () { 'use strict';
18579
18668
  var FeatureFlagManager = function(initOptions) {
18580
18669
  this.getFullApiRoute = initOptions.getFullApiRoute;
18581
18670
  this.getMpConfig = initOptions.getConfigFunc;
18671
+ this.setMpConfig = initOptions.setConfigFunc;
18582
18672
  this.getMpProperty = initOptions.getPropertyFunc;
18583
18673
  this.track = initOptions.trackingFunc;
18584
18674
  };
@@ -18616,6 +18706,23 @@ define((function () { 'use strict';
18616
18706
  return !!this.getMpConfig(FLAGS_CONFIG_KEY);
18617
18707
  };
18618
18708
 
18709
+ FeatureFlagManager.prototype.updateContext = function(newContext, options) {
18710
+ if (!this.isSystemEnabled()) {
18711
+ logger.critical('Feature Flags not enabled, cannot update context');
18712
+ return Promise.resolve();
18713
+ }
18714
+
18715
+ var ffConfig = this.getMpConfig(FLAGS_CONFIG_KEY);
18716
+ if (!_.isObject(ffConfig)) {
18717
+ ffConfig = {};
18718
+ }
18719
+ var oldContext = (options && options['replace']) ? {} : this.getConfig(CONFIG_CONTEXT);
18720
+ ffConfig[CONFIG_CONTEXT] = _.extend({}, oldContext, newContext);
18721
+
18722
+ this.setMpConfig(FLAGS_CONFIG_KEY, ffConfig);
18723
+ return this.fetchFlags();
18724
+ };
18725
+
18619
18726
  FeatureFlagManager.prototype.areFlagsReady = function() {
18620
18727
  if (!this.isSystemEnabled()) {
18621
18728
  logger.error('Feature Flags not enabled');
@@ -18625,7 +18732,7 @@ define((function () { 'use strict';
18625
18732
 
18626
18733
  FeatureFlagManager.prototype.fetchFlags = function() {
18627
18734
  if (!this.isSystemEnabled()) {
18628
- return;
18735
+ return Promise.resolve();
18629
18736
  }
18630
18737
 
18631
18738
  var distinctId = this.getMpProperty('distinct_id');
@@ -18665,6 +18772,8 @@ define((function () { 'use strict';
18665
18772
  this.markFetchComplete();
18666
18773
  logger.error(error);
18667
18774
  }.bind(this));
18775
+
18776
+ return this.fetchPromise;
18668
18777
  };
18669
18778
 
18670
18779
  FeatureFlagManager.prototype.markFetchComplete = function() {
@@ -18777,6 +18886,7 @@ define((function () { 'use strict';
18777
18886
  FeatureFlagManager.prototype['get_variant_value_sync'] = FeatureFlagManager.prototype.getVariantValueSync;
18778
18887
  FeatureFlagManager.prototype['is_enabled'] = FeatureFlagManager.prototype.isEnabled;
18779
18888
  FeatureFlagManager.prototype['is_enabled_sync'] = FeatureFlagManager.prototype.isEnabledSync;
18889
+ FeatureFlagManager.prototype['update_context'] = FeatureFlagManager.prototype.updateContext;
18780
18890
 
18781
18891
  // Deprecated method
18782
18892
  FeatureFlagManager.prototype['get_feature_data'] = FeatureFlagManager.prototype.getFeatureData;
@@ -20237,7 +20347,7 @@ define((function () { 'use strict';
20237
20347
  'batch_autostart': true,
20238
20348
  'hooks': {},
20239
20349
  'record_block_class': new RegExp('^(mp-block|fs-exclude|amp-block|rr-block|ph-no-capture)$'),
20240
- 'record_block_selector': 'img, video',
20350
+ 'record_block_selector': 'img, video, audio',
20241
20351
  'record_canvas': false,
20242
20352
  'record_collect_fonts': false,
20243
20353
  'record_heatmap_data': false,
@@ -20461,6 +20571,7 @@ define((function () { 'use strict';
20461
20571
  return this.get_api_host('flags') + '/' + this.get_config('api_routes')['flags'];
20462
20572
  }, this),
20463
20573
  getConfigFunc: _.bind(this.get_config, this),
20574
+ setConfigFunc: _.bind(this.set_config, this),
20464
20575
  getPropertyFunc: _.bind(this.get_property, this),
20465
20576
  trackingFunc: _.bind(this.track, this)
20466
20577
  });
@@ -13944,7 +13944,7 @@ if (typeof Promise !== 'undefined' && Promise.toString().indexOf('[native code]'
13944
13944
 
13945
13945
  var Config = {
13946
13946
  DEBUG: false,
13947
- LIB_VERSION: '2.67.0'
13947
+ LIB_VERSION: '2.68.0'
13948
13948
  };
13949
13949
 
13950
13950
  /* eslint camelcase: "off", eqeqeq: "off" */
@@ -18229,6 +18229,38 @@ function shouldTrackValue(value) {
18229
18229
  return true;
18230
18230
  }
18231
18231
 
18232
+ /** @const */ var DEFAULT_RAGE_CLICK_THRESHOLD_PX = 30;
18233
+ /** @const */ var DEFAULT_RAGE_CLICK_TIMEOUT_MS = 1000;
18234
+ /** @const */ var DEFAULT_RAGE_CLICK_CLICK_COUNT = 4;
18235
+
18236
+ function RageClickTracker() {
18237
+ this.clicks = [];
18238
+ }
18239
+
18240
+ RageClickTracker.prototype.isRageClick = function(x, y, options) {
18241
+ options = options || {};
18242
+ var thresholdPx = options['threshold_px'] || DEFAULT_RAGE_CLICK_THRESHOLD_PX;
18243
+ var timeoutMs = options['timeout_ms'] || DEFAULT_RAGE_CLICK_TIMEOUT_MS;
18244
+ var clickCount = options['click_count'] || DEFAULT_RAGE_CLICK_CLICK_COUNT;
18245
+ var timestamp = Date.now();
18246
+
18247
+ var lastClick = this.clicks[this.clicks.length - 1];
18248
+ if (
18249
+ lastClick &&
18250
+ timestamp - lastClick.timestamp < timeoutMs &&
18251
+ Math.sqrt(Math.pow(x - lastClick.x, 2) + Math.pow(y - lastClick.y, 2)) < thresholdPx
18252
+ ) {
18253
+ this.clicks.push({ x: x, y: y, timestamp: timestamp });
18254
+ if (this.clicks.length >= clickCount) {
18255
+ this.clicks = [];
18256
+ return true;
18257
+ }
18258
+ } else {
18259
+ this.clicks = [{ x: x, y: y, timestamp: timestamp }];
18260
+ }
18261
+ return false;
18262
+ };
18263
+
18232
18264
  var AUTOCAPTURE_CONFIG_KEY = 'autocapture';
18233
18265
  var LEGACY_PAGEVIEW_CONFIG_KEY = 'track_pageview';
18234
18266
 
@@ -18250,6 +18282,7 @@ var CONFIG_SCROLL_CHECKPOINTS = 'scroll_depth_percent_checkpoints';
18250
18282
  var CONFIG_TRACK_CLICK = 'click';
18251
18283
  var CONFIG_TRACK_INPUT = 'input';
18252
18284
  var CONFIG_TRACK_PAGEVIEW = 'pageview';
18285
+ var CONFIG_TRACK_RAGE_CLICK = 'rage_click';
18253
18286
  var CONFIG_TRACK_SCROLL = 'scroll';
18254
18287
  var CONFIG_TRACK_SUBMIT = 'submit';
18255
18288
 
@@ -18267,6 +18300,7 @@ CONFIG_DEFAULTS$1[CONFIG_SCROLL_CHECKPOINTS] = [25, 50, 75, 100];
18267
18300
  CONFIG_DEFAULTS$1[CONFIG_TRACK_CLICK] = true;
18268
18301
  CONFIG_DEFAULTS$1[CONFIG_TRACK_INPUT] = true;
18269
18302
  CONFIG_DEFAULTS$1[CONFIG_TRACK_PAGEVIEW] = PAGEVIEW_OPTION_FULL_URL;
18303
+ CONFIG_DEFAULTS$1[CONFIG_TRACK_RAGE_CLICK] = true;
18270
18304
  CONFIG_DEFAULTS$1[CONFIG_TRACK_SCROLL] = true;
18271
18305
  CONFIG_DEFAULTS$1[CONFIG_TRACK_SUBMIT] = true;
18272
18306
 
@@ -18276,6 +18310,7 @@ var DEFAULT_PROPS = {
18276
18310
 
18277
18311
  var MP_EV_CLICK = '$mp_click';
18278
18312
  var MP_EV_INPUT = '$mp_input_change';
18313
+ var MP_EV_RAGE_CLICK = '$mp_rage_click';
18279
18314
  var MP_EV_SCROLL = '$mp_scroll';
18280
18315
  var MP_EV_SUBMIT = '$mp_submit';
18281
18316
 
@@ -18298,6 +18333,7 @@ Autocapture.prototype.init = function() {
18298
18333
  this.initInputTracking();
18299
18334
  this.initScrollTracking();
18300
18335
  this.initSubmitTracking();
18336
+ this.initRageClickTracking();
18301
18337
  };
18302
18338
 
18303
18339
  Autocapture.prototype.getFullConfig = function() {
@@ -18376,6 +18412,11 @@ Autocapture.prototype.trackDomEvent = function(ev, mpEventName) {
18376
18412
  return;
18377
18413
  }
18378
18414
 
18415
+ var isCapturedForHeatMap = this.mp.is_recording_heatmap_data() && (
18416
+ (mpEventName === MP_EV_CLICK && !this.getConfig(CONFIG_TRACK_CLICK)) ||
18417
+ (mpEventName === MP_EV_RAGE_CLICK && !this._getRageClickConfig())
18418
+ );
18419
+
18379
18420
  var props = getPropsForDOMEvent(ev, {
18380
18421
  allowElementCallback: this.getConfig(CONFIG_ALLOW_ELEMENT_CALLBACK),
18381
18422
  allowSelectors: this.getConfig(CONFIG_ALLOW_SELECTORS),
@@ -18384,7 +18425,7 @@ Autocapture.prototype.trackDomEvent = function(ev, mpEventName) {
18384
18425
  blockSelectors: this.getConfig(CONFIG_BLOCK_SELECTORS),
18385
18426
  captureExtraAttrs: this.getConfig(CONFIG_CAPTURE_EXTRA_ATTRS),
18386
18427
  captureTextContent: this.getConfig(CONFIG_CAPTURE_TEXT_CONTENT),
18387
- capturedForHeatMap: mpEventName === MP_EV_CLICK && !this.getConfig(CONFIG_TRACK_CLICK) && this.mp.is_recording_heatmap_data(),
18428
+ capturedForHeatMap: isCapturedForHeatMap,
18388
18429
  });
18389
18430
  if (props) {
18390
18431
  _.extend(props, DEFAULT_PROPS);
@@ -18392,6 +18433,24 @@ Autocapture.prototype.trackDomEvent = function(ev, mpEventName) {
18392
18433
  }
18393
18434
  };
18394
18435
 
18436
+ Autocapture.prototype._getRageClickConfig = function() {
18437
+ var config = this.getConfig(CONFIG_TRACK_RAGE_CLICK);
18438
+
18439
+ if (!config) {
18440
+ return null; // rage click tracking disabled
18441
+ }
18442
+
18443
+ if (config === true) {
18444
+ return {}; // use defaults
18445
+ }
18446
+
18447
+ if (typeof config === 'object') {
18448
+ return config; // use custom configuration
18449
+ }
18450
+
18451
+ return {}; // fallback to defaults for any other truthy value
18452
+ };
18453
+
18395
18454
  Autocapture.prototype.initClickTracking = function() {
18396
18455
  win.removeEventListener(EV_CLICK, this.listenerClick);
18397
18456
 
@@ -18493,6 +18552,36 @@ Autocapture.prototype.initPageviewTracking = function() {
18493
18552
  }.bind(this)));
18494
18553
  };
18495
18554
 
18555
+ Autocapture.prototype.initRageClickTracking = function() {
18556
+ win.removeEventListener(EV_CLICK, this.listenerRageClick);
18557
+
18558
+ var rageClickConfig = this._getRageClickConfig();
18559
+ if (!rageClickConfig && !this.mp.get_config('record_heatmap_data')) {
18560
+ return;
18561
+ }
18562
+
18563
+ logger$1.log('Initializing rage click tracking');
18564
+ if (!this._rageClickTracker) {
18565
+ this._rageClickTracker = new RageClickTracker();
18566
+ }
18567
+
18568
+ this.listenerRageClick = function(ev) {
18569
+ var currentRageClickConfig = this._getRageClickConfig();
18570
+ if (!currentRageClickConfig && !this.mp.is_recording_heatmap_data()) {
18571
+ return;
18572
+ }
18573
+
18574
+ if (this.currentUrlBlocked()) {
18575
+ return;
18576
+ }
18577
+
18578
+ if (this._rageClickTracker.isRageClick(ev['pageX'], ev['pageY'], currentRageClickConfig)) {
18579
+ this.trackDomEvent(ev, MP_EV_RAGE_CLICK);
18580
+ }
18581
+ }.bind(this);
18582
+ win.addEventListener(EV_CLICK, this.listenerRageClick);
18583
+ };
18584
+
18496
18585
  Autocapture.prototype.initScrollTracking = function() {
18497
18586
  win.removeEventListener(EV_SCROLLEND, this.listenerScroll);
18498
18587
 
@@ -18579,6 +18668,7 @@ CONFIG_DEFAULTS[CONFIG_CONTEXT] = {};
18579
18668
  var FeatureFlagManager = function(initOptions) {
18580
18669
  this.getFullApiRoute = initOptions.getFullApiRoute;
18581
18670
  this.getMpConfig = initOptions.getConfigFunc;
18671
+ this.setMpConfig = initOptions.setConfigFunc;
18582
18672
  this.getMpProperty = initOptions.getPropertyFunc;
18583
18673
  this.track = initOptions.trackingFunc;
18584
18674
  };
@@ -18616,6 +18706,23 @@ FeatureFlagManager.prototype.isSystemEnabled = function() {
18616
18706
  return !!this.getMpConfig(FLAGS_CONFIG_KEY);
18617
18707
  };
18618
18708
 
18709
+ FeatureFlagManager.prototype.updateContext = function(newContext, options) {
18710
+ if (!this.isSystemEnabled()) {
18711
+ logger.critical('Feature Flags not enabled, cannot update context');
18712
+ return Promise.resolve();
18713
+ }
18714
+
18715
+ var ffConfig = this.getMpConfig(FLAGS_CONFIG_KEY);
18716
+ if (!_.isObject(ffConfig)) {
18717
+ ffConfig = {};
18718
+ }
18719
+ var oldContext = (options && options['replace']) ? {} : this.getConfig(CONFIG_CONTEXT);
18720
+ ffConfig[CONFIG_CONTEXT] = _.extend({}, oldContext, newContext);
18721
+
18722
+ this.setMpConfig(FLAGS_CONFIG_KEY, ffConfig);
18723
+ return this.fetchFlags();
18724
+ };
18725
+
18619
18726
  FeatureFlagManager.prototype.areFlagsReady = function() {
18620
18727
  if (!this.isSystemEnabled()) {
18621
18728
  logger.error('Feature Flags not enabled');
@@ -18625,7 +18732,7 @@ FeatureFlagManager.prototype.areFlagsReady = function() {
18625
18732
 
18626
18733
  FeatureFlagManager.prototype.fetchFlags = function() {
18627
18734
  if (!this.isSystemEnabled()) {
18628
- return;
18735
+ return Promise.resolve();
18629
18736
  }
18630
18737
 
18631
18738
  var distinctId = this.getMpProperty('distinct_id');
@@ -18665,6 +18772,8 @@ FeatureFlagManager.prototype.fetchFlags = function() {
18665
18772
  this.markFetchComplete();
18666
18773
  logger.error(error);
18667
18774
  }.bind(this));
18775
+
18776
+ return this.fetchPromise;
18668
18777
  };
18669
18778
 
18670
18779
  FeatureFlagManager.prototype.markFetchComplete = function() {
@@ -18777,6 +18886,7 @@ FeatureFlagManager.prototype['get_variant_value'] = FeatureFlagManager.prototype
18777
18886
  FeatureFlagManager.prototype['get_variant_value_sync'] = FeatureFlagManager.prototype.getVariantValueSync;
18778
18887
  FeatureFlagManager.prototype['is_enabled'] = FeatureFlagManager.prototype.isEnabled;
18779
18888
  FeatureFlagManager.prototype['is_enabled_sync'] = FeatureFlagManager.prototype.isEnabledSync;
18889
+ FeatureFlagManager.prototype['update_context'] = FeatureFlagManager.prototype.updateContext;
18780
18890
 
18781
18891
  // Deprecated method
18782
18892
  FeatureFlagManager.prototype['get_feature_data'] = FeatureFlagManager.prototype.getFeatureData;
@@ -20237,7 +20347,7 @@ var DEFAULT_CONFIG = {
20237
20347
  'batch_autostart': true,
20238
20348
  'hooks': {},
20239
20349
  'record_block_class': new RegExp('^(mp-block|fs-exclude|amp-block|rr-block|ph-no-capture)$'),
20240
- 'record_block_selector': 'img, video',
20350
+ 'record_block_selector': 'img, video, audio',
20241
20351
  'record_canvas': false,
20242
20352
  'record_collect_fonts': false,
20243
20353
  'record_heatmap_data': false,
@@ -20461,6 +20571,7 @@ MixpanelLib.prototype._init = function(token, config, name) {
20461
20571
  return this.get_api_host('flags') + '/' + this.get_config('api_routes')['flags'];
20462
20572
  }, this),
20463
20573
  getConfigFunc: _.bind(this.get_config, this),
20574
+ setConfigFunc: _.bind(this.set_config, this),
20464
20575
  getPropertyFunc: _.bind(this.get_property, this),
20465
20576
  trackingFunc: _.bind(this.track, this)
20466
20577
  });
@@ -3,7 +3,7 @@
3
3
 
4
4
  var Config = {
5
5
  DEBUG: false,
6
- LIB_VERSION: '2.67.0'
6
+ LIB_VERSION: '2.68.0'
7
7
  };
8
8
 
9
9
  // since es6 imports are static and we run unit tests from the console, window won't be defined when importing this file
@@ -2655,6 +2655,38 @@
2655
2655
  return true;
2656
2656
  }
2657
2657
 
2658
+ /** @const */ var DEFAULT_RAGE_CLICK_THRESHOLD_PX = 30;
2659
+ /** @const */ var DEFAULT_RAGE_CLICK_TIMEOUT_MS = 1000;
2660
+ /** @const */ var DEFAULT_RAGE_CLICK_CLICK_COUNT = 4;
2661
+
2662
+ function RageClickTracker() {
2663
+ this.clicks = [];
2664
+ }
2665
+
2666
+ RageClickTracker.prototype.isRageClick = function(x, y, options) {
2667
+ options = options || {};
2668
+ var thresholdPx = options['threshold_px'] || DEFAULT_RAGE_CLICK_THRESHOLD_PX;
2669
+ var timeoutMs = options['timeout_ms'] || DEFAULT_RAGE_CLICK_TIMEOUT_MS;
2670
+ var clickCount = options['click_count'] || DEFAULT_RAGE_CLICK_CLICK_COUNT;
2671
+ var timestamp = Date.now();
2672
+
2673
+ var lastClick = this.clicks[this.clicks.length - 1];
2674
+ if (
2675
+ lastClick &&
2676
+ timestamp - lastClick.timestamp < timeoutMs &&
2677
+ Math.sqrt(Math.pow(x - lastClick.x, 2) + Math.pow(y - lastClick.y, 2)) < thresholdPx
2678
+ ) {
2679
+ this.clicks.push({ x: x, y: y, timestamp: timestamp });
2680
+ if (this.clicks.length >= clickCount) {
2681
+ this.clicks = [];
2682
+ return true;
2683
+ }
2684
+ } else {
2685
+ this.clicks = [{ x: x, y: y, timestamp: timestamp }];
2686
+ }
2687
+ return false;
2688
+ };
2689
+
2658
2690
  var AUTOCAPTURE_CONFIG_KEY = 'autocapture';
2659
2691
  var LEGACY_PAGEVIEW_CONFIG_KEY = 'track_pageview';
2660
2692
 
@@ -2676,6 +2708,7 @@
2676
2708
  var CONFIG_TRACK_CLICK = 'click';
2677
2709
  var CONFIG_TRACK_INPUT = 'input';
2678
2710
  var CONFIG_TRACK_PAGEVIEW = 'pageview';
2711
+ var CONFIG_TRACK_RAGE_CLICK = 'rage_click';
2679
2712
  var CONFIG_TRACK_SCROLL = 'scroll';
2680
2713
  var CONFIG_TRACK_SUBMIT = 'submit';
2681
2714
 
@@ -2693,6 +2726,7 @@
2693
2726
  CONFIG_DEFAULTS$1[CONFIG_TRACK_CLICK] = true;
2694
2727
  CONFIG_DEFAULTS$1[CONFIG_TRACK_INPUT] = true;
2695
2728
  CONFIG_DEFAULTS$1[CONFIG_TRACK_PAGEVIEW] = PAGEVIEW_OPTION_FULL_URL;
2729
+ CONFIG_DEFAULTS$1[CONFIG_TRACK_RAGE_CLICK] = true;
2696
2730
  CONFIG_DEFAULTS$1[CONFIG_TRACK_SCROLL] = true;
2697
2731
  CONFIG_DEFAULTS$1[CONFIG_TRACK_SUBMIT] = true;
2698
2732
 
@@ -2702,6 +2736,7 @@
2702
2736
 
2703
2737
  var MP_EV_CLICK = '$mp_click';
2704
2738
  var MP_EV_INPUT = '$mp_input_change';
2739
+ var MP_EV_RAGE_CLICK = '$mp_rage_click';
2705
2740
  var MP_EV_SCROLL = '$mp_scroll';
2706
2741
  var MP_EV_SUBMIT = '$mp_submit';
2707
2742
 
@@ -2724,6 +2759,7 @@
2724
2759
  this.initInputTracking();
2725
2760
  this.initScrollTracking();
2726
2761
  this.initSubmitTracking();
2762
+ this.initRageClickTracking();
2727
2763
  };
2728
2764
 
2729
2765
  Autocapture.prototype.getFullConfig = function() {
@@ -2802,6 +2838,11 @@
2802
2838
  return;
2803
2839
  }
2804
2840
 
2841
+ var isCapturedForHeatMap = this.mp.is_recording_heatmap_data() && (
2842
+ (mpEventName === MP_EV_CLICK && !this.getConfig(CONFIG_TRACK_CLICK)) ||
2843
+ (mpEventName === MP_EV_RAGE_CLICK && !this._getRageClickConfig())
2844
+ );
2845
+
2805
2846
  var props = getPropsForDOMEvent(ev, {
2806
2847
  allowElementCallback: this.getConfig(CONFIG_ALLOW_ELEMENT_CALLBACK),
2807
2848
  allowSelectors: this.getConfig(CONFIG_ALLOW_SELECTORS),
@@ -2810,7 +2851,7 @@
2810
2851
  blockSelectors: this.getConfig(CONFIG_BLOCK_SELECTORS),
2811
2852
  captureExtraAttrs: this.getConfig(CONFIG_CAPTURE_EXTRA_ATTRS),
2812
2853
  captureTextContent: this.getConfig(CONFIG_CAPTURE_TEXT_CONTENT),
2813
- capturedForHeatMap: mpEventName === MP_EV_CLICK && !this.getConfig(CONFIG_TRACK_CLICK) && this.mp.is_recording_heatmap_data(),
2854
+ capturedForHeatMap: isCapturedForHeatMap,
2814
2855
  });
2815
2856
  if (props) {
2816
2857
  _.extend(props, DEFAULT_PROPS);
@@ -2818,6 +2859,24 @@
2818
2859
  }
2819
2860
  };
2820
2861
 
2862
+ Autocapture.prototype._getRageClickConfig = function() {
2863
+ var config = this.getConfig(CONFIG_TRACK_RAGE_CLICK);
2864
+
2865
+ if (!config) {
2866
+ return null; // rage click tracking disabled
2867
+ }
2868
+
2869
+ if (config === true) {
2870
+ return {}; // use defaults
2871
+ }
2872
+
2873
+ if (typeof config === 'object') {
2874
+ return config; // use custom configuration
2875
+ }
2876
+
2877
+ return {}; // fallback to defaults for any other truthy value
2878
+ };
2879
+
2821
2880
  Autocapture.prototype.initClickTracking = function() {
2822
2881
  win.removeEventListener(EV_CLICK, this.listenerClick);
2823
2882
 
@@ -2919,6 +2978,36 @@
2919
2978
  }.bind(this)));
2920
2979
  };
2921
2980
 
2981
+ Autocapture.prototype.initRageClickTracking = function() {
2982
+ win.removeEventListener(EV_CLICK, this.listenerRageClick);
2983
+
2984
+ var rageClickConfig = this._getRageClickConfig();
2985
+ if (!rageClickConfig && !this.mp.get_config('record_heatmap_data')) {
2986
+ return;
2987
+ }
2988
+
2989
+ logger$4.log('Initializing rage click tracking');
2990
+ if (!this._rageClickTracker) {
2991
+ this._rageClickTracker = new RageClickTracker();
2992
+ }
2993
+
2994
+ this.listenerRageClick = function(ev) {
2995
+ var currentRageClickConfig = this._getRageClickConfig();
2996
+ if (!currentRageClickConfig && !this.mp.is_recording_heatmap_data()) {
2997
+ return;
2998
+ }
2999
+
3000
+ if (this.currentUrlBlocked()) {
3001
+ return;
3002
+ }
3003
+
3004
+ if (this._rageClickTracker.isRageClick(ev['pageX'], ev['pageY'], currentRageClickConfig)) {
3005
+ this.trackDomEvent(ev, MP_EV_RAGE_CLICK);
3006
+ }
3007
+ }.bind(this);
3008
+ win.addEventListener(EV_CLICK, this.listenerRageClick);
3009
+ };
3010
+
2922
3011
  Autocapture.prototype.initScrollTracking = function() {
2923
3012
  win.removeEventListener(EV_SCROLLEND, this.listenerScroll);
2924
3013
 
@@ -3005,6 +3094,7 @@
3005
3094
  var FeatureFlagManager = function(initOptions) {
3006
3095
  this.getFullApiRoute = initOptions.getFullApiRoute;
3007
3096
  this.getMpConfig = initOptions.getConfigFunc;
3097
+ this.setMpConfig = initOptions.setConfigFunc;
3008
3098
  this.getMpProperty = initOptions.getPropertyFunc;
3009
3099
  this.track = initOptions.trackingFunc;
3010
3100
  };
@@ -3042,6 +3132,23 @@
3042
3132
  return !!this.getMpConfig(FLAGS_CONFIG_KEY);
3043
3133
  };
3044
3134
 
3135
+ FeatureFlagManager.prototype.updateContext = function(newContext, options) {
3136
+ if (!this.isSystemEnabled()) {
3137
+ logger$3.critical('Feature Flags not enabled, cannot update context');
3138
+ return Promise.resolve();
3139
+ }
3140
+
3141
+ var ffConfig = this.getMpConfig(FLAGS_CONFIG_KEY);
3142
+ if (!_.isObject(ffConfig)) {
3143
+ ffConfig = {};
3144
+ }
3145
+ var oldContext = (options && options['replace']) ? {} : this.getConfig(CONFIG_CONTEXT);
3146
+ ffConfig[CONFIG_CONTEXT] = _.extend({}, oldContext, newContext);
3147
+
3148
+ this.setMpConfig(FLAGS_CONFIG_KEY, ffConfig);
3149
+ return this.fetchFlags();
3150
+ };
3151
+
3045
3152
  FeatureFlagManager.prototype.areFlagsReady = function() {
3046
3153
  if (!this.isSystemEnabled()) {
3047
3154
  logger$3.error('Feature Flags not enabled');
@@ -3051,7 +3158,7 @@
3051
3158
 
3052
3159
  FeatureFlagManager.prototype.fetchFlags = function() {
3053
3160
  if (!this.isSystemEnabled()) {
3054
- return;
3161
+ return Promise.resolve();
3055
3162
  }
3056
3163
 
3057
3164
  var distinctId = this.getMpProperty('distinct_id');
@@ -3091,6 +3198,8 @@
3091
3198
  this.markFetchComplete();
3092
3199
  logger$3.error(error);
3093
3200
  }.bind(this));
3201
+
3202
+ return this.fetchPromise;
3094
3203
  };
3095
3204
 
3096
3205
  FeatureFlagManager.prototype.markFetchComplete = function() {
@@ -3203,6 +3312,7 @@
3203
3312
  FeatureFlagManager.prototype['get_variant_value_sync'] = FeatureFlagManager.prototype.getVariantValueSync;
3204
3313
  FeatureFlagManager.prototype['is_enabled'] = FeatureFlagManager.prototype.isEnabled;
3205
3314
  FeatureFlagManager.prototype['is_enabled_sync'] = FeatureFlagManager.prototype.isEnabledSync;
3315
+ FeatureFlagManager.prototype['update_context'] = FeatureFlagManager.prototype.updateContext;
3206
3316
 
3207
3317
  // Deprecated method
3208
3318
  FeatureFlagManager.prototype['get_feature_data'] = FeatureFlagManager.prototype.getFeatureData;
@@ -5974,7 +6084,7 @@
5974
6084
  'batch_autostart': true,
5975
6085
  'hooks': {},
5976
6086
  'record_block_class': new RegExp('^(mp-block|fs-exclude|amp-block|rr-block|ph-no-capture)$'),
5977
- 'record_block_selector': 'img, video',
6087
+ 'record_block_selector': 'img, video, audio',
5978
6088
  'record_canvas': false,
5979
6089
  'record_collect_fonts': false,
5980
6090
  'record_heatmap_data': false,
@@ -6198,6 +6308,7 @@
6198
6308
  return this.get_api_host('flags') + '/' + this.get_config('api_routes')['flags'];
6199
6309
  }, this),
6200
6310
  getConfigFunc: _.bind(this.get_config, this),
6311
+ setConfigFunc: _.bind(this.set_config, this),
6201
6312
  getPropertyFunc: _.bind(this.get_property, this),
6202
6313
  trackingFunc: _.bind(this.track, this)
6203
6314
  });