posthog-js 1.36.0 → 1.37.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/dist/es.js CHANGED
@@ -917,7 +917,7 @@ var LZString = {
917
917
  }
918
918
  };
919
919
 
920
- var version = "1.36.0";
920
+ var version = "1.37.0";
921
921
 
922
922
  // e.g. Config.DEBUG = Config.DEBUG || instance.get_config('debug')
923
923
 
@@ -1199,7 +1199,6 @@ var _strip_empty_properties = function _strip_empty_properties(p) {
1199
1199
 
1200
1200
  return ret;
1201
1201
  };
1202
- var COPY_IN_PROGRESS_ATTRIBUTE = typeof Symbol !== 'undefined' ? Symbol('__deepCircularCopyInProgress__') : '__deepCircularCopyInProgress__';
1203
1202
  /**
1204
1203
  * Deep copies an object.
1205
1204
  * It handles cycles by replacing all references to them with `undefined`
@@ -1207,35 +1206,39 @@ var COPY_IN_PROGRESS_ATTRIBUTE = typeof Symbol !== 'undefined' ? Symbol('__deepC
1207
1206
  *
1208
1207
  * @param value
1209
1208
  * @param customizer
1210
- * @param [key] if provided this is the object key associated with the value to be copied. It allows the customizer function to have context when it runs
1211
1209
  * @returns {{}|undefined|*}
1212
1210
  */
1213
1211
 
1214
- function deepCircularCopy(value, customizer, key) {
1215
- if (value !== Object(value)) return customizer ? customizer(value, key) : value; // primitive value
1212
+ function deepCircularCopy(value, customizer) {
1213
+ var COPY_IN_PROGRESS_SET = new Set();
1216
1214
 
1217
- if (value[COPY_IN_PROGRESS_ATTRIBUTE]) return undefined;
1218
- value[COPY_IN_PROGRESS_ATTRIBUTE] = true;
1219
- var result;
1215
+ function internalDeepCircularCopy(value, key) {
1216
+ if (value !== Object(value)) return customizer ? customizer(value, key) : value; // primitive value
1220
1217
 
1221
- if (_isArray(value)) {
1222
- result = [];
1218
+ if (COPY_IN_PROGRESS_SET.has(value)) return undefined;
1219
+ COPY_IN_PROGRESS_SET.add(value);
1220
+ var result;
1223
1221
 
1224
- _eachArray(value, function (it) {
1225
- result.push(deepCircularCopy(it, customizer));
1226
- });
1227
- } else {
1228
- result = {};
1222
+ if (_isArray(value)) {
1223
+ result = [];
1229
1224
 
1230
- _each(value, function (val, key) {
1231
- if (key !== COPY_IN_PROGRESS_ATTRIBUTE) {
1232
- result[key] = deepCircularCopy(val, customizer, key);
1233
- }
1234
- });
1225
+ _eachArray(value, function (it) {
1226
+ result.push(internalDeepCircularCopy(it));
1227
+ });
1228
+ } else {
1229
+ result = {};
1230
+
1231
+ _each(value, function (val, key) {
1232
+ if (!COPY_IN_PROGRESS_SET.has(val)) {
1233
+ result[key] = internalDeepCircularCopy(val, key);
1234
+ }
1235
+ });
1236
+ }
1237
+
1238
+ return result;
1235
1239
  }
1236
1240
 
1237
- delete value[COPY_IN_PROGRESS_ATTRIBUTE];
1238
- return result;
1241
+ return internalDeepCircularCopy(value);
1239
1242
  }
1240
1243
 
1241
1244
  var LONG_STRINGS_ALLOW_LIST = ['$performance_raw'];
@@ -1861,20 +1864,64 @@ function isTextNode(el) {
1861
1864
  function isDocumentFragment(el) {
1862
1865
  return !!el && el.nodeType === 11; // Node.DOCUMENT_FRAGMENT_NODE - use integer constant for browser portability
1863
1866
  }
1864
- var usefulElements = ['a', 'button', 'form', 'input', 'select', 'textarea', 'label'];
1867
+ var autocaptureCompatibleElements = ['a', 'button', 'form', 'input', 'select', 'textarea', 'label'];
1865
1868
  /*
1866
1869
  * Check whether a DOM event should be "captured" or if it may contain sentitive data
1867
1870
  * using a variety of heuristics.
1868
1871
  * @param {Element} el - element to check
1869
1872
  * @param {Event} event - event to check
1873
+ * @param {Object} autocaptureConfig - autocapture config
1870
1874
  * @returns {boolean} whether the event should be captured
1871
1875
  */
1872
1876
 
1873
1877
  function shouldCaptureDomEvent(el, event) {
1878
+ var autocaptureConfig = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : undefined;
1879
+
1874
1880
  if (!el || isTag(el, 'html') || !isElementNode(el)) {
1875
1881
  return false;
1876
1882
  }
1877
1883
 
1884
+ if (autocaptureConfig !== null && autocaptureConfig !== void 0 && autocaptureConfig.url_allowlist) {
1885
+ var url = window.location.href;
1886
+ var allowlist = autocaptureConfig.url_allowlist;
1887
+
1888
+ if (allowlist && !allowlist.some(function (regex) {
1889
+ return url.match(regex);
1890
+ })) {
1891
+ return false;
1892
+ }
1893
+ }
1894
+
1895
+ if (autocaptureConfig !== null && autocaptureConfig !== void 0 && autocaptureConfig.dom_event_allowlist) {
1896
+ var _allowlist = autocaptureConfig.dom_event_allowlist;
1897
+
1898
+ if (_allowlist && !_allowlist.some(function (eventType) {
1899
+ return event.type === eventType;
1900
+ })) {
1901
+ return false;
1902
+ }
1903
+ }
1904
+
1905
+ if (autocaptureConfig !== null && autocaptureConfig !== void 0 && autocaptureConfig.element_allowlist) {
1906
+ var _allowlist2 = autocaptureConfig.element_allowlist;
1907
+
1908
+ if (_allowlist2 && !_allowlist2.some(function (elementType) {
1909
+ return el.tagName.toLowerCase() === elementType;
1910
+ })) {
1911
+ return false;
1912
+ }
1913
+ }
1914
+
1915
+ if (autocaptureConfig !== null && autocaptureConfig !== void 0 && autocaptureConfig.css_selector_allowlist) {
1916
+ var _allowlist3 = autocaptureConfig.css_selector_allowlist;
1917
+
1918
+ if (_allowlist3 && !_allowlist3.some(function (selector) {
1919
+ return el.matches(selector);
1920
+ })) {
1921
+ return false;
1922
+ }
1923
+ }
1924
+
1878
1925
  var parentIsUsefulElement = false;
1879
1926
  var targetElementList = [el]; // TODO: remove this var, it's never queried
1880
1927
 
@@ -1892,7 +1939,7 @@ function shouldCaptureDomEvent(el, event) {
1892
1939
  parentNode = curEl.parentNode || false;
1893
1940
  if (!parentNode) break;
1894
1941
 
1895
- if (usefulElements.indexOf(parentNode.tagName.toLowerCase()) > -1) {
1942
+ if (autocaptureCompatibleElements.indexOf(parentNode.tagName.toLowerCase()) > -1) {
1896
1943
  parentIsUsefulElement = true;
1897
1944
  } else {
1898
1945
  var _compStyles = window.getComputedStyle(parentNode);
@@ -1930,7 +1977,7 @@ function shouldCaptureDomEvent(el, event) {
1930
1977
 
1931
1978
  default:
1932
1979
  if (parentIsUsefulElement) return event.type === 'click';
1933
- return event.type === 'click' && (usefulElements.indexOf(tag) > -1 || el.getAttribute('contenteditable') === 'true');
1980
+ return event.type === 'click' && (autocaptureCompatibleElements.indexOf(tag) > -1 || el.getAttribute('contenteditable') === 'true');
1934
1981
  }
1935
1982
  }
1936
1983
  /*
@@ -2134,7 +2181,7 @@ var autocapture = {
2134
2181
  tag_name: tag_name
2135
2182
  };
2136
2183
 
2137
- if (usefulElements.indexOf(tag_name) > -1 && !maskText) {
2184
+ if (autocaptureCompatibleElements.indexOf(tag_name) > -1 && !maskText) {
2138
2185
  props['$el_text'] = getSafeText(elem);
2139
2186
  }
2140
2187
 
@@ -2245,7 +2292,7 @@ var autocapture = {
2245
2292
  (_this$rageclicks = this.rageclicks) === null || _this$rageclicks === void 0 ? void 0 : _this$rageclicks.click(e.clientX, e.clientY, new Date().getTime());
2246
2293
  }
2247
2294
 
2248
- if (target && shouldCaptureDomEvent(target, e)) {
2295
+ if (target && shouldCaptureDomEvent(target, e, this.config)) {
2249
2296
  var targetElementList = [target];
2250
2297
  var curEl = target;
2251
2298
 
@@ -2325,7 +2372,21 @@ var autocapture = {
2325
2372
  },
2326
2373
  _customProperties: [],
2327
2374
  rageclicks: null,
2375
+ config: undefined,
2328
2376
  init: function init(instance) {
2377
+ var _this$config;
2378
+
2379
+ if (typeof instance.__autocapture !== 'boolean') {
2380
+ this.config = instance.__autocapture;
2381
+ } // precompile the regex
2382
+
2383
+
2384
+ if ((_this$config = this.config) !== null && _this$config !== void 0 && _this$config.url_allowlist) {
2385
+ this.config.url_allowlist = this.config.url_allowlist.map(function (url) {
2386
+ return new RegExp(url);
2387
+ });
2388
+ }
2389
+
2329
2390
  this.rageclicks = new RageClick(instance);
2330
2391
  },
2331
2392
  afterDecideResponse: function afterDecideResponse(response, instance) {
@@ -2346,7 +2407,7 @@ var autocapture = {
2346
2407
 
2347
2408
  this._addDomEventHandlers(instance);
2348
2409
  } else {
2349
- instance['__autocapture_enabled'] = false;
2410
+ instance['__autocapture'] = false;
2350
2411
  }
2351
2412
  },
2352
2413
  // this is a mechanism to ramp up CE with no server-side interaction.
@@ -5294,6 +5355,10 @@ function strToU8(str, latin1) {
5294
5355
  return slc(ar, 0, ai);
5295
5356
  }
5296
5357
 
5358
+ /**
5359
+ * If an array is passed for an allowlist, autocapture events will only be sent for elements matching
5360
+ * at least one of the elements in the array. Multiple allowlists can be used
5361
+ */
5297
5362
  var Compression;
5298
5363
 
5299
5364
  (function (Compression) {
@@ -6117,7 +6182,7 @@ var defaultConfig = function defaultConfig() {
6117
6182
  ui_host: null,
6118
6183
  token: '',
6119
6184
  autocapture: true,
6120
- rageclick: false,
6185
+ rageclick: true,
6121
6186
  cross_subdomain_cookie: (document$1 === null || document$1 === void 0 ? void 0 : (_document$location = document$1.location) === null || _document$location === void 0 ? void 0 : (_document$location$ho = _document$location.hostname) === null || _document$location$ho === void 0 ? void 0 : _document$location$ho.indexOf('herokuapp.com')) === -1,
6122
6187
  persistence: 'cookie',
6123
6188
  persistence_name: '',
@@ -6220,17 +6285,18 @@ var create_mplib = function create_mplib(token, config, name) {
6220
6285
  instance.toolbar.maybeLoadToolbar();
6221
6286
  instance.sessionRecording = new SessionRecording(instance);
6222
6287
  instance.sessionRecording.startRecordingIfEnabled();
6223
- instance.__autocapture_enabled = instance.get_config('autocapture');
6288
+ instance.__autocapture = instance.get_config('autocapture');
6224
6289
 
6225
6290
  if (instance.get_config('autocapture')) {
6291
+ instance.__autocapture = instance.get_config('autocapture');
6226
6292
  var num_buckets = 100;
6227
6293
  var num_enabled_buckets = 100;
6228
6294
 
6229
6295
  if (!autocapture.enabledForProject(instance.get_config('token'), num_buckets, num_enabled_buckets)) {
6230
- instance.__autocapture_enabled = false;
6296
+ instance.__autocapture = false;
6231
6297
  logger.log('Not in active bucket: disabling Automatic Event Collection.');
6232
6298
  } else if (!autocapture.isBrowserSupported()) {
6233
- instance.__autocapture_enabled = false;
6299
+ instance.__autocapture = false;
6234
6300
  logger.log('Disabling Automatic Event Collection because this browser is not supported');
6235
6301
  } else {
6236
6302
  autocapture.init(instance);
@@ -6276,7 +6342,7 @@ var PostHog = /*#__PURE__*/function () {
6276
6342
  this.__captureHooks = [];
6277
6343
  this.__request_queue = [];
6278
6344
  this.__loaded = false;
6279
- this.__autocapture_enabled = undefined;
6345
+ this.__autocapture = undefined;
6280
6346
 
6281
6347
  this._jsc = function () {};
6282
6348
 
@@ -7155,6 +7221,19 @@ var PostHog = /*#__PURE__*/function () {
7155
7221
  this.reloadFeatureFlags();
7156
7222
  }
7157
7223
  }
7224
+ /**
7225
+ * Resets only the group properties of the user currently logged in.
7226
+ */
7227
+
7228
+ }, {
7229
+ key: "resetGroups",
7230
+ value: function resetGroups() {
7231
+ this.register({
7232
+ $groups: {}
7233
+ }); // If groups changed, reload feature flags.
7234
+
7235
+ this.reloadFeatureFlags();
7236
+ }
7158
7237
  /**
7159
7238
  * Clears super properties and generates a new random distinct_id for this instance.
7160
7239
  * Useful for clearing data when a user logs out.
@@ -7269,8 +7348,8 @@ var PostHog = /*#__PURE__*/function () {
7269
7348
  * // Automatically capture clicks, form submissions and change events
7270
7349
  * autocapture: true
7271
7350
  *
7272
- * // Capture rage clicks (beta) - useful for session recording
7273
- * rageclick: false
7351
+ * // Capture rage clicks
7352
+ * rageclick: true
7274
7353
  *
7275
7354
  * // transport for sending requests ('XHR' or 'sendBeacon')
7276
7355
  * // NB: sendBeacon should only be used for scenarios such as