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.
- package/CHANGELOG.md +12 -0
- package/README.md +1 -1
- package/dist/mixpanel-core.cjs.js +276 -54
- package/dist/mixpanel-recorder.js +6 -2
- 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 +276 -54
- package/dist/mixpanel-with-recorder.js +297 -75
- package/dist/mixpanel-with-recorder.min.js +1 -1
- package/dist/mixpanel.amd.js +297 -75
- package/dist/mixpanel.cjs.js +297 -75
- package/dist/mixpanel.globals.js +276 -54
- package/dist/mixpanel.min.js +151 -144
- package/dist/mixpanel.module.js +297 -75
- package/dist/mixpanel.umd.js +297 -75
- package/package.json +1 -1
- package/src/autocapture/index.js +4 -3
- package/src/autocapture/utils.js +7 -1
- package/src/config.js +1 -1
- package/src/flags/index.js +200 -0
- package/src/mixpanel-core.js +29 -3
- package/src/mixpanel-people.js +2 -12
- package/src/utils.js +5 -1
package/dist/mixpanel.globals.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
var Config = {
|
|
5
5
|
DEBUG: false,
|
|
6
|
-
LIB_VERSION: '2.
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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(
|
|
4864
|
-
|
|
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':
|
|
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
|
}
|