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.
- package/CHANGELOG.md +5 -0
- package/dist/mixpanel-core.cjs.js +115 -4
- 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 +115 -4
- package/dist/mixpanel-with-recorder.js +115 -4
- package/dist/mixpanel-with-recorder.min.js +1 -1
- package/dist/mixpanel.amd.js +115 -4
- package/dist/mixpanel.cjs.js +115 -4
- package/dist/mixpanel.globals.js +115 -4
- package/dist/mixpanel.min.js +148 -146
- package/dist/mixpanel.module.js +115 -4
- package/dist/mixpanel.umd.js +115 -4
- package/package.json +1 -1
- package/src/autocapture/index.js +59 -1
- package/src/autocapture/rageclick.js +38 -0
- package/src/config.js +1 -1
- package/src/flags/index.js +22 -1
- package/src/index.d.ts +18 -0
- package/src/mixpanel-core.js +2 -1
package/dist/mixpanel.module.js
CHANGED
|
@@ -13942,7 +13942,7 @@ if (typeof Promise !== 'undefined' && Promise.toString().indexOf('[native code]'
|
|
|
13942
13942
|
|
|
13943
13943
|
var Config = {
|
|
13944
13944
|
DEBUG: false,
|
|
13945
|
-
LIB_VERSION: '2.
|
|
13945
|
+
LIB_VERSION: '2.68.0'
|
|
13946
13946
|
};
|
|
13947
13947
|
|
|
13948
13948
|
/* eslint camelcase: "off", eqeqeq: "off" */
|
|
@@ -18227,6 +18227,38 @@ function shouldTrackValue(value) {
|
|
|
18227
18227
|
return true;
|
|
18228
18228
|
}
|
|
18229
18229
|
|
|
18230
|
+
/** @const */ var DEFAULT_RAGE_CLICK_THRESHOLD_PX = 30;
|
|
18231
|
+
/** @const */ var DEFAULT_RAGE_CLICK_TIMEOUT_MS = 1000;
|
|
18232
|
+
/** @const */ var DEFAULT_RAGE_CLICK_CLICK_COUNT = 4;
|
|
18233
|
+
|
|
18234
|
+
function RageClickTracker() {
|
|
18235
|
+
this.clicks = [];
|
|
18236
|
+
}
|
|
18237
|
+
|
|
18238
|
+
RageClickTracker.prototype.isRageClick = function(x, y, options) {
|
|
18239
|
+
options = options || {};
|
|
18240
|
+
var thresholdPx = options['threshold_px'] || DEFAULT_RAGE_CLICK_THRESHOLD_PX;
|
|
18241
|
+
var timeoutMs = options['timeout_ms'] || DEFAULT_RAGE_CLICK_TIMEOUT_MS;
|
|
18242
|
+
var clickCount = options['click_count'] || DEFAULT_RAGE_CLICK_CLICK_COUNT;
|
|
18243
|
+
var timestamp = Date.now();
|
|
18244
|
+
|
|
18245
|
+
var lastClick = this.clicks[this.clicks.length - 1];
|
|
18246
|
+
if (
|
|
18247
|
+
lastClick &&
|
|
18248
|
+
timestamp - lastClick.timestamp < timeoutMs &&
|
|
18249
|
+
Math.sqrt(Math.pow(x - lastClick.x, 2) + Math.pow(y - lastClick.y, 2)) < thresholdPx
|
|
18250
|
+
) {
|
|
18251
|
+
this.clicks.push({ x: x, y: y, timestamp: timestamp });
|
|
18252
|
+
if (this.clicks.length >= clickCount) {
|
|
18253
|
+
this.clicks = [];
|
|
18254
|
+
return true;
|
|
18255
|
+
}
|
|
18256
|
+
} else {
|
|
18257
|
+
this.clicks = [{ x: x, y: y, timestamp: timestamp }];
|
|
18258
|
+
}
|
|
18259
|
+
return false;
|
|
18260
|
+
};
|
|
18261
|
+
|
|
18230
18262
|
var AUTOCAPTURE_CONFIG_KEY = 'autocapture';
|
|
18231
18263
|
var LEGACY_PAGEVIEW_CONFIG_KEY = 'track_pageview';
|
|
18232
18264
|
|
|
@@ -18248,6 +18280,7 @@ var CONFIG_SCROLL_CHECKPOINTS = 'scroll_depth_percent_checkpoints';
|
|
|
18248
18280
|
var CONFIG_TRACK_CLICK = 'click';
|
|
18249
18281
|
var CONFIG_TRACK_INPUT = 'input';
|
|
18250
18282
|
var CONFIG_TRACK_PAGEVIEW = 'pageview';
|
|
18283
|
+
var CONFIG_TRACK_RAGE_CLICK = 'rage_click';
|
|
18251
18284
|
var CONFIG_TRACK_SCROLL = 'scroll';
|
|
18252
18285
|
var CONFIG_TRACK_SUBMIT = 'submit';
|
|
18253
18286
|
|
|
@@ -18265,6 +18298,7 @@ CONFIG_DEFAULTS$1[CONFIG_SCROLL_CHECKPOINTS] = [25, 50, 75, 100];
|
|
|
18265
18298
|
CONFIG_DEFAULTS$1[CONFIG_TRACK_CLICK] = true;
|
|
18266
18299
|
CONFIG_DEFAULTS$1[CONFIG_TRACK_INPUT] = true;
|
|
18267
18300
|
CONFIG_DEFAULTS$1[CONFIG_TRACK_PAGEVIEW] = PAGEVIEW_OPTION_FULL_URL;
|
|
18301
|
+
CONFIG_DEFAULTS$1[CONFIG_TRACK_RAGE_CLICK] = true;
|
|
18268
18302
|
CONFIG_DEFAULTS$1[CONFIG_TRACK_SCROLL] = true;
|
|
18269
18303
|
CONFIG_DEFAULTS$1[CONFIG_TRACK_SUBMIT] = true;
|
|
18270
18304
|
|
|
@@ -18274,6 +18308,7 @@ var DEFAULT_PROPS = {
|
|
|
18274
18308
|
|
|
18275
18309
|
var MP_EV_CLICK = '$mp_click';
|
|
18276
18310
|
var MP_EV_INPUT = '$mp_input_change';
|
|
18311
|
+
var MP_EV_RAGE_CLICK = '$mp_rage_click';
|
|
18277
18312
|
var MP_EV_SCROLL = '$mp_scroll';
|
|
18278
18313
|
var MP_EV_SUBMIT = '$mp_submit';
|
|
18279
18314
|
|
|
@@ -18296,6 +18331,7 @@ Autocapture.prototype.init = function() {
|
|
|
18296
18331
|
this.initInputTracking();
|
|
18297
18332
|
this.initScrollTracking();
|
|
18298
18333
|
this.initSubmitTracking();
|
|
18334
|
+
this.initRageClickTracking();
|
|
18299
18335
|
};
|
|
18300
18336
|
|
|
18301
18337
|
Autocapture.prototype.getFullConfig = function() {
|
|
@@ -18374,6 +18410,11 @@ Autocapture.prototype.trackDomEvent = function(ev, mpEventName) {
|
|
|
18374
18410
|
return;
|
|
18375
18411
|
}
|
|
18376
18412
|
|
|
18413
|
+
var isCapturedForHeatMap = this.mp.is_recording_heatmap_data() && (
|
|
18414
|
+
(mpEventName === MP_EV_CLICK && !this.getConfig(CONFIG_TRACK_CLICK)) ||
|
|
18415
|
+
(mpEventName === MP_EV_RAGE_CLICK && !this._getRageClickConfig())
|
|
18416
|
+
);
|
|
18417
|
+
|
|
18377
18418
|
var props = getPropsForDOMEvent(ev, {
|
|
18378
18419
|
allowElementCallback: this.getConfig(CONFIG_ALLOW_ELEMENT_CALLBACK),
|
|
18379
18420
|
allowSelectors: this.getConfig(CONFIG_ALLOW_SELECTORS),
|
|
@@ -18382,7 +18423,7 @@ Autocapture.prototype.trackDomEvent = function(ev, mpEventName) {
|
|
|
18382
18423
|
blockSelectors: this.getConfig(CONFIG_BLOCK_SELECTORS),
|
|
18383
18424
|
captureExtraAttrs: this.getConfig(CONFIG_CAPTURE_EXTRA_ATTRS),
|
|
18384
18425
|
captureTextContent: this.getConfig(CONFIG_CAPTURE_TEXT_CONTENT),
|
|
18385
|
-
capturedForHeatMap:
|
|
18426
|
+
capturedForHeatMap: isCapturedForHeatMap,
|
|
18386
18427
|
});
|
|
18387
18428
|
if (props) {
|
|
18388
18429
|
_.extend(props, DEFAULT_PROPS);
|
|
@@ -18390,6 +18431,24 @@ Autocapture.prototype.trackDomEvent = function(ev, mpEventName) {
|
|
|
18390
18431
|
}
|
|
18391
18432
|
};
|
|
18392
18433
|
|
|
18434
|
+
Autocapture.prototype._getRageClickConfig = function() {
|
|
18435
|
+
var config = this.getConfig(CONFIG_TRACK_RAGE_CLICK);
|
|
18436
|
+
|
|
18437
|
+
if (!config) {
|
|
18438
|
+
return null; // rage click tracking disabled
|
|
18439
|
+
}
|
|
18440
|
+
|
|
18441
|
+
if (config === true) {
|
|
18442
|
+
return {}; // use defaults
|
|
18443
|
+
}
|
|
18444
|
+
|
|
18445
|
+
if (typeof config === 'object') {
|
|
18446
|
+
return config; // use custom configuration
|
|
18447
|
+
}
|
|
18448
|
+
|
|
18449
|
+
return {}; // fallback to defaults for any other truthy value
|
|
18450
|
+
};
|
|
18451
|
+
|
|
18393
18452
|
Autocapture.prototype.initClickTracking = function() {
|
|
18394
18453
|
win.removeEventListener(EV_CLICK, this.listenerClick);
|
|
18395
18454
|
|
|
@@ -18491,6 +18550,36 @@ Autocapture.prototype.initPageviewTracking = function() {
|
|
|
18491
18550
|
}.bind(this)));
|
|
18492
18551
|
};
|
|
18493
18552
|
|
|
18553
|
+
Autocapture.prototype.initRageClickTracking = function() {
|
|
18554
|
+
win.removeEventListener(EV_CLICK, this.listenerRageClick);
|
|
18555
|
+
|
|
18556
|
+
var rageClickConfig = this._getRageClickConfig();
|
|
18557
|
+
if (!rageClickConfig && !this.mp.get_config('record_heatmap_data')) {
|
|
18558
|
+
return;
|
|
18559
|
+
}
|
|
18560
|
+
|
|
18561
|
+
logger$1.log('Initializing rage click tracking');
|
|
18562
|
+
if (!this._rageClickTracker) {
|
|
18563
|
+
this._rageClickTracker = new RageClickTracker();
|
|
18564
|
+
}
|
|
18565
|
+
|
|
18566
|
+
this.listenerRageClick = function(ev) {
|
|
18567
|
+
var currentRageClickConfig = this._getRageClickConfig();
|
|
18568
|
+
if (!currentRageClickConfig && !this.mp.is_recording_heatmap_data()) {
|
|
18569
|
+
return;
|
|
18570
|
+
}
|
|
18571
|
+
|
|
18572
|
+
if (this.currentUrlBlocked()) {
|
|
18573
|
+
return;
|
|
18574
|
+
}
|
|
18575
|
+
|
|
18576
|
+
if (this._rageClickTracker.isRageClick(ev['pageX'], ev['pageY'], currentRageClickConfig)) {
|
|
18577
|
+
this.trackDomEvent(ev, MP_EV_RAGE_CLICK);
|
|
18578
|
+
}
|
|
18579
|
+
}.bind(this);
|
|
18580
|
+
win.addEventListener(EV_CLICK, this.listenerRageClick);
|
|
18581
|
+
};
|
|
18582
|
+
|
|
18494
18583
|
Autocapture.prototype.initScrollTracking = function() {
|
|
18495
18584
|
win.removeEventListener(EV_SCROLLEND, this.listenerScroll);
|
|
18496
18585
|
|
|
@@ -18577,6 +18666,7 @@ CONFIG_DEFAULTS[CONFIG_CONTEXT] = {};
|
|
|
18577
18666
|
var FeatureFlagManager = function(initOptions) {
|
|
18578
18667
|
this.getFullApiRoute = initOptions.getFullApiRoute;
|
|
18579
18668
|
this.getMpConfig = initOptions.getConfigFunc;
|
|
18669
|
+
this.setMpConfig = initOptions.setConfigFunc;
|
|
18580
18670
|
this.getMpProperty = initOptions.getPropertyFunc;
|
|
18581
18671
|
this.track = initOptions.trackingFunc;
|
|
18582
18672
|
};
|
|
@@ -18614,6 +18704,23 @@ FeatureFlagManager.prototype.isSystemEnabled = function() {
|
|
|
18614
18704
|
return !!this.getMpConfig(FLAGS_CONFIG_KEY);
|
|
18615
18705
|
};
|
|
18616
18706
|
|
|
18707
|
+
FeatureFlagManager.prototype.updateContext = function(newContext, options) {
|
|
18708
|
+
if (!this.isSystemEnabled()) {
|
|
18709
|
+
logger.critical('Feature Flags not enabled, cannot update context');
|
|
18710
|
+
return Promise.resolve();
|
|
18711
|
+
}
|
|
18712
|
+
|
|
18713
|
+
var ffConfig = this.getMpConfig(FLAGS_CONFIG_KEY);
|
|
18714
|
+
if (!_.isObject(ffConfig)) {
|
|
18715
|
+
ffConfig = {};
|
|
18716
|
+
}
|
|
18717
|
+
var oldContext = (options && options['replace']) ? {} : this.getConfig(CONFIG_CONTEXT);
|
|
18718
|
+
ffConfig[CONFIG_CONTEXT] = _.extend({}, oldContext, newContext);
|
|
18719
|
+
|
|
18720
|
+
this.setMpConfig(FLAGS_CONFIG_KEY, ffConfig);
|
|
18721
|
+
return this.fetchFlags();
|
|
18722
|
+
};
|
|
18723
|
+
|
|
18617
18724
|
FeatureFlagManager.prototype.areFlagsReady = function() {
|
|
18618
18725
|
if (!this.isSystemEnabled()) {
|
|
18619
18726
|
logger.error('Feature Flags not enabled');
|
|
@@ -18623,7 +18730,7 @@ FeatureFlagManager.prototype.areFlagsReady = function() {
|
|
|
18623
18730
|
|
|
18624
18731
|
FeatureFlagManager.prototype.fetchFlags = function() {
|
|
18625
18732
|
if (!this.isSystemEnabled()) {
|
|
18626
|
-
return;
|
|
18733
|
+
return Promise.resolve();
|
|
18627
18734
|
}
|
|
18628
18735
|
|
|
18629
18736
|
var distinctId = this.getMpProperty('distinct_id');
|
|
@@ -18663,6 +18770,8 @@ FeatureFlagManager.prototype.fetchFlags = function() {
|
|
|
18663
18770
|
this.markFetchComplete();
|
|
18664
18771
|
logger.error(error);
|
|
18665
18772
|
}.bind(this));
|
|
18773
|
+
|
|
18774
|
+
return this.fetchPromise;
|
|
18666
18775
|
};
|
|
18667
18776
|
|
|
18668
18777
|
FeatureFlagManager.prototype.markFetchComplete = function() {
|
|
@@ -18775,6 +18884,7 @@ FeatureFlagManager.prototype['get_variant_value'] = FeatureFlagManager.prototype
|
|
|
18775
18884
|
FeatureFlagManager.prototype['get_variant_value_sync'] = FeatureFlagManager.prototype.getVariantValueSync;
|
|
18776
18885
|
FeatureFlagManager.prototype['is_enabled'] = FeatureFlagManager.prototype.isEnabled;
|
|
18777
18886
|
FeatureFlagManager.prototype['is_enabled_sync'] = FeatureFlagManager.prototype.isEnabledSync;
|
|
18887
|
+
FeatureFlagManager.prototype['update_context'] = FeatureFlagManager.prototype.updateContext;
|
|
18778
18888
|
|
|
18779
18889
|
// Deprecated method
|
|
18780
18890
|
FeatureFlagManager.prototype['get_feature_data'] = FeatureFlagManager.prototype.getFeatureData;
|
|
@@ -20235,7 +20345,7 @@ var DEFAULT_CONFIG = {
|
|
|
20235
20345
|
'batch_autostart': true,
|
|
20236
20346
|
'hooks': {},
|
|
20237
20347
|
'record_block_class': new RegExp('^(mp-block|fs-exclude|amp-block|rr-block|ph-no-capture)$'),
|
|
20238
|
-
'record_block_selector': 'img, video',
|
|
20348
|
+
'record_block_selector': 'img, video, audio',
|
|
20239
20349
|
'record_canvas': false,
|
|
20240
20350
|
'record_collect_fonts': false,
|
|
20241
20351
|
'record_heatmap_data': false,
|
|
@@ -20459,6 +20569,7 @@ MixpanelLib.prototype._init = function(token, config, name) {
|
|
|
20459
20569
|
return this.get_api_host('flags') + '/' + this.get_config('api_routes')['flags'];
|
|
20460
20570
|
}, this),
|
|
20461
20571
|
getConfigFunc: _.bind(this.get_config, this),
|
|
20572
|
+
setConfigFunc: _.bind(this.set_config, this),
|
|
20462
20573
|
getPropertyFunc: _.bind(this.get_property, this),
|
|
20463
20574
|
trackingFunc: _.bind(this.track, this)
|
|
20464
20575
|
});
|
package/dist/mixpanel.umd.js
CHANGED
|
@@ -13948,7 +13948,7 @@
|
|
|
13948
13948
|
|
|
13949
13949
|
var Config = {
|
|
13950
13950
|
DEBUG: false,
|
|
13951
|
-
LIB_VERSION: '2.
|
|
13951
|
+
LIB_VERSION: '2.68.0'
|
|
13952
13952
|
};
|
|
13953
13953
|
|
|
13954
13954
|
/* eslint camelcase: "off", eqeqeq: "off" */
|
|
@@ -18233,6 +18233,38 @@
|
|
|
18233
18233
|
return true;
|
|
18234
18234
|
}
|
|
18235
18235
|
|
|
18236
|
+
/** @const */ var DEFAULT_RAGE_CLICK_THRESHOLD_PX = 30;
|
|
18237
|
+
/** @const */ var DEFAULT_RAGE_CLICK_TIMEOUT_MS = 1000;
|
|
18238
|
+
/** @const */ var DEFAULT_RAGE_CLICK_CLICK_COUNT = 4;
|
|
18239
|
+
|
|
18240
|
+
function RageClickTracker() {
|
|
18241
|
+
this.clicks = [];
|
|
18242
|
+
}
|
|
18243
|
+
|
|
18244
|
+
RageClickTracker.prototype.isRageClick = function(x, y, options) {
|
|
18245
|
+
options = options || {};
|
|
18246
|
+
var thresholdPx = options['threshold_px'] || DEFAULT_RAGE_CLICK_THRESHOLD_PX;
|
|
18247
|
+
var timeoutMs = options['timeout_ms'] || DEFAULT_RAGE_CLICK_TIMEOUT_MS;
|
|
18248
|
+
var clickCount = options['click_count'] || DEFAULT_RAGE_CLICK_CLICK_COUNT;
|
|
18249
|
+
var timestamp = Date.now();
|
|
18250
|
+
|
|
18251
|
+
var lastClick = this.clicks[this.clicks.length - 1];
|
|
18252
|
+
if (
|
|
18253
|
+
lastClick &&
|
|
18254
|
+
timestamp - lastClick.timestamp < timeoutMs &&
|
|
18255
|
+
Math.sqrt(Math.pow(x - lastClick.x, 2) + Math.pow(y - lastClick.y, 2)) < thresholdPx
|
|
18256
|
+
) {
|
|
18257
|
+
this.clicks.push({ x: x, y: y, timestamp: timestamp });
|
|
18258
|
+
if (this.clicks.length >= clickCount) {
|
|
18259
|
+
this.clicks = [];
|
|
18260
|
+
return true;
|
|
18261
|
+
}
|
|
18262
|
+
} else {
|
|
18263
|
+
this.clicks = [{ x: x, y: y, timestamp: timestamp }];
|
|
18264
|
+
}
|
|
18265
|
+
return false;
|
|
18266
|
+
};
|
|
18267
|
+
|
|
18236
18268
|
var AUTOCAPTURE_CONFIG_KEY = 'autocapture';
|
|
18237
18269
|
var LEGACY_PAGEVIEW_CONFIG_KEY = 'track_pageview';
|
|
18238
18270
|
|
|
@@ -18254,6 +18286,7 @@
|
|
|
18254
18286
|
var CONFIG_TRACK_CLICK = 'click';
|
|
18255
18287
|
var CONFIG_TRACK_INPUT = 'input';
|
|
18256
18288
|
var CONFIG_TRACK_PAGEVIEW = 'pageview';
|
|
18289
|
+
var CONFIG_TRACK_RAGE_CLICK = 'rage_click';
|
|
18257
18290
|
var CONFIG_TRACK_SCROLL = 'scroll';
|
|
18258
18291
|
var CONFIG_TRACK_SUBMIT = 'submit';
|
|
18259
18292
|
|
|
@@ -18271,6 +18304,7 @@
|
|
|
18271
18304
|
CONFIG_DEFAULTS$1[CONFIG_TRACK_CLICK] = true;
|
|
18272
18305
|
CONFIG_DEFAULTS$1[CONFIG_TRACK_INPUT] = true;
|
|
18273
18306
|
CONFIG_DEFAULTS$1[CONFIG_TRACK_PAGEVIEW] = PAGEVIEW_OPTION_FULL_URL;
|
|
18307
|
+
CONFIG_DEFAULTS$1[CONFIG_TRACK_RAGE_CLICK] = true;
|
|
18274
18308
|
CONFIG_DEFAULTS$1[CONFIG_TRACK_SCROLL] = true;
|
|
18275
18309
|
CONFIG_DEFAULTS$1[CONFIG_TRACK_SUBMIT] = true;
|
|
18276
18310
|
|
|
@@ -18280,6 +18314,7 @@
|
|
|
18280
18314
|
|
|
18281
18315
|
var MP_EV_CLICK = '$mp_click';
|
|
18282
18316
|
var MP_EV_INPUT = '$mp_input_change';
|
|
18317
|
+
var MP_EV_RAGE_CLICK = '$mp_rage_click';
|
|
18283
18318
|
var MP_EV_SCROLL = '$mp_scroll';
|
|
18284
18319
|
var MP_EV_SUBMIT = '$mp_submit';
|
|
18285
18320
|
|
|
@@ -18302,6 +18337,7 @@
|
|
|
18302
18337
|
this.initInputTracking();
|
|
18303
18338
|
this.initScrollTracking();
|
|
18304
18339
|
this.initSubmitTracking();
|
|
18340
|
+
this.initRageClickTracking();
|
|
18305
18341
|
};
|
|
18306
18342
|
|
|
18307
18343
|
Autocapture.prototype.getFullConfig = function() {
|
|
@@ -18380,6 +18416,11 @@
|
|
|
18380
18416
|
return;
|
|
18381
18417
|
}
|
|
18382
18418
|
|
|
18419
|
+
var isCapturedForHeatMap = this.mp.is_recording_heatmap_data() && (
|
|
18420
|
+
(mpEventName === MP_EV_CLICK && !this.getConfig(CONFIG_TRACK_CLICK)) ||
|
|
18421
|
+
(mpEventName === MP_EV_RAGE_CLICK && !this._getRageClickConfig())
|
|
18422
|
+
);
|
|
18423
|
+
|
|
18383
18424
|
var props = getPropsForDOMEvent(ev, {
|
|
18384
18425
|
allowElementCallback: this.getConfig(CONFIG_ALLOW_ELEMENT_CALLBACK),
|
|
18385
18426
|
allowSelectors: this.getConfig(CONFIG_ALLOW_SELECTORS),
|
|
@@ -18388,7 +18429,7 @@
|
|
|
18388
18429
|
blockSelectors: this.getConfig(CONFIG_BLOCK_SELECTORS),
|
|
18389
18430
|
captureExtraAttrs: this.getConfig(CONFIG_CAPTURE_EXTRA_ATTRS),
|
|
18390
18431
|
captureTextContent: this.getConfig(CONFIG_CAPTURE_TEXT_CONTENT),
|
|
18391
|
-
capturedForHeatMap:
|
|
18432
|
+
capturedForHeatMap: isCapturedForHeatMap,
|
|
18392
18433
|
});
|
|
18393
18434
|
if (props) {
|
|
18394
18435
|
_.extend(props, DEFAULT_PROPS);
|
|
@@ -18396,6 +18437,24 @@
|
|
|
18396
18437
|
}
|
|
18397
18438
|
};
|
|
18398
18439
|
|
|
18440
|
+
Autocapture.prototype._getRageClickConfig = function() {
|
|
18441
|
+
var config = this.getConfig(CONFIG_TRACK_RAGE_CLICK);
|
|
18442
|
+
|
|
18443
|
+
if (!config) {
|
|
18444
|
+
return null; // rage click tracking disabled
|
|
18445
|
+
}
|
|
18446
|
+
|
|
18447
|
+
if (config === true) {
|
|
18448
|
+
return {}; // use defaults
|
|
18449
|
+
}
|
|
18450
|
+
|
|
18451
|
+
if (typeof config === 'object') {
|
|
18452
|
+
return config; // use custom configuration
|
|
18453
|
+
}
|
|
18454
|
+
|
|
18455
|
+
return {}; // fallback to defaults for any other truthy value
|
|
18456
|
+
};
|
|
18457
|
+
|
|
18399
18458
|
Autocapture.prototype.initClickTracking = function() {
|
|
18400
18459
|
win.removeEventListener(EV_CLICK, this.listenerClick);
|
|
18401
18460
|
|
|
@@ -18497,6 +18556,36 @@
|
|
|
18497
18556
|
}.bind(this)));
|
|
18498
18557
|
};
|
|
18499
18558
|
|
|
18559
|
+
Autocapture.prototype.initRageClickTracking = function() {
|
|
18560
|
+
win.removeEventListener(EV_CLICK, this.listenerRageClick);
|
|
18561
|
+
|
|
18562
|
+
var rageClickConfig = this._getRageClickConfig();
|
|
18563
|
+
if (!rageClickConfig && !this.mp.get_config('record_heatmap_data')) {
|
|
18564
|
+
return;
|
|
18565
|
+
}
|
|
18566
|
+
|
|
18567
|
+
logger$1.log('Initializing rage click tracking');
|
|
18568
|
+
if (!this._rageClickTracker) {
|
|
18569
|
+
this._rageClickTracker = new RageClickTracker();
|
|
18570
|
+
}
|
|
18571
|
+
|
|
18572
|
+
this.listenerRageClick = function(ev) {
|
|
18573
|
+
var currentRageClickConfig = this._getRageClickConfig();
|
|
18574
|
+
if (!currentRageClickConfig && !this.mp.is_recording_heatmap_data()) {
|
|
18575
|
+
return;
|
|
18576
|
+
}
|
|
18577
|
+
|
|
18578
|
+
if (this.currentUrlBlocked()) {
|
|
18579
|
+
return;
|
|
18580
|
+
}
|
|
18581
|
+
|
|
18582
|
+
if (this._rageClickTracker.isRageClick(ev['pageX'], ev['pageY'], currentRageClickConfig)) {
|
|
18583
|
+
this.trackDomEvent(ev, MP_EV_RAGE_CLICK);
|
|
18584
|
+
}
|
|
18585
|
+
}.bind(this);
|
|
18586
|
+
win.addEventListener(EV_CLICK, this.listenerRageClick);
|
|
18587
|
+
};
|
|
18588
|
+
|
|
18500
18589
|
Autocapture.prototype.initScrollTracking = function() {
|
|
18501
18590
|
win.removeEventListener(EV_SCROLLEND, this.listenerScroll);
|
|
18502
18591
|
|
|
@@ -18583,6 +18672,7 @@
|
|
|
18583
18672
|
var FeatureFlagManager = function(initOptions) {
|
|
18584
18673
|
this.getFullApiRoute = initOptions.getFullApiRoute;
|
|
18585
18674
|
this.getMpConfig = initOptions.getConfigFunc;
|
|
18675
|
+
this.setMpConfig = initOptions.setConfigFunc;
|
|
18586
18676
|
this.getMpProperty = initOptions.getPropertyFunc;
|
|
18587
18677
|
this.track = initOptions.trackingFunc;
|
|
18588
18678
|
};
|
|
@@ -18620,6 +18710,23 @@
|
|
|
18620
18710
|
return !!this.getMpConfig(FLAGS_CONFIG_KEY);
|
|
18621
18711
|
};
|
|
18622
18712
|
|
|
18713
|
+
FeatureFlagManager.prototype.updateContext = function(newContext, options) {
|
|
18714
|
+
if (!this.isSystemEnabled()) {
|
|
18715
|
+
logger.critical('Feature Flags not enabled, cannot update context');
|
|
18716
|
+
return Promise.resolve();
|
|
18717
|
+
}
|
|
18718
|
+
|
|
18719
|
+
var ffConfig = this.getMpConfig(FLAGS_CONFIG_KEY);
|
|
18720
|
+
if (!_.isObject(ffConfig)) {
|
|
18721
|
+
ffConfig = {};
|
|
18722
|
+
}
|
|
18723
|
+
var oldContext = (options && options['replace']) ? {} : this.getConfig(CONFIG_CONTEXT);
|
|
18724
|
+
ffConfig[CONFIG_CONTEXT] = _.extend({}, oldContext, newContext);
|
|
18725
|
+
|
|
18726
|
+
this.setMpConfig(FLAGS_CONFIG_KEY, ffConfig);
|
|
18727
|
+
return this.fetchFlags();
|
|
18728
|
+
};
|
|
18729
|
+
|
|
18623
18730
|
FeatureFlagManager.prototype.areFlagsReady = function() {
|
|
18624
18731
|
if (!this.isSystemEnabled()) {
|
|
18625
18732
|
logger.error('Feature Flags not enabled');
|
|
@@ -18629,7 +18736,7 @@
|
|
|
18629
18736
|
|
|
18630
18737
|
FeatureFlagManager.prototype.fetchFlags = function() {
|
|
18631
18738
|
if (!this.isSystemEnabled()) {
|
|
18632
|
-
return;
|
|
18739
|
+
return Promise.resolve();
|
|
18633
18740
|
}
|
|
18634
18741
|
|
|
18635
18742
|
var distinctId = this.getMpProperty('distinct_id');
|
|
@@ -18669,6 +18776,8 @@
|
|
|
18669
18776
|
this.markFetchComplete();
|
|
18670
18777
|
logger.error(error);
|
|
18671
18778
|
}.bind(this));
|
|
18779
|
+
|
|
18780
|
+
return this.fetchPromise;
|
|
18672
18781
|
};
|
|
18673
18782
|
|
|
18674
18783
|
FeatureFlagManager.prototype.markFetchComplete = function() {
|
|
@@ -18781,6 +18890,7 @@
|
|
|
18781
18890
|
FeatureFlagManager.prototype['get_variant_value_sync'] = FeatureFlagManager.prototype.getVariantValueSync;
|
|
18782
18891
|
FeatureFlagManager.prototype['is_enabled'] = FeatureFlagManager.prototype.isEnabled;
|
|
18783
18892
|
FeatureFlagManager.prototype['is_enabled_sync'] = FeatureFlagManager.prototype.isEnabledSync;
|
|
18893
|
+
FeatureFlagManager.prototype['update_context'] = FeatureFlagManager.prototype.updateContext;
|
|
18784
18894
|
|
|
18785
18895
|
// Deprecated method
|
|
18786
18896
|
FeatureFlagManager.prototype['get_feature_data'] = FeatureFlagManager.prototype.getFeatureData;
|
|
@@ -20241,7 +20351,7 @@
|
|
|
20241
20351
|
'batch_autostart': true,
|
|
20242
20352
|
'hooks': {},
|
|
20243
20353
|
'record_block_class': new RegExp('^(mp-block|fs-exclude|amp-block|rr-block|ph-no-capture)$'),
|
|
20244
|
-
'record_block_selector': 'img, video',
|
|
20354
|
+
'record_block_selector': 'img, video, audio',
|
|
20245
20355
|
'record_canvas': false,
|
|
20246
20356
|
'record_collect_fonts': false,
|
|
20247
20357
|
'record_heatmap_data': false,
|
|
@@ -20465,6 +20575,7 @@
|
|
|
20465
20575
|
return this.get_api_host('flags') + '/' + this.get_config('api_routes')['flags'];
|
|
20466
20576
|
}, this),
|
|
20467
20577
|
getConfigFunc: _.bind(this.get_config, this),
|
|
20578
|
+
setConfigFunc: _.bind(this.set_config, this),
|
|
20468
20579
|
getPropertyFunc: _.bind(this.get_property, this),
|
|
20469
20580
|
trackingFunc: _.bind(this.track, this)
|
|
20470
20581
|
});
|
package/package.json
CHANGED
package/src/autocapture/index.js
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
EV_CHANGE, EV_CLICK, EV_HASHCHANGE, EV_MP_LOCATION_CHANGE, EV_POPSTATE,
|
|
6
6
|
EV_SCROLLEND, EV_SUBMIT
|
|
7
7
|
} from './utils';
|
|
8
|
+
import { RageClickTracker } from './rageclick';
|
|
8
9
|
|
|
9
10
|
var AUTOCAPTURE_CONFIG_KEY = 'autocapture';
|
|
10
11
|
var LEGACY_PAGEVIEW_CONFIG_KEY = 'track_pageview';
|
|
@@ -27,6 +28,7 @@ var CONFIG_SCROLL_CHECKPOINTS = 'scroll_depth_percent_checkpoints';
|
|
|
27
28
|
var CONFIG_TRACK_CLICK = 'click';
|
|
28
29
|
var CONFIG_TRACK_INPUT = 'input';
|
|
29
30
|
var CONFIG_TRACK_PAGEVIEW = 'pageview';
|
|
31
|
+
var CONFIG_TRACK_RAGE_CLICK = 'rage_click';
|
|
30
32
|
var CONFIG_TRACK_SCROLL = 'scroll';
|
|
31
33
|
var CONFIG_TRACK_SUBMIT = 'submit';
|
|
32
34
|
|
|
@@ -44,6 +46,7 @@ CONFIG_DEFAULTS[CONFIG_SCROLL_CHECKPOINTS] = [25, 50, 75, 100];
|
|
|
44
46
|
CONFIG_DEFAULTS[CONFIG_TRACK_CLICK] = true;
|
|
45
47
|
CONFIG_DEFAULTS[CONFIG_TRACK_INPUT] = true;
|
|
46
48
|
CONFIG_DEFAULTS[CONFIG_TRACK_PAGEVIEW] = PAGEVIEW_OPTION_FULL_URL;
|
|
49
|
+
CONFIG_DEFAULTS[CONFIG_TRACK_RAGE_CLICK] = true;
|
|
47
50
|
CONFIG_DEFAULTS[CONFIG_TRACK_SCROLL] = true;
|
|
48
51
|
CONFIG_DEFAULTS[CONFIG_TRACK_SUBMIT] = true;
|
|
49
52
|
|
|
@@ -53,6 +56,7 @@ var DEFAULT_PROPS = {
|
|
|
53
56
|
|
|
54
57
|
var MP_EV_CLICK = '$mp_click';
|
|
55
58
|
var MP_EV_INPUT = '$mp_input_change';
|
|
59
|
+
var MP_EV_RAGE_CLICK = '$mp_rage_click';
|
|
56
60
|
var MP_EV_SCROLL = '$mp_scroll';
|
|
57
61
|
var MP_EV_SUBMIT = '$mp_submit';
|
|
58
62
|
|
|
@@ -75,6 +79,7 @@ Autocapture.prototype.init = function() {
|
|
|
75
79
|
this.initInputTracking();
|
|
76
80
|
this.initScrollTracking();
|
|
77
81
|
this.initSubmitTracking();
|
|
82
|
+
this.initRageClickTracking();
|
|
78
83
|
};
|
|
79
84
|
|
|
80
85
|
Autocapture.prototype.getFullConfig = function() {
|
|
@@ -153,6 +158,11 @@ Autocapture.prototype.trackDomEvent = function(ev, mpEventName) {
|
|
|
153
158
|
return;
|
|
154
159
|
}
|
|
155
160
|
|
|
161
|
+
var isCapturedForHeatMap = this.mp.is_recording_heatmap_data() && (
|
|
162
|
+
(mpEventName === MP_EV_CLICK && !this.getConfig(CONFIG_TRACK_CLICK)) ||
|
|
163
|
+
(mpEventName === MP_EV_RAGE_CLICK && !this._getRageClickConfig())
|
|
164
|
+
);
|
|
165
|
+
|
|
156
166
|
var props = getPropsForDOMEvent(ev, {
|
|
157
167
|
allowElementCallback: this.getConfig(CONFIG_ALLOW_ELEMENT_CALLBACK),
|
|
158
168
|
allowSelectors: this.getConfig(CONFIG_ALLOW_SELECTORS),
|
|
@@ -161,7 +171,7 @@ Autocapture.prototype.trackDomEvent = function(ev, mpEventName) {
|
|
|
161
171
|
blockSelectors: this.getConfig(CONFIG_BLOCK_SELECTORS),
|
|
162
172
|
captureExtraAttrs: this.getConfig(CONFIG_CAPTURE_EXTRA_ATTRS),
|
|
163
173
|
captureTextContent: this.getConfig(CONFIG_CAPTURE_TEXT_CONTENT),
|
|
164
|
-
capturedForHeatMap:
|
|
174
|
+
capturedForHeatMap: isCapturedForHeatMap,
|
|
165
175
|
});
|
|
166
176
|
if (props) {
|
|
167
177
|
_.extend(props, DEFAULT_PROPS);
|
|
@@ -169,6 +179,24 @@ Autocapture.prototype.trackDomEvent = function(ev, mpEventName) {
|
|
|
169
179
|
}
|
|
170
180
|
};
|
|
171
181
|
|
|
182
|
+
Autocapture.prototype._getRageClickConfig = function() {
|
|
183
|
+
var config = this.getConfig(CONFIG_TRACK_RAGE_CLICK);
|
|
184
|
+
|
|
185
|
+
if (!config) {
|
|
186
|
+
return null; // rage click tracking disabled
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
if (config === true) {
|
|
190
|
+
return {}; // use defaults
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (typeof config === 'object') {
|
|
194
|
+
return config; // use custom configuration
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
return {}; // fallback to defaults for any other truthy value
|
|
198
|
+
};
|
|
199
|
+
|
|
172
200
|
Autocapture.prototype.initClickTracking = function() {
|
|
173
201
|
window.removeEventListener(EV_CLICK, this.listenerClick);
|
|
174
202
|
|
|
@@ -270,6 +298,36 @@ Autocapture.prototype.initPageviewTracking = function() {
|
|
|
270
298
|
}.bind(this)));
|
|
271
299
|
};
|
|
272
300
|
|
|
301
|
+
Autocapture.prototype.initRageClickTracking = function() {
|
|
302
|
+
window.removeEventListener(EV_CLICK, this.listenerRageClick);
|
|
303
|
+
|
|
304
|
+
var rageClickConfig = this._getRageClickConfig();
|
|
305
|
+
if (!rageClickConfig && !this.mp.get_config('record_heatmap_data')) {
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
logger.log('Initializing rage click tracking');
|
|
310
|
+
if (!this._rageClickTracker) {
|
|
311
|
+
this._rageClickTracker = new RageClickTracker();
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
this.listenerRageClick = function(ev) {
|
|
315
|
+
var currentRageClickConfig = this._getRageClickConfig();
|
|
316
|
+
if (!currentRageClickConfig && !this.mp.is_recording_heatmap_data()) {
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
if (this.currentUrlBlocked()) {
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
if (this._rageClickTracker.isRageClick(ev['pageX'], ev['pageY'], currentRageClickConfig)) {
|
|
325
|
+
this.trackDomEvent(ev, MP_EV_RAGE_CLICK);
|
|
326
|
+
}
|
|
327
|
+
}.bind(this);
|
|
328
|
+
window.addEventListener(EV_CLICK, this.listenerRageClick);
|
|
329
|
+
};
|
|
330
|
+
|
|
273
331
|
Autocapture.prototype.initScrollTracking = function() {
|
|
274
332
|
window.removeEventListener(EV_SCROLLEND, this.listenerScroll);
|
|
275
333
|
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/** @const */ var DEFAULT_RAGE_CLICK_THRESHOLD_PX = 30;
|
|
2
|
+
/** @const */ var DEFAULT_RAGE_CLICK_TIMEOUT_MS = 1000;
|
|
3
|
+
/** @const */ var DEFAULT_RAGE_CLICK_CLICK_COUNT = 4;
|
|
4
|
+
|
|
5
|
+
function RageClickTracker() {
|
|
6
|
+
this.clicks = [];
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
RageClickTracker.prototype.isRageClick = function(x, y, options) {
|
|
10
|
+
options = options || {};
|
|
11
|
+
var thresholdPx = options['threshold_px'] || DEFAULT_RAGE_CLICK_THRESHOLD_PX;
|
|
12
|
+
var timeoutMs = options['timeout_ms'] || DEFAULT_RAGE_CLICK_TIMEOUT_MS;
|
|
13
|
+
var clickCount = options['click_count'] || DEFAULT_RAGE_CLICK_CLICK_COUNT;
|
|
14
|
+
var timestamp = Date.now();
|
|
15
|
+
|
|
16
|
+
var lastClick = this.clicks[this.clicks.length - 1];
|
|
17
|
+
if (
|
|
18
|
+
lastClick &&
|
|
19
|
+
timestamp - lastClick.timestamp < timeoutMs &&
|
|
20
|
+
Math.sqrt(Math.pow(x - lastClick.x, 2) + Math.pow(y - lastClick.y, 2)) < thresholdPx
|
|
21
|
+
) {
|
|
22
|
+
this.clicks.push({ x: x, y: y, timestamp: timestamp });
|
|
23
|
+
if (this.clicks.length >= clickCount) {
|
|
24
|
+
this.clicks = [];
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
} else {
|
|
28
|
+
this.clicks = [{ x: x, y: y, timestamp: timestamp }];
|
|
29
|
+
}
|
|
30
|
+
return false;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export {
|
|
34
|
+
RageClickTracker,
|
|
35
|
+
DEFAULT_RAGE_CLICK_THRESHOLD_PX,
|
|
36
|
+
DEFAULT_RAGE_CLICK_TIMEOUT_MS,
|
|
37
|
+
DEFAULT_RAGE_CLICK_CLICK_COUNT
|
|
38
|
+
};
|