virtual-scroller 1.16.2 → 1.16.4

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 (70) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/README.md +75 -35
  3. package/bundle/virtual-scroller-dom.js +1 -1
  4. package/bundle/virtual-scroller-dom.js.map +1 -1
  5. package/bundle/virtual-scroller-react.js +1 -1
  6. package/bundle/virtual-scroller-react.js.map +1 -1
  7. package/bundle/virtual-scroller.js +1 -1
  8. package/bundle/virtual-scroller.js.map +1 -1
  9. package/commonjs/DOM/ListTopOffsetWatcher.js +2 -4
  10. package/commonjs/DOM/ListTopOffsetWatcher.js.map +1 -1
  11. package/commonjs/Layout.test.js +26 -24
  12. package/commonjs/Layout.test.js.map +1 -1
  13. package/commonjs/Scroll.js +8 -11
  14. package/commonjs/Scroll.js.map +1 -1
  15. package/commonjs/VirtualScroller.constructor.js +7 -8
  16. package/commonjs/VirtualScroller.constructor.js.map +1 -1
  17. package/commonjs/VirtualScroller.js +10 -1
  18. package/commonjs/VirtualScroller.js.map +1 -1
  19. package/commonjs/VirtualScroller.layout.js +62 -20
  20. package/commonjs/VirtualScroller.layout.js.map +1 -1
  21. package/commonjs/VirtualScroller.onRender.js +25 -2
  22. package/commonjs/VirtualScroller.onRender.js.map +1 -1
  23. package/commonjs/VirtualScroller.state.js +39 -0
  24. package/commonjs/VirtualScroller.state.js.map +1 -1
  25. package/commonjs/react/useCreateVirtualScroller.js +1 -1
  26. package/commonjs/react/useCreateVirtualScroller.js.map +1 -1
  27. package/commonjs/test/VirtualScroller.js +8 -3
  28. package/commonjs/test/VirtualScroller.js.map +1 -1
  29. package/commonjs/utility/px.test.js +9 -5
  30. package/commonjs/utility/px.test.js.map +1 -1
  31. package/commonjs/utility/scheduleOnNextTick.js +25 -0
  32. package/commonjs/utility/scheduleOnNextTick.js.map +1 -0
  33. package/index.d.ts +4 -0
  34. package/modules/DOM/ListTopOffsetWatcher.js +1 -6
  35. package/modules/DOM/ListTopOffsetWatcher.js.map +1 -1
  36. package/modules/Layout.test.js +20 -19
  37. package/modules/Layout.test.js.map +1 -1
  38. package/modules/Scroll.js +8 -11
  39. package/modules/Scroll.js.map +1 -1
  40. package/modules/VirtualScroller.constructor.js +7 -8
  41. package/modules/VirtualScroller.constructor.js.map +1 -1
  42. package/modules/VirtualScroller.js +9 -1
  43. package/modules/VirtualScroller.js.map +1 -1
  44. package/modules/VirtualScroller.layout.js +61 -23
  45. package/modules/VirtualScroller.layout.js.map +1 -1
  46. package/modules/VirtualScroller.onRender.js +24 -2
  47. package/modules/VirtualScroller.onRender.js.map +1 -1
  48. package/modules/VirtualScroller.state.js +39 -1
  49. package/modules/VirtualScroller.state.js.map +1 -1
  50. package/modules/react/useCreateVirtualScroller.js +1 -1
  51. package/modules/react/useCreateVirtualScroller.js.map +1 -1
  52. package/modules/test/VirtualScroller.js +5 -2
  53. package/modules/test/VirtualScroller.js.map +1 -1
  54. package/modules/utility/px.test.js +5 -3
  55. package/modules/utility/px.test.js.map +1 -1
  56. package/modules/utility/scheduleOnNextTick.js +15 -0
  57. package/modules/utility/scheduleOnNextTick.js.map +1 -0
  58. package/package.json +6 -5
  59. package/source/DOM/ListTopOffsetWatcher.js +0 -6
  60. package/source/Layout.test.js +21 -20
  61. package/source/Scroll.js +7 -9
  62. package/source/VirtualScroller.constructor.js +7 -7
  63. package/source/VirtualScroller.js +8 -0
  64. package/source/VirtualScroller.layout.js +61 -25
  65. package/source/VirtualScroller.onRender.js +29 -3
  66. package/source/VirtualScroller.state.js +38 -0
  67. package/source/react/useCreateVirtualScroller.js +1 -1
  68. package/source/test/VirtualScroller.js +6 -2
  69. package/source/utility/px.test.js +6 -3
  70. package/source/utility/scheduleOnNextTick.js +16 -0
@@ -1 +1 @@
1
- {"version":3,"file":"VirtualScroller.onRender.js","names":["log","warn","reportError","isDebug","getStateSnapshot","shallowEqual","LAYOUT_REASON","setTbodyPadding","_onRender","newState","prevState","waitingForRender","onStateChange","isItemsContainerElementTableBody","getItemsContainerElement","beforeItemsHeight","afterItemsHeight","mostRecentSetStateValue","resetStateUpdateFlags","call","nonMeasuredItemsHaveBeenRendered","itemHeightHasChanged","widthHasChanged","layoutUpdateReason","ITEM_HEIGHT_CHANGED","NON_MEASURED_ITEMS_HAVE_BEEN_MEASURED","VIEWPORT_WIDTH_CHANGED","itemHeights","reset","verticalSpacing","undefined","previousItems","items","newItems","itemsDiff","getItemsDiff","prependedItemsCount","onPrepend","onNewItemsRendered","ITEMS_CHANGED","stateUpdate","firstShownItemIndex","lastShownItemIndex","verticalSpacingStateUpdate","measureItemHeightsAndSpacing","cleanedUpBeforeResize","beforeResize","cleanUpBeforeResizeItemHeights","scrollBy","scroll","scrollByY","_isActive","_afterRenderStateUpdateThatWasStopped","updateStateRightAfterRender","reason","updateState","newLayout","appendedItemsCount","getState","itemStates","itemHeightsThatChangedWhileNewItemsWereBeingRendered","Object","keys","i","Number","itemStatesThatChangedWhileNewItemsWereBeingRendered","previouslyCalculatedLayout","listHeightMeasurement","hasSnapshot","listBottomOffsetChange","getListBottomOffsetChange","shownItemsHeight","_useTimeoutInRenderLoop","cancelLayoutTimer","scheduleLayoutTimer","onUpdateShownItemIndexes","Boolean","firstNonMeasuredItemIndex","newItemsWillBeRendered","updateLayoutAfterRenderBecauseItemHeightChanged"],"sources":["../source/VirtualScroller.onRender.js"],"sourcesContent":["import log, { warn, reportError, isDebug } from './utility/debug.js'\r\nimport getStateSnapshot from './utility/getStateSnapshot.js'\r\nimport shallowEqual from './utility/shallowEqual.js'\r\nimport { LAYOUT_REASON } from './Layout.js'\r\nimport { setTbodyPadding } from './DOM/tbody.js'\r\n\r\nexport default function() {\r\n\t/**\r\n\t * Should be called right after updates to `state` have been rendered.\r\n\t * @param {object} newState\r\n\t * @param {object} [prevState]\r\n\t */\r\n\tthis._onRender = (newState, prevState) => {\r\n\t\tthis.waitingForRender = false\r\n\r\n\t\tlog('~ Rendered ~')\r\n\t\tif (isDebug()) {\r\n\t\t\tlog('State', getStateSnapshot(newState))\r\n\t\t}\r\n\r\n\t\tif (this.onStateChange) {\r\n\t\t\tif (!shallowEqual(newState, prevState)) {\r\n\t\t\t\tthis.onStateChange(newState)\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Update `<tbody/>` `padding`.\r\n\t\t// (`<tbody/>` is different in a way that it can't have `margin`, only `padding`).\r\n\t\t// https://gitlab.com/catamphetamine/virtual-scroller/-/issues/1\r\n\t\tif (this.isItemsContainerElementTableBody()) {\r\n\t\t\tsetTbodyPadding(\r\n\t\t\t\tthis.getItemsContainerElement(),\r\n\t\t\t\tnewState.beforeItemsHeight,\r\n\t\t\t\tnewState.afterItemsHeight\r\n\t\t\t)\r\n\t\t}\r\n\r\n\t\t// `this.mostRecentlySetState` checks that state management behavior is correct:\r\n\t\t// that in situations when there're multiple new states waiting to be set,\r\n\t\t// only the latest one gets applied.\r\n\t\t// It keeps the code simpler and prevents possible race condition bugs.\r\n\t\t// For example, `VirtualScroller` keeps track of its latest requested\r\n\t\t// state update in different instance variable flags which assume that\r\n\t\t// only that latest requested state update gets actually applied.\r\n\t\t//\r\n\t\t// This check should also be performed for the initial render in order to\r\n\t\t// guarantee that no potentially incorrect state update goes unnoticed.\r\n\t\t// Incorrect state updates could happen when `VirtualScroller` state\r\n\t\t// is managed externally by passing `getState()`/`updateState()` options.\r\n\t\t//\r\n\t\t// Perform the check only when `this.mostRecentSetStateValue` is defined.\r\n\t\t// `this.mostRecentSetStateValue` is normally gonna be `undefined` at the initial render\r\n\t\t// because the initial state is not set by calling `this.updateState()`.\r\n\t\t// At the same time, it is possible that the initial render is delayed\r\n\t\t// for whatever reason, and `this.updateState()` gets called before the initial render,\r\n\t\t// so `this.mostRecentSetStateValue` could also be defined at the initial render,\r\n\t\t// in which case the check should be performed.\r\n\t\t//\r\n\t\tif (this.mostRecentSetStateValue) {\r\n\t\t\t// \"Shallow equality\" is used here instead of \"strict equality\"\r\n\t\t\t// because a developer might choose to supply an `updateState()` function\r\n\t\t\t// rather than a `setState()` function, in which case the `updateState()` function\r\n\t\t\t// would construct its own state object.\r\n\t\t\tif (!shallowEqual(newState, this.mostRecentSetStateValue)) {\r\n\t\t\t\twarn('The most recent state that was set', getStateSnapshot(this.mostRecentSetStateValue))\r\n\t\t\t\treportError('`VirtualScroller` has been rendered with a `state` that is not equal to the most recently set one')\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// `this.resetStateUpdateFlags()` must be called before calling\r\n\t\t// `this.measureItemHeightsAndSpacing()`.\r\n\t\tconst {\r\n\t\t\tnonMeasuredItemsHaveBeenRendered,\r\n\t\t\titemHeightHasChanged,\r\n\t\t\twidthHasChanged\r\n\t\t} = resetStateUpdateFlags.call(this)\r\n\r\n\t\tlet layoutUpdateReason\r\n\r\n\t\tif (itemHeightHasChanged) {\r\n\t\t\tlayoutUpdateReason = LAYOUT_REASON.ITEM_HEIGHT_CHANGED\r\n\t\t}\r\n\r\n\t\tif (!prevState) {\r\n\t\t\tif (!layoutUpdateReason) {\r\n\t\t\t\treturn\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// If the `VirtualScroller`, while calculating layout parameters, encounters\r\n\t\t// a not-shown item with a non-measured height, it calls `updateState()` just to\r\n\t\t// render that item first, and then, after the list has been re-rendered, it measures\r\n\t\t// the item's height and then proceeds with calculating the correct layout parameters.\r\n\t\tif (nonMeasuredItemsHaveBeenRendered) {\r\n\t\t\tlayoutUpdateReason = LAYOUT_REASON.NON_MEASURED_ITEMS_HAVE_BEEN_MEASURED\r\n\t\t}\r\n\r\n\t\t// If scrollable container width has changed, and it has been re-rendered,\r\n\t\t// then it's time to measure the new item heights and then perform a re-layout\r\n\t\t// with the correctly calculated layout parameters.\r\n\t\t//\r\n\t\t// A re-layout is required because the layout parameters calculated on resize\r\n\t\t// are approximate ones, and the exact item heights aren't known at that point.\r\n\t\t// So on resize, it calls `updateState()` just to re-render the `VirtualScroller`.\r\n\t\t// After it has been re-rendered, it will measure item heights and then calculate\r\n\t\t// correct layout parameters.\r\n\t\t//\r\n\t\tif (widthHasChanged) {\r\n\t\t\tlayoutUpdateReason = LAYOUT_REASON.VIEWPORT_WIDTH_CHANGED\r\n\r\n\t\t\t// Reset measured item heights on viewport width change.\r\n\t\t\tthis.itemHeights.reset()\r\n\r\n\t\t\t// Reset `verticalSpacing` (will be re-measured).\r\n\t\t\tthis.verticalSpacing = undefined\r\n\t\t}\r\n\r\n\t\tif (prevState) {\r\n\t\t\tconst { items: previousItems } = prevState\r\n\t\t\tconst { items: newItems } = newState\r\n\t\t\t// Even if `this.newItemsWillBeRendered` flag is `true`,\r\n\t\t\t// `newItems` could still be equal to `previousItems`.\r\n\t\t\t// For example, when `updateState()` calls don't update `state` immediately\r\n\t\t\t// and a developer first calls `setItems(newItems)` and then calls `setItems(oldItems)`:\r\n\t\t\t// in that case, `this.newItemsWillBeRendered` flag will be `true` but the actual `items`\r\n\t\t\t// in state wouldn't have changed due to the first `updateState()` call being overwritten\r\n\t\t\t// by the second `updateState()` call (that's called \"batching state updates\" in React).\r\n\t\t\tif (newItems !== previousItems) {\r\n\t\t\t\tconst itemsDiff = this.getItemsDiff(previousItems, newItems)\r\n\t\t\t\tif (itemsDiff) {\r\n\t\t\t\t\t// The call to `.onPrepend()` must precede the call to `.measureItemHeights()`\r\n\t\t\t\t\t// which is called in `.onRender()`.\r\n\t\t\t\t\t// `this.itemHeights.onPrepend()` updates `firstMeasuredItemIndex`\r\n\t\t\t\t\t// and `lastMeasuredItemIndex` of `this.itemHeights`.\r\n\t\t\t\t\tconst { prependedItemsCount } = itemsDiff\r\n\t\t\t\t\tthis.itemHeights.onPrepend(prependedItemsCount)\r\n\t\t\t\t} else {\r\n\t\t\t\t\tthis.itemHeights.reset()\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (!widthHasChanged) {\r\n\t\t\t\t\t// The call to `this.onNewItemsRendered()` must precede the call to\r\n\t\t\t\t\t// `.measureItemHeights()` which is called in `.onRender()` because\r\n\t\t\t\t\t// `this.onNewItemsRendered()` updates `firstMeasuredItemIndex` and\r\n\t\t\t\t\t// `lastMeasuredItemIndex` of `this.itemHeights` in case of a prepend.\r\n\t\t\t\t\t//\r\n\t\t\t\t\t// If after prepending items the scroll position\r\n\t\t\t\t\t// should be \"restored\" so that there's no \"jump\" of content\r\n\t\t\t\t\t// then it means that all previous items have just been rendered\r\n\t\t\t\t\t// in a single pass, and there's no need to update layout again.\r\n\t\t\t\t\t//\r\n\t\t\t\t\tif (onNewItemsRendered.call(this, itemsDiff, newState) !== 'SEAMLESS_PREPEND') {\r\n\t\t\t\t\t\tlayoutUpdateReason = LAYOUT_REASON.ITEMS_CHANGED\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tlet stateUpdate\r\n\r\n\t\t// Re-measure item heights.\r\n\t\t// Also, measure vertical spacing (if not measured) and fix `<table/>` padding.\r\n\t\t//\r\n\t\t// This block should go after `if (newItems !== previousItems) {}`\r\n\t\t// because `this.itemHeights` can get `.reset()` there, which would\r\n\t\t// discard all the measurements done here, and having currently shown\r\n\t\t// item height measurements is required.\r\n\t\t//\r\n\t\tif (\r\n\t\t\t(prevState && (\r\n\t\t\t\tnewState.firstShownItemIndex !== prevState.firstShownItemIndex ||\r\n\t\t\t\tnewState.lastShownItemIndex !== prevState.lastShownItemIndex ||\r\n\t\t\t\tnewState.items !== prevState.items\r\n\t\t\t)) ||\r\n\t\t\twidthHasChanged\r\n\t\t) {\r\n\t\t\tconst verticalSpacingStateUpdate = this.measureItemHeightsAndSpacing()\r\n\t\t\tif (verticalSpacingStateUpdate) {\r\n\t\t\t\tstateUpdate = {\r\n\t\t\t\t\t...stateUpdate,\r\n\t\t\t\t\t...verticalSpacingStateUpdate\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Clean up \"before resize\" item heights and adjust the scroll position accordingly.\r\n\t\t// Calling `this.beforeResize.cleanUpBeforeResizeItemHeights()` might trigger\r\n\t\t// a `this.updateState()` call but that wouldn't matter because `beforeResize`\r\n\t\t// properties have already been modified directly in `state` (a hacky technique)\r\n\t\tconst cleanedUpBeforeResize = this.beforeResize.cleanUpBeforeResizeItemHeights()\r\n\t\tif (cleanedUpBeforeResize !== undefined) {\r\n\t\t\tconst { scrollBy, beforeResize } = cleanedUpBeforeResize\r\n\t\t\tlog('Correct scroll position by', scrollBy)\r\n\t\t\tthis.scroll.scrollByY(scrollBy)\r\n\t\t\tstateUpdate = {\r\n\t\t\t\t...stateUpdate,\r\n\t\t\t\tbeforeResize\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (!this._isActive) {\r\n\t\t\tthis._afterRenderStateUpdateThatWasStopped = stateUpdate\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\tif (layoutUpdateReason) {\r\n\t\t\tupdateStateRightAfterRender.call(this, {\r\n\t\t\t\tstateUpdate,\r\n\t\t\t\treason: layoutUpdateReason\r\n\t\t\t})\r\n\t\t} else if (stateUpdate) {\r\n\t\t\tthis.updateState(stateUpdate)\r\n\t\t} else {\r\n\t\t\tlog('~ Finished Layout ~')\r\n\t\t}\r\n\t}\r\n\r\n\t// After a new set of items has been rendered:\r\n\t//\r\n\t// * Restores scroll position when using `preserveScrollPositionOnPrependItems`\r\n\t// and items have been prepended.\r\n\t//\r\n\t// * Applies any \"pending\" `itemHeights` updates — those ones that happened\r\n\t// while an asynchronous `updateState()` call in `setItems()` was pending.\r\n\t//\r\n\t// * Either creates or resets the snapshot of the current layout.\r\n\t//\r\n\t// The current layout snapshot could be stored as a \"previously calculated layout\" variable\r\n\t// so that it could theoretically be used when calculating new layout incrementally\r\n\t// rather than from scratch, which would be an optimization.\r\n\t//\r\n\t// The \"previously calculated layout\" feature is not currently used.\r\n\t//\r\n\tfunction onNewItemsRendered(itemsDiff, newLayout) {\r\n\t\t// If it's an \"incremental\" update.\r\n\t\tif (itemsDiff) {\r\n\t\t\tconst {\r\n\t\t\t\tprependedItemsCount,\r\n\t\t\t\tappendedItemsCount\r\n\t\t\t} = itemsDiff\r\n\r\n\t\t\tconst {\r\n\t\t\t\titemHeights,\r\n\t\t\t\titemStates\r\n\t\t\t} = this.getState()\r\n\r\n\t\t\t// See if any items' heights changed while new items were being rendered.\r\n\t\t\tif (this.itemHeightsThatChangedWhileNewItemsWereBeingRendered) {\r\n\t\t\t\tfor (const i of Object.keys(this.itemHeightsThatChangedWhileNewItemsWereBeingRendered)) {\r\n\t\t\t\t\titemHeights[prependedItemsCount + Number(i)] = this.itemHeightsThatChangedWhileNewItemsWereBeingRendered[i]\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// See if any items' states changed while new items were being rendered.\r\n\t\t\tif (this.itemStatesThatChangedWhileNewItemsWereBeingRendered) {\r\n\t\t\t\tfor (const i of Object.keys(this.itemStatesThatChangedWhileNewItemsWereBeingRendered)) {\r\n\t\t\t\t\titemStates[prependedItemsCount + Number(i)] = this.itemStatesThatChangedWhileNewItemsWereBeingRendered[i]\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (prependedItemsCount === 0) {\r\n\t\t\t\t// Adjust `this.previouslyCalculatedLayout`.\r\n\t\t\t\tif (this.previouslyCalculatedLayout) {\r\n\t\t\t\t\tif (\r\n\t\t\t\t\t\tthis.previouslyCalculatedLayout.firstShownItemIndex === newLayout.firstShownItemIndex &&\r\n\t\t\t\t\t\tthis.previouslyCalculatedLayout.lastShownItemIndex === newLayout.lastShownItemIndex\r\n\t\t\t\t\t) {\r\n\t\t\t\t\t\t// `this.previouslyCalculatedLayout` stays the same.\r\n\t\t\t\t\t\t// `firstShownItemIndex` / `lastShownItemIndex` didn't get changed in `setItems()`,\r\n\t\t\t\t\t\t// so `beforeItemsHeight` and `shownItemsHeight` also stayed the same.\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\twarn('Unexpected (non-matching) \"firstShownItemIndex\" or \"lastShownItemIndex\" encountered in \"onRender()\" after appending items')\r\n\t\t\t\t\t\twarn('Previously calculated layout', this.previouslyCalculatedLayout)\r\n\t\t\t\t\t\twarn('New layout', newLayout)\r\n\t\t\t\t\t\tthis.previouslyCalculatedLayout = undefined\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\treturn 'SEAMLESS_APPEND'\r\n\t\t\t} else {\r\n\t\t\t\tif (this.listHeightMeasurement.hasSnapshot()) {\r\n\t\t\t\t\tif (newLayout.firstShownItemIndex === 0) {\r\n\t\t\t\t\t\t// Restore (adjust) scroll position.\r\n\t\t\t\t\t\tlog('~ Restore Scroll Position ~')\r\n\t\t\t\t\t\tconst listBottomOffsetChange = this.listHeightMeasurement.getListBottomOffsetChange({\r\n\t\t\t\t\t\t\tbeforeItemsHeight: newLayout.beforeItemsHeight\r\n\t\t\t\t\t\t})\r\n\t\t\t\t\t\tthis.listHeightMeasurement.reset()\r\n\t\t\t\t\t\tif (listBottomOffsetChange) {\r\n\t\t\t\t\t\t\tlog('Scroll down by', listBottomOffsetChange)\r\n\t\t\t\t\t\t\tthis.scroll.scrollByY(listBottomOffsetChange)\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tlog('Scroll position hasn\\'t changed')\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\t// Create new `this.previouslyCalculatedLayout`.\r\n\t\t\t\t\t\tif (this.previouslyCalculatedLayout) {\r\n\t\t\t\t\t\t\tif (\r\n\t\t\t\t\t\t\t\tthis.previouslyCalculatedLayout.firstShownItemIndex === 0 &&\r\n\t\t\t\t\t\t\t\tthis.previouslyCalculatedLayout.lastShownItemIndex === newLayout.lastShownItemIndex - prependedItemsCount\r\n\t\t\t\t\t\t\t) {\r\n\t\t\t\t\t\t\t\tthis.previouslyCalculatedLayout = {\r\n\t\t\t\t\t\t\t\t\tbeforeItemsHeight: 0,\r\n\t\t\t\t\t\t\t\t\tshownItemsHeight: this.previouslyCalculatedLayout.shownItemsHeight + listBottomOffsetChange,\r\n\t\t\t\t\t\t\t\t\tfirstShownItemIndex: 0,\r\n\t\t\t\t\t\t\t\t\tlastShownItemIndex: newLayout.lastShownItemIndex\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t\twarn('Unexpected (non-matching) \"firstShownItemIndex\" or \"lastShownItemIndex\" encountered in \"onRender()\" after prepending items')\r\n\t\t\t\t\t\t\t\twarn('Previously calculated layout', this.previouslyCalculatedLayout)\r\n\t\t\t\t\t\t\t\twarn('New layout', newLayout)\r\n\t\t\t\t\t\t\t\tthis.previouslyCalculatedLayout = undefined\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\treturn 'SEAMLESS_PREPEND'\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\twarn(`Unexpected \"firstShownItemIndex\" ${newLayout.firstShownItemIndex} encountered in \"onRender()\" after prepending items. Expected 0.`)\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Reset `this.previouslyCalculatedLayout` in any case other than\r\n\t\t// SEAMLESS_PREPEND or SEAMLESS_APPEND.\r\n\t\tthis.previouslyCalculatedLayout = undefined\r\n\t}\r\n\r\n\tfunction updateStateRightAfterRender({\r\n\t\treason,\r\n\t\tstateUpdate\r\n\t}) {\r\n\t\t// In React, `setTimeout()` is used to prevent a React error:\r\n\t\t// \"Maximum update depth exceeded.\r\n\t\t// This can happen when a component repeatedly calls\r\n\t\t// `.updateState()` inside `componentWillUpdate()` or `componentDidUpdate()`.\r\n\t\t// React limits the number of nested updates to prevent infinite loops.\"\r\n\t\tif (this._useTimeoutInRenderLoop) {\r\n\t\t\t// Cancel a previously scheduled re-layout.\r\n\t\t\tstateUpdate = this.cancelLayoutTimer({ stateUpdate })\r\n\t\t\t// Schedule a new re-layout.\r\n\t\t\tthis.scheduleLayoutTimer({\r\n\t\t\t\treason,\r\n\t\t\t\tstateUpdate\r\n\t\t\t})\r\n\t\t} else {\r\n\t\t\tthis.onUpdateShownItemIndexes({\r\n\t\t\t\treason,\r\n\t\t\t\tstateUpdate\r\n\t\t\t})\r\n\t\t}\r\n\t}\r\n\r\n\tfunction resetStateUpdateFlags() {\r\n\t\t// Read and reset `this.widthHasChanged` flag.\r\n\t\t//\r\n\t\t// If `this.widthHasChanged` flag was reset after calling\r\n\t\t// `this.measureWidthHeightsAndSpacingAndUpdateTablePadding()`\r\n\t\t// then there would be a bug because\r\n\t\t// `this.measureWidthHeightsAndSpacingAndUpdateTablePadding()`\r\n\t\t// calls `this.updateState({ verticalSpacing })` which calls\r\n\t\t// `this.onRender()` immediately, so `this.widthHasChanged`\r\n\t\t// flag wouldn't be reset by that time and would trigger things\r\n\t\t// like `this.itemHeights.reset()` a second time.\r\n\t\t//\r\n\t\t// So, instead read the value of `this.widthHasChanged` flag\r\n\t\t// and reset it right away to prevent any such potential bugs.\r\n\t\t//\r\n\t\tconst widthHasChanged = Boolean(this.widthHasChanged)\r\n\t\t//\r\n\t\t// Reset `this.widthHasChanged` flag.\r\n\t\tthis.widthHasChanged = undefined\r\n\r\n\t\t// Read `this.firstNonMeasuredItemIndex` flag.\r\n\t\tconst nonMeasuredItemsHaveBeenRendered = this.firstNonMeasuredItemIndex !== undefined\r\n\t\tif (nonMeasuredItemsHaveBeenRendered) {\r\n\t\t\tlog('Non-measured item index', this.firstNonMeasuredItemIndex)\r\n\t\t}\r\n\t\t// Reset `this.firstNonMeasuredItemIndex` flag.\r\n\t\tthis.firstNonMeasuredItemIndex = undefined\r\n\r\n\t\t// Reset `this.newItemsWillBeRendered` flag.\r\n\t\tthis.newItemsWillBeRendered = undefined\r\n\r\n\t\t// Reset `this.itemHeightsThatChangedWhileNewItemsWereBeingRendered`.\r\n\t\tthis.itemHeightsThatChangedWhileNewItemsWereBeingRendered = undefined\r\n\r\n\t\t// Reset `this.itemStatesThatChangedWhileNewItemsWereBeingRendered`.\r\n\t\tthis.itemStatesThatChangedWhileNewItemsWereBeingRendered = undefined\r\n\r\n\t\t// Reset `this.updateLayoutAfterRenderBecauseItemHeightChanged`.\r\n\t\tconst itemHeightHasChanged = this.updateLayoutAfterRenderBecauseItemHeightChanged\r\n\t\tthis.updateLayoutAfterRenderBecauseItemHeightChanged = undefined\r\n\r\n\t\treturn {\r\n\t\t\tnonMeasuredItemsHaveBeenRendered,\r\n\t\t\titemHeightHasChanged,\r\n\t\t\twidthHasChanged\r\n\t\t}\r\n\t}\r\n}"],"mappings":"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"}
1
+ {"version":3,"file":"VirtualScroller.onRender.js","names":["log","warn","reportError","isDebug","getStateSnapshot","shallowEqual","LAYOUT_REASON","setTbodyPadding","_onRender","newState","prevState","waitingForRender","onStateChange","isItemsContainerElementTableBody","getItemsContainerElement","beforeItemsHeight","afterItemsHeight","mostRecentSetStateValue","resetStateUpdateFlags","call","nonMeasuredItemsHaveBeenRendered","itemHeightHasChanged","widthHasChanged","layoutUpdateReason","ITEM_HEIGHT_CHANGED","NON_MEASURED_ITEMS_HAVE_BEEN_MEASURED","VIEWPORT_WIDTH_CHANGED","itemHeights","reset","verticalSpacing","undefined","previousItems","items","newItems","itemsDiff","getItemsDiff","prependedItemsCount","onPrepend","onNewItemsRendered","ITEMS_CHANGED","stateUpdate","firstShownItemIndex","lastShownItemIndex","verticalSpacingStateUpdate","measureItemHeightsAndSpacing","cleanedUpBeforeResize","beforeResize","cleanUpBeforeResizeItemHeights","scrollBy","scroll","scrollByY","_isActive","_afterRenderStateUpdateThatWasStopped","updateStateRightAfterRender","reason","updateState","newLayout","appendedItemsCount","getState","itemStates","itemHeightsThatChangedWhileNewItemsWereBeingRendered","Object","keys","i","Number","itemStatesThatChangedWhileNewItemsWereBeingRendered","previouslyCalculatedLayout","listHeightMeasurement","hasSnapshot","listBottomOffsetChange","getListBottomOffsetChange","shownItemsHeight","_delayRecursiveRenderUntilNextTick","_stateUpdateSequenceStartedAt","Date","now","UNINTERRUPTED_RECURSIVE_STATE_UPDATE_SEQUENCE_MAX_ALLOWED_DURATION","cancelLayoutTimer","scheduleLayoutTimer","onUpdateShownItemIndexes","Boolean","firstNonMeasuredItemIndex","newItemsWillBeRendered","updateLayoutAfterRenderBecauseItemHeightChanged","FPS","FRAME_DURATION"],"sources":["../source/VirtualScroller.onRender.js"],"sourcesContent":["import log, { warn, reportError, isDebug } from './utility/debug.js'\r\nimport getStateSnapshot from './utility/getStateSnapshot.js'\r\nimport shallowEqual from './utility/shallowEqual.js'\r\nimport { LAYOUT_REASON } from './Layout.js'\r\nimport { setTbodyPadding } from './DOM/tbody.js'\r\n\r\nexport default function() {\r\n\t/**\r\n\t * Should be called right after updates to `state` have been rendered.\r\n\t * @param {object} newState\r\n\t * @param {object} [prevState]\r\n\t */\r\n\tthis._onRender = (newState, prevState) => {\r\n\t\tthis.waitingForRender = false\r\n\r\n\t\tlog('~ Rendered ~')\r\n\t\tif (isDebug()) {\r\n\t\t\tlog('State', getStateSnapshot(newState))\r\n\t\t}\r\n\r\n\t\tif (this.onStateChange) {\r\n\t\t\tif (!shallowEqual(newState, prevState)) {\r\n\t\t\t\tthis.onStateChange(newState)\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Update `<tbody/>` `padding`.\r\n\t\t// (`<tbody/>` is different in a way that it can't have `margin`, only `padding`).\r\n\t\t// https://gitlab.com/catamphetamine/virtual-scroller/-/issues/1\r\n\t\tif (this.isItemsContainerElementTableBody()) {\r\n\t\t\tsetTbodyPadding(\r\n\t\t\t\tthis.getItemsContainerElement(),\r\n\t\t\t\tnewState.beforeItemsHeight,\r\n\t\t\t\tnewState.afterItemsHeight\r\n\t\t\t)\r\n\t\t}\r\n\r\n\t\t// `this.mostRecentlySetState` checks that state management behavior is correct:\r\n\t\t// that in situations when there're multiple new states waiting to be set,\r\n\t\t// only the latest one gets applied.\r\n\t\t// It keeps the code simpler and prevents possible race condition bugs.\r\n\t\t// For example, `VirtualScroller` keeps track of its latest requested\r\n\t\t// state update in different instance variable flags which assume that\r\n\t\t// only that latest requested state update gets actually applied.\r\n\t\t//\r\n\t\t// This check should also be performed for the initial render in order to\r\n\t\t// guarantee that no potentially incorrect state update goes unnoticed.\r\n\t\t// Incorrect state updates could happen when `VirtualScroller` state\r\n\t\t// is managed externally by passing `getState()`/`updateState()` options.\r\n\t\t//\r\n\t\t// Perform the check only when `this.mostRecentSetStateValue` is defined.\r\n\t\t// `this.mostRecentSetStateValue` is normally gonna be `undefined` at the initial render\r\n\t\t// because the initial state is not set by calling `this.updateState()`.\r\n\t\t// At the same time, it is possible that the initial render is delayed\r\n\t\t// for whatever reason, and `this.updateState()` gets called before the initial render,\r\n\t\t// so `this.mostRecentSetStateValue` could also be defined at the initial render,\r\n\t\t// in which case the check should be performed.\r\n\t\t//\r\n\t\tif (this.mostRecentSetStateValue) {\r\n\t\t\t// \"Shallow equality\" is used here instead of \"strict equality\"\r\n\t\t\t// because a developer might choose to supply an `updateState()` function\r\n\t\t\t// rather than a `setState()` function, in which case the `updateState()` function\r\n\t\t\t// would construct its own state object.\r\n\t\t\tif (!shallowEqual(newState, this.mostRecentSetStateValue)) {\r\n\t\t\t\twarn('The most recent state that was set', getStateSnapshot(this.mostRecentSetStateValue))\r\n\t\t\t\treportError('`VirtualScroller` has been rendered with a `state` that is not equal to the most recently set one')\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// `this.resetStateUpdateFlags()` must be called before calling\r\n\t\t// `this.measureItemHeightsAndSpacing()`.\r\n\t\tconst {\r\n\t\t\tnonMeasuredItemsHaveBeenRendered,\r\n\t\t\titemHeightHasChanged,\r\n\t\t\twidthHasChanged\r\n\t\t} = resetStateUpdateFlags.call(this)\r\n\r\n\t\tlet layoutUpdateReason\r\n\r\n\t\tif (itemHeightHasChanged) {\r\n\t\t\tlayoutUpdateReason = LAYOUT_REASON.ITEM_HEIGHT_CHANGED\r\n\t\t}\r\n\r\n\t\tif (!prevState) {\r\n\t\t\tif (!layoutUpdateReason) {\r\n\t\t\t\treturn\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// If the `VirtualScroller`, while calculating layout parameters, encounters\r\n\t\t// a not-shown item with a non-measured height, it calls `updateState()` just to\r\n\t\t// render that item first, and then, after the list has been re-rendered, it measures\r\n\t\t// the item's height and then proceeds with calculating the correct layout parameters.\r\n\t\tif (nonMeasuredItemsHaveBeenRendered) {\r\n\t\t\tlayoutUpdateReason = LAYOUT_REASON.NON_MEASURED_ITEMS_HAVE_BEEN_MEASURED\r\n\t\t}\r\n\r\n\t\t// If scrollable container width has changed, and it has been re-rendered,\r\n\t\t// then it's time to measure the new item heights and then perform a re-layout\r\n\t\t// with the correctly calculated layout parameters.\r\n\t\t//\r\n\t\t// A re-layout is required because the layout parameters calculated on resize\r\n\t\t// are approximate ones, and the exact item heights aren't known at that point.\r\n\t\t// So on resize, it calls `updateState()` just to re-render the `VirtualScroller`.\r\n\t\t// After it has been re-rendered, it will measure item heights and then calculate\r\n\t\t// correct layout parameters.\r\n\t\t//\r\n\t\tif (widthHasChanged) {\r\n\t\t\tlayoutUpdateReason = LAYOUT_REASON.VIEWPORT_WIDTH_CHANGED\r\n\r\n\t\t\t// Reset measured item heights on viewport width change.\r\n\t\t\tthis.itemHeights.reset()\r\n\r\n\t\t\t// Reset `verticalSpacing` (will be re-measured).\r\n\t\t\tthis.verticalSpacing = undefined\r\n\t\t}\r\n\r\n\t\tif (prevState) {\r\n\t\t\tconst { items: previousItems } = prevState\r\n\t\t\tconst { items: newItems } = newState\r\n\t\t\t// Even if `this.newItemsWillBeRendered` flag is `true`,\r\n\t\t\t// `newItems` could still be equal to `previousItems`.\r\n\t\t\t// For example, when `updateState()` calls don't update `state` immediately\r\n\t\t\t// and a developer first calls `setItems(newItems)` and then calls `setItems(oldItems)`:\r\n\t\t\t// in that case, `this.newItemsWillBeRendered` flag will be `true` but the actual `items`\r\n\t\t\t// in state wouldn't have changed due to the first `updateState()` call being overwritten\r\n\t\t\t// by the second `updateState()` call (that's called \"batching state updates\" in React).\r\n\t\t\tif (newItems !== previousItems) {\r\n\t\t\t\tconst itemsDiff = this.getItemsDiff(previousItems, newItems)\r\n\t\t\t\tif (itemsDiff) {\r\n\t\t\t\t\t// The call to `.onPrepend()` must precede the call to `.measureItemHeights()`\r\n\t\t\t\t\t// which is called in `.onRender()`.\r\n\t\t\t\t\t// `this.itemHeights.onPrepend()` updates `firstMeasuredItemIndex`\r\n\t\t\t\t\t// and `lastMeasuredItemIndex` of `this.itemHeights`.\r\n\t\t\t\t\tconst { prependedItemsCount } = itemsDiff\r\n\t\t\t\t\tthis.itemHeights.onPrepend(prependedItemsCount)\r\n\t\t\t\t} else {\r\n\t\t\t\t\tthis.itemHeights.reset()\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (!widthHasChanged) {\r\n\t\t\t\t\t// The call to `this.onNewItemsRendered()` must precede the call to\r\n\t\t\t\t\t// `.measureItemHeights()` which is called in `.onRender()` because\r\n\t\t\t\t\t// `this.onNewItemsRendered()` updates `firstMeasuredItemIndex` and\r\n\t\t\t\t\t// `lastMeasuredItemIndex` of `this.itemHeights` in case of a prepend.\r\n\t\t\t\t\t//\r\n\t\t\t\t\t// If after prepending items the scroll position\r\n\t\t\t\t\t// should be \"restored\" so that there's no \"jump\" of content\r\n\t\t\t\t\t// then it means that all previous items have just been rendered\r\n\t\t\t\t\t// in a single pass, and there's no need to update layout again.\r\n\t\t\t\t\t//\r\n\t\t\t\t\tif (onNewItemsRendered.call(this, itemsDiff, newState) !== 'SEAMLESS_PREPEND') {\r\n\t\t\t\t\t\tlayoutUpdateReason = LAYOUT_REASON.ITEMS_CHANGED\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tlet stateUpdate\r\n\r\n\t\t// Re-measure item heights.\r\n\t\t// Also, measure vertical spacing (if not measured) and fix `<table/>` padding.\r\n\t\t//\r\n\t\t// This block should go after `if (newItems !== previousItems) {}`\r\n\t\t// because `this.itemHeights` can get `.reset()` there, which would\r\n\t\t// discard all the measurements done here, and having currently shown\r\n\t\t// item height measurements is required.\r\n\t\t//\r\n\t\tif (\r\n\t\t\t(prevState && (\r\n\t\t\t\tnewState.firstShownItemIndex !== prevState.firstShownItemIndex ||\r\n\t\t\t\tnewState.lastShownItemIndex !== prevState.lastShownItemIndex ||\r\n\t\t\t\tnewState.items !== prevState.items\r\n\t\t\t)) ||\r\n\t\t\twidthHasChanged\r\n\t\t) {\r\n\t\t\tconst verticalSpacingStateUpdate = this.measureItemHeightsAndSpacing()\r\n\t\t\tif (verticalSpacingStateUpdate) {\r\n\t\t\t\tstateUpdate = {\r\n\t\t\t\t\t...stateUpdate,\r\n\t\t\t\t\t...verticalSpacingStateUpdate\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Clean up \"before resize\" item heights and adjust the scroll position accordingly.\r\n\t\t// Calling `this.beforeResize.cleanUpBeforeResizeItemHeights()` might trigger\r\n\t\t// a `this.updateState()` call but that wouldn't matter because `beforeResize`\r\n\t\t// properties have already been modified directly in `state` (a hacky technique)\r\n\t\tconst cleanedUpBeforeResize = this.beforeResize.cleanUpBeforeResizeItemHeights()\r\n\t\tif (cleanedUpBeforeResize !== undefined) {\r\n\t\t\tconst { scrollBy, beforeResize } = cleanedUpBeforeResize\r\n\t\t\tlog('Correct scroll position by', scrollBy)\r\n\t\t\tthis.scroll.scrollByY(scrollBy)\r\n\t\t\tstateUpdate = {\r\n\t\t\t\t...stateUpdate,\r\n\t\t\t\tbeforeResize\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (!this._isActive) {\r\n\t\t\tthis._afterRenderStateUpdateThatWasStopped = stateUpdate\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\tif (layoutUpdateReason) {\r\n\t\t\t// Update layout.\r\n\t\t\tupdateStateRightAfterRender.call(this, {\r\n\t\t\t\tstateUpdate,\r\n\t\t\t\treason: layoutUpdateReason\r\n\t\t\t})\r\n\t\t} else if (stateUpdate) {\r\n\t\t\t// Don't update layout. Just update some state.\r\n\t\t\t// `stateUpdate` isn't supposed to affect the layout in any way\r\n\t\t\t// because it doesn't contain any properties that affect the rendering of the list.\r\n\t\t\t// I.e. it doesn't contain properties like `beforeItemsHeight` or `afterItemsHeight`, etc.\r\n\t\t\tthis.updateState(stateUpdate)\r\n\t\t} else {\r\n\t\t\tlog('~ Finished Layout ~')\r\n\t\t}\r\n\t}\r\n\r\n\t// After a new set of items has been rendered:\r\n\t//\r\n\t// * Restores scroll position when using `preserveScrollPositionOnPrependItems`\r\n\t// and items have been prepended.\r\n\t//\r\n\t// * Applies any \"pending\" `itemHeights` updates — those ones that happened\r\n\t// while an asynchronous `updateState()` call in `setItems()` was pending.\r\n\t//\r\n\t// * Either creates or resets the snapshot of the current layout.\r\n\t//\r\n\t// The current layout snapshot could be stored as a \"previously calculated layout\" variable\r\n\t// so that it could theoretically be used when calculating new layout incrementally\r\n\t// rather than from scratch, which would be an optimization.\r\n\t//\r\n\t// The \"previously calculated layout\" feature is not currently used.\r\n\t//\r\n\tfunction onNewItemsRendered(itemsDiff, newLayout) {\r\n\t\t// If it's an \"incremental\" update.\r\n\t\tif (itemsDiff) {\r\n\t\t\tconst {\r\n\t\t\t\tprependedItemsCount,\r\n\t\t\t\tappendedItemsCount\r\n\t\t\t} = itemsDiff\r\n\r\n\t\t\tconst {\r\n\t\t\t\titemHeights,\r\n\t\t\t\titemStates\r\n\t\t\t} = this.getState()\r\n\r\n\t\t\t// See if any items' heights changed while new items were being rendered.\r\n\t\t\tif (this.itemHeightsThatChangedWhileNewItemsWereBeingRendered) {\r\n\t\t\t\tfor (const i of Object.keys(this.itemHeightsThatChangedWhileNewItemsWereBeingRendered)) {\r\n\t\t\t\t\titemHeights[prependedItemsCount + Number(i)] = this.itemHeightsThatChangedWhileNewItemsWereBeingRendered[i]\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// See if any items' states changed while new items were being rendered.\r\n\t\t\tif (this.itemStatesThatChangedWhileNewItemsWereBeingRendered) {\r\n\t\t\t\tfor (const i of Object.keys(this.itemStatesThatChangedWhileNewItemsWereBeingRendered)) {\r\n\t\t\t\t\titemStates[prependedItemsCount + Number(i)] = this.itemStatesThatChangedWhileNewItemsWereBeingRendered[i]\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (prependedItemsCount === 0) {\r\n\t\t\t\t// Adjust `this.previouslyCalculatedLayout`.\r\n\t\t\t\tif (this.previouslyCalculatedLayout) {\r\n\t\t\t\t\tif (\r\n\t\t\t\t\t\tthis.previouslyCalculatedLayout.firstShownItemIndex === newLayout.firstShownItemIndex &&\r\n\t\t\t\t\t\tthis.previouslyCalculatedLayout.lastShownItemIndex === newLayout.lastShownItemIndex\r\n\t\t\t\t\t) {\r\n\t\t\t\t\t\t// `this.previouslyCalculatedLayout` stays the same.\r\n\t\t\t\t\t\t// `firstShownItemIndex` / `lastShownItemIndex` didn't get changed in `setItems()`,\r\n\t\t\t\t\t\t// so `beforeItemsHeight` and `shownItemsHeight` also stayed the same.\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\twarn('Unexpected (non-matching) \"firstShownItemIndex\" or \"lastShownItemIndex\" encountered in \"onRender()\" after appending items')\r\n\t\t\t\t\t\twarn('Previously calculated layout', this.previouslyCalculatedLayout)\r\n\t\t\t\t\t\twarn('New layout', newLayout)\r\n\t\t\t\t\t\tthis.previouslyCalculatedLayout = undefined\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\treturn 'SEAMLESS_APPEND'\r\n\t\t\t} else {\r\n\t\t\t\tif (this.listHeightMeasurement.hasSnapshot()) {\r\n\t\t\t\t\tif (newLayout.firstShownItemIndex === 0) {\r\n\t\t\t\t\t\t// Restore (adjust) scroll position.\r\n\t\t\t\t\t\tlog('~ Restore Scroll Position ~')\r\n\t\t\t\t\t\tconst listBottomOffsetChange = this.listHeightMeasurement.getListBottomOffsetChange({\r\n\t\t\t\t\t\t\tbeforeItemsHeight: newLayout.beforeItemsHeight\r\n\t\t\t\t\t\t})\r\n\t\t\t\t\t\tthis.listHeightMeasurement.reset()\r\n\t\t\t\t\t\tif (listBottomOffsetChange) {\r\n\t\t\t\t\t\t\tlog('Scroll down by', listBottomOffsetChange)\r\n\t\t\t\t\t\t\tthis.scroll.scrollByY(listBottomOffsetChange)\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tlog('Scroll position hasn\\'t changed')\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\t// Create new `this.previouslyCalculatedLayout`.\r\n\t\t\t\t\t\tif (this.previouslyCalculatedLayout) {\r\n\t\t\t\t\t\t\tif (\r\n\t\t\t\t\t\t\t\tthis.previouslyCalculatedLayout.firstShownItemIndex === 0 &&\r\n\t\t\t\t\t\t\t\tthis.previouslyCalculatedLayout.lastShownItemIndex === newLayout.lastShownItemIndex - prependedItemsCount\r\n\t\t\t\t\t\t\t) {\r\n\t\t\t\t\t\t\t\tthis.previouslyCalculatedLayout = {\r\n\t\t\t\t\t\t\t\t\tbeforeItemsHeight: 0,\r\n\t\t\t\t\t\t\t\t\tshownItemsHeight: this.previouslyCalculatedLayout.shownItemsHeight + listBottomOffsetChange,\r\n\t\t\t\t\t\t\t\t\tfirstShownItemIndex: 0,\r\n\t\t\t\t\t\t\t\t\tlastShownItemIndex: newLayout.lastShownItemIndex\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t\twarn('Unexpected (non-matching) \"firstShownItemIndex\" or \"lastShownItemIndex\" encountered in \"onRender()\" after prepending items')\r\n\t\t\t\t\t\t\t\twarn('Previously calculated layout', this.previouslyCalculatedLayout)\r\n\t\t\t\t\t\t\t\twarn('New layout', newLayout)\r\n\t\t\t\t\t\t\t\tthis.previouslyCalculatedLayout = undefined\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\treturn 'SEAMLESS_PREPEND'\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\twarn(`Unexpected \"firstShownItemIndex\" ${newLayout.firstShownItemIndex} encountered in \"onRender()\" after prepending items. Expected 0.`)\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Reset `this.previouslyCalculatedLayout` in any case other than\r\n\t\t// SEAMLESS_PREPEND or SEAMLESS_APPEND.\r\n\t\tthis.previouslyCalculatedLayout = undefined\r\n\t}\r\n\r\n\tfunction updateStateRightAfterRender({\r\n\t\treason,\r\n\t\tstateUpdate\r\n\t}) {\r\n\t\t// React doesn't like it when `setState()` is called during render:\r\n\t\t//\r\n\t\t// \"Maximum update depth exceeded.\r\n\t\t// This can happen when a component repeatedly calls\r\n\t\t// `.updateState()` inside `componentWillUpdate()` or `componentDidUpdate()`.\r\n\t\t// React limits the number of nested updates to prevent infinite loops.\"\r\n\t\t//\r\n\t\t// To work around that, in React it always prefers a delayed state update\r\n\t\t// over an immediate state update right after a prevous state update.\r\n\t\t//\r\n\t\t// Another case when it should introduce an artificial momentary delay\r\n\t\t// in a chain of immediate \"syncrhonous\" re-renders is when such chain\r\n\t\t// of re-renders has been freezing the UI for far too long.\r\n\t\t//\r\n\t\tif (this._delayRecursiveRenderUntilNextTick || (\r\n\t\t\tthis._delayRecursiveRenderUntilNextTick !== false &&\r\n\t\t\tthis._stateUpdateSequenceStartedAt !== undefined &&\r\n\t\t\tDate.now() - this._stateUpdateSequenceStartedAt > UNINTERRUPTED_RECURSIVE_STATE_UPDATE_SEQUENCE_MAX_ALLOWED_DURATION\r\n\t\t)) {\r\n\t\t\t// Cancel a previously scheduled re-layout.\r\n\t\t\tstateUpdate = this.cancelLayoutTimer({ stateUpdate })\r\n\t\t\t// Schedule a new re-layout.\r\n\t\t\tthis.scheduleLayoutTimer({\r\n\t\t\t\treason,\r\n\t\t\t\tstateUpdate\r\n\t\t\t})\r\n\t\t} else {\r\n\t\t\tthis.onUpdateShownItemIndexes({\r\n\t\t\t\treason,\r\n\t\t\t\tstateUpdate\r\n\t\t\t})\r\n\t\t}\r\n\t}\r\n\r\n\tfunction resetStateUpdateFlags() {\r\n\t\t// Read and reset `this.widthHasChanged` flag.\r\n\t\t//\r\n\t\t// If `this.widthHasChanged` flag was reset after calling\r\n\t\t// `this.measureWidthHeightsAndSpacingAndUpdateTablePadding()`\r\n\t\t// then there would be a bug because\r\n\t\t// `this.measureWidthHeightsAndSpacingAndUpdateTablePadding()`\r\n\t\t// calls `this.updateState({ verticalSpacing })` which calls\r\n\t\t// `this.onRender()` immediately, so `this.widthHasChanged`\r\n\t\t// flag wouldn't be reset by that time and would trigger things\r\n\t\t// like `this.itemHeights.reset()` a second time.\r\n\t\t//\r\n\t\t// So, instead read the value of `this.widthHasChanged` flag\r\n\t\t// and reset it right away to prevent any such potential bugs.\r\n\t\t//\r\n\t\tconst widthHasChanged = Boolean(this.widthHasChanged)\r\n\t\t//\r\n\t\t// Reset `this.widthHasChanged` flag.\r\n\t\tthis.widthHasChanged = undefined\r\n\r\n\t\t// Read `this.firstNonMeasuredItemIndex` flag.\r\n\t\tconst nonMeasuredItemsHaveBeenRendered = this.firstNonMeasuredItemIndex !== undefined\r\n\t\tif (nonMeasuredItemsHaveBeenRendered) {\r\n\t\t\tlog('Non-measured item index', this.firstNonMeasuredItemIndex)\r\n\t\t}\r\n\t\t// Reset `this.firstNonMeasuredItemIndex` flag.\r\n\t\tthis.firstNonMeasuredItemIndex = undefined\r\n\r\n\t\t// Reset `this.newItemsWillBeRendered` flag.\r\n\t\tthis.newItemsWillBeRendered = undefined\r\n\r\n\t\t// Reset `this.itemHeightsThatChangedWhileNewItemsWereBeingRendered`.\r\n\t\tthis.itemHeightsThatChangedWhileNewItemsWereBeingRendered = undefined\r\n\r\n\t\t// Reset `this.itemStatesThatChangedWhileNewItemsWereBeingRendered`.\r\n\t\tthis.itemStatesThatChangedWhileNewItemsWereBeingRendered = undefined\r\n\r\n\t\t// Reset `this.updateLayoutAfterRenderBecauseItemHeightChanged`.\r\n\t\tconst itemHeightHasChanged = this.updateLayoutAfterRenderBecauseItemHeightChanged\r\n\t\tthis.updateLayoutAfterRenderBecauseItemHeightChanged = undefined\r\n\r\n\t\treturn {\r\n\t\t\tnonMeasuredItemsHaveBeenRendered,\r\n\t\t\titemHeightHasChanged,\r\n\t\t\twidthHasChanged\r\n\t\t}\r\n\t}\r\n}\r\n\r\nconst FPS = 60 // though 120 fps is common on smartphones these days.\r\nconst FRAME_DURATION = 1000 / FPS // in milliseconds\r\n\r\n// Allow recursive \"synchronous\" re-renders\r\n// until they start \"blocking\" the \"main thread\"\r\n// for so long that it starts causing \"frame drops\".\r\nconst UNINTERRUPTED_RECURSIVE_STATE_UPDATE_SEQUENCE_MAX_ALLOWED_DURATION = FRAME_DURATION"],"mappings":"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"}
@@ -7,7 +7,8 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
7
7
  import fillArray from './utility/fillArray.js';
8
8
  import log, { warn, isDebug, reportError } from './utility/debug.js';
9
9
  import { cleanUpBeforeResizeState } from './BeforeResize.js';
10
- import getStateSnapshot from './utility/getStateSnapshot.js'; // There're three main places where state is updated:
10
+ import getStateSnapshot from './utility/getStateSnapshot.js';
11
+ import { scheduleOnNextTick } from './utility/scheduleOnNextTick.js'; // There're three main places where state is updated:
11
12
  //
12
13
  // * On scroll.
13
14
  // * On window resize.
@@ -88,6 +89,43 @@ export default function createStateHelpers(_ref) {
88
89
  if (isDebug()) {
89
90
  log('~ Set state ~');
90
91
  log(getStateSnapshot(stateUpdate));
92
+ } // Start tracking the time that elapsed since the start of a state update,
93
+ // because by default a state update causes a "syncrhonous" re-render
94
+ // which could, in turn, require an immediate follow-up re-render,
95
+ // which could again require an immediate follow-up re-render, etc,
96
+ // causing a "synchronous" re-render recursion, potentially freezing the UI.
97
+ //
98
+ // An avalanche of immediate follow-up re-renders usually happens
99
+ // when there're a lot of items in the list — hundreds of thousands —
100
+ // and the user suddenly scrolls down at the very bottom of the list
101
+ // causing a long chain of re-renders when the list starts gradually rendering
102
+ // all the items from top to bottom until it gets to the bottom of the list.
103
+ //
104
+ // In order to prevent freezing the UI in such cases, and to provide the user
105
+ // with the ability to break away from this kind of recursion, `VirtualScroller`
106
+ // has to introduce a momentary delay between successive "synchronous" re-renders.
107
+ //
108
+ // At the same time, it should only introduce such artificial momentary delay
109
+ // when it's really required in order to not hinder the list's performance unnecessarily.
110
+ //
111
+ // A kind of "golen mean" then is to measure the time that a succession of
112
+ // "synchronous" re-renders has already been going for, and interrupt it
113
+ // with a momentary delay if it has been going on for too long.
114
+ // How much's too long? Well, it could be a duration of a single frame.
115
+ //
116
+ // P.S. If this `.updateState()` call was initiated from another `.updateState()` call,
117
+ // i.e. if it was done recursively, then the time tracking will have already been started.
118
+ //
119
+
120
+
121
+ if (_this._stateUpdateSequenceStartedAt === undefined) {
122
+ _this._stateUpdateSequenceStartedAt = Date.now(); // Automatically reset `this._stateUpdateSequenceStartedAt` variable on "next tick",
123
+ // i.e. outside of a "synchronous" recursion.
124
+
125
+ _this._stateUpdateSequenceStartedAtResetTimer = scheduleOnNextTick(function () {
126
+ _this._stateUpdateSequenceStartedAtResetTimer = undefined;
127
+ _this._stateUpdateSequenceStartedAt = undefined;
128
+ });
91
129
  } // Ensure that a non-initial `stateUpdate` can only contain an `items`
92
130
  // property when it comes from a `setItems()` call.
93
131
 
@@ -1 +1 @@
1
- {"version":3,"file":"VirtualScroller.state.js","names":["fillArray","log","warn","isDebug","reportError","cleanUpBeforeResizeState","getStateSnapshot","createStateHelpers","initialState","state","getInitialItemState","onStateChange","render","initialItems","items","_render","_setItemState","itemOrIndex","newItemState","i","_getItemIndexByItemOrIndex","undefined","JSON","stringify","getState","itemStates","newItemsWillBeRendered","itemStatesThatChangedWhileNewItemsWereBeingRendered","String","_getState","updateState","stateUpdate","_isSettingNewItems","waitingForRender","previousState","mostRecentSetStateValue","_setState","getInitialState","getRestoredState","call","getInitialStateFromScratch","useState","setState","_isActive","Error","_usesCustomStateStorage","newState","useDefaultStateStorage","defaultGetState","bind","defaultSetState","setInitialState","defaultSetInitialState","setUpState","onRender","getInitialLayoutState","beforeStart","Array","length","firstShownItemIndex","lastShownItemIndex","verticalSpacing","isStateColumnsCountMismatch","columnsCount","getActualColumnsCount","itemsCount","layout","getInitialLayoutValues","beforeItemsHeight","afterItemsHeight","itemHeights","onBeforeShowItems","getActualColumnsCountForState","stateColumnsCount","Math","floor"],"sources":["../source/VirtualScroller.state.js"],"sourcesContent":["import fillArray from './utility/fillArray.js'\r\nimport log, { warn, isDebug, reportError } from './utility/debug.js'\r\nimport { cleanUpBeforeResizeState } from './BeforeResize.js'\r\nimport getStateSnapshot from './utility/getStateSnapshot.js'\r\n\r\n// There're three main places where state is updated:\r\n//\r\n// * On scroll.\r\n// * On window resize.\r\n// * On set new items.\r\n//\r\n// State updates may be \"asynchronous\" (like in React), in which case the\r\n// corresponding operation is \"pending\" until the state update is applied.\r\n//\r\n// If there's a \"pending\" window resize or a \"pending\" update of the set of items,\r\n// then \"on scroll\" updates aren't dispatched.\r\n//\r\n// If there's a \"pending\" on scroll update and the window is resize or a new set\r\n// of items is set, then that \"pending\" on scroll update gets overwritten.\r\n//\r\n// If there's a \"pending\" update of the set of items, then window resize handler\r\n// sees that \"pending\" update and dispatches its own state update so that the\r\n// \"pending\" state update originating from `setItems()` is not lost.\r\n//\r\n// If there's a \"pending\" window resize, and a new set of items is set,\r\n// then the state update of the window resize handler gets overwritten.\r\n\r\nexport default function createStateHelpers({\r\n\tstate: initialState,\r\n\tgetInitialItemState,\r\n\tonStateChange,\r\n\trender,\r\n\titems: initialItems\r\n}) {\r\n\tthis.onStateChange = onStateChange\r\n\tthis._render = render\r\n\r\n\tthis.getInitialItemState = getInitialItemState\r\n\r\n\tthis._setItemState = (itemOrIndex, newItemState) => {\r\n\t\t// Item index.\r\n\t\tconst i = this._getItemIndexByItemOrIndex(itemOrIndex)\r\n\r\n\t\t// If the item wasn't found, the error was already reported,\r\n\t\t// so just return some \"sensible\" default value.\r\n\t\tif (i === undefined) {\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\tif (isDebug()) {\r\n\t\t\tlog('~ Item state changed ~')\r\n\t\t\tlog('Item index', i)\r\n\t\t\t// Uses `JSON.stringify()` here instead of just outputting the JSON objects as is\r\n\t\t\t// because outputting JSON objects as is would show different results later when\r\n\t\t\t// the developer inspects those in the web browser console if those state objects\r\n\t\t\t// get modified in between they've been output to the console and the developer\r\n\t\t\t// decided to inspect them.\r\n\t\t\tlog('Previous state' + '\\n' + JSON.stringify(this.getState().itemStates[i], null, 2))\r\n\t\t\tlog('New state' + '\\n' + JSON.stringify(newItemState, null, 2))\r\n\t\t}\r\n\r\n\t\tthis.getState().itemStates[i] = newItemState\r\n\r\n\t\t// If there was a request for `setState()` with new `items`, then the changes\r\n\t\t// to `currentState.itemStates[]` made above would be overwritten when that\r\n\t\t// pending `setState()` call gets applied.\r\n\t\t// To fix that, the updates to current `itemStates[]` are noted in\r\n\t\t// `this.itemStatesThatChangedWhileNewItemsWereBeingRendered` variable.\r\n\t\t// That variable is then checked when the `setState()` call with the new `items`\r\n\t\t// has been updated.\r\n\t\tif (this.newItemsWillBeRendered) {\r\n\t\t\tif (!this.itemStatesThatChangedWhileNewItemsWereBeingRendered) {\r\n\t\t\t\tthis.itemStatesThatChangedWhileNewItemsWereBeingRendered = {}\r\n\t\t\t}\r\n\t\t\tthis.itemStatesThatChangedWhileNewItemsWereBeingRendered[String(i)] = newItemState\r\n\t\t}\r\n\t}\r\n\r\n\tthis.getState = () => this._getState()\r\n\r\n\tthis.updateState = (stateUpdate) => {\r\n\t\tif (isDebug()) {\r\n\t\t\tlog('~ Set state ~')\r\n\t\t\tlog(getStateSnapshot(stateUpdate))\r\n\t\t}\r\n\r\n\t\t// Ensure that a non-initial `stateUpdate` can only contain an `items`\r\n\t\t// property when it comes from a `setItems()` call.\r\n\t\tif (stateUpdate.items) {\r\n\t\t\tif (!this._isSettingNewItems) {\r\n\t\t\t\treportError('A `stateUpdate` can only contain `items` property as a result of calling `.setItems()`')\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis._isSettingNewItems = undefined\r\n\r\n\t\tthis.waitingForRender = true\r\n\r\n\t\t// Store previous `state`.\r\n\t\tthis.previousState = this.getState()\r\n\r\n\t\t// If it's the first call to `this.updateState()` then initialize\r\n\t\t// the most recent `setState()` value to be the current state.\r\n\t\tif (!this.mostRecentSetStateValue) {\r\n\t\t\tthis.mostRecentSetStateValue = this.getState()\r\n\t\t}\r\n\r\n\t\t// Accumulates all \"pending\" state updates until they have been applied.\r\n\t\tthis.mostRecentSetStateValue = {\r\n\t\t\t...this.mostRecentSetStateValue,\r\n\t\t\t...stateUpdate\r\n\t\t}\r\n\r\n\t\t// Update `state`.\r\n\t\tthis._setState(this.mostRecentSetStateValue, stateUpdate)\r\n\t}\r\n\r\n\tthis.getInitialState = () => {\r\n\t\tif (initialState) {\r\n\t\t\treturn getRestoredState.call(this, initialState)\r\n\t\t}\r\n\t\treturn getInitialStateFromScratch.call(this, { getInitialItemState })\r\n\t}\r\n\r\n\tthis.useState = ({\r\n\t\tgetState,\r\n\t\tsetState,\r\n\t\tupdateState\r\n\t}) => {\r\n\t\tif (this._isActive) {\r\n\t\t\tthrow new Error('[virtual-scroller] `VirtualScroller` has already been started')\r\n\t\t}\r\n\r\n\t\tif (this._getState) {\r\n\t\t\tthrow new Error('[virtual-scroller] Custom state storage has already been configured')\r\n\t\t}\r\n\r\n\t\tif (render) {\r\n\t\t\tthrow new Error('[virtual-scroller] Creating a `VirtualScroller` class instance with a `render()` parameter implies using the default (internal) state storage')\r\n\t\t}\r\n\r\n\t\tif (setState && updateState) {\r\n\t\t\tthrow new Error('[virtual-scroller] When using a custom state storage, one must supply either `setState()` or `updateState()` function but not both')\r\n\t\t}\r\n\r\n\t\tif (!getState || !(setState || updateState)) {\r\n\t\t\tthrow new Error('[virtual-scroller] When using a custom state storage, one must supply both `getState()` and `setState()`/`updateState()` functions')\r\n\t\t}\r\n\r\n\t\tthis._usesCustomStateStorage = true\r\n\r\n\t\tthis._getState = getState\r\n\r\n\t\tthis._setState = (newState, stateUpdate) => {\r\n\t\t\tif (setState) {\r\n\t\t\t\tsetState(newState)\r\n\t\t\t} else {\r\n\t\t\t\tupdateState(stateUpdate)\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tthis.useDefaultStateStorage = () => {\r\n\t\tif (!render) {\r\n\t\t\tthrow new Error('[virtual-scroller] When using the default (internal) state management, one must supply a `render(state, prevState)` function parameter')\r\n\t\t}\r\n\r\n\t\t// Create default `getState()`/`setState()` functions.\r\n\t\tthis._getState = defaultGetState.bind(this)\r\n\t\tthis._setState = defaultSetState.bind(this)\r\n\r\n\t\t// When `state` is stored externally, a developer is responsible for\r\n\t\t// initializing it with the initial value.\r\n\t\t// Otherwise, if default state management is used, set the initial state now.\r\n\t\tconst setInitialState = defaultSetInitialState.bind(this)\r\n\t\tsetInitialState(this.getInitialState())\r\n\t}\r\n\r\n\tthis.setUpState = () => {\r\n\t\t// If no custom state storage has been configured, use the default one.\r\n\t\t// Also sets the initial state.\r\n\t\tif (!this._usesCustomStateStorage) {\r\n\t\t\tthis.useDefaultStateStorage()\r\n\t\t}\r\n\t}\r\n\r\n\tfunction defaultGetState() {\r\n\t\treturn this.state\r\n\t}\r\n\r\n\tfunction defaultSetInitialState(newState) {\r\n\t\tthis.state = newState\r\n\t}\r\n\r\n\tfunction defaultSetState(newState, stateUpdate) {\r\n\t\t// // Because the default state updates are \"synchronous\" (immediate),\r\n\t\t// // the `...stateUpdate` could be applied over `...this.state`,\r\n\t\t// // and no state updates would be lost.\r\n\t\t// // But if it was \"asynchronous\" (not immediate), then `...this.state`\r\n\t\t// // wouldn't work in all cases, because it could be stale in cases\r\n\t\t// // when more than a single `setState()` call is made before\r\n\t\t// // the state actually updates, making some properties of `this.state` stale.\r\n\t\t// this.state = {\r\n\t\t// \t...this.state,\r\n\t\t// \t...stateUpdate\r\n\t\t// }\r\n\r\n\t\tthis.state = newState\r\n\r\n\t\trender(this.state, this.previousState)\r\n\r\n\t\tthis.onRender()\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the initial state of the `VirtualScroller` \"from scratch\".\r\n\t * (i.e. not from a previously saved one).\r\n\t * @param {function} [options.getInitialItemState] — Gets initial item state.\r\n\t * @return {object}\r\n\t */\r\n\tfunction getInitialStateFromScratch({ getInitialItemState }) {\r\n\t\tconst items = initialItems\r\n\r\n\t\tconst state = {\r\n\t\t\t...getInitialLayoutState.call(this, items, { beforeStart: true }),\r\n\t\t\titems,\r\n\t\t\titemStates: fillArray(new Array(items.length), (i) => getInitialItemState(items[i]))\r\n\t\t}\r\n\r\n\t\tif (isDebug()) {\r\n\t\t\tlog('Initial state (autogenerated)', getStateSnapshot(state))\r\n\t\t}\r\n\t\tlog('First shown item index', state.firstShownItemIndex)\r\n\t\tlog('Last shown item index', state.lastShownItemIndex)\r\n\r\n\t\treturn state\r\n\t}\r\n\r\n\tfunction getRestoredState(state) {\r\n\t\tif (isDebug()) {\r\n\t\t\tlog('Restore state', getStateSnapshot(state))\r\n\t\t}\r\n\r\n\t\t// Possibly clean up \"before resize\" property in state.\r\n\t\t// \"Before resize\" state property is cleaned up when all \"before resize\" item heights\r\n\t\t// have been re-measured in an asynchronous `this.updateState({ beforeResize: undefined })` call.\r\n\t\t// If `VirtualScroller` state was snapshotted externally before that `this.updateState()` call\r\n\t\t// has been applied, then \"before resize\" property might have not been cleaned up properly.\r\n\t\tstate = cleanUpBeforeResizeState(state)\r\n\r\n\t\t// Reset `verticalSpacing` so that it re-measures it after the list\r\n\t\t// has been rendered initially. The rationale is that a previously captured\r\n\t\t// inter-item vertical spacing can't be \"trusted\" in a sense that the user\r\n\t\t// might have resized the window after the previous `state` has been snapshotted.\r\n\t\t// If the user has resized the window, then changing window width might have\r\n\t\t// activated different CSS `@media()` \"queries\" resulting in a potentially different\r\n\t\t// vertical spacing when the `VirtualScroller` is re-created with such previously\r\n\t\t// snapshotted state.\r\n\t\tstate = {\r\n\t\t\t...state,\r\n\t\t\tverticalSpacing: undefined\r\n\t\t}\r\n\r\n\t\t// `this.verticalSpacing` acts as a \"true\" source for vertical spacing value.\r\n\t\t// Vertical spacing is also stored in `state` but `state` updates could be\r\n\t\t// \"asynchronous\" (not applied immediately) and `this.onUpdateShownItemIndexes()`\r\n\t\t// requires vertical spacing to be correct at any time, without any delays.\r\n\t\t// So, vertical spacing is also duplicated in `state`, but the \"true\" source\r\n\t\t// is still `this.verticalSpacing`.\r\n\t\t//\r\n\t\t// `this.verticalSpacing` must be initialized before calling `this.getInitialStateFromScratch()`\r\n\t\t// because `this.getInitialStateFromScratch()` uses `this.verticalSpacing` in its calculations.\r\n\t\t//\r\n\t\t// With the code above, `state.verticalSpacing` is always gonna be `undefined`,\r\n\t\t// so commented out this code. It's safer to just re-measure vertical spacing\r\n\t\t// from scratch when `VirtualScroller` is mounted.\r\n\t\t//\r\n\t\t// this.verticalSpacing = state ? state.verticalSpacing : undefined\r\n\r\n\t\t// Check if the actual `columnsCount` on the screen matches the one from state.\r\n\t\tif (isStateColumnsCountMismatch(state, {\r\n\t\t\tcolumnsCount: this.getActualColumnsCount()\r\n\t\t})) {\r\n\t\t\twarn('Reset Layout')\r\n\t\t\tstate = {\r\n\t\t\t\t...state,\r\n\t\t\t\t...getInitialLayoutState.call(this, state.items, { beforeStart: false })\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn state\r\n\t}\r\n\r\n\tfunction getInitialLayoutState(items, { beforeStart }) {\r\n\t\tconst itemsCount = items.length\r\n\r\n\t\tconst {\r\n\t\t\tfirstShownItemIndex,\r\n\t\t\tlastShownItemIndex,\r\n\t\t\tbeforeItemsHeight,\r\n\t\t\tafterItemsHeight\r\n\t\t} = this.layout.getInitialLayoutValues({\r\n\t\t\titemsCount,\r\n\t\t\tcolumnsCount: this.getActualColumnsCount(),\r\n\t\t\tbeforeStart\r\n\t\t})\r\n\r\n\t\tconst itemHeights = new Array(itemsCount)\r\n\r\n\t\t// Optionally preload items to be rendered.\r\n\t\tthis.onBeforeShowItems(\r\n\t\t\titems,\r\n\t\t\titemHeights,\r\n\t\t\tfirstShownItemIndex,\r\n\t\t\tlastShownItemIndex\r\n\t\t)\r\n\r\n\t\treturn {\r\n\t\t\titemHeights,\r\n\t\t\tcolumnsCount: this.getActualColumnsCountForState(),\r\n\t\t\tverticalSpacing: this.verticalSpacing,\r\n\t\t\tfirstShownItemIndex,\r\n\t\t\tlastShownItemIndex,\r\n\t\t\tbeforeItemsHeight,\r\n\t\t\tafterItemsHeight\r\n\t\t}\r\n\t}\r\n\r\n\t// Checks if the actual `columnsCount` on the screen matches the one from state.\r\n\t//\r\n\t// For example, a developer might snapshot `VirtualScroller` state\r\n\t// when the user navigates from the page containing the list\r\n\t// in order to later restore the list's state when the user goes \"Back\".\r\n\t// But, the user might have also resized the window while being on that\r\n\t// \"other\" page, and when they come \"Back\", their snapshotted state\r\n\t// no longer qualifies. Well, it does qualify, but only partially.\r\n\t// For example, `itemStates` are still valid, but first and last shown\r\n\t// item indexes aren't.\r\n\t//\r\n\tfunction isStateColumnsCountMismatch(state, { columnsCount }) {\r\n\t\tconst stateColumnsCount = state.columnsCount || 1\r\n\t\tif (stateColumnsCount !== columnsCount) {\r\n\t\t\twarn('~ Columns Count changed from', stateColumnsCount, 'to', columnsCount, '~')\r\n\t\t\treturn true\r\n\t\t}\r\n\t\tconst firstShownItemIndex = Math.floor(state.firstShownItemIndex / columnsCount) * columnsCount\r\n\t\tif (firstShownItemIndex !== state.firstShownItemIndex) {\r\n\t\t\twarn('~ First Shown Item Index', state.firstShownItemIndex, 'is not divisible by Columns Count', columnsCount, '~')\r\n\t\t\treturn true\r\n\t\t}\r\n\t}\r\n}"],"mappings":"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"}
1
+ {"version":3,"file":"VirtualScroller.state.js","names":["fillArray","log","warn","isDebug","reportError","cleanUpBeforeResizeState","getStateSnapshot","scheduleOnNextTick","createStateHelpers","initialState","state","getInitialItemState","onStateChange","render","initialItems","items","_render","_setItemState","itemOrIndex","newItemState","i","_getItemIndexByItemOrIndex","undefined","JSON","stringify","getState","itemStates","newItemsWillBeRendered","itemStatesThatChangedWhileNewItemsWereBeingRendered","String","_getState","updateState","stateUpdate","_stateUpdateSequenceStartedAt","Date","now","_stateUpdateSequenceStartedAtResetTimer","_isSettingNewItems","waitingForRender","previousState","mostRecentSetStateValue","_setState","getInitialState","getRestoredState","call","getInitialStateFromScratch","useState","setState","_isActive","Error","_usesCustomStateStorage","newState","useDefaultStateStorage","defaultGetState","bind","defaultSetState","setInitialState","defaultSetInitialState","setUpState","onRender","getInitialLayoutState","beforeStart","Array","length","firstShownItemIndex","lastShownItemIndex","verticalSpacing","isStateColumnsCountMismatch","columnsCount","getActualColumnsCount","itemsCount","layout","getInitialLayoutValues","beforeItemsHeight","afterItemsHeight","itemHeights","onBeforeShowItems","getActualColumnsCountForState","stateColumnsCount","Math","floor"],"sources":["../source/VirtualScroller.state.js"],"sourcesContent":["import fillArray from './utility/fillArray.js'\r\nimport log, { warn, isDebug, reportError } from './utility/debug.js'\r\nimport { cleanUpBeforeResizeState } from './BeforeResize.js'\r\nimport getStateSnapshot from './utility/getStateSnapshot.js'\r\nimport { scheduleOnNextTick } from './utility/scheduleOnNextTick.js'\r\n\r\n// There're three main places where state is updated:\r\n//\r\n// * On scroll.\r\n// * On window resize.\r\n// * On set new items.\r\n//\r\n// State updates may be \"asynchronous\" (like in React), in which case the\r\n// corresponding operation is \"pending\" until the state update is applied.\r\n//\r\n// If there's a \"pending\" window resize or a \"pending\" update of the set of items,\r\n// then \"on scroll\" updates aren't dispatched.\r\n//\r\n// If there's a \"pending\" on scroll update and the window is resize or a new set\r\n// of items is set, then that \"pending\" on scroll update gets overwritten.\r\n//\r\n// If there's a \"pending\" update of the set of items, then window resize handler\r\n// sees that \"pending\" update and dispatches its own state update so that the\r\n// \"pending\" state update originating from `setItems()` is not lost.\r\n//\r\n// If there's a \"pending\" window resize, and a new set of items is set,\r\n// then the state update of the window resize handler gets overwritten.\r\n\r\nexport default function createStateHelpers({\r\n\tstate: initialState,\r\n\tgetInitialItemState,\r\n\tonStateChange,\r\n\trender,\r\n\titems: initialItems\r\n}) {\r\n\tthis.onStateChange = onStateChange\r\n\tthis._render = render\r\n\r\n\tthis.getInitialItemState = getInitialItemState\r\n\r\n\tthis._setItemState = (itemOrIndex, newItemState) => {\r\n\t\t// Item index.\r\n\t\tconst i = this._getItemIndexByItemOrIndex(itemOrIndex)\r\n\r\n\t\t// If the item wasn't found, the error was already reported,\r\n\t\t// so just return some \"sensible\" default value.\r\n\t\tif (i === undefined) {\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\tif (isDebug()) {\r\n\t\t\tlog('~ Item state changed ~')\r\n\t\t\tlog('Item index', i)\r\n\t\t\t// Uses `JSON.stringify()` here instead of just outputting the JSON objects as is\r\n\t\t\t// because outputting JSON objects as is would show different results later when\r\n\t\t\t// the developer inspects those in the web browser console if those state objects\r\n\t\t\t// get modified in between they've been output to the console and the developer\r\n\t\t\t// decided to inspect them.\r\n\t\t\tlog('Previous state' + '\\n' + JSON.stringify(this.getState().itemStates[i], null, 2))\r\n\t\t\tlog('New state' + '\\n' + JSON.stringify(newItemState, null, 2))\r\n\t\t}\r\n\r\n\t\tthis.getState().itemStates[i] = newItemState\r\n\r\n\t\t// If there was a request for `setState()` with new `items`, then the changes\r\n\t\t// to `currentState.itemStates[]` made above would be overwritten when that\r\n\t\t// pending `setState()` call gets applied.\r\n\t\t// To fix that, the updates to current `itemStates[]` are noted in\r\n\t\t// `this.itemStatesThatChangedWhileNewItemsWereBeingRendered` variable.\r\n\t\t// That variable is then checked when the `setState()` call with the new `items`\r\n\t\t// has been updated.\r\n\t\tif (this.newItemsWillBeRendered) {\r\n\t\t\tif (!this.itemStatesThatChangedWhileNewItemsWereBeingRendered) {\r\n\t\t\t\tthis.itemStatesThatChangedWhileNewItemsWereBeingRendered = {}\r\n\t\t\t}\r\n\t\t\tthis.itemStatesThatChangedWhileNewItemsWereBeingRendered[String(i)] = newItemState\r\n\t\t}\r\n\t}\r\n\r\n\tthis.getState = () => this._getState()\r\n\r\n\tthis.updateState = (stateUpdate) => {\r\n\t\tif (isDebug()) {\r\n\t\t\tlog('~ Set state ~')\r\n\t\t\tlog(getStateSnapshot(stateUpdate))\r\n\t\t}\r\n\r\n\t\t// Start tracking the time that elapsed since the start of a state update,\r\n\t\t// because by default a state update causes a \"syncrhonous\" re-render\r\n\t\t// which could, in turn, require an immediate follow-up re-render,\r\n\t\t// which could again require an immediate follow-up re-render, etc,\r\n\t\t// causing a \"synchronous\" re-render recursion, potentially freezing the UI.\r\n\t\t//\r\n\t\t// An avalanche of immediate follow-up re-renders usually happens\r\n\t\t// when there're a lot of items in the list — hundreds of thousands —\r\n\t\t// and the user suddenly scrolls down at the very bottom of the list\r\n\t\t// causing a long chain of re-renders when the list starts gradually rendering\r\n\t\t// all the items from top to bottom until it gets to the bottom of the list.\r\n\t\t//\r\n\t\t// In order to prevent freezing the UI in such cases, and to provide the user\r\n\t\t// with the ability to break away from this kind of recursion, `VirtualScroller`\r\n\t\t// has to introduce a momentary delay between successive \"synchronous\" re-renders.\r\n\t\t//\r\n\t\t// At the same time, it should only introduce such artificial momentary delay\r\n\t\t// when it's really required in order to not hinder the list's performance unnecessarily.\r\n\t\t//\r\n\t\t// A kind of \"golen mean\" then is to measure the time that a succession of\r\n\t\t// \"synchronous\" re-renders has already been going for, and interrupt it\r\n\t\t// with a momentary delay if it has been going on for too long.\r\n\t\t// How much's too long? Well, it could be a duration of a single frame.\r\n\t\t//\r\n\t\t// P.S. If this `.updateState()` call was initiated from another `.updateState()` call,\r\n\t\t// i.e. if it was done recursively, then the time tracking will have already been started.\r\n\t\t//\r\n\t\tif (this._stateUpdateSequenceStartedAt === undefined) {\r\n\t\t\tthis._stateUpdateSequenceStartedAt = Date.now()\r\n\t\t\t// Automatically reset `this._stateUpdateSequenceStartedAt` variable on \"next tick\",\r\n\t\t\t// i.e. outside of a \"synchronous\" recursion.\r\n\t\t\tthis._stateUpdateSequenceStartedAtResetTimer = scheduleOnNextTick(() => {\r\n\t\t\t\tthis._stateUpdateSequenceStartedAtResetTimer = undefined\r\n\t\t\t\tthis._stateUpdateSequenceStartedAt = undefined\r\n\t\t\t})\r\n\t\t}\r\n\r\n\t\t// Ensure that a non-initial `stateUpdate` can only contain an `items`\r\n\t\t// property when it comes from a `setItems()` call.\r\n\t\tif (stateUpdate.items) {\r\n\t\t\tif (!this._isSettingNewItems) {\r\n\t\t\t\treportError('A `stateUpdate` can only contain `items` property as a result of calling `.setItems()`')\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis._isSettingNewItems = undefined\r\n\r\n\t\tthis.waitingForRender = true\r\n\r\n\t\t// Store previous `state`.\r\n\t\tthis.previousState = this.getState()\r\n\r\n\t\t// If it's the first call to `this.updateState()` then initialize\r\n\t\t// the most recent `setState()` value to be the current state.\r\n\t\tif (!this.mostRecentSetStateValue) {\r\n\t\t\tthis.mostRecentSetStateValue = this.getState()\r\n\t\t}\r\n\r\n\t\t// Accumulates all \"pending\" state updates until they have been applied.\r\n\t\tthis.mostRecentSetStateValue = {\r\n\t\t\t...this.mostRecentSetStateValue,\r\n\t\t\t...stateUpdate\r\n\t\t}\r\n\r\n\t\t// Update `state`.\r\n\t\tthis._setState(this.mostRecentSetStateValue, stateUpdate)\r\n\t}\r\n\r\n\tthis.getInitialState = () => {\r\n\t\tif (initialState) {\r\n\t\t\treturn getRestoredState.call(this, initialState)\r\n\t\t}\r\n\t\treturn getInitialStateFromScratch.call(this, { getInitialItemState })\r\n\t}\r\n\r\n\tthis.useState = ({\r\n\t\tgetState,\r\n\t\tsetState,\r\n\t\tupdateState\r\n\t}) => {\r\n\t\tif (this._isActive) {\r\n\t\t\tthrow new Error('[virtual-scroller] `VirtualScroller` has already been started')\r\n\t\t}\r\n\r\n\t\tif (this._getState) {\r\n\t\t\tthrow new Error('[virtual-scroller] Custom state storage has already been configured')\r\n\t\t}\r\n\r\n\t\tif (render) {\r\n\t\t\tthrow new Error('[virtual-scroller] Creating a `VirtualScroller` class instance with a `render()` parameter implies using the default (internal) state storage')\r\n\t\t}\r\n\r\n\t\tif (setState && updateState) {\r\n\t\t\tthrow new Error('[virtual-scroller] When using a custom state storage, one must supply either `setState()` or `updateState()` function but not both')\r\n\t\t}\r\n\r\n\t\tif (!getState || !(setState || updateState)) {\r\n\t\t\tthrow new Error('[virtual-scroller] When using a custom state storage, one must supply both `getState()` and `setState()`/`updateState()` functions')\r\n\t\t}\r\n\r\n\t\tthis._usesCustomStateStorage = true\r\n\r\n\t\tthis._getState = getState\r\n\r\n\t\tthis._setState = (newState, stateUpdate) => {\r\n\t\t\tif (setState) {\r\n\t\t\t\tsetState(newState)\r\n\t\t\t} else {\r\n\t\t\t\tupdateState(stateUpdate)\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tthis.useDefaultStateStorage = () => {\r\n\t\tif (!render) {\r\n\t\t\tthrow new Error('[virtual-scroller] When using the default (internal) state management, one must supply a `render(state, prevState)` function parameter')\r\n\t\t}\r\n\r\n\t\t// Create default `getState()`/`setState()` functions.\r\n\t\tthis._getState = defaultGetState.bind(this)\r\n\t\tthis._setState = defaultSetState.bind(this)\r\n\r\n\t\t// When `state` is stored externally, a developer is responsible for\r\n\t\t// initializing it with the initial value.\r\n\t\t// Otherwise, if default state management is used, set the initial state now.\r\n\t\tconst setInitialState = defaultSetInitialState.bind(this)\r\n\t\tsetInitialState(this.getInitialState())\r\n\t}\r\n\r\n\tthis.setUpState = () => {\r\n\t\t// If no custom state storage has been configured, use the default one.\r\n\t\t// Also sets the initial state.\r\n\t\tif (!this._usesCustomStateStorage) {\r\n\t\t\tthis.useDefaultStateStorage()\r\n\t\t}\r\n\t}\r\n\r\n\tfunction defaultGetState() {\r\n\t\treturn this.state\r\n\t}\r\n\r\n\tfunction defaultSetInitialState(newState) {\r\n\t\tthis.state = newState\r\n\t}\r\n\r\n\tfunction defaultSetState(newState, stateUpdate) {\r\n\t\t// // Because the default state updates are \"synchronous\" (immediate),\r\n\t\t// // the `...stateUpdate` could be applied over `...this.state`,\r\n\t\t// // and no state updates would be lost.\r\n\t\t// // But if it was \"asynchronous\" (not immediate), then `...this.state`\r\n\t\t// // wouldn't work in all cases, because it could be stale in cases\r\n\t\t// // when more than a single `setState()` call is made before\r\n\t\t// // the state actually updates, making some properties of `this.state` stale.\r\n\t\t// this.state = {\r\n\t\t// \t...this.state,\r\n\t\t// \t...stateUpdate\r\n\t\t// }\r\n\r\n\t\tthis.state = newState\r\n\r\n\t\trender(this.state, this.previousState)\r\n\r\n\t\tthis.onRender()\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the initial state of the `VirtualScroller` \"from scratch\".\r\n\t * (i.e. not from a previously saved one).\r\n\t * @param {function} [options.getInitialItemState] — Gets initial item state.\r\n\t * @return {object}\r\n\t */\r\n\tfunction getInitialStateFromScratch({ getInitialItemState }) {\r\n\t\tconst items = initialItems\r\n\r\n\t\tconst state = {\r\n\t\t\t...getInitialLayoutState.call(this, items, { beforeStart: true }),\r\n\t\t\titems,\r\n\t\t\titemStates: fillArray(new Array(items.length), (i) => getInitialItemState(items[i]))\r\n\t\t}\r\n\r\n\t\tif (isDebug()) {\r\n\t\t\tlog('Initial state (autogenerated)', getStateSnapshot(state))\r\n\t\t}\r\n\t\tlog('First shown item index', state.firstShownItemIndex)\r\n\t\tlog('Last shown item index', state.lastShownItemIndex)\r\n\r\n\t\treturn state\r\n\t}\r\n\r\n\tfunction getRestoredState(state) {\r\n\t\tif (isDebug()) {\r\n\t\t\tlog('Restore state', getStateSnapshot(state))\r\n\t\t}\r\n\r\n\t\t// Possibly clean up \"before resize\" property in state.\r\n\t\t// \"Before resize\" state property is cleaned up when all \"before resize\" item heights\r\n\t\t// have been re-measured in an asynchronous `this.updateState({ beforeResize: undefined })` call.\r\n\t\t// If `VirtualScroller` state was snapshotted externally before that `this.updateState()` call\r\n\t\t// has been applied, then \"before resize\" property might have not been cleaned up properly.\r\n\t\tstate = cleanUpBeforeResizeState(state)\r\n\r\n\t\t// Reset `verticalSpacing` so that it re-measures it after the list\r\n\t\t// has been rendered initially. The rationale is that a previously captured\r\n\t\t// inter-item vertical spacing can't be \"trusted\" in a sense that the user\r\n\t\t// might have resized the window after the previous `state` has been snapshotted.\r\n\t\t// If the user has resized the window, then changing window width might have\r\n\t\t// activated different CSS `@media()` \"queries\" resulting in a potentially different\r\n\t\t// vertical spacing when the `VirtualScroller` is re-created with such previously\r\n\t\t// snapshotted state.\r\n\t\tstate = {\r\n\t\t\t...state,\r\n\t\t\tverticalSpacing: undefined\r\n\t\t}\r\n\r\n\t\t// `this.verticalSpacing` acts as a \"true\" source for vertical spacing value.\r\n\t\t// Vertical spacing is also stored in `state` but `state` updates could be\r\n\t\t// \"asynchronous\" (not applied immediately) and `this.onUpdateShownItemIndexes()`\r\n\t\t// requires vertical spacing to be correct at any time, without any delays.\r\n\t\t// So, vertical spacing is also duplicated in `state`, but the \"true\" source\r\n\t\t// is still `this.verticalSpacing`.\r\n\t\t//\r\n\t\t// `this.verticalSpacing` must be initialized before calling `this.getInitialStateFromScratch()`\r\n\t\t// because `this.getInitialStateFromScratch()` uses `this.verticalSpacing` in its calculations.\r\n\t\t//\r\n\t\t// With the code above, `state.verticalSpacing` is always gonna be `undefined`,\r\n\t\t// so commented out this code. It's safer to just re-measure vertical spacing\r\n\t\t// from scratch when `VirtualScroller` is mounted.\r\n\t\t//\r\n\t\t// this.verticalSpacing = state ? state.verticalSpacing : undefined\r\n\r\n\t\t// Check if the actual `columnsCount` on the screen matches the one from state.\r\n\t\tif (isStateColumnsCountMismatch(state, {\r\n\t\t\tcolumnsCount: this.getActualColumnsCount()\r\n\t\t})) {\r\n\t\t\twarn('Reset Layout')\r\n\t\t\tstate = {\r\n\t\t\t\t...state,\r\n\t\t\t\t...getInitialLayoutState.call(this, state.items, { beforeStart: false })\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn state\r\n\t}\r\n\r\n\tfunction getInitialLayoutState(items, { beforeStart }) {\r\n\t\tconst itemsCount = items.length\r\n\r\n\t\tconst {\r\n\t\t\tfirstShownItemIndex,\r\n\t\t\tlastShownItemIndex,\r\n\t\t\tbeforeItemsHeight,\r\n\t\t\tafterItemsHeight\r\n\t\t} = this.layout.getInitialLayoutValues({\r\n\t\t\titemsCount,\r\n\t\t\tcolumnsCount: this.getActualColumnsCount(),\r\n\t\t\tbeforeStart\r\n\t\t})\r\n\r\n\t\tconst itemHeights = new Array(itemsCount)\r\n\r\n\t\t// Optionally preload items to be rendered.\r\n\t\tthis.onBeforeShowItems(\r\n\t\t\titems,\r\n\t\t\titemHeights,\r\n\t\t\tfirstShownItemIndex,\r\n\t\t\tlastShownItemIndex\r\n\t\t)\r\n\r\n\t\treturn {\r\n\t\t\titemHeights,\r\n\t\t\tcolumnsCount: this.getActualColumnsCountForState(),\r\n\t\t\tverticalSpacing: this.verticalSpacing,\r\n\t\t\tfirstShownItemIndex,\r\n\t\t\tlastShownItemIndex,\r\n\t\t\tbeforeItemsHeight,\r\n\t\t\tafterItemsHeight\r\n\t\t}\r\n\t}\r\n\r\n\t// Checks if the actual `columnsCount` on the screen matches the one from state.\r\n\t//\r\n\t// For example, a developer might snapshot `VirtualScroller` state\r\n\t// when the user navigates from the page containing the list\r\n\t// in order to later restore the list's state when the user goes \"Back\".\r\n\t// But, the user might have also resized the window while being on that\r\n\t// \"other\" page, and when they come \"Back\", their snapshotted state\r\n\t// no longer qualifies. Well, it does qualify, but only partially.\r\n\t// For example, `itemStates` are still valid, but first and last shown\r\n\t// item indexes aren't.\r\n\t//\r\n\tfunction isStateColumnsCountMismatch(state, { columnsCount }) {\r\n\t\tconst stateColumnsCount = state.columnsCount || 1\r\n\t\tif (stateColumnsCount !== columnsCount) {\r\n\t\t\twarn('~ Columns Count changed from', stateColumnsCount, 'to', columnsCount, '~')\r\n\t\t\treturn true\r\n\t\t}\r\n\t\tconst firstShownItemIndex = Math.floor(state.firstShownItemIndex / columnsCount) * columnsCount\r\n\t\tif (firstShownItemIndex !== state.firstShownItemIndex) {\r\n\t\t\twarn('~ First Shown Item Index', state.firstShownItemIndex, 'is not divisible by Columns Count', columnsCount, '~')\r\n\t\t\treturn true\r\n\t\t}\r\n\t}\r\n}"],"mappings":";;;;;;AAAA,OAAOA,SAAP,MAAsB,wBAAtB;AACA,OAAOC,GAAP,IAAcC,IAAd,EAAoBC,OAApB,EAA6BC,WAA7B,QAAgD,oBAAhD;AACA,SAASC,wBAAT,QAAyC,mBAAzC;AACA,OAAOC,gBAAP,MAA6B,+BAA7B;AACA,SAASC,kBAAT,QAAmC,iCAAnC,C,CAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,eAAe,SAASC,kBAAT,OAMZ;EAAA;;EAAA,IALKC,YAKL,QALFC,KAKE;EAAA,IAJFC,mBAIE,QAJFA,mBAIE;EAAA,IAHFC,aAGE,QAHFA,aAGE;EAAA,IAFFC,MAEE,QAFFA,MAEE;EAAA,IADKC,YACL,QADFC,KACE;EACF,KAAKH,aAAL,GAAqBA,aAArB;EACA,KAAKI,OAAL,GAAeH,MAAf;EAEA,KAAKF,mBAAL,GAA2BA,mBAA3B;;EAEA,KAAKM,aAAL,GAAqB,UAACC,WAAD,EAAcC,YAAd,EAA+B;IACnD;IACA,IAAMC,CAAC,GAAG,KAAI,CAACC,0BAAL,CAAgCH,WAAhC,CAAV,CAFmD,CAInD;IACA;;;IACA,IAAIE,CAAC,KAAKE,SAAV,EAAqB;MACpB;IACA;;IAED,IAAInB,OAAO,EAAX,EAAe;MACdF,GAAG,CAAC,wBAAD,CAAH;MACAA,GAAG,CAAC,YAAD,EAAemB,CAAf,CAAH,CAFc,CAGd;MACA;MACA;MACA;MACA;;MACAnB,GAAG,CAAC,mBAAmB,IAAnB,GAA0BsB,IAAI,CAACC,SAAL,CAAe,KAAI,CAACC,QAAL,GAAgBC,UAAhB,CAA2BN,CAA3B,CAAf,EAA8C,IAA9C,EAAoD,CAApD,CAA3B,CAAH;MACAnB,GAAG,CAAC,cAAc,IAAd,GAAqBsB,IAAI,CAACC,SAAL,CAAeL,YAAf,EAA6B,IAA7B,EAAmC,CAAnC,CAAtB,CAAH;IACA;;IAED,KAAI,CAACM,QAAL,GAAgBC,UAAhB,CAA2BN,CAA3B,IAAgCD,YAAhC,CAtBmD,CAwBnD;IACA;IACA;IACA;IACA;IACA;IACA;;IACA,IAAI,KAAI,CAACQ,sBAAT,EAAiC;MAChC,IAAI,CAAC,KAAI,CAACC,mDAAV,EAA+D;QAC9D,KAAI,CAACA,mDAAL,GAA2D,EAA3D;MACA;;MACD,KAAI,CAACA,mDAAL,CAAyDC,MAAM,CAACT,CAAD,CAA/D,IAAsED,YAAtE;IACA;EACD,CArCD;;EAuCA,KAAKM,QAAL,GAAgB;IAAA,OAAM,KAAI,CAACK,SAAL,EAAN;EAAA,CAAhB;;EAEA,KAAKC,WAAL,GAAmB,UAACC,WAAD,EAAiB;IACnC,IAAI7B,OAAO,EAAX,EAAe;MACdF,GAAG,CAAC,eAAD,CAAH;MACAA,GAAG,CAACK,gBAAgB,CAAC0B,WAAD,CAAjB,CAAH;IACA,CAJkC,CAMnC;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;;IACA,IAAI,KAAI,CAACC,6BAAL,KAAuCX,SAA3C,EAAsD;MACrD,KAAI,CAACW,6BAAL,GAAqCC,IAAI,CAACC,GAAL,EAArC,CADqD,CAErD;MACA;;MACA,KAAI,CAACC,uCAAL,GAA+C7B,kBAAkB,CAAC,YAAM;QACvE,KAAI,CAAC6B,uCAAL,GAA+Cd,SAA/C;QACA,KAAI,CAACW,6BAAL,GAAqCX,SAArC;MACA,CAHgE,CAAjE;IAIA,CAzCkC,CA2CnC;IACA;;;IACA,IAAIU,WAAW,CAACjB,KAAhB,EAAuB;MACtB,IAAI,CAAC,KAAI,CAACsB,kBAAV,EAA8B;QAC7BjC,WAAW,CAAC,wFAAD,CAAX;MACA;IACD;;IACD,KAAI,CAACiC,kBAAL,GAA0Bf,SAA1B;IAEA,KAAI,CAACgB,gBAAL,GAAwB,IAAxB,CApDmC,CAsDnC;;IACA,KAAI,CAACC,aAAL,GAAqB,KAAI,CAACd,QAAL,EAArB,CAvDmC,CAyDnC;IACA;;IACA,IAAI,CAAC,KAAI,CAACe,uBAAV,EAAmC;MAClC,KAAI,CAACA,uBAAL,GAA+B,KAAI,CAACf,QAAL,EAA/B;IACA,CA7DkC,CA+DnC;;;IACA,KAAI,CAACe,uBAAL,mCACI,KAAI,CAACA,uBADT,GAEIR,WAFJ,EAhEmC,CAqEnC;;IACA,KAAI,CAACS,SAAL,CAAe,KAAI,CAACD,uBAApB,EAA6CR,WAA7C;EACA,CAvED;;EAyEA,KAAKU,eAAL,GAAuB,YAAM;IAC5B,IAAIjC,YAAJ,EAAkB;MACjB,OAAOkC,gBAAgB,CAACC,IAAjB,CAAsB,KAAtB,EAA4BnC,YAA5B,CAAP;IACA;;IACD,OAAOoC,0BAA0B,CAACD,IAA3B,CAAgC,KAAhC,EAAsC;MAAEjC,mBAAmB,EAAnBA;IAAF,CAAtC,CAAP;EACA,CALD;;EAOA,KAAKmC,QAAL,GAAgB,iBAIV;IAAA,IAHLrB,QAGK,SAHLA,QAGK;IAAA,IAFLsB,QAEK,SAFLA,QAEK;IAAA,IADLhB,WACK,SADLA,WACK;;IACL,IAAI,KAAI,CAACiB,SAAT,EAAoB;MACnB,MAAM,IAAIC,KAAJ,CAAU,+DAAV,CAAN;IACA;;IAED,IAAI,KAAI,CAACnB,SAAT,EAAoB;MACnB,MAAM,IAAImB,KAAJ,CAAU,qEAAV,CAAN;IACA;;IAED,IAAIpC,MAAJ,EAAY;MACX,MAAM,IAAIoC,KAAJ,CAAU,+IAAV,CAAN;IACA;;IAED,IAAIF,QAAQ,IAAIhB,WAAhB,EAA6B;MAC5B,MAAM,IAAIkB,KAAJ,CAAU,oIAAV,CAAN;IACA;;IAED,IAAI,CAACxB,QAAD,IAAa,EAAEsB,QAAQ,IAAIhB,WAAd,CAAjB,EAA6C;MAC5C,MAAM,IAAIkB,KAAJ,CAAU,oIAAV,CAAN;IACA;;IAED,KAAI,CAACC,uBAAL,GAA+B,IAA/B;IAEA,KAAI,CAACpB,SAAL,GAAiBL,QAAjB;;IAEA,KAAI,CAACgB,SAAL,GAAiB,UAACU,QAAD,EAAWnB,WAAX,EAA2B;MAC3C,IAAIe,QAAJ,EAAc;QACbA,QAAQ,CAACI,QAAD,CAAR;MACA,CAFD,MAEO;QACNpB,WAAW,CAACC,WAAD,CAAX;MACA;IACD,CAND;EAOA,CApCD;;EAsCA,KAAKoB,sBAAL,GAA8B,YAAM;IACnC,IAAI,CAACvC,MAAL,EAAa;MACZ,MAAM,IAAIoC,KAAJ,CAAU,wIAAV,CAAN;IACA,CAHkC,CAKnC;;;IACA,KAAI,CAACnB,SAAL,GAAiBuB,eAAe,CAACC,IAAhB,CAAqB,KAArB,CAAjB;IACA,KAAI,CAACb,SAAL,GAAiBc,eAAe,CAACD,IAAhB,CAAqB,KAArB,CAAjB,CAPmC,CASnC;IACA;IACA;;IACA,IAAME,eAAe,GAAGC,sBAAsB,CAACH,IAAvB,CAA4B,KAA5B,CAAxB;IACAE,eAAe,CAAC,KAAI,CAACd,eAAL,EAAD,CAAf;EACA,CAdD;;EAgBA,KAAKgB,UAAL,GAAkB,YAAM;IACvB;IACA;IACA,IAAI,CAAC,KAAI,CAACR,uBAAV,EAAmC;MAClC,KAAI,CAACE,sBAAL;IACA;EACD,CAND;;EAQA,SAASC,eAAT,GAA2B;IAC1B,OAAO,KAAK3C,KAAZ;EACA;;EAED,SAAS+C,sBAAT,CAAgCN,QAAhC,EAA0C;IACzC,KAAKzC,KAAL,GAAayC,QAAb;EACA;;EAED,SAASI,eAAT,CAAyBJ,QAAzB,EAAmCnB,WAAnC,EAAgD;IAC/C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA,KAAKtB,KAAL,GAAayC,QAAb;IAEAtC,MAAM,CAAC,KAAKH,KAAN,EAAa,KAAK6B,aAAlB,CAAN;IAEA,KAAKoB,QAAL;EACA;EAED;AACD;AACA;AACA;AACA;AACA;;;EACC,SAASd,0BAAT,QAA6D;IAAA,IAAvBlC,mBAAuB,SAAvBA,mBAAuB;IAC5D,IAAMI,KAAK,GAAGD,YAAd;;IAEA,IAAMJ,KAAK,mCACPkD,qBAAqB,CAAChB,IAAtB,CAA2B,IAA3B,EAAiC7B,KAAjC,EAAwC;MAAE8C,WAAW,EAAE;IAAf,CAAxC,CADO;MAEV9C,KAAK,EAALA,KAFU;MAGVW,UAAU,EAAE1B,SAAS,CAAC,IAAI8D,KAAJ,CAAU/C,KAAK,CAACgD,MAAhB,CAAD,EAA0B,UAAC3C,CAAD;QAAA,OAAOT,mBAAmB,CAACI,KAAK,CAACK,CAAD,CAAN,CAA1B;MAAA,CAA1B;IAHX,EAAX;;IAMA,IAAIjB,OAAO,EAAX,EAAe;MACdF,GAAG,CAAC,+BAAD,EAAkCK,gBAAgB,CAACI,KAAD,CAAlD,CAAH;IACA;;IACDT,GAAG,CAAC,wBAAD,EAA2BS,KAAK,CAACsD,mBAAjC,CAAH;IACA/D,GAAG,CAAC,uBAAD,EAA0BS,KAAK,CAACuD,kBAAhC,CAAH;IAEA,OAAOvD,KAAP;EACA;;EAED,SAASiC,gBAAT,CAA0BjC,KAA1B,EAAiC;IAChC,IAAIP,OAAO,EAAX,EAAe;MACdF,GAAG,CAAC,eAAD,EAAkBK,gBAAgB,CAACI,KAAD,CAAlC,CAAH;IACA,CAH+B,CAKhC;IACA;IACA;IACA;IACA;;;IACAA,KAAK,GAAGL,wBAAwB,CAACK,KAAD,CAAhC,CAVgC,CAYhC;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;IACAA,KAAK,mCACDA,KADC;MAEJwD,eAAe,EAAE5C;IAFb,EAAL,CApBgC,CAyBhC;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;;IACA,IAAI6C,2BAA2B,CAACzD,KAAD,EAAQ;MACtC0D,YAAY,EAAE,KAAKC,qBAAL;IADwB,CAAR,CAA/B,EAEI;MACHnE,IAAI,CAAC,cAAD,CAAJ;MACAQ,KAAK,mCACDA,KADC,GAEDkD,qBAAqB,CAAChB,IAAtB,CAA2B,IAA3B,EAAiClC,KAAK,CAACK,KAAvC,EAA8C;QAAE8C,WAAW,EAAE;MAAf,CAA9C,CAFC,CAAL;IAIA;;IAED,OAAOnD,KAAP;EACA;;EAED,SAASkD,qBAAT,CAA+B7C,KAA/B,SAAuD;IAAA,IAAf8C,WAAe,SAAfA,WAAe;IACtD,IAAMS,UAAU,GAAGvD,KAAK,CAACgD,MAAzB;;IAEA,4BAKI,KAAKQ,MAAL,CAAYC,sBAAZ,CAAmC;MACtCF,UAAU,EAAVA,UADsC;MAEtCF,YAAY,EAAE,KAAKC,qBAAL,EAFwB;MAGtCR,WAAW,EAAXA;IAHsC,CAAnC,CALJ;IAAA,IACCG,mBADD,yBACCA,mBADD;IAAA,IAECC,kBAFD,yBAECA,kBAFD;IAAA,IAGCQ,iBAHD,yBAGCA,iBAHD;IAAA,IAICC,gBAJD,yBAICA,gBAJD;;IAWA,IAAMC,WAAW,GAAG,IAAIb,KAAJ,CAAUQ,UAAV,CAApB,CAdsD,CAgBtD;;IACA,KAAKM,iBAAL,CACC7D,KADD,EAEC4D,WAFD,EAGCX,mBAHD,EAICC,kBAJD;IAOA,OAAO;MACNU,WAAW,EAAXA,WADM;MAENP,YAAY,EAAE,KAAKS,6BAAL,EAFR;MAGNX,eAAe,EAAE,KAAKA,eAHhB;MAINF,mBAAmB,EAAnBA,mBAJM;MAKNC,kBAAkB,EAAlBA,kBALM;MAMNQ,iBAAiB,EAAjBA,iBANM;MAONC,gBAAgB,EAAhBA;IAPM,CAAP;EASA,CAzUC,CA2UF;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;EACA,SAASP,2BAAT,CAAqCzD,KAArC,SAA8D;IAAA,IAAhB0D,YAAgB,SAAhBA,YAAgB;IAC7D,IAAMU,iBAAiB,GAAGpE,KAAK,CAAC0D,YAAN,IAAsB,CAAhD;;IACA,IAAIU,iBAAiB,KAAKV,YAA1B,EAAwC;MACvClE,IAAI,CAAC,8BAAD,EAAiC4E,iBAAjC,EAAoD,IAApD,EAA0DV,YAA1D,EAAwE,GAAxE,CAAJ;MACA,OAAO,IAAP;IACA;;IACD,IAAMJ,mBAAmB,GAAGe,IAAI,CAACC,KAAL,CAAWtE,KAAK,CAACsD,mBAAN,GAA4BI,YAAvC,IAAuDA,YAAnF;;IACA,IAAIJ,mBAAmB,KAAKtD,KAAK,CAACsD,mBAAlC,EAAuD;MACtD9D,IAAI,CAAC,0BAAD,EAA6BQ,KAAK,CAACsD,mBAAnC,EAAwD,mCAAxD,EAA6FI,YAA7F,EAA2G,GAA3G,CAAJ;MACA,OAAO,IAAP;IACA;EACD;AACD"}
@@ -24,7 +24,7 @@ export default function useVirtualScroller(_ref, _ref2) {
24
24
  return useMemo(function () {
25
25
  // Create `virtual-scroller` instance.
26
26
  return new VirtualScroller(getItemsContainerElement, items, {
27
- _useTimeoutInRenderLoop: true,
27
+ delayRecursiveRenderUntilNextTick: true,
28
28
  // `estimatedItemHeight` is deprecated, use `getEstimatedItemHeight()` instead.
29
29
  estimatedItemHeight: estimatedItemHeight,
30
30
  getEstimatedItemHeight: getEstimatedItemHeight,
@@ -1 +1 @@
1
- {"version":3,"file":"useCreateVirtualScroller.js","names":["useMemo","VirtualScroller","useVirtualScroller","items","estimatedItemHeight","getEstimatedItemHeight","getEstimatedVisibleItemRowsCount","getEstimatedInterItemVerticalSpacing","bypass","onItemInitialRender","onItemFirstRender","initialScrollPosition","onScrollPositionChange","measureItemsBatchSize","scrollableContainer","getScrollableContainer","getColumnsCount","getItemId","initialState","getInitialItemState","onStateChange","getItemsContainerElement","_useTimeoutInRenderLoop","state"],"sources":["../../source/react/useCreateVirtualScroller.js"],"sourcesContent":["import { useMemo } from 'react'\r\n\r\nimport VirtualScroller from '../VirtualScroller.js'\r\n\r\n// Creates a `VirtualScroller` instance.\r\nexport default function useVirtualScroller({\r\n\titems,\r\n\t// `estimatedItemHeight` is deprecated, use `getEstimatedItemHeight()` instead.\r\n\testimatedItemHeight,\r\n\tgetEstimatedItemHeight,\r\n\tgetEstimatedVisibleItemRowsCount,\r\n\tgetEstimatedInterItemVerticalSpacing,\r\n\tbypass,\r\n\t// bypassBatchSize,\r\n\tonItemInitialRender,\r\n\t// `onItemFirstRender(i)` is deprecated, use `onItemInitialRender(item)` instead.\r\n\tonItemFirstRender,\r\n\tinitialScrollPosition,\r\n\tonScrollPositionChange,\r\n\tmeasureItemsBatchSize,\r\n\t// `scrollableContainer` property is deprecated.\r\n\t// Use `getScrollableContainer()` property instead.\r\n\tscrollableContainer,\r\n\tgetScrollableContainer,\r\n\tgetColumnsCount,\r\n\tgetItemId,\r\n\tinitialState,\r\n\tgetInitialItemState,\r\n\tonStateChange\r\n}, {\r\n\tgetItemsContainerElement\r\n}) {\r\n\treturn useMemo(() => {\r\n\t\t// Create `virtual-scroller` instance.\r\n\t\treturn new VirtualScroller(\r\n\t\t\tgetItemsContainerElement,\r\n\t\t\titems,\r\n\t\t\t{\r\n\t\t\t\t_useTimeoutInRenderLoop: true,\r\n\t\t\t\t// `estimatedItemHeight` is deprecated, use `getEstimatedItemHeight()` instead.\r\n\t\t\t\testimatedItemHeight,\r\n\t\t\t\tgetEstimatedItemHeight,\r\n\t\t\t\tgetEstimatedVisibleItemRowsCount,\r\n\t\t\t\tgetEstimatedInterItemVerticalSpacing,\r\n\t\t\t\tbypass,\r\n\t\t\t\t// bypassBatchSize,\r\n\t\t\t\tonItemInitialRender,\r\n\t\t\t\t// `onItemFirstRender(i)` is deprecated, use `onItemInitialRender(item)` instead.\r\n\t\t\t\tonItemFirstRender,\r\n\t\t\t\tinitialScrollPosition,\r\n\t\t\t\tonScrollPositionChange,\r\n\t\t\t\tmeasureItemsBatchSize,\r\n\t\t\t\t// `scrollableContainer` property is deprecated.\r\n\t\t\t\t// Use `getScrollableContainer()` property instead.\r\n\t\t\t\tscrollableContainer,\r\n\t\t\t\tgetScrollableContainer,\r\n\t\t\t\tgetColumnsCount,\r\n\t\t\t\tgetItemId,\r\n\t\t\t\tstate: initialState,\r\n\t\t\t\tgetInitialItemState,\r\n\t\t\t\tonStateChange\r\n\t\t\t}\r\n\t\t)\r\n\t}, [])\r\n}"],"mappings":"AAAA,SAASA,OAAT,QAAwB,OAAxB;AAEA,OAAOC,eAAP,MAA4B,uBAA5B,C,CAEA;;AACA,eAAe,SAASC,kBAAT,cA0BZ;EAAA,IAzBFC,KAyBE,QAzBFA,KAyBE;EAAA,IAvBFC,mBAuBE,QAvBFA,mBAuBE;EAAA,IAtBFC,sBAsBE,QAtBFA,sBAsBE;EAAA,IArBFC,gCAqBE,QArBFA,gCAqBE;EAAA,IApBFC,oCAoBE,QApBFA,oCAoBE;EAAA,IAnBFC,MAmBE,QAnBFA,MAmBE;EAAA,IAjBFC,mBAiBE,QAjBFA,mBAiBE;EAAA,IAfFC,iBAeE,QAfFA,iBAeE;EAAA,IAdFC,qBAcE,QAdFA,qBAcE;EAAA,IAbFC,sBAaE,QAbFA,sBAaE;EAAA,IAZFC,qBAYE,QAZFA,qBAYE;EAAA,IATFC,mBASE,QATFA,mBASE;EAAA,IARFC,sBAQE,QARFA,sBAQE;EAAA,IAPFC,eAOE,QAPFA,eAOE;EAAA,IANFC,SAME,QANFA,SAME;EAAA,IALFC,YAKE,QALFA,YAKE;EAAA,IAJFC,mBAIE,QAJFA,mBAIE;EAAA,IAHFC,aAGE,QAHFA,aAGE;EAAA,IADFC,wBACE,SADFA,wBACE;EACF,OAAOrB,OAAO,CAAC,YAAM;IACpB;IACA,OAAO,IAAIC,eAAJ,CACNoB,wBADM,EAENlB,KAFM,EAGN;MACCmB,uBAAuB,EAAE,IAD1B;MAEC;MACAlB,mBAAmB,EAAnBA,mBAHD;MAICC,sBAAsB,EAAtBA,sBAJD;MAKCC,gCAAgC,EAAhCA,gCALD;MAMCC,oCAAoC,EAApCA,oCAND;MAOCC,MAAM,EAANA,MAPD;MAQC;MACAC,mBAAmB,EAAnBA,mBATD;MAUC;MACAC,iBAAiB,EAAjBA,iBAXD;MAYCC,qBAAqB,EAArBA,qBAZD;MAaCC,sBAAsB,EAAtBA,sBAbD;MAcCC,qBAAqB,EAArBA,qBAdD;MAeC;MACA;MACAC,mBAAmB,EAAnBA,mBAjBD;MAkBCC,sBAAsB,EAAtBA,sBAlBD;MAmBCC,eAAe,EAAfA,eAnBD;MAoBCC,SAAS,EAATA,SApBD;MAqBCM,KAAK,EAAEL,YArBR;MAsBCC,mBAAmB,EAAnBA,mBAtBD;MAuBCC,aAAa,EAAbA;IAvBD,CAHM,CAAP;EA6BA,CA/Ba,EA+BX,EA/BW,CAAd;AAgCA"}
1
+ {"version":3,"file":"useCreateVirtualScroller.js","names":["useMemo","VirtualScroller","useVirtualScroller","items","estimatedItemHeight","getEstimatedItemHeight","getEstimatedVisibleItemRowsCount","getEstimatedInterItemVerticalSpacing","bypass","onItemInitialRender","onItemFirstRender","initialScrollPosition","onScrollPositionChange","measureItemsBatchSize","scrollableContainer","getScrollableContainer","getColumnsCount","getItemId","initialState","getInitialItemState","onStateChange","getItemsContainerElement","delayRecursiveRenderUntilNextTick","state"],"sources":["../../source/react/useCreateVirtualScroller.js"],"sourcesContent":["import { useMemo } from 'react'\r\n\r\nimport VirtualScroller from '../VirtualScroller.js'\r\n\r\n// Creates a `VirtualScroller` instance.\r\nexport default function useVirtualScroller({\r\n\titems,\r\n\t// `estimatedItemHeight` is deprecated, use `getEstimatedItemHeight()` instead.\r\n\testimatedItemHeight,\r\n\tgetEstimatedItemHeight,\r\n\tgetEstimatedVisibleItemRowsCount,\r\n\tgetEstimatedInterItemVerticalSpacing,\r\n\tbypass,\r\n\t// bypassBatchSize,\r\n\tonItemInitialRender,\r\n\t// `onItemFirstRender(i)` is deprecated, use `onItemInitialRender(item)` instead.\r\n\tonItemFirstRender,\r\n\tinitialScrollPosition,\r\n\tonScrollPositionChange,\r\n\tmeasureItemsBatchSize,\r\n\t// `scrollableContainer` property is deprecated.\r\n\t// Use `getScrollableContainer()` property instead.\r\n\tscrollableContainer,\r\n\tgetScrollableContainer,\r\n\tgetColumnsCount,\r\n\tgetItemId,\r\n\tinitialState,\r\n\tgetInitialItemState,\r\n\tonStateChange\r\n}, {\r\n\tgetItemsContainerElement\r\n}) {\r\n\treturn useMemo(() => {\r\n\t\t// Create `virtual-scroller` instance.\r\n\t\treturn new VirtualScroller(\r\n\t\t\tgetItemsContainerElement,\r\n\t\t\titems,\r\n\t\t\t{\r\n\t\t\t\tdelayRecursiveRenderUntilNextTick: true,\r\n\t\t\t\t// `estimatedItemHeight` is deprecated, use `getEstimatedItemHeight()` instead.\r\n\t\t\t\testimatedItemHeight,\r\n\t\t\t\tgetEstimatedItemHeight,\r\n\t\t\t\tgetEstimatedVisibleItemRowsCount,\r\n\t\t\t\tgetEstimatedInterItemVerticalSpacing,\r\n\t\t\t\tbypass,\r\n\t\t\t\t// bypassBatchSize,\r\n\t\t\t\tonItemInitialRender,\r\n\t\t\t\t// `onItemFirstRender(i)` is deprecated, use `onItemInitialRender(item)` instead.\r\n\t\t\t\tonItemFirstRender,\r\n\t\t\t\tinitialScrollPosition,\r\n\t\t\t\tonScrollPositionChange,\r\n\t\t\t\tmeasureItemsBatchSize,\r\n\t\t\t\t// `scrollableContainer` property is deprecated.\r\n\t\t\t\t// Use `getScrollableContainer()` property instead.\r\n\t\t\t\tscrollableContainer,\r\n\t\t\t\tgetScrollableContainer,\r\n\t\t\t\tgetColumnsCount,\r\n\t\t\t\tgetItemId,\r\n\t\t\t\tstate: initialState,\r\n\t\t\t\tgetInitialItemState,\r\n\t\t\t\tonStateChange\r\n\t\t\t}\r\n\t\t)\r\n\t}, [])\r\n}"],"mappings":"AAAA,SAASA,OAAT,QAAwB,OAAxB;AAEA,OAAOC,eAAP,MAA4B,uBAA5B,C,CAEA;;AACA,eAAe,SAASC,kBAAT,cA0BZ;EAAA,IAzBFC,KAyBE,QAzBFA,KAyBE;EAAA,IAvBFC,mBAuBE,QAvBFA,mBAuBE;EAAA,IAtBFC,sBAsBE,QAtBFA,sBAsBE;EAAA,IArBFC,gCAqBE,QArBFA,gCAqBE;EAAA,IApBFC,oCAoBE,QApBFA,oCAoBE;EAAA,IAnBFC,MAmBE,QAnBFA,MAmBE;EAAA,IAjBFC,mBAiBE,QAjBFA,mBAiBE;EAAA,IAfFC,iBAeE,QAfFA,iBAeE;EAAA,IAdFC,qBAcE,QAdFA,qBAcE;EAAA,IAbFC,sBAaE,QAbFA,sBAaE;EAAA,IAZFC,qBAYE,QAZFA,qBAYE;EAAA,IATFC,mBASE,QATFA,mBASE;EAAA,IARFC,sBAQE,QARFA,sBAQE;EAAA,IAPFC,eAOE,QAPFA,eAOE;EAAA,IANFC,SAME,QANFA,SAME;EAAA,IALFC,YAKE,QALFA,YAKE;EAAA,IAJFC,mBAIE,QAJFA,mBAIE;EAAA,IAHFC,aAGE,QAHFA,aAGE;EAAA,IADFC,wBACE,SADFA,wBACE;EACF,OAAOrB,OAAO,CAAC,YAAM;IACpB;IACA,OAAO,IAAIC,eAAJ,CACNoB,wBADM,EAENlB,KAFM,EAGN;MACCmB,iCAAiC,EAAE,IADpC;MAEC;MACAlB,mBAAmB,EAAnBA,mBAHD;MAICC,sBAAsB,EAAtBA,sBAJD;MAKCC,gCAAgC,EAAhCA,gCALD;MAMCC,oCAAoC,EAApCA,oCAND;MAOCC,MAAM,EAANA,MAPD;MAQC;MACAC,mBAAmB,EAAnBA,mBATD;MAUC;MACAC,iBAAiB,EAAjBA,iBAXD;MAYCC,qBAAqB,EAArBA,qBAZD;MAaCC,sBAAsB,EAAtBA,sBAbD;MAcCC,qBAAqB,EAArBA,qBAdD;MAeC;MACA;MACAC,mBAAmB,EAAnBA,mBAjBD;MAkBCC,sBAAsB,EAAtBA,sBAlBD;MAmBCC,eAAe,EAAfA,eAnBD;MAoBCC,SAAS,EAATA,SApBD;MAqBCM,KAAK,EAAEL,YArBR;MAsBCC,mBAAmB,EAAnBA,mBAtBD;MAuBCC,aAAa,EAAbA;IAvBD,CAHM,CAAP;EA6BA,CA/Ba,EA+BX,EA/BW,CAAd;AAgCA"}
@@ -16,6 +16,8 @@ function _defineProperties(target, props) { for (var i = 0; i < props.length; i+
16
16
 
17
17
  function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
18
18
 
19
+ import { describe, it } from 'mocha';
20
+ import { expect } from 'chai';
19
21
  import VirtualScroller from '../VirtualScroller.js';
20
22
  import Engine from './Engine.js';
21
23
  var DEBUG = false;
@@ -121,7 +123,8 @@ var TestVirtualScroller = /*#__PURE__*/function () {
121
123
  this.virtualScroller = new VirtualScroller(getItemsContainerElement, items, {
122
124
  scrollableContainer: scrollableContainerElement,
123
125
  engine: Engine,
124
- _waitForScrollingToStop: false,
126
+ _delayUnnecessaryRerenderUntilStopsScrolling: false,
127
+ delayRecursiveRenderUntilNextTick: false,
125
128
  getItemId: getItemId,
126
129
  getColumnsCount: getColumnsCount,
127
130
  state: initialState,
@@ -185,7 +188,7 @@ var TestVirtualScroller = /*#__PURE__*/function () {
185
188
  key: "verifyState",
186
189
  value: function verifyState(expectedState) {
187
190
  // `mocha`/`chai`.
188
- this.virtualScroller.getState().should.deep.include(expectedState);
191
+ expect(this.virtualScroller.getState()).to.deep.include(expectedState);
189
192
  }
190
193
  }, {
191
194
  key: "expectStateUpdate",
@@ -1 +1 @@
1
- {"version":3,"file":"VirtualScroller.js","names":["VirtualScroller","Engine","DEBUG","TestVirtualScroller","scrollableContainerWidth","screenWidth","scrollableContainerHeight","screenHeight","columnsCount","verticalSpacing","items","getItemId","initialState","state","rest","Object","keys","length","Error","join","expectedStateUpdates","scrollableContainerElement","width","height","containerElement","paddingTop","paddingBottom","children","setScrollableContainerWidth","setScrollableContainerHeight","getItemsContainerElement","__columnsCount","getColumnsCount","getItemWidth","hasPausedStateUpdates","undefined","pausedStateUpdate","pausedStateUpdateAction","onBeforeUpdateState","stateUpdate","expectedStateUpdate","shift","expect","to","deep","equal","callback","render","virtualScroller","getState","beforeItemsHeight","afterItemsHeight","firstShownItemIndex","lastShownItemIndex","slice","map","item","getWidth","getHeight","getArea","area","getMarginTop","scrollableContainer","engine","_waitForScrollingToStop","onStateChange","console","log","getInitialState","useState","updateState","stateUpdateAction","onRender","expectedState","should","include","push","firstNonMeasuredItemIndex","getScrollY","scrollPosition","scrollToY","updateScreenDimensions","_triggerResizeListener","JSON","stringify","stop","start","updateLayout","itemOrIndex","getItemScrollPosition","onItemHeightDidChange","newState","setItemState","getAverageItemHeight","newItems","options","setItems"],"sources":["../../source/test/VirtualScroller.js"],"sourcesContent":["import VirtualScroller from '../VirtualScroller.js'\r\nimport Engine from './Engine.js'\r\n\r\nconst DEBUG = false\r\n\r\nexport default class TestVirtualScroller {\r\n\tconstructor({\r\n\t\tscreenWidth: scrollableContainerWidth,\r\n\t\tscreenHeight: scrollableContainerHeight,\r\n\t\tcolumnsCount,\r\n\t\tverticalSpacing,\r\n\t\titems,\r\n\t\tgetItemId,\r\n\t\tstate: initialState,\r\n\t\t...rest\r\n\t}) {\r\n\t\t// Validate that no unknown properties are passed.\r\n\t\t// This prevents the cases when a developer confuses\r\n\t\t// `TestVirtualScroller` options for `VirtualScroller` options.\r\n\t\tif (Object.keys(rest).length > 0) {\r\n\t\t\tthrow new Error(`Unknown options: ${Object.keys(rest).join(', ')}`)\r\n\t\t}\r\n\r\n\t\tthis.expectedStateUpdates = []\r\n\r\n\t\tconst scrollableContainerElement = {\r\n\t\t\twidth: scrollableContainerWidth,\r\n\t\t\theight: scrollableContainerHeight\r\n\t\t}\r\n\r\n\t\tconst containerElement = {\r\n\t\t\tpaddingTop: 0,\r\n\t\t\tpaddingBottom: 0,\r\n\t\t\twidth: scrollableContainerElement.width,\r\n\t\t\tchildren: []\r\n\t\t}\r\n\r\n\t\tthis.setScrollableContainerWidth = (width) => {\r\n\t\t\tscrollableContainerElement.width = width\r\n\t\t\tcontainerElement.width = width\r\n\t\t}\r\n\r\n\t\tthis.setScrollableContainerHeight = (height) => {\r\n\t\t\tscrollableContainerElement.height = height\r\n\t\t}\r\n\r\n\t\tconst getItemsContainerElement = () => containerElement\r\n\r\n\t\tthis.__columnsCount = columnsCount\r\n\r\n\t\tconst getColumnsCount = () => this.__columnsCount\r\n\t\tconst getItemWidth = () => scrollableContainerElement.width / getColumnsCount()\r\n\r\n\t\tthis.hasPausedStateUpdates = undefined\r\n\t\tthis.pausedStateUpdate = undefined\r\n\t\tthis.pausedStateUpdateAction = undefined\r\n\r\n\t\tconst onBeforeUpdateState = (stateUpdate) => {\r\n\t\t\tif (this.expectedStateUpdates.length > 0) {\r\n\t\t\t\tconst expectedStateUpdate = this.expectedStateUpdates.shift()\r\n\t\t\t\texpect(stateUpdate).to.deep.equal(expectedStateUpdate.stateUpdate)\r\n\t\t\t\tif (expectedStateUpdate.callback) {\r\n\t\t\t\t\texpectedStateUpdate.callback()\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tconst render = () => {\r\n\t\t\tconst {\r\n\t\t\t\titems,\r\n\t\t\t\tbeforeItemsHeight,\r\n\t\t\t\tafterItemsHeight,\r\n\t\t\t\tfirstShownItemIndex,\r\n\t\t\t\tlastShownItemIndex\r\n\t\t\t} = this.virtualScroller.getState()\r\n\r\n\t\t\tcontainerElement.paddingTop = beforeItemsHeight\r\n\t\t\tcontainerElement.paddingBottom = afterItemsHeight\r\n\r\n\t\t\tcontainerElement.children = items\r\n\t\t\t\t.slice(firstShownItemIndex, lastShownItemIndex + 1)\r\n\t\t\t\t.map((item) => ({\r\n\t\t\t\t\tgetWidth: () => getItemWidth(),\r\n\t\t\t\t\tgetHeight: () => (item.getArea ? item.getArea() : item.area) / getItemWidth(),\r\n\t\t\t\t\tgetMarginTop: () => verticalSpacing\r\n\t\t\t\t}))\r\n\t\t}\r\n\r\n\t\tthis.virtualScroller = new VirtualScroller(getItemsContainerElement, items, {\r\n\t\t\tscrollableContainer: scrollableContainerElement,\r\n\t\t\tengine: Engine,\r\n\t\t\t_waitForScrollingToStop: false,\r\n\t\t\tgetItemId,\r\n\t\t\tgetColumnsCount,\r\n\t\t\tstate: initialState,\r\n\t\t\tonStateChange(state) {\r\n\t\t\t\tif (DEBUG) {\r\n\t\t\t\t\tconsole.log('~ Updated State ~')\r\n\t\t\t\t\tconsole.log(state)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t})\r\n\r\n\t\tlet state = this.virtualScroller.getInitialState()\r\n\r\n\t\tthis.virtualScroller.useState({\r\n\t\t\tgetState: () => state,\r\n\t\t\tupdateState: (stateUpdate) => {\r\n\t\t\t\tconst stateUpdateAction = (stateUpdate) => {\r\n\t\t\t\t\t// Is only used in tests.\r\n\t\t\t\t\tif (onBeforeUpdateState) {\r\n\t\t\t\t\t\tonBeforeUpdateState(stateUpdate)\r\n\t\t\t\t\t}\r\n\t\t\t\t\tstate = {\r\n\t\t\t\t\t\t...state,\r\n\t\t\t\t\t\t...stateUpdate\r\n\t\t\t\t\t}\r\n\t\t\t\t\trender()\r\n\t\t\t\t\tthis.virtualScroller.onRender()\r\n\t\t\t\t}\r\n\t\t\t\tif (this.hasPausedStateUpdates) {\r\n\t\t\t\t\tthis.pausedStateUpdate = {\r\n\t\t\t\t\t\t...this.pausedStateUpdate,\r\n\t\t\t\t\t\t...stateUpdate\r\n\t\t\t\t\t}\r\n\t\t\t\t\tthis.pausedStateUpdateAction = stateUpdateAction\r\n\t\t\t\t} else {\r\n\t\t\t\t\tstateUpdateAction(stateUpdate)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t})\r\n\r\n\t\trender()\r\n\t}\r\n\r\n\tpauseStateUpdates() {\r\n\t\tif (this.hasPausedStateUpdates) {\r\n\t\t\tthrow new Error('[virtual-scroller] State updates have already been paused')\r\n\t\t}\r\n\t\tthis.hasPausedStateUpdates = true\r\n\t}\r\n\r\n\tresumeStateUpdates() {\r\n\t\tif (this.pausedStateUpdate) {\r\n\t\t\tthis.pausedStateUpdateAction(this.pausedStateUpdate)\r\n\t\t\tthis.pausedStateUpdate = undefined\r\n\t\t\tthis.pausedStateUpdateAction = undefined\r\n\t\t}\r\n\t\tthis.hasPausedStateUpdates = false\r\n\t}\r\n\r\n\tverifyState(expectedState) {\r\n\t\t// `mocha`/`chai`.\r\n\t\tthis.virtualScroller.getState().should.deep.include(expectedState)\r\n\t}\r\n\r\n\texpectStateUpdate(stateUpdate, callback) {\r\n\t\tthis.expectedStateUpdates.push({\r\n\t\t\tstateUpdate,\r\n\t\t\tcallback\r\n\t\t})\r\n\t}\r\n\r\n\tgetFirstNonMeasuredItemIndex() {\r\n\t\treturn this.virtualScroller.firstNonMeasuredItemIndex\r\n\t}\r\n\r\n\tgetScrollY() {\r\n\t\treturn this.virtualScroller.scrollableContainer.getScrollY()\r\n\t}\r\n\r\n\tscrollTo(scrollPosition) {\r\n\t\tthis.virtualScroller.scrollableContainer.scrollToY(scrollPosition)\r\n\t}\r\n\r\n\tupdateScreenDimensions({\r\n\t\tscreenWidth: scrollableContainerWidth,\r\n\t\tscreenHeight: scrollableContainerHeight,\r\n\t\tcolumnsCount\r\n\t}) {\r\n\t\t// Resize scrollable container.\r\n\t\tthis.setScrollableContainerWidth(scrollableContainerWidth)\r\n\t\tthis.setScrollableContainerHeight(scrollableContainerHeight)\r\n\r\n\t\t// Update columns count.\r\n\t\tthis.__columnsCount = columnsCount\r\n\t}\r\n\r\n\t// Returns a `Promise`.\r\n\ttriggerResize({\r\n\t\tscreenWidth,\r\n\t\tscreenHeight,\r\n\t\tcolumnsCount,\r\n\t\tverticalSpacing\r\n\t}) {\r\n\t\tthis.updateScreenDimensions({\r\n\t\t\tscreenWidth,\r\n\t\t\tscreenHeight,\r\n\t\t\tcolumnsCount,\r\n\t\t\tverticalSpacing\r\n\t\t})\r\n\r\n\t\t// Call \"on resize\" listener.\r\n\t\treturn this.virtualScroller.scrollableContainer._triggerResizeListener()\r\n\t}\r\n\r\n\tstop() {\r\n\t\tif (this.expectedStateUpdates.length > 0) {\r\n\t\t\tthrow new Error(`[virtual-scroller] Expected ${this.expectedStateUpdates.length} state updates which didn't happen:\\n${JSON.stringify(this.expectedStateUpdates, null, 2)}`)\r\n\t\t}\r\n\t\tif (this.pausedStateUpdate) {\r\n\t\t\tthrow new Error('[virtual-scroller] State updates were paused and haven\\'t been resumed afterwards')\r\n\t\t}\r\n\t\tthis.virtualScroller.stop()\r\n\t}\r\n\r\n\tstart() {\r\n\t\tthis.virtualScroller.start()\r\n\t}\r\n\r\n\tgetState() {\r\n\t\treturn this.virtualScroller.getState()\r\n\t}\r\n\r\n\tupdateLayout() {\r\n\t\tthis.virtualScroller.updateLayout()\r\n\t}\r\n\r\n\tgetItemScrollPosition(itemOrIndex) {\r\n\t\treturn this.virtualScroller.getItemScrollPosition(itemOrIndex)\r\n\t}\r\n\r\n\tonItemHeightDidChange(itemOrIndex) {\r\n\t\tthis.virtualScroller.onItemHeightDidChange(itemOrIndex)\r\n\t}\r\n\r\n\tsetItemState(itemOrIndex, newState) {\r\n\t\tthis.virtualScroller.setItemState(itemOrIndex, newState)\r\n\t}\r\n\r\n\tgetAverageItemHeight() {\r\n\t\treturn this.virtualScroller.getAverageItemHeight()\r\n\t}\r\n\r\n\tsetItems(newItems, options) {\r\n\t\tthis.virtualScroller.setItems(newItems, options)\r\n\t}\r\n}\r\n"],"mappings":"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"}
1
+ {"version":3,"file":"VirtualScroller.js","names":["describe","it","expect","VirtualScroller","Engine","DEBUG","TestVirtualScroller","scrollableContainerWidth","screenWidth","scrollableContainerHeight","screenHeight","columnsCount","verticalSpacing","items","getItemId","initialState","state","rest","Object","keys","length","Error","join","expectedStateUpdates","scrollableContainerElement","width","height","containerElement","paddingTop","paddingBottom","children","setScrollableContainerWidth","setScrollableContainerHeight","getItemsContainerElement","__columnsCount","getColumnsCount","getItemWidth","hasPausedStateUpdates","undefined","pausedStateUpdate","pausedStateUpdateAction","onBeforeUpdateState","stateUpdate","expectedStateUpdate","shift","to","deep","equal","callback","render","virtualScroller","getState","beforeItemsHeight","afterItemsHeight","firstShownItemIndex","lastShownItemIndex","slice","map","item","getWidth","getHeight","getArea","area","getMarginTop","scrollableContainer","engine","_delayUnnecessaryRerenderUntilStopsScrolling","delayRecursiveRenderUntilNextTick","onStateChange","console","log","getInitialState","useState","updateState","stateUpdateAction","onRender","expectedState","include","push","firstNonMeasuredItemIndex","getScrollY","scrollPosition","scrollToY","updateScreenDimensions","_triggerResizeListener","JSON","stringify","stop","start","updateLayout","itemOrIndex","getItemScrollPosition","onItemHeightDidChange","newState","setItemState","getAverageItemHeight","newItems","options","setItems"],"sources":["../../source/test/VirtualScroller.js"],"sourcesContent":["import { describe, it } from 'mocha'\r\nimport { expect } from 'chai'\r\n\r\nimport VirtualScroller from '../VirtualScroller.js'\r\nimport Engine from './Engine.js'\r\n\r\nconst DEBUG = false\r\n\r\nexport default class TestVirtualScroller {\r\n\tconstructor({\r\n\t\tscreenWidth: scrollableContainerWidth,\r\n\t\tscreenHeight: scrollableContainerHeight,\r\n\t\tcolumnsCount,\r\n\t\tverticalSpacing,\r\n\t\titems,\r\n\t\tgetItemId,\r\n\t\tstate: initialState,\r\n\t\t...rest\r\n\t}) {\r\n\t\t// Validate that no unknown properties are passed.\r\n\t\t// This prevents the cases when a developer confuses\r\n\t\t// `TestVirtualScroller` options for `VirtualScroller` options.\r\n\t\tif (Object.keys(rest).length > 0) {\r\n\t\t\tthrow new Error(`Unknown options: ${Object.keys(rest).join(', ')}`)\r\n\t\t}\r\n\r\n\t\tthis.expectedStateUpdates = []\r\n\r\n\t\tconst scrollableContainerElement = {\r\n\t\t\twidth: scrollableContainerWidth,\r\n\t\t\theight: scrollableContainerHeight\r\n\t\t}\r\n\r\n\t\tconst containerElement = {\r\n\t\t\tpaddingTop: 0,\r\n\t\t\tpaddingBottom: 0,\r\n\t\t\twidth: scrollableContainerElement.width,\r\n\t\t\tchildren: []\r\n\t\t}\r\n\r\n\t\tthis.setScrollableContainerWidth = (width) => {\r\n\t\t\tscrollableContainerElement.width = width\r\n\t\t\tcontainerElement.width = width\r\n\t\t}\r\n\r\n\t\tthis.setScrollableContainerHeight = (height) => {\r\n\t\t\tscrollableContainerElement.height = height\r\n\t\t}\r\n\r\n\t\tconst getItemsContainerElement = () => containerElement\r\n\r\n\t\tthis.__columnsCount = columnsCount\r\n\r\n\t\tconst getColumnsCount = () => this.__columnsCount\r\n\t\tconst getItemWidth = () => scrollableContainerElement.width / getColumnsCount()\r\n\r\n\t\tthis.hasPausedStateUpdates = undefined\r\n\t\tthis.pausedStateUpdate = undefined\r\n\t\tthis.pausedStateUpdateAction = undefined\r\n\r\n\t\tconst onBeforeUpdateState = (stateUpdate) => {\r\n\t\t\tif (this.expectedStateUpdates.length > 0) {\r\n\t\t\t\tconst expectedStateUpdate = this.expectedStateUpdates.shift()\r\n\t\t\t\texpect(stateUpdate).to.deep.equal(expectedStateUpdate.stateUpdate)\r\n\t\t\t\tif (expectedStateUpdate.callback) {\r\n\t\t\t\t\texpectedStateUpdate.callback()\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tconst render = () => {\r\n\t\t\tconst {\r\n\t\t\t\titems,\r\n\t\t\t\tbeforeItemsHeight,\r\n\t\t\t\tafterItemsHeight,\r\n\t\t\t\tfirstShownItemIndex,\r\n\t\t\t\tlastShownItemIndex\r\n\t\t\t} = this.virtualScroller.getState()\r\n\r\n\t\t\tcontainerElement.paddingTop = beforeItemsHeight\r\n\t\t\tcontainerElement.paddingBottom = afterItemsHeight\r\n\r\n\t\t\tcontainerElement.children = items\r\n\t\t\t\t.slice(firstShownItemIndex, lastShownItemIndex + 1)\r\n\t\t\t\t.map((item) => ({\r\n\t\t\t\t\tgetWidth: () => getItemWidth(),\r\n\t\t\t\t\tgetHeight: () => (item.getArea ? item.getArea() : item.area) / getItemWidth(),\r\n\t\t\t\t\tgetMarginTop: () => verticalSpacing\r\n\t\t\t\t}))\r\n\t\t}\r\n\r\n\t\tthis.virtualScroller = new VirtualScroller(getItemsContainerElement, items, {\r\n\t\t\tscrollableContainer: scrollableContainerElement,\r\n\t\t\tengine: Engine,\r\n\t\t\t_delayUnnecessaryRerenderUntilStopsScrolling: false,\r\n\t\t\tdelayRecursiveRenderUntilNextTick: false,\r\n\t\t\tgetItemId,\r\n\t\t\tgetColumnsCount,\r\n\t\t\tstate: initialState,\r\n\t\t\tonStateChange(state) {\r\n\t\t\t\tif (DEBUG) {\r\n\t\t\t\t\tconsole.log('~ Updated State ~')\r\n\t\t\t\t\tconsole.log(state)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t})\r\n\r\n\t\tlet state = this.virtualScroller.getInitialState()\r\n\r\n\t\tthis.virtualScroller.useState({\r\n\t\t\tgetState: () => state,\r\n\t\t\tupdateState: (stateUpdate) => {\r\n\t\t\t\tconst stateUpdateAction = (stateUpdate) => {\r\n\t\t\t\t\t// Is only used in tests.\r\n\t\t\t\t\tif (onBeforeUpdateState) {\r\n\t\t\t\t\t\tonBeforeUpdateState(stateUpdate)\r\n\t\t\t\t\t}\r\n\t\t\t\t\tstate = {\r\n\t\t\t\t\t\t...state,\r\n\t\t\t\t\t\t...stateUpdate\r\n\t\t\t\t\t}\r\n\t\t\t\t\trender()\r\n\t\t\t\t\tthis.virtualScroller.onRender()\r\n\t\t\t\t}\r\n\t\t\t\tif (this.hasPausedStateUpdates) {\r\n\t\t\t\t\tthis.pausedStateUpdate = {\r\n\t\t\t\t\t\t...this.pausedStateUpdate,\r\n\t\t\t\t\t\t...stateUpdate\r\n\t\t\t\t\t}\r\n\t\t\t\t\tthis.pausedStateUpdateAction = stateUpdateAction\r\n\t\t\t\t} else {\r\n\t\t\t\t\tstateUpdateAction(stateUpdate)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t})\r\n\r\n\t\trender()\r\n\t}\r\n\r\n\tpauseStateUpdates() {\r\n\t\tif (this.hasPausedStateUpdates) {\r\n\t\t\tthrow new Error('[virtual-scroller] State updates have already been paused')\r\n\t\t}\r\n\t\tthis.hasPausedStateUpdates = true\r\n\t}\r\n\r\n\tresumeStateUpdates() {\r\n\t\tif (this.pausedStateUpdate) {\r\n\t\t\tthis.pausedStateUpdateAction(this.pausedStateUpdate)\r\n\t\t\tthis.pausedStateUpdate = undefined\r\n\t\t\tthis.pausedStateUpdateAction = undefined\r\n\t\t}\r\n\t\tthis.hasPausedStateUpdates = false\r\n\t}\r\n\r\n\tverifyState(expectedState) {\r\n\t\t// `mocha`/`chai`.\r\n\t\texpect(this.virtualScroller.getState()).to.deep.include(expectedState)\r\n\t}\r\n\r\n\texpectStateUpdate(stateUpdate, callback) {\r\n\t\tthis.expectedStateUpdates.push({\r\n\t\t\tstateUpdate,\r\n\t\t\tcallback\r\n\t\t})\r\n\t}\r\n\r\n\tgetFirstNonMeasuredItemIndex() {\r\n\t\treturn this.virtualScroller.firstNonMeasuredItemIndex\r\n\t}\r\n\r\n\tgetScrollY() {\r\n\t\treturn this.virtualScroller.scrollableContainer.getScrollY()\r\n\t}\r\n\r\n\tscrollTo(scrollPosition) {\r\n\t\tthis.virtualScroller.scrollableContainer.scrollToY(scrollPosition)\r\n\t}\r\n\r\n\tupdateScreenDimensions({\r\n\t\tscreenWidth: scrollableContainerWidth,\r\n\t\tscreenHeight: scrollableContainerHeight,\r\n\t\tcolumnsCount\r\n\t}) {\r\n\t\t// Resize scrollable container.\r\n\t\tthis.setScrollableContainerWidth(scrollableContainerWidth)\r\n\t\tthis.setScrollableContainerHeight(scrollableContainerHeight)\r\n\r\n\t\t// Update columns count.\r\n\t\tthis.__columnsCount = columnsCount\r\n\t}\r\n\r\n\t// Returns a `Promise`.\r\n\ttriggerResize({\r\n\t\tscreenWidth,\r\n\t\tscreenHeight,\r\n\t\tcolumnsCount,\r\n\t\tverticalSpacing\r\n\t}) {\r\n\t\tthis.updateScreenDimensions({\r\n\t\t\tscreenWidth,\r\n\t\t\tscreenHeight,\r\n\t\t\tcolumnsCount,\r\n\t\t\tverticalSpacing\r\n\t\t})\r\n\r\n\t\t// Call \"on resize\" listener.\r\n\t\treturn this.virtualScroller.scrollableContainer._triggerResizeListener()\r\n\t}\r\n\r\n\tstop() {\r\n\t\tif (this.expectedStateUpdates.length > 0) {\r\n\t\t\tthrow new Error(`[virtual-scroller] Expected ${this.expectedStateUpdates.length} state updates which didn't happen:\\n${JSON.stringify(this.expectedStateUpdates, null, 2)}`)\r\n\t\t}\r\n\t\tif (this.pausedStateUpdate) {\r\n\t\t\tthrow new Error('[virtual-scroller] State updates were paused and haven\\'t been resumed afterwards')\r\n\t\t}\r\n\t\tthis.virtualScroller.stop()\r\n\t}\r\n\r\n\tstart() {\r\n\t\tthis.virtualScroller.start()\r\n\t}\r\n\r\n\tgetState() {\r\n\t\treturn this.virtualScroller.getState()\r\n\t}\r\n\r\n\tupdateLayout() {\r\n\t\tthis.virtualScroller.updateLayout()\r\n\t}\r\n\r\n\tgetItemScrollPosition(itemOrIndex) {\r\n\t\treturn this.virtualScroller.getItemScrollPosition(itemOrIndex)\r\n\t}\r\n\r\n\tonItemHeightDidChange(itemOrIndex) {\r\n\t\tthis.virtualScroller.onItemHeightDidChange(itemOrIndex)\r\n\t}\r\n\r\n\tsetItemState(itemOrIndex, newState) {\r\n\t\tthis.virtualScroller.setItemState(itemOrIndex, newState)\r\n\t}\r\n\r\n\tgetAverageItemHeight() {\r\n\t\treturn this.virtualScroller.getAverageItemHeight()\r\n\t}\r\n\r\n\tsetItems(newItems, options) {\r\n\t\tthis.virtualScroller.setItems(newItems, options)\r\n\t}\r\n}\r\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA,SAASA,QAAT,EAAmBC,EAAnB,QAA6B,OAA7B;AACA,SAASC,MAAT,QAAuB,MAAvB;AAEA,OAAOC,eAAP,MAA4B,uBAA5B;AACA,OAAOC,MAAP,MAAmB,aAAnB;AAEA,IAAMC,KAAK,GAAG,KAAd;;IAEqBC,mB;EACpB,mCASG;IAAA;;IAAA,IARWC,wBAQX,QARFC,WAQE;IAAA,IAPYC,yBAOZ,QAPFC,YAOE;IAAA,IANFC,YAME,QANFA,YAME;IAAA,IALFC,eAKE,QALFA,eAKE;IAAA,IAJFC,KAIE,QAJFA,KAIE;IAAA,IAHFC,SAGE,QAHFA,SAGE;IAAA,IAFKC,YAEL,QAFFC,KAEE;IAAA,IADCC,IACD;;IAAA;;IACF;IACA;IACA;IACA,IAAIC,MAAM,CAACC,IAAP,CAAYF,IAAZ,EAAkBG,MAAlB,GAA2B,CAA/B,EAAkC;MACjC,MAAM,IAAIC,KAAJ,4BAA8BH,MAAM,CAACC,IAAP,CAAYF,IAAZ,EAAkBK,IAAlB,CAAuB,IAAvB,CAA9B,EAAN;IACA;;IAED,KAAKC,oBAAL,GAA4B,EAA5B;IAEA,IAAMC,0BAA0B,GAAG;MAClCC,KAAK,EAAElB,wBAD2B;MAElCmB,MAAM,EAAEjB;IAF0B,CAAnC;IAKA,IAAMkB,gBAAgB,GAAG;MACxBC,UAAU,EAAE,CADY;MAExBC,aAAa,EAAE,CAFS;MAGxBJ,KAAK,EAAED,0BAA0B,CAACC,KAHV;MAIxBK,QAAQ,EAAE;IAJc,CAAzB;;IAOA,KAAKC,2BAAL,GAAmC,UAACN,KAAD,EAAW;MAC7CD,0BAA0B,CAACC,KAA3B,GAAmCA,KAAnC;MACAE,gBAAgB,CAACF,KAAjB,GAAyBA,KAAzB;IACA,CAHD;;IAKA,KAAKO,4BAAL,GAAoC,UAACN,MAAD,EAAY;MAC/CF,0BAA0B,CAACE,MAA3B,GAAoCA,MAApC;IACA,CAFD;;IAIA,IAAMO,wBAAwB,GAAG,SAA3BA,wBAA2B;MAAA,OAAMN,gBAAN;IAAA,CAAjC;;IAEA,KAAKO,cAAL,GAAsBvB,YAAtB;;IAEA,IAAMwB,eAAe,GAAG,SAAlBA,eAAkB;MAAA,OAAM,KAAI,CAACD,cAAX;IAAA,CAAxB;;IACA,IAAME,YAAY,GAAG,SAAfA,YAAe;MAAA,OAAMZ,0BAA0B,CAACC,KAA3B,GAAmCU,eAAe,EAAxD;IAAA,CAArB;;IAEA,KAAKE,qBAAL,GAA6BC,SAA7B;IACA,KAAKC,iBAAL,GAAyBD,SAAzB;IACA,KAAKE,uBAAL,GAA+BF,SAA/B;;IAEA,IAAMG,mBAAmB,GAAG,SAAtBA,mBAAsB,CAACC,WAAD,EAAiB;MAC5C,IAAI,KAAI,CAACnB,oBAAL,CAA0BH,MAA1B,GAAmC,CAAvC,EAA0C;QACzC,IAAMuB,mBAAmB,GAAG,KAAI,CAACpB,oBAAL,CAA0BqB,KAA1B,EAA5B;;QACA1C,MAAM,CAACwC,WAAD,CAAN,CAAoBG,EAApB,CAAuBC,IAAvB,CAA4BC,KAA5B,CAAkCJ,mBAAmB,CAACD,WAAtD;;QACA,IAAIC,mBAAmB,CAACK,QAAxB,EAAkC;UACjCL,mBAAmB,CAACK,QAApB;QACA;MACD;IACD,CARD;;IAUA,IAAMC,MAAM,GAAG,SAATA,MAAS,GAAM;MACpB,4BAMI,KAAI,CAACC,eAAL,CAAqBC,QAArB,EANJ;MAAA,IACCtC,KADD,yBACCA,KADD;MAAA,IAECuC,iBAFD,yBAECA,iBAFD;MAAA,IAGCC,gBAHD,yBAGCA,gBAHD;MAAA,IAICC,mBAJD,yBAICA,mBAJD;MAAA,IAKCC,kBALD,yBAKCA,kBALD;;MAQA5B,gBAAgB,CAACC,UAAjB,GAA8BwB,iBAA9B;MACAzB,gBAAgB,CAACE,aAAjB,GAAiCwB,gBAAjC;MAEA1B,gBAAgB,CAACG,QAAjB,GAA4BjB,KAAK,CAC/B2C,KAD0B,CACpBF,mBADoB,EACCC,kBAAkB,GAAG,CADtB,EAE1BE,GAF0B,CAEtB,UAACC,IAAD;QAAA,OAAW;UACfC,QAAQ,EAAE;YAAA,OAAMvB,YAAY,EAAlB;UAAA,CADK;UAEfwB,SAAS,EAAE;YAAA,OAAM,CAACF,IAAI,CAACG,OAAL,GAAeH,IAAI,CAACG,OAAL,EAAf,GAAgCH,IAAI,CAACI,IAAtC,IAA8C1B,YAAY,EAAhE;UAAA,CAFI;UAGf2B,YAAY,EAAE;YAAA,OAAMnD,eAAN;UAAA;QAHC,CAAX;MAAA,CAFsB,CAA5B;IAOA,CAnBD;;IAqBA,KAAKsC,eAAL,GAAuB,IAAI/C,eAAJ,CAAoB8B,wBAApB,EAA8CpB,KAA9C,EAAqD;MAC3EmD,mBAAmB,EAAExC,0BADsD;MAE3EyC,MAAM,EAAE7D,MAFmE;MAG3E8D,4CAA4C,EAAE,KAH6B;MAI3EC,iCAAiC,EAAE,KAJwC;MAK3ErD,SAAS,EAATA,SAL2E;MAM3EqB,eAAe,EAAfA,eAN2E;MAO3EnB,KAAK,EAAED,YAPoE;MAQ3EqD,aAR2E,yBAQ7DpD,KAR6D,EAQtD;QACpB,IAAIX,KAAJ,EAAW;UACVgE,OAAO,CAACC,GAAR,CAAY,mBAAZ;UACAD,OAAO,CAACC,GAAR,CAAYtD,KAAZ;QACA;MACD;IAb0E,CAArD,CAAvB;IAgBA,IAAIA,KAAK,GAAG,KAAKkC,eAAL,CAAqBqB,eAArB,EAAZ;IAEA,KAAKrB,eAAL,CAAqBsB,QAArB,CAA8B;MAC7BrB,QAAQ,EAAE;QAAA,OAAMnC,KAAN;MAAA,CADmB;MAE7ByD,WAAW,EAAE,qBAAC/B,WAAD,EAAiB;QAC7B,IAAMgC,iBAAiB,GAAG,SAApBA,iBAAoB,CAAChC,WAAD,EAAiB;UAC1C;UACA,IAAID,mBAAJ,EAAyB;YACxBA,mBAAmB,CAACC,WAAD,CAAnB;UACA;;UACD1B,KAAK,mCACDA,KADC,GAED0B,WAFC,CAAL;UAIAO,MAAM;;UACN,KAAI,CAACC,eAAL,CAAqByB,QAArB;QACA,CAXD;;QAYA,IAAI,KAAI,CAACtC,qBAAT,EAAgC;UAC/B,KAAI,CAACE,iBAAL,mCACI,KAAI,CAACA,iBADT,GAEIG,WAFJ;UAIA,KAAI,CAACF,uBAAL,GAA+BkC,iBAA/B;QACA,CAND,MAMO;UACNA,iBAAiB,CAAChC,WAAD,CAAjB;QACA;MACD;IAxB4B,CAA9B;IA2BAO,MAAM;EACN;;;;WAED,6BAAoB;MACnB,IAAI,KAAKZ,qBAAT,EAAgC;QAC/B,MAAM,IAAIhB,KAAJ,CAAU,2DAAV,CAAN;MACA;;MACD,KAAKgB,qBAAL,GAA6B,IAA7B;IACA;;;WAED,8BAAqB;MACpB,IAAI,KAAKE,iBAAT,EAA4B;QAC3B,KAAKC,uBAAL,CAA6B,KAAKD,iBAAlC;QACA,KAAKA,iBAAL,GAAyBD,SAAzB;QACA,KAAKE,uBAAL,GAA+BF,SAA/B;MACA;;MACD,KAAKD,qBAAL,GAA6B,KAA7B;IACA;;;WAED,qBAAYuC,aAAZ,EAA2B;MAC1B;MACA1E,MAAM,CAAC,KAAKgD,eAAL,CAAqBC,QAArB,EAAD,CAAN,CAAwCN,EAAxC,CAA2CC,IAA3C,CAAgD+B,OAAhD,CAAwDD,aAAxD;IACA;;;WAED,2BAAkBlC,WAAlB,EAA+BM,QAA/B,EAAyC;MACxC,KAAKzB,oBAAL,CAA0BuD,IAA1B,CAA+B;QAC9BpC,WAAW,EAAXA,WAD8B;QAE9BM,QAAQ,EAARA;MAF8B,CAA/B;IAIA;;;WAED,wCAA+B;MAC9B,OAAO,KAAKE,eAAL,CAAqB6B,yBAA5B;IACA;;;WAED,sBAAa;MACZ,OAAO,KAAK7B,eAAL,CAAqBc,mBAArB,CAAyCgB,UAAzC,EAAP;IACA;;;WAED,kBAASC,cAAT,EAAyB;MACxB,KAAK/B,eAAL,CAAqBc,mBAArB,CAAyCkB,SAAzC,CAAmDD,cAAnD;IACA;;;WAED,uCAIG;MAAA,IAHW1E,wBAGX,SAHFC,WAGE;MAAA,IAFYC,yBAEZ,SAFFC,YAEE;MAAA,IADFC,YACE,SADFA,YACE;MACF;MACA,KAAKoB,2BAAL,CAAiCxB,wBAAjC;MACA,KAAKyB,4BAAL,CAAkCvB,yBAAlC,EAHE,CAKF;;MACA,KAAKyB,cAAL,GAAsBvB,YAAtB;IACA,C,CAED;;;;WACA,8BAKG;MAAA,IAJFH,WAIE,SAJFA,WAIE;MAAA,IAHFE,YAGE,SAHFA,YAGE;MAAA,IAFFC,YAEE,SAFFA,YAEE;MAAA,IADFC,eACE,SADFA,eACE;MACF,KAAKuE,sBAAL,CAA4B;QAC3B3E,WAAW,EAAXA,WAD2B;QAE3BE,YAAY,EAAZA,YAF2B;QAG3BC,YAAY,EAAZA,YAH2B;QAI3BC,eAAe,EAAfA;MAJ2B,CAA5B,EADE,CAQF;;MACA,OAAO,KAAKsC,eAAL,CAAqBc,mBAArB,CAAyCoB,sBAAzC,EAAP;IACA;;;WAED,gBAAO;MACN,IAAI,KAAK7D,oBAAL,CAA0BH,MAA1B,GAAmC,CAAvC,EAA0C;QACzC,MAAM,IAAIC,KAAJ,uCAAyC,KAAKE,oBAAL,CAA0BH,MAAnE,kDAAiHiE,IAAI,CAACC,SAAL,CAAe,KAAK/D,oBAApB,EAA0C,IAA1C,EAAgD,CAAhD,CAAjH,EAAN;MACA;;MACD,IAAI,KAAKgB,iBAAT,EAA4B;QAC3B,MAAM,IAAIlB,KAAJ,CAAU,mFAAV,CAAN;MACA;;MACD,KAAK6B,eAAL,CAAqBqC,IAArB;IACA;;;WAED,iBAAQ;MACP,KAAKrC,eAAL,CAAqBsC,KAArB;IACA;;;WAED,oBAAW;MACV,OAAO,KAAKtC,eAAL,CAAqBC,QAArB,EAAP;IACA;;;WAED,wBAAe;MACd,KAAKD,eAAL,CAAqBuC,YAArB;IACA;;;WAED,+BAAsBC,WAAtB,EAAmC;MAClC,OAAO,KAAKxC,eAAL,CAAqByC,qBAArB,CAA2CD,WAA3C,CAAP;IACA;;;WAED,+BAAsBA,WAAtB,EAAmC;MAClC,KAAKxC,eAAL,CAAqB0C,qBAArB,CAA2CF,WAA3C;IACA;;;WAED,sBAAaA,WAAb,EAA0BG,QAA1B,EAAoC;MACnC,KAAK3C,eAAL,CAAqB4C,YAArB,CAAkCJ,WAAlC,EAA+CG,QAA/C;IACA;;;WAED,gCAAuB;MACtB,OAAO,KAAK3C,eAAL,CAAqB6C,oBAArB,EAAP;IACA;;;WAED,kBAASC,QAAT,EAAmBC,OAAnB,EAA4B;MAC3B,KAAK/C,eAAL,CAAqBgD,QAArB,CAA8BF,QAA9B,EAAwCC,OAAxC;IACA;;;;;;SAlPmB3F,mB"}
@@ -1,9 +1,11 @@
1
+ import { describe, it } from 'mocha';
2
+ import { expect } from 'chai';
1
3
  import px from './px.js';
2
4
  describe('utility/px', function () {
3
5
  it('should truncate px values', function () {
4
- px(0).should.equal('0px');
5
- px(1).should.equal('1px');
6
- px(1.2345).should.equal('1.23px');
6
+ expect(px(0)).to.equal('0px');
7
+ expect(px(1)).to.equal('1px');
8
+ expect(px(1.2345)).to.equal('1.23px');
7
9
  });
8
10
  });
9
11
  //# sourceMappingURL=px.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"px.test.js","names":["px","describe","it","should","equal"],"sources":["../../source/utility/px.test.js"],"sourcesContent":["import px from './px.js'\r\n\r\ndescribe('utility/px', function() {\r\n\tit('should truncate px values', function() {\r\n\t\tpx(0).should.equal('0px')\r\n\t\tpx(1).should.equal('1px')\r\n\t\tpx(1.2345).should.equal('1.23px')\r\n\t})\r\n})"],"mappings":"AAAA,OAAOA,EAAP,MAAe,SAAf;AAEAC,QAAQ,CAAC,YAAD,EAAe,YAAW;EACjCC,EAAE,CAAC,2BAAD,EAA8B,YAAW;IAC1CF,EAAE,CAAC,CAAD,CAAF,CAAMG,MAAN,CAAaC,KAAb,CAAmB,KAAnB;IACAJ,EAAE,CAAC,CAAD,CAAF,CAAMG,MAAN,CAAaC,KAAb,CAAmB,KAAnB;IACAJ,EAAE,CAAC,MAAD,CAAF,CAAWG,MAAX,CAAkBC,KAAlB,CAAwB,QAAxB;EACA,CAJC,CAAF;AAKA,CANO,CAAR"}
1
+ {"version":3,"file":"px.test.js","names":["describe","it","expect","px","to","equal"],"sources":["../../source/utility/px.test.js"],"sourcesContent":["import { describe, it } from 'mocha'\r\nimport { expect } from 'chai'\r\n\r\nimport px from './px.js'\r\n\r\ndescribe('utility/px', function() {\r\n\tit('should truncate px values', function() {\r\n\t\texpect(px(0)).to.equal('0px')\r\n\t\texpect(px(1)).to.equal('1px')\r\n\t\texpect(px(1.2345)).to.equal('1.23px')\r\n\t})\r\n})"],"mappings":"AAAA,SAASA,QAAT,EAAmBC,EAAnB,QAA6B,OAA7B;AACA,SAASC,MAAT,QAAuB,MAAvB;AAEA,OAAOC,EAAP,MAAe,SAAf;AAEAH,QAAQ,CAAC,YAAD,EAAe,YAAW;EACjCC,EAAE,CAAC,2BAAD,EAA8B,YAAW;IAC1CC,MAAM,CAACC,EAAE,CAAC,CAAD,CAAH,CAAN,CAAcC,EAAd,CAAiBC,KAAjB,CAAuB,KAAvB;IACAH,MAAM,CAACC,EAAE,CAAC,CAAD,CAAH,CAAN,CAAcC,EAAd,CAAiBC,KAAjB,CAAuB,KAAvB;IACAH,MAAM,CAACC,EAAE,CAAC,MAAD,CAAH,CAAN,CAAmBC,EAAnB,CAAsBC,KAAtB,CAA4B,QAA5B;EACA,CAJC,CAAF;AAKA,CANO,CAAR"}
@@ -0,0 +1,15 @@
1
+ // For some weird reason, in Chrome, `setTimeout()` would lag up to a second (or more) behind.
2
+ // Turns out, Chrome developers have deprecated `setTimeout()` API entirely without asking anyone.
3
+ // Replacing `setTimeout()` with `requestAnimationFrame()` can work around that Chrome bug.
4
+ // https://github.com/bvaughn/react-virtualized/issues/722
5
+ import { setTimeout, clearTimeout } from 'request-animation-frame-timeout'; // This function could also use `requestAnimationFrame()` function
6
+ // but `setTimeout()` with `0` delay has practically the same effect
7
+ // and at the same time it's more universally supported, e.g. in Node.js.
8
+
9
+ export function scheduleOnNextTick(func) {
10
+ return setTimeout(func, 0);
11
+ }
12
+ export function unscheduleOnNextTick(timerId) {
13
+ clearTimeout(timerId);
14
+ }
15
+ //# sourceMappingURL=scheduleOnNextTick.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheduleOnNextTick.js","names":["setTimeout","clearTimeout","scheduleOnNextTick","func","unscheduleOnNextTick","timerId"],"sources":["../../source/utility/scheduleOnNextTick.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// This function could also use `requestAnimationFrame()` function\r\n// but `setTimeout()` with `0` delay has practically the same effect\r\n// and at the same time it's more universally supported, e.g. in Node.js.\r\nexport function scheduleOnNextTick(func) {\r\n\treturn setTimeout(func, 0)\r\n}\r\n\r\nexport function unscheduleOnNextTick(timerId) {\r\n\tclearTimeout(timerId)\r\n}"],"mappings":"AAAA;AACA;AACA;AACA;AACA,SAASA,UAAT,EAAqBC,YAArB,QAAyC,iCAAzC,C,CAEA;AACA;AACA;;AACA,OAAO,SAASC,kBAAT,CAA4BC,IAA5B,EAAkC;EACxC,OAAOH,UAAU,CAACG,IAAD,EAAO,CAAP,CAAjB;AACA;AAED,OAAO,SAASC,oBAAT,CAA8BC,OAA9B,EAAuC;EAC7CJ,YAAY,CAACI,OAAD,CAAZ;AACA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "virtual-scroller",
3
- "version": "1.16.2",
3
+ "version": "1.16.4",
4
4
  "description": "A component for efficiently rendering large lists of variable height items",
5
5
  "main": "index.cjs",
6
6
  "module": "index.js",
@@ -57,11 +57,12 @@
57
57
  "rollup-plugin-terser": "^7.0.2"
58
58
  },
59
59
  "scripts": {
60
- "test": "mocha --colors --bail --reporter spec --require ./test/setup.js \"source/**/*.test.js\" \"test/**/*.test.js\" --recursive",
60
+ "test": "mocha --bail --require ./test/globals.js \"source/**/*.test.js\" \"test/*.test.js\" \"test/!(exports)/**/*.test.js\"",
61
+ "test:exports": "mocha --bail \"test/exports/**/*.test.js\"",
61
62
  "test-coverage": "npm-run-all build:commonjs:clean build:commonjs build:commonjs:tests test-coverage:commonjs",
62
- "test-coverage:commonjs": "node --experimental-json-modules node_modules/istanbul/lib/cli.js cover -x \"*.test.js\" -x \"commonjs/DOM/**/*.js\" -x \"react/DOM/**/*.js\" -x \"commonjs/utility/shallowEqual.js\" -x \"commonjs/utility/debounce.js\" -x \"commonjs/utility/debug.js\" node_modules/mocha/bin/_mocha -- --colors --reporter dot --require regenerator-runtime --require ./test/setup.js \"commonjs/**/*.test.js\" --recursive",
63
+ "test-coverage:commonjs": "instanbul cover -x \"*.test.js\" -x \"commonjs/DOM/**/*.js\" -x \"react/DOM/**/*.js\" -x \"commonjs/utility/shallowEqual.js\" -x \"commonjs/utility/debounce.js\" -x \"commonjs/utility/debug.js\" node_modules/mocha/bin/_mocha -- --colors --reporter dot --require regenerator-runtime --require ./test/globals.js \"commonjs/**/*.test.js\" --recursive",
63
64
  "coveralls": "nyc report --reporter=text-lcov | coveralls",
64
- "build:commonjs:tests": "cross-env babel ./test/**/*.js --out-dir ./commonjs/test --source-maps --ignore \"test/exports.test.js\",\"test/VirtualScroller.js\",\"test/setup.js\"",
65
+ "build:commonjs:tests": "cross-env babel ./test/**/*.js --out-dir ./commonjs/test --source-maps --ignore \"test/exports.test.js\",\"test/VirtualScroller.js\",\"test/globals.js\"",
65
66
  "build:browser": "rollup --config rollup.config.mjs",
66
67
  "build:clean": "npm-run-all build:commonjs:clean build:es6:clean",
67
68
  "build:commonjs:clean": "rimraf ./commonjs/**/*",
@@ -71,7 +72,7 @@
71
72
  "build:es6": "cross-env BABEL_ENV=es6 babel ./source --out-dir ./modules --source-maps --ignore *.test.js",
72
73
  "build:es6:clean": "rimraf ./modules/**/*",
73
74
  "build": "npm-run-all build:clean build:commonjs build:es6 build:browser",
74
- "prepublishOnly": "npm-run-all build test"
75
+ "prepublishOnly": "npm-run-all build test test:exports"
75
76
  },
76
77
  "repository": {
77
78
  "type": "git",
@@ -1,9 +1,3 @@
1
- // For some weird reason, in Chrome, `setTimeout()` would lag up to a second (or more) behind.
2
- // Turns out, Chrome developers have deprecated `setTimeout()` API entirely without asking anyone.
3
- // Replacing `setTimeout()` with `requestAnimationFrame()` can work around that Chrome bug.
4
- // https://github.com/bvaughn/react-virtualized/issues/722
5
- import { setTimeout, clearTimeout } from 'request-animation-frame-timeout'
6
-
7
1
  // Refreshing two times every seconds seems reasonable.
8
2
  const WATCH_LIST_TOP_OFFSET_INTERVAL = 500
9
3