mixpanel-browser 2.72.0 → 2.73.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.
@@ -17,7 +17,9 @@ if (typeof(window) === 'undefined') {
17
17
  screen: { width: 0, height: 0 },
18
18
  location: loc,
19
19
  addEventListener: function() {},
20
- removeEventListener: function() {}
20
+ removeEventListener: function() {},
21
+ dispatchEvent: function() {},
22
+ CustomEvent: function () {}
21
23
  };
22
24
  } else {
23
25
  win = window;
@@ -14532,7 +14534,7 @@ if (typeof Promise !== 'undefined' && Promise.toString().indexOf('[native code]'
14532
14534
 
14533
14535
  var Config = {
14534
14536
  DEBUG: false,
14535
- LIB_VERSION: '2.72.0'
14537
+ LIB_VERSION: '2.73.0'
14536
14538
  };
14537
14539
 
14538
14540
  /* eslint camelcase: "off", eqeqeq: "off" */
@@ -21800,8 +21802,6 @@ var mixpanel_master; // main mixpanel instance / object
21800
21802
  var INIT_MODULE = 0;
21801
21803
  var INIT_SNIPPET = 1;
21802
21804
 
21803
- var IDENTITY_FUNC = function(x) {return x;};
21804
-
21805
21805
  /** @const */ var PRIMARY_INSTANCE_NAME = 'mixpanel';
21806
21806
  /** @const */ var PAYLOAD_TYPE_BASE64 = 'base64';
21807
21807
  /** @const */ var PAYLOAD_TYPE_JSON = 'json';
@@ -21967,6 +21967,17 @@ var create_mplib = function(token, config, name) {
21967
21967
  // global debug to be true
21968
21968
  Config.DEBUG = Config.DEBUG || instance.get_config('debug');
21969
21969
 
21970
+ var source = init_type === INIT_MODULE ? 'module' : 'snippet';
21971
+ win.dispatchEvent(new win.CustomEvent('$mp_sdk_to_extension_event', {
21972
+ 'detail': {
21973
+ 'instance': instance,
21974
+ 'source': source,
21975
+ 'token': token,
21976
+ 'name': name,
21977
+ 'info': _.info
21978
+ }
21979
+ }));
21980
+
21970
21981
  // if target is not defined, we called init after the lib already
21971
21982
  // loaded, so there won't be an array of things to execute
21972
21983
  if (!_.isUndefined(target) && _.isArray(target)) {
@@ -22037,6 +22048,8 @@ MixpanelLib.prototype._init = function(token, config, name) {
22037
22048
  }
22038
22049
  }
22039
22050
 
22051
+ this.hooks = {};
22052
+
22040
22053
  this.set_config(_.extend({}, DEFAULT_CONFIG, variable_features, config, {
22041
22054
  'name': name,
22042
22055
  'token': token,
@@ -22637,7 +22650,12 @@ MixpanelLib.prototype.init_batchers = function() {
22637
22650
  );
22638
22651
  }, this),
22639
22652
  beforeSendHook: _.bind(function(item) {
22640
- return this._run_hook('before_send_' + attrs.type, item);
22653
+ var ret = this._run_hook('before_send_' + attrs.type, item);
22654
+ if (ret) {
22655
+ return ret[0];
22656
+ } else {
22657
+ return null;
22658
+ }
22641
22659
  }, this),
22642
22660
  stopAllBatchingFunc: _.bind(this.stop_batch_senders, this),
22643
22661
  usePersistence: true,
@@ -22730,6 +22748,9 @@ MixpanelLib.prototype._track_or_batch = function(options, callback) {
22730
22748
  var send_request_immediately = _.bind(function() {
22731
22749
  if (!send_request_options.skip_hooks) {
22732
22750
  truncated_data = this._run_hook('before_send_' + options.type, truncated_data);
22751
+ if (truncated_data) {
22752
+ truncated_data = truncated_data[0];
22753
+ }
22733
22754
  }
22734
22755
  if (truncated_data) {
22735
22756
  console$1.log('MIXPANEL REQUEST:');
@@ -22784,6 +22805,17 @@ MixpanelLib.prototype._track_or_batch = function(options, callback) {
22784
22805
  * with the tracking payload sent to the API server is returned; otherwise false.
22785
22806
  */
22786
22807
  MixpanelLib.prototype.track = addOptOutCheckMixpanelLib(function(event_name, properties, options, callback) {
22808
+ var ret;
22809
+ if (!(options && options.skip_hooks)) {
22810
+ ret = this._run_hook('before_track', event_name, properties);
22811
+ if (ret === null) {
22812
+ return;
22813
+ } else {
22814
+ event_name = ret[0];
22815
+ properties = ret[1];
22816
+ }
22817
+ }
22818
+
22787
22819
  if (!callback && typeof options === 'function') {
22788
22820
  callback = options;
22789
22821
  options = null;
@@ -22853,7 +22885,7 @@ MixpanelLib.prototype.track = addOptOutCheckMixpanelLib(function(event_name, pro
22853
22885
  'event': event_name,
22854
22886
  'properties': properties
22855
22887
  };
22856
- var ret = this._track_or_batch({
22888
+ ret = this._track_or_batch({
22857
22889
  type: 'events',
22858
22890
  data: data,
22859
22891
  endpoint: this.get_api_host('events') + '/' + this.get_config('api_routes')['track'],
@@ -23199,6 +23231,14 @@ var options_for_register = function(days_or_options) {
23199
23231
  * @param {boolean} [days_or_options.persistent=true] - whether to put in persistent storage (cookie/localStorage)
23200
23232
  */
23201
23233
  MixpanelLib.prototype.register = function(props, days_or_options) {
23234
+ var ret = this._run_hook('before_register', props, days_or_options);
23235
+ if (ret === null) {
23236
+ return;
23237
+ } else {
23238
+ props = ret[0];
23239
+ days_or_options = ret[1];
23240
+ }
23241
+
23202
23242
  var options = options_for_register(days_or_options);
23203
23243
  if (options['persistent']) {
23204
23244
  this['persistence'].register(props, options['days']);
@@ -23235,6 +23275,15 @@ MixpanelLib.prototype.register = function(props, days_or_options) {
23235
23275
  * @param {boolean} [days_or_options.persistent=true] - whether to put in persistent storage (cookie/localStorage)
23236
23276
  */
23237
23277
  MixpanelLib.prototype.register_once = function(props, default_value, days_or_options) {
23278
+ var ret = this._run_hook('before_register_once', props, default_value, days_or_options);
23279
+ if (ret === null) {
23280
+ return;
23281
+ } else {
23282
+ props = ret[0];
23283
+ default_value = ret[1];
23284
+ days_or_options = ret[2];
23285
+ }
23286
+
23238
23287
  var options = options_for_register(days_or_options);
23239
23288
  if (options['persistent']) {
23240
23289
  this['persistence'].register_once(props, default_value, options['days']);
@@ -23258,6 +23307,14 @@ MixpanelLib.prototype.register_once = function(props, default_value, days_or_opt
23258
23307
  * @param {boolean} [options.persistent=true] - whether to look in persistent storage (cookie/localStorage)
23259
23308
  */
23260
23309
  MixpanelLib.prototype.unregister = function(property, options) {
23310
+ var ret = this._run_hook('before_unregister', property, options);
23311
+ if (ret === null) {
23312
+ return;
23313
+ } else {
23314
+ property = ret[0];
23315
+ options = ret[1];
23316
+ }
23317
+
23261
23318
  options = options_for_register(options);
23262
23319
  if (options['persistent']) {
23263
23320
  this['persistence'].unregister(property);
@@ -23306,6 +23363,13 @@ MixpanelLib.prototype.identify = function(
23306
23363
  // _set_once_callback:function A callback to be run if and when the People set_once queue is flushed
23307
23364
  // _union_callback:function A callback to be run if and when the People union queue is flushed
23308
23365
  // _unset_callback:function A callback to be run if and when the People unset queue is flushed
23366
+ var ret = this._run_hook('before_identify', new_distinct_id);
23367
+
23368
+ if (ret === null) {
23369
+ return -1;
23370
+ } else {
23371
+ new_distinct_id = ret[0];
23372
+ }
23309
23373
 
23310
23374
  var previous_distinct_id = this.get_distinct_id();
23311
23375
  if (new_distinct_id && previous_distinct_id !== new_distinct_id) {
@@ -23630,6 +23694,25 @@ MixpanelLib.prototype.set_config = function(config) {
23630
23694
  if (('autocapture' in config || 'record_heatmap_data' in config) && this.autocapture) {
23631
23695
  this.autocapture.init();
23632
23696
  }
23697
+
23698
+ if (_.isObject(config['hooks'])) {
23699
+ this.hooks = {};
23700
+ _.each(config['hooks'], function(hook_value, hook_name) {
23701
+ if (_.isFunction(hook_value)) {
23702
+ this.hooks[hook_name] = [hook_value];
23703
+ } else if (_.isArray(hook_value)) {
23704
+ this.hooks[hook_name] = [];
23705
+ for (var i = 0; i < hook_value.length; i++) {
23706
+ if (!_.isFunction(hook_value[i])) {
23707
+ console$1.critical('Invalid hook added. Hook is not a function');
23708
+ }
23709
+ this.hooks[hook_name].push(hook_value[i]);
23710
+ }
23711
+ } else {
23712
+ console$1.critical('Invalid hooks added. Ensure that the hook values passed into config.hooks are functions or arrays of functions.');
23713
+ }
23714
+ }, this);
23715
+ }
23633
23716
  }
23634
23717
  };
23635
23718
 
@@ -23647,12 +23730,26 @@ MixpanelLib.prototype.get_config = function(prop_name) {
23647
23730
  * @returns {any|null} return value of user-provided hook, or null if nothing was returned
23648
23731
  */
23649
23732
  MixpanelLib.prototype._run_hook = function(hook_name) {
23650
- var ret = (this['config']['hooks'][hook_name] || IDENTITY_FUNC).apply(this, slice.call(arguments, 1));
23651
- if (typeof ret === 'undefined') {
23652
- this.report_error(hook_name + ' hook did not return a value');
23653
- ret = null;
23654
- }
23655
- return ret;
23733
+ var hook_data = slice.call(arguments, 1);
23734
+ _.each(this.hooks[hook_name], function(hook) {
23735
+ if (hook_data === null) {
23736
+ return null;
23737
+ }
23738
+
23739
+ var ret = hook.apply(this, hook_data);
23740
+
23741
+ if (typeof ret === 'undefined') {
23742
+ this.report_error(hook_name + ' hook did not return a valid value');
23743
+ hook_data = null;
23744
+ } else {
23745
+ if (!_.isArray(ret)) {
23746
+ ret = [ret];
23747
+ }
23748
+ hook_data.splice.apply(hook_data, [0, ret.length].concat(ret));
23749
+ }
23750
+ }, this);
23751
+
23752
+ return hook_data;
23656
23753
  };
23657
23754
 
23658
23755
  /**
@@ -23963,6 +24060,25 @@ MixpanelLib.prototype.report_error = function(msg, err) {
23963
24060
  }
23964
24061
  };
23965
24062
 
24063
+ MixpanelLib.prototype.add_hook = function(hook_name, hook_fn) {
24064
+ if (!this.hooks[hook_name]) {
24065
+ this.hooks[hook_name] = [];
24066
+ }
24067
+ this.hooks[hook_name].push(hook_fn);
24068
+ };
24069
+
24070
+ MixpanelLib.prototype.remove_hook = function(hook_name, hook_fn) {
24071
+ var fn_index;
24072
+ if (this.hooks[hook_name]) {
24073
+ fn_index = this.hooks[hook_name].indexOf(hook_fn);
24074
+ if (fn_index !== -1) {
24075
+ this.hooks[hook_name].splice(fn_index, 1);
24076
+ } else {
24077
+ console$1.log('remove_hook failed. Matching hook was not found');
24078
+ }
24079
+ }
24080
+ };
24081
+
23966
24082
  // EXPORTS (for closure compiler)
23967
24083
 
23968
24084
  // MixpanelLib Exports
@@ -23995,6 +24111,8 @@ MixpanelLib.prototype['get_group'] = MixpanelLib.protot
23995
24111
  MixpanelLib.prototype['set_group'] = MixpanelLib.prototype.set_group;
23996
24112
  MixpanelLib.prototype['add_group'] = MixpanelLib.prototype.add_group;
23997
24113
  MixpanelLib.prototype['remove_group'] = MixpanelLib.prototype.remove_group;
24114
+ MixpanelLib.prototype['add_hook'] = MixpanelLib.prototype.add_hook;
24115
+ MixpanelLib.prototype['remove_hook'] = MixpanelLib.prototype.remove_hook;
23998
24116
  MixpanelLib.prototype['track_with_groups'] = MixpanelLib.prototype.track_with_groups;
23999
24117
  MixpanelLib.prototype['start_batch_senders'] = MixpanelLib.prototype.start_batch_senders;
24000
24118
  MixpanelLib.prototype['stop_batch_senders'] = MixpanelLib.prototype.stop_batch_senders;
@@ -3,7 +3,7 @@
3
3
 
4
4
  var Config = {
5
5
  DEBUG: false,
6
- LIB_VERSION: '2.72.0'
6
+ LIB_VERSION: '2.73.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
@@ -23,7 +23,9 @@
23
23
  screen: { width: 0, height: 0 },
24
24
  location: loc,
25
25
  addEventListener: function() {},
26
- removeEventListener: function() {}
26
+ removeEventListener: function() {},
27
+ dispatchEvent: function() {},
28
+ CustomEvent: function () {}
27
29
  };
28
30
  } else {
29
31
  win = window;
@@ -6836,8 +6838,6 @@
6836
6838
  var INIT_MODULE = 0;
6837
6839
  var INIT_SNIPPET = 1;
6838
6840
 
6839
- var IDENTITY_FUNC = function(x) {return x;};
6840
-
6841
6841
  /** @const */ var PRIMARY_INSTANCE_NAME = 'mixpanel';
6842
6842
  /** @const */ var PAYLOAD_TYPE_BASE64 = 'base64';
6843
6843
  /** @const */ var PAYLOAD_TYPE_JSON = 'json';
@@ -7003,6 +7003,17 @@
7003
7003
  // global debug to be true
7004
7004
  Config.DEBUG = Config.DEBUG || instance.get_config('debug');
7005
7005
 
7006
+ var source = init_type === INIT_MODULE ? 'module' : 'snippet';
7007
+ win.dispatchEvent(new win.CustomEvent('$mp_sdk_to_extension_event', {
7008
+ 'detail': {
7009
+ 'instance': instance,
7010
+ 'source': source,
7011
+ 'token': token,
7012
+ 'name': name,
7013
+ 'info': _.info
7014
+ }
7015
+ }));
7016
+
7006
7017
  // if target is not defined, we called init after the lib already
7007
7018
  // loaded, so there won't be an array of things to execute
7008
7019
  if (!_.isUndefined(target) && _.isArray(target)) {
@@ -7073,6 +7084,8 @@
7073
7084
  }
7074
7085
  }
7075
7086
 
7087
+ this.hooks = {};
7088
+
7076
7089
  this.set_config(_.extend({}, DEFAULT_CONFIG, variable_features, config, {
7077
7090
  'name': name,
7078
7091
  'token': token,
@@ -7673,7 +7686,12 @@
7673
7686
  );
7674
7687
  }, this),
7675
7688
  beforeSendHook: _.bind(function(item) {
7676
- return this._run_hook('before_send_' + attrs.type, item);
7689
+ var ret = this._run_hook('before_send_' + attrs.type, item);
7690
+ if (ret) {
7691
+ return ret[0];
7692
+ } else {
7693
+ return null;
7694
+ }
7677
7695
  }, this),
7678
7696
  stopAllBatchingFunc: _.bind(this.stop_batch_senders, this),
7679
7697
  usePersistence: true,
@@ -7766,6 +7784,9 @@
7766
7784
  var send_request_immediately = _.bind(function() {
7767
7785
  if (!send_request_options.skip_hooks) {
7768
7786
  truncated_data = this._run_hook('before_send_' + options.type, truncated_data);
7787
+ if (truncated_data) {
7788
+ truncated_data = truncated_data[0];
7789
+ }
7769
7790
  }
7770
7791
  if (truncated_data) {
7771
7792
  console.log('MIXPANEL REQUEST:');
@@ -7820,6 +7841,17 @@
7820
7841
  * with the tracking payload sent to the API server is returned; otherwise false.
7821
7842
  */
7822
7843
  MixpanelLib.prototype.track = addOptOutCheckMixpanelLib(function(event_name, properties, options, callback) {
7844
+ var ret;
7845
+ if (!(options && options.skip_hooks)) {
7846
+ ret = this._run_hook('before_track', event_name, properties);
7847
+ if (ret === null) {
7848
+ return;
7849
+ } else {
7850
+ event_name = ret[0];
7851
+ properties = ret[1];
7852
+ }
7853
+ }
7854
+
7823
7855
  if (!callback && typeof options === 'function') {
7824
7856
  callback = options;
7825
7857
  options = null;
@@ -7889,7 +7921,7 @@
7889
7921
  'event': event_name,
7890
7922
  'properties': properties
7891
7923
  };
7892
- var ret = this._track_or_batch({
7924
+ ret = this._track_or_batch({
7893
7925
  type: 'events',
7894
7926
  data: data,
7895
7927
  endpoint: this.get_api_host('events') + '/' + this.get_config('api_routes')['track'],
@@ -8235,6 +8267,14 @@
8235
8267
  * @param {boolean} [days_or_options.persistent=true] - whether to put in persistent storage (cookie/localStorage)
8236
8268
  */
8237
8269
  MixpanelLib.prototype.register = function(props, days_or_options) {
8270
+ var ret = this._run_hook('before_register', props, days_or_options);
8271
+ if (ret === null) {
8272
+ return;
8273
+ } else {
8274
+ props = ret[0];
8275
+ days_or_options = ret[1];
8276
+ }
8277
+
8238
8278
  var options = options_for_register(days_or_options);
8239
8279
  if (options['persistent']) {
8240
8280
  this['persistence'].register(props, options['days']);
@@ -8271,6 +8311,15 @@
8271
8311
  * @param {boolean} [days_or_options.persistent=true] - whether to put in persistent storage (cookie/localStorage)
8272
8312
  */
8273
8313
  MixpanelLib.prototype.register_once = function(props, default_value, days_or_options) {
8314
+ var ret = this._run_hook('before_register_once', props, default_value, days_or_options);
8315
+ if (ret === null) {
8316
+ return;
8317
+ } else {
8318
+ props = ret[0];
8319
+ default_value = ret[1];
8320
+ days_or_options = ret[2];
8321
+ }
8322
+
8274
8323
  var options = options_for_register(days_or_options);
8275
8324
  if (options['persistent']) {
8276
8325
  this['persistence'].register_once(props, default_value, options['days']);
@@ -8294,6 +8343,14 @@
8294
8343
  * @param {boolean} [options.persistent=true] - whether to look in persistent storage (cookie/localStorage)
8295
8344
  */
8296
8345
  MixpanelLib.prototype.unregister = function(property, options) {
8346
+ var ret = this._run_hook('before_unregister', property, options);
8347
+ if (ret === null) {
8348
+ return;
8349
+ } else {
8350
+ property = ret[0];
8351
+ options = ret[1];
8352
+ }
8353
+
8297
8354
  options = options_for_register(options);
8298
8355
  if (options['persistent']) {
8299
8356
  this['persistence'].unregister(property);
@@ -8342,6 +8399,13 @@
8342
8399
  // _set_once_callback:function A callback to be run if and when the People set_once queue is flushed
8343
8400
  // _union_callback:function A callback to be run if and when the People union queue is flushed
8344
8401
  // _unset_callback:function A callback to be run if and when the People unset queue is flushed
8402
+ var ret = this._run_hook('before_identify', new_distinct_id);
8403
+
8404
+ if (ret === null) {
8405
+ return -1;
8406
+ } else {
8407
+ new_distinct_id = ret[0];
8408
+ }
8345
8409
 
8346
8410
  var previous_distinct_id = this.get_distinct_id();
8347
8411
  if (new_distinct_id && previous_distinct_id !== new_distinct_id) {
@@ -8666,6 +8730,25 @@
8666
8730
  if (('autocapture' in config || 'record_heatmap_data' in config) && this.autocapture) {
8667
8731
  this.autocapture.init();
8668
8732
  }
8733
+
8734
+ if (_.isObject(config['hooks'])) {
8735
+ this.hooks = {};
8736
+ _.each(config['hooks'], function(hook_value, hook_name) {
8737
+ if (_.isFunction(hook_value)) {
8738
+ this.hooks[hook_name] = [hook_value];
8739
+ } else if (_.isArray(hook_value)) {
8740
+ this.hooks[hook_name] = [];
8741
+ for (var i = 0; i < hook_value.length; i++) {
8742
+ if (!_.isFunction(hook_value[i])) {
8743
+ console.critical('Invalid hook added. Hook is not a function');
8744
+ }
8745
+ this.hooks[hook_name].push(hook_value[i]);
8746
+ }
8747
+ } else {
8748
+ console.critical('Invalid hooks added. Ensure that the hook values passed into config.hooks are functions or arrays of functions.');
8749
+ }
8750
+ }, this);
8751
+ }
8669
8752
  }
8670
8753
  };
8671
8754
 
@@ -8683,12 +8766,26 @@
8683
8766
  * @returns {any|null} return value of user-provided hook, or null if nothing was returned
8684
8767
  */
8685
8768
  MixpanelLib.prototype._run_hook = function(hook_name) {
8686
- var ret = (this['config']['hooks'][hook_name] || IDENTITY_FUNC).apply(this, slice.call(arguments, 1));
8687
- if (typeof ret === 'undefined') {
8688
- this.report_error(hook_name + ' hook did not return a value');
8689
- ret = null;
8690
- }
8691
- return ret;
8769
+ var hook_data = slice.call(arguments, 1);
8770
+ _.each(this.hooks[hook_name], function(hook) {
8771
+ if (hook_data === null) {
8772
+ return null;
8773
+ }
8774
+
8775
+ var ret = hook.apply(this, hook_data);
8776
+
8777
+ if (typeof ret === 'undefined') {
8778
+ this.report_error(hook_name + ' hook did not return a valid value');
8779
+ hook_data = null;
8780
+ } else {
8781
+ if (!_.isArray(ret)) {
8782
+ ret = [ret];
8783
+ }
8784
+ hook_data.splice.apply(hook_data, [0, ret.length].concat(ret));
8785
+ }
8786
+ }, this);
8787
+
8788
+ return hook_data;
8692
8789
  };
8693
8790
 
8694
8791
  /**
@@ -8999,6 +9096,25 @@
8999
9096
  }
9000
9097
  };
9001
9098
 
9099
+ MixpanelLib.prototype.add_hook = function(hook_name, hook_fn) {
9100
+ if (!this.hooks[hook_name]) {
9101
+ this.hooks[hook_name] = [];
9102
+ }
9103
+ this.hooks[hook_name].push(hook_fn);
9104
+ };
9105
+
9106
+ MixpanelLib.prototype.remove_hook = function(hook_name, hook_fn) {
9107
+ var fn_index;
9108
+ if (this.hooks[hook_name]) {
9109
+ fn_index = this.hooks[hook_name].indexOf(hook_fn);
9110
+ if (fn_index !== -1) {
9111
+ this.hooks[hook_name].splice(fn_index, 1);
9112
+ } else {
9113
+ console.log('remove_hook failed. Matching hook was not found');
9114
+ }
9115
+ }
9116
+ };
9117
+
9002
9118
  // EXPORTS (for closure compiler)
9003
9119
 
9004
9120
  // MixpanelLib Exports
@@ -9031,6 +9147,8 @@
9031
9147
  MixpanelLib.prototype['set_group'] = MixpanelLib.prototype.set_group;
9032
9148
  MixpanelLib.prototype['add_group'] = MixpanelLib.prototype.add_group;
9033
9149
  MixpanelLib.prototype['remove_group'] = MixpanelLib.prototype.remove_group;
9150
+ MixpanelLib.prototype['add_hook'] = MixpanelLib.prototype.add_hook;
9151
+ MixpanelLib.prototype['remove_hook'] = MixpanelLib.prototype.remove_hook;
9034
9152
  MixpanelLib.prototype['track_with_groups'] = MixpanelLib.prototype.track_with_groups;
9035
9153
  MixpanelLib.prototype['start_batch_senders'] = MixpanelLib.prototype.start_batch_senders;
9036
9154
  MixpanelLib.prototype['stop_batch_senders'] = MixpanelLib.prototype.stop_batch_senders;