virtual-scroller 1.8.0 → 1.9.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.
Files changed (248) hide show
  1. package/.gitlab-ci.yml +1 -1
  2. package/CHANGELOG.md +57 -0
  3. package/README.md +337 -160
  4. package/bundle/virtual-scroller-dom.js +1 -1
  5. package/bundle/virtual-scroller-dom.js.map +1 -1
  6. package/bundle/virtual-scroller-react.js +1 -1
  7. package/bundle/virtual-scroller-react.js.map +1 -1
  8. package/bundle/virtual-scroller.js +1 -1
  9. package/bundle/virtual-scroller.js.map +1 -1
  10. package/commonjs/BeforeResize.js +23 -27
  11. package/commonjs/BeforeResize.js.map +1 -1
  12. package/commonjs/DOM/Engine.js +7 -7
  13. package/commonjs/DOM/Engine.js.map +1 -1
  14. package/commonjs/DOM/ItemsContainer.js +1 -1
  15. package/commonjs/DOM/ItemsContainer.js.map +1 -1
  16. package/commonjs/DOM/ListTopOffsetWatcher.js +15 -9
  17. package/commonjs/DOM/ListTopOffsetWatcher.js.map +1 -1
  18. package/commonjs/DOM/ScrollableContainer.js +28 -28
  19. package/commonjs/DOM/ScrollableContainer.js.map +1 -1
  20. package/commonjs/DOM/VirtualScroller.js +20 -17
  21. package/commonjs/DOM/VirtualScroller.js.map +1 -1
  22. package/commonjs/DOM/tbody.js +16 -10
  23. package/commonjs/DOM/tbody.js.map +1 -1
  24. package/commonjs/ItemHeights.js +23 -17
  25. package/commonjs/ItemHeights.js.map +1 -1
  26. package/commonjs/Layout.js +15 -13
  27. package/commonjs/Layout.js.map +1 -1
  28. package/commonjs/Layout.test.js +8 -3
  29. package/commonjs/Layout.test.js.map +1 -1
  30. package/commonjs/{ListHeightChangeWatcher.js → ListHeightMeasurement.js} +26 -28
  31. package/commonjs/ListHeightMeasurement.js.map +1 -0
  32. package/commonjs/Resize.js +38 -28
  33. package/commonjs/Resize.js.map +1 -1
  34. package/commonjs/Scroll.js +28 -44
  35. package/commonjs/Scroll.js.map +1 -1
  36. package/commonjs/VirtualScroller.columns.js +43 -0
  37. package/commonjs/VirtualScroller.columns.js.map +1 -0
  38. package/commonjs/VirtualScroller.constructor.js +408 -0
  39. package/commonjs/VirtualScroller.constructor.js.map +1 -0
  40. package/commonjs/VirtualScroller.items.js +305 -0
  41. package/commonjs/VirtualScroller.items.js.map +1 -0
  42. package/commonjs/VirtualScroller.js +132 -1872
  43. package/commonjs/VirtualScroller.js.map +1 -1
  44. package/commonjs/VirtualScroller.layout.js +562 -0
  45. package/commonjs/VirtualScroller.layout.js.map +1 -0
  46. package/commonjs/VirtualScroller.onRender.js +357 -0
  47. package/commonjs/VirtualScroller.onRender.js.map +1 -0
  48. package/commonjs/VirtualScroller.resize.js +186 -0
  49. package/commonjs/VirtualScroller.resize.js.map +1 -0
  50. package/commonjs/VirtualScroller.state.js +301 -0
  51. package/commonjs/VirtualScroller.state.js.map +1 -0
  52. package/commonjs/VirtualScroller.verticalSpacing.js +65 -0
  53. package/commonjs/VirtualScroller.verticalSpacing.js.map +1 -0
  54. package/commonjs/getItemCoordinates.js.map +1 -1
  55. package/commonjs/getItemsDiff.js.map +1 -1
  56. package/commonjs/getVerticalSpacing.js.map +1 -1
  57. package/commonjs/package.json +5 -0
  58. package/commonjs/react/VirtualScroller.js +184 -618
  59. package/commonjs/react/VirtualScroller.js.map +1 -1
  60. package/commonjs/react/useClassName.js +26 -0
  61. package/commonjs/react/useClassName.js.map +1 -0
  62. package/commonjs/react/useHandleItemsChange.js +116 -0
  63. package/commonjs/react/useHandleItemsChange.js.map +1 -0
  64. package/commonjs/react/useInstanceMethods.js +37 -0
  65. package/commonjs/react/useInstanceMethods.js.map +1 -0
  66. package/commonjs/react/useItemKeys.js +60 -0
  67. package/commonjs/react/useItemKeys.js.map +1 -0
  68. package/commonjs/react/useOnItemHeightChange.js +32 -0
  69. package/commonjs/react/useOnItemHeightChange.js.map +1 -0
  70. package/commonjs/react/useOnItemStateChange.js +32 -0
  71. package/commonjs/react/useOnItemStateChange.js.map +1 -0
  72. package/commonjs/react/useState.js +140 -0
  73. package/commonjs/react/useState.js.map +1 -0
  74. package/commonjs/react/useStyle.js +29 -0
  75. package/commonjs/react/useStyle.js.map +1 -0
  76. package/commonjs/react/useVirtualScroller.js +62 -0
  77. package/commonjs/react/useVirtualScroller.js.map +1 -0
  78. package/commonjs/react/useVirtualScrollerStartStop.js +20 -0
  79. package/commonjs/react/useVirtualScrollerStartStop.js.map +1 -0
  80. package/commonjs/test/Engine.js +23 -0
  81. package/commonjs/test/Engine.js.map +1 -0
  82. package/commonjs/test/ItemsContainer.js +127 -0
  83. package/commonjs/test/ItemsContainer.js.map +1 -0
  84. package/commonjs/test/ScrollableContainer.js +130 -0
  85. package/commonjs/test/ScrollableContainer.js.map +1 -0
  86. package/commonjs/test/VirtualScroller.js +281 -0
  87. package/commonjs/test/VirtualScroller.js.map +1 -0
  88. package/commonjs/utility/debounce.js +2 -2
  89. package/commonjs/utility/debounce.js.map +1 -1
  90. package/commonjs/utility/debug.js.map +1 -1
  91. package/commonjs/utility/getStateSnapshot.js +2 -2
  92. package/commonjs/utility/getStateSnapshot.js.map +1 -1
  93. package/commonjs/utility/px.js.map +1 -1
  94. package/commonjs/utility/px.test.js +1 -1
  95. package/commonjs/utility/px.test.js.map +1 -1
  96. package/commonjs/utility/shallowEqual.js +1 -1
  97. package/commonjs/utility/shallowEqual.js.map +1 -1
  98. package/commonjs/utility/throttle.js.map +1 -1
  99. package/dom/index.cjs +4 -0
  100. package/dom/index.cjs.js +9 -0
  101. package/dom/index.d.ts +6 -4
  102. package/dom/index.js +1 -1
  103. package/dom/package.json +10 -4
  104. package/index.cjs +4 -0
  105. package/index.cjs.js +9 -0
  106. package/index.d.ts +30 -15
  107. package/index.js +1 -1
  108. package/modules/BeforeResize.js +22 -27
  109. package/modules/BeforeResize.js.map +1 -1
  110. package/modules/DOM/Engine.js +6 -6
  111. package/modules/DOM/Engine.js.map +1 -1
  112. package/modules/DOM/ItemsContainer.js +1 -1
  113. package/modules/DOM/ItemsContainer.js.map +1 -1
  114. package/modules/DOM/ListTopOffsetWatcher.js +15 -9
  115. package/modules/DOM/ListTopOffsetWatcher.js.map +1 -1
  116. package/modules/DOM/ScrollableContainer.js +28 -28
  117. package/modules/DOM/ScrollableContainer.js.map +1 -1
  118. package/modules/DOM/VirtualScroller.js +19 -16
  119. package/modules/DOM/VirtualScroller.js.map +1 -1
  120. package/modules/DOM/tbody.js +11 -9
  121. package/modules/DOM/tbody.js.map +1 -1
  122. package/modules/ItemHeights.js +22 -16
  123. package/modules/ItemHeights.js.map +1 -1
  124. package/modules/Layout.js +14 -12
  125. package/modules/Layout.js.map +1 -1
  126. package/modules/Layout.test.js +8 -3
  127. package/modules/Layout.test.js.map +1 -1
  128. package/modules/{ListHeightChangeWatcher.js → ListHeightMeasurement.js} +25 -27
  129. package/modules/ListHeightMeasurement.js.map +1 -0
  130. package/modules/Resize.js +38 -28
  131. package/modules/Resize.js.map +1 -1
  132. package/modules/Scroll.js +28 -44
  133. package/modules/Scroll.js.map +1 -1
  134. package/modules/VirtualScroller.columns.js +36 -0
  135. package/modules/VirtualScroller.columns.js.map +1 -0
  136. package/modules/VirtualScroller.constructor.js +371 -0
  137. package/modules/VirtualScroller.constructor.js.map +1 -0
  138. package/modules/VirtualScroller.items.js +288 -0
  139. package/modules/VirtualScroller.items.js.map +1 -0
  140. package/modules/VirtualScroller.js +132 -1860
  141. package/modules/VirtualScroller.js.map +1 -1
  142. package/modules/VirtualScroller.layout.js +549 -0
  143. package/modules/VirtualScroller.layout.js.map +1 -0
  144. package/modules/VirtualScroller.onRender.js +337 -0
  145. package/modules/VirtualScroller.onRender.js.map +1 -0
  146. package/modules/VirtualScroller.resize.js +176 -0
  147. package/modules/VirtualScroller.resize.js.map +1 -0
  148. package/modules/VirtualScroller.state.js +283 -0
  149. package/modules/VirtualScroller.state.js.map +1 -0
  150. package/modules/VirtualScroller.verticalSpacing.js +54 -0
  151. package/modules/VirtualScroller.verticalSpacing.js.map +1 -0
  152. package/modules/getItemCoordinates.js.map +1 -1
  153. package/modules/getItemsDiff.js.map +1 -1
  154. package/modules/getVerticalSpacing.js.map +1 -1
  155. package/modules/react/VirtualScroller.js +176 -625
  156. package/modules/react/VirtualScroller.js.map +1 -1
  157. package/modules/react/useClassName.js +18 -0
  158. package/modules/react/useClassName.js.map +1 -0
  159. package/modules/react/useHandleItemsChange.js +108 -0
  160. package/modules/react/useHandleItemsChange.js.map +1 -0
  161. package/modules/react/useInstanceMethods.js +28 -0
  162. package/modules/react/useInstanceMethods.js.map +1 -0
  163. package/modules/react/useItemKeys.js +52 -0
  164. package/modules/react/useItemKeys.js.map +1 -0
  165. package/modules/react/useOnItemHeightChange.js +24 -0
  166. package/modules/react/useOnItemHeightChange.js.map +1 -0
  167. package/modules/react/useOnItemStateChange.js +24 -0
  168. package/modules/react/useOnItemStateChange.js.map +1 -0
  169. package/modules/react/useState.js +132 -0
  170. package/modules/react/useState.js.map +1 -0
  171. package/modules/react/useStyle.js +19 -0
  172. package/modules/react/useStyle.js.map +1 -0
  173. package/modules/react/useVirtualScroller.js +51 -0
  174. package/modules/react/useVirtualScroller.js.map +1 -0
  175. package/modules/react/useVirtualScrollerStartStop.js +12 -0
  176. package/modules/react/useVirtualScrollerStartStop.js.map +1 -0
  177. package/modules/test/Engine.js +11 -0
  178. package/modules/test/Engine.js.map +1 -0
  179. package/modules/test/ItemsContainer.js +120 -0
  180. package/modules/test/ItemsContainer.js.map +1 -0
  181. package/modules/test/ScrollableContainer.js +123 -0
  182. package/modules/test/ScrollableContainer.js.map +1 -0
  183. package/modules/test/VirtualScroller.js +270 -0
  184. package/modules/test/VirtualScroller.js.map +1 -0
  185. package/modules/utility/debounce.js +2 -2
  186. package/modules/utility/debounce.js.map +1 -1
  187. package/modules/utility/debug.js.map +1 -1
  188. package/modules/utility/getStateSnapshot.js +2 -2
  189. package/modules/utility/getStateSnapshot.js.map +1 -1
  190. package/modules/utility/px.js.map +1 -1
  191. package/modules/utility/px.test.js +1 -1
  192. package/modules/utility/px.test.js.map +1 -1
  193. package/modules/utility/shallowEqual.js +1 -1
  194. package/modules/utility/shallowEqual.js.map +1 -1
  195. package/modules/utility/throttle.js.map +1 -1
  196. package/package.json +46 -23
  197. package/react/index.cjs +4 -0
  198. package/react/index.cjs.js +9 -0
  199. package/react/index.d.ts +10 -9
  200. package/react/index.js +1 -1
  201. package/react/package.json +10 -4
  202. package/rollup.config.mjs +62 -0
  203. package/runnable/create-commonjs-package-json.js +11 -0
  204. package/source/BeforeResize.js +16 -21
  205. package/source/DOM/Engine.js +8 -10
  206. package/source/DOM/ListTopOffsetWatcher.js +13 -8
  207. package/source/DOM/ScrollableContainer.js +23 -21
  208. package/source/DOM/VirtualScroller.js +27 -11
  209. package/source/DOM/tbody.js +30 -21
  210. package/source/ItemHeights.js +19 -14
  211. package/source/Layout.js +12 -9
  212. package/source/Layout.test.js +8 -3
  213. package/source/{ListHeightChangeWatcher.js → ListHeightMeasurement.js} +21 -20
  214. package/source/Resize.js +41 -25
  215. package/source/Scroll.js +27 -35
  216. package/source/VirtualScroller.columns.js +26 -0
  217. package/source/VirtualScroller.constructor.js +336 -0
  218. package/source/VirtualScroller.items.js +302 -0
  219. package/source/VirtualScroller.js +144 -1872
  220. package/source/VirtualScroller.layout.js +539 -0
  221. package/source/VirtualScroller.onRender.js +345 -0
  222. package/source/VirtualScroller.resize.js +189 -0
  223. package/source/VirtualScroller.state.js +284 -0
  224. package/source/VirtualScroller.verticalSpacing.js +51 -0
  225. package/source/react/VirtualScroller.js +243 -587
  226. package/source/react/useClassName.js +14 -0
  227. package/source/react/useHandleItemsChange.js +115 -0
  228. package/source/react/useInstanceMethods.js +25 -0
  229. package/source/react/useItemKeys.js +59 -0
  230. package/source/react/useOnItemHeightChange.js +28 -0
  231. package/source/react/useOnItemStateChange.js +28 -0
  232. package/source/react/useState.js +114 -0
  233. package/source/react/useStyle.js +20 -0
  234. package/source/react/useVirtualScroller.js +59 -0
  235. package/source/react/useVirtualScrollerStartStop.js +12 -0
  236. package/source/test/Engine.js +11 -0
  237. package/source/test/ItemsContainer.js +87 -0
  238. package/source/test/ScrollableContainer.js +88 -0
  239. package/source/test/VirtualScroller.js +232 -0
  240. package/source/utility/debounce.js +2 -2
  241. package/source/utility/px.test.js +1 -1
  242. package/babel.config.js +0 -25
  243. package/babel.js +0 -5
  244. package/commonjs/ListHeightChangeWatcher.js.map +0 -1
  245. package/dom/index.commonjs.js +0 -4
  246. package/index.commonjs.js +0 -4
  247. package/modules/ListHeightChangeWatcher.js.map +0 -1
  248. package/react/index.commonjs.js +0 -4
@@ -3,15 +3,16 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ exports.cleanUpBeforeResizeState = cleanUpBeforeResizeState;
6
7
  exports["default"] = void 0;
7
8
 
8
- var _debug = _interopRequireDefault(require("./utility/debug"));
9
+ var _debug = _interopRequireDefault(require("./utility/debug.js"));
9
10
 
10
11
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
11
12
 
12
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
13
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
13
14
 
14
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
15
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
15
16
 
16
17
  function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
17
18
 
@@ -19,7 +20,7 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
19
20
 
20
21
  function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
21
22
 
22
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
23
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
23
24
 
24
25
  var BeforeResize = /*#__PURE__*/function () {
25
26
  function BeforeResize(_ref) {
@@ -32,27 +33,12 @@ var BeforeResize = /*#__PURE__*/function () {
32
33
  this.getState = getState;
33
34
  this.getVerticalSpacing = getVerticalSpacing;
34
35
  this.getColumnsCount = getColumnsCount;
35
- } // Possibly clean up "before resize" property in state.
36
- // "Before resize" state property is cleaned up when all "before resize" item heights
37
- // have been re-measured in an asynchronous `this.setState({ beforeResize: undefined })` call.
38
- // If `VirtualScroller` state was snapshotted externally before that `this.setState()` call
39
- // has been applied, then "before resize" property might have not been cleaned up properly.
40
-
36
+ }
41
37
 
42
38
  _createClass(BeforeResize, [{
43
- key: "onInitialState",
44
- value: function onInitialState(state) {
45
- if (state) {
46
- if (state.beforeResize) {
47
- if (state.beforeResize.itemHeights.length === 0) {
48
- state.beforeResize = undefined;
49
- }
50
- }
51
-
52
- if (state.beforeResize) {
53
- this._includesBeforeResizeInState = true;
54
- }
55
- }
39
+ key: "initializeFromState",
40
+ value: function initializeFromState(state) {
41
+ this._includesBeforeResizeInState = Boolean(state.beforeResize);
56
42
  } // Cleans up "before resize" item heights and adjusts the scroll position accordingly.
57
43
  //
58
44
  // Hypothetically, it could also wait for the user to stop scrolling and only then
@@ -72,7 +58,7 @@ var BeforeResize = /*#__PURE__*/function () {
72
58
 
73
59
  }, {
74
60
  key: "cleanUpBeforeResizeItemHeights",
75
- value: function cleanUpBeforeResizeItemHeights(prevState) {
61
+ value: function cleanUpBeforeResizeItemHeights() {
76
62
  var _this$getState = this.getState(),
77
63
  firstShownItemIndex = _this$getState.firstShownItemIndex,
78
64
  lastShownItemIndex = _this$getState.lastShownItemIndex,
@@ -155,9 +141,9 @@ var BeforeResize = /*#__PURE__*/function () {
155
141
  cleanedUpBeforeResizeItemRowsHeight += _rowHeight;
156
142
  cleanedUpBeforeResizeItemRowsHeight += beforeResize.verticalSpacing;
157
143
  k++;
158
- } // Schedule an asynchronous `this.setState()` call that will update
144
+ } // Schedule an asynchronous `this.updateState()` call that will update
159
145
  // `beforeResize` property of `state`. Ideally, it should be updated
160
- // immediately, but since `this.setState()` calls are asynchronous,
146
+ // immediately, but since `this.updateState()` calls are asynchronous,
161
147
  // the code updates just the underlying `beforeResize.itemHeights`
162
148
  // array immediately instead, which is still a hack but still a lesser one.
163
149
 
@@ -175,7 +161,7 @@ var BeforeResize = /*#__PURE__*/function () {
175
161
  }
176
162
  } // Immediately update `beforeResize.itemHeights`
177
163
  // so that the component isn't left in an inconsistent state
178
- // before a `this.setState()` call below is applied.
164
+ // before a `this.updateState()` call below is applied.
179
165
 
180
166
 
181
167
  beforeResize.itemHeights.splice(firstShownItemIndex, beforeResize.itemHeights.length - firstShownItemIndex); // Return the "scroll by" amount that would correct the scroll position.
@@ -316,4 +302,14 @@ function equalizeItemHeights(itemHeights, maxItemsCount, columnsCount) {
316
302
 
317
303
  return itemHeights.slice(0, maxItemsCount);
318
304
  }
305
+
306
+ function cleanUpBeforeResizeState(state) {
307
+ if (state.beforeResize) {
308
+ if (state.beforeResize.itemHeights.length === 0) {
309
+ state.beforeResize = undefined;
310
+ }
311
+ }
312
+
313
+ return state;
314
+ }
319
315
  //# sourceMappingURL=BeforeResize.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../source/BeforeResize.js"],"names":["BeforeResize","getState","getVerticalSpacing","getColumnsCount","state","beforeResize","itemHeights","length","undefined","_includesBeforeResizeInState","prevState","firstShownItemIndex","lastShownItemIndex","newlyShownItemRowsHeight","prevFirstReMeasuredItemsRowIndex","Math","floor","newlyShownItemsToIndex","min","i","rowHeight","columnIndex","itemHeight","getAverageItemHeight","max","cleanedUpBeforeResizeItemRowsHeight","maxParticipatingBeforeResizeItemsCount","participatingBeforeResizeItemRowsCount","ceil","columnsCount","firstCleanedUpBeforeResizeItemsRowIndex","k","verticalSpacing","firstDroppedBeforeResizeItemIndex","lastDroppedBeforeResizeItemIndex","slice","splice","scrollBy","newFirstShownItemIndex","newColumnsCount","prevBeforeResize","prevBeforeResizeItemsCount","prevBeforeResizeBeforeItemsHeight","prevBeforeResizeItemRowsCount","rowIndex","newBeforeResizeAdditionalBeforeItemsHeight","newBeforeResizeBeforeItemsHeight","newBeforeResizeBeforeItemRowsCount","Array","fill","concat","equalizeItemHeights","maxItemsCount"],"mappings":"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","sourcesContent":["import log from './utility/debug'\r\n\r\nexport default class BeforeResize {\r\n\tconstructor({\r\n\t\tgetState,\r\n\t\tgetVerticalSpacing,\r\n\t\tgetColumnsCount\r\n\t}) {\r\n\t\tthis.getState = getState\r\n\t\tthis.getVerticalSpacing = getVerticalSpacing\r\n\t\tthis.getColumnsCount = getColumnsCount\r\n\t}\r\n\r\n\t// Possibly clean up \"before resize\" property in state.\r\n\t// \"Before resize\" state property is cleaned up when all \"before resize\" item heights\r\n\t// have been re-measured in an asynchronous `this.setState({ beforeResize: undefined })` call.\r\n\t// If `VirtualScroller` state was snapshotted externally before that `this.setState()` call\r\n\t// has been applied, then \"before resize\" property might have not been cleaned up properly.\r\n\tonInitialState(state) {\r\n\t\tif (state) {\r\n\t\t\tif (state.beforeResize) {\r\n\t\t\t\tif (state.beforeResize.itemHeights.length === 0) {\r\n\t\t\t\t\tstate.beforeResize = undefined\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tif (state.beforeResize) {\r\n\t\t\t\tthis._includesBeforeResizeInState = true\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t// Cleans up \"before resize\" item heights and adjusts the scroll position accordingly.\r\n\t//\r\n\t// Hypothetically, it could also wait for the user to stop scrolling and only then\r\n\t// adjust the scroll position. The rationale is that if `window.scrollTo()` is called\r\n\t// while the user is scrolling, the user would occasionally experience \"lost\" mouse wheel\r\n\t// events when scrolling with a mouse wheel.\r\n\t//\r\n\t// Seems like Twitter's website waits for the user to stop scrolling before applying\r\n\t// the scroll position correction after a window resize. This library could do that too,\r\n\t// but that would require rewriting \"before items height\" top padding calculation\r\n\t// so that it doesn't re-calculate it on every re-render and instead does so incrementally,\r\n\t// and then, when the user stops, it re-calculates it from scratch removing the error\r\n\t// and adjusting the scroll position accordingly so that there's no \"jump of content\".\r\n\t//\r\n\t// But, seems like it works fine as it is and there's no need to rewrite anything.\r\n\t//\r\n\tcleanUpBeforeResizeItemHeights(prevState) {\r\n\t\tconst {\r\n\t\t\tfirstShownItemIndex,\r\n\t\t\tlastShownItemIndex,\r\n\t\t\titemHeights,\r\n\t\t\tbeforeResize\r\n\t\t} = this.getState()\r\n\r\n\t\t// If there're \"before resize\" properties in `state`\r\n\t\t// then it means that the corresponding items are waiting to be\r\n\t\t// re-measured after container resize. Since the resize,\r\n\t\t// some of those non-re-measured items might have just been measured,\r\n\t\t// so see if that's true, and if it is, remove those now-obsolete\r\n\t\t// \"before resize\" item heights and ajust the scroll position\r\n\t\t// so that there's no \"content jumping\".\r\n\r\n\t\tif (beforeResize) {\r\n\t\t\t// If the user has scrolled up to reveal a previously hidden item\r\n\t\t\t// that has not yet been re-measured after a previous resize.\r\n\t\t\tif (firstShownItemIndex < beforeResize.itemHeights.length) {\r\n\t\t\t\tlog('~ Clean up \"before resize\" item heights and correct scroll position ~')\r\n\r\n\t\t\t\t// Some of the \"before\" items have been un-hidden and re-measured.\r\n\t\t\t\t// Un-hiding those items would result in a \"jump of content\"\r\n\t\t\t\t// because \"before resize\" heights of those un-hidden items\r\n\t\t\t\t// could (and most likely will) be different from the current ones,\r\n\t\t\t\t// or because \"before resize\" columns count is different from\r\n\t\t\t\t// the current one.\r\n\t\t\t\t// To prevent a \"jump of content\", calculate the scroll position\r\n\t\t\t\t// difference and adjust the scroll position.\r\n\r\n\t\t\t\t// The height of the item rows that have transitioned\r\n\t\t\t\t// from hidden to shown.\r\n\t\t\t\tlet newlyShownItemRowsHeight = 0\r\n\r\n\t\t\t\t// Some of the `itemHeights` between the current `firstShownItemIndex` and\r\n\t\t\t\t// the previous `firstShownItemIndex` could stay `undefined` if the user\r\n\t\t\t\t// scrolled \"abruptly\": for example, by using a `window.scrollTo()` call.\r\n\t\t\t\t// In that case, the items below the visible ones won't be rendered and measured.\r\n\t\t\t\t// In such case, limit the items being iterated over to the current `lastShownItemIndex`\r\n\t\t\t\t// rather than the previous `firstShownItemIndex`.\r\n\t\t\t\tconst prevFirstReMeasuredItemsRowIndex = Math.floor(beforeResize.itemHeights.length / this.getColumnsCount())\r\n\t\t\t\tconst newlyShownItemsToIndex = Math.min(\r\n\t\t\t\t\tprevFirstReMeasuredItemsRowIndex * this.getColumnsCount() - 1,\r\n\t\t\t\t\tlastShownItemIndex\r\n\t\t\t\t)\r\n\r\n\t\t\t\tlet i = firstShownItemIndex\r\n\t\t\t\twhile (i <= newlyShownItemsToIndex) {\r\n\t\t\t\t\t// Calculate newly shown row height.\r\n\t\t\t\t\tlet rowHeight = 0\r\n\t\t\t\t\tlet columnIndex = 0\r\n\t\t\t\t\twhile (columnIndex < this.getColumnsCount() && i <= newlyShownItemsToIndex) {\r\n\t\t\t\t\t\tlet itemHeight = itemHeights[i]\r\n\t\t\t\t\t\tif (itemHeight === undefined) {\r\n\t\t\t\t\t\t\t// `itemHeight` can only be `undefined` when not `beforeResize`.\r\n\t\t\t\t\t\t\t// Use the current \"average item height\" as a substitute.\r\n\t\t\t\t\t\t\titemHeight = this.getAverageItemHeight()\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\trowHeight = Math.max(rowHeight, itemHeight)\r\n\t\t\t\t\t\ti++\r\n\t\t\t\t\t\tcolumnIndex++\r\n\t\t\t\t\t}\r\n\t\t\t\t\t// Append to the total \"newly shown item rows height\".\r\n\t\t\t\t\tnewlyShownItemRowsHeight += rowHeight\r\n\t\t\t\t\tnewlyShownItemRowsHeight += this.getVerticalSpacing()\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// The height of the \"before resize\" item rows\r\n\t\t\t\t// that will be \"cleaned up\" in this function call.\r\n\t\t\t\tlet cleanedUpBeforeResizeItemRowsHeight = 0\r\n\r\n\t\t\t\t// Some of the `beforeResize` item rows might have been skipped if the user\r\n\t\t\t\t// scrolled up \"abruptly\": for example, by using a `window.scrollTo()` call.\r\n\t\t\t\t// In that case, the \"before resize\" items below the bottom border of the screen\r\n\t\t\t\t// shouldn't be accounted for when calculating the scrollbar adjustment shift\r\n\t\t\t\t// because items after `lastShownItemIndex` aren't participating in the calculation\r\n\t\t\t\t// of `newlyShownItemRowsHeight`.\r\n\t\t\t\tconst maxParticipatingBeforeResizeItemsCount = Math.min(beforeResize.itemHeights.length, lastShownItemIndex + 1)\r\n\t\t\t\tconst participatingBeforeResizeItemRowsCount = Math.ceil(maxParticipatingBeforeResizeItemsCount / beforeResize.columnsCount)\r\n\r\n\t\t\t\tconst firstCleanedUpBeforeResizeItemsRowIndex = firstShownItemIndex === 0\r\n\t\t\t\t\t? 0\r\n\t\t\t\t\t: Math.floor((firstShownItemIndex - 1) / beforeResize.columnsCount) + 1\r\n\r\n\t\t\t\tlet k = firstCleanedUpBeforeResizeItemsRowIndex\r\n\t\t\t\twhile (k < participatingBeforeResizeItemRowsCount) {\r\n\t\t\t\t\tconst rowHeight = beforeResize.itemHeights[k * beforeResize.columnsCount]\r\n\t\t\t\t\tcleanedUpBeforeResizeItemRowsHeight += rowHeight\r\n\t\t\t\t\tcleanedUpBeforeResizeItemRowsHeight += beforeResize.verticalSpacing\r\n\t\t\t\t\tk++\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Schedule an asynchronous `this.setState()` call that will update\r\n\t\t\t\t// `beforeResize` property of `state`. Ideally, it should be updated\r\n\t\t\t\t// immediately, but since `this.setState()` calls are asynchronous,\r\n\t\t\t\t// the code updates just the underlying `beforeResize.itemHeights`\r\n\t\t\t\t// array immediately instead, which is still a hack but still a lesser one.\r\n\t\t\t\tif (firstShownItemIndex === 0) {\r\n\t\t\t\t\tlog('Drop all \"before resize\" item heights')\r\n\t\t\t\t} else {\r\n\t\t\t\t\tconst firstDroppedBeforeResizeItemIndex = firstShownItemIndex\r\n\t\t\t\t\tconst lastDroppedBeforeResizeItemIndex = beforeResize.itemHeights.length - 1\r\n\t\t\t\t\tif (firstDroppedBeforeResizeItemIndex === lastDroppedBeforeResizeItemIndex) {\r\n\t\t\t\t\t\tlog('For item index', firstDroppedBeforeResizeItemIndex, '— drop \"before resize\" height', beforeResize.itemHeights[firstDroppedBeforeResizeItemIndex], )\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tlog('For item indexes from', firstDroppedBeforeResizeItemIndex, 'to', lastDroppedBeforeResizeItemIndex, '— drop \"before resize\" heights', beforeResize.itemHeights.slice(firstDroppedBeforeResizeItemIndex))\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Immediately update `beforeResize.itemHeights`\r\n\t\t\t\t// so that the component isn't left in an inconsistent state\r\n\t\t\t\t// before a `this.setState()` call below is applied.\r\n\t\t\t\tbeforeResize.itemHeights.splice(\r\n\t\t\t\t\tfirstShownItemIndex,\r\n\t\t\t\t\tbeforeResize.itemHeights.length - firstShownItemIndex\r\n\t\t\t\t)\r\n\r\n\t\t\t\t// Return the \"scroll by\" amount that would correct the scroll position.\r\n\t\t\t\t// Also return a state update.\r\n\t\t\t\treturn {\r\n\t\t\t\t\tscrollBy: newlyShownItemRowsHeight - cleanedUpBeforeResizeItemRowsHeight,\r\n\t\t\t\t\tbeforeResize: firstShownItemIndex === 0 ? undefined : {\r\n\t\t\t\t\t\t// Simply change the \"reference\" to `beforeResize` while leaving\r\n\t\t\t\t\t\t// its contents unchanged. That simply indicates that it has been updated:\r\n\t\t\t\t\t\t// `beforeResize.itemHeights` array length has been changed \"directly\".\r\n\t\t\t\t\t\t...beforeResize\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t// Snapshots \"before resize\" values in order to preserve the currently\r\n\t// shown items' vertical position on screen so that there's no \"content jumping\".\r\n\t//\r\n\t// `newFirstShownItemIndex` is `> 0`.\r\n\t//\r\n\tsnapshotBeforeResizeItemHeights({\r\n\t\tfirstShownItemIndex,\r\n\t\tnewFirstShownItemIndex,\r\n\t\tnewColumnsCount\r\n\t}) {\r\n\t\tconst columnsCount = this.getColumnsCount()\r\n\t\tconst verticalSpacing = this.getVerticalSpacing()\r\n\r\n\t\tthis._includesBeforeResizeInState = true\r\n\r\n\t\tconst {\r\n\t\t\tbeforeResize: prevBeforeResize,\r\n\t\t\titemHeights\r\n\t\t} = this.getState()\r\n\r\n\t\tconst prevBeforeResizeItemsCount = prevBeforeResize\r\n\t\t\t? prevBeforeResize.itemHeights.length\r\n\t\t\t: 0\r\n\r\n\t\t// If there already are \"before resize\" values in `state`\r\n\t\t// then it means that those should be merged with the new ones.\r\n\t\t//\r\n\t\t// `beforeResize.itemHeights` could be empty in an edge case\r\n\t\t// when there's a pending state update that sets `beforeResize`\r\n\t\t// to `undefined`, and in that case empty `beforeResize.itemHeights`\r\n\t\t// signals about that type of a situation.\r\n\t\t//\r\n\t\tif (prevBeforeResizeItemsCount > 0) {\r\n\t\t\t// Because the \"previous\" before resize values might have been captured\r\n\t\t\t// for a window width corresponding to a layout with a different columns count\r\n\t\t\t// and different vertical spacing, re-calculate those item heights as if\r\n\t\t\t// they corresponded to the current columns count and current vertical spacing,\r\n\t\t\t// since \"previous\" and \"new\" before resize item heights are gonna be merged.\r\n\t\t\tif (\r\n\t\t\t\tprevBeforeResize.columnsCount !== columnsCount ||\r\n\t\t\t\tprevBeforeResize.verticalSpacing !== verticalSpacing\r\n\t\t\t) {\r\n\t\t\t\tlet prevBeforeResizeBeforeItemsHeight = 0\r\n\r\n\t\t\t\tconst prevBeforeResizeItemRowsCount = Math.ceil(prevBeforeResizeItemsCount / prevBeforeResize.columnsCount)\r\n\t\t\t\tlet rowIndex = 0\r\n\t\t\t\twhile (rowIndex < prevBeforeResizeItemRowsCount) {\r\n\t\t\t\t\t// Since all \"before resize\" item heights are equal within a row,\r\n\t\t\t\t\t// the height of the first \"before resize\" item in a row is that row's height.\r\n\t\t\t\t\tconst rowHeight = prevBeforeResize.itemHeights[rowIndex * prevBeforeResize.columnsCount]\r\n\t\t\t\t\tprevBeforeResizeBeforeItemsHeight += rowHeight\r\n\t\t\t\t\tprevBeforeResizeBeforeItemsHeight += prevBeforeResize.verticalSpacing\r\n\t\t\t\t\trowIndex++\r\n\t\t\t\t}\r\n\r\n\t\t\t\tlet newBeforeResizeAdditionalBeforeItemsHeight = 0\r\n\t\t\t\tlet i = firstShownItemIndex\r\n\t\t\t\twhile (i < newFirstShownItemIndex) {\r\n\t\t\t\t\tlet rowHeight = 0\r\n\t\t\t\t\tlet k = 0\r\n\t\t\t\t\twhile (k < columnsCount && i < newFirstShownItemIndex) {\r\n\t\t\t\t\t\trowHeight = Math.max(rowHeight, itemHeights[i])\r\n\t\t\t\t\t\tk++\r\n\t\t\t\t\t\ti++\r\n\t\t\t\t\t}\r\n\t\t\t\t\tnewBeforeResizeAdditionalBeforeItemsHeight += rowHeight\r\n\t\t\t\t\tnewBeforeResizeAdditionalBeforeItemsHeight += verticalSpacing\r\n\t\t\t\t}\r\n\r\n\t\t\t\tconst newBeforeResizeBeforeItemsHeight = prevBeforeResizeBeforeItemsHeight + newBeforeResizeAdditionalBeforeItemsHeight\r\n\t\t\t\tconst newBeforeResizeBeforeItemRowsCount = Math.ceil(newFirstShownItemIndex / columnsCount)\r\n\r\n\t\t\t\treturn new Array(newFirstShownItemIndex).fill(\r\n\t\t\t\t\t// Re-calculate \"before resize\" item heights so that \"previous\" and \"new\" ones\r\n\t\t\t\t\t// correspond to the same (new) columns count.\r\n\t\t\t\t\t// Also don't occasionally set item heights to `< 0`.\r\n\t\t\t\t\tMath.max(0, newBeforeResizeBeforeItemsHeight / newBeforeResizeBeforeItemRowsCount - verticalSpacing)\r\n\t\t\t\t)\r\n\t\t\t} else {\r\n\t\t\t\t// Add new item heights to the previously snapshotted ones.\r\n\t\t\t\treturn prevBeforeResize.itemHeights.concat(\r\n\t\t\t\t\tequalizeItemHeights(\r\n\t\t\t\t\t\titemHeights,\r\n\t\t\t\t\t\tnewFirstShownItemIndex,\r\n\t\t\t\t\t\tcolumnsCount\r\n\t\t\t\t\t).slice(prevBeforeResize.itemHeights.length)\r\n\t\t\t\t)\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\treturn equalizeItemHeights(\r\n\t\t\t\titemHeights,\r\n\t\t\t\tnewFirstShownItemIndex,\r\n\t\t\t\tcolumnsCount\r\n\t\t\t)\r\n\t\t}\r\n\t}\r\n\r\n\tshouldIncludeBeforeResizeValuesInState() {\r\n\t\treturn this._includesBeforeResizeInState\r\n\t}\r\n}\r\n\r\n// Equalizes all item heights within a given row, for each row.\r\n//\r\n// The reason is that `beforeResize.itemHeights` is not necessarily divisible by\r\n// `beforeResize.columnsCount`, which would result in varying last row height\r\n// as items get removed from `beforeResize.itemHeights` as the user scrolls up.\r\n//\r\n// By equalizing all item heights within a given row, for each row, such \"jumping\"\r\n// last \"before resize\" row height is prevented when the user scrolls up.\r\n//\r\nfunction equalizeItemHeights(itemHeights, maxItemsCount, columnsCount) {\r\n\titemHeights = itemHeights.slice(0, Math.ceil(maxItemsCount / columnsCount) * columnsCount)\r\n\r\n\tlet rowIndex = 0\r\n\twhile (rowIndex * columnsCount < maxItemsCount) {\r\n\t\t// Calculate row height.\r\n\t\tlet rowHeight = 0\r\n\t\tlet k = 0\r\n\t\twhile (k < columnsCount) {\r\n\t\t\trowHeight = Math.max(rowHeight, itemHeights[rowIndex * columnsCount + k])\r\n\t\t\tk++\r\n\t\t}\r\n\r\n\t\t// Equalize all item heights within the row.\r\n\t\tk = 0\r\n\t\twhile (k < columnsCount) {\r\n\t\t\titemHeights[rowIndex * columnsCount + k] = rowHeight\r\n\t\t\tk++\r\n\t\t}\r\n\r\n\t\t// Proceed with the next row.\r\n\t\trowIndex++\r\n\t}\r\n\r\n\treturn itemHeights.slice(0, maxItemsCount)\r\n}"],"file":"BeforeResize.js"}
1
+ {"version":3,"file":"BeforeResize.js","names":["BeforeResize","getState","getVerticalSpacing","getColumnsCount","state","_includesBeforeResizeInState","Boolean","beforeResize","firstShownItemIndex","lastShownItemIndex","itemHeights","length","log","newlyShownItemRowsHeight","prevFirstReMeasuredItemsRowIndex","Math","floor","newlyShownItemsToIndex","min","i","rowHeight","columnIndex","itemHeight","undefined","getAverageItemHeight","max","cleanedUpBeforeResizeItemRowsHeight","maxParticipatingBeforeResizeItemsCount","participatingBeforeResizeItemRowsCount","ceil","columnsCount","firstCleanedUpBeforeResizeItemsRowIndex","k","verticalSpacing","firstDroppedBeforeResizeItemIndex","lastDroppedBeforeResizeItemIndex","slice","splice","scrollBy","newFirstShownItemIndex","newColumnsCount","prevBeforeResize","prevBeforeResizeItemsCount","prevBeforeResizeBeforeItemsHeight","prevBeforeResizeItemRowsCount","rowIndex","newBeforeResizeAdditionalBeforeItemsHeight","newBeforeResizeBeforeItemsHeight","newBeforeResizeBeforeItemRowsCount","Array","fill","concat","equalizeItemHeights","maxItemsCount","cleanUpBeforeResizeState"],"sources":["../source/BeforeResize.js"],"sourcesContent":["import log from './utility/debug.js'\r\n\r\nexport default class BeforeResize {\r\n\tconstructor({\r\n\t\tgetState,\r\n\t\tgetVerticalSpacing,\r\n\t\tgetColumnsCount\r\n\t}) {\r\n\t\tthis.getState = getState\r\n\t\tthis.getVerticalSpacing = getVerticalSpacing\r\n\t\tthis.getColumnsCount = getColumnsCount\r\n\t}\r\n\r\n\tinitializeFromState(state) {\r\n\t\tthis._includesBeforeResizeInState = Boolean(state.beforeResize)\r\n\t}\r\n\r\n\t// Cleans up \"before resize\" item heights and adjusts the scroll position accordingly.\r\n\t//\r\n\t// Hypothetically, it could also wait for the user to stop scrolling and only then\r\n\t// adjust the scroll position. The rationale is that if `window.scrollTo()` is called\r\n\t// while the user is scrolling, the user would occasionally experience \"lost\" mouse wheel\r\n\t// events when scrolling with a mouse wheel.\r\n\t//\r\n\t// Seems like Twitter's website waits for the user to stop scrolling before applying\r\n\t// the scroll position correction after a window resize. This library could do that too,\r\n\t// but that would require rewriting \"before items height\" top padding calculation\r\n\t// so that it doesn't re-calculate it on every re-render and instead does so incrementally,\r\n\t// and then, when the user stops, it re-calculates it from scratch removing the error\r\n\t// and adjusting the scroll position accordingly so that there's no \"jump of content\".\r\n\t//\r\n\t// But, seems like it works fine as it is and there's no need to rewrite anything.\r\n\t//\r\n\tcleanUpBeforeResizeItemHeights() {\r\n\t\tconst {\r\n\t\t\tfirstShownItemIndex,\r\n\t\t\tlastShownItemIndex,\r\n\t\t\titemHeights,\r\n\t\t\tbeforeResize\r\n\t\t} = this.getState()\r\n\r\n\t\t// If there're \"before resize\" properties in `state`\r\n\t\t// then it means that the corresponding items are waiting to be\r\n\t\t// re-measured after container resize. Since the resize,\r\n\t\t// some of those non-re-measured items might have just been measured,\r\n\t\t// so see if that's true, and if it is, remove those now-obsolete\r\n\t\t// \"before resize\" item heights and ajust the scroll position\r\n\t\t// so that there's no \"content jumping\".\r\n\r\n\t\tif (beforeResize) {\r\n\t\t\t// If the user has scrolled up to reveal a previously hidden item\r\n\t\t\t// that has not yet been re-measured after a previous resize.\r\n\t\t\tif (firstShownItemIndex < beforeResize.itemHeights.length) {\r\n\t\t\t\tlog('~ Clean up \"before resize\" item heights and correct scroll position ~')\r\n\r\n\t\t\t\t// Some of the \"before\" items have been un-hidden and re-measured.\r\n\t\t\t\t// Un-hiding those items would result in a \"jump of content\"\r\n\t\t\t\t// because \"before resize\" heights of those un-hidden items\r\n\t\t\t\t// could (and most likely will) be different from the current ones,\r\n\t\t\t\t// or because \"before resize\" columns count is different from\r\n\t\t\t\t// the current one.\r\n\t\t\t\t// To prevent a \"jump of content\", calculate the scroll position\r\n\t\t\t\t// difference and adjust the scroll position.\r\n\r\n\t\t\t\t// The height of the item rows that have transitioned\r\n\t\t\t\t// from hidden to shown.\r\n\t\t\t\tlet newlyShownItemRowsHeight = 0\r\n\r\n\t\t\t\t// Some of the `itemHeights` between the current `firstShownItemIndex` and\r\n\t\t\t\t// the previous `firstShownItemIndex` could stay `undefined` if the user\r\n\t\t\t\t// scrolled \"abruptly\": for example, by using a `window.scrollTo()` call.\r\n\t\t\t\t// In that case, the items below the visible ones won't be rendered and measured.\r\n\t\t\t\t// In such case, limit the items being iterated over to the current `lastShownItemIndex`\r\n\t\t\t\t// rather than the previous `firstShownItemIndex`.\r\n\t\t\t\tconst prevFirstReMeasuredItemsRowIndex = Math.floor(beforeResize.itemHeights.length / this.getColumnsCount())\r\n\t\t\t\tconst newlyShownItemsToIndex = Math.min(\r\n\t\t\t\t\tprevFirstReMeasuredItemsRowIndex * this.getColumnsCount() - 1,\r\n\t\t\t\t\tlastShownItemIndex\r\n\t\t\t\t)\r\n\r\n\t\t\t\tlet i = firstShownItemIndex\r\n\t\t\t\twhile (i <= newlyShownItemsToIndex) {\r\n\t\t\t\t\t// Calculate newly shown row height.\r\n\t\t\t\t\tlet rowHeight = 0\r\n\t\t\t\t\tlet columnIndex = 0\r\n\t\t\t\t\twhile (columnIndex < this.getColumnsCount() && i <= newlyShownItemsToIndex) {\r\n\t\t\t\t\t\tlet itemHeight = itemHeights[i]\r\n\t\t\t\t\t\tif (itemHeight === undefined) {\r\n\t\t\t\t\t\t\t// `itemHeight` can only be `undefined` when not `beforeResize`.\r\n\t\t\t\t\t\t\t// Use the current \"average item height\" as a substitute.\r\n\t\t\t\t\t\t\titemHeight = this.getAverageItemHeight()\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\trowHeight = Math.max(rowHeight, itemHeight)\r\n\t\t\t\t\t\ti++\r\n\t\t\t\t\t\tcolumnIndex++\r\n\t\t\t\t\t}\r\n\t\t\t\t\t// Append to the total \"newly shown item rows height\".\r\n\t\t\t\t\tnewlyShownItemRowsHeight += rowHeight\r\n\t\t\t\t\tnewlyShownItemRowsHeight += this.getVerticalSpacing()\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// The height of the \"before resize\" item rows\r\n\t\t\t\t// that will be \"cleaned up\" in this function call.\r\n\t\t\t\tlet cleanedUpBeforeResizeItemRowsHeight = 0\r\n\r\n\t\t\t\t// Some of the `beforeResize` item rows might have been skipped if the user\r\n\t\t\t\t// scrolled up \"abruptly\": for example, by using a `window.scrollTo()` call.\r\n\t\t\t\t// In that case, the \"before resize\" items below the bottom border of the screen\r\n\t\t\t\t// shouldn't be accounted for when calculating the scrollbar adjustment shift\r\n\t\t\t\t// because items after `lastShownItemIndex` aren't participating in the calculation\r\n\t\t\t\t// of `newlyShownItemRowsHeight`.\r\n\t\t\t\tconst maxParticipatingBeforeResizeItemsCount = Math.min(beforeResize.itemHeights.length, lastShownItemIndex + 1)\r\n\t\t\t\tconst participatingBeforeResizeItemRowsCount = Math.ceil(maxParticipatingBeforeResizeItemsCount / beforeResize.columnsCount)\r\n\r\n\t\t\t\tconst firstCleanedUpBeforeResizeItemsRowIndex = firstShownItemIndex === 0\r\n\t\t\t\t\t? 0\r\n\t\t\t\t\t: Math.floor((firstShownItemIndex - 1) / beforeResize.columnsCount) + 1\r\n\r\n\t\t\t\tlet k = firstCleanedUpBeforeResizeItemsRowIndex\r\n\t\t\t\twhile (k < participatingBeforeResizeItemRowsCount) {\r\n\t\t\t\t\tconst rowHeight = beforeResize.itemHeights[k * beforeResize.columnsCount]\r\n\t\t\t\t\tcleanedUpBeforeResizeItemRowsHeight += rowHeight\r\n\t\t\t\t\tcleanedUpBeforeResizeItemRowsHeight += beforeResize.verticalSpacing\r\n\t\t\t\t\tk++\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Schedule an asynchronous `this.updateState()` call that will update\r\n\t\t\t\t// `beforeResize` property of `state`. Ideally, it should be updated\r\n\t\t\t\t// immediately, but since `this.updateState()` calls are asynchronous,\r\n\t\t\t\t// the code updates just the underlying `beforeResize.itemHeights`\r\n\t\t\t\t// array immediately instead, which is still a hack but still a lesser one.\r\n\t\t\t\tif (firstShownItemIndex === 0) {\r\n\t\t\t\t\tlog('Drop all \"before resize\" item heights')\r\n\t\t\t\t} else {\r\n\t\t\t\t\tconst firstDroppedBeforeResizeItemIndex = firstShownItemIndex\r\n\t\t\t\t\tconst lastDroppedBeforeResizeItemIndex = beforeResize.itemHeights.length - 1\r\n\t\t\t\t\tif (firstDroppedBeforeResizeItemIndex === lastDroppedBeforeResizeItemIndex) {\r\n\t\t\t\t\t\tlog('For item index', firstDroppedBeforeResizeItemIndex, '— drop \"before resize\" height', beforeResize.itemHeights[firstDroppedBeforeResizeItemIndex], )\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tlog('For item indexes from', firstDroppedBeforeResizeItemIndex, 'to', lastDroppedBeforeResizeItemIndex, '— drop \"before resize\" heights', beforeResize.itemHeights.slice(firstDroppedBeforeResizeItemIndex))\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Immediately update `beforeResize.itemHeights`\r\n\t\t\t\t// so that the component isn't left in an inconsistent state\r\n\t\t\t\t// before a `this.updateState()` call below is applied.\r\n\t\t\t\tbeforeResize.itemHeights.splice(\r\n\t\t\t\t\tfirstShownItemIndex,\r\n\t\t\t\t\tbeforeResize.itemHeights.length - firstShownItemIndex\r\n\t\t\t\t)\r\n\r\n\t\t\t\t// Return the \"scroll by\" amount that would correct the scroll position.\r\n\t\t\t\t// Also return a state update.\r\n\t\t\t\treturn {\r\n\t\t\t\t\tscrollBy: newlyShownItemRowsHeight - cleanedUpBeforeResizeItemRowsHeight,\r\n\t\t\t\t\tbeforeResize: firstShownItemIndex === 0 ? undefined : {\r\n\t\t\t\t\t\t// Simply change the \"reference\" to `beforeResize` while leaving\r\n\t\t\t\t\t\t// its contents unchanged. That simply indicates that it has been updated:\r\n\t\t\t\t\t\t// `beforeResize.itemHeights` array length has been changed \"directly\".\r\n\t\t\t\t\t\t...beforeResize\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t// Snapshots \"before resize\" values in order to preserve the currently\r\n\t// shown items' vertical position on screen so that there's no \"content jumping\".\r\n\t//\r\n\t// `newFirstShownItemIndex` is `> 0`.\r\n\t//\r\n\tsnapshotBeforeResizeItemHeights({\r\n\t\tfirstShownItemIndex,\r\n\t\tnewFirstShownItemIndex,\r\n\t\tnewColumnsCount\r\n\t}) {\r\n\t\tconst columnsCount = this.getColumnsCount()\r\n\t\tconst verticalSpacing = this.getVerticalSpacing()\r\n\r\n\t\tthis._includesBeforeResizeInState = true\r\n\r\n\t\tconst {\r\n\t\t\tbeforeResize: prevBeforeResize,\r\n\t\t\titemHeights\r\n\t\t} = this.getState()\r\n\r\n\t\tconst prevBeforeResizeItemsCount = prevBeforeResize\r\n\t\t\t? prevBeforeResize.itemHeights.length\r\n\t\t\t: 0\r\n\r\n\t\t// If there already are \"before resize\" values in `state`\r\n\t\t// then it means that those should be merged with the new ones.\r\n\t\t//\r\n\t\t// `beforeResize.itemHeights` could be empty in an edge case\r\n\t\t// when there's a pending state update that sets `beforeResize`\r\n\t\t// to `undefined`, and in that case empty `beforeResize.itemHeights`\r\n\t\t// signals about that type of a situation.\r\n\t\t//\r\n\t\tif (prevBeforeResizeItemsCount > 0) {\r\n\t\t\t// Because the \"previous\" before resize values might have been captured\r\n\t\t\t// for a window width corresponding to a layout with a different columns count\r\n\t\t\t// and different vertical spacing, re-calculate those item heights as if\r\n\t\t\t// they corresponded to the current columns count and current vertical spacing,\r\n\t\t\t// since \"previous\" and \"new\" before resize item heights are gonna be merged.\r\n\t\t\tif (\r\n\t\t\t\tprevBeforeResize.columnsCount !== columnsCount ||\r\n\t\t\t\tprevBeforeResize.verticalSpacing !== verticalSpacing\r\n\t\t\t) {\r\n\t\t\t\tlet prevBeforeResizeBeforeItemsHeight = 0\r\n\r\n\t\t\t\tconst prevBeforeResizeItemRowsCount = Math.ceil(prevBeforeResizeItemsCount / prevBeforeResize.columnsCount)\r\n\t\t\t\tlet rowIndex = 0\r\n\t\t\t\twhile (rowIndex < prevBeforeResizeItemRowsCount) {\r\n\t\t\t\t\t// Since all \"before resize\" item heights are equal within a row,\r\n\t\t\t\t\t// the height of the first \"before resize\" item in a row is that row's height.\r\n\t\t\t\t\tconst rowHeight = prevBeforeResize.itemHeights[rowIndex * prevBeforeResize.columnsCount]\r\n\t\t\t\t\tprevBeforeResizeBeforeItemsHeight += rowHeight\r\n\t\t\t\t\tprevBeforeResizeBeforeItemsHeight += prevBeforeResize.verticalSpacing\r\n\t\t\t\t\trowIndex++\r\n\t\t\t\t}\r\n\r\n\t\t\t\tlet newBeforeResizeAdditionalBeforeItemsHeight = 0\r\n\t\t\t\tlet i = firstShownItemIndex\r\n\t\t\t\twhile (i < newFirstShownItemIndex) {\r\n\t\t\t\t\tlet rowHeight = 0\r\n\t\t\t\t\tlet k = 0\r\n\t\t\t\t\twhile (k < columnsCount && i < newFirstShownItemIndex) {\r\n\t\t\t\t\t\trowHeight = Math.max(rowHeight, itemHeights[i])\r\n\t\t\t\t\t\tk++\r\n\t\t\t\t\t\ti++\r\n\t\t\t\t\t}\r\n\t\t\t\t\tnewBeforeResizeAdditionalBeforeItemsHeight += rowHeight\r\n\t\t\t\t\tnewBeforeResizeAdditionalBeforeItemsHeight += verticalSpacing\r\n\t\t\t\t}\r\n\r\n\t\t\t\tconst newBeforeResizeBeforeItemsHeight = prevBeforeResizeBeforeItemsHeight + newBeforeResizeAdditionalBeforeItemsHeight\r\n\t\t\t\tconst newBeforeResizeBeforeItemRowsCount = Math.ceil(newFirstShownItemIndex / columnsCount)\r\n\r\n\t\t\t\treturn new Array(newFirstShownItemIndex).fill(\r\n\t\t\t\t\t// Re-calculate \"before resize\" item heights so that \"previous\" and \"new\" ones\r\n\t\t\t\t\t// correspond to the same (new) columns count.\r\n\t\t\t\t\t// Also don't occasionally set item heights to `< 0`.\r\n\t\t\t\t\tMath.max(0, newBeforeResizeBeforeItemsHeight / newBeforeResizeBeforeItemRowsCount - verticalSpacing)\r\n\t\t\t\t)\r\n\t\t\t} else {\r\n\t\t\t\t// Add new item heights to the previously snapshotted ones.\r\n\t\t\t\treturn prevBeforeResize.itemHeights.concat(\r\n\t\t\t\t\tequalizeItemHeights(\r\n\t\t\t\t\t\titemHeights,\r\n\t\t\t\t\t\tnewFirstShownItemIndex,\r\n\t\t\t\t\t\tcolumnsCount\r\n\t\t\t\t\t).slice(prevBeforeResize.itemHeights.length)\r\n\t\t\t\t)\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\treturn equalizeItemHeights(\r\n\t\t\t\titemHeights,\r\n\t\t\t\tnewFirstShownItemIndex,\r\n\t\t\t\tcolumnsCount\r\n\t\t\t)\r\n\t\t}\r\n\t}\r\n\r\n\tshouldIncludeBeforeResizeValuesInState() {\r\n\t\treturn this._includesBeforeResizeInState\r\n\t}\r\n}\r\n\r\n// Equalizes all item heights within a given row, for each row.\r\n//\r\n// The reason is that `beforeResize.itemHeights` is not necessarily divisible by\r\n// `beforeResize.columnsCount`, which would result in varying last row height\r\n// as items get removed from `beforeResize.itemHeights` as the user scrolls up.\r\n//\r\n// By equalizing all item heights within a given row, for each row, such \"jumping\"\r\n// last \"before resize\" row height is prevented when the user scrolls up.\r\n//\r\nfunction equalizeItemHeights(itemHeights, maxItemsCount, columnsCount) {\r\n\titemHeights = itemHeights.slice(0, Math.ceil(maxItemsCount / columnsCount) * columnsCount)\r\n\r\n\tlet rowIndex = 0\r\n\twhile (rowIndex * columnsCount < maxItemsCount) {\r\n\t\t// Calculate row height.\r\n\t\tlet rowHeight = 0\r\n\t\tlet k = 0\r\n\t\twhile (k < columnsCount) {\r\n\t\t\trowHeight = Math.max(rowHeight, itemHeights[rowIndex * columnsCount + k])\r\n\t\t\tk++\r\n\t\t}\r\n\r\n\t\t// Equalize all item heights within the row.\r\n\t\tk = 0\r\n\t\twhile (k < columnsCount) {\r\n\t\t\titemHeights[rowIndex * columnsCount + k] = rowHeight\r\n\t\t\tk++\r\n\t\t}\r\n\r\n\t\t// Proceed with the next row.\r\n\t\trowIndex++\r\n\t}\r\n\r\n\treturn itemHeights.slice(0, maxItemsCount)\r\n}\r\n\r\nexport function cleanUpBeforeResizeState(state) {\r\n\tif (state.beforeResize) {\r\n\t\tif (state.beforeResize.itemHeights.length === 0) {\r\n\t\t\tstate.beforeResize = undefined\r\n\t\t}\r\n\t}\r\n\treturn state\r\n}"],"mappings":"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"}
@@ -1,17 +1,17 @@
1
1
  "use strict";
2
2
 
3
- function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
3
+ function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
4
4
 
5
5
  Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
8
  exports["default"] = void 0;
9
9
 
10
- var _ItemsContainer = _interopRequireDefault(require("./ItemsContainer"));
10
+ var _ItemsContainer = _interopRequireDefault(require("./ItemsContainer.js"));
11
11
 
12
- var _ScrollableContainer = _interopRequireWildcard(require("./ScrollableContainer"));
12
+ var _ScrollableContainer = _interopRequireWildcard(require("./ScrollableContainer.js"));
13
13
 
14
- var _ListTopOffsetWatcher = _interopRequireDefault(require("./ListTopOffsetWatcher"));
14
+ var _ListTopOffsetWatcher = _interopRequireDefault(require("./ListTopOffsetWatcher.js"));
15
15
 
16
16
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
17
17
 
@@ -26,9 +26,9 @@ var _default = {
26
26
  // Creates a `scrollableContainer`.
27
27
  // On client side, `scrollableContainer` is always created.
28
28
  // On server side, `scrollableContainer` is not created (and not used).
29
- createScrollableContainer: function createScrollableContainer(scrollableContainer, getItemsContainerElement) {
30
- if (scrollableContainer) {
31
- return new _ScrollableContainer["default"](scrollableContainer, getItemsContainerElement);
29
+ createScrollableContainer: function createScrollableContainer(getScrollableContainerElement, getItemsContainerElement) {
30
+ if (getScrollableContainerElement) {
31
+ return new _ScrollableContainer["default"](getScrollableContainerElement, getItemsContainerElement);
32
32
  } else if (typeof window !== 'undefined') {
33
33
  return new _ScrollableContainer.ScrollableWindowContainer(getItemsContainerElement);
34
34
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../source/DOM/Engine.js"],"names":["createItemsContainer","getItemsContainerElement","ItemsContainer","createScrollableContainer","scrollableContainer","ScrollableContainer","window","ScrollableWindowContainer","watchListTopOffset","getListTopOffset","onListTopOffsetChange","ListTopOffsetWatcher"],"mappings":";;;;;;;;;AAAA;;AAEA;;AAIA;;;;;;;;eAEe;AACdA,EAAAA,oBADc,gCACOC,wBADP,EACiC;AAC9C,WAAO,IAAIC,0BAAJ,CAAmBD,wBAAnB,CAAP;AACA,GAHa;AAId;AACA;AACA;AACAE,EAAAA,yBAPc,qCAOYC,mBAPZ,EAOiCH,wBAPjC,EAO2D;AACxE,QAAIG,mBAAJ,EAAyB;AACxB,aAAO,IAAIC,+BAAJ,CAAwBD,mBAAxB,EAA6CH,wBAA7C,CAAP;AACA,KAFD,MAEO,IAAI,OAAOK,MAAP,KAAkB,WAAtB,EAAmC;AACzC,aAAO,IAAIC,8CAAJ,CAA8BN,wBAA9B,CAAP;AACA;AACD,GAba;AAcdO,EAAAA,kBAdc,oCAiBX;AAAA,QAFFC,gBAEE,QAFFA,gBAEE;AAAA,QADFC,qBACE,QADFA,qBACE;AACF,WAAO,IAAIC,gCAAJ,CAAyB;AAC/BF,MAAAA,gBAAgB,EAAhBA,gBAD+B;AAE/BC,MAAAA,qBAAqB,EAArBA;AAF+B,KAAzB,CAAP;AAIA;AAtBa,C","sourcesContent":["import ItemsContainer from './ItemsContainer'\r\n\r\nimport ScrollableContainer, {\r\n\tScrollableWindowContainer\r\n} from './ScrollableContainer'\r\n\r\nimport ListTopOffsetWatcher from './ListTopOffsetWatcher'\r\n\r\nexport default {\r\n\tcreateItemsContainer(getItemsContainerElement) {\r\n\t\treturn new ItemsContainer(getItemsContainerElement)\r\n\t},\r\n\t// Creates a `scrollableContainer`.\r\n\t// On client side, `scrollableContainer` is always created.\r\n\t// On server side, `scrollableContainer` is not created (and not used).\r\n\tcreateScrollableContainer(scrollableContainer, getItemsContainerElement) {\r\n\t\tif (scrollableContainer) {\r\n\t\t\treturn new ScrollableContainer(scrollableContainer, getItemsContainerElement)\r\n\t\t} else if (typeof window !== 'undefined') {\r\n\t\t\treturn new ScrollableWindowContainer(getItemsContainerElement)\r\n\t\t}\r\n\t},\r\n\twatchListTopOffset({\r\n\t\tgetListTopOffset,\r\n\t\tonListTopOffsetChange\r\n\t}) {\r\n\t\treturn new ListTopOffsetWatcher({\r\n\t\t\tgetListTopOffset,\r\n\t\t\tonListTopOffsetChange\r\n\t\t})\r\n\t}\r\n}"],"file":"Engine.js"}
1
+ {"version":3,"file":"Engine.js","names":["createItemsContainer","getItemsContainerElement","ItemsContainer","createScrollableContainer","getScrollableContainerElement","ScrollableContainer","window","ScrollableWindowContainer","watchListTopOffset","getListTopOffset","onListTopOffsetChange","ListTopOffsetWatcher"],"sources":["../../source/DOM/Engine.js"],"sourcesContent":["import ItemsContainer from './ItemsContainer.js'\r\nimport ScrollableContainer, { ScrollableWindowContainer } from './ScrollableContainer.js'\r\nimport ListTopOffsetWatcher from './ListTopOffsetWatcher.js'\r\n\r\nexport default {\r\n\tcreateItemsContainer(getItemsContainerElement) {\r\n\t\treturn new ItemsContainer(getItemsContainerElement)\r\n\t},\r\n\r\n\t// Creates a `scrollableContainer`.\r\n\t// On client side, `scrollableContainer` is always created.\r\n\t// On server side, `scrollableContainer` is not created (and not used).\r\n\tcreateScrollableContainer(getScrollableContainerElement, getItemsContainerElement) {\r\n\t\tif (getScrollableContainerElement) {\r\n\t\t\treturn new ScrollableContainer(getScrollableContainerElement, getItemsContainerElement)\r\n\t\t} else if (typeof window !== 'undefined') {\r\n\t\t\treturn new ScrollableWindowContainer(getItemsContainerElement)\r\n\t\t}\r\n\t},\r\n\r\n\twatchListTopOffset({\r\n\t\tgetListTopOffset,\r\n\t\tonListTopOffsetChange\r\n\t}) {\r\n\t\treturn new ListTopOffsetWatcher({\r\n\t\t\tgetListTopOffset,\r\n\t\t\tonListTopOffsetChange\r\n\t\t})\r\n\t}\r\n}"],"mappings":";;;;;;;;;AAAA;;AACA;;AACA;;;;;;;;eAEe;EACdA,oBADc,gCACOC,wBADP,EACiC;IAC9C,OAAO,IAAIC,0BAAJ,CAAmBD,wBAAnB,CAAP;EACA,CAHa;EAKd;EACA;EACA;EACAE,yBARc,qCAQYC,6BARZ,EAQ2CH,wBAR3C,EAQqE;IAClF,IAAIG,6BAAJ,EAAmC;MAClC,OAAO,IAAIC,+BAAJ,CAAwBD,6BAAxB,EAAuDH,wBAAvD,CAAP;IACA,CAFD,MAEO,IAAI,OAAOK,MAAP,KAAkB,WAAtB,EAAmC;MACzC,OAAO,IAAIC,8CAAJ,CAA8BN,wBAA9B,CAAP;IACA;EACD,CAda;EAgBdO,kBAhBc,oCAmBX;IAAA,IAFFC,gBAEE,QAFFA,gBAEE;IAAA,IADFC,qBACE,QADFA,qBACE;IACF,OAAO,IAAIC,gCAAJ,CAAyB;MAC/BF,gBAAgB,EAAhBA,gBAD+B;MAE/BC,qBAAqB,EAArBA;IAF+B,CAAzB,CAAP;EAIA;AAxBa,C"}
@@ -9,7 +9,7 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
9
9
 
10
10
  function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
11
11
 
12
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
12
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
13
13
 
14
14
  var ItemsContainer = /*#__PURE__*/function () {
15
15
  /**
@@ -1 +1 @@
1
- {"version":3,"sources":["../../source/DOM/ItemsContainer.js"],"names":["ItemsContainer","getElement","renderedElementIndex","childNodes","getBoundingClientRect","top","height","firstChild","removeChild"],"mappings":";;;;;;;;;;;;;IAAqBA,c;AACpB;AACD;AACA;AACA;AACC,0BAAYC,UAAZ,EAAwB;AAAA;;AACvB,SAAKA,UAAL,GAAkBA,UAAlB;AACA;AAED;AACD;AACA;AACA;AACA;;;;;WACC,qCAA4BC,oBAA5B,EAAkD;AACjD,aAAO,KAAKD,UAAL,GAAkBE,UAAlB,CAA6BD,oBAA7B,EAAmDE,qBAAnD,GAA2EC,GAA3E,GAAiF,KAAKJ,UAAL,GAAkBG,qBAAlB,GAA0CC,GAAlI;AACA;AAED;AACD;AACA;AACA;AACA;;;;WACC,kCAAyBH,oBAAzB,EAA+C;AAC9C;AACA;AACA,aAAO,KAAKD,UAAL,GAAkBE,UAAlB,CAA6BD,oBAA7B,EAAmDE,qBAAnD,GAA2EE,MAAlF;AACA;AAED;AACD;AACA;AACA;;;;WACC,qBAAY;AACX;AACA;AACA,aAAO,KAAKL,UAAL,GAAkBG,qBAAlB,GAA0CE,MAAjD;AACA;AAED;AACD;AACA;;;;WACC,iBAAQ;AACP,aAAO,KAAKL,UAAL,GAAkBM,UAAzB,EAAqC;AACpC,aAAKN,UAAL,GAAkBO,WAAlB,CAA8B,KAAKP,UAAL,GAAkBM,UAAhD;AACA;AACD","sourcesContent":["export default class ItemsContainer {\r\n\t/**\r\n\t * Constructs a new \"container\" from an element.\r\n\t * @param {function} getElement\r\n\t */\r\n\tconstructor(getElement) {\r\n\t\tthis.getElement = getElement\r\n\t}\r\n\r\n\t/**\r\n\t * Returns an item element's \"top offset\", relative to the items `container`'s top edge.\r\n\t * @param {number} renderedElementIndex — An index of an item relative to the \"first shown item index\". For example, if the list is showing items from index 8 to index 12 then `renderedElementIndex = 0` would mean the item at index `8`.\r\n\t * @return {number}\r\n\t */\r\n\tgetNthRenderedItemTopOffset(renderedElementIndex) {\r\n\t\treturn this.getElement().childNodes[renderedElementIndex].getBoundingClientRect().top - this.getElement().getBoundingClientRect().top\r\n\t}\r\n\r\n\t/**\r\n\t * Returns an item element's height.\r\n\t * @param {number} renderedElementIndex — An index of an item relative to the \"first shown item index\". For example, if the list is showing items from index 8 to index 12 then `renderedElementIndex = 0` would mean the item at index `8`.\r\n\t * @return {number}\r\n\t */\r\n\tgetNthRenderedItemHeight(renderedElementIndex) {\r\n\t\t// `offsetHeight` is not precise enough (doesn't return fractional pixels).\r\n\t\t// return this.getElement().childNodes[renderedElementIndex].offsetHeight\r\n\t\treturn this.getElement().childNodes[renderedElementIndex].getBoundingClientRect().height\r\n\t}\r\n\r\n\t/**\r\n\t * Returns items container height.\r\n\t * @return {number}\r\n\t */\r\n\tgetHeight() {\r\n\t\t// `offsetHeight` is not precise enough (doesn't return fractional pixels).\r\n\t\t// return this.getElement().offsetHeight\r\n\t\treturn this.getElement().getBoundingClientRect().height\r\n\t}\r\n\r\n\t/**\r\n\t * Removes all item elements of an items container.\r\n\t */\r\n\tclear() {\r\n\t\twhile (this.getElement().firstChild) {\r\n\t\t\tthis.getElement().removeChild(this.getElement().firstChild)\r\n\t\t}\r\n\t}\r\n}"],"file":"ItemsContainer.js"}
1
+ {"version":3,"file":"ItemsContainer.js","names":["ItemsContainer","getElement","renderedElementIndex","childNodes","getBoundingClientRect","top","height","firstChild","removeChild"],"sources":["../../source/DOM/ItemsContainer.js"],"sourcesContent":["export default class ItemsContainer {\r\n\t/**\r\n\t * Constructs a new \"container\" from an element.\r\n\t * @param {function} getElement\r\n\t */\r\n\tconstructor(getElement) {\r\n\t\tthis.getElement = getElement\r\n\t}\r\n\r\n\t/**\r\n\t * Returns an item element's \"top offset\", relative to the items `container`'s top edge.\r\n\t * @param {number} renderedElementIndex — An index of an item relative to the \"first shown item index\". For example, if the list is showing items from index 8 to index 12 then `renderedElementIndex = 0` would mean the item at index `8`.\r\n\t * @return {number}\r\n\t */\r\n\tgetNthRenderedItemTopOffset(renderedElementIndex) {\r\n\t\treturn this.getElement().childNodes[renderedElementIndex].getBoundingClientRect().top - this.getElement().getBoundingClientRect().top\r\n\t}\r\n\r\n\t/**\r\n\t * Returns an item element's height.\r\n\t * @param {number} renderedElementIndex — An index of an item relative to the \"first shown item index\". For example, if the list is showing items from index 8 to index 12 then `renderedElementIndex = 0` would mean the item at index `8`.\r\n\t * @return {number}\r\n\t */\r\n\tgetNthRenderedItemHeight(renderedElementIndex) {\r\n\t\t// `offsetHeight` is not precise enough (doesn't return fractional pixels).\r\n\t\t// return this.getElement().childNodes[renderedElementIndex].offsetHeight\r\n\t\treturn this.getElement().childNodes[renderedElementIndex].getBoundingClientRect().height\r\n\t}\r\n\r\n\t/**\r\n\t * Returns items container height.\r\n\t * @return {number}\r\n\t */\r\n\tgetHeight() {\r\n\t\t// `offsetHeight` is not precise enough (doesn't return fractional pixels).\r\n\t\t// return this.getElement().offsetHeight\r\n\t\treturn this.getElement().getBoundingClientRect().height\r\n\t}\r\n\r\n\t/**\r\n\t * Removes all item elements of an items container.\r\n\t */\r\n\tclear() {\r\n\t\twhile (this.getElement().firstChild) {\r\n\t\t\tthis.getElement().removeChild(this.getElement().firstChild)\r\n\t\t}\r\n\t}\r\n}"],"mappings":";;;;;;;;;;;;;IAAqBA,c;EACpB;AACD;AACA;AACA;EACC,wBAAYC,UAAZ,EAAwB;IAAA;;IACvB,KAAKA,UAAL,GAAkBA,UAAlB;EACA;EAED;AACD;AACA;AACA;AACA;;;;;WACC,qCAA4BC,oBAA5B,EAAkD;MACjD,OAAO,KAAKD,UAAL,GAAkBE,UAAlB,CAA6BD,oBAA7B,EAAmDE,qBAAnD,GAA2EC,GAA3E,GAAiF,KAAKJ,UAAL,GAAkBG,qBAAlB,GAA0CC,GAAlI;IACA;IAED;AACD;AACA;AACA;AACA;;;;WACC,kCAAyBH,oBAAzB,EAA+C;MAC9C;MACA;MACA,OAAO,KAAKD,UAAL,GAAkBE,UAAlB,CAA6BD,oBAA7B,EAAmDE,qBAAnD,GAA2EE,MAAlF;IACA;IAED;AACD;AACA;AACA;;;;WACC,qBAAY;MACX;MACA;MACA,OAAO,KAAKL,UAAL,GAAkBG,qBAAlB,GAA0CE,MAAjD;IACA;IAED;AACD;AACA;;;;WACC,iBAAQ;MACP,OAAO,KAAKL,UAAL,GAAkBM,UAAzB,EAAqC;QACpC,KAAKN,UAAL,GAAkBO,WAAlB,CAA8B,KAAKP,UAAL,GAAkBM,UAAhD;MACA;IACD"}
@@ -11,7 +11,7 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
11
11
 
12
12
  function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
13
13
 
14
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
14
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
15
15
 
16
16
  // Refreshing two times every seconds seems reasonable.
17
17
  var WATCH_LIST_TOP_OFFSET_INTERVAL = 500; // Refreshing for 3 seconds after the initial page load seems reasonable.
@@ -24,18 +24,19 @@ var WATCH_LIST_TOP_OFFSET_MAX_DURATION = 3000; // `VirtualScroller` calls `this.
24
24
  // returns "incorrect" `top` position because the styles haven't been applied yet.
25
25
  //
26
26
  // For example, consider a page:
27
+ //
27
28
  // <div class="page">
28
29
  // <nav class="sidebar">...</nav>
29
30
  // <main>...</main>
30
31
  // </div>
31
32
  //
32
- // The sidebar is styled as `position: fixed`, but until
33
- // the page styles have been applied it's gonna be a regular `<div/>`
33
+ // The sidebar is styled as `position: fixed`, but, until
34
+ // the page styles have been applied, it's gonna be a regular `<div/>`
34
35
  // meaning that `<main/>` will be rendered below the sidebar
35
- // and will appear offscreen and so it will only render the first item.
36
+ // and will appear offscreen, and so it will only render the first item.
36
37
  //
37
- // Then, the page styles are loaded and applied and the sidebar
38
- // is now `position: fixed` so `<main/>` is now rendered at the top of the page
38
+ // Then, the page styles are loaded and applied, and the sidebar
39
+ // is now `position: fixed`, so `<main/>` is now rendered at the top of the page,
39
40
  // but `VirtualScroller`'s `.render()` has already been called
40
41
  // and it won't re-render until the user scrolls or the window is resized.
41
42
  //
@@ -90,13 +91,18 @@ var ListTopOffsetWatcher = /*#__PURE__*/function () {
90
91
  }, {
91
92
  key: "start",
92
93
  value: function start() {
93
- this.isRendered = true;
94
+ this._isActive = true;
94
95
  this.watchListTopOffset();
95
96
  }
97
+ }, {
98
+ key: "isStarted",
99
+ value: function isStarted() {
100
+ return this._isActive;
101
+ }
96
102
  }, {
97
103
  key: "stop",
98
104
  value: function stop() {
99
- this.isRendered = false;
105
+ this._isActive = false;
100
106
 
101
107
  if (this.watchListTopOffsetTimer) {
102
108
  (0, _requestAnimationFrameTimeout.clearTimeout)(this.watchListTopOffsetTimer);
@@ -113,7 +119,7 @@ var ListTopOffsetWatcher = /*#__PURE__*/function () {
113
119
  var check = function check() {
114
120
  // If `VirtualScroller` has been unmounted
115
121
  // while `setTimeout()` was waiting, then exit.
116
- if (!_this.isRendered) {
122
+ if (!_this._isActive) {
117
123
  return;
118
124
  } // Skip comparing `top` coordinate of the list
119
125
  // when this function is called for the first time.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../source/DOM/ListTopOffsetWatcher.js"],"names":["WATCH_LIST_TOP_OFFSET_INTERVAL","WATCH_LIST_TOP_OFFSET_MAX_DURATION","ListTopOffsetWatcher","getListTopOffset","onListTopOffsetChange","listTopOffset","listTopOffsetInsideScrollableContainer","undefined","start","isRendered","watchListTopOffset","watchListTopOffsetTimer","startedAt","Date","now","check"],"mappings":";;;;;;;AAIA;;;;;;;;AAEA;AACA,IAAMA,8BAA8B,GAAG,GAAvC,C,CAEA;;AACA,IAAMC,kCAAkC,GAAG,IAA3C,C,CAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;IACqBC,oB;AACpB,sCAGG;AAAA,QAFFC,gBAEE,QAFFA,gBAEE;AAAA,QADFC,qBACE,QADFA,qBACE;;AAAA;;AACF,SAAKD,gBAAL,GAAwBA,gBAAxB;AACA,SAAKC,qBAAL,GAA6BA,qBAA7B;AACA;;;;WAED,yBAAgBC,aAAhB,EAA+B;AAC9B,UAAI,KAAKC,sCAAL,KAAgDC,SAApD,EAA+D;AAC9D;AACA;AACA;AACA;AACA,aAAKC,KAAL;AACA;;AACD,WAAKF,sCAAL,GAA8CD,aAA9C;AACA;;;WAED,iBAAQ;AACP,WAAKI,UAAL,GAAkB,IAAlB;AACA,WAAKC,kBAAL;AACA;;;WAED,gBAAO;AACN,WAAKD,UAAL,GAAkB,KAAlB;;AAEA,UAAI,KAAKE,uBAAT,EAAkC;AACjC,wDAAa,KAAKA,uBAAlB;AACA,aAAKA,uBAAL,GAA+BJ,SAA/B;AACA;AACD;;;WAED,8BAAqB;AAAA;;AACpB,UAAMK,SAAS,GAAGC,IAAI,CAACC,GAAL,EAAlB;;AACA,UAAMC,KAAK,GAAG,SAARA,KAAQ,GAAM;AACnB;AACA;AACA,YAAI,CAAC,KAAI,CAACN,UAAV,EAAsB;AACrB;AACA,SALkB,CAMnB;AACA;;;AACA,YAAI,KAAI,CAACH,sCAAL,KAAgDC,SAApD,EAA+D;AAC9D;AACA;AACA;AACA,cAAI,KAAI,CAACJ,gBAAL,OAA4B,KAAI,CAACG,sCAArC,EAA6E;AAC5E,YAAA,KAAI,CAACF,qBAAL;AACA;AACD,SAfkB,CAgBnB;AACA;AACA;AACA;AACA;AACA;AACA;;;AACA,YAAIS,IAAI,CAACC,GAAL,KAAaF,SAAb,GAAyBX,kCAA7B,EAAiE;AAChE,UAAA,KAAI,CAACU,uBAAL,GAA+B,8CAAWI,KAAX,EAAkBf,8BAAlB,CAA/B;AACA;AACD,OA1BD,CAFoB,CA6BpB;;;AACAe,MAAAA,KAAK;AACL","sourcesContent":["// For some weird reason, in Chrome, `setTimeout()` would lag up to a second (or more) behind.\r\n// Turns out, Chrome developers have deprecated `setTimeout()` API entirely without asking anyone.\r\n// Replacing `setTimeout()` with `requestAnimationFrame()` can work around that Chrome bug.\r\n// https://github.com/bvaughn/react-virtualized/issues/722\r\nimport { setTimeout, clearTimeout } from 'request-animation-frame-timeout'\r\n\r\n// Refreshing two times every seconds seems reasonable.\r\nconst WATCH_LIST_TOP_OFFSET_INTERVAL = 500\r\n\r\n// Refreshing for 3 seconds after the initial page load seems reasonable.\r\nconst WATCH_LIST_TOP_OFFSET_MAX_DURATION = 3000\r\n\r\n// `VirtualScroller` calls `this.layout.layOut()` on mount,\r\n// but if the page styles are applied after `VirtualScroller` mounts\r\n// (for example, if styles are applied via javascript, like Webpack does)\r\n// then the list might not render correctly and it will only show the first item.\r\n// The reason is that in that case calling `.getListTopOffset()` on mount\r\n// returns \"incorrect\" `top` position because the styles haven't been applied yet.\r\n//\r\n// For example, consider a page:\r\n// <div class=\"page\">\r\n// <nav class=\"sidebar\">...</nav>\r\n// <main>...</main>\r\n// </div>\r\n//\r\n// The sidebar is styled as `position: fixed`, but until\r\n// the page styles have been applied it's gonna be a regular `<div/>`\r\n// meaning that `<main/>` will be rendered below the sidebar\r\n// and will appear offscreen and so it will only render the first item.\r\n//\r\n// Then, the page styles are loaded and applied and the sidebar\r\n// is now `position: fixed` so `<main/>` is now rendered at the top of the page\r\n// but `VirtualScroller`'s `.render()` has already been called\r\n// and it won't re-render until the user scrolls or the window is resized.\r\n//\r\n// This type of a bug doesn't seem to occur in production, but it can appear\r\n// in development mode when using Webpack. The workaround `VirtualScroller`\r\n// implements for such cases is calling `.getListTopOffset()`\r\n// on the list container DOM element periodically (every second) to check\r\n// if the `top` coordinate has changed as a result of CSS being applied:\r\n// if it has then it recalculates the shown item indexes.\r\n//\r\n// Maybe this bug could occur in production when using Webpack chunks.\r\n// That depends on how a style of a chunk is added to the page:\r\n// if it's added via `javascript` after the page has been rendered\r\n// then this workaround will also work for that case.\r\n//\r\n// Another example would be a page having a really tall expanded \"accordion\"\r\n// section, below which a `VirtualScroller` list resides. If the user un-expands\r\n// such expanded \"accordion\" section, the list would become visible but\r\n// it wouldn't get re-rendered because no `scroll` event has occured,\r\n// and the list only re-renders automatically on `scroll` events.\r\n// To work around such cases, call `virtualScroller.updateLayout()` method manually.\r\n// The workaround below could be extended to refresh the list's top coordinate\r\n// indefinitely and at higher intervals, but why waste CPU time on that.\r\n// There doesn't seem to be any DOM API for tracking an element's top position.\r\n// There is `IntersectionObserver` API but it doesn't exactly do that.\r\n//\r\nexport default class ListTopOffsetWatcher {\r\n\tconstructor({\r\n\t\tgetListTopOffset,\r\n\t\tonListTopOffsetChange\r\n\t}) {\r\n\t\tthis.getListTopOffset = getListTopOffset\r\n\t\tthis.onListTopOffsetChange = onListTopOffsetChange\r\n\t}\r\n\r\n\tonListTopOffset(listTopOffset) {\r\n\t\tif (this.listTopOffsetInsideScrollableContainer === undefined) {\r\n\t\t\t// Start periodical checks of the list's top offset\r\n\t\t\t// in order to perform a re-layout in case it changes.\r\n\t\t\t// See the comments in `ListTopOffsetWatcher.js` file\r\n\t\t\t// on why can the list's top offset change, and in which circumstances.\r\n\t\t\tthis.start()\r\n\t\t}\r\n\t\tthis.listTopOffsetInsideScrollableContainer = listTopOffset\r\n\t}\r\n\r\n\tstart() {\r\n\t\tthis.isRendered = true\r\n\t\tthis.watchListTopOffset()\r\n\t}\r\n\r\n\tstop() {\r\n\t\tthis.isRendered = false\r\n\r\n\t\tif (this.watchListTopOffsetTimer) {\r\n\t\t\tclearTimeout(this.watchListTopOffsetTimer)\r\n\t\t\tthis.watchListTopOffsetTimer = undefined\r\n\t\t}\r\n\t}\r\n\r\n\twatchListTopOffset() {\r\n\t\tconst startedAt = Date.now()\r\n\t\tconst check = () => {\r\n\t\t\t// If `VirtualScroller` has been unmounted\r\n\t\t\t// while `setTimeout()` was waiting, then exit.\r\n\t\t\tif (!this.isRendered) {\r\n\t\t\t\treturn\r\n\t\t\t}\r\n\t\t\t// Skip comparing `top` coordinate of the list\r\n\t\t\t// when this function is called for the first time.\r\n\t\t\tif (this.listTopOffsetInsideScrollableContainer !== undefined) {\r\n\t\t\t\t// Calling `this.getListTopOffset()` on an element\r\n\t\t\t\t// runs about 0.003 milliseconds on a modern desktop CPU,\r\n\t\t\t\t// so I guess it's fine calling it twice a second.\r\n\t\t\t\tif (this.getListTopOffset() !== this.listTopOffsetInsideScrollableContainer) {\r\n\t\t\t\t\tthis.onListTopOffsetChange()\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t// Compare `top` coordinate of the list twice a second\r\n\t\t\t// to find out if it has changed as a result of loading CSS styles.\r\n\t\t\t// The total duration of 3 seconds would be enough for any styles to load, I guess.\r\n\t\t\t// There could be other cases changing the `top` coordinate\r\n\t\t\t// of the list (like collapsing an \"accordeon\" panel above the list\r\n\t\t\t// without scrolling the page), but those cases should be handled\r\n\t\t\t// by manually calling `.updateLayout()` instance method on `VirtualScroller` instance.\r\n\t\t\tif (Date.now() - startedAt < WATCH_LIST_TOP_OFFSET_MAX_DURATION) {\r\n\t\t\t\tthis.watchListTopOffsetTimer = setTimeout(check, WATCH_LIST_TOP_OFFSET_INTERVAL)\r\n\t\t\t}\r\n\t\t}\r\n\t\t// Run the cycle.\r\n\t\tcheck()\r\n\t}\r\n}"],"file":"ListTopOffsetWatcher.js"}
1
+ {"version":3,"file":"ListTopOffsetWatcher.js","names":["WATCH_LIST_TOP_OFFSET_INTERVAL","WATCH_LIST_TOP_OFFSET_MAX_DURATION","ListTopOffsetWatcher","getListTopOffset","onListTopOffsetChange","listTopOffset","listTopOffsetInsideScrollableContainer","undefined","start","_isActive","watchListTopOffset","watchListTopOffsetTimer","clearTimeout","startedAt","Date","now","check","setTimeout"],"sources":["../../source/DOM/ListTopOffsetWatcher.js"],"sourcesContent":["// For some weird reason, in Chrome, `setTimeout()` would lag up to a second (or more) behind.\r\n// Turns out, Chrome developers have deprecated `setTimeout()` API entirely without asking anyone.\r\n// Replacing `setTimeout()` with `requestAnimationFrame()` can work around that Chrome bug.\r\n// https://github.com/bvaughn/react-virtualized/issues/722\r\nimport { setTimeout, clearTimeout } from 'request-animation-frame-timeout'\r\n\r\n// Refreshing two times every seconds seems reasonable.\r\nconst WATCH_LIST_TOP_OFFSET_INTERVAL = 500\r\n\r\n// Refreshing for 3 seconds after the initial page load seems reasonable.\r\nconst WATCH_LIST_TOP_OFFSET_MAX_DURATION = 3000\r\n\r\n// `VirtualScroller` calls `this.layout.layOut()` on mount,\r\n// but if the page styles are applied after `VirtualScroller` mounts\r\n// (for example, if styles are applied via javascript, like Webpack does)\r\n// then the list might not render correctly and it will only show the first item.\r\n// The reason is that in that case calling `.getListTopOffset()` on mount\r\n// returns \"incorrect\" `top` position because the styles haven't been applied yet.\r\n//\r\n// For example, consider a page:\r\n//\r\n// <div class=\"page\">\r\n// <nav class=\"sidebar\">...</nav>\r\n// <main>...</main>\r\n// </div>\r\n//\r\n// The sidebar is styled as `position: fixed`, but, until\r\n// the page styles have been applied, it's gonna be a regular `<div/>`\r\n// meaning that `<main/>` will be rendered below the sidebar\r\n// and will appear offscreen, and so it will only render the first item.\r\n//\r\n// Then, the page styles are loaded and applied, and the sidebar\r\n// is now `position: fixed`, so `<main/>` is now rendered at the top of the page,\r\n// but `VirtualScroller`'s `.render()` has already been called\r\n// and it won't re-render until the user scrolls or the window is resized.\r\n//\r\n// This type of a bug doesn't seem to occur in production, but it can appear\r\n// in development mode when using Webpack. The workaround `VirtualScroller`\r\n// implements for such cases is calling `.getListTopOffset()`\r\n// on the list container DOM element periodically (every second) to check\r\n// if the `top` coordinate has changed as a result of CSS being applied:\r\n// if it has then it recalculates the shown item indexes.\r\n//\r\n// Maybe this bug could occur in production when using Webpack chunks.\r\n// That depends on how a style of a chunk is added to the page:\r\n// if it's added via `javascript` after the page has been rendered\r\n// then this workaround will also work for that case.\r\n//\r\n// Another example would be a page having a really tall expanded \"accordion\"\r\n// section, below which a `VirtualScroller` list resides. If the user un-expands\r\n// such expanded \"accordion\" section, the list would become visible but\r\n// it wouldn't get re-rendered because no `scroll` event has occured,\r\n// and the list only re-renders automatically on `scroll` events.\r\n// To work around such cases, call `virtualScroller.updateLayout()` method manually.\r\n// The workaround below could be extended to refresh the list's top coordinate\r\n// indefinitely and at higher intervals, but why waste CPU time on that.\r\n// There doesn't seem to be any DOM API for tracking an element's top position.\r\n// There is `IntersectionObserver` API but it doesn't exactly do that.\r\n//\r\nexport default class ListTopOffsetWatcher {\r\n\tconstructor({\r\n\t\tgetListTopOffset,\r\n\t\tonListTopOffsetChange\r\n\t}) {\r\n\t\tthis.getListTopOffset = getListTopOffset\r\n\t\tthis.onListTopOffsetChange = onListTopOffsetChange\r\n\t}\r\n\r\n\tonListTopOffset(listTopOffset) {\r\n\t\tif (this.listTopOffsetInsideScrollableContainer === undefined) {\r\n\t\t\t// Start periodical checks of the list's top offset\r\n\t\t\t// in order to perform a re-layout in case it changes.\r\n\t\t\t// See the comments in `ListTopOffsetWatcher.js` file\r\n\t\t\t// on why can the list's top offset change, and in which circumstances.\r\n\t\t\tthis.start()\r\n\t\t}\r\n\t\tthis.listTopOffsetInsideScrollableContainer = listTopOffset\r\n\t}\r\n\r\n\tstart() {\r\n\t\tthis._isActive = true\r\n\t\tthis.watchListTopOffset()\r\n\t}\r\n\r\n\tisStarted() {\r\n\t\treturn this._isActive\r\n\t}\r\n\r\n\tstop() {\r\n\t\tthis._isActive = false\r\n\r\n\t\tif (this.watchListTopOffsetTimer) {\r\n\t\t\tclearTimeout(this.watchListTopOffsetTimer)\r\n\t\t\tthis.watchListTopOffsetTimer = undefined\r\n\t\t}\r\n\t}\r\n\r\n\twatchListTopOffset() {\r\n\t\tconst startedAt = Date.now()\r\n\t\tconst check = () => {\r\n\t\t\t// If `VirtualScroller` has been unmounted\r\n\t\t\t// while `setTimeout()` was waiting, then exit.\r\n\t\t\tif (!this._isActive) {\r\n\t\t\t\treturn\r\n\t\t\t}\r\n\t\t\t// Skip comparing `top` coordinate of the list\r\n\t\t\t// when this function is called for the first time.\r\n\t\t\tif (this.listTopOffsetInsideScrollableContainer !== undefined) {\r\n\t\t\t\t// Calling `this.getListTopOffset()` on an element\r\n\t\t\t\t// runs about 0.003 milliseconds on a modern desktop CPU,\r\n\t\t\t\t// so I guess it's fine calling it twice a second.\r\n\t\t\t\tif (this.getListTopOffset() !== this.listTopOffsetInsideScrollableContainer) {\r\n\t\t\t\t\tthis.onListTopOffsetChange()\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t// Compare `top` coordinate of the list twice a second\r\n\t\t\t// to find out if it has changed as a result of loading CSS styles.\r\n\t\t\t// The total duration of 3 seconds would be enough for any styles to load, I guess.\r\n\t\t\t// There could be other cases changing the `top` coordinate\r\n\t\t\t// of the list (like collapsing an \"accordeon\" panel above the list\r\n\t\t\t// without scrolling the page), but those cases should be handled\r\n\t\t\t// by manually calling `.updateLayout()` instance method on `VirtualScroller` instance.\r\n\t\t\tif (Date.now() - startedAt < WATCH_LIST_TOP_OFFSET_MAX_DURATION) {\r\n\t\t\t\tthis.watchListTopOffsetTimer = setTimeout(check, WATCH_LIST_TOP_OFFSET_INTERVAL)\r\n\t\t\t}\r\n\t\t}\r\n\t\t// Run the cycle.\r\n\t\tcheck()\r\n\t}\r\n}"],"mappings":";;;;;;;AAIA;;;;;;;;AAEA;AACA,IAAMA,8BAA8B,GAAG,GAAvC,C,CAEA;;AACA,IAAMC,kCAAkC,GAAG,IAA3C,C,CAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;IACqBC,oB;EACpB,oCAGG;IAAA,IAFFC,gBAEE,QAFFA,gBAEE;IAAA,IADFC,qBACE,QADFA,qBACE;;IAAA;;IACF,KAAKD,gBAAL,GAAwBA,gBAAxB;IACA,KAAKC,qBAAL,GAA6BA,qBAA7B;EACA;;;;WAED,yBAAgBC,aAAhB,EAA+B;MAC9B,IAAI,KAAKC,sCAAL,KAAgDC,SAApD,EAA+D;QAC9D;QACA;QACA;QACA;QACA,KAAKC,KAAL;MACA;;MACD,KAAKF,sCAAL,GAA8CD,aAA9C;IACA;;;WAED,iBAAQ;MACP,KAAKI,SAAL,GAAiB,IAAjB;MACA,KAAKC,kBAAL;IACA;;;WAED,qBAAY;MACX,OAAO,KAAKD,SAAZ;IACA;;;WAED,gBAAO;MACN,KAAKA,SAAL,GAAiB,KAAjB;;MAEA,IAAI,KAAKE,uBAAT,EAAkC;QACjC,IAAAC,0CAAA,EAAa,KAAKD,uBAAlB;QACA,KAAKA,uBAAL,GAA+BJ,SAA/B;MACA;IACD;;;WAED,8BAAqB;MAAA;;MACpB,IAAMM,SAAS,GAAGC,IAAI,CAACC,GAAL,EAAlB;;MACA,IAAMC,KAAK,GAAG,SAARA,KAAQ,GAAM;QACnB;QACA;QACA,IAAI,CAAC,KAAI,CAACP,SAAV,EAAqB;UACpB;QACA,CALkB,CAMnB;QACA;;;QACA,IAAI,KAAI,CAACH,sCAAL,KAAgDC,SAApD,EAA+D;UAC9D;UACA;UACA;UACA,IAAI,KAAI,CAACJ,gBAAL,OAA4B,KAAI,CAACG,sCAArC,EAA6E;YAC5E,KAAI,CAACF,qBAAL;UACA;QACD,CAfkB,CAgBnB;QACA;QACA;QACA;QACA;QACA;QACA;;;QACA,IAAIU,IAAI,CAACC,GAAL,KAAaF,SAAb,GAAyBZ,kCAA7B,EAAiE;UAChE,KAAI,CAACU,uBAAL,GAA+B,IAAAM,wCAAA,EAAWD,KAAX,EAAkBhB,8BAAlB,CAA/B;QACA;MACD,CA1BD,CAFoB,CA6BpB;;;MACAgB,KAAK;IACL"}
@@ -1,13 +1,13 @@
1
1
  "use strict";
2
2
 
3
- function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
3
+ function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
4
4
 
5
5
  Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
8
  exports["default"] = exports.ScrollableWindowContainer = void 0;
9
9
 
10
- function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
10
+ function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
11
11
 
12
12
  function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
13
13
 
@@ -25,18 +25,18 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
25
25
 
26
26
  function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
27
27
 
28
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
28
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
29
29
 
30
30
  var ScrollableContainer = /*#__PURE__*/function () {
31
31
  /**
32
32
  * Constructs a new "scrollable container" from an element.
33
- * @param {Element} scrollableContainer
33
+ * @param {func} getElement — Returns the scrollable container element.
34
34
  * @param {func} getItemsContainerElement — Returns items "container" element.
35
35
  */
36
- function ScrollableContainer(element, getItemsContainerElement) {
36
+ function ScrollableContainer(getElement, getItemsContainerElement) {
37
37
  _classCallCheck(this, ScrollableContainer);
38
38
 
39
- this.element = element;
39
+ this.getElement = getElement;
40
40
  this.getItemsContainerElement = getItemsContainerElement;
41
41
  }
42
42
  /**
@@ -48,7 +48,7 @@ var ScrollableContainer = /*#__PURE__*/function () {
48
48
  _createClass(ScrollableContainer, [{
49
49
  key: "getScrollY",
50
50
  value: function getScrollY() {
51
- return this.element.scrollTop;
51
+ return this.getElement().scrollTop;
52
52
  }
53
53
  /**
54
54
  * Scrolls to a specific position.
@@ -61,10 +61,10 @@ var ScrollableContainer = /*#__PURE__*/function () {
61
61
  // IE 11 doesn't seem to have a `.scrollTo()` method.
62
62
  // https://gitlab.com/catamphetamine/virtual-scroller/-/issues/10
63
63
  // https://stackoverflow.com/questions/39908825/window-scrollto-is-not-working-in-internet-explorer-11
64
- if (this.element.scrollTo) {
65
- this.element.scrollTo(0, scrollY);
64
+ if (this.getElement().scrollTo) {
65
+ this.getElement().scrollTo(0, scrollY);
66
66
  } else {
67
- this.element.scrollTop = scrollY;
67
+ this.getElement().scrollTop = scrollY;
68
68
  }
69
69
  }
70
70
  /**
@@ -76,7 +76,7 @@ var ScrollableContainer = /*#__PURE__*/function () {
76
76
  }, {
77
77
  key: "getWidth",
78
78
  value: function getWidth() {
79
- return this.element.offsetWidth;
79
+ return this.getElement().offsetWidth;
80
80
  }
81
81
  /**
82
82
  * Returns the height of the "scrollable container" itself.
@@ -87,10 +87,10 @@ var ScrollableContainer = /*#__PURE__*/function () {
87
87
  }, {
88
88
  key: "getHeight",
89
89
  value: function getHeight() {
90
- // if (!this.element && !precise) {
90
+ // if (!this.getElement() && !precise) {
91
91
  // return getScreenHeight()
92
92
  // }
93
- return this.element.offsetHeight;
93
+ return this.getElement().offsetHeight;
94
94
  }
95
95
  /**
96
96
  * Returns a "top offset" of an items container element
@@ -101,29 +101,28 @@ var ScrollableContainer = /*#__PURE__*/function () {
101
101
  }, {
102
102
  key: "getItemsContainerTopOffset",
103
103
  value: function getItemsContainerTopOffset() {
104
- var scrollableContainerTop = this.element.getBoundingClientRect().top;
105
- var scrollableContainerBorderTopWidth = this.element.clientTop;
104
+ var scrollableContainerTop = this.getElement().getBoundingClientRect().top;
105
+ var scrollableContainerBorderTopWidth = this.getElement().clientTop;
106
106
  var itemsContainerTop = this.getItemsContainerElement().getBoundingClientRect().top;
107
107
  return itemsContainerTop - scrollableContainerTop + this.getScrollY() - scrollableContainerBorderTopWidth;
108
108
  } // isVisible() {
109
- // const { top, bottom } = this.element.getBoundingClientRect()
109
+ // const { top, bottom } = this.getElement().getBoundingClientRect()
110
110
  // return bottom > 0 && top < getScreenHeight()
111
111
  // }
112
112
 
113
113
  /**
114
114
  * Adds a "scroll" event listener to the "scrollable container".
115
- * @param {onScroll} Should be called whenever the scroll position inside the "scrollable container" (potentially) changes.
115
+ * @param {onScrollListener} Should be called whenever the scroll position inside the "scrollable container" (potentially) changes.
116
116
  * @return {function} Returns a function that stops listening.
117
117
  */
118
118
 
119
119
  }, {
120
120
  key: "onScroll",
121
- value: function onScroll(_onScroll) {
122
- var _this = this;
123
-
124
- this.element.addEventListener('scroll', _onScroll);
121
+ value: function onScroll(onScrollListener) {
122
+ var element = this.getElement();
123
+ element.addEventListener('scroll', onScrollListener);
125
124
  return function () {
126
- return _this.element.removeEventListener('scroll', _onScroll);
125
+ return element.removeEventListener('scroll', onScrollListener);
127
126
  };
128
127
  }
129
128
  /**
@@ -135,8 +134,6 @@ var ScrollableContainer = /*#__PURE__*/function () {
135
134
  }, {
136
135
  key: "onResize",
137
136
  value: function onResize(_onResize) {
138
- var _this2 = this;
139
-
140
137
  // Watches "scrollable container"'s dimensions via a `ResizeObserver`.
141
138
  // https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver
142
139
  // https://web.dev/resize-observer/
@@ -146,7 +143,7 @@ var ScrollableContainer = /*#__PURE__*/function () {
146
143
  var resizeObserver = new ResizeObserver(function (entries) {
147
144
  // "one entry per observed element".
148
145
  // https://web.dev/resize-observer/
149
- // `entry.target === this.element`.
146
+ // `entry.target === this.getElement()`.
150
147
  var entry = entries[0]; // // If `entry.contentBoxSize` property is supported by the web browser.
151
148
  // if (entry.contentBoxSize) {
152
149
  // // https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserverEntry/contentBoxSize
@@ -156,10 +153,11 @@ var ScrollableContainer = /*#__PURE__*/function () {
156
153
 
157
154
  _onResize();
158
155
  });
159
- resizeObserver.observe(this.element);
156
+ var element = this.getElement();
157
+ resizeObserver.observe(element);
160
158
 
161
159
  unobserve = function unobserve() {
162
- return resizeObserver.unobserve(_this2.element);
160
+ return resizeObserver.unobserve(element);
163
161
  };
164
162
  } // I guess, if window is resized, `onResize()` will be triggered twice:
165
163
  // once for window resize, and once for the scrollable container resize.
@@ -199,7 +197,9 @@ var ScrollableWindowContainer = /*#__PURE__*/function (_ScrollableContainer) {
199
197
  function ScrollableWindowContainer(getItemsContainerElement) {
200
198
  _classCallCheck(this, ScrollableWindowContainer);
201
199
 
202
- return _super.call(this, window, getItemsContainerElement);
200
+ return _super.call(this, function () {
201
+ return window;
202
+ }, getItemsContainerElement);
203
203
  }
204
204
  /**
205
205
  * Returns the current scroll position.