instantsearch.js 4.38.0 → 4.38.1

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 CHANGED
@@ -1,3 +1,12 @@
1
+ ## [4.38.1](https://github.com/algolia/instantsearch.js/compare/v4.38.0...v4.38.1) (2022-02-08)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **routing:** fix history router based on history length ([#5004](https://github.com/algolia/instantsearch.js/issues/5004)) ([40541af](https://github.com/algolia/instantsearch.js/commit/40541af5c8face0e32a1ec3a4665a8387d89c626))
7
+ * **metadata:** ensure safe user agent detection ([#5009](https://github.com/algolia/instantsearch.js/pull/5009) [15a6a9d](https://github.com/algolia/instantsearch.js/commit/15a6a9d10ee512fab6884696bc59bedea13bd1b3))
8
+
9
+
1
10
  # [4.38.0](https://github.com/algolia/instantsearch.js/compare/v4.37.3...v4.38.0) (2022-01-28)
2
11
 
3
12
 
@@ -58,16 +58,23 @@ var BrowserHistory = /*#__PURE__*/function () {
58
58
 
59
59
  _defineProperty(this, "shouldPushState", true);
60
60
 
61
+ _defineProperty(this, "isDisposed", false);
62
+
63
+ _defineProperty(this, "latestAcknowledgedHistory", 0);
64
+
61
65
  this.windowTitle = windowTitle;
62
66
  this.writeTimer = undefined;
63
67
  this.writeDelay = writeDelay;
64
68
  this._createURL = createURL;
65
69
  this.parseURL = parseURL;
66
70
  this.getLocation = getLocation;
67
- (0, _index.safelyRunOnBrowser)(function () {
71
+ (0, _index.safelyRunOnBrowser)(function (_ref2) {
72
+ var window = _ref2.window;
73
+
68
74
  var title = _this.windowTitle && _this.windowTitle(_this.read());
69
75
 
70
76
  setWindowTitle(title);
77
+ _this.latestAcknowledgedHistory = window.history.length;
71
78
  });
72
79
  }
73
80
  /**
@@ -92,8 +99,8 @@ var BrowserHistory = /*#__PURE__*/function () {
92
99
  value: function write(routeState) {
93
100
  var _this2 = this;
94
101
 
95
- (0, _index.safelyRunOnBrowser)(function (_ref2) {
96
- var window = _ref2.window;
102
+ (0, _index.safelyRunOnBrowser)(function (_ref3) {
103
+ var window = _ref3.window;
97
104
 
98
105
  var url = _this2.createURL(routeState);
99
106
 
@@ -104,10 +111,17 @@ var BrowserHistory = /*#__PURE__*/function () {
104
111
  }
105
112
 
106
113
  _this2.writeTimer = setTimeout(function () {
107
- setWindowTitle(title);
114
+ setWindowTitle(title); // We do want to `pushState` if:
115
+ // - the router is not disposed, IS.js needs to update the URL
116
+ // OR
117
+ // - the last write was from InstantSearch.js
118
+ // (unlike a SPA, where it would have last written)
119
+
120
+ var lastPushWasByISAfterDispose = !_this2.isDisposed || _this2.latestAcknowledgedHistory === window.history.length;
108
121
 
109
- if (_this2.shouldPushState) {
122
+ if (_this2.shouldPushState && lastPushWasByISAfterDispose) {
110
123
  window.history.pushState(routeState, title || '', url);
124
+ _this2.latestAcknowledgedHistory = window.history.length;
111
125
  }
112
126
 
113
127
  _this2.shouldPushState = true;
@@ -143,8 +157,8 @@ var BrowserHistory = /*#__PURE__*/function () {
143
157
  }
144
158
  };
145
159
 
146
- (0, _index.safelyRunOnBrowser)(function (_ref3) {
147
- var window = _ref3.window;
160
+ (0, _index.safelyRunOnBrowser)(function (_ref4) {
161
+ var window = _ref4.window;
148
162
  window.addEventListener('popstate', _this3._onPopState);
149
163
  });
150
164
  }
@@ -174,8 +188,9 @@ var BrowserHistory = /*#__PURE__*/function () {
174
188
  value: function dispose() {
175
189
  var _this4 = this;
176
190
 
177
- (0, _index.safelyRunOnBrowser)(function (_ref4) {
178
- var window = _ref4.window;
191
+ this.isDisposed = true;
192
+ (0, _index.safelyRunOnBrowser)(function (_ref5) {
193
+ var window = _ref5.window;
179
194
 
180
195
  if (_this4._onPopState) {
181
196
  window.removeEventListener('popstate', _this4._onPopState);
@@ -194,12 +209,12 @@ var BrowserHistory = /*#__PURE__*/function () {
194
209
  }();
195
210
 
196
211
  function historyRouter() {
197
- var _ref5 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
198
- _ref5$createURL = _ref5.createURL,
199
- createURL = _ref5$createURL === void 0 ? function (_ref6) {
200
- var qsModule = _ref6.qsModule,
201
- routeState = _ref6.routeState,
202
- location = _ref6.location;
212
+ var _ref6 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
213
+ _ref6$createURL = _ref6.createURL,
214
+ createURL = _ref6$createURL === void 0 ? function (_ref7) {
215
+ var qsModule = _ref7.qsModule,
216
+ routeState = _ref7.routeState,
217
+ location = _ref7.location;
203
218
  var protocol = location.protocol,
204
219
  hostname = location.hostname,
205
220
  _location$port = location.port,
@@ -215,11 +230,11 @@ function historyRouter() {
215
230
  }
216
231
 
217
232
  return "".concat(protocol, "//").concat(hostname).concat(portWithPrefix).concat(pathname, "?").concat(queryString).concat(hash);
218
- } : _ref5$createURL,
219
- _ref5$parseURL = _ref5.parseURL,
220
- parseURL = _ref5$parseURL === void 0 ? function (_ref7) {
221
- var qsModule = _ref7.qsModule,
222
- location = _ref7.location;
233
+ } : _ref6$createURL,
234
+ _ref6$parseURL = _ref6.parseURL,
235
+ parseURL = _ref6$parseURL === void 0 ? function (_ref8) {
236
+ var qsModule = _ref8.qsModule,
237
+ location = _ref8.location;
223
238
  // `qs` by default converts arrays with more than 20 items to an object.
224
239
  // We want to avoid this because the data structure manipulated can therefore vary.
225
240
  // Setting the limit to `100` seems a good number because the engine's default is 100
@@ -233,21 +248,21 @@ function historyRouter() {
233
248
  return qsModule.parse(location.search.slice(1), {
234
249
  arrayLimit: 99
235
250
  });
236
- } : _ref5$parseURL,
237
- _ref5$writeDelay = _ref5.writeDelay,
238
- writeDelay = _ref5$writeDelay === void 0 ? 400 : _ref5$writeDelay,
239
- windowTitle = _ref5.windowTitle,
240
- _ref5$getLocation = _ref5.getLocation,
241
- getLocation = _ref5$getLocation === void 0 ? function () {
242
- return (0, _index.safelyRunOnBrowser)(function (_ref8) {
243
- var window = _ref8.window;
251
+ } : _ref6$parseURL,
252
+ _ref6$writeDelay = _ref6.writeDelay,
253
+ writeDelay = _ref6$writeDelay === void 0 ? 400 : _ref6$writeDelay,
254
+ windowTitle = _ref6.windowTitle,
255
+ _ref6$getLocation = _ref6.getLocation,
256
+ getLocation = _ref6$getLocation === void 0 ? function () {
257
+ return (0, _index.safelyRunOnBrowser)(function (_ref9) {
258
+ var window = _ref9.window;
244
259
  return window.location;
245
260
  }, {
246
261
  fallback: function fallback() {
247
262
  throw new Error('You need to provide `getLocation` to the `history` router in environments where `window` does not exist.');
248
263
  }
249
264
  });
250
- } : _ref5$getLocation;
265
+ } : _ref6$getLocation;
251
266
 
252
267
  return new BrowserHistory({
253
268
  createURL: createURL,
@@ -4,5 +4,5 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
- var _default = '4.38.0';
7
+ var _default = '4.38.1';
8
8
  exports.default = _default;
@@ -54,8 +54,10 @@ function extractPayload(widgets, instantSearchInstance, payload) {
54
54
 
55
55
  function isMetadataEnabled() {
56
56
  return (0, _index.safelyRunOnBrowser)(function (_ref) {
57
+ var _window$navigator, _window$navigator$use;
58
+
57
59
  var window = _ref.window;
58
- return window.navigator.userAgent.indexOf('Algolia Crawler') > -1;
60
+ return ((_window$navigator = window.navigator) === null || _window$navigator === void 0 ? void 0 : (_window$navigator$use = _window$navigator.userAgent) === null || _window$navigator$use === void 0 ? void 0 : _window$navigator$use.indexOf('Algolia Crawler')) > -1;
59
61
  }, {
60
62
  fallback: function fallback() {
61
63
  return false;
@@ -466,6 +466,17 @@ declare class BrowserHistory<TRouteState> implements Router<TRouteState> {
466
466
  * It needs to avoid pushing state to history in case of back/forward in browser
467
467
  */
468
468
  private shouldPushState;
469
+ /**
470
+ * Indicates whether the history router is disposed or not.
471
+ */
472
+ private isDisposed;
473
+ /**
474
+ * Indicates the window.history.length before the last call to
475
+ * window.history.pushState (called in `write`).
476
+ * It allows to determine if a `pushState` has been triggered elsewhere,
477
+ * and thus to prevent the `write` method from calling `pushState`.
478
+ */
479
+ private latestAcknowledgedHistory;
469
480
  /**
470
481
  * Initializes a new storage provider that syncs the search state to the URL
471
482
  * using web APIs (`window.location.pushState` and `onpopstate` event).
@@ -1,4 +1,4 @@
1
- /*! InstantSearch.js 4.38.0 | © Algolia, Inc. and contributors; MIT License | https://github.com/algolia/instantsearch.js */
1
+ /*! InstantSearch.js 4.38.1 | © Algolia, Inc. and contributors; MIT License | https://github.com/algolia/instantsearch.js */
2
2
  (function (global, factory) {
3
3
  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
4
4
  typeof define === 'function' && define.amd ? define(factory) :
@@ -8483,7 +8483,7 @@
8483
8483
  instantSearchInstance.renderState = _objectSpread2(_objectSpread2({}, instantSearchInstance.renderState), {}, _defineProperty({}, parentIndexName, _objectSpread2(_objectSpread2({}, instantSearchInstance.renderState[parentIndexName]), renderState)));
8484
8484
  }
8485
8485
 
8486
- var version$1 = '4.38.0';
8486
+ var version$1 = '4.38.1';
8487
8487
 
8488
8488
  var NAMESPACE = 'ais';
8489
8489
  var component = function component(componentName) {
@@ -9600,16 +9600,23 @@
9600
9600
 
9601
9601
  _defineProperty(this, "shouldPushState", true);
9602
9602
 
9603
+ _defineProperty(this, "isDisposed", false);
9604
+
9605
+ _defineProperty(this, "latestAcknowledgedHistory", 0);
9606
+
9603
9607
  this.windowTitle = windowTitle;
9604
9608
  this.writeTimer = undefined;
9605
9609
  this.writeDelay = writeDelay;
9606
9610
  this._createURL = createURL;
9607
9611
  this.parseURL = parseURL;
9608
9612
  this.getLocation = getLocation;
9609
- safelyRunOnBrowser(function () {
9613
+ safelyRunOnBrowser(function (_ref2) {
9614
+ var window = _ref2.window;
9615
+
9610
9616
  var title = _this.windowTitle && _this.windowTitle(_this.read());
9611
9617
 
9612
9618
  setWindowTitle(title);
9619
+ _this.latestAcknowledgedHistory = window.history.length;
9613
9620
  });
9614
9621
  }
9615
9622
  /**
@@ -9634,8 +9641,8 @@
9634
9641
  value: function write(routeState) {
9635
9642
  var _this2 = this;
9636
9643
 
9637
- safelyRunOnBrowser(function (_ref2) {
9638
- var window = _ref2.window;
9644
+ safelyRunOnBrowser(function (_ref3) {
9645
+ var window = _ref3.window;
9639
9646
 
9640
9647
  var url = _this2.createURL(routeState);
9641
9648
 
@@ -9646,10 +9653,17 @@
9646
9653
  }
9647
9654
 
9648
9655
  _this2.writeTimer = setTimeout(function () {
9649
- setWindowTitle(title);
9656
+ setWindowTitle(title); // We do want to `pushState` if:
9657
+ // - the router is not disposed, IS.js needs to update the URL
9658
+ // OR
9659
+ // - the last write was from InstantSearch.js
9660
+ // (unlike a SPA, where it would have last written)
9650
9661
 
9651
- if (_this2.shouldPushState) {
9662
+ var lastPushWasByISAfterDispose = !_this2.isDisposed || _this2.latestAcknowledgedHistory === window.history.length;
9663
+
9664
+ if (_this2.shouldPushState && lastPushWasByISAfterDispose) {
9652
9665
  window.history.pushState(routeState, title || '', url);
9666
+ _this2.latestAcknowledgedHistory = window.history.length;
9653
9667
  }
9654
9668
 
9655
9669
  _this2.shouldPushState = true;
@@ -9685,8 +9699,8 @@
9685
9699
  }
9686
9700
  };
9687
9701
 
9688
- safelyRunOnBrowser(function (_ref3) {
9689
- var window = _ref3.window;
9702
+ safelyRunOnBrowser(function (_ref4) {
9703
+ var window = _ref4.window;
9690
9704
  window.addEventListener('popstate', _this3._onPopState);
9691
9705
  });
9692
9706
  }
@@ -9716,8 +9730,9 @@
9716
9730
  value: function dispose() {
9717
9731
  var _this4 = this;
9718
9732
 
9719
- safelyRunOnBrowser(function (_ref4) {
9720
- var window = _ref4.window;
9733
+ this.isDisposed = true;
9734
+ safelyRunOnBrowser(function (_ref5) {
9735
+ var window = _ref5.window;
9721
9736
 
9722
9737
  if (_this4._onPopState) {
9723
9738
  window.removeEventListener('popstate', _this4._onPopState);
@@ -9736,12 +9751,12 @@
9736
9751
  }();
9737
9752
 
9738
9753
  function historyRouter() {
9739
- var _ref5 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
9740
- _ref5$createURL = _ref5.createURL,
9741
- createURL = _ref5$createURL === void 0 ? function (_ref6) {
9742
- var qsModule = _ref6.qsModule,
9743
- routeState = _ref6.routeState,
9744
- location = _ref6.location;
9754
+ var _ref6 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
9755
+ _ref6$createURL = _ref6.createURL,
9756
+ createURL = _ref6$createURL === void 0 ? function (_ref7) {
9757
+ var qsModule = _ref7.qsModule,
9758
+ routeState = _ref7.routeState,
9759
+ location = _ref7.location;
9745
9760
  var protocol = location.protocol,
9746
9761
  hostname = location.hostname,
9747
9762
  _location$port = location.port,
@@ -9757,11 +9772,11 @@
9757
9772
  }
9758
9773
 
9759
9774
  return "".concat(protocol, "//").concat(hostname).concat(portWithPrefix).concat(pathname, "?").concat(queryString).concat(hash);
9760
- } : _ref5$createURL,
9761
- _ref5$parseURL = _ref5.parseURL,
9762
- parseURL = _ref5$parseURL === void 0 ? function (_ref7) {
9763
- var qsModule = _ref7.qsModule,
9764
- location = _ref7.location;
9775
+ } : _ref6$createURL,
9776
+ _ref6$parseURL = _ref6.parseURL,
9777
+ parseURL = _ref6$parseURL === void 0 ? function (_ref8) {
9778
+ var qsModule = _ref8.qsModule,
9779
+ location = _ref8.location;
9765
9780
  // `qs` by default converts arrays with more than 20 items to an object.
9766
9781
  // We want to avoid this because the data structure manipulated can therefore vary.
9767
9782
  // Setting the limit to `100` seems a good number because the engine's default is 100
@@ -9775,21 +9790,21 @@
9775
9790
  return qsModule.parse(location.search.slice(1), {
9776
9791
  arrayLimit: 99
9777
9792
  });
9778
- } : _ref5$parseURL,
9779
- _ref5$writeDelay = _ref5.writeDelay,
9780
- writeDelay = _ref5$writeDelay === void 0 ? 400 : _ref5$writeDelay,
9781
- windowTitle = _ref5.windowTitle,
9782
- _ref5$getLocation = _ref5.getLocation,
9783
- getLocation = _ref5$getLocation === void 0 ? function () {
9784
- return safelyRunOnBrowser(function (_ref8) {
9785
- var window = _ref8.window;
9793
+ } : _ref6$parseURL,
9794
+ _ref6$writeDelay = _ref6.writeDelay,
9795
+ writeDelay = _ref6$writeDelay === void 0 ? 400 : _ref6$writeDelay,
9796
+ windowTitle = _ref6.windowTitle,
9797
+ _ref6$getLocation = _ref6.getLocation,
9798
+ getLocation = _ref6$getLocation === void 0 ? function () {
9799
+ return safelyRunOnBrowser(function (_ref9) {
9800
+ var window = _ref9.window;
9786
9801
  return window.location;
9787
9802
  }, {
9788
9803
  fallback: function fallback() {
9789
9804
  throw new Error('You need to provide `getLocation` to the `history` router in environments where `window` does not exist.');
9790
9805
  }
9791
9806
  });
9792
- } : _ref5$getLocation;
9807
+ } : _ref6$getLocation;
9793
9808
 
9794
9809
  return new BrowserHistory({
9795
9810
  createURL: createURL,
@@ -9891,8 +9906,10 @@
9891
9906
 
9892
9907
  function isMetadataEnabled() {
9893
9908
  return safelyRunOnBrowser(function (_ref) {
9909
+ var _window$navigator, _window$navigator$use;
9910
+
9894
9911
  var window = _ref.window;
9895
- return window.navigator.userAgent.indexOf('Algolia Crawler') > -1;
9912
+ return ((_window$navigator = window.navigator) === null || _window$navigator === void 0 ? void 0 : (_window$navigator$use = _window$navigator.userAgent) === null || _window$navigator$use === void 0 ? void 0 : _window$navigator$use.indexOf('Algolia Crawler')) > -1;
9896
9913
  }, {
9897
9914
  fallback: function fallback() {
9898
9915
  return false;