mixpanel-browser 2.63.0 → 2.65.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.
@@ -3,7 +3,7 @@
3
3
 
4
4
  var Config = {
5
5
  DEBUG: false,
6
- LIB_VERSION: '2.63.0'
6
+ LIB_VERSION: '2.65.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
@@ -1871,6 +1871,9 @@
1871
1871
  return 'Microsoft Edge';
1872
1872
  } else if (_.includes(user_agent, 'FBIOS')) {
1873
1873
  return 'Facebook Mobile';
1874
+ } else if (_.includes(user_agent, 'Whale/')) {
1875
+ // https://user-agents.net/browsers/whale-browser
1876
+ return 'Whale Browser';
1874
1877
  } else if (_.includes(user_agent, 'Chrome')) {
1875
1878
  return 'Chrome';
1876
1879
  } else if (_.includes(user_agent, 'CriOS')) {
@@ -1922,7 +1925,8 @@
1922
1925
  'Android Mobile': /android\s(\d+(\.\d+)?)/,
1923
1926
  'Samsung Internet': /SamsungBrowser\/(\d+(\.\d+)?)/,
1924
1927
  'Internet Explorer': /(rv:|MSIE )(\d+(\.\d+)?)/,
1925
- 'Mozilla': /rv:(\d+(\.\d+)?)/
1928
+ 'Mozilla': /rv:(\d+(\.\d+)?)/,
1929
+ 'Whale Browser': /Whale\/(\d+(\.\d+)?)/
1926
1930
  };
1927
1931
  var regex = versionRegexs[browser];
1928
1932
  if (regex === undefined) {
@@ -2159,7 +2163,7 @@
2159
2163
  'href', 'name', 'role', 'title', 'type'
2160
2164
  ];
2161
2165
 
2162
- var logger$3 = console_with_prefix('autocapture');
2166
+ var logger$4 = console_with_prefix('autocapture');
2163
2167
 
2164
2168
 
2165
2169
  function getClasses(el) {
@@ -2245,6 +2249,7 @@
2245
2249
  var blockSelectors = config.blockSelectors || [];
2246
2250
  var captureTextContent = config.captureTextContent || false;
2247
2251
  var captureExtraAttrs = config.captureExtraAttrs || [];
2252
+ var capturedForHeatMap = config.capturedForHeatMap || false;
2248
2253
 
2249
2254
  // convert array to set every time, as the config may have changed
2250
2255
  var blockAttrsSet = {};
@@ -2299,7 +2304,9 @@
2299
2304
  '$elements': elementsJson,
2300
2305
  '$el_attr__href': href,
2301
2306
  '$viewportHeight': Math.max(docElement['clientHeight'], win['innerHeight'] || 0),
2302
- '$viewportWidth': Math.max(docElement['clientWidth'], win['innerWidth'] || 0)
2307
+ '$viewportWidth': Math.max(docElement['clientWidth'], win['innerWidth'] || 0),
2308
+ '$pageHeight': document$1['body']['offsetHeight'] || 0,
2309
+ '$pageWidth': document$1['body']['offsetWidth'] || 0,
2303
2310
  };
2304
2311
  _.each(captureExtraAttrs, function(attr) {
2305
2312
  if (!blockAttrsSet[attr] && target.hasAttribute(attr)) {
@@ -2323,6 +2330,9 @@
2323
2330
  props['$' + prop] = ev[prop];
2324
2331
  }
2325
2332
  });
2333
+ if (capturedForHeatMap) {
2334
+ props['$captured_for_heatmap'] = true;
2335
+ }
2326
2336
  target = guessRealClickTarget(ev);
2327
2337
  }
2328
2338
  // prioritize text content from "real" click target if different from original target
@@ -2417,7 +2427,7 @@
2417
2427
  return false;
2418
2428
  }
2419
2429
  } catch (err) {
2420
- logger$3.critical('Error while checking element in allowElementCallback', err);
2430
+ logger$4.critical('Error while checking element in allowElementCallback', err);
2421
2431
  return false;
2422
2432
  }
2423
2433
  }
@@ -2434,7 +2444,7 @@
2434
2444
  return true;
2435
2445
  }
2436
2446
  } catch (err) {
2437
- logger$3.critical('Error while checking selector: ' + sel, err);
2447
+ logger$4.critical('Error while checking selector: ' + sel, err);
2438
2448
  }
2439
2449
  }
2440
2450
  return false;
@@ -2449,7 +2459,7 @@
2449
2459
  return true;
2450
2460
  }
2451
2461
  } catch (err) {
2452
- logger$3.critical('Error while checking element in blockElementCallback', err);
2462
+ logger$4.critical('Error while checking element in blockElementCallback', err);
2453
2463
  return true;
2454
2464
  }
2455
2465
  }
@@ -2463,7 +2473,7 @@
2463
2473
  return true;
2464
2474
  }
2465
2475
  } catch (err) {
2466
- logger$3.critical('Error while checking selector: ' + sel, err);
2476
+ logger$4.critical('Error while checking selector: ' + sel, err);
2467
2477
  }
2468
2478
  }
2469
2479
  }
@@ -2669,22 +2679,22 @@
2669
2679
  var CONFIG_TRACK_SCROLL = 'scroll';
2670
2680
  var CONFIG_TRACK_SUBMIT = 'submit';
2671
2681
 
2672
- var CONFIG_DEFAULTS = {};
2673
- CONFIG_DEFAULTS[CONFIG_ALLOW_SELECTORS] = [];
2674
- CONFIG_DEFAULTS[CONFIG_ALLOW_URL_REGEXES] = [];
2675
- CONFIG_DEFAULTS[CONFIG_BLOCK_ATTRS] = [];
2676
- CONFIG_DEFAULTS[CONFIG_BLOCK_ELEMENT_CALLBACK] = null;
2677
- CONFIG_DEFAULTS[CONFIG_BLOCK_SELECTORS] = [];
2678
- CONFIG_DEFAULTS[CONFIG_BLOCK_URL_REGEXES] = [];
2679
- CONFIG_DEFAULTS[CONFIG_CAPTURE_EXTRA_ATTRS] = [];
2680
- CONFIG_DEFAULTS[CONFIG_CAPTURE_TEXT_CONTENT] = false;
2681
- CONFIG_DEFAULTS[CONFIG_SCROLL_CAPTURE_ALL] = false;
2682
- CONFIG_DEFAULTS[CONFIG_SCROLL_CHECKPOINTS] = [25, 50, 75, 100];
2683
- CONFIG_DEFAULTS[CONFIG_TRACK_CLICK] = true;
2684
- CONFIG_DEFAULTS[CONFIG_TRACK_INPUT] = true;
2685
- CONFIG_DEFAULTS[CONFIG_TRACK_PAGEVIEW] = PAGEVIEW_OPTION_FULL_URL;
2686
- CONFIG_DEFAULTS[CONFIG_TRACK_SCROLL] = true;
2687
- CONFIG_DEFAULTS[CONFIG_TRACK_SUBMIT] = true;
2682
+ var CONFIG_DEFAULTS$1 = {};
2683
+ CONFIG_DEFAULTS$1[CONFIG_ALLOW_SELECTORS] = [];
2684
+ CONFIG_DEFAULTS$1[CONFIG_ALLOW_URL_REGEXES] = [];
2685
+ CONFIG_DEFAULTS$1[CONFIG_BLOCK_ATTRS] = [];
2686
+ CONFIG_DEFAULTS$1[CONFIG_BLOCK_ELEMENT_CALLBACK] = null;
2687
+ CONFIG_DEFAULTS$1[CONFIG_BLOCK_SELECTORS] = [];
2688
+ CONFIG_DEFAULTS$1[CONFIG_BLOCK_URL_REGEXES] = [];
2689
+ CONFIG_DEFAULTS$1[CONFIG_CAPTURE_EXTRA_ATTRS] = [];
2690
+ CONFIG_DEFAULTS$1[CONFIG_CAPTURE_TEXT_CONTENT] = false;
2691
+ CONFIG_DEFAULTS$1[CONFIG_SCROLL_CAPTURE_ALL] = false;
2692
+ CONFIG_DEFAULTS$1[CONFIG_SCROLL_CHECKPOINTS] = [25, 50, 75, 100];
2693
+ CONFIG_DEFAULTS$1[CONFIG_TRACK_CLICK] = true;
2694
+ CONFIG_DEFAULTS$1[CONFIG_TRACK_INPUT] = true;
2695
+ CONFIG_DEFAULTS$1[CONFIG_TRACK_PAGEVIEW] = PAGEVIEW_OPTION_FULL_URL;
2696
+ CONFIG_DEFAULTS$1[CONFIG_TRACK_SCROLL] = true;
2697
+ CONFIG_DEFAULTS$1[CONFIG_TRACK_SUBMIT] = true;
2688
2698
 
2689
2699
  var DEFAULT_PROPS = {
2690
2700
  '$mp_autocapture': true
@@ -2705,7 +2715,7 @@
2705
2715
 
2706
2716
  Autocapture.prototype.init = function() {
2707
2717
  if (!minDOMApisSupported()) {
2708
- logger$3.critical('Autocapture unavailable: missing required DOM APIs');
2718
+ logger$4.critical('Autocapture unavailable: missing required DOM APIs');
2709
2719
  return;
2710
2720
  }
2711
2721
 
@@ -2722,10 +2732,10 @@
2722
2732
  // Autocapture is completely off
2723
2733
  return {};
2724
2734
  } else if (_.isObject(autocaptureConfig)) {
2725
- return _.extend({}, CONFIG_DEFAULTS, autocaptureConfig);
2735
+ return _.extend({}, CONFIG_DEFAULTS$1, autocaptureConfig);
2726
2736
  } else {
2727
2737
  // Autocapture config is non-object truthy value, return default
2728
- return CONFIG_DEFAULTS;
2738
+ return CONFIG_DEFAULTS$1;
2729
2739
  }
2730
2740
  };
2731
2741
 
@@ -2749,7 +2759,7 @@
2749
2759
  break;
2750
2760
  }
2751
2761
  } catch (err) {
2752
- logger$3.critical('Error while checking block URL regex: ' + allowRegex, err);
2762
+ logger$4.critical('Error while checking block URL regex: ' + allowRegex, err);
2753
2763
  return true;
2754
2764
  }
2755
2765
  }
@@ -2770,7 +2780,7 @@
2770
2780
  return true;
2771
2781
  }
2772
2782
  } catch (err) {
2773
- logger$3.critical('Error while checking block URL regex: ' + blockUrlRegexes[i], err);
2783
+ logger$4.critical('Error while checking block URL regex: ' + blockUrlRegexes[i], err);
2774
2784
  return true;
2775
2785
  }
2776
2786
  }
@@ -2799,7 +2809,8 @@
2799
2809
  blockElementCallback: this.getConfig(CONFIG_BLOCK_ELEMENT_CALLBACK),
2800
2810
  blockSelectors: this.getConfig(CONFIG_BLOCK_SELECTORS),
2801
2811
  captureExtraAttrs: this.getConfig(CONFIG_CAPTURE_EXTRA_ATTRS),
2802
- captureTextContent: this.getConfig(CONFIG_CAPTURE_TEXT_CONTENT)
2812
+ captureTextContent: this.getConfig(CONFIG_CAPTURE_TEXT_CONTENT),
2813
+ capturedForHeatMap: mpEventName === MP_EV_CLICK && !this.getConfig(CONFIG_TRACK_CLICK) && this.mp.is_recording_heatmap_data(),
2803
2814
  });
2804
2815
  if (props) {
2805
2816
  _.extend(props, DEFAULT_PROPS);
@@ -2810,13 +2821,13 @@
2810
2821
  Autocapture.prototype.initClickTracking = function() {
2811
2822
  win.removeEventListener(EV_CLICK, this.listenerClick);
2812
2823
 
2813
- if (!this.getConfig(CONFIG_TRACK_CLICK)) {
2824
+ if (!this.getConfig(CONFIG_TRACK_CLICK) && !this.mp.get_config('record_heatmap_data')) {
2814
2825
  return;
2815
2826
  }
2816
- logger$3.log('Initializing click tracking');
2827
+ logger$4.log('Initializing click tracking');
2817
2828
 
2818
2829
  this.listenerClick = win.addEventListener(EV_CLICK, function(ev) {
2819
- if (!this.getConfig(CONFIG_TRACK_CLICK)) {
2830
+ if (!this.getConfig(CONFIG_TRACK_CLICK) && !this.mp.is_recording_heatmap_data()) {
2820
2831
  return;
2821
2832
  }
2822
2833
  this.trackDomEvent(ev, MP_EV_CLICK);
@@ -2829,7 +2840,7 @@
2829
2840
  if (!this.getConfig(CONFIG_TRACK_INPUT)) {
2830
2841
  return;
2831
2842
  }
2832
- logger$3.log('Initializing input tracking');
2843
+ logger$4.log('Initializing input tracking');
2833
2844
 
2834
2845
  this.listenerChange = win.addEventListener(EV_CHANGE, function(ev) {
2835
2846
  if (!this.getConfig(CONFIG_TRACK_INPUT)) {
@@ -2847,7 +2858,7 @@
2847
2858
  if (!this.pageviewTrackingConfig()) {
2848
2859
  return;
2849
2860
  }
2850
- logger$3.log('Initializing pageview tracking');
2861
+ logger$4.log('Initializing pageview tracking');
2851
2862
 
2852
2863
  var previousTrackedUrl = '';
2853
2864
  var tracked = false;
@@ -2902,7 +2913,7 @@
2902
2913
  }
2903
2914
  if (didPathChange) {
2904
2915
  this.lastScrollCheckpoint = 0;
2905
- logger$3.log('Path change: re-initializing scroll depth checkpoints');
2916
+ logger$4.log('Path change: re-initializing scroll depth checkpoints');
2906
2917
  }
2907
2918
  }
2908
2919
  }.bind(this)));
@@ -2914,7 +2925,7 @@
2914
2925
  if (!this.getConfig(CONFIG_TRACK_SCROLL)) {
2915
2926
  return;
2916
2927
  }
2917
- logger$3.log('Initializing scroll tracking');
2928
+ logger$4.log('Initializing scroll tracking');
2918
2929
  this.lastScrollCheckpoint = 0;
2919
2930
 
2920
2931
  this.listenerScroll = win.addEventListener(EV_SCROLLEND, safewrap(function() {
@@ -2951,7 +2962,7 @@
2951
2962
  }
2952
2963
  }
2953
2964
  } catch (err) {
2954
- logger$3.critical('Error while calculating scroll percentage', err);
2965
+ logger$4.critical('Error while calculating scroll percentage', err);
2955
2966
  }
2956
2967
  if (shouldTrack) {
2957
2968
  this.mp.track(MP_EV_SCROLL, props);
@@ -2965,7 +2976,7 @@
2965
2976
  if (!this.getConfig(CONFIG_TRACK_SUBMIT)) {
2966
2977
  return;
2967
2978
  }
2968
- logger$3.log('Initializing submit tracking');
2979
+ logger$4.log('Initializing submit tracking');
2969
2980
 
2970
2981
  this.listenerSubmit = win.addEventListener(EV_SUBMIT, function(ev) {
2971
2982
  if (!this.getConfig(CONFIG_TRACK_SUBMIT)) {
@@ -2978,6 +2989,202 @@
2978
2989
  // TODO integrate error_reporter from mixpanel instance
2979
2990
  safewrapClass(Autocapture);
2980
2991
 
2992
+ var fetch = win['fetch'];
2993
+ var logger$3 = console_with_prefix('flags');
2994
+
2995
+ var FLAGS_CONFIG_KEY = 'flags';
2996
+
2997
+ var CONFIG_CONTEXT = 'context';
2998
+ var CONFIG_DEFAULTS = {};
2999
+ CONFIG_DEFAULTS[CONFIG_CONTEXT] = {};
3000
+
3001
+ /**
3002
+ * FeatureFlagManager: support for Mixpanel's feature flagging product
3003
+ * @constructor
3004
+ */
3005
+ var FeatureFlagManager = function(initOptions) {
3006
+ this.getMpConfig = initOptions.getConfigFunc;
3007
+ this.getDistinctId = initOptions.getDistinctIdFunc;
3008
+ this.track = initOptions.trackingFunc;
3009
+ };
3010
+
3011
+ FeatureFlagManager.prototype.init = function() {
3012
+ if (!minApisSupported()) {
3013
+ logger$3.critical('Feature Flags unavailable: missing minimum required APIs');
3014
+ return;
3015
+ }
3016
+
3017
+ this.flags = null;
3018
+ this.fetchFlags();
3019
+
3020
+ this.trackedFeatures = new Set();
3021
+ };
3022
+
3023
+ FeatureFlagManager.prototype.getFullConfig = function() {
3024
+ var ffConfig = this.getMpConfig(FLAGS_CONFIG_KEY);
3025
+ if (!ffConfig) {
3026
+ // flags are completely off
3027
+ return {};
3028
+ } else if (_.isObject(ffConfig)) {
3029
+ return _.extend({}, CONFIG_DEFAULTS, ffConfig);
3030
+ } else {
3031
+ // config is non-object truthy value, return default
3032
+ return CONFIG_DEFAULTS;
3033
+ }
3034
+ };
3035
+
3036
+ FeatureFlagManager.prototype.getConfig = function(key) {
3037
+ return this.getFullConfig()[key];
3038
+ };
3039
+
3040
+ FeatureFlagManager.prototype.isSystemEnabled = function() {
3041
+ return !!this.getMpConfig(FLAGS_CONFIG_KEY);
3042
+ };
3043
+
3044
+ FeatureFlagManager.prototype.areFlagsReady = function() {
3045
+ if (!this.isSystemEnabled()) {
3046
+ logger$3.error('Feature Flags not enabled');
3047
+ }
3048
+ return !!this.flags;
3049
+ };
3050
+
3051
+ FeatureFlagManager.prototype.fetchFlags = function() {
3052
+ if (!this.isSystemEnabled()) {
3053
+ return;
3054
+ }
3055
+
3056
+ var distinctId = this.getDistinctId();
3057
+ logger$3.log('Fetching flags for distinct ID: ' + distinctId);
3058
+ var reqParams = {
3059
+ 'context': _.extend({'distinct_id': distinctId}, this.getConfig(CONFIG_CONTEXT))
3060
+ };
3061
+ this.fetchPromise = win['fetch'](this.getMpConfig('api_host') + '/' + this.getMpConfig('api_routes')['flags'], {
3062
+ 'method': 'POST',
3063
+ 'headers': {
3064
+ 'Authorization': 'Basic ' + btoa(this.getMpConfig('token') + ':'),
3065
+ 'Content-Type': 'application/octet-stream'
3066
+ },
3067
+ 'body': JSON.stringify(reqParams)
3068
+ }).then(function(response) {
3069
+ return response.json().then(function(responseBody) {
3070
+ var responseFlags = responseBody['flags'];
3071
+ if (!responseFlags) {
3072
+ throw new Error('No flags in API response');
3073
+ }
3074
+ var flags = new Map();
3075
+ _.each(responseFlags, function(data, key) {
3076
+ flags.set(key, {
3077
+ 'key': data['variant_key'],
3078
+ 'value': data['variant_value']
3079
+ });
3080
+ });
3081
+ this.flags = flags;
3082
+ }.bind(this)).catch(function(error) {
3083
+ logger$3.error(error);
3084
+ });
3085
+ }.bind(this)).catch(function() {});
3086
+ };
3087
+
3088
+ FeatureFlagManager.prototype.getVariant = function(featureName, fallback) {
3089
+ if (!this.fetchPromise) {
3090
+ return new Promise(function(resolve) {
3091
+ logger$3.critical('Feature Flags not initialized');
3092
+ resolve(fallback);
3093
+ });
3094
+ }
3095
+
3096
+ return this.fetchPromise.then(function() {
3097
+ return this.getVariantSync(featureName, fallback);
3098
+ }.bind(this)).catch(function(error) {
3099
+ logger$3.error(error);
3100
+ return fallback;
3101
+ });
3102
+ };
3103
+
3104
+ FeatureFlagManager.prototype.getVariantSync = function(featureName, fallback) {
3105
+ if (!this.areFlagsReady()) {
3106
+ logger$3.log('Flags not loaded yet');
3107
+ return fallback;
3108
+ }
3109
+ var feature = this.flags.get(featureName);
3110
+ if (!feature) {
3111
+ logger$3.log('No flag found: "' + featureName + '"');
3112
+ return fallback;
3113
+ }
3114
+ this.trackFeatureCheck(featureName, feature);
3115
+ return feature;
3116
+ };
3117
+
3118
+ FeatureFlagManager.prototype.getVariantValue = function(featureName, fallbackValue) {
3119
+ return this.getVariant(featureName, {'value': fallbackValue}).then(function(feature) {
3120
+ return feature['value'];
3121
+ }).catch(function(error) {
3122
+ logger$3.error(error);
3123
+ return fallbackValue;
3124
+ });
3125
+ };
3126
+
3127
+ // TODO remove deprecated method
3128
+ FeatureFlagManager.prototype.getFeatureData = function(featureName, fallbackValue) {
3129
+ logger$3.critical('mixpanel.flags.get_feature_data() is deprecated and will be removed in a future release. Use mixpanel.flags.get_variant_value() instead.');
3130
+ return this.getVariantValue(featureName, fallbackValue);
3131
+ };
3132
+
3133
+ FeatureFlagManager.prototype.getVariantValueSync = function(featureName, fallbackValue) {
3134
+ return this.getVariantSync(featureName, {'value': fallbackValue})['value'];
3135
+ };
3136
+
3137
+ FeatureFlagManager.prototype.isEnabled = function(featureName, fallbackValue) {
3138
+ return this.getVariantValue(featureName).then(function() {
3139
+ return this.isEnabledSync(featureName, fallbackValue);
3140
+ }.bind(this)).catch(function(error) {
3141
+ logger$3.error(error);
3142
+ return fallbackValue;
3143
+ });
3144
+ };
3145
+
3146
+ FeatureFlagManager.prototype.isEnabledSync = function(featureName, fallbackValue) {
3147
+ fallbackValue = fallbackValue || false;
3148
+ var val = this.getVariantValueSync(featureName, fallbackValue);
3149
+ if (val !== true && val !== false) {
3150
+ logger$3.error('Feature flag "' + featureName + '" value: ' + val + ' is not a boolean; returning fallback value: ' + fallbackValue);
3151
+ val = fallbackValue;
3152
+ }
3153
+ return val;
3154
+ };
3155
+
3156
+ FeatureFlagManager.prototype.trackFeatureCheck = function(featureName, feature) {
3157
+ if (this.trackedFeatures.has(featureName)) {
3158
+ return;
3159
+ }
3160
+ this.trackedFeatures.add(featureName);
3161
+ this.track('$experiment_started', {
3162
+ 'Experiment name': featureName,
3163
+ 'Variant name': feature['key'],
3164
+ '$experiment_type': 'feature_flag'
3165
+ });
3166
+ };
3167
+
3168
+ function minApisSupported() {
3169
+ return !!fetch &&
3170
+ typeof Promise !== 'undefined' &&
3171
+ typeof Map !== 'undefined' &&
3172
+ typeof Set !== 'undefined';
3173
+ }
3174
+
3175
+ safewrapClass(FeatureFlagManager);
3176
+
3177
+ FeatureFlagManager.prototype['are_flags_ready'] = FeatureFlagManager.prototype.areFlagsReady;
3178
+ FeatureFlagManager.prototype['get_variant'] = FeatureFlagManager.prototype.getVariant;
3179
+ FeatureFlagManager.prototype['get_variant_sync'] = FeatureFlagManager.prototype.getVariantSync;
3180
+ FeatureFlagManager.prototype['get_variant_value'] = FeatureFlagManager.prototype.getVariantValue;
3181
+ FeatureFlagManager.prototype['get_variant_value_sync'] = FeatureFlagManager.prototype.getVariantValueSync;
3182
+ FeatureFlagManager.prototype['is_enabled'] = FeatureFlagManager.prototype.isEnabled;
3183
+ FeatureFlagManager.prototype['is_enabled_sync'] = FeatureFlagManager.prototype.isEnabledSync;
3184
+
3185
+ // Deprecated method
3186
+ FeatureFlagManager.prototype['get_feature_data'] = FeatureFlagManager.prototype.getFeatureData;
3187
+
2981
3188
  /* eslint camelcase: "off" */
2982
3189
 
2983
3190
 
@@ -4860,18 +5067,8 @@
4860
5067
  * @param {Function} [callback] If provided, the callback will be called when the server responds
4861
5068
  * @deprecated
4862
5069
  */
4863
- MixpanelPeople.prototype.track_charge = addOptOutCheckMixpanelPeople(function(amount, properties, callback) {
4864
- if (!_.isNumber(amount)) {
4865
- amount = parseFloat(amount);
4866
- if (isNaN(amount)) {
4867
- console.error('Invalid value passed to mixpanel.people.track_charge - must be a number');
4868
- return;
4869
- }
4870
- }
4871
-
4872
- return this.append('$transactions', _.extend({
4873
- '$amount': amount
4874
- }, properties), callback);
5070
+ MixpanelPeople.prototype.track_charge = addOptOutCheckMixpanelPeople(function() {
5071
+ console.error('mixpanel.people.track_charge() is deprecated and no longer has any effect.');
4875
5072
  });
4876
5073
 
4877
5074
  /*
@@ -5693,10 +5890,11 @@
5693
5890
  }
5694
5891
 
5695
5892
  var DEFAULT_API_ROUTES = {
5696
- 'track': 'track/',
5893
+ 'track': 'track/',
5697
5894
  'engage': 'engage/',
5698
5895
  'groups': 'groups/',
5699
- 'record': 'record/'
5896
+ 'record': 'record/',
5897
+ 'flags': 'flags/'
5700
5898
  };
5701
5899
 
5702
5900
  /*
@@ -5705,6 +5903,7 @@
5705
5903
  var DEFAULT_CONFIG = {
5706
5904
  'api_host': 'https://api-js.mixpanel.com',
5707
5905
  'api_routes': DEFAULT_API_ROUTES,
5906
+ 'api_extra_query_params': {},
5708
5907
  'api_method': 'POST',
5709
5908
  'api_transport': 'XHR',
5710
5909
  'api_payload_format': PAYLOAD_TYPE_BASE64,
@@ -5714,6 +5913,7 @@
5714
5913
  'cross_site_cookie': false,
5715
5914
  'cross_subdomain_cookie': true,
5716
5915
  'error_reporter': NOOP_FUNC,
5916
+ 'flags': false,
5717
5917
  'persistence': 'cookie',
5718
5918
  'persistence_name': '',
5719
5919
  'cookie_domain': '',
@@ -5754,6 +5954,7 @@
5754
5954
  'record_block_selector': 'img, video',
5755
5955
  'record_canvas': false,
5756
5956
  'record_collect_fonts': false,
5957
+ 'record_heatmap_data': false,
5757
5958
  'record_idle_timeout_ms': 30 * 60 * 1000, // 30 minutes
5758
5959
  'record_mask_text_class': new RegExp('^(mp-mask|fs-mask|amp-mask|rr-mask|ph-mask)$'),
5759
5960
  'record_mask_text_selector': '*',
@@ -5969,6 +6170,14 @@
5969
6170
  }, '');
5970
6171
  }
5971
6172
 
6173
+ this.flags = new FeatureFlagManager({
6174
+ getConfigFunc: _.bind(this.get_config, this),
6175
+ getDistinctIdFunc: _.bind(this.get_distinct_id, this),
6176
+ trackingFunc: _.bind(this.track, this)
6177
+ });
6178
+ this.flags.init();
6179
+ this['flags'] = this.flags;
6180
+
5972
6181
  this.autocapture = new Autocapture(this);
5973
6182
  this.autocapture.init();
5974
6183
 
@@ -6094,6 +6303,10 @@
6094
6303
  }
6095
6304
  };
6096
6305
 
6306
+ MixpanelLib.prototype.is_recording_heatmap_data = function () {
6307
+ return this._get_session_replay_id() && this.get_config('record_heatmap_data');
6308
+ };
6309
+
6097
6310
  MixpanelLib.prototype.get_session_recording_properties = function () {
6098
6311
  var props = {};
6099
6312
  var replay_id = this._get_session_replay_id();
@@ -6278,6 +6491,8 @@
6278
6491
  delete data['data'];
6279
6492
  }
6280
6493
 
6494
+ _.extend(data, this.get_config('api_extra_query_params'));
6495
+
6281
6496
  url += '?' + _.HTTPBuildQuery(data);
6282
6497
 
6283
6498
  var lib = this;
@@ -7175,6 +7390,11 @@
7175
7390
  '$anon_distinct_id': previous_distinct_id
7176
7391
  }, {skip_hooks: true});
7177
7392
  }
7393
+
7394
+ // check feature flags again if distinct id has changed
7395
+ if (new_distinct_id !== previous_distinct_id) {
7396
+ this.flags.fetchFlags();
7397
+ }
7178
7398
  };
7179
7399
 
7180
7400
  /**
@@ -7189,6 +7409,8 @@
7189
7409
  'distinct_id': DEVICE_ID_PREFIX + uuid,
7190
7410
  '$device_id': uuid
7191
7411
  }, '');
7412
+ this.stop_session_recording();
7413
+ this._check_and_start_session_recording();
7192
7414
  };
7193
7415
 
7194
7416
  /**
@@ -7449,7 +7671,7 @@
7449
7671
  }
7450
7672
  Config.DEBUG = Config.DEBUG || this.get_config('debug');
7451
7673
 
7452
- if ('autocapture' in config && this.autocapture) {
7674
+ if (('autocapture' in config || 'record_heatmap_data' in config) && this.autocapture) {
7453
7675
  this.autocapture.init();
7454
7676
  }
7455
7677
  }