virtual-scroller 1.12.2 → 1.12.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/CODE_OF_CONDUCT.md +78 -0
- package/README.md +1 -1
- package/bundle/virtual-scroller-dom.js +1 -1
- package/bundle/virtual-scroller-dom.js.map +1 -1
- package/bundle/virtual-scroller-react.js +1 -1
- package/bundle/virtual-scroller-react.js.map +1 -1
- package/bundle/virtual-scroller.js +1 -1
- package/bundle/virtual-scroller.js.map +1 -1
- package/commonjs/Layout.js +1 -1
- package/commonjs/Layout.js.map +1 -1
- package/commonjs/Scroll.js +2 -1
- package/commonjs/Scroll.js.map +1 -1
- package/commonjs/VirtualScroller.js +62 -23
- package/commonjs/VirtualScroller.js.map +1 -1
- package/commonjs/VirtualScroller.layout.js +16 -10
- package/commonjs/VirtualScroller.layout.js.map +1 -1
- package/commonjs/VirtualScroller.onRender.js +2 -2
- package/commonjs/VirtualScroller.onRender.js.map +1 -1
- package/commonjs/react/VirtualScroller.js +3 -0
- package/commonjs/react/VirtualScroller.js.map +1 -1
- package/commonjs/react/useEffectDontMountTwiceInStrictMode.js +83 -0
- package/commonjs/react/useEffectDontMountTwiceInStrictMode.js.map +1 -0
- package/commonjs/react/useInsertionEffectDontMountTwiceInStrictMode.js +20 -0
- package/commonjs/react/useInsertionEffectDontMountTwiceInStrictMode.js.map +1 -0
- package/commonjs/react/useLayoutEffectDontMountTwiceInStrictMode.js +20 -0
- package/commonjs/react/useLayoutEffectDontMountTwiceInStrictMode.js.map +1 -0
- package/commonjs/react/useState.js +13 -7
- package/commonjs/react/useState.js.map +1 -1
- package/commonjs/react/useStateNoStaleBug.js +59 -0
- package/commonjs/react/useStateNoStaleBug.js.map +1 -0
- package/modules/Layout.js +1 -1
- package/modules/Layout.js.map +1 -1
- package/modules/Scroll.js +2 -1
- package/modules/Scroll.js.map +1 -1
- package/modules/VirtualScroller.js +62 -23
- package/modules/VirtualScroller.js.map +1 -1
- package/modules/VirtualScroller.layout.js +16 -10
- package/modules/VirtualScroller.layout.js.map +1 -1
- package/modules/VirtualScroller.onRender.js +2 -2
- package/modules/VirtualScroller.onRender.js.map +1 -1
- package/modules/react/VirtualScroller.js +3 -1
- package/modules/react/VirtualScroller.js.map +1 -1
- package/modules/react/useEffectDontMountTwiceInStrictMode.js +75 -0
- package/modules/react/useEffectDontMountTwiceInStrictMode.js.map +1 -0
- package/modules/react/useInsertionEffectDontMountTwiceInStrictMode.js +9 -0
- package/modules/react/useInsertionEffectDontMountTwiceInStrictMode.js.map +1 -0
- package/modules/react/useLayoutEffectDontMountTwiceInStrictMode.js +9 -0
- package/modules/react/useLayoutEffectDontMountTwiceInStrictMode.js.map +1 -0
- package/modules/react/useState.js +11 -8
- package/modules/react/useState.js.map +1 -1
- package/modules/react/useStateNoStaleBug.js +51 -0
- package/modules/react/useStateNoStaleBug.js.map +1 -0
- package/package.json +1 -1
- package/source/Layout.js +1 -1
- package/source/Scroll.js +1 -0
- package/source/VirtualScroller.js +61 -21
- package/source/VirtualScroller.layout.js +14 -8
- package/source/VirtualScroller.onRender.js +2 -2
- package/source/react/VirtualScroller.js +3 -0
- package/source/react/useEffectDontMountTwiceInStrictMode.js +68 -0
- package/source/react/useInsertionEffectDontMountTwiceInStrictMode.js +10 -0
- package/source/react/useLayoutEffectDontMountTwiceInStrictMode.js +10 -0
- package/source/react/useState.js +8 -5
- package/source/react/useStateNoStaleBug.js +35 -0
package/commonjs/Layout.js
CHANGED
|
@@ -86,7 +86,7 @@ var Layout = /*#__PURE__*/function () {
|
|
|
86
86
|
return getValue();
|
|
87
87
|
} catch (error) {
|
|
88
88
|
if (error instanceof _ScrollableContainerNotReadyError["default"]) {
|
|
89
|
-
(0, _debug["default"])(
|
|
89
|
+
(0, _debug["default"])("Scrollable container size is not known at this point, so \"".concat(name, "\" can't be calculated yet. Default to"), defaultValue);
|
|
90
90
|
return defaultValue;
|
|
91
91
|
} else {
|
|
92
92
|
throw error;
|
package/commonjs/Layout.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Layout.js","names":["Layout","bypass","getInitialEstimatedItemHeight","getInitialEstimatedVisibleItemRowsCount","measureItemsBatchSize","getPrerenderMargin","getVerticalSpacing","getVerticalSpacingBeforeResize","getColumnsCount","getColumnsCountBeforeResize","getItemHeight","getItemHeightBeforeResize","getBeforeResizeItemsCount","getAverageItemHeight","getMaxVisibleAreaHeight","getPreviouslyCalculatedLayout","name","getValue","defaultValue","error","ScrollableContainerNotReadyError","log","itemsCount","columnsCount","beforeStart","firstShownItemIndex","lastShownItemIndex","getLastShownItemIndex","getInitialLastShownItemIndex","getInitialLayoutValueWithFallback","beforeItemsHeight","afterItemsHeight","estimatedRowsCount","getEstimatedRowsCountForHeight","isNaN","Error","Math","min","height","estimatedItemHeight","getEstimatedItemHeight","verticalSpacing","ceil","averageItemHeight","prependedItemsCount","appendedItemsCount","shouldRestoreScrollPosition","onResetGridLayout","appendedRowsCount","addedHeightAfter","prependedRowsCount","addedHeightBefore","warn","shownItemsCountBeforeItemsUpdate","afterItemsCount","i","nonMeasuredAreaHeight","indexOfTheFirstItemInTheRow","itemsCountToRenderForMeasurement","Infinity","undefined","firstNonMeasuredItemIndex","visibleAreaTop","visibleAreaBottom","indexes","_getShownItemIndex","fromIndex","findFirstShownItemIndex","getNonVisibleListShownItemIndexes","findLastShownItemIndex","parameters","beforeResize","beforeResizeItemsCount","notFound","beforeResizeItemsHeight","floor","currentRowFirstItemIndex","hasMoreRows","verticalSpacingAfterCurrentRow","currentRowHeight","columnIndex","itemHeight","getItemNotMeasuredIndexes","max","itemsHeightFromFirstRowToThisRow","rowStepsIntoVisibleAreaTop","rowStepsOutOfVisibleAreaBottomOrIsAtTheBorder","layout","beforeItemsCount","getBeforeItemsHeight","rowHeight","lastShownRowIndex","topOffsetInsideScrollableContainer","beforeResizeRowsCount","maxBeforeResizeRowsCount","beforeResizeRowIndex","itemRowIndex","rowIndex","LAYOUT_REASON","SCROLL","STOPPED_SCROLLING","MANUAL","STARTED","NON_MEASURED_ITEMS_HAVE_BEEN_MEASURED","VIEWPORT_WIDTH_CHANGED","VIEWPORT_HEIGHT_CHANGED","VIEWPORT_SIZE_UNCHANGED","ITEM_HEIGHT_CHANGED","ITEMS_CHANGED","TOP_OFFSET_CHANGED"],"sources":["../source/Layout.js"],"sourcesContent":["import log, { warn } from './utility/debug.js'\r\nimport ScrollableContainerNotReadyError from './ScrollableContainerNotReadyError.js'\r\n\r\nexport default class Layout {\r\n\tconstructor({\r\n\t\tbypass,\r\n\t\tgetInitialEstimatedItemHeight,\r\n\t\tgetInitialEstimatedVisibleItemRowsCount,\r\n\t\tmeasureItemsBatchSize,\r\n\t\tgetPrerenderMargin,\r\n\t\tgetVerticalSpacing,\r\n\t\tgetVerticalSpacingBeforeResize,\r\n\t\tgetColumnsCount,\r\n\t\tgetColumnsCountBeforeResize,\r\n\t\tgetItemHeight,\r\n\t\tgetItemHeightBeforeResize,\r\n\t\tgetBeforeResizeItemsCount,\r\n\t\tgetAverageItemHeight,\r\n\t\tgetMaxVisibleAreaHeight,\r\n\t\tgetPreviouslyCalculatedLayout\r\n\t}) {\r\n\t\tthis.bypass = bypass\r\n\t\tthis.getInitialEstimatedItemHeight = getInitialEstimatedItemHeight\r\n\t\tthis.getInitialEstimatedVisibleItemRowsCount = getInitialEstimatedVisibleItemRowsCount\r\n\t\tthis.measureItemsBatchSize = measureItemsBatchSize\r\n\t\tthis.getPrerenderMargin = getPrerenderMargin\r\n\t\tthis.getVerticalSpacing = getVerticalSpacing\r\n\t\tthis.getVerticalSpacingBeforeResize = getVerticalSpacingBeforeResize\r\n\t\tthis.getColumnsCount = getColumnsCount\r\n\t\tthis.getColumnsCountBeforeResize = getColumnsCountBeforeResize\r\n\t\tthis.getItemHeight = getItemHeight\r\n\t\tthis.getItemHeightBeforeResize = getItemHeightBeforeResize\r\n\t\tthis.getBeforeResizeItemsCount = getBeforeResizeItemsCount\r\n\t\tthis.getAverageItemHeight = getAverageItemHeight\r\n\t\tthis.getMaxVisibleAreaHeight = getMaxVisibleAreaHeight\r\n\t\t//\r\n\t\t// The \"previously calculated layout\" feature is not currently used.\r\n\t\t//\r\n\t\t// The current layout snapshot could be stored as a \"previously calculated layout\" variable\r\n\t\t// so that it could theoretically be used when calculating new layout incrementally\r\n\t\t// rather than from scratch, which would be an optimization.\r\n\t\t//\r\n\t\tthis.getPreviouslyCalculatedLayout = getPreviouslyCalculatedLayout\r\n\t}\r\n\r\n\t// React `<VirtualScroller/>` component attempts to create the initial state\r\n\t// before the component tree has mounted. This could result in an inability to\r\n\t// calculate some initial layout values like `columnsCount` or `lastShownItemIndex`.\r\n\t// Such errors aren't considered critical because layout will be re-calculated\r\n\t// after the component mounts. The workaround is to use some sane default values\r\n\t// until the scrollable container has mounted.\r\n\tgetInitialLayoutValueWithFallback(name, getValue, defaultValue) {\r\n\t\ttry {\r\n\t\t\treturn getValue()\r\n\t\t} catch (error) {\r\n\t\t\tif (error instanceof ScrollableContainerNotReadyError) {\r\n\t\t\t\tlog('Couldn\\'t calculate', name, 'before scrollable container is ready. Default to', defaultValue);\r\n\t\t\t\treturn defaultValue\r\n\t\t\t} else {\r\n\t\t\t\tthrow error\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tgetInitialLayoutValues({\r\n\t\titemsCount,\r\n\t\tcolumnsCount,\r\n\t\tbeforeStart\r\n\t}) {\r\n\t\tlet firstShownItemIndex\r\n\t\tlet lastShownItemIndex\r\n\t\t// If there're no items then `firstShownItemIndex` stays `undefined`.\r\n\t\tif (itemsCount > 0) {\r\n\t\t\tconst getLastShownItemIndex = () => {\r\n\t\t\t\treturn this.getInitialLastShownItemIndex({\r\n\t\t\t\t\titemsCount,\r\n\t\t\t\t\tcolumnsCount,\r\n\t\t\t\t\tfirstShownItemIndex\r\n\t\t\t\t})\r\n\t\t\t}\r\n\t\t\tfirstShownItemIndex = 0\r\n\t\t\tlastShownItemIndex = beforeStart\r\n\t\t\t\t? this.getInitialLayoutValueWithFallback(\r\n\t\t\t\t\t'lastShownItemIndex',\r\n\t\t\t\t\tgetLastShownItemIndex,\r\n\t\t\t\t\t0\r\n\t\t\t\t)\r\n\t\t\t\t: getLastShownItemIndex()\r\n\t\t}\r\n\t\treturn {\r\n\t\t\tbeforeItemsHeight: 0,\r\n\t\t\tafterItemsHeight: 0,\r\n\t\t\tfirstShownItemIndex,\r\n\t\t\tlastShownItemIndex\r\n\t\t}\r\n\t}\r\n\r\n\tgetInitialLastShownItemIndex({\r\n\t\titemsCount,\r\n\t\tcolumnsCount,\r\n\t\tfirstShownItemIndex\r\n\t}) {\r\n\t\tif (this.bypass) {\r\n\t\t\treturn itemsCount - 1\r\n\t\t}\r\n\t\t// On server side, at initialization time,\r\n\t\t// `scrollableContainer` is `undefined`,\r\n\t\t// so default to `1` estimated rows count.\r\n\t\tlet estimatedRowsCount = 1\r\n\t\tif (this.getMaxVisibleAreaHeight()) {\r\n\t\t\testimatedRowsCount = this.getEstimatedRowsCountForHeight(this.getMaxVisibleAreaHeight() + this.getPrerenderMargin())\r\n\t\t} else if (this.getInitialEstimatedVisibleItemRowsCount) {\r\n\t\t\testimatedRowsCount = this.getInitialEstimatedVisibleItemRowsCount()\r\n\t\t\tif (isNaN(estimatedRowsCount)) {\r\n\t\t\t\tthrow new Error('[virtual-scroller] `getEstimatedVisibleItemRowsCount()` must return a number')\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn Math.min(\r\n\t\t\tfirstShownItemIndex + (estimatedRowsCount * columnsCount - 1),\r\n\t\t\titemsCount - 1\r\n\t\t)\r\n\t}\r\n\r\n\tgetEstimatedRowsCountForHeight(height) {\r\n\t\tconst estimatedItemHeight = this.getEstimatedItemHeight()\r\n\t\tconst verticalSpacing = this.getVerticalSpacing()\r\n\t\tif (estimatedItemHeight) {\r\n\t\t\treturn Math.ceil((height + verticalSpacing) / (estimatedItemHeight + verticalSpacing))\r\n\t\t} else {\r\n\t\t\t// If no items have been rendered yet, and no `estimatedItemHeight` option\r\n\t\t\t// has been passed, then default to `1` estimated rows count in any `height`.\r\n\t\t\treturn 1\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Returns estimated list item height.\r\n\t * (depends on which items have been previously rendered and measured).\r\n\t * @return {number}\r\n\t */\r\n\tgetEstimatedItemHeight() {\r\n\t\tconst averageItemHeight = this.getAverageItemHeight()\r\n\t\tif (averageItemHeight) {\r\n\t\t\treturn averageItemHeight\r\n\t\t}\r\n\t\tif (this.getInitialEstimatedItemHeight) {\r\n\t\t\tconst estimatedItemHeight = this.getInitialEstimatedItemHeight()\r\n\t\t\tif (isNaN(estimatedItemHeight)) {\r\n\t\t\t\tthrow new Error('[virtual-scroller] `getInitialEstimatedItemHeight()` must return a number')\r\n\t\t\t}\r\n\t\t\treturn estimatedItemHeight\r\n\t\t}\r\n\t\treturn 0\r\n\t}\r\n\r\n\tgetLayoutUpdateForItemsDiff({\r\n\t\tfirstShownItemIndex,\r\n\t\tlastShownItemIndex,\r\n\t\tbeforeItemsHeight,\r\n\t\tafterItemsHeight\r\n\t}, {\r\n\t\tprependedItemsCount,\r\n\t\tappendedItemsCount\r\n\t}, {\r\n\t\titemsCount,\r\n\t\tcolumnsCount,\r\n\t\tshouldRestoreScrollPosition,\r\n\t\tonResetGridLayout\r\n\t}) {\r\n\t\t// const layoutUpdate = {}\r\n\r\n\t\t// If the layout stays the same, then simply increase\r\n\t\t// the top and bottom margins proportionally to the amount\r\n\t\t// of the items added.\r\n\t\tconst averageItemHeight = this.getAverageItemHeight()\r\n\t\tconst verticalSpacing = this.getVerticalSpacing()\r\n\r\n\t\tif (appendedItemsCount > 0) {\r\n\t\t\tconst appendedRowsCount = Math.ceil(appendedItemsCount / columnsCount)\r\n\t\t\tconst addedHeightAfter = appendedRowsCount * (verticalSpacing + averageItemHeight)\r\n\r\n\t\t\tafterItemsHeight += addedHeightAfter\r\n\r\n\t\t\t// layoutUpdate = {\r\n\t\t\t// \t...layoutUpdate,\r\n\t\t\t// \tafterItemsHeight\r\n\t\t\t// }\r\n\t\t}\r\n\r\n\t\tif (prependedItemsCount > 0) {\r\n\t\t\tconst prependedRowsCount = Math.ceil(prependedItemsCount / columnsCount)\r\n\t\t\tconst addedHeightBefore = prependedRowsCount * (averageItemHeight + verticalSpacing)\r\n\r\n\t\t\tfirstShownItemIndex += prependedItemsCount\r\n\t\t\tlastShownItemIndex += prependedItemsCount\r\n\t\t\tbeforeItemsHeight += addedHeightBefore\r\n\r\n\t\t\t// If the currently shown items position on screen should be preserved\r\n\t\t\t// when prepending new items, then it means that:\r\n\t\t\t// * The current scroll position should be snapshotted.\r\n\t\t\t// * The current list height should be snapshotted.\r\n\t\t\t// * All prepended items should be shown so that their height could be\r\n\t\t\t// measured after they're rendered. Based on the prepended items' height,\r\n\t\t\t// the scroll position will be restored so that there's no \"jump of content\".\r\n\t\t\tif (shouldRestoreScrollPosition) {\r\n\t\t\t\tfirstShownItemIndex = 0\r\n\t\t\t\tbeforeItemsHeight = 0\r\n\t\t\t}\r\n\r\n\t\t\tif (prependedItemsCount % columnsCount > 0) {\r\n\t\t\t\t// Rows will be rebalanced as a result of prepending new items,\r\n\t\t\t\t// and row heights can change as a result, so re-layout items\r\n\t\t\t\t// after they've been measured (after the upcoming re-render).\r\n\t\t\t\t//\r\n\t\t\t\t// For example, consider a web page where item rows are `display: flex`.\r\n\t\t\t\t// Suppose there're 3 columns and it shows items from 4 to 6.\r\n\t\t\t\t//\r\n\t\t\t\t// ------------------------------------------\r\n\t\t\t\t// | Apples are | Bananas | Cranberries |\r\n\t\t\t\t// | green | | |\r\n\t\t\t\t// ------------------------------------------\r\n\t\t\t\t// | Dates | Elderberry | Figs are |\r\n\t\t\t\t// | | | tasty |\r\n\t\t\t\t// ------------------------------------------\r\n\t\t\t\t//\r\n\t\t\t\t// Now, 1 item gets prepended. As a result, all existing rows will have\r\n\t\t\t\t// a different set of items, which means that the row heights will change.\r\n\t\t\t\t//\r\n\t\t\t\t// ------------------------------------------\r\n\t\t\t\t// | Zucchini | Apples are | Bananas |\r\n\t\t\t\t// | | green | |\r\n\t\t\t\t// ------------------------------------------\r\n\t\t\t\t// | Cranberries | Dates | Elderberry |\r\n\t\t\t\t// ------------------------------------------\r\n\t\t\t\t// | Figs |\r\n\t\t\t\t// | are tasty |\r\n\t\t\t\t// ---------------\r\n\t\t\t\t//\r\n\t\t\t\t// As it can be seen above, the second row's height has changed from 2 to 1.\r\n\t\t\t\t// Not only that, but `itemHeights` have changed as well, so if you thought\r\n\t\t\t\t// that the library could easily recalculate row heights using `Math.max()` — \r\n\t\t\t\t// turns out it's not always the case.\r\n\t\t\t\t//\r\n\t\t\t\t// There could be an explicit opt-in option for automatically recalculating\r\n\t\t\t\t// row heights, but I don't want to write code for such an extremely rare\r\n\t\t\t\t// use case. Instead, use the `getColumnsCount()` parameter function when\r\n\t\t\t\t// fetching previous items.\r\n\r\n\t\t\t\tonResetGridLayout()\r\n\r\n\t\t\t\twarn('~ Prepended items count', prependedItemsCount, 'is not divisible by Columns Count', columnsCount, '~')\r\n\t\t\t\twarn('Layout reset required')\r\n\r\n\t\t\t\tconst shownItemsCountBeforeItemsUpdate = lastShownItemIndex - firstShownItemIndex + 1\r\n\r\n\t\t\t\tfirstShownItemIndex = 0\r\n\t\t\t\tbeforeItemsHeight = 0\r\n\r\n\t\t\t\tif (!shouldRestoreScrollPosition) {\r\n\t\t\t\t\t// Limit shown items count if too many items have been prepended.\r\n\t\t\t\t\tif (prependedItemsCount > shownItemsCountBeforeItemsUpdate) {\r\n\t\t\t\t\t\tlastShownItemIndex = this.getInitialLastShownItemIndex({\r\n\t\t\t\t\t\t\titemsCount,\r\n\t\t\t\t\t\t\tcolumnsCount,\r\n\t\t\t\t\t\t\tfirstShownItemIndex\r\n\t\t\t\t\t\t})\r\n\r\n\t\t\t\t\t\t// Approximate `afterItemsHeight` calculation.\r\n\t\t\t\t\t\tconst afterItemsCount = itemsCount - (lastShownItemIndex + 1)\r\n\t\t\t\t\t\tafterItemsHeight = Math.ceil(afterItemsCount / columnsCount) * (verticalSpacing + averageItemHeight)\r\n\r\n\t\t\t\t\t\t// layoutUpdate = {\r\n\t\t\t\t\t\t// \t...layoutUpdate,\r\n\t\t\t\t\t\t// \tafterItemsHeight\r\n\t\t\t\t\t\t// }\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// layoutUpdate = {\r\n\t\t\t// \t...layoutUpdate,\r\n\t\t\t// \tbeforeItemsHeight,\r\n\t\t\t// \tfirstShownItemIndex,\r\n\t\t\t// \tlastShownItemIndex\r\n\t\t\t// }\r\n\t\t}\r\n\r\n\t\t// return layoutUpdate\r\n\r\n\t\t// Overwrite all four props in all scenarios.\r\n\t\t// The reason is that only this way subsequent `setItems()` calls\r\n\t\t// will be truly \"stateless\" when a chain of `setItems()` calls\r\n\t\t// could be replaced with just the last one in a scenario when\r\n\t\t// `updateState()` calls are \"asynchronous\" (delayed execution).\r\n\t\t//\r\n\t\t// So, for example, the user calls `setItems()` with one set of items.\r\n\t\t// A `updateState()` call has been dispatched but the `state` hasn't been updated yet.\r\n\t\t// Then the user calls `setItems()` with another set of items.\r\n\t\t// If this function only returned a minimal set of properties that actually change,\r\n\t\t// the other layout properties of the second `setItems()` call wouldn't overwrite the ones\r\n\t\t// scheduled for update during the first `setItems()` call, resulting in an inconsistent `state`.\r\n\t\t//\r\n\t\t// For example, the first `setItems()` call does a `updateState()` call where it updates\r\n\t\t// `afterItemsHeight`, and then the second `setItems()` call only updates `beforeItemsHeight`\r\n\t\t// and `firstShownItemIndex` and `lastShownItemIndex`. If the second `setItems()` call was to\r\n\t\t// overwrite any effects of the pending-but-not-yet-applied first `setItems()` call, it would\r\n\t\t// have to call `updateState()` with an `afterItemsHeight` property too, even though it hasn't change.\r\n\t\t// That would be just to revert the change to `afterItemsHeight` state property already scheduled\r\n\t\t// by the first `setItems()` call.\r\n\t\t//\r\n\t\treturn {\r\n\t\t\tbeforeItemsHeight,\r\n\t\t\tafterItemsHeight,\r\n\t\t\tfirstShownItemIndex,\r\n\t\t\tlastShownItemIndex\r\n\t\t}\r\n\t}\r\n\r\n\t// If an item that hasn't been shown (and measured) yet is encountered\r\n\t// then show such item and then retry after it has been measured.\r\n\tgetItemNotMeasuredIndexes(i, {\r\n\t\titemsCount,\r\n\t\tfirstShownItemIndex,\r\n\t\tnonMeasuredAreaHeight,\r\n\t\tindexOfTheFirstItemInTheRow\r\n\t}) {\r\n\t\tlog('Item index', i, 'height is required for calculations but hasn\\'t been measured yet. Mark the item as \"shown\", rerender the list, measure the item\\'s height and redo the layout.')\r\n\r\n\t\tconst columnsCount = this.getColumnsCount()\r\n\r\n\t\tconst itemsCountToRenderForMeasurement = Math.min(\r\n\t\t\tthis.getEstimatedRowsCountForHeight(nonMeasuredAreaHeight) * columnsCount,\r\n\t\t\tthis.measureItemsBatchSize || Infinity,\r\n\t\t)\r\n\r\n\t\tif (firstShownItemIndex === undefined) {\r\n\t\t\tfirstShownItemIndex = indexOfTheFirstItemInTheRow\r\n\t\t}\r\n\r\n\t\tconst lastShownItemIndex = Math.min(\r\n\t\t\tindexOfTheFirstItemInTheRow + itemsCountToRenderForMeasurement - 1,\r\n\t\t\t// Guard against index overflow.\r\n\t\t\titemsCount - 1\r\n\t\t)\r\n\r\n\t\treturn {\r\n\t\t\tfirstNonMeasuredItemIndex: i,\r\n\t\t\tfirstShownItemIndex,\r\n\t\t\tlastShownItemIndex\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Finds the indexes of the currently visible items.\r\n\t * @return {object} `{ firstShownItemIndex: number, lastShownItemIndex: number, firstNonMeasuredItemIndex: number? }`\r\n\t */\r\n\tgetShownItemIndexes({\r\n\t\titemsCount,\r\n\t\tvisibleAreaTop,\r\n\t\tvisibleAreaBottom\r\n\t}) {\r\n\t\tlet indexes = this._getShownItemIndex({\r\n\t\t\titemsCount,\r\n\t\t\tfromIndex: 0,\r\n\t\t\tvisibleAreaTop,\r\n\t\t\tvisibleAreaBottom,\r\n\t\t\tfindFirstShownItemIndex: true\r\n\t\t})\r\n\r\n\t\tif (indexes === null) {\r\n\t\t\treturn this.getNonVisibleListShownItemIndexes()\r\n\t\t}\r\n\r\n\t\tif (indexes.firstNonMeasuredItemIndex !== undefined) {\r\n\t\t\treturn indexes\r\n\t\t}\r\n\r\n\t\tconst { firstShownItemIndex, beforeItemsHeight } = indexes\r\n\r\n\t\tindexes = this._getShownItemIndex({\r\n\t\t\titemsCount,\r\n\t\t\tfromIndex: firstShownItemIndex,\r\n\t\t\tbeforeItemsHeight,\r\n\t\t\tvisibleAreaTop,\r\n\t\t\tvisibleAreaBottom,\r\n\t\t\tfindLastShownItemIndex: true\r\n\t\t})\r\n\r\n\t\tif (indexes === null) {\r\n\t\t\treturn this.getNonVisibleListShownItemIndexes()\r\n\t\t}\r\n\r\n\t\tif (indexes.firstNonMeasuredItemIndex !== undefined) {\r\n\t\t\treturn indexes\r\n\t\t}\r\n\r\n\t\tconst { lastShownItemIndex } = indexes\r\n\r\n\t\treturn {\r\n\t\t\tfirstShownItemIndex,\r\n\t\t\tlastShownItemIndex\r\n\t\t}\r\n\t}\r\n\r\n\t_getShownItemIndex(parameters) {\r\n\t\tconst {\r\n\t\t\tbeforeResize,\r\n\t\t\titemsCount,\r\n\t\t\tvisibleAreaTop,\r\n\t\t\tvisibleAreaBottom,\r\n\t\t\tfindFirstShownItemIndex,\r\n\t\t\tfindLastShownItemIndex,\r\n\t\t\t// backwards\r\n\t\t} = parameters\r\n\r\n\t\tlet {\r\n\t\t\tfromIndex,\r\n\t\t\tbeforeItemsHeight\r\n\t\t} = parameters\r\n\r\n\t\t// This function could potentially also use `this.getPreviouslyCalculatedLayout()`\r\n\t\t// in order to skip calculating visible item indexes from scratch\r\n\t\t// and instead just calculate the difference from a \"previously calculated layout\".\r\n\t\t//\r\n\t\t// I did a simple test in a web browser and found out that running the following\r\n\t\t// piece of code is less than 10 milliseconds:\r\n\t\t//\r\n\t\t// var startedAt = Date.now()\r\n\t\t// var i = 0\r\n\t\t// while (i < 1000000) {\r\n\t\t// i++\r\n\t\t// }\r\n\t\t// console.log(Date.now() - startedAt)\r\n\t\t//\r\n\t\t// Which becomes negligible in my project's use case (a couple thousands items max).\r\n\t\t//\r\n\t\t// If someone would attempt to use a \"previously calculated layout\" here\r\n\t\t// then `shownItemsHeight` would also have to be returned from this function:\r\n\t\t// the total height of all shown items including vertical spacing between them.\r\n\t\t//\r\n\t\t// If \"previously calculated layout\" would be used then it would first find\r\n\t\t// `firstShownItemIndex` and then find `lastShownItemIndex` as part of two\r\n\t\t// separate calls of this function, each with or without `backwards` flag,\r\n\t\t// depending on whether `visibleAreaTop` and `visibleAreBottom` have shifted up or down.\r\n\r\n\t\tlet firstShownItemIndex\r\n\t\tlet lastShownItemIndex\r\n\r\n\t\t// It's not always required to pass `beforeItemsHeight` parameter:\r\n\t\t// when `fromIndex` is `0`, it's also assumed to be `0`.\r\n\t\tif (fromIndex === 0) {\r\n\t\t\tbeforeItemsHeight = 0\r\n\t\t}\r\n\r\n\t\tif (beforeItemsHeight === undefined) {\r\n\t\t\tthrow new Error('[virtual-scroller] `beforeItemsHeight` not passed to `Layout.getShownItemIndexes()` when starting from index ' + fromIndex);\r\n\t\t}\r\n\r\n\t\t// const backwards = false\r\n\t\t// while (backwards ? i >= 0 : i < itemsCount) {}\r\n\r\n\t\tif (!beforeResize) {\r\n\t\t\tconst beforeResizeItemsCount = this.getBeforeResizeItemsCount()\r\n\t\t\tif (beforeResizeItemsCount > fromIndex) {\r\n\t\t\t\t// First search for the item in \"before resize\" items.\r\n\t\t\t\tconst {\r\n\t\t\t\t\tnotFound,\r\n\t\t\t\t\tbeforeItemsHeight: beforeResizeItemsHeight,\r\n\t\t\t\t\tfirstShownItemIndex,\r\n\t\t\t\t\tlastShownItemIndex\r\n\t\t\t\t} = this._getShownItemIndex({\r\n\t\t\t\t\t...parameters,\r\n\t\t\t\t\tbeforeResize: true,\r\n\t\t\t\t\titemsCount: beforeResizeItemsCount\r\n\t\t\t\t})\r\n\r\n\t\t\t\t// If the item was not found in \"before resize\" items\r\n\t\t\t\t// then search in regular items skipping \"before resize\" ones.\r\n\t\t\t\tif (notFound) {\r\n\t\t\t\t\tbeforeItemsHeight = beforeResizeItemsHeight\r\n\t\t\t\t\tfromIndex += beforeResizeItemsCount\r\n\t\t\t\t} else {\r\n\t\t\t\t\t// If the item was found in \"before resize\" items\r\n\t\t\t\t\t// then return the result.\r\n\t\t\t\t\t// Rebalance first / last shown item indexes based on\r\n\t\t\t\t\t// the current columns count, if required.\r\n\t\t\t\t\tconst columnsCount = this.getColumnsCount()\r\n\t\t\t\t\treturn {\r\n\t\t\t\t\t\tfirstShownItemIndex: firstShownItemIndex === undefined\r\n\t\t\t\t\t\t\t? undefined\r\n\t\t\t\t\t\t\t: Math.floor(firstShownItemIndex / columnsCount) * columnsCount,\r\n\t\t\t\t\t\tlastShownItemIndex: lastShownItemIndex === undefined\r\n\t\t\t\t\t\t\t? undefined\r\n\t\t\t\t\t\t\t: Math.floor(lastShownItemIndex / columnsCount) * columnsCount,\r\n\t\t\t\t\t\tbeforeItemsHeight: beforeResizeItemsHeight\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\tconst columnsCount = beforeResize ? this.getColumnsCountBeforeResize() : this.getColumnsCount()\r\n\t\tconst verticalSpacing = beforeResize ? this.getVerticalSpacingBeforeResize() : this.getVerticalSpacing()\r\n\r\n\t\tlet i = fromIndex\r\n\t\twhile (i < itemsCount) {\r\n\t\t\tconst currentRowFirstItemIndex = i\r\n\r\n\t\t\tconst hasMoreRows = itemsCount > currentRowFirstItemIndex + columnsCount\r\n\t\t\tconst verticalSpacingAfterCurrentRow = hasMoreRows ? verticalSpacing : 0\r\n\r\n\t\t\tlet currentRowHeight = 0\r\n\r\n\t\t\t// Calculate current row height.\r\n\t\t\tlet columnIndex = 0\r\n\t\t\twhile (columnIndex < columnsCount && i < itemsCount) {\r\n\t\t\t\tconst itemHeight = beforeResize ? this.getItemHeightBeforeResize(i) : this.getItemHeight(i)\r\n\r\n\t\t\t\t// If this item hasn't been measured yet (or re-measured after a resize)\r\n\t\t\t\t// then mark it as the first non-measured one.\r\n\t\t\t\t//\r\n\t\t\t\t// Can't happen by definition when `beforeResize` parameter is `true`.\r\n\t\t\t\t//\r\n\t\t\t\tif (itemHeight === undefined) {\r\n\t\t\t\t\treturn this.getItemNotMeasuredIndexes(i, {\r\n\t\t\t\t\t\titemsCount,\r\n\t\t\t\t\t\tfirstShownItemIndex: findLastShownItemIndex ? fromIndex : undefined,\r\n\t\t\t\t\t\tindexOfTheFirstItemInTheRow: currentRowFirstItemIndex,\r\n\t\t\t\t\t\tnonMeasuredAreaHeight: (visibleAreaBottom + this.getPrerenderMargin()) - beforeItemsHeight\r\n\t\t\t\t\t})\r\n\t\t\t\t}\r\n\r\n\t\t\t\tcurrentRowHeight = Math.max(currentRowHeight, itemHeight)\r\n\r\n\t\t\t\tcolumnIndex++\r\n\t\t\t\ti++\r\n\t\t\t}\r\n\r\n\t\t\tconst itemsHeightFromFirstRowToThisRow = beforeItemsHeight + currentRowHeight\r\n\r\n\t\t\tconst rowStepsIntoVisibleAreaTop = itemsHeightFromFirstRowToThisRow > visibleAreaTop - this.getPrerenderMargin()\r\n\t\t\tconst rowStepsOutOfVisibleAreaBottomOrIsAtTheBorder = itemsHeightFromFirstRowToThisRow + verticalSpacingAfterCurrentRow >= visibleAreaBottom + this.getPrerenderMargin()\r\n\r\n\t\t\t// if (backwards) {\r\n\t\t\t// \tif (findFirstShownItemIndex) {\r\n\t\t\t// \t\tif (rowStepsOutOfVisibleAreaTop) {\r\n\t\t\t// \t\t\treturn {\r\n\t\t\t// \t\t\t\tfirstShownItemIndex: currentRowFirstItemIndex + columnsCount\r\n\t\t\t// \t\t\t}\r\n\t\t\t// \t\t}\r\n\t\t\t// \t} else if (findLastShownItemIndex) {\r\n\t\t\t// \t\tif (rowStepsIntoVisibleAreaBottom) {\r\n\t\t\t// \t\t\treturn {\r\n\t\t\t// \t\t\t\tlastShownItemIndex: currentRowFirstItemIndex + columnsCount - 1\r\n\t\t\t// \t\t\t}\r\n\t\t\t// \t\t}\r\n\t\t\t// \t}\r\n\t\t\t// }\r\n\r\n\t\t\tif (findFirstShownItemIndex) {\r\n\t\t\t\tif (rowStepsIntoVisibleAreaTop) {\r\n\t\t\t\t\t// If item is the first one visible in the viewport\r\n\t\t\t\t\t// then start showing items from this row.\r\n\t\t\t\t\treturn {\r\n\t\t\t\t\t\tfirstShownItemIndex: currentRowFirstItemIndex,\r\n\t\t\t\t\t\tbeforeItemsHeight\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t} else if (findLastShownItemIndex) {\r\n\t\t\t\tif (rowStepsOutOfVisibleAreaBottomOrIsAtTheBorder) {\r\n\t\t\t\t\treturn {\r\n\t\t\t\t\t\tlastShownItemIndex: Math.min(\r\n\t\t\t\t\t\t\t// The index of the last item in the current row.\r\n\t\t\t\t\t\t\tcurrentRowFirstItemIndex + columnsCount - 1,\r\n\t\t\t\t\t\t\t// Guards against index overflow.\r\n\t\t\t\t\t\t\titemsCount - 1\r\n\t\t\t\t\t\t)\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tbeforeItemsHeight += currentRowHeight + verticalSpacingAfterCurrentRow\r\n\r\n\t\t\t// if (backwards) {\r\n\t\t\t// \t// Set `i` to be the first item of the current row.\r\n\t\t\t// \ti -= columnsCount\r\n\t\t\t// \tconst prevoiusRowIsBeforeResize = i - 1 < this.getBeforeResizeItemsCount()\r\n\t\t\t// \tconst previousRowColumnsCount = prevoiusRowIsBeforeResize ? this.getColumnsCountBeforeResize() : this.getColumnsCount()\r\n\t\t\t// \t// Set `i` to be the first item of the previous row.\r\n\t\t\t// \ti -= previousRowColumnsCount\r\n\t\t\t// }\r\n\t\t}\r\n\r\n\t\t// if (backwards) {\r\n\t\t// \tif (findFirstShownItemIndex) {\r\n\t\t// \t\twarn('The list is supposed to be visible but no visible item has been found (while traversing backwards)')\r\n\t\t// \t\treturn null\r\n\t\t// \t} else if (findLastShownItemIndex) {\r\n\t\t// \t\treturn {\r\n\t\t// \t\t\tfirstShownItemIndex: 0\r\n\t\t// \t\t}\r\n\t\t// \t}\r\n\t\t// }\r\n\r\n\t\tif (beforeResize) {\r\n\t\t\treturn {\r\n\t\t\t\tnotFound: true,\r\n\t\t\t\tbeforeItemsHeight\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// This case isn't supposed to happen but it could hypothetically happen\r\n\t\t// because the list height is measured from the user's screen and\r\n\t\t// not necessarily can be trusted.\r\n\t\tif (findFirstShownItemIndex) {\r\n\t\t\twarn('The list is supposed to be visible but no visible item has been found')\r\n\t\t\treturn null\r\n\t\t} else if (findLastShownItemIndex) {\r\n\t\t\treturn {\r\n\t\t\t\tlastShownItemIndex: itemsCount - 1\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tgetNonVisibleListShownItemIndexes() {\r\n\t\tconst layout = {\r\n\t\t\tfirstShownItemIndex: 0,\r\n\t\t\tlastShownItemIndex: 0\r\n\t\t}\r\n\t\tif (this.getItemHeight(0) === undefined) {\r\n\t\t\tlayout.firstNonMeasuredItemIndex = 0\r\n\t\t}\r\n\t\treturn layout\r\n\t}\r\n\r\n\t/**\r\n\t * Measures \"before\" items height.\r\n\t * @param {number} beforeItemsCount — Basically, first shown item index.\r\n\t * @return {number}\r\n\t */\r\n\tgetBeforeItemsHeight(\r\n\t\tbeforeItemsCount,\r\n\t\t{ beforeResize } = {}\r\n\t) {\r\n\t\t// This function could potentially also use `this.getPreviouslyCalculatedLayout()`\r\n\t\t// in order to skip calculating visible item indexes from scratch\r\n\t\t// and instead just calculate the difference from a \"previously calculated layout\".\r\n\t\t//\r\n\t\t// I did a simple test in a web browser and found out that running the following\r\n\t\t// piece of code is less than 10 milliseconds:\r\n\t\t//\r\n\t\t// var startedAt = Date.now()\r\n\t\t// var i = 0\r\n\t\t// while (i < 1000000) {\r\n\t\t// i++\r\n\t\t// }\r\n\t\t// console.log(Date.now() - startedAt)\r\n\t\t//\r\n\t\t// Which becomes negligible in my project's use case (a couple thousands items max).\r\n\r\n\t\tlet beforeItemsHeight = 0\r\n\t\tlet i = 0\r\n\r\n\t\tif (!beforeResize) {\r\n\t\t\tconst beforeResizeItemsCount = this.getBeforeResizeItemsCount()\r\n\r\n\t\t\tif (beforeResizeItemsCount > 0) {\r\n\t\t\t\t// First add all \"before resize\" item heights.\r\n\t\t\t\tbeforeItemsHeight = this.getBeforeItemsHeight(\r\n\t\t\t\t\t// `firstShownItemIndex` (called `beforeItemsCount`) could be greater than\r\n\t\t\t\t\t// `beforeResizeItemsCount` when the user scrolls down.\r\n\t\t\t\t\t// `firstShownItemIndex` (called `beforeItemsCount`) could be less than\r\n\t\t\t\t\t// `beforeResizeItemsCount` when the user scrolls up.\r\n\t\t\t\t\tMath.min(beforeItemsCount, beforeResizeItemsCount),\r\n\t\t\t\t\t{ beforeResize: true }\r\n\t\t\t\t)\r\n\t\t\t\ti = beforeResizeItemsCount\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tconst columnsCount = beforeResize ? this.getColumnsCountBeforeResize() : this.getColumnsCount()\r\n\t\tconst verticalSpacing = beforeResize ? this.getVerticalSpacingBeforeResize() : this.getVerticalSpacing()\r\n\r\n\t\twhile (i < beforeItemsCount) {\r\n\t\t\tconst currentRowFirstItemIndex = i\r\n\r\n\t\t\tlet rowHeight = 0\r\n\t\t\tlet columnIndex = 0\r\n\t\t\t// Not checking for `itemsCount` overflow here because `i = beforeItemsCount`\r\n\t\t\t// can only start at the start of a row, meaning that when calculating\r\n\t\t\t// \"before items height\" it's not supposed to add item heights from the\r\n\t\t\t// last row of items because in that case it would have to iterate from\r\n\t\t\t// `i === beforeItemsCount` and that condition is already checked above.\r\n\t\t\t// while (i < itemsCount) {\r\n\t\t\twhile (columnIndex < columnsCount) {\r\n\t\t\t\tlet itemHeight = beforeResize ? this.getItemHeightBeforeResize(i) : this.getItemHeight(i)\r\n\t\t\t\tif (itemHeight === undefined) {\r\n\t\t\t\t\t// `itemHeight` can only be `undefined` when not `beforeResize`.\r\n\t\t\t\t\t// Use the current \"average item height\" as a substitute.\r\n\t\t\t\t\titemHeight = this.getAverageItemHeight()\r\n\t\t\t\t}\r\n\t\t\t\trowHeight = Math.max(rowHeight, itemHeight)\r\n\t\t\t\ti++\r\n\t\t\t\tcolumnIndex++\r\n\t\t\t}\r\n\r\n\t\t\tbeforeItemsHeight += rowHeight\r\n\t\t\tbeforeItemsHeight += verticalSpacing\r\n\t\t}\r\n\r\n\t\treturn beforeItemsHeight\r\n\t}\r\n\r\n\t/**\r\n\t * Measures \"after\" items height.\r\n\t * @param {number} lastShownItemIndex — Last shown item index.\r\n\t * @param {number} itemsCount — Items count.\r\n\t * @return {number}\r\n\t */\r\n\tgetAfterItemsHeight(\r\n\t\tlastShownItemIndex,\r\n\t\titemsCount\r\n\t) {\r\n\t\t// This function could potentially also use `this.getPreviouslyCalculatedLayout()`\r\n\t\t// in order to skip calculating visible item indexes from scratch\r\n\t\t// and instead just calculate the difference from a \"previously calculated layout\".\r\n\t\t//\r\n\t\t// I did a simple test in a web browser and found out that running the following\r\n\t\t// piece of code is less than 10 milliseconds:\r\n\t\t//\r\n\t\t// var startedAt = Date.now()\r\n\t\t// var i = 0\r\n\t\t// while (i < 1000000) {\r\n\t\t// i++\r\n\t\t// }\r\n\t\t// console.log(Date.now() - startedAt)\r\n\t\t//\r\n\t\t// Which becomes negligible in my project's use case (a couple thousands items max).\r\n\r\n\t\tconst columnsCount = this.getColumnsCount()\r\n\t\tconst lastShownRowIndex = Math.floor(lastShownItemIndex / columnsCount)\r\n\r\n\t\tlet afterItemsHeight = 0\r\n\r\n\t\tlet i = lastShownItemIndex + 1\r\n\t\twhile (i < itemsCount) {\r\n\t\t\tlet rowHeight = 0\r\n\t\t\tlet columnIndex = 0\r\n\t\t\twhile (columnIndex < columnsCount && i < itemsCount) {\r\n\t\t\t\tlet itemHeight = this.getItemHeight(i)\r\n\t\t\t\tif (itemHeight === undefined) {\r\n\t\t\t\t\titemHeight = this.getAverageItemHeight()\r\n\t\t\t\t}\r\n\t\t\t\trowHeight = Math.max(rowHeight, itemHeight)\r\n\t\t\t\ti++\r\n\t\t\t\tcolumnIndex++\r\n\t\t\t}\r\n\r\n\t\t\t// Add all \"after\" items height.\r\n\t\t\tafterItemsHeight += this.getVerticalSpacing()\r\n\t\t\tafterItemsHeight += rowHeight\r\n\t\t}\r\n\r\n\t\treturn afterItemsHeight\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the items's top offset relative to the top edge of the first item.\r\n\t * @param {number} i — Item index\r\n\t * @return {[number]} Returns `undefined` if any of the previous items haven't been rendered yet.\r\n\t */\r\n\tgetItemTopOffset(i) {\r\n\t\tlet topOffsetInsideScrollableContainer = 0\r\n\r\n\t\tconst beforeResizeItemsCount = this.getBeforeResizeItemsCount()\r\n\t\tconst beforeResizeRowsCount = beforeResizeItemsCount === 0\r\n\t\t\t? 0\r\n\t\t\t: Math.ceil(beforeResizeItemsCount / this.getColumnsCountBeforeResize())\r\n\r\n\t\tconst maxBeforeResizeRowsCount = i < beforeResizeItemsCount\r\n\t\t\t? Math.floor(i / this.getColumnsCountBeforeResize())\r\n\t\t\t: beforeResizeRowsCount\r\n\r\n\t\tlet beforeResizeRowIndex = 0\r\n\t\twhile (beforeResizeRowIndex < maxBeforeResizeRowsCount) {\r\n\t\t\tconst rowHeight = this.getItemHeightBeforeResize(\r\n\t\t\t\tbeforeResizeRowIndex * this.getColumnsCountBeforeResize()\r\n\t\t\t)\r\n\r\n\t\t\ttopOffsetInsideScrollableContainer += rowHeight\r\n\t\t\ttopOffsetInsideScrollableContainer += this.getVerticalSpacingBeforeResize()\r\n\r\n\t\t\tbeforeResizeRowIndex++\r\n\t\t}\r\n\r\n\t\tconst itemRowIndex = Math.floor((i - beforeResizeItemsCount) / this.getColumnsCount())\r\n\r\n\t\tlet rowIndex = 0\r\n\t\twhile (rowIndex < itemRowIndex) {\r\n\t\t\tlet rowHeight = 0\r\n\t\t\tlet columnIndex = 0\r\n\t\t\twhile (columnIndex < this.getColumnsCount()) {\r\n\t\t\t\tconst itemHeight = this.getItemHeight(\r\n\t\t\t\t\tbeforeResizeItemsCount + rowIndex * this.getColumnsCount() + columnIndex\r\n\t\t\t\t)\r\n\t\t\t\tif (itemHeight === undefined) {\r\n\t\t\t\t\treturn\r\n\t\t\t\t}\r\n\t\t\t\trowHeight = Math.max(rowHeight, itemHeight)\r\n\t\t\t\tcolumnIndex++\r\n\t\t\t}\r\n\r\n\t\t\ttopOffsetInsideScrollableContainer += rowHeight\r\n\t\t\ttopOffsetInsideScrollableContainer += this.getVerticalSpacing()\r\n\r\n\t\t\trowIndex++\r\n\t\t}\r\n\r\n\t\treturn topOffsetInsideScrollableContainer\r\n\t}\r\n}\r\n\r\nexport const LAYOUT_REASON = {\r\n\tSCROLL: 'scroll',\r\n\tSTOPPED_SCROLLING: 'stopped scrolling',\r\n\tMANUAL: 'manual',\r\n\tSTARTED: 'started',\r\n\tNON_MEASURED_ITEMS_HAVE_BEEN_MEASURED: 'non-measured item heights have been measured',\r\n\tVIEWPORT_WIDTH_CHANGED: 'viewport width changed',\r\n\tVIEWPORT_HEIGHT_CHANGED: 'viewport height changed',\r\n\tVIEWPORT_SIZE_UNCHANGED: 'viewport size unchanged',\r\n\tITEM_HEIGHT_CHANGED: 'item height changed',\r\n\tITEMS_CHANGED: 'items changed',\r\n\tTOP_OFFSET_CHANGED: 'list top offset changed'\r\n}"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Layout.js","names":["Layout","bypass","getInitialEstimatedItemHeight","getInitialEstimatedVisibleItemRowsCount","measureItemsBatchSize","getPrerenderMargin","getVerticalSpacing","getVerticalSpacingBeforeResize","getColumnsCount","getColumnsCountBeforeResize","getItemHeight","getItemHeightBeforeResize","getBeforeResizeItemsCount","getAverageItemHeight","getMaxVisibleAreaHeight","getPreviouslyCalculatedLayout","name","getValue","defaultValue","error","ScrollableContainerNotReadyError","log","itemsCount","columnsCount","beforeStart","firstShownItemIndex","lastShownItemIndex","getLastShownItemIndex","getInitialLastShownItemIndex","getInitialLayoutValueWithFallback","beforeItemsHeight","afterItemsHeight","estimatedRowsCount","getEstimatedRowsCountForHeight","isNaN","Error","Math","min","height","estimatedItemHeight","getEstimatedItemHeight","verticalSpacing","ceil","averageItemHeight","prependedItemsCount","appendedItemsCount","shouldRestoreScrollPosition","onResetGridLayout","appendedRowsCount","addedHeightAfter","prependedRowsCount","addedHeightBefore","warn","shownItemsCountBeforeItemsUpdate","afterItemsCount","i","nonMeasuredAreaHeight","indexOfTheFirstItemInTheRow","itemsCountToRenderForMeasurement","Infinity","undefined","firstNonMeasuredItemIndex","visibleAreaTop","visibleAreaBottom","indexes","_getShownItemIndex","fromIndex","findFirstShownItemIndex","getNonVisibleListShownItemIndexes","findLastShownItemIndex","parameters","beforeResize","beforeResizeItemsCount","notFound","beforeResizeItemsHeight","floor","currentRowFirstItemIndex","hasMoreRows","verticalSpacingAfterCurrentRow","currentRowHeight","columnIndex","itemHeight","getItemNotMeasuredIndexes","max","itemsHeightFromFirstRowToThisRow","rowStepsIntoVisibleAreaTop","rowStepsOutOfVisibleAreaBottomOrIsAtTheBorder","layout","beforeItemsCount","getBeforeItemsHeight","rowHeight","lastShownRowIndex","topOffsetInsideScrollableContainer","beforeResizeRowsCount","maxBeforeResizeRowsCount","beforeResizeRowIndex","itemRowIndex","rowIndex","LAYOUT_REASON","SCROLL","STOPPED_SCROLLING","MANUAL","STARTED","NON_MEASURED_ITEMS_HAVE_BEEN_MEASURED","VIEWPORT_WIDTH_CHANGED","VIEWPORT_HEIGHT_CHANGED","VIEWPORT_SIZE_UNCHANGED","ITEM_HEIGHT_CHANGED","ITEMS_CHANGED","TOP_OFFSET_CHANGED"],"sources":["../source/Layout.js"],"sourcesContent":["import log, { warn } from './utility/debug.js'\r\nimport ScrollableContainerNotReadyError from './ScrollableContainerNotReadyError.js'\r\n\r\nexport default class Layout {\r\n\tconstructor({\r\n\t\tbypass,\r\n\t\tgetInitialEstimatedItemHeight,\r\n\t\tgetInitialEstimatedVisibleItemRowsCount,\r\n\t\tmeasureItemsBatchSize,\r\n\t\tgetPrerenderMargin,\r\n\t\tgetVerticalSpacing,\r\n\t\tgetVerticalSpacingBeforeResize,\r\n\t\tgetColumnsCount,\r\n\t\tgetColumnsCountBeforeResize,\r\n\t\tgetItemHeight,\r\n\t\tgetItemHeightBeforeResize,\r\n\t\tgetBeforeResizeItemsCount,\r\n\t\tgetAverageItemHeight,\r\n\t\tgetMaxVisibleAreaHeight,\r\n\t\tgetPreviouslyCalculatedLayout\r\n\t}) {\r\n\t\tthis.bypass = bypass\r\n\t\tthis.getInitialEstimatedItemHeight = getInitialEstimatedItemHeight\r\n\t\tthis.getInitialEstimatedVisibleItemRowsCount = getInitialEstimatedVisibleItemRowsCount\r\n\t\tthis.measureItemsBatchSize = measureItemsBatchSize\r\n\t\tthis.getPrerenderMargin = getPrerenderMargin\r\n\t\tthis.getVerticalSpacing = getVerticalSpacing\r\n\t\tthis.getVerticalSpacingBeforeResize = getVerticalSpacingBeforeResize\r\n\t\tthis.getColumnsCount = getColumnsCount\r\n\t\tthis.getColumnsCountBeforeResize = getColumnsCountBeforeResize\r\n\t\tthis.getItemHeight = getItemHeight\r\n\t\tthis.getItemHeightBeforeResize = getItemHeightBeforeResize\r\n\t\tthis.getBeforeResizeItemsCount = getBeforeResizeItemsCount\r\n\t\tthis.getAverageItemHeight = getAverageItemHeight\r\n\t\tthis.getMaxVisibleAreaHeight = getMaxVisibleAreaHeight\r\n\t\t//\r\n\t\t// The \"previously calculated layout\" feature is not currently used.\r\n\t\t//\r\n\t\t// The current layout snapshot could be stored as a \"previously calculated layout\" variable\r\n\t\t// so that it could theoretically be used when calculating new layout incrementally\r\n\t\t// rather than from scratch, which would be an optimization.\r\n\t\t//\r\n\t\tthis.getPreviouslyCalculatedLayout = getPreviouslyCalculatedLayout\r\n\t}\r\n\r\n\t// React `<VirtualScroller/>` component attempts to create the initial state\r\n\t// before the component tree has mounted. This could result in an inability to\r\n\t// calculate some initial layout values like `columnsCount` or `lastShownItemIndex`.\r\n\t// Such errors aren't considered critical because layout will be re-calculated\r\n\t// after the component mounts. The workaround is to use some sane default values\r\n\t// until the scrollable container has mounted.\r\n\tgetInitialLayoutValueWithFallback(name, getValue, defaultValue) {\r\n\t\ttry {\r\n\t\t\treturn getValue()\r\n\t\t} catch (error) {\r\n\t\t\tif (error instanceof ScrollableContainerNotReadyError) {\r\n\t\t\t\tlog(`Scrollable container size is not known at this point, so \"${name}\" can't be calculated yet. Default to`, defaultValue);\r\n\t\t\t\treturn defaultValue\r\n\t\t\t} else {\r\n\t\t\t\tthrow error\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tgetInitialLayoutValues({\r\n\t\titemsCount,\r\n\t\tcolumnsCount,\r\n\t\tbeforeStart\r\n\t}) {\r\n\t\tlet firstShownItemIndex\r\n\t\tlet lastShownItemIndex\r\n\t\t// If there're no items then `firstShownItemIndex` stays `undefined`.\r\n\t\tif (itemsCount > 0) {\r\n\t\t\tconst getLastShownItemIndex = () => {\r\n\t\t\t\treturn this.getInitialLastShownItemIndex({\r\n\t\t\t\t\titemsCount,\r\n\t\t\t\t\tcolumnsCount,\r\n\t\t\t\t\tfirstShownItemIndex\r\n\t\t\t\t})\r\n\t\t\t}\r\n\t\t\tfirstShownItemIndex = 0\r\n\t\t\tlastShownItemIndex = beforeStart\r\n\t\t\t\t? this.getInitialLayoutValueWithFallback(\r\n\t\t\t\t\t'lastShownItemIndex',\r\n\t\t\t\t\tgetLastShownItemIndex,\r\n\t\t\t\t\t0\r\n\t\t\t\t)\r\n\t\t\t\t: getLastShownItemIndex()\r\n\t\t}\r\n\t\treturn {\r\n\t\t\tbeforeItemsHeight: 0,\r\n\t\t\tafterItemsHeight: 0,\r\n\t\t\tfirstShownItemIndex,\r\n\t\t\tlastShownItemIndex\r\n\t\t}\r\n\t}\r\n\r\n\tgetInitialLastShownItemIndex({\r\n\t\titemsCount,\r\n\t\tcolumnsCount,\r\n\t\tfirstShownItemIndex\r\n\t}) {\r\n\t\tif (this.bypass) {\r\n\t\t\treturn itemsCount - 1\r\n\t\t}\r\n\t\t// On server side, at initialization time,\r\n\t\t// `scrollableContainer` is `undefined`,\r\n\t\t// so default to `1` estimated rows count.\r\n\t\tlet estimatedRowsCount = 1\r\n\t\tif (this.getMaxVisibleAreaHeight()) {\r\n\t\t\testimatedRowsCount = this.getEstimatedRowsCountForHeight(this.getMaxVisibleAreaHeight() + this.getPrerenderMargin())\r\n\t\t} else if (this.getInitialEstimatedVisibleItemRowsCount) {\r\n\t\t\testimatedRowsCount = this.getInitialEstimatedVisibleItemRowsCount()\r\n\t\t\tif (isNaN(estimatedRowsCount)) {\r\n\t\t\t\tthrow new Error('[virtual-scroller] `getEstimatedVisibleItemRowsCount()` must return a number')\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn Math.min(\r\n\t\t\tfirstShownItemIndex + (estimatedRowsCount * columnsCount - 1),\r\n\t\t\titemsCount - 1\r\n\t\t)\r\n\t}\r\n\r\n\tgetEstimatedRowsCountForHeight(height) {\r\n\t\tconst estimatedItemHeight = this.getEstimatedItemHeight()\r\n\t\tconst verticalSpacing = this.getVerticalSpacing()\r\n\t\tif (estimatedItemHeight) {\r\n\t\t\treturn Math.ceil((height + verticalSpacing) / (estimatedItemHeight + verticalSpacing))\r\n\t\t} else {\r\n\t\t\t// If no items have been rendered yet, and no `estimatedItemHeight` option\r\n\t\t\t// has been passed, then default to `1` estimated rows count in any `height`.\r\n\t\t\treturn 1\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Returns estimated list item height.\r\n\t * (depends on which items have been previously rendered and measured).\r\n\t * @return {number}\r\n\t */\r\n\tgetEstimatedItemHeight() {\r\n\t\tconst averageItemHeight = this.getAverageItemHeight()\r\n\t\tif (averageItemHeight) {\r\n\t\t\treturn averageItemHeight\r\n\t\t}\r\n\t\tif (this.getInitialEstimatedItemHeight) {\r\n\t\t\tconst estimatedItemHeight = this.getInitialEstimatedItemHeight()\r\n\t\t\tif (isNaN(estimatedItemHeight)) {\r\n\t\t\t\tthrow new Error('[virtual-scroller] `getInitialEstimatedItemHeight()` must return a number')\r\n\t\t\t}\r\n\t\t\treturn estimatedItemHeight\r\n\t\t}\r\n\t\treturn 0\r\n\t}\r\n\r\n\tgetLayoutUpdateForItemsDiff({\r\n\t\tfirstShownItemIndex,\r\n\t\tlastShownItemIndex,\r\n\t\tbeforeItemsHeight,\r\n\t\tafterItemsHeight\r\n\t}, {\r\n\t\tprependedItemsCount,\r\n\t\tappendedItemsCount\r\n\t}, {\r\n\t\titemsCount,\r\n\t\tcolumnsCount,\r\n\t\tshouldRestoreScrollPosition,\r\n\t\tonResetGridLayout\r\n\t}) {\r\n\t\t// const layoutUpdate = {}\r\n\r\n\t\t// If the layout stays the same, then simply increase\r\n\t\t// the top and bottom margins proportionally to the amount\r\n\t\t// of the items added.\r\n\t\tconst averageItemHeight = this.getAverageItemHeight()\r\n\t\tconst verticalSpacing = this.getVerticalSpacing()\r\n\r\n\t\tif (appendedItemsCount > 0) {\r\n\t\t\tconst appendedRowsCount = Math.ceil(appendedItemsCount / columnsCount)\r\n\t\t\tconst addedHeightAfter = appendedRowsCount * (verticalSpacing + averageItemHeight)\r\n\r\n\t\t\tafterItemsHeight += addedHeightAfter\r\n\r\n\t\t\t// layoutUpdate = {\r\n\t\t\t// \t...layoutUpdate,\r\n\t\t\t// \tafterItemsHeight\r\n\t\t\t// }\r\n\t\t}\r\n\r\n\t\tif (prependedItemsCount > 0) {\r\n\t\t\tconst prependedRowsCount = Math.ceil(prependedItemsCount / columnsCount)\r\n\t\t\tconst addedHeightBefore = prependedRowsCount * (averageItemHeight + verticalSpacing)\r\n\r\n\t\t\tfirstShownItemIndex += prependedItemsCount\r\n\t\t\tlastShownItemIndex += prependedItemsCount\r\n\t\t\tbeforeItemsHeight += addedHeightBefore\r\n\r\n\t\t\t// If the currently shown items position on screen should be preserved\r\n\t\t\t// when prepending new items, then it means that:\r\n\t\t\t// * The current scroll position should be snapshotted.\r\n\t\t\t// * The current list height should be snapshotted.\r\n\t\t\t// * All prepended items should be shown so that their height could be\r\n\t\t\t// measured after they're rendered. Based on the prepended items' height,\r\n\t\t\t// the scroll position will be restored so that there's no \"jump of content\".\r\n\t\t\tif (shouldRestoreScrollPosition) {\r\n\t\t\t\tfirstShownItemIndex = 0\r\n\t\t\t\tbeforeItemsHeight = 0\r\n\t\t\t}\r\n\r\n\t\t\tif (prependedItemsCount % columnsCount > 0) {\r\n\t\t\t\t// Rows will be rebalanced as a result of prepending new items,\r\n\t\t\t\t// and row heights can change as a result, so re-layout items\r\n\t\t\t\t// after they've been measured (after the upcoming re-render).\r\n\t\t\t\t//\r\n\t\t\t\t// For example, consider a web page where item rows are `display: flex`.\r\n\t\t\t\t// Suppose there're 3 columns and it shows items from 4 to 6.\r\n\t\t\t\t//\r\n\t\t\t\t// ------------------------------------------\r\n\t\t\t\t// | Apples are | Bananas | Cranberries |\r\n\t\t\t\t// | green | | |\r\n\t\t\t\t// ------------------------------------------\r\n\t\t\t\t// | Dates | Elderberry | Figs are |\r\n\t\t\t\t// | | | tasty |\r\n\t\t\t\t// ------------------------------------------\r\n\t\t\t\t//\r\n\t\t\t\t// Now, 1 item gets prepended. As a result, all existing rows will have\r\n\t\t\t\t// a different set of items, which means that the row heights will change.\r\n\t\t\t\t//\r\n\t\t\t\t// ------------------------------------------\r\n\t\t\t\t// | Zucchini | Apples are | Bananas |\r\n\t\t\t\t// | | green | |\r\n\t\t\t\t// ------------------------------------------\r\n\t\t\t\t// | Cranberries | Dates | Elderberry |\r\n\t\t\t\t// ------------------------------------------\r\n\t\t\t\t// | Figs |\r\n\t\t\t\t// | are tasty |\r\n\t\t\t\t// ---------------\r\n\t\t\t\t//\r\n\t\t\t\t// As it can be seen above, the second row's height has changed from 2 to 1.\r\n\t\t\t\t// Not only that, but `itemHeights` have changed as well, so if you thought\r\n\t\t\t\t// that the library could easily recalculate row heights using `Math.max()` — \r\n\t\t\t\t// turns out it's not always the case.\r\n\t\t\t\t//\r\n\t\t\t\t// There could be an explicit opt-in option for automatically recalculating\r\n\t\t\t\t// row heights, but I don't want to write code for such an extremely rare\r\n\t\t\t\t// use case. Instead, use the `getColumnsCount()` parameter function when\r\n\t\t\t\t// fetching previous items.\r\n\r\n\t\t\t\tonResetGridLayout()\r\n\r\n\t\t\t\twarn('~ Prepended items count', prependedItemsCount, 'is not divisible by Columns Count', columnsCount, '~')\r\n\t\t\t\twarn('Layout reset required')\r\n\r\n\t\t\t\tconst shownItemsCountBeforeItemsUpdate = lastShownItemIndex - firstShownItemIndex + 1\r\n\r\n\t\t\t\tfirstShownItemIndex = 0\r\n\t\t\t\tbeforeItemsHeight = 0\r\n\r\n\t\t\t\tif (!shouldRestoreScrollPosition) {\r\n\t\t\t\t\t// Limit shown items count if too many items have been prepended.\r\n\t\t\t\t\tif (prependedItemsCount > shownItemsCountBeforeItemsUpdate) {\r\n\t\t\t\t\t\tlastShownItemIndex = this.getInitialLastShownItemIndex({\r\n\t\t\t\t\t\t\titemsCount,\r\n\t\t\t\t\t\t\tcolumnsCount,\r\n\t\t\t\t\t\t\tfirstShownItemIndex\r\n\t\t\t\t\t\t})\r\n\r\n\t\t\t\t\t\t// Approximate `afterItemsHeight` calculation.\r\n\t\t\t\t\t\tconst afterItemsCount = itemsCount - (lastShownItemIndex + 1)\r\n\t\t\t\t\t\tafterItemsHeight = Math.ceil(afterItemsCount / columnsCount) * (verticalSpacing + averageItemHeight)\r\n\r\n\t\t\t\t\t\t// layoutUpdate = {\r\n\t\t\t\t\t\t// \t...layoutUpdate,\r\n\t\t\t\t\t\t// \tafterItemsHeight\r\n\t\t\t\t\t\t// }\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// layoutUpdate = {\r\n\t\t\t// \t...layoutUpdate,\r\n\t\t\t// \tbeforeItemsHeight,\r\n\t\t\t// \tfirstShownItemIndex,\r\n\t\t\t// \tlastShownItemIndex\r\n\t\t\t// }\r\n\t\t}\r\n\r\n\t\t// return layoutUpdate\r\n\r\n\t\t// Overwrite all four props in all scenarios.\r\n\t\t// The reason is that only this way subsequent `setItems()` calls\r\n\t\t// will be truly \"stateless\" when a chain of `setItems()` calls\r\n\t\t// could be replaced with just the last one in a scenario when\r\n\t\t// `updateState()` calls are \"asynchronous\" (delayed execution).\r\n\t\t//\r\n\t\t// So, for example, the user calls `setItems()` with one set of items.\r\n\t\t// A `updateState()` call has been dispatched but the `state` hasn't been updated yet.\r\n\t\t// Then the user calls `setItems()` with another set of items.\r\n\t\t// If this function only returned a minimal set of properties that actually change,\r\n\t\t// the other layout properties of the second `setItems()` call wouldn't overwrite the ones\r\n\t\t// scheduled for update during the first `setItems()` call, resulting in an inconsistent `state`.\r\n\t\t//\r\n\t\t// For example, the first `setItems()` call does a `updateState()` call where it updates\r\n\t\t// `afterItemsHeight`, and then the second `setItems()` call only updates `beforeItemsHeight`\r\n\t\t// and `firstShownItemIndex` and `lastShownItemIndex`. If the second `setItems()` call was to\r\n\t\t// overwrite any effects of the pending-but-not-yet-applied first `setItems()` call, it would\r\n\t\t// have to call `updateState()` with an `afterItemsHeight` property too, even though it hasn't change.\r\n\t\t// That would be just to revert the change to `afterItemsHeight` state property already scheduled\r\n\t\t// by the first `setItems()` call.\r\n\t\t//\r\n\t\treturn {\r\n\t\t\tbeforeItemsHeight,\r\n\t\t\tafterItemsHeight,\r\n\t\t\tfirstShownItemIndex,\r\n\t\t\tlastShownItemIndex\r\n\t\t}\r\n\t}\r\n\r\n\t// If an item that hasn't been shown (and measured) yet is encountered\r\n\t// then show such item and then retry after it has been measured.\r\n\tgetItemNotMeasuredIndexes(i, {\r\n\t\titemsCount,\r\n\t\tfirstShownItemIndex,\r\n\t\tnonMeasuredAreaHeight,\r\n\t\tindexOfTheFirstItemInTheRow\r\n\t}) {\r\n\t\tlog('Item index', i, 'height is required for calculations but hasn\\'t been measured yet. Mark the item as \"shown\", rerender the list, measure the item\\'s height and redo the layout.')\r\n\r\n\t\tconst columnsCount = this.getColumnsCount()\r\n\r\n\t\tconst itemsCountToRenderForMeasurement = Math.min(\r\n\t\t\tthis.getEstimatedRowsCountForHeight(nonMeasuredAreaHeight) * columnsCount,\r\n\t\t\tthis.measureItemsBatchSize || Infinity,\r\n\t\t)\r\n\r\n\t\tif (firstShownItemIndex === undefined) {\r\n\t\t\tfirstShownItemIndex = indexOfTheFirstItemInTheRow\r\n\t\t}\r\n\r\n\t\tconst lastShownItemIndex = Math.min(\r\n\t\t\tindexOfTheFirstItemInTheRow + itemsCountToRenderForMeasurement - 1,\r\n\t\t\t// Guard against index overflow.\r\n\t\t\titemsCount - 1\r\n\t\t)\r\n\r\n\t\treturn {\r\n\t\t\tfirstNonMeasuredItemIndex: i,\r\n\t\t\tfirstShownItemIndex,\r\n\t\t\tlastShownItemIndex\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Finds the indexes of the currently visible items.\r\n\t * @return {object} `{ firstShownItemIndex: number, lastShownItemIndex: number, firstNonMeasuredItemIndex: number? }`\r\n\t */\r\n\tgetShownItemIndexes({\r\n\t\titemsCount,\r\n\t\tvisibleAreaTop,\r\n\t\tvisibleAreaBottom\r\n\t}) {\r\n\t\tlet indexes = this._getShownItemIndex({\r\n\t\t\titemsCount,\r\n\t\t\tfromIndex: 0,\r\n\t\t\tvisibleAreaTop,\r\n\t\t\tvisibleAreaBottom,\r\n\t\t\tfindFirstShownItemIndex: true\r\n\t\t})\r\n\r\n\t\tif (indexes === null) {\r\n\t\t\treturn this.getNonVisibleListShownItemIndexes()\r\n\t\t}\r\n\r\n\t\tif (indexes.firstNonMeasuredItemIndex !== undefined) {\r\n\t\t\treturn indexes\r\n\t\t}\r\n\r\n\t\tconst { firstShownItemIndex, beforeItemsHeight } = indexes\r\n\r\n\t\tindexes = this._getShownItemIndex({\r\n\t\t\titemsCount,\r\n\t\t\tfromIndex: firstShownItemIndex,\r\n\t\t\tbeforeItemsHeight,\r\n\t\t\tvisibleAreaTop,\r\n\t\t\tvisibleAreaBottom,\r\n\t\t\tfindLastShownItemIndex: true\r\n\t\t})\r\n\r\n\t\tif (indexes === null) {\r\n\t\t\treturn this.getNonVisibleListShownItemIndexes()\r\n\t\t}\r\n\r\n\t\tif (indexes.firstNonMeasuredItemIndex !== undefined) {\r\n\t\t\treturn indexes\r\n\t\t}\r\n\r\n\t\tconst { lastShownItemIndex } = indexes\r\n\r\n\t\treturn {\r\n\t\t\tfirstShownItemIndex,\r\n\t\t\tlastShownItemIndex\r\n\t\t}\r\n\t}\r\n\r\n\t_getShownItemIndex(parameters) {\r\n\t\tconst {\r\n\t\t\tbeforeResize,\r\n\t\t\titemsCount,\r\n\t\t\tvisibleAreaTop,\r\n\t\t\tvisibleAreaBottom,\r\n\t\t\tfindFirstShownItemIndex,\r\n\t\t\tfindLastShownItemIndex,\r\n\t\t\t// backwards\r\n\t\t} = parameters\r\n\r\n\t\tlet {\r\n\t\t\tfromIndex,\r\n\t\t\tbeforeItemsHeight\r\n\t\t} = parameters\r\n\r\n\t\t// This function could potentially also use `this.getPreviouslyCalculatedLayout()`\r\n\t\t// in order to skip calculating visible item indexes from scratch\r\n\t\t// and instead just calculate the difference from a \"previously calculated layout\".\r\n\t\t//\r\n\t\t// I did a simple test in a web browser and found out that running the following\r\n\t\t// piece of code is less than 10 milliseconds:\r\n\t\t//\r\n\t\t// var startedAt = Date.now()\r\n\t\t// var i = 0\r\n\t\t// while (i < 1000000) {\r\n\t\t// i++\r\n\t\t// }\r\n\t\t// console.log(Date.now() - startedAt)\r\n\t\t//\r\n\t\t// Which becomes negligible in my project's use case (a couple thousands items max).\r\n\t\t//\r\n\t\t// If someone would attempt to use a \"previously calculated layout\" here\r\n\t\t// then `shownItemsHeight` would also have to be returned from this function:\r\n\t\t// the total height of all shown items including vertical spacing between them.\r\n\t\t//\r\n\t\t// If \"previously calculated layout\" would be used then it would first find\r\n\t\t// `firstShownItemIndex` and then find `lastShownItemIndex` as part of two\r\n\t\t// separate calls of this function, each with or without `backwards` flag,\r\n\t\t// depending on whether `visibleAreaTop` and `visibleAreBottom` have shifted up or down.\r\n\r\n\t\tlet firstShownItemIndex\r\n\t\tlet lastShownItemIndex\r\n\r\n\t\t// It's not always required to pass `beforeItemsHeight` parameter:\r\n\t\t// when `fromIndex` is `0`, it's also assumed to be `0`.\r\n\t\tif (fromIndex === 0) {\r\n\t\t\tbeforeItemsHeight = 0\r\n\t\t}\r\n\r\n\t\tif (beforeItemsHeight === undefined) {\r\n\t\t\tthrow new Error('[virtual-scroller] `beforeItemsHeight` not passed to `Layout.getShownItemIndexes()` when starting from index ' + fromIndex);\r\n\t\t}\r\n\r\n\t\t// const backwards = false\r\n\t\t// while (backwards ? i >= 0 : i < itemsCount) {}\r\n\r\n\t\tif (!beforeResize) {\r\n\t\t\tconst beforeResizeItemsCount = this.getBeforeResizeItemsCount()\r\n\t\t\tif (beforeResizeItemsCount > fromIndex) {\r\n\t\t\t\t// First search for the item in \"before resize\" items.\r\n\t\t\t\tconst {\r\n\t\t\t\t\tnotFound,\r\n\t\t\t\t\tbeforeItemsHeight: beforeResizeItemsHeight,\r\n\t\t\t\t\tfirstShownItemIndex,\r\n\t\t\t\t\tlastShownItemIndex\r\n\t\t\t\t} = this._getShownItemIndex({\r\n\t\t\t\t\t...parameters,\r\n\t\t\t\t\tbeforeResize: true,\r\n\t\t\t\t\titemsCount: beforeResizeItemsCount\r\n\t\t\t\t})\r\n\r\n\t\t\t\t// If the item was not found in \"before resize\" items\r\n\t\t\t\t// then search in regular items skipping \"before resize\" ones.\r\n\t\t\t\tif (notFound) {\r\n\t\t\t\t\tbeforeItemsHeight = beforeResizeItemsHeight\r\n\t\t\t\t\tfromIndex += beforeResizeItemsCount\r\n\t\t\t\t} else {\r\n\t\t\t\t\t// If the item was found in \"before resize\" items\r\n\t\t\t\t\t// then return the result.\r\n\t\t\t\t\t// Rebalance first / last shown item indexes based on\r\n\t\t\t\t\t// the current columns count, if required.\r\n\t\t\t\t\tconst columnsCount = this.getColumnsCount()\r\n\t\t\t\t\treturn {\r\n\t\t\t\t\t\tfirstShownItemIndex: firstShownItemIndex === undefined\r\n\t\t\t\t\t\t\t? undefined\r\n\t\t\t\t\t\t\t: Math.floor(firstShownItemIndex / columnsCount) * columnsCount,\r\n\t\t\t\t\t\tlastShownItemIndex: lastShownItemIndex === undefined\r\n\t\t\t\t\t\t\t? undefined\r\n\t\t\t\t\t\t\t: Math.floor(lastShownItemIndex / columnsCount) * columnsCount,\r\n\t\t\t\t\t\tbeforeItemsHeight: beforeResizeItemsHeight\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\tconst columnsCount = beforeResize ? this.getColumnsCountBeforeResize() : this.getColumnsCount()\r\n\t\tconst verticalSpacing = beforeResize ? this.getVerticalSpacingBeforeResize() : this.getVerticalSpacing()\r\n\r\n\t\tlet i = fromIndex\r\n\t\twhile (i < itemsCount) {\r\n\t\t\tconst currentRowFirstItemIndex = i\r\n\r\n\t\t\tconst hasMoreRows = itemsCount > currentRowFirstItemIndex + columnsCount\r\n\t\t\tconst verticalSpacingAfterCurrentRow = hasMoreRows ? verticalSpacing : 0\r\n\r\n\t\t\tlet currentRowHeight = 0\r\n\r\n\t\t\t// Calculate current row height.\r\n\t\t\tlet columnIndex = 0\r\n\t\t\twhile (columnIndex < columnsCount && i < itemsCount) {\r\n\t\t\t\tconst itemHeight = beforeResize ? this.getItemHeightBeforeResize(i) : this.getItemHeight(i)\r\n\r\n\t\t\t\t// If this item hasn't been measured yet (or re-measured after a resize)\r\n\t\t\t\t// then mark it as the first non-measured one.\r\n\t\t\t\t//\r\n\t\t\t\t// Can't happen by definition when `beforeResize` parameter is `true`.\r\n\t\t\t\t//\r\n\t\t\t\tif (itemHeight === undefined) {\r\n\t\t\t\t\treturn this.getItemNotMeasuredIndexes(i, {\r\n\t\t\t\t\t\titemsCount,\r\n\t\t\t\t\t\tfirstShownItemIndex: findLastShownItemIndex ? fromIndex : undefined,\r\n\t\t\t\t\t\tindexOfTheFirstItemInTheRow: currentRowFirstItemIndex,\r\n\t\t\t\t\t\tnonMeasuredAreaHeight: (visibleAreaBottom + this.getPrerenderMargin()) - beforeItemsHeight\r\n\t\t\t\t\t})\r\n\t\t\t\t}\r\n\r\n\t\t\t\tcurrentRowHeight = Math.max(currentRowHeight, itemHeight)\r\n\r\n\t\t\t\tcolumnIndex++\r\n\t\t\t\ti++\r\n\t\t\t}\r\n\r\n\t\t\tconst itemsHeightFromFirstRowToThisRow = beforeItemsHeight + currentRowHeight\r\n\r\n\t\t\tconst rowStepsIntoVisibleAreaTop = itemsHeightFromFirstRowToThisRow > visibleAreaTop - this.getPrerenderMargin()\r\n\t\t\tconst rowStepsOutOfVisibleAreaBottomOrIsAtTheBorder = itemsHeightFromFirstRowToThisRow + verticalSpacingAfterCurrentRow >= visibleAreaBottom + this.getPrerenderMargin()\r\n\r\n\t\t\t// if (backwards) {\r\n\t\t\t// \tif (findFirstShownItemIndex) {\r\n\t\t\t// \t\tif (rowStepsOutOfVisibleAreaTop) {\r\n\t\t\t// \t\t\treturn {\r\n\t\t\t// \t\t\t\tfirstShownItemIndex: currentRowFirstItemIndex + columnsCount\r\n\t\t\t// \t\t\t}\r\n\t\t\t// \t\t}\r\n\t\t\t// \t} else if (findLastShownItemIndex) {\r\n\t\t\t// \t\tif (rowStepsIntoVisibleAreaBottom) {\r\n\t\t\t// \t\t\treturn {\r\n\t\t\t// \t\t\t\tlastShownItemIndex: currentRowFirstItemIndex + columnsCount - 1\r\n\t\t\t// \t\t\t}\r\n\t\t\t// \t\t}\r\n\t\t\t// \t}\r\n\t\t\t// }\r\n\r\n\t\t\tif (findFirstShownItemIndex) {\r\n\t\t\t\tif (rowStepsIntoVisibleAreaTop) {\r\n\t\t\t\t\t// If item is the first one visible in the viewport\r\n\t\t\t\t\t// then start showing items from this row.\r\n\t\t\t\t\treturn {\r\n\t\t\t\t\t\tfirstShownItemIndex: currentRowFirstItemIndex,\r\n\t\t\t\t\t\tbeforeItemsHeight\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t} else if (findLastShownItemIndex) {\r\n\t\t\t\tif (rowStepsOutOfVisibleAreaBottomOrIsAtTheBorder) {\r\n\t\t\t\t\treturn {\r\n\t\t\t\t\t\tlastShownItemIndex: Math.min(\r\n\t\t\t\t\t\t\t// The index of the last item in the current row.\r\n\t\t\t\t\t\t\tcurrentRowFirstItemIndex + columnsCount - 1,\r\n\t\t\t\t\t\t\t// Guards against index overflow.\r\n\t\t\t\t\t\t\titemsCount - 1\r\n\t\t\t\t\t\t)\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tbeforeItemsHeight += currentRowHeight + verticalSpacingAfterCurrentRow\r\n\r\n\t\t\t// if (backwards) {\r\n\t\t\t// \t// Set `i` to be the first item of the current row.\r\n\t\t\t// \ti -= columnsCount\r\n\t\t\t// \tconst prevoiusRowIsBeforeResize = i - 1 < this.getBeforeResizeItemsCount()\r\n\t\t\t// \tconst previousRowColumnsCount = prevoiusRowIsBeforeResize ? this.getColumnsCountBeforeResize() : this.getColumnsCount()\r\n\t\t\t// \t// Set `i` to be the first item of the previous row.\r\n\t\t\t// \ti -= previousRowColumnsCount\r\n\t\t\t// }\r\n\t\t}\r\n\r\n\t\t// if (backwards) {\r\n\t\t// \tif (findFirstShownItemIndex) {\r\n\t\t// \t\twarn('The list is supposed to be visible but no visible item has been found (while traversing backwards)')\r\n\t\t// \t\treturn null\r\n\t\t// \t} else if (findLastShownItemIndex) {\r\n\t\t// \t\treturn {\r\n\t\t// \t\t\tfirstShownItemIndex: 0\r\n\t\t// \t\t}\r\n\t\t// \t}\r\n\t\t// }\r\n\r\n\t\tif (beforeResize) {\r\n\t\t\treturn {\r\n\t\t\t\tnotFound: true,\r\n\t\t\t\tbeforeItemsHeight\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// This case isn't supposed to happen but it could hypothetically happen\r\n\t\t// because the list height is measured from the user's screen and\r\n\t\t// not necessarily can be trusted.\r\n\t\tif (findFirstShownItemIndex) {\r\n\t\t\twarn('The list is supposed to be visible but no visible item has been found')\r\n\t\t\treturn null\r\n\t\t} else if (findLastShownItemIndex) {\r\n\t\t\treturn {\r\n\t\t\t\tlastShownItemIndex: itemsCount - 1\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tgetNonVisibleListShownItemIndexes() {\r\n\t\tconst layout = {\r\n\t\t\tfirstShownItemIndex: 0,\r\n\t\t\tlastShownItemIndex: 0\r\n\t\t}\r\n\t\tif (this.getItemHeight(0) === undefined) {\r\n\t\t\tlayout.firstNonMeasuredItemIndex = 0\r\n\t\t}\r\n\t\treturn layout\r\n\t}\r\n\r\n\t/**\r\n\t * Measures \"before\" items height.\r\n\t * @param {number} beforeItemsCount — Basically, first shown item index.\r\n\t * @return {number}\r\n\t */\r\n\tgetBeforeItemsHeight(\r\n\t\tbeforeItemsCount,\r\n\t\t{ beforeResize } = {}\r\n\t) {\r\n\t\t// This function could potentially also use `this.getPreviouslyCalculatedLayout()`\r\n\t\t// in order to skip calculating visible item indexes from scratch\r\n\t\t// and instead just calculate the difference from a \"previously calculated layout\".\r\n\t\t//\r\n\t\t// I did a simple test in a web browser and found out that running the following\r\n\t\t// piece of code is less than 10 milliseconds:\r\n\t\t//\r\n\t\t// var startedAt = Date.now()\r\n\t\t// var i = 0\r\n\t\t// while (i < 1000000) {\r\n\t\t// i++\r\n\t\t// }\r\n\t\t// console.log(Date.now() - startedAt)\r\n\t\t//\r\n\t\t// Which becomes negligible in my project's use case (a couple thousands items max).\r\n\r\n\t\tlet beforeItemsHeight = 0\r\n\t\tlet i = 0\r\n\r\n\t\tif (!beforeResize) {\r\n\t\t\tconst beforeResizeItemsCount = this.getBeforeResizeItemsCount()\r\n\r\n\t\t\tif (beforeResizeItemsCount > 0) {\r\n\t\t\t\t// First add all \"before resize\" item heights.\r\n\t\t\t\tbeforeItemsHeight = this.getBeforeItemsHeight(\r\n\t\t\t\t\t// `firstShownItemIndex` (called `beforeItemsCount`) could be greater than\r\n\t\t\t\t\t// `beforeResizeItemsCount` when the user scrolls down.\r\n\t\t\t\t\t// `firstShownItemIndex` (called `beforeItemsCount`) could be less than\r\n\t\t\t\t\t// `beforeResizeItemsCount` when the user scrolls up.\r\n\t\t\t\t\tMath.min(beforeItemsCount, beforeResizeItemsCount),\r\n\t\t\t\t\t{ beforeResize: true }\r\n\t\t\t\t)\r\n\t\t\t\ti = beforeResizeItemsCount\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tconst columnsCount = beforeResize ? this.getColumnsCountBeforeResize() : this.getColumnsCount()\r\n\t\tconst verticalSpacing = beforeResize ? this.getVerticalSpacingBeforeResize() : this.getVerticalSpacing()\r\n\r\n\t\twhile (i < beforeItemsCount) {\r\n\t\t\tconst currentRowFirstItemIndex = i\r\n\r\n\t\t\tlet rowHeight = 0\r\n\t\t\tlet columnIndex = 0\r\n\t\t\t// Not checking for `itemsCount` overflow here because `i = beforeItemsCount`\r\n\t\t\t// can only start at the start of a row, meaning that when calculating\r\n\t\t\t// \"before items height\" it's not supposed to add item heights from the\r\n\t\t\t// last row of items because in that case it would have to iterate from\r\n\t\t\t// `i === beforeItemsCount` and that condition is already checked above.\r\n\t\t\t// while (i < itemsCount) {\r\n\t\t\twhile (columnIndex < columnsCount) {\r\n\t\t\t\tlet itemHeight = beforeResize ? this.getItemHeightBeforeResize(i) : this.getItemHeight(i)\r\n\t\t\t\tif (itemHeight === undefined) {\r\n\t\t\t\t\t// `itemHeight` can only be `undefined` when not `beforeResize`.\r\n\t\t\t\t\t// Use the current \"average item height\" as a substitute.\r\n\t\t\t\t\titemHeight = this.getAverageItemHeight()\r\n\t\t\t\t}\r\n\t\t\t\trowHeight = Math.max(rowHeight, itemHeight)\r\n\t\t\t\ti++\r\n\t\t\t\tcolumnIndex++\r\n\t\t\t}\r\n\r\n\t\t\tbeforeItemsHeight += rowHeight\r\n\t\t\tbeforeItemsHeight += verticalSpacing\r\n\t\t}\r\n\r\n\t\treturn beforeItemsHeight\r\n\t}\r\n\r\n\t/**\r\n\t * Measures \"after\" items height.\r\n\t * @param {number} lastShownItemIndex — Last shown item index.\r\n\t * @param {number} itemsCount — Items count.\r\n\t * @return {number}\r\n\t */\r\n\tgetAfterItemsHeight(\r\n\t\tlastShownItemIndex,\r\n\t\titemsCount\r\n\t) {\r\n\t\t// This function could potentially also use `this.getPreviouslyCalculatedLayout()`\r\n\t\t// in order to skip calculating visible item indexes from scratch\r\n\t\t// and instead just calculate the difference from a \"previously calculated layout\".\r\n\t\t//\r\n\t\t// I did a simple test in a web browser and found out that running the following\r\n\t\t// piece of code is less than 10 milliseconds:\r\n\t\t//\r\n\t\t// var startedAt = Date.now()\r\n\t\t// var i = 0\r\n\t\t// while (i < 1000000) {\r\n\t\t// i++\r\n\t\t// }\r\n\t\t// console.log(Date.now() - startedAt)\r\n\t\t//\r\n\t\t// Which becomes negligible in my project's use case (a couple thousands items max).\r\n\r\n\t\tconst columnsCount = this.getColumnsCount()\r\n\t\tconst lastShownRowIndex = Math.floor(lastShownItemIndex / columnsCount)\r\n\r\n\t\tlet afterItemsHeight = 0\r\n\r\n\t\tlet i = lastShownItemIndex + 1\r\n\t\twhile (i < itemsCount) {\r\n\t\t\tlet rowHeight = 0\r\n\t\t\tlet columnIndex = 0\r\n\t\t\twhile (columnIndex < columnsCount && i < itemsCount) {\r\n\t\t\t\tlet itemHeight = this.getItemHeight(i)\r\n\t\t\t\tif (itemHeight === undefined) {\r\n\t\t\t\t\titemHeight = this.getAverageItemHeight()\r\n\t\t\t\t}\r\n\t\t\t\trowHeight = Math.max(rowHeight, itemHeight)\r\n\t\t\t\ti++\r\n\t\t\t\tcolumnIndex++\r\n\t\t\t}\r\n\r\n\t\t\t// Add all \"after\" items height.\r\n\t\t\tafterItemsHeight += this.getVerticalSpacing()\r\n\t\t\tafterItemsHeight += rowHeight\r\n\t\t}\r\n\r\n\t\treturn afterItemsHeight\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the items's top offset relative to the top edge of the first item.\r\n\t * @param {number} i — Item index\r\n\t * @return {[number]} Returns `undefined` if any of the previous items haven't been rendered yet.\r\n\t */\r\n\tgetItemTopOffset(i) {\r\n\t\tlet topOffsetInsideScrollableContainer = 0\r\n\r\n\t\tconst beforeResizeItemsCount = this.getBeforeResizeItemsCount()\r\n\t\tconst beforeResizeRowsCount = beforeResizeItemsCount === 0\r\n\t\t\t? 0\r\n\t\t\t: Math.ceil(beforeResizeItemsCount / this.getColumnsCountBeforeResize())\r\n\r\n\t\tconst maxBeforeResizeRowsCount = i < beforeResizeItemsCount\r\n\t\t\t? Math.floor(i / this.getColumnsCountBeforeResize())\r\n\t\t\t: beforeResizeRowsCount\r\n\r\n\t\tlet beforeResizeRowIndex = 0\r\n\t\twhile (beforeResizeRowIndex < maxBeforeResizeRowsCount) {\r\n\t\t\tconst rowHeight = this.getItemHeightBeforeResize(\r\n\t\t\t\tbeforeResizeRowIndex * this.getColumnsCountBeforeResize()\r\n\t\t\t)\r\n\r\n\t\t\ttopOffsetInsideScrollableContainer += rowHeight\r\n\t\t\ttopOffsetInsideScrollableContainer += this.getVerticalSpacingBeforeResize()\r\n\r\n\t\t\tbeforeResizeRowIndex++\r\n\t\t}\r\n\r\n\t\tconst itemRowIndex = Math.floor((i - beforeResizeItemsCount) / this.getColumnsCount())\r\n\r\n\t\tlet rowIndex = 0\r\n\t\twhile (rowIndex < itemRowIndex) {\r\n\t\t\tlet rowHeight = 0\r\n\t\t\tlet columnIndex = 0\r\n\t\t\twhile (columnIndex < this.getColumnsCount()) {\r\n\t\t\t\tconst itemHeight = this.getItemHeight(\r\n\t\t\t\t\tbeforeResizeItemsCount + rowIndex * this.getColumnsCount() + columnIndex\r\n\t\t\t\t)\r\n\t\t\t\tif (itemHeight === undefined) {\r\n\t\t\t\t\treturn\r\n\t\t\t\t}\r\n\t\t\t\trowHeight = Math.max(rowHeight, itemHeight)\r\n\t\t\t\tcolumnIndex++\r\n\t\t\t}\r\n\r\n\t\t\ttopOffsetInsideScrollableContainer += rowHeight\r\n\t\t\ttopOffsetInsideScrollableContainer += this.getVerticalSpacing()\r\n\r\n\t\t\trowIndex++\r\n\t\t}\r\n\r\n\t\treturn topOffsetInsideScrollableContainer\r\n\t}\r\n}\r\n\r\nexport const LAYOUT_REASON = {\r\n\tSCROLL: 'scroll',\r\n\tSTOPPED_SCROLLING: 'stopped scrolling',\r\n\tMANUAL: 'manual',\r\n\tSTARTED: 'started',\r\n\tNON_MEASURED_ITEMS_HAVE_BEEN_MEASURED: 'non-measured item heights have been measured',\r\n\tVIEWPORT_WIDTH_CHANGED: 'viewport width changed',\r\n\tVIEWPORT_HEIGHT_CHANGED: 'viewport height changed',\r\n\tVIEWPORT_SIZE_UNCHANGED: 'viewport size unchanged',\r\n\tITEM_HEIGHT_CHANGED: 'item height changed',\r\n\tITEMS_CHANGED: 'items changed',\r\n\tTOP_OFFSET_CHANGED: 'list top offset changed'\r\n}"],"mappings":"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"}
|
package/commonjs/Scroll.js
CHANGED
|
@@ -139,7 +139,8 @@ var Scroll = /*#__PURE__*/function () {
|
|
|
139
139
|
key: "start",
|
|
140
140
|
value: function start() {
|
|
141
141
|
if (this.initialScrollPosition !== undefined) {
|
|
142
|
-
this.scrollToY(this.initialScrollPosition);
|
|
142
|
+
this.scrollToY(this.initialScrollPosition); // Don't restore this scroll position on restart.
|
|
143
|
+
|
|
143
144
|
this.initialScrollPosition = undefined;
|
|
144
145
|
}
|
|
145
146
|
|
package/commonjs/Scroll.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Scroll.js","names":["Scroll","bypass","scrollableContainer","itemsContainer","onScroll","initialScrollPosition","onScrollPositionChange","isImmediateLayoutScheduled","hasNonRenderedItemsAtTheTop","hasNonRenderedItemsAtTheBottom","getLatestLayoutVisibleArea","getListTopOffset","getPrerenderMargin","onScrolledToTop","waitForScrollingToStop","scrollByY","scrollToY","getScrollY","ignoreScrollEvents","cancelOnStopScrollingTimer","forceUpdate","top","getHeight","bottom","log","shouldCallOnScrollListenerWhenStopsScrolling","watchOnStopScrolling","undefined","stopListeningToScroll","onScrollListener","scrollY","onStopScrollingTimer","clearTimeout","setTimeout","delayed","ON_STOP_SCROLLING_INACTIVE_PERIOD"],"sources":["../source/Scroll.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\nimport log from './utility/debug.js'\r\n\r\nexport default class Scroll {\r\n\tconstructor({\r\n\t\tbypass,\r\n\t\tscrollableContainer,\r\n\t\titemsContainer,\r\n\t\tonScroll,\r\n\t\tinitialScrollPosition,\r\n\t\tonScrollPositionChange,\r\n\t\tisImmediateLayoutScheduled,\r\n\t\thasNonRenderedItemsAtTheTop,\r\n\t\thasNonRenderedItemsAtTheBottom,\r\n\t\tgetLatestLayoutVisibleArea,\r\n\t\tgetListTopOffset,\r\n\t\tgetPrerenderMargin,\r\n\t\tonScrolledToTop,\r\n\t\twaitForScrollingToStop\r\n\t}) {\r\n\t\tthis.bypass = bypass\r\n\t\tthis.scrollableContainer = scrollableContainer\r\n\t\tthis.itemsContainer = itemsContainer\r\n\t\tthis.onScroll = onScroll\r\n\t\tthis.initialScrollPosition = initialScrollPosition\r\n\t\tthis.onScrollPositionChange = onScrollPositionChange\r\n\t\tthis.isImmediateLayoutScheduled = isImmediateLayoutScheduled\r\n\t\tthis.hasNonRenderedItemsAtTheTop = hasNonRenderedItemsAtTheTop\r\n\t\tthis.hasNonRenderedItemsAtTheBottom = hasNonRenderedItemsAtTheBottom\r\n\t\tthis.getLatestLayoutVisibleArea = getLatestLayoutVisibleArea\r\n\t\tthis.getListTopOffset = getListTopOffset\r\n\t\tthis.getPrerenderMargin = getPrerenderMargin\r\n\t\tthis.onScrolledToTop = onScrolledToTop\r\n\t\tthis.waitForScrollingToStop = waitForScrollingToStop\r\n\t}\r\n\r\n\tstart() {\r\n\t\tif (this.initialScrollPosition !== undefined) {\r\n\t\t\tthis.scrollToY(this.initialScrollPosition)\r\n\t\t\tthis.initialScrollPosition = undefined\r\n\t\t}\r\n\t\tif (this.onScrollPositionChange) {\r\n\t\t\tthis.onScrollPositionChange(this.getScrollY())\r\n\t\t}\r\n\t\tthis.stopListeningToScroll = this.scrollableContainer.onScroll(this.onScrollListener)\r\n\t}\r\n\r\n\tstop() {\r\n\t\tthis.stopListeningToScroll()\r\n\t\tthis.stopListeningToScroll = undefined\r\n\t\t// this.onStopScrollingListener = undefined\r\n\t\tthis.shouldCallOnScrollListenerWhenStopsScrolling = undefined\r\n\t\tthis.cancelOnStopScrollingTimer()\r\n\t}\r\n\r\n\tscrollToY(scrollY) {\r\n\t\tthis.ignoreScrollEvents = true\r\n\t\tthis.scrollableContainer.scrollToY(scrollY)\r\n\t\tthis.ignoreScrollEvents = undefined\r\n\t}\r\n\r\n\tscrollByY = (scrollByY) => {\r\n\t\tthis.scrollToY(this.getScrollY() + scrollByY)\r\n\t}\r\n\r\n\tgetScrollY() {\r\n\t\treturn this.scrollableContainer.getScrollY()\r\n\t}\r\n\r\n\tcancelOnStopScrollingTimer() {\r\n\t\tif (this.onStopScrollingTimer) {\r\n\t\t\tclearTimeout(this.onStopScrollingTimer)\r\n\t\t\tthis.onStopScrollingTimer = undefined\r\n\t\t}\r\n\t}\r\n\r\n\tcancelScheduledLayout() {\r\n\t\t// Cancel a \"re-layout when user stops scrolling\" timer.\r\n\t\tthis.cancelOnStopScrollingTimer()\r\n\t}\r\n\r\n\tonScrollListener = () => {\r\n\t\tif (this.onScrollPositionChange) {\r\n\t\t\tthis.onScrollPositionChange(this.getScrollY())\r\n\t\t}\r\n\r\n\t\t// If the user has scrolled up to the top of the items container.\r\n\t\t// (this option isn't currently used)\r\n\t\tif (this.onScrolledToTop) {\r\n\t\t\tif (this.getScrollY() < this.getListTopOffset()) {\r\n\t\t\t\tthis.onScrolledToTop()\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (this.bypass) {\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\tif (this.ignoreScrollEvents) {\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\t// Prefer not performing a re-layout while the user is scrolling (if possible).\r\n\t\t// If the user doesn't scroll too far and then stops for a moment,\r\n\t\t// then a mid-scroll re-layout could be delayed until such a brief stop:\r\n\t\t// presumably, this results in better (smoother) scrolling performance,\r\n\t\t// delaying the work to when it doesn't introduce any stutter or \"jank\".\r\n\r\n\t\t// Reset `this.onStopScrollingTimer` (will be re-created below).\r\n\t\tthis.cancelOnStopScrollingTimer()\r\n\r\n\t\t// See if the latest \"layout\" (the currently rendered set of items)\r\n\t\t// is still sufficient in order to show all the items that're\r\n\t\t// currently inside the viewport. If there're some non-rendered items\r\n\t\t// that're visible in the current viewport, then those items\r\n\t\t// should be rendered \"immediately\" rather than waiting until\r\n\t\t// the user stops scrolling.\r\n\t\tconst forceUpdate =\r\n\t\t\t// If the items have been rendered at least once\r\n\t\t\tthis.getLatestLayoutVisibleArea() && (\r\n\t\t\t\t(\r\n\t\t\t\t\t// If the user has scrolled up past the \"prerender margin\"\r\n\t\t\t\t\t// and there're some non-rendered items at the top,\r\n\t\t\t\t\t// then force a re-layout.\r\n\t\t\t\t\t//\r\n\t\t\t\t\t// (during these calculations we assume that the list's top coordinate\r\n\t\t\t\t\t// hasn't changed since previous layout; even if that's not exactly true,\r\n\t\t\t\t\t// the items will be re-layout when the user stops scrolling anyway)\r\n\t\t\t\t\t//\r\n\t\t\t\t\t(this.getScrollY() < this.getLatestLayoutVisibleArea().top - this.getPrerenderMargin()) &&\r\n\t\t\t\t\tthis.hasNonRenderedItemsAtTheTop()\r\n\t\t\t\t)\r\n\t\t\t\t||\r\n\t\t\t\t(\r\n\t\t\t\t\t// If the user has scrolled down past the \"prerender margin\"\r\n\t\t\t\t\t// and there're any non-rendered items left at the end,\r\n\t\t\t\t\t// then force a re-layout.\r\n\t\t\t\t\t//\r\n\t\t\t\t\t// (during these calculations we assume that the list's top coordinate\r\n\t\t\t\t\t// hasn't changed since previous layout; even if that's not exactly true,\r\n\t\t\t\t\t// the items will be re-layout when the user stops scrolling anyway)\r\n\t\t\t\t\t//\r\n\t\t\t\t\t(this.getScrollY() + this.scrollableContainer.getHeight() > this.getLatestLayoutVisibleArea().bottom + this.getPrerenderMargin()) &&\r\n\t\t\t\t\tthis.hasNonRenderedItemsAtTheBottom()\r\n\t\t\t\t)\r\n\t\t\t)\r\n\r\n\t\tif (forceUpdate) {\r\n\t\t\tlog('The user has scrolled far enough: perform a re-layout')\r\n\t\t} else {\r\n\t\t\tlog('The user is scrolling: perform a re-layout when they stop scrolling')\r\n\t\t}\r\n\r\n\t\tif (forceUpdate || this.waitForScrollingToStop === false) {\r\n\t\t\treturn this.onScroll()\r\n\t\t}\r\n\r\n\t\t// If a re-layout is already scheduled at the next \"frame\",\r\n\t\t// don't schedule a \"re-layout when user stops scrolling\" timer.\r\n\t\tif (this.isImmediateLayoutScheduled()) {\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\tthis.shouldCallOnScrollListenerWhenStopsScrolling = true\r\n\t\tthis.watchOnStopScrolling()\r\n\t}\r\n\r\n\twatchOnStopScrolling() {\r\n\t\tthis.onStopScrollingTimer = setTimeout(\r\n\t\t\t() => {\r\n\t\t\t\tthis.onStopScrollingTimer = undefined\r\n\r\n\t\t\t\tif (this.shouldCallOnScrollListenerWhenStopsScrolling) {\r\n\t\t\t\t\tthis.shouldCallOnScrollListenerWhenStopsScrolling = undefined\r\n\t\t\t\t\tthis.onScroll({ delayed: true })\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// `onStopScrolling()` feature is not currently used.\r\n\t\t\t\t// if (this.onStopScrollingListener) {\r\n\t\t\t\t// \tconst onStopScrollingListener = this.onStopScrollingListener\r\n\t\t\t\t// \tthis.onStopScrollingListener = undefined\r\n\t\t\t\t// \t// `onStopScrollingListener()` may hypothetically schedule\r\n\t\t\t\t// \t// another `onStopScrolling()` listener, so set\r\n\t\t\t\t// \t// `this.onStopScrollingListener` to `undefined` before\r\n\t\t\t\t// \t// calling it rather than after.\r\n\t\t\t\t// \tlog('~ The user has stopped scrolling ~')\r\n\t\t\t\t// \tonStopScrollingListener()\r\n\t\t\t\t// }\r\n\t\t\t},\r\n\t\t\t// \"scroll\" events are usually dispatched every 16 milliseconds\r\n\t\t\t// for 60fps refresh rate, so waiting for 100 milliseconds feels\r\n\t\t\t// reasonable: that would be about 6 frames of inactivity period,\r\n\t\t\t// which could mean that either the user has stopped scrolling\r\n\t\t\t// (for a moment) or the browser is lagging and stuttering\r\n\t\t\t// (skipping frames due to high load).\r\n\t\t\t// If the user continues scrolling then this timeout is constantly\r\n\t\t\t// refreshed (cancelled and then re-created).\r\n\t\t\tON_STOP_SCROLLING_INACTIVE_PERIOD\r\n\t\t)\r\n\t}\r\n\r\n\t// (this function isn't currently used)\r\n\t// onStopScrolling(onStopScrollingListener) {\r\n\t// \tthis.onStopScrollingListener = onStopScrollingListener\r\n\t// \tif (!this.onStopScrollingTimer) {\r\n\t// \t\tthis.watchOnStopScrolling()\r\n\t// \t}\r\n\t// }\r\n\r\n\t/**\r\n\t * Returns visible area coordinates relative to the scrollable container.\r\n\t * @return {object} `{ top: number, bottom: number }`\r\n\t */\r\n\tgetVisibleAreaBounds() {\r\n\t\tconst scrollY = this.getScrollY()\r\n\t\treturn {\r\n\t\t\t// The first pixel of the screen.\r\n\t\t\ttop: scrollY,\r\n\t\t\t// The pixel after the last pixel of the screen.\r\n\t\t\tbottom: scrollY + this.scrollableContainer.getHeight()\r\n\t\t}\r\n\t}\r\n}\r\n\r\nconst ON_STOP_SCROLLING_INACTIVE_PERIOD = 100"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Scroll.js","names":["Scroll","bypass","scrollableContainer","itemsContainer","onScroll","initialScrollPosition","onScrollPositionChange","isImmediateLayoutScheduled","hasNonRenderedItemsAtTheTop","hasNonRenderedItemsAtTheBottom","getLatestLayoutVisibleArea","getListTopOffset","getPrerenderMargin","onScrolledToTop","waitForScrollingToStop","scrollByY","scrollToY","getScrollY","ignoreScrollEvents","cancelOnStopScrollingTimer","forceUpdate","top","getHeight","bottom","log","shouldCallOnScrollListenerWhenStopsScrolling","watchOnStopScrolling","undefined","stopListeningToScroll","onScrollListener","scrollY","onStopScrollingTimer","clearTimeout","setTimeout","delayed","ON_STOP_SCROLLING_INACTIVE_PERIOD"],"sources":["../source/Scroll.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\nimport log from './utility/debug.js'\r\n\r\nexport default class Scroll {\r\n\tconstructor({\r\n\t\tbypass,\r\n\t\tscrollableContainer,\r\n\t\titemsContainer,\r\n\t\tonScroll,\r\n\t\tinitialScrollPosition,\r\n\t\tonScrollPositionChange,\r\n\t\tisImmediateLayoutScheduled,\r\n\t\thasNonRenderedItemsAtTheTop,\r\n\t\thasNonRenderedItemsAtTheBottom,\r\n\t\tgetLatestLayoutVisibleArea,\r\n\t\tgetListTopOffset,\r\n\t\tgetPrerenderMargin,\r\n\t\tonScrolledToTop,\r\n\t\twaitForScrollingToStop\r\n\t}) {\r\n\t\tthis.bypass = bypass\r\n\t\tthis.scrollableContainer = scrollableContainer\r\n\t\tthis.itemsContainer = itemsContainer\r\n\t\tthis.onScroll = onScroll\r\n\t\tthis.initialScrollPosition = initialScrollPosition\r\n\t\tthis.onScrollPositionChange = onScrollPositionChange\r\n\t\tthis.isImmediateLayoutScheduled = isImmediateLayoutScheduled\r\n\t\tthis.hasNonRenderedItemsAtTheTop = hasNonRenderedItemsAtTheTop\r\n\t\tthis.hasNonRenderedItemsAtTheBottom = hasNonRenderedItemsAtTheBottom\r\n\t\tthis.getLatestLayoutVisibleArea = getLatestLayoutVisibleArea\r\n\t\tthis.getListTopOffset = getListTopOffset\r\n\t\tthis.getPrerenderMargin = getPrerenderMargin\r\n\t\tthis.onScrolledToTop = onScrolledToTop\r\n\t\tthis.waitForScrollingToStop = waitForScrollingToStop\r\n\t}\r\n\r\n\tstart() {\r\n\t\tif (this.initialScrollPosition !== undefined) {\r\n\t\t\tthis.scrollToY(this.initialScrollPosition)\r\n\t\t\t// Don't restore this scroll position on restart.\r\n\t\t\tthis.initialScrollPosition = undefined\r\n\t\t}\r\n\t\tif (this.onScrollPositionChange) {\r\n\t\t\tthis.onScrollPositionChange(this.getScrollY())\r\n\t\t}\r\n\t\tthis.stopListeningToScroll = this.scrollableContainer.onScroll(this.onScrollListener)\r\n\t}\r\n\r\n\tstop() {\r\n\t\tthis.stopListeningToScroll()\r\n\t\tthis.stopListeningToScroll = undefined\r\n\t\t// this.onStopScrollingListener = undefined\r\n\t\tthis.shouldCallOnScrollListenerWhenStopsScrolling = undefined\r\n\t\tthis.cancelOnStopScrollingTimer()\r\n\t}\r\n\r\n\tscrollToY(scrollY) {\r\n\t\tthis.ignoreScrollEvents = true\r\n\t\tthis.scrollableContainer.scrollToY(scrollY)\r\n\t\tthis.ignoreScrollEvents = undefined\r\n\t}\r\n\r\n\tscrollByY = (scrollByY) => {\r\n\t\tthis.scrollToY(this.getScrollY() + scrollByY)\r\n\t}\r\n\r\n\tgetScrollY() {\r\n\t\treturn this.scrollableContainer.getScrollY()\r\n\t}\r\n\r\n\tcancelOnStopScrollingTimer() {\r\n\t\tif (this.onStopScrollingTimer) {\r\n\t\t\tclearTimeout(this.onStopScrollingTimer)\r\n\t\t\tthis.onStopScrollingTimer = undefined\r\n\t\t}\r\n\t}\r\n\r\n\tcancelScheduledLayout() {\r\n\t\t// Cancel a \"re-layout when user stops scrolling\" timer.\r\n\t\tthis.cancelOnStopScrollingTimer()\r\n\t}\r\n\r\n\tonScrollListener = () => {\r\n\t\tif (this.onScrollPositionChange) {\r\n\t\t\tthis.onScrollPositionChange(this.getScrollY())\r\n\t\t}\r\n\r\n\t\t// If the user has scrolled up to the top of the items container.\r\n\t\t// (this option isn't currently used)\r\n\t\tif (this.onScrolledToTop) {\r\n\t\t\tif (this.getScrollY() < this.getListTopOffset()) {\r\n\t\t\t\tthis.onScrolledToTop()\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (this.bypass) {\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\tif (this.ignoreScrollEvents) {\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\t// Prefer not performing a re-layout while the user is scrolling (if possible).\r\n\t\t// If the user doesn't scroll too far and then stops for a moment,\r\n\t\t// then a mid-scroll re-layout could be delayed until such a brief stop:\r\n\t\t// presumably, this results in better (smoother) scrolling performance,\r\n\t\t// delaying the work to when it doesn't introduce any stutter or \"jank\".\r\n\r\n\t\t// Reset `this.onStopScrollingTimer` (will be re-created below).\r\n\t\tthis.cancelOnStopScrollingTimer()\r\n\r\n\t\t// See if the latest \"layout\" (the currently rendered set of items)\r\n\t\t// is still sufficient in order to show all the items that're\r\n\t\t// currently inside the viewport. If there're some non-rendered items\r\n\t\t// that're visible in the current viewport, then those items\r\n\t\t// should be rendered \"immediately\" rather than waiting until\r\n\t\t// the user stops scrolling.\r\n\t\tconst forceUpdate =\r\n\t\t\t// If the items have been rendered at least once\r\n\t\t\tthis.getLatestLayoutVisibleArea() && (\r\n\t\t\t\t(\r\n\t\t\t\t\t// If the user has scrolled up past the \"prerender margin\"\r\n\t\t\t\t\t// and there're some non-rendered items at the top,\r\n\t\t\t\t\t// then force a re-layout.\r\n\t\t\t\t\t//\r\n\t\t\t\t\t// (during these calculations we assume that the list's top coordinate\r\n\t\t\t\t\t// hasn't changed since previous layout; even if that's not exactly true,\r\n\t\t\t\t\t// the items will be re-layout when the user stops scrolling anyway)\r\n\t\t\t\t\t//\r\n\t\t\t\t\t(this.getScrollY() < this.getLatestLayoutVisibleArea().top - this.getPrerenderMargin()) &&\r\n\t\t\t\t\tthis.hasNonRenderedItemsAtTheTop()\r\n\t\t\t\t)\r\n\t\t\t\t||\r\n\t\t\t\t(\r\n\t\t\t\t\t// If the user has scrolled down past the \"prerender margin\"\r\n\t\t\t\t\t// and there're any non-rendered items left at the end,\r\n\t\t\t\t\t// then force a re-layout.\r\n\t\t\t\t\t//\r\n\t\t\t\t\t// (during these calculations we assume that the list's top coordinate\r\n\t\t\t\t\t// hasn't changed since previous layout; even if that's not exactly true,\r\n\t\t\t\t\t// the items will be re-layout when the user stops scrolling anyway)\r\n\t\t\t\t\t//\r\n\t\t\t\t\t(this.getScrollY() + this.scrollableContainer.getHeight() > this.getLatestLayoutVisibleArea().bottom + this.getPrerenderMargin()) &&\r\n\t\t\t\t\tthis.hasNonRenderedItemsAtTheBottom()\r\n\t\t\t\t)\r\n\t\t\t)\r\n\r\n\t\tif (forceUpdate) {\r\n\t\t\tlog('The user has scrolled far enough: perform a re-layout')\r\n\t\t} else {\r\n\t\t\tlog('The user is scrolling: perform a re-layout when they stop scrolling')\r\n\t\t}\r\n\r\n\t\tif (forceUpdate || this.waitForScrollingToStop === false) {\r\n\t\t\treturn this.onScroll()\r\n\t\t}\r\n\r\n\t\t// If a re-layout is already scheduled at the next \"frame\",\r\n\t\t// don't schedule a \"re-layout when user stops scrolling\" timer.\r\n\t\tif (this.isImmediateLayoutScheduled()) {\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\tthis.shouldCallOnScrollListenerWhenStopsScrolling = true\r\n\t\tthis.watchOnStopScrolling()\r\n\t}\r\n\r\n\twatchOnStopScrolling() {\r\n\t\tthis.onStopScrollingTimer = setTimeout(\r\n\t\t\t() => {\r\n\t\t\t\tthis.onStopScrollingTimer = undefined\r\n\r\n\t\t\t\tif (this.shouldCallOnScrollListenerWhenStopsScrolling) {\r\n\t\t\t\t\tthis.shouldCallOnScrollListenerWhenStopsScrolling = undefined\r\n\t\t\t\t\tthis.onScroll({ delayed: true })\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// `onStopScrolling()` feature is not currently used.\r\n\t\t\t\t// if (this.onStopScrollingListener) {\r\n\t\t\t\t// \tconst onStopScrollingListener = this.onStopScrollingListener\r\n\t\t\t\t// \tthis.onStopScrollingListener = undefined\r\n\t\t\t\t// \t// `onStopScrollingListener()` may hypothetically schedule\r\n\t\t\t\t// \t// another `onStopScrolling()` listener, so set\r\n\t\t\t\t// \t// `this.onStopScrollingListener` to `undefined` before\r\n\t\t\t\t// \t// calling it rather than after.\r\n\t\t\t\t// \tlog('~ The user has stopped scrolling ~')\r\n\t\t\t\t// \tonStopScrollingListener()\r\n\t\t\t\t// }\r\n\t\t\t},\r\n\t\t\t// \"scroll\" events are usually dispatched every 16 milliseconds\r\n\t\t\t// for 60fps refresh rate, so waiting for 100 milliseconds feels\r\n\t\t\t// reasonable: that would be about 6 frames of inactivity period,\r\n\t\t\t// which could mean that either the user has stopped scrolling\r\n\t\t\t// (for a moment) or the browser is lagging and stuttering\r\n\t\t\t// (skipping frames due to high load).\r\n\t\t\t// If the user continues scrolling then this timeout is constantly\r\n\t\t\t// refreshed (cancelled and then re-created).\r\n\t\t\tON_STOP_SCROLLING_INACTIVE_PERIOD\r\n\t\t)\r\n\t}\r\n\r\n\t// (this function isn't currently used)\r\n\t// onStopScrolling(onStopScrollingListener) {\r\n\t// \tthis.onStopScrollingListener = onStopScrollingListener\r\n\t// \tif (!this.onStopScrollingTimer) {\r\n\t// \t\tthis.watchOnStopScrolling()\r\n\t// \t}\r\n\t// }\r\n\r\n\t/**\r\n\t * Returns visible area coordinates relative to the scrollable container.\r\n\t * @return {object} `{ top: number, bottom: number }`\r\n\t */\r\n\tgetVisibleAreaBounds() {\r\n\t\tconst scrollY = this.getScrollY()\r\n\t\treturn {\r\n\t\t\t// The first pixel of the screen.\r\n\t\t\ttop: scrollY,\r\n\t\t\t// The pixel after the last pixel of the screen.\r\n\t\t\tbottom: scrollY + this.scrollableContainer.getHeight()\r\n\t\t}\r\n\t}\r\n}\r\n\r\nconst ON_STOP_SCROLLING_INACTIVE_PERIOD = 100"],"mappings":"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"}
|
|
@@ -114,7 +114,12 @@ var VirtualScroller = /*#__PURE__*/function () {
|
|
|
114
114
|
}
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
-
|
|
117
|
+
if (isRestart) {
|
|
118
|
+
(0, _debug["default"])('~ Start (restart) ~');
|
|
119
|
+
} else {
|
|
120
|
+
(0, _debug["default"])('~ Start ~');
|
|
121
|
+
} // `this._isActive = true` should be placed somewhere at the start of this function.
|
|
122
|
+
|
|
118
123
|
|
|
119
124
|
this._isActive = true; // Reset `ListHeightMeasurement` just in case it has some "leftover" state.
|
|
120
125
|
|
|
@@ -129,20 +134,15 @@ var VirtualScroller = /*#__PURE__*/function () {
|
|
|
129
134
|
if (!(0, _tbody.hasTbodyStyles)(this.getItemsContainerElement())) {
|
|
130
135
|
(0, _tbody.addTbodyStyles)(this.getItemsContainerElement());
|
|
131
136
|
}
|
|
132
|
-
} // If there was a pending state update that didn't get applied
|
|
133
|
-
// because
|
|
134
|
-
//
|
|
135
|
-
//
|
|
136
|
-
//
|
|
137
|
-
// * `scrollableContainerWidth`
|
|
138
|
-
// * `verticalSpacing`
|
|
139
|
-
// * `beforeResize`
|
|
140
|
-
// All of those get rewritten in `onResize()` anyway.
|
|
141
|
-
//
|
|
137
|
+
} // If there was a pending "after render" state update that didn't get applied
|
|
138
|
+
// because the `VirtualScroller` got stopped, then apply that pending "after render"
|
|
139
|
+
// state update now. Such state update could include properties like:
|
|
140
|
+
// * A `verticalSpacing` that has been measured in `onRender()`.
|
|
141
|
+
// * A cleaned-up `beforeResize` object that was cleaned-up in `onRender()`.
|
|
142
142
|
|
|
143
143
|
|
|
144
|
-
var stateUpdate = this.
|
|
145
|
-
this.
|
|
144
|
+
var stateUpdate = this._afterRenderStateUpdateThatWasStopped;
|
|
145
|
+
this._afterRenderStateUpdateThatWasStopped = undefined; // Reset `this.verticalSpacing` so that it re-measures it in cases when
|
|
146
146
|
// the `VirtualScroller` was previously stopped and is now being restarted.
|
|
147
147
|
// The rationale is that a previously captured inter-item vertical spacing
|
|
148
148
|
// can't be "trusted" in a sense that the user might have resized the window
|
|
@@ -176,12 +176,10 @@ var VirtualScroller = /*#__PURE__*/function () {
|
|
|
176
176
|
var prevWidth = this.getState().scrollableContainerWidth;
|
|
177
177
|
|
|
178
178
|
if (newWidth !== prevWidth) {
|
|
179
|
-
(0, _debug["default"])('~ Scrollable container width changed from', prevWidth, 'to', newWidth, '~'); //
|
|
180
|
-
//
|
|
181
|
-
//
|
|
182
|
-
//
|
|
183
|
-
// * `beforeResize`
|
|
184
|
-
// All of those get rewritten in `onResize()` anyway.
|
|
179
|
+
(0, _debug["default"])('~ Scrollable container width changed from', prevWidth, 'to', newWidth, '~'); // The pending state update (if present) won't be applied in this case.
|
|
180
|
+
// That's ok because such state update could currently only originate in
|
|
181
|
+
// `this.onResize()` function. Therefore, alling `this.onResize()` again
|
|
182
|
+
// would rewrite all those `stateUpdate` properties anyway, so they're not passed.
|
|
185
183
|
|
|
186
184
|
return this.onResize();
|
|
187
185
|
}
|
|
@@ -255,8 +253,9 @@ var VirtualScroller = /*#__PURE__*/function () {
|
|
|
255
253
|
}, {
|
|
256
254
|
key: "onItemHeightDidChange",
|
|
257
255
|
value: function onItemHeightDidChange(i) {
|
|
258
|
-
|
|
259
|
-
|
|
256
|
+
// See the comments in the `setItemState()` function below for the rationale
|
|
257
|
+
// on why the `hasToBeStarted()` check was commented out.
|
|
258
|
+
// this.hasToBeStarted()
|
|
260
259
|
this._onItemHeightDidChange(i);
|
|
261
260
|
}
|
|
262
261
|
/**
|
|
@@ -268,8 +267,48 @@ var VirtualScroller = /*#__PURE__*/function () {
|
|
|
268
267
|
}, {
|
|
269
268
|
key: "setItemState",
|
|
270
269
|
value: function setItemState(i, newItemState) {
|
|
271
|
-
|
|
272
|
-
|
|
270
|
+
// There is an issue in React 18.2.0 when `useInsertionEffect()` doesn't run twice
|
|
271
|
+
// on mount unlike `useLayoutEffect()` in "strict" mode. That causes a bug in a React
|
|
272
|
+
// implementation of the `virtual-scroller`.
|
|
273
|
+
// https://gitlab.com/catamphetamine/virtual-scroller/-/issues/33
|
|
274
|
+
// https://github.com/facebook/react/issues/26320
|
|
275
|
+
// A workaround for that bug is ignoring the second-initial run of the effects at mount.
|
|
276
|
+
//
|
|
277
|
+
// But in that case, if an `ItemComponent` calls `setItemState()` in `useLayoutEffect()`,
|
|
278
|
+
// it could result in a bug.
|
|
279
|
+
//
|
|
280
|
+
// Consider a type of `useLayoutEffect()` that skips the initial mount:
|
|
281
|
+
// `useLayoutEffectSkipInitialMount()`.
|
|
282
|
+
// Suppose that effect is written in such a way that it only skips the first call of itself.
|
|
283
|
+
// In that case, if React is run in "strict" mode, the effect will no longer work as expected
|
|
284
|
+
// and it won't actually skip the initial mount and will be executed during the second initial run.
|
|
285
|
+
// But the `VirtualScroller` itself has already implemented a workaround that prevents
|
|
286
|
+
// its hooks from running twice on mount. This means that `useVirtualScrollerStartStop()`
|
|
287
|
+
// of the React component would have already stopped the `VirtualScroller` by the time
|
|
288
|
+
// `ItemComponent`'s incorrectly-behaving `useLayoutEffectSkipInitialMount()` effect is run,
|
|
289
|
+
// resulting in an error: "`VirtualScroller` hasn't been started".
|
|
290
|
+
//
|
|
291
|
+
// The log when not in "strict" mode would be:
|
|
292
|
+
//
|
|
293
|
+
// * `useLayoutEffect()` is run in `ItemComponent` — skips the initial run.
|
|
294
|
+
// * `useLayoutEffect()` is run in `useVirtualScrollerStartStop()`. It starts the `VirtualScroller`.
|
|
295
|
+
// * Some dependency property gets updated inside `ItemComponent`.
|
|
296
|
+
// * `useLayoutEffect()` is run in `ItemComponent` — no longer skips. Calls `setItemState()`.
|
|
297
|
+
// * The `VirtualScroller` is started so it handles `setState()` correctly.
|
|
298
|
+
//
|
|
299
|
+
// The log when in "strict" mode would be:
|
|
300
|
+
//
|
|
301
|
+
// * `useLayoutEffect()` is run in `ItemComponent` — skips the initial run.
|
|
302
|
+
// * `useLayoutEffect()` is run in `useVirtualScrollerStartStop()`. It starts the `VirtualScroller`.
|
|
303
|
+
// * `useLayoutEffect()` is unmounted in `useVirtualScrollerStartStop()`. It stops the `VirtualScroller`.
|
|
304
|
+
// * `useLayoutEffect()` is unmounted in `ItemComponent` — does nothing.
|
|
305
|
+
// * `useLayoutEffect()` is run the second time in `ItemComponent` — no longer skips. Calls `setItemState()`.
|
|
306
|
+
// * The `VirtualScroller` is stopped so it throws an error: "`VirtualScroller` hasn't been started".
|
|
307
|
+
//
|
|
308
|
+
// For that reason, the requirement of the `VirtualScroller` to be started was commented out.
|
|
309
|
+
// Commenting it out wouldn't result in any potential bugs because the code would work correctly
|
|
310
|
+
// in both cases.
|
|
311
|
+
// this.hasToBeStarted()
|
|
273
312
|
this._setItemState(i, newItemState);
|
|
274
313
|
} // (deprecated)
|
|
275
314
|
// Use `.setItemState()` method name instead.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VirtualScroller.js","names":["VirtualScroller","getItemsContainerElement","items","options","_isActive","Error","log","resize","stop","scroll","listTopOffsetWatcher","isStarted","cancelLayoutTimer","hasToBeStarted","onUpdateShownItemIndexes","reason","LAYOUT_REASON","MANUAL","_onRender","getState","previousState","VirtualScrollerConstructor","call","isRestart","waitingForRender","_usesCustomStateStorage","useDefaultStateStorage","_render","listHeightMeasurement","reset","_isResizing","undefined","_isSettingNewItems","tbody","hasTbodyStyles","addTbodyStyles","stateUpdate","_stoppedStateUpdate","verticalSpacing","verticalSpacingStateUpdate","measureItemHeightsAndSpacing","start","scrollableContainerWidth","scrollableContainer","getWidth","newWidth","prevWidth","onResize","columnsCount","getActualColumnsCount","columnsCountFromState","STARTED","i","itemTopOffsetInList","layout","getItemTopOffset","getListTopOffsetInsideScrollableContainer","warn","onItemHeightDidChange","_onItemHeightDidChange","newItemState","_setItemState","setItemState","newItems","_setItems"],"sources":["../source/VirtualScroller.js"],"sourcesContent":["import VirtualScrollerConstructor from './VirtualScroller.constructor.js'\r\nimport { hasTbodyStyles, addTbodyStyles } from './DOM/tbody.js'\r\nimport { LAYOUT_REASON } from './Layout.js'\r\nimport log, { warn } from './utility/debug.js'\r\n\r\nexport default class VirtualScroller {\r\n\t/**\r\n\t * @param {function} getItemsContainerElement — Returns the container DOM `Element`.\r\n\t * @param {any[]} items — The list of items.\r\n\t * @param {Object} [options] — See README.md.\r\n\t * @return {VirtualScroller}\r\n\t */\r\n\tconstructor(\r\n\t\tgetItemsContainerElement,\r\n\t\titems,\r\n\t\toptions = {}\r\n\t) {\r\n\t\tVirtualScrollerConstructor.call(\r\n\t\t\tthis,\r\n\t\t\tgetItemsContainerElement,\r\n\t\t\titems,\r\n\t\t\toptions\r\n\t\t)\r\n\t}\r\n\r\n\t/**\r\n\t * Should be invoked after a \"container\" DOM Element is mounted (inserted into the DOM tree).\r\n\t */\r\n\tstart() {\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\t// If has been stopped previously.\r\n\t\tconst isRestart = this._isActive === false\r\n\r\n\t\tif (!isRestart) {\r\n\t\t\tthis.waitingForRender = true\r\n\r\n\t\t\t// If no custom state storage has been configured, use the default one.\r\n\t\t\t// Also sets the initial state.\r\n\t\t\tif (!this._usesCustomStateStorage) {\r\n\t\t\t\tthis.useDefaultStateStorage()\r\n\t\t\t}\r\n\t\t\t// If `render()` function parameter was passed,\r\n\t\t\t// perform an initial render.\r\n\t\t\tif (this._render) {\r\n\t\t\t\tthis._render(this.getState())\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tlog('~ Start ~')\r\n\r\n\t\t// `this._isActive = true` should be placed somewhere at the start of this function.\r\n\t\tthis._isActive = true\r\n\r\n\t\t// Reset `ListHeightMeasurement` just in case it has some \"leftover\" state.\r\n\t\tthis.listHeightMeasurement.reset()\r\n\r\n\t\t// Reset `_isResizing` flag just in case it has some \"leftover\" value.\r\n\t\tthis._isResizing = undefined\r\n\r\n\t\t// Reset `_isSettingNewItems` flag just in case it has some \"leftover\" value.\r\n\t\tthis._isSettingNewItems = undefined\r\n\r\n\t\t// Work around `<tbody/>` not being able to have `padding`.\r\n\t\t// https://gitlab.com/catamphetamine/virtual-scroller/-/issues/1\r\n\t\tif (this.tbody) {\r\n\t\t\tif (!hasTbodyStyles(this.getItemsContainerElement())) {\r\n\t\t\t\taddTbodyStyles(this.getItemsContainerElement())\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// If there was a pending state update that didn't get applied\r\n\t\t// because of stopping the `VirtualScroller`, apply that state update now.\r\n\t\t//\r\n\t\t// The pending state update won't get applied if the scrollable container width\r\n\t\t// has changed but that's ok because that state update currently could only contain:\r\n\t\t// * `scrollableContainerWidth`\r\n\t\t// * `verticalSpacing`\r\n\t\t// * `beforeResize`\r\n\t\t// All of those get rewritten in `onResize()` anyway.\r\n\t\t//\r\n\t\tlet stateUpdate = this._stoppedStateUpdate\r\n\t\tthis._stoppedStateUpdate = undefined\r\n\r\n\t\t// Reset `this.verticalSpacing` so that it re-measures it in cases when\r\n\t\t// the `VirtualScroller` was previously stopped and is now being restarted.\r\n\t\t// The rationale is that a previously captured inter-item vertical spacing\r\n\t\t// can't be \"trusted\" in a sense that the user might have resized the window\r\n\t\t// 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 after the restart.\r\n\t\t// If it's not a restart then `this.verticalSpacing` is `undefined` anyway.\r\n\t\tthis.verticalSpacing = undefined\r\n\r\n\t\tconst verticalSpacingStateUpdate = this.measureItemHeightsAndSpacing()\r\n\t\tif (verticalSpacingStateUpdate) {\r\n\t\t\tstateUpdate = {\r\n\t\t\t\t...stateUpdate,\r\n\t\t\t\t...verticalSpacingStateUpdate\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tthis.resize.start()\r\n\t\tthis.scroll.start()\r\n\r\n\t\t// If `scrollableContainerWidth` hasn't been measured yet,\r\n\t\t// measure it and write it to state.\r\n\t\tif (this.getState().scrollableContainerWidth === undefined) {\r\n\t\t\tconst scrollableContainerWidth = this.scrollableContainer.getWidth()\r\n\t\t\tstateUpdate = {\r\n\t\t\t\t...stateUpdate,\r\n\t\t\t\tscrollableContainerWidth\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\t// Reset layout:\r\n\t\t\t// * If the scrollable container width has changed while stopped.\r\n\t\t\t// * If the restored state was calculated for another scrollable container width.\r\n\t\t\tconst newWidth = this.scrollableContainer.getWidth()\r\n\t\t\tconst prevWidth = this.getState().scrollableContainerWidth\r\n\t\t\tif (newWidth !== prevWidth) {\r\n\t\t\t\tlog('~ Scrollable container width changed from', prevWidth, 'to', newWidth, '~')\r\n\t\t\t\t// `stateUpdate` doesn't get passed to `this.onResize()`, and, therefore,\r\n\t\t\t\t// won't be applied. But that's ok because currently it could only contain:\r\n\t\t\t\t// * `scrollableContainerWidth`\r\n\t\t\t\t// * `verticalSpacing`\r\n\t\t\t\t// * `beforeResize`\r\n\t\t\t\t// All of those get rewritten in `onResize()` anyway.\r\n\t\t\t\treturn this.onResize()\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// If the `VirtualScroller` uses custom (external) state storage, then\r\n\t\t// check if the columns count has changed between calling `.getInitialState()`\r\n\t\t// and `.start()`. If it has, perform a re-layout \"from scratch\".\r\n\t\tif (this._usesCustomStateStorage) {\r\n\t\t\tconst columnsCount = this.getActualColumnsCount()\r\n\t\t\tconst columnsCountFromState = this.getState().columnsCount || 1\r\n\t\t\tif (columnsCount !== columnsCountFromState) {\r\n\t\t\t\treturn this.onResize()\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Re-calculate layout and re-render the list.\r\n\t\t// Do that even if when an initial `state` parameter, containing layout values,\r\n\t\t// has been passed. The reason is that the `state` parameter can't be \"trusted\"\r\n\t\t// in a way that it could have been snapshotted for another window width and\r\n\t\t// the user might have resized their window since then.\r\n\t\tthis.onUpdateShownItemIndexes({ reason: LAYOUT_REASON.STARTED, stateUpdate })\r\n\t}\r\n\r\n\t// Could be passed as a \"callback\" parameter, so bind it to `this`.\r\n\tstop = () => {\r\n\t\tif (!this._isActive) {\r\n\t\t\tthrow new Error('[virtual-scroller] Can\\'t stop a `VirtualScroller` that hasn\\'t been started')\r\n\t\t}\r\n\r\n\t\tthis._isActive = false\r\n\r\n\t\tlog('~ Stop ~')\r\n\r\n\t\tthis.resize.stop()\r\n\t\tthis.scroll.stop()\r\n\r\n\t\t// Stop `ListTopOffsetWatcher` if it has been started.\r\n\t\t// There seems to be no need to restart `ListTopOffsetWatcher`.\r\n\t\t// It's mainly a hacky workaround for development mode anyway.\r\n\t\tif (this.listTopOffsetWatcher && this.listTopOffsetWatcher.isStarted()) {\r\n\t\t\tthis.listTopOffsetWatcher.stop()\r\n\t\t}\r\n\r\n\t\t// Cancel any scheduled layout.\r\n\t\tthis.cancelLayoutTimer({})\r\n\t}\r\n\r\n\thasToBeStarted() {\r\n\t\tif (!this._isActive) {\r\n\t\t\tthrow new Error('[virtual-scroller] `VirtualScroller` hasn\\'t been started')\r\n\t\t}\r\n\t}\r\n\r\n\t// Bind it to `this` because this function could hypothetically be passed\r\n\t// as a \"callback\" parameter.\r\n\tupdateLayout = () => {\r\n\t\tthis.hasToBeStarted()\r\n\t\tthis.onUpdateShownItemIndexes({ reason: LAYOUT_REASON.MANUAL })\r\n\t}\r\n\r\n\t// Bind the function to `this` so that it could be passed as a callback\r\n\t// in a random application's code.\r\n\tonRender = () => {\r\n\t\tthis._onRender(this.getState(), this.previousState)\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the items's top offset relative to the scrollable container's top edge.\r\n\t * @param {number} i — Item index\r\n\t * @return {[number]} Returns the item's scroll Y position. Returns `undefined` if any of the previous items haven't been rendered yet.\r\n\t */\r\n\tgetItemScrollPosition(i) {\r\n\t\tconst itemTopOffsetInList = this.layout.getItemTopOffset(i)\r\n\t\tif (itemTopOffsetInList === undefined) {\r\n\t\t\treturn\r\n\t\t}\r\n\t\treturn this.getListTopOffsetInsideScrollableContainer() + itemTopOffsetInList\r\n\t}\r\n\r\n\t/**\r\n\t * @deprecated\r\n\t * `.onItemHeightChange()` has been renamed to `.onItemHeightDidChange()`.\r\n\t */\r\n\tonItemHeightChange(i) {\r\n\t\twarn('`.onItemHeightChange(i)` method was renamed to `.onItemHeightDidChange(i)`')\r\n\t\tthis.onItemHeightDidChange(i)\r\n\t}\r\n\r\n\t/**\r\n\t * Forces a re-measure of an item's height.\r\n\t * @param {number} i — Item index\r\n\t */\r\n\tonItemHeightDidChange(i) {\r\n\t\tthis.hasToBeStarted()\r\n\t\tthis._onItemHeightDidChange(i)\r\n\t}\r\n\r\n\t/**\r\n\t * Updates an item's state in `state.itemStates[]`.\r\n\t * @param {number} i — Item index\r\n\t * @param {any} i — Item's new state\r\n\t */\r\n\tsetItemState(i, newItemState) {\r\n\t\tthis.hasToBeStarted()\r\n\t\tthis._setItemState(i, newItemState)\r\n\t}\r\n\r\n\t// (deprecated)\r\n\t// Use `.setItemState()` method name instead.\r\n\tonItemStateChange(i, newItemState) {\r\n\t\tthis.setItemState(i, newItemState)\r\n\t}\r\n\r\n\t/**\r\n\t * Updates `items`. For example, can prepend or append new items to the list.\r\n\t * @param {any[]} newItems\r\n\t * @param {boolean} [options.preserveScrollPositionOnPrependItems] — Set to `true` to enable \"restore scroll position after prepending items\" feature (could be useful when implementing \"Show previous items\" button).\r\n\t */\r\n\tsetItems(newItems, options = {}) {\r\n\t\tthis.hasToBeStarted()\r\n\t\treturn this._setItems(newItems, options)\r\n\t}\r\n}"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"VirtualScroller.js","names":["VirtualScroller","getItemsContainerElement","items","options","_isActive","Error","log","resize","stop","scroll","listTopOffsetWatcher","isStarted","cancelLayoutTimer","hasToBeStarted","onUpdateShownItemIndexes","reason","LAYOUT_REASON","MANUAL","_onRender","getState","previousState","VirtualScrollerConstructor","call","isRestart","waitingForRender","_usesCustomStateStorage","useDefaultStateStorage","_render","listHeightMeasurement","reset","_isResizing","undefined","_isSettingNewItems","tbody","hasTbodyStyles","addTbodyStyles","stateUpdate","_afterRenderStateUpdateThatWasStopped","verticalSpacing","verticalSpacingStateUpdate","measureItemHeightsAndSpacing","start","scrollableContainerWidth","scrollableContainer","getWidth","newWidth","prevWidth","onResize","columnsCount","getActualColumnsCount","columnsCountFromState","STARTED","i","itemTopOffsetInList","layout","getItemTopOffset","getListTopOffsetInsideScrollableContainer","warn","onItemHeightDidChange","_onItemHeightDidChange","newItemState","_setItemState","setItemState","newItems","_setItems"],"sources":["../source/VirtualScroller.js"],"sourcesContent":["import VirtualScrollerConstructor from './VirtualScroller.constructor.js'\r\nimport { hasTbodyStyles, addTbodyStyles } from './DOM/tbody.js'\r\nimport { LAYOUT_REASON } from './Layout.js'\r\nimport log, { warn } from './utility/debug.js'\r\n\r\nexport default class VirtualScroller {\r\n\t/**\r\n\t * @param {function} getItemsContainerElement — Returns the container DOM `Element`.\r\n\t * @param {any[]} items — The list of items.\r\n\t * @param {Object} [options] — See README.md.\r\n\t * @return {VirtualScroller}\r\n\t */\r\n\tconstructor(\r\n\t\tgetItemsContainerElement,\r\n\t\titems,\r\n\t\toptions = {}\r\n\t) {\r\n\t\tVirtualScrollerConstructor.call(\r\n\t\t\tthis,\r\n\t\t\tgetItemsContainerElement,\r\n\t\t\titems,\r\n\t\t\toptions\r\n\t\t)\r\n\t}\r\n\r\n\t/**\r\n\t * Should be invoked after a \"container\" DOM Element is mounted (inserted into the DOM tree).\r\n\t */\r\n\tstart() {\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\t// If has been stopped previously.\r\n\t\tconst isRestart = this._isActive === false\r\n\r\n\t\tif (!isRestart) {\r\n\t\t\tthis.waitingForRender = true\r\n\r\n\t\t\t// If no custom state storage has been configured, use the default one.\r\n\t\t\t// Also sets the initial state.\r\n\t\t\tif (!this._usesCustomStateStorage) {\r\n\t\t\t\tthis.useDefaultStateStorage()\r\n\t\t\t}\r\n\t\t\t// If `render()` function parameter was passed,\r\n\t\t\t// perform an initial render.\r\n\t\t\tif (this._render) {\r\n\t\t\t\tthis._render(this.getState())\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (isRestart) {\r\n\t\t\tlog('~ Start (restart) ~')\r\n\t\t} else {\r\n\t\t\tlog('~ Start ~')\r\n\t\t}\r\n\r\n\t\t// `this._isActive = true` should be placed somewhere at the start of this function.\r\n\t\tthis._isActive = true\r\n\r\n\t\t// Reset `ListHeightMeasurement` just in case it has some \"leftover\" state.\r\n\t\tthis.listHeightMeasurement.reset()\r\n\r\n\t\t// Reset `_isResizing` flag just in case it has some \"leftover\" value.\r\n\t\tthis._isResizing = undefined\r\n\r\n\t\t// Reset `_isSettingNewItems` flag just in case it has some \"leftover\" value.\r\n\t\tthis._isSettingNewItems = undefined\r\n\r\n\t\t// Work around `<tbody/>` not being able to have `padding`.\r\n\t\t// https://gitlab.com/catamphetamine/virtual-scroller/-/issues/1\r\n\t\tif (this.tbody) {\r\n\t\t\tif (!hasTbodyStyles(this.getItemsContainerElement())) {\r\n\t\t\t\taddTbodyStyles(this.getItemsContainerElement())\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// If there was a pending \"after render\" state update that didn't get applied\r\n\t\t// because the `VirtualScroller` got stopped, then apply that pending \"after render\"\r\n\t\t// state update now. Such state update could include properties like:\r\n\t\t// * A `verticalSpacing` that has been measured in `onRender()`.\r\n\t\t// * A cleaned-up `beforeResize` object that was cleaned-up in `onRender()`.\r\n\t\tlet stateUpdate = this._afterRenderStateUpdateThatWasStopped\r\n\t\tthis._afterRenderStateUpdateThatWasStopped = undefined\r\n\r\n\t\t// Reset `this.verticalSpacing` so that it re-measures it in cases when\r\n\t\t// the `VirtualScroller` was previously stopped and is now being restarted.\r\n\t\t// The rationale is that a previously captured inter-item vertical spacing\r\n\t\t// can't be \"trusted\" in a sense that the user might have resized the window\r\n\t\t// 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 after the restart.\r\n\t\t// If it's not a restart then `this.verticalSpacing` is `undefined` anyway.\r\n\t\tthis.verticalSpacing = undefined\r\n\r\n\t\tconst verticalSpacingStateUpdate = this.measureItemHeightsAndSpacing()\r\n\t\tif (verticalSpacingStateUpdate) {\r\n\t\t\tstateUpdate = {\r\n\t\t\t\t...stateUpdate,\r\n\t\t\t\t...verticalSpacingStateUpdate\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tthis.resize.start()\r\n\t\tthis.scroll.start()\r\n\r\n\t\t// If `scrollableContainerWidth` hasn't been measured yet,\r\n\t\t// measure it and write it to state.\r\n\t\tif (this.getState().scrollableContainerWidth === undefined) {\r\n\t\t\tconst scrollableContainerWidth = this.scrollableContainer.getWidth()\r\n\t\t\tstateUpdate = {\r\n\t\t\t\t...stateUpdate,\r\n\t\t\t\tscrollableContainerWidth\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\t// Reset layout:\r\n\t\t\t// * If the scrollable container width has changed while stopped.\r\n\t\t\t// * If the restored state was calculated for another scrollable container width.\r\n\t\t\tconst newWidth = this.scrollableContainer.getWidth()\r\n\t\t\tconst prevWidth = this.getState().scrollableContainerWidth\r\n\t\t\tif (newWidth !== prevWidth) {\r\n\t\t\t\tlog('~ Scrollable container width changed from', prevWidth, 'to', newWidth, '~')\r\n\t\t\t\t// The pending state update (if present) won't be applied in this case.\r\n\t\t\t\t// That's ok because such state update could currently only originate in\r\n\t\t\t\t// `this.onResize()` function. Therefore, alling `this.onResize()` again\r\n\t\t\t\t// would rewrite all those `stateUpdate` properties anyway, so they're not passed.\r\n\t\t\t\treturn this.onResize()\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// If the `VirtualScroller` uses custom (external) state storage, then\r\n\t\t// check if the columns count has changed between calling `.getInitialState()`\r\n\t\t// and `.start()`. If it has, perform a re-layout \"from scratch\".\r\n\t\tif (this._usesCustomStateStorage) {\r\n\t\t\tconst columnsCount = this.getActualColumnsCount()\r\n\t\t\tconst columnsCountFromState = this.getState().columnsCount || 1\r\n\t\t\tif (columnsCount !== columnsCountFromState) {\r\n\t\t\t\treturn this.onResize()\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Re-calculate layout and re-render the list.\r\n\t\t// Do that even if when an initial `state` parameter, containing layout values,\r\n\t\t// has been passed. The reason is that the `state` parameter can't be \"trusted\"\r\n\t\t// in a way that it could have been snapshotted for another window width and\r\n\t\t// the user might have resized their window since then.\r\n\t\tthis.onUpdateShownItemIndexes({ reason: LAYOUT_REASON.STARTED, stateUpdate })\r\n\t}\r\n\r\n\t// Could be passed as a \"callback\" parameter, so bind it to `this`.\r\n\tstop = () => {\r\n\t\tif (!this._isActive) {\r\n\t\t\tthrow new Error('[virtual-scroller] Can\\'t stop a `VirtualScroller` that hasn\\'t been started')\r\n\t\t}\r\n\r\n\t\tthis._isActive = false\r\n\r\n\t\tlog('~ Stop ~')\r\n\r\n\t\tthis.resize.stop()\r\n\t\tthis.scroll.stop()\r\n\r\n\t\t// Stop `ListTopOffsetWatcher` if it has been started.\r\n\t\t// There seems to be no need to restart `ListTopOffsetWatcher`.\r\n\t\t// It's mainly a hacky workaround for development mode anyway.\r\n\t\tif (this.listTopOffsetWatcher && this.listTopOffsetWatcher.isStarted()) {\r\n\t\t\tthis.listTopOffsetWatcher.stop()\r\n\t\t}\r\n\r\n\t\t// Cancel any scheduled layout.\r\n\t\tthis.cancelLayoutTimer({})\r\n\t}\r\n\r\n\thasToBeStarted() {\r\n\t\tif (!this._isActive) {\r\n\t\t\tthrow new Error('[virtual-scroller] `VirtualScroller` hasn\\'t been started')\r\n\t\t}\r\n\t}\r\n\r\n\t// Bind it to `this` because this function could hypothetically be passed\r\n\t// as a \"callback\" parameter.\r\n\tupdateLayout = () => {\r\n\t\tthis.hasToBeStarted()\r\n\t\tthis.onUpdateShownItemIndexes({ reason: LAYOUT_REASON.MANUAL })\r\n\t}\r\n\r\n\t// Bind the function to `this` so that it could be passed as a callback\r\n\t// in a random application's code.\r\n\tonRender = () => {\r\n\t\tthis._onRender(this.getState(), this.previousState)\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the items's top offset relative to the scrollable container's top edge.\r\n\t * @param {number} i — Item index\r\n\t * @return {[number]} Returns the item's scroll Y position. Returns `undefined` if any of the previous items haven't been rendered yet.\r\n\t */\r\n\tgetItemScrollPosition(i) {\r\n\t\tconst itemTopOffsetInList = this.layout.getItemTopOffset(i)\r\n\t\tif (itemTopOffsetInList === undefined) {\r\n\t\t\treturn\r\n\t\t}\r\n\t\treturn this.getListTopOffsetInsideScrollableContainer() + itemTopOffsetInList\r\n\t}\r\n\r\n\t/**\r\n\t * @deprecated\r\n\t * `.onItemHeightChange()` has been renamed to `.onItemHeightDidChange()`.\r\n\t */\r\n\tonItemHeightChange(i) {\r\n\t\twarn('`.onItemHeightChange(i)` method was renamed to `.onItemHeightDidChange(i)`')\r\n\t\tthis.onItemHeightDidChange(i)\r\n\t}\r\n\r\n\t/**\r\n\t * Forces a re-measure of an item's height.\r\n\t * @param {number} i — Item index\r\n\t */\r\n\tonItemHeightDidChange(i) {\r\n\t\t// See the comments in the `setItemState()` function below for the rationale\r\n\t\t// on why the `hasToBeStarted()` check was commented out.\r\n\t\t// this.hasToBeStarted()\r\n\t\tthis._onItemHeightDidChange(i)\r\n\t}\r\n\r\n\t/**\r\n\t * Updates an item's state in `state.itemStates[]`.\r\n\t * @param {number} i — Item index\r\n\t * @param {any} i — Item's new state\r\n\t */\r\n\tsetItemState(i, newItemState) {\r\n\t\t// There is an issue in React 18.2.0 when `useInsertionEffect()` doesn't run twice\r\n\t\t// on mount unlike `useLayoutEffect()` in \"strict\" mode. That causes a bug in a React\r\n\t\t// implementation of the `virtual-scroller`.\r\n\t\t// https://gitlab.com/catamphetamine/virtual-scroller/-/issues/33\r\n\t\t// https://github.com/facebook/react/issues/26320\r\n\t\t// A workaround for that bug is ignoring the second-initial run of the effects at mount.\r\n\t\t//\r\n\t\t// But in that case, if an `ItemComponent` calls `setItemState()` in `useLayoutEffect()`,\r\n\t\t// it could result in a bug.\r\n\t\t//\r\n\t\t// Consider a type of `useLayoutEffect()` that skips the initial mount:\r\n\t\t// `useLayoutEffectSkipInitialMount()`.\r\n\t\t// Suppose that effect is written in such a way that it only skips the first call of itself.\r\n\t\t// In that case, if React is run in \"strict\" mode, the effect will no longer work as expected\r\n\t\t// and it won't actually skip the initial mount and will be executed during the second initial run.\r\n\t\t// But the `VirtualScroller` itself has already implemented a workaround that prevents\r\n\t\t// its hooks from running twice on mount. This means that `useVirtualScrollerStartStop()`\r\n\t\t// of the React component would have already stopped the `VirtualScroller` by the time\r\n\t\t// `ItemComponent`'s incorrectly-behaving `useLayoutEffectSkipInitialMount()` effect is run,\r\n\t\t// resulting in an error: \"`VirtualScroller` hasn't been started\".\r\n\t\t//\r\n\t\t// The log when not in \"strict\" mode would be:\r\n\t\t//\r\n\t\t// * `useLayoutEffect()` is run in `ItemComponent` — skips the initial run.\r\n\t\t// * `useLayoutEffect()` is run in `useVirtualScrollerStartStop()`. It starts the `VirtualScroller`.\r\n\t\t// * Some dependency property gets updated inside `ItemComponent`.\r\n\t\t// * `useLayoutEffect()` is run in `ItemComponent` — no longer skips. Calls `setItemState()`.\r\n\t\t// * The `VirtualScroller` is started so it handles `setState()` correctly.\r\n\t\t//\r\n\t\t// The log when in \"strict\" mode would be:\r\n\t\t//\r\n\t\t// * `useLayoutEffect()` is run in `ItemComponent` — skips the initial run.\r\n\t\t// * `useLayoutEffect()` is run in `useVirtualScrollerStartStop()`. It starts the `VirtualScroller`.\r\n\t\t// * `useLayoutEffect()` is unmounted in `useVirtualScrollerStartStop()`. It stops the `VirtualScroller`.\r\n\t\t// * `useLayoutEffect()` is unmounted in `ItemComponent` — does nothing.\r\n\t\t// * `useLayoutEffect()` is run the second time in `ItemComponent` — no longer skips. Calls `setItemState()`.\r\n\t\t// * The `VirtualScroller` is stopped so it throws an error: \"`VirtualScroller` hasn't been started\".\r\n\t\t//\r\n\t\t// For that reason, the requirement of the `VirtualScroller` to be started was commented out.\r\n\t\t// Commenting it out wouldn't result in any potential bugs because the code would work correctly\r\n\t\t// in both cases.\r\n\t\t// this.hasToBeStarted()\r\n\t\tthis._setItemState(i, newItemState)\r\n\t}\r\n\r\n\t// (deprecated)\r\n\t// Use `.setItemState()` method name instead.\r\n\tonItemStateChange(i, newItemState) {\r\n\t\tthis.setItemState(i, newItemState)\r\n\t}\r\n\r\n\t/**\r\n\t * Updates `items`. For example, can prepend or append new items to the list.\r\n\t * @param {any[]} newItems\r\n\t * @param {boolean} [options.preserveScrollPositionOnPrependItems] — Set to `true` to enable \"restore scroll position after prepending items\" feature (could be useful when implementing \"Show previous items\" button).\r\n\t */\r\n\tsetItems(newItems, options = {}) {\r\n\t\tthis.hasToBeStarted()\r\n\t\treturn this._setItems(newItems, options)\r\n\t}\r\n}"],"mappings":"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"}
|
|
@@ -465,9 +465,13 @@ function _default() {
|
|
|
465
465
|
(0, _debug["default"])('New height', newHeight);
|
|
466
466
|
|
|
467
467
|
if (previousHeight !== newHeight) {
|
|
468
|
-
(0, _debug["default"])('~ Item height has changed. Should update layout. ~'); // Update or reset a previously calculated layout
|
|
469
|
-
// so that the "diff"s based on that
|
|
470
|
-
//
|
|
468
|
+
(0, _debug["default"])('~ Item height has changed. Should update layout. ~'); // Update or reset a previously calculated layout with the new item height
|
|
469
|
+
// so that the potential future "diff"s based on that "previously calculated" layout
|
|
470
|
+
// would be correct.
|
|
471
|
+
//
|
|
472
|
+
// The "previously calculated layout" feature is not currently used
|
|
473
|
+
// so this function call doesn't really affect anything.
|
|
474
|
+
//
|
|
471
475
|
|
|
472
476
|
updatePreviouslyCalculatedLayoutOnItemHeightChange.call(_this, i, previousHeight, newHeight); // Recalculate layout.
|
|
473
477
|
//
|
|
@@ -479,13 +483,15 @@ function _default() {
|
|
|
479
483
|
// being applied, resulting in weird "race condition" bugs.
|
|
480
484
|
//
|
|
481
485
|
|
|
482
|
-
if (_this.
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
486
|
+
if (_this._isActive) {
|
|
487
|
+
if (_this.waitingForRender) {
|
|
488
|
+
(0, _debug["default"])('~ Another state update is already waiting to be rendered. Delay the layout update until then. ~');
|
|
489
|
+
_this.updateLayoutAfterRenderBecauseItemHeightChanged = true;
|
|
490
|
+
} else {
|
|
491
|
+
_this.onUpdateShownItemIndexes({
|
|
492
|
+
reason: _Layout.LAYOUT_REASON.ITEM_HEIGHT_CHANGED
|
|
493
|
+
});
|
|
494
|
+
}
|
|
489
495
|
} // If there was a request for `setState()` with new `items`, then the changes
|
|
490
496
|
// to `currentState.itemHeights[]` made above in a `remeasureItemHeight()` call
|
|
491
497
|
// would be overwritten when that pending `setState()` call gets applied.
|