virtual-scroller 1.10.2 → 1.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/README.md +48 -24
- 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/DOM/VirtualScroller.js +5 -0
- package/commonjs/DOM/VirtualScroller.js.map +1 -1
- package/commonjs/ItemHeights.js +1 -1
- package/commonjs/ItemHeights.js.map +1 -1
- package/commonjs/VirtualScroller.constructor.js +3 -0
- package/commonjs/VirtualScroller.constructor.js.map +1 -1
- package/commonjs/VirtualScroller.items.js +11 -10
- package/commonjs/VirtualScroller.items.js.map +1 -1
- package/commonjs/VirtualScroller.js +10 -3
- package/commonjs/VirtualScroller.js.map +1 -1
- package/commonjs/VirtualScroller.layout.js +2 -2
- package/commonjs/VirtualScroller.layout.js.map +1 -1
- package/commonjs/VirtualScroller.state.js +23 -13
- package/commonjs/VirtualScroller.state.js.map +1 -1
- package/commonjs/react/VirtualScroller.js +26 -11
- package/commonjs/react/VirtualScroller.js.map +1 -1
- package/commonjs/react/{useOnItemStateChange.js → useSetItemState.js} +7 -7
- package/commonjs/react/useSetItemState.js.map +1 -0
- package/commonjs/react/useVirtualScroller.js +2 -1
- package/commonjs/react/useVirtualScroller.js.map +1 -1
- package/commonjs/utility/fillArray.js +18 -0
- package/commonjs/utility/fillArray.js.map +1 -0
- package/dom/index.d.ts +7 -6
- package/index.d.ts +16 -15
- package/modules/DOM/VirtualScroller.js +5 -0
- package/modules/DOM/VirtualScroller.js.map +1 -1
- package/modules/ItemHeights.js +1 -1
- package/modules/ItemHeights.js.map +1 -1
- package/modules/VirtualScroller.constructor.js +3 -0
- package/modules/VirtualScroller.constructor.js.map +1 -1
- package/modules/VirtualScroller.items.js +10 -10
- package/modules/VirtualScroller.items.js.map +1 -1
- package/modules/VirtualScroller.js +10 -3
- package/modules/VirtualScroller.js.map +1 -1
- package/modules/VirtualScroller.layout.js +2 -2
- package/modules/VirtualScroller.layout.js.map +1 -1
- package/modules/VirtualScroller.state.js +20 -11
- package/modules/VirtualScroller.state.js.map +1 -1
- package/modules/react/VirtualScroller.js +26 -11
- package/modules/react/VirtualScroller.js.map +1 -1
- package/modules/react/{useOnItemStateChange.js → useSetItemState.js} +6 -6
- package/modules/react/useSetItemState.js.map +1 -0
- package/modules/react/useVirtualScroller.js +2 -1
- package/modules/react/useVirtualScroller.js.map +1 -1
- package/modules/utility/fillArray.js +11 -0
- package/modules/utility/fillArray.js.map +1 -0
- package/package.json +1 -1
- package/react/index.d.ts +14 -8
- package/source/DOM/VirtualScroller.js +4 -0
- package/source/ItemHeights.js +1 -1
- package/source/VirtualScroller.constructor.js +2 -1
- package/source/VirtualScroller.items.js +16 -8
- package/source/VirtualScroller.js +8 -2
- package/source/VirtualScroller.layout.js +2 -2
- package/source/VirtualScroller.state.js +15 -7
- package/source/react/VirtualScroller.js +25 -10
- package/source/react/{useOnItemStateChange.js → useSetItemState.js} +5 -5
- package/source/react/useVirtualScroller.js +2 -0
- package/source/utility/fillArray.js +8 -0
- package/commonjs/react/useOnItemStateChange.js.map +0 -1
- package/modules/react/useOnItemStateChange.js.map +0 -1
|
@@ -177,6 +177,11 @@ var VirtualScroller = /*#__PURE__*/function () {
|
|
|
177
177
|
value: function onItemHeightChange(i) {
|
|
178
178
|
this.virtualScroller.onItemHeightChange(i);
|
|
179
179
|
}
|
|
180
|
+
}, {
|
|
181
|
+
key: "setItemState",
|
|
182
|
+
value: function setItemState(i, newState) {
|
|
183
|
+
this.virtualScroller.setItemState(i, newState);
|
|
184
|
+
}
|
|
180
185
|
/**
|
|
181
186
|
* @deprecated
|
|
182
187
|
* `.updateItems()` has been renamed to `.setItems()`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VirtualScroller.js","names":["VirtualScroller","itemsContainerElement","items","renderItem","options","state","prevState","firstShownItemIndex","lastShownItemIndex","beforeItemsHeight","afterItemsHeight","tbody","container","style","paddingTop","px","paddingBottom","diffRender","length","i","log","unmountItem","childNodes","firstChild","shouldPrependItems","prependBeforeItemElement","item","insertBefore","appendChild","warn","stop","virtualScroller","start","onMount","onItemUnmount","restOptions","tagName","VirtualScrollerCore","render","itemElement","removeChild","onItemHeightChange","newItems","setItems"],"sources":["../../source/DOM/VirtualScroller.js"],"sourcesContent":["import VirtualScrollerCore from '../VirtualScroller.js'\r\n\r\nimport log, { warn } from '../utility/debug.js'\r\nimport px from '../utility/px.js'\r\n\r\nexport default class VirtualScroller {\r\n constructor(itemsContainerElement, items, renderItem, options = {}) {\r\n this.container = itemsContainerElement\r\n this.renderItem = renderItem\r\n\r\n const {\r\n onMount,\r\n onItemUnmount,\r\n ...restOptions\r\n } = options\r\n\r\n this.onItemUnmount = onItemUnmount\r\n this.tbody = this.container.tagName === 'TBODY'\r\n\r\n this.virtualScroller = new VirtualScrollerCore(\r\n () => this.container,\r\n items,\r\n {\r\n ...restOptions,\r\n render: this.render,\r\n tbody: this.tbody\r\n }\r\n )\r\n\r\n this.start()\r\n\r\n // `onMount()` option is deprecated due to no longer being used.\r\n // If someone thinks there's a valid use case for it, create an issue.\r\n if (onMount) {\r\n onMount()\r\n }\r\n }\r\n\r\n render = (state, prevState) => {\r\n const {\r\n items,\r\n firstShownItemIndex,\r\n lastShownItemIndex,\r\n beforeItemsHeight,\r\n afterItemsHeight\r\n } = state\r\n\r\n // log('~ On state change ~')\r\n // log('Previous state', prevState)\r\n // log('New state', state)\r\n\r\n // Set container padding top and bottom.\r\n // Work around `<tbody/>` not being able to have `padding`.\r\n // https://gitlab.com/catamphetamine/virtual-scroller/-/issues/1\r\n // `this.virtualScroller` hasn't been initialized yet at this stage,\r\n // so using `this.tbody` instead of `this.virtualScroller.tbody`.\r\n if (!this.tbody) {\r\n this.container.style.paddingTop = px(beforeItemsHeight)\r\n this.container.style.paddingBottom = px(afterItemsHeight)\r\n }\r\n\r\n // Perform an intelligent \"diff\" re-render if the `items` are the same.\r\n const diffRender = prevState && items === prevState.items && items.length > 0\r\n // Remove no longer visible items from the DOM.\r\n if (diffRender) {\r\n // Decrement instead of increment here because\r\n // `this.container.removeChild()` changes indexes.\r\n let i = prevState.lastShownItemIndex\r\n while (i >= prevState.firstShownItemIndex) {\r\n if (i >= firstShownItemIndex && i <= lastShownItemIndex) {\r\n // The item is still visible.\r\n } else {\r\n log('DOM: Remove element for item index', i)\r\n // The item is no longer visible. Remove it.\r\n this.unmountItem(this.container.childNodes[i - prevState.firstShownItemIndex])\r\n }\r\n i--\r\n }\r\n } else {\r\n log('DOM: Rerender the list from scratch')\r\n while (this.container.firstChild) {\r\n this.unmountItem(this.container.firstChild)\r\n }\r\n }\r\n\r\n // Add newly visible items to the DOM.\r\n let shouldPrependItems = diffRender\r\n const prependBeforeItemElement = shouldPrependItems && this.container.firstChild\r\n let i = firstShownItemIndex\r\n while (i <= lastShownItemIndex) {\r\n if (diffRender && i >= prevState.firstShownItemIndex && i <= prevState.lastShownItemIndex) {\r\n // The item is already being rendered.\r\n // Next items will be appended rather than prepended.\r\n if (shouldPrependItems) {\r\n shouldPrependItems = false\r\n }\r\n } else {\r\n const item = this.renderItem(items[i])\r\n if (shouldPrependItems) {\r\n log('DOM: Prepend element for item index', i)\r\n // Append `item` to `this.container` before the retained items.\r\n this.container.insertBefore(item, prependBeforeItemElement)\r\n } else {\r\n log('DOM: Append element for item index', i)\r\n // Append `item` to `this.container`.\r\n this.container.appendChild(item)\r\n }\r\n }\r\n i++\r\n }\r\n }\r\n\r\n // Public API. Should be \"bound\" to `this`.\r\n onUnmount = () => {\r\n warn('`.onUnmount()` instance method name is deprecated, use `.stop()` instance method name instead.')\r\n this.stop()\r\n }\r\n\r\n // Public API. Should be \"bound\" to `this`.\r\n destroy = () => {\r\n warn('`.destroy()` instance method name is deprecated, use `.stop()` instance method name instead.')\r\n this.stop()\r\n }\r\n\r\n // Public API.\r\n // Should be \"bound\" to `this`.\r\n stop = () => {\r\n this.virtualScroller.stop()\r\n }\r\n\r\n // Potentially public API in some hypothetical scenario.\r\n // Should be \"bound\" to `this`.\r\n start = () => {\r\n this.virtualScroller.start()\r\n }\r\n\r\n unmountItem(itemElement) {\r\n this.container.removeChild(itemElement)\r\n if (this.onItemUnmount) {\r\n this.onItemUnmount(itemElement)\r\n }\r\n }\r\n\r\n onItemHeightChange(i) {\r\n this.virtualScroller.onItemHeightChange(i)\r\n }\r\n\r\n /**\r\n * @deprecated\r\n * `.updateItems()` has been renamed to `.setItems()`.\r\n */\r\n updateItems(newItems, options) {\r\n this.setItems(newItems, options)\r\n }\r\n\r\n setItems(newItems, options) {\r\n this.virtualScroller.setItems(newItems, options)\r\n }\r\n\r\n /*\r\n getItemCoordinates(i) {\r\n return this.virtualScroller.getItemCoordinates(i)\r\n }\r\n */\r\n}"],"mappings":"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
|
|
1
|
+
{"version":3,"file":"VirtualScroller.js","names":["VirtualScroller","itemsContainerElement","items","renderItem","options","state","prevState","firstShownItemIndex","lastShownItemIndex","beforeItemsHeight","afterItemsHeight","tbody","container","style","paddingTop","px","paddingBottom","diffRender","length","i","log","unmountItem","childNodes","firstChild","shouldPrependItems","prependBeforeItemElement","item","insertBefore","appendChild","warn","stop","virtualScroller","start","onMount","onItemUnmount","restOptions","tagName","VirtualScrollerCore","render","itemElement","removeChild","onItemHeightChange","newState","setItemState","newItems","setItems"],"sources":["../../source/DOM/VirtualScroller.js"],"sourcesContent":["import VirtualScrollerCore from '../VirtualScroller.js'\r\n\r\nimport log, { warn } from '../utility/debug.js'\r\nimport px from '../utility/px.js'\r\n\r\nexport default class VirtualScroller {\r\n constructor(itemsContainerElement, items, renderItem, options = {}) {\r\n this.container = itemsContainerElement\r\n this.renderItem = renderItem\r\n\r\n const {\r\n onMount,\r\n onItemUnmount,\r\n ...restOptions\r\n } = options\r\n\r\n this.onItemUnmount = onItemUnmount\r\n this.tbody = this.container.tagName === 'TBODY'\r\n\r\n this.virtualScroller = new VirtualScrollerCore(\r\n () => this.container,\r\n items,\r\n {\r\n ...restOptions,\r\n render: this.render,\r\n tbody: this.tbody\r\n }\r\n )\r\n\r\n this.start()\r\n\r\n // `onMount()` option is deprecated due to no longer being used.\r\n // If someone thinks there's a valid use case for it, create an issue.\r\n if (onMount) {\r\n onMount()\r\n }\r\n }\r\n\r\n render = (state, prevState) => {\r\n const {\r\n items,\r\n firstShownItemIndex,\r\n lastShownItemIndex,\r\n beforeItemsHeight,\r\n afterItemsHeight\r\n } = state\r\n\r\n // log('~ On state change ~')\r\n // log('Previous state', prevState)\r\n // log('New state', state)\r\n\r\n // Set container padding top and bottom.\r\n // Work around `<tbody/>` not being able to have `padding`.\r\n // https://gitlab.com/catamphetamine/virtual-scroller/-/issues/1\r\n // `this.virtualScroller` hasn't been initialized yet at this stage,\r\n // so using `this.tbody` instead of `this.virtualScroller.tbody`.\r\n if (!this.tbody) {\r\n this.container.style.paddingTop = px(beforeItemsHeight)\r\n this.container.style.paddingBottom = px(afterItemsHeight)\r\n }\r\n\r\n // Perform an intelligent \"diff\" re-render if the `items` are the same.\r\n const diffRender = prevState && items === prevState.items && items.length > 0\r\n // Remove no longer visible items from the DOM.\r\n if (diffRender) {\r\n // Decrement instead of increment here because\r\n // `this.container.removeChild()` changes indexes.\r\n let i = prevState.lastShownItemIndex\r\n while (i >= prevState.firstShownItemIndex) {\r\n if (i >= firstShownItemIndex && i <= lastShownItemIndex) {\r\n // The item is still visible.\r\n } else {\r\n log('DOM: Remove element for item index', i)\r\n // The item is no longer visible. Remove it.\r\n this.unmountItem(this.container.childNodes[i - prevState.firstShownItemIndex])\r\n }\r\n i--\r\n }\r\n } else {\r\n log('DOM: Rerender the list from scratch')\r\n while (this.container.firstChild) {\r\n this.unmountItem(this.container.firstChild)\r\n }\r\n }\r\n\r\n // Add newly visible items to the DOM.\r\n let shouldPrependItems = diffRender\r\n const prependBeforeItemElement = shouldPrependItems && this.container.firstChild\r\n let i = firstShownItemIndex\r\n while (i <= lastShownItemIndex) {\r\n if (diffRender && i >= prevState.firstShownItemIndex && i <= prevState.lastShownItemIndex) {\r\n // The item is already being rendered.\r\n // Next items will be appended rather than prepended.\r\n if (shouldPrependItems) {\r\n shouldPrependItems = false\r\n }\r\n } else {\r\n const item = this.renderItem(items[i])\r\n if (shouldPrependItems) {\r\n log('DOM: Prepend element for item index', i)\r\n // Append `item` to `this.container` before the retained items.\r\n this.container.insertBefore(item, prependBeforeItemElement)\r\n } else {\r\n log('DOM: Append element for item index', i)\r\n // Append `item` to `this.container`.\r\n this.container.appendChild(item)\r\n }\r\n }\r\n i++\r\n }\r\n }\r\n\r\n // Public API. Should be \"bound\" to `this`.\r\n onUnmount = () => {\r\n warn('`.onUnmount()` instance method name is deprecated, use `.stop()` instance method name instead.')\r\n this.stop()\r\n }\r\n\r\n // Public API. Should be \"bound\" to `this`.\r\n destroy = () => {\r\n warn('`.destroy()` instance method name is deprecated, use `.stop()` instance method name instead.')\r\n this.stop()\r\n }\r\n\r\n // Public API.\r\n // Should be \"bound\" to `this`.\r\n stop = () => {\r\n this.virtualScroller.stop()\r\n }\r\n\r\n // Potentially public API in some hypothetical scenario.\r\n // Should be \"bound\" to `this`.\r\n start = () => {\r\n this.virtualScroller.start()\r\n }\r\n\r\n unmountItem(itemElement) {\r\n this.container.removeChild(itemElement)\r\n if (this.onItemUnmount) {\r\n this.onItemUnmount(itemElement)\r\n }\r\n }\r\n\r\n onItemHeightChange(i) {\r\n this.virtualScroller.onItemHeightChange(i)\r\n }\r\n\r\n setItemState(i, newState) {\r\n this.virtualScroller.setItemState(i, newState)\r\n }\r\n\r\n /**\r\n * @deprecated\r\n * `.updateItems()` has been renamed to `.setItems()`.\r\n */\r\n updateItems(newItems, options) {\r\n this.setItems(newItems, options)\r\n }\r\n\r\n setItems(newItems, options) {\r\n this.virtualScroller.setItems(newItems, options)\r\n }\r\n\r\n /*\r\n getItemCoordinates(i) {\r\n return this.virtualScroller.getItemCoordinates(i)\r\n }\r\n */\r\n}"],"mappings":"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"}
|
package/commonjs/ItemHeights.js
CHANGED
|
@@ -208,7 +208,7 @@ var ItemHeights = /*#__PURE__*/function () {
|
|
|
208
208
|
var _height = this._measureItemHeight(i, firstShownItemIndex);
|
|
209
209
|
|
|
210
210
|
if (previousHeight !== _height) {
|
|
211
|
-
(0, _debug.warn)('Item index', i, 'height changed unexpectedly: it was', previousHeight, 'before, but now it is', _height, '. An item\'s height is allowed to change only in two cases: when the item\'s "state" changes and the developer calls `
|
|
211
|
+
(0, _debug.warn)('Item index', i, 'height changed unexpectedly: it was', previousHeight, 'before, but now it is', _height, '. An item\'s height is allowed to change only in two cases: when the item\'s "state" changes and the developer calls `setItemState(i, newState)`, or when the item\'s height changes for some other reason and the developer calls `onItemHeightChange(i)`. Perhaps you forgot to persist the item\'s "state" by calling `setItemState(i, newState)` when it changed, and that "state" got lost when the item element was unmounted, which resulted in a different height when the item was shown again having its "state" reset.'); // Update the item's height as an attempt to fix things.
|
|
212
212
|
|
|
213
213
|
this._set(i, _height);
|
|
214
214
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ItemHeights.js","names":["ItemHeights","container","itemHeights","getItemHeight","setItemHeight","_get","_set","reset","measuredItemsHeight","firstMeasuredItemIndex","undefined","lastMeasuredItemIndex","i","length","firstShownItemIndex","getNthRenderedItemHeight","lastShownItemIndex","log","nonPreviouslyMeasuredItemIndexes","previousFirstMeasuredItemIndex","previousLastMeasuredItemIndex","firstMeasuredItemIndexHasBeenUpdated","push","height","_measureItemHeight","previousHeight","warn","count"],"sources":["../source/ItemHeights.js"],"sourcesContent":["import log, { warn, isDebug, reportError } from './utility/debug.js'\r\n\r\nexport default class ItemHeights {\r\n\tconstructor({\r\n\t\tcontainer,\r\n\t\titemHeights,\r\n\t\tgetItemHeight,\r\n\t\tsetItemHeight\r\n\t}) {\r\n\t\tthis.container = container\r\n\t\tthis._get = getItemHeight\r\n\t\tthis._set = setItemHeight\r\n\t\tthis.reset()\r\n\t}\r\n\r\n\treset() {\r\n\t\tthis.measuredItemsHeight = 0\r\n\t\t// \"First measured item index\" variable was introduced\r\n\t\t// because it's not always `0`: when `virtualScroller.setItems()`\r\n\t\t// is called, some items might get prepended, in which case\r\n\t\t// `this.lastMeasuredItemIndex` is updated. If there was no\r\n\t\t// `this.firstMeasuredItemIndex`, then the average item height\r\n\t\t// calculated in `.getAverage()` would be incorrect in the timeframe\r\n\t\t// between `.setItems()` is called and those changes have been rendered.\r\n\t\t// And in that timeframe, `.getAverage()` is used to calculate the \"layout\":\r\n\t\t// stuff like \"before/after items height\" and \"estimated items count on screen\".\r\n\t\tthis.firstMeasuredItemIndex = undefined\r\n\t\tthis.lastMeasuredItemIndex = undefined\r\n\t}\r\n\r\n\t/**\r\n\t * Can only be called after a `.reset()` (including new instance creation).\r\n\t * Initializes `this.measuredItemsHeight`, `this.firstMeasuredItemIndex`\r\n\t * and `this.lastMeasuredItemIndex` instance variables from `VirtualScroller` `state`.\r\n\t * These instance variables are used when calculating \"average\" item height:\r\n\t * the \"average\" item height is simply `this.measuredItemsHeight` divided by\r\n\t * `this.lastMeasuredItemIndex` minus `this.firstMeasuredItemIndex` plus 1.\r\n\t */\r\n\treadItemHeightsFromState({ itemHeights }) {\r\n\t\tlet i = 0\r\n\t\twhile (i < itemHeights.length) {\r\n\t\t\tif (itemHeights[i] === undefined) {\r\n\t\t\t\tif (this.firstMeasuredItemIndex !== undefined) {\r\n\t\t\t\t\tthis.lastMeasuredItemIndex = i - 1\r\n\t\t\t\t\tbreak\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (this.firstMeasuredItemIndex === undefined) {\r\n\t\t\t\t\tthis.firstMeasuredItemIndex = i\r\n\t\t\t\t}\r\n\t\t\t\tthis.measuredItemsHeight += itemHeights[i]\r\n\t\t\t}\r\n\t\t\ti++\r\n\t\t}\r\n\t}\r\n\r\n\t// Seems to be no longer used.\r\n\t// getItemHeight(i, firstShownItemIndex) {\r\n\t// \tif (this._get(i)) {\r\n\t// \t\treturn this._get(i)\r\n\t// \t}\r\n\t// \tconst itemHeight = this._measureItemHeight(i, firstShownItemIndex)\r\n\t// \tif (itemHeight) {\r\n\t// \t\tthis._set(i, itemHeight)\r\n\t// \t\treturn itemHeight\r\n\t// \t}\r\n\t// \treturn this.getAverage()\r\n\t// }\r\n\r\n\t_measureItemHeight(i, firstShownItemIndex) {\r\n\t\treturn this.container.getNthRenderedItemHeight(i - firstShownItemIndex)\r\n\t}\r\n\r\n\t/**\r\n\t * Measures item heights:\r\n\t *\r\n\t * * For the items that haven't been previously measured,\r\n\t * measures them for the first time.\r\n\t *\r\n\t * * For the items that have been previoulsy measured,\r\n\t * validate that their previously measured height\r\n\t * is still equal to their current height.\r\n\t * The unequalness may not necessarily be caused by\r\n\t * incorrect use of `virtual-scroller`: there are\r\n\t * also some valid use cases when such unequalness\r\n\t * could happen (see the comments in the code).\r\n\t *\r\n\t * @param {number} firstShownItemIndex\r\n\t * @param {number} lastShownItemIndex\r\n\t * @return {number[]} The indexes of the items that have not previously been measured and have been measured now.\r\n\t */\r\n\tmeasureItemHeights(firstShownItemIndex, lastShownItemIndex) {\r\n\t\tlog('~ Measure item heights ~')\r\n\t\t// If no items are rendered, don't measure anything.\r\n\t\tif (firstShownItemIndex === undefined) {\r\n\t\t\treturn\r\n\t\t}\r\n\t\t// Reset `this.measuredItemsHeight` if it's not a \"continuous\" measured items list:\r\n\t\t// if a group of items has been measured previously, and now it has rendered a completely\r\n\t\t// different group of items, and there's a non-measured \"gap\" between those two groups,\r\n\t\t// then reset `this.measuredItemsHeight` and \"first measured\"/\"last measured\" item indexes.\r\n\t\t// For example, this could happen when `.setItems()` prepends a lot of new items.\r\n\t\tif (this.firstMeasuredItemIndex !== undefined) {\r\n\t\t\tif (\r\n\t\t\t\tfirstShownItemIndex > this.lastMeasuredItemIndex + 1 ||\r\n\t\t\t\tlastShownItemIndex < this.firstMeasuredItemIndex - 1\r\n\t\t\t) {\r\n\t\t\t\t// Reset.\r\n\t\t\t\tlog('Non-measured items gap detected. Reset first and last measured item indexes.')\r\n\t\t\t\tthis.reset()\r\n\t\t\t}\r\n\t\t}\r\n\t\tconst nonPreviouslyMeasuredItemIndexes = []\r\n\t\tconst previousFirstMeasuredItemIndex = this.firstMeasuredItemIndex\r\n\t\tconst previousLastMeasuredItemIndex = this.lastMeasuredItemIndex\r\n\t\tlet firstMeasuredItemIndexHasBeenUpdated = false\r\n\t\tlet i = firstShownItemIndex\r\n\t\twhile (i <= lastShownItemIndex) {\r\n\t\t\t// Measure item heights that haven't been measured previously.\r\n\t\t\t// Don't re-measure item heights that have been measured previously.\r\n\t\t\t// The rationale is that developers are supposed to manually call\r\n\t\t\t// `.onItemHeightChange()` every time an item's height changes.\r\n\t\t\t// If developers don't neglect that rule, item heights won't\r\n\t\t\t// change unexpectedly.\r\n\t\t\tif (this._get(i) === undefined) {\r\n\t\t\t\tnonPreviouslyMeasuredItemIndexes.push(i)\r\n\t\t\t\tconst height = this._measureItemHeight(i, firstShownItemIndex)\r\n\t\t\t\tlog('Item index', i, 'height', height)\r\n\t\t\t\tthis._set(i, height)\r\n\t\t\t\t// Update average item height calculation variables\r\n\t\t\t\t// related to the previously measured items\r\n\t\t\t\t// that're above the items currently being shown.\r\n\t\t\t\t// It is known to be a \"continuous\" measured items list,\r\n\t\t\t\t// because the code at the start of this function checks that.\r\n\t\t\t\tif (previousFirstMeasuredItemIndex === undefined || i < previousFirstMeasuredItemIndex) {\r\n\t\t\t\t\tthis.measuredItemsHeight += height\r\n\t\t\t\t\t// Update first measured item index.\r\n\t\t\t\t\tif (!firstMeasuredItemIndexHasBeenUpdated) {\r\n\t\t\t\t\t\t// log('Set first measured item index', i)\r\n\t\t\t\t\t\tthis.firstMeasuredItemIndex = i\r\n\t\t\t\t\t\tfirstMeasuredItemIndexHasBeenUpdated = true\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t// Update average item height calculation variables\r\n\t\t\t\t// related to the previously measured items\r\n\t\t\t\t// that're below the items currently being shown.\r\n\t\t\t\t// It is known to be a \"continuous\" measured items list,\r\n\t\t\t\t// because the code at the start of this function checks that.\r\n\t\t\t\tif (previousLastMeasuredItemIndex === undefined || i > previousLastMeasuredItemIndex) {\r\n\t\t\t\t\t// If `previousLastMeasuredItemIndex` is `undefined`\r\n\t\t\t\t\t// then `previousFirstMeasuredItemIndex` is also `undefined`\r\n\t\t\t\t\t// which means that the item's `height` has already been added\r\n\t\t\t\t\t// to `this.measuredItemsHeight` in the code above,\r\n\t\t\t\t\t// so this condition guards against counting the item's `height`\r\n\t\t\t\t\t// twice in `this.measuredItemsHeight`.\r\n\t\t\t\t\tif (previousLastMeasuredItemIndex !== undefined) {\r\n\t\t\t\t\t\t// Add newly shown item height.\r\n\t\t\t\t\t\tthis.measuredItemsHeight += height\r\n\t\t\t\t\t}\r\n\t\t\t\t\t// Update last measured item index.\r\n\t\t\t\t\tthis.lastMeasuredItemIndex = i\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\t// Validate that the item's height didn't change since it was last measured.\r\n\t\t\t\t// If it did, then display a warning and update the item's height\r\n\t\t\t\t// as an attempt to fix things.\r\n\t\t\t\t// If an item's height changes unexpectedly then it means that there'll\r\n\t\t\t\t// likely be \"content jumping\".\r\n\t\t\t\tconst previousHeight = this._get(i)\r\n\t\t\t\tconst height = this._measureItemHeight(i, firstShownItemIndex)\r\n\t\t\t\tif (previousHeight !== height) {\r\n\t\t\t\t\twarn('Item index', i, 'height changed unexpectedly: it was', previousHeight, 'before, but now it is', height, '. An item\\'s height is allowed to change only in two cases: when the item\\'s \"state\" changes and the developer calls `onItemStateChange(i, newState)`, or when the item\\'s height changes for some other reason and the developer calls `onItemHeightChange(i)`. Perhaps you forgot to persist the item\\'s \"state\" by calling `onItemStateChange(i, newState)` when it changed, and that \"state\" got lost when the item element was unmounted, which resulted in a different height when the item was shown again having its \"state\" reset.')\r\n\t\t\t\t\t// Update the item's height as an attempt to fix things.\r\n\t\t\t\t\tthis._set(i, height)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\ti++\r\n\t\t}\r\n\t\t// // Update average item height.\r\n\t\t// this.updateAverageItemHeight()\r\n\t\treturn nonPreviouslyMeasuredItemIndexes\r\n\t}\r\n\r\n\t/**\r\n\t * Re-measures item height.\r\n\t * @param {number} i — Item index.\r\n\t * @param {number} firstShownItemIndex\r\n\t */\r\n\tremeasureItemHeight(i, firstShownItemIndex) {\r\n\t\tconst previousHeight = this._get(i)\r\n\t\tconst height = this._measureItemHeight(i, firstShownItemIndex)\r\n\t\t// // Because this function is called from `.onItemHeightChange()`,\r\n\t\t// // there're no guarantees in which circumstances a developer calls it,\r\n\t\t// // and for which item indexes.\r\n\t\t// // Therefore, to guard against cases of incorrect usage,\r\n\t\t// // this function won't crash anything if the item isn't rendered\r\n\t\t// // or hasn't been previously rendered.\r\n\t\t// if (height !== undefined) {\r\n\t\t// \treportError(`\"onItemHeightChange()\" has been called for item ${i}, but that item isn't rendered.`)\r\n\t\t// \treturn\r\n\t\t// }\r\n\t\t// if (previousHeight === undefined) {\r\n\t\t// \treportError(`\"onItemHeightChange()\" has been called for item ${i}, but that item hasn't been rendered before.`)\r\n\t\t// \treturn\r\n\t\t// }\r\n\t\tthis._set(i, height)\r\n\t\tthis.measuredItemsHeight += height - previousHeight\r\n\t\treturn height\r\n\t}\r\n\r\n\t// /**\r\n\t// * \"Average\" item height is stored as an instance variable.\r\n\t// * For example, for caching, so that it isn't calculated every time it's requested.\r\n\t// * But that would be negligible performance gain, not really worth the extra code.\r\n\t// * Another thing it's stored for as an instance variable is\r\n\t// * keeping \"previous\" \"average\" item height, because it can be more precise\r\n\t// * than the newly calculated \"average\" item height, provided it had\r\n\t// * more \"samples\" (measured items). The newly calculated average item height\r\n\t// * could get less samples in a scenario when the scroll somehow jumps\r\n\t// * from one position to some other distant position: in that case previous\r\n\t// * \"total measured items height\" is discarded and the new one is initialized.\r\n\t// * Could such situation happen in real life? I guess, it's unlikely.\r\n\t// * So I'm commenting out this code, but still keeping it just in case.\r\n\t// */\r\n\t// updateAverageItemHeight() {\r\n\t// \tthis.averageItemHeightSamplesCount = this.lastMeasuredItemIndex - this.firstMeasuredItemIndex + 1\r\n\t// \tthis.averageItemHeight = this.measuredItemsHeight / this.averageItemHeightSamplesCount\r\n\t// }\r\n\t//\r\n\t// /**\r\n\t// * Public API: is called by `VirtualScroller`.\r\n\t// * @return {number}\r\n\t// */\r\n\t// getAverage() {\r\n\t// \t// Previously measured average item height might still be\r\n\t// \t// more precise if it contains more measured items (\"samples\").\r\n\t// \tif (this.previousAverageItemHeight) {\r\n\t// \t\tif (this.previousAverageItemHeightSamplesCount > this.averageItemHeightSamplesCount) {\r\n\t// \t\t\treturn this.previousAverageItemHeight\r\n\t// \t\t}\r\n\t// \t}\r\n\t// \treturn this.averageItemHeight || 0\r\n\t// }\r\n\r\n\t/**\r\n\t * Public API: is called by `VirtualScroller`.\r\n\t * @return {number}\r\n\t */\r\n\tgetAverage() {\r\n\t\tif (this.lastMeasuredItemIndex === undefined) {\r\n\t\t\treturn 0\r\n\t\t}\r\n\t\treturn this.measuredItemsHeight / (this.lastMeasuredItemIndex - this.firstMeasuredItemIndex + 1)\r\n\t}\r\n\r\n\tonPrepend(count) {\r\n\t\tif (this.firstMeasuredItemIndex !== undefined) {\r\n\t\t\tthis.firstMeasuredItemIndex += count\r\n\t\t\tthis.lastMeasuredItemIndex += count\r\n\t\t}\r\n\t}\r\n}"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ItemHeights.js","names":["ItemHeights","container","itemHeights","getItemHeight","setItemHeight","_get","_set","reset","measuredItemsHeight","firstMeasuredItemIndex","undefined","lastMeasuredItemIndex","i","length","firstShownItemIndex","getNthRenderedItemHeight","lastShownItemIndex","log","nonPreviouslyMeasuredItemIndexes","previousFirstMeasuredItemIndex","previousLastMeasuredItemIndex","firstMeasuredItemIndexHasBeenUpdated","push","height","_measureItemHeight","previousHeight","warn","count"],"sources":["../source/ItemHeights.js"],"sourcesContent":["import log, { warn, isDebug, reportError } from './utility/debug.js'\r\n\r\nexport default class ItemHeights {\r\n\tconstructor({\r\n\t\tcontainer,\r\n\t\titemHeights,\r\n\t\tgetItemHeight,\r\n\t\tsetItemHeight\r\n\t}) {\r\n\t\tthis.container = container\r\n\t\tthis._get = getItemHeight\r\n\t\tthis._set = setItemHeight\r\n\t\tthis.reset()\r\n\t}\r\n\r\n\treset() {\r\n\t\tthis.measuredItemsHeight = 0\r\n\t\t// \"First measured item index\" variable was introduced\r\n\t\t// because it's not always `0`: when `virtualScroller.setItems()`\r\n\t\t// is called, some items might get prepended, in which case\r\n\t\t// `this.lastMeasuredItemIndex` is updated. If there was no\r\n\t\t// `this.firstMeasuredItemIndex`, then the average item height\r\n\t\t// calculated in `.getAverage()` would be incorrect in the timeframe\r\n\t\t// between `.setItems()` is called and those changes have been rendered.\r\n\t\t// And in that timeframe, `.getAverage()` is used to calculate the \"layout\":\r\n\t\t// stuff like \"before/after items height\" and \"estimated items count on screen\".\r\n\t\tthis.firstMeasuredItemIndex = undefined\r\n\t\tthis.lastMeasuredItemIndex = undefined\r\n\t}\r\n\r\n\t/**\r\n\t * Can only be called after a `.reset()` (including new instance creation).\r\n\t * Initializes `this.measuredItemsHeight`, `this.firstMeasuredItemIndex`\r\n\t * and `this.lastMeasuredItemIndex` instance variables from `VirtualScroller` `state`.\r\n\t * These instance variables are used when calculating \"average\" item height:\r\n\t * the \"average\" item height is simply `this.measuredItemsHeight` divided by\r\n\t * `this.lastMeasuredItemIndex` minus `this.firstMeasuredItemIndex` plus 1.\r\n\t */\r\n\treadItemHeightsFromState({ itemHeights }) {\r\n\t\tlet i = 0\r\n\t\twhile (i < itemHeights.length) {\r\n\t\t\tif (itemHeights[i] === undefined) {\r\n\t\t\t\tif (this.firstMeasuredItemIndex !== undefined) {\r\n\t\t\t\t\tthis.lastMeasuredItemIndex = i - 1\r\n\t\t\t\t\tbreak\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (this.firstMeasuredItemIndex === undefined) {\r\n\t\t\t\t\tthis.firstMeasuredItemIndex = i\r\n\t\t\t\t}\r\n\t\t\t\tthis.measuredItemsHeight += itemHeights[i]\r\n\t\t\t}\r\n\t\t\ti++\r\n\t\t}\r\n\t}\r\n\r\n\t// Seems to be no longer used.\r\n\t// getItemHeight(i, firstShownItemIndex) {\r\n\t// \tif (this._get(i)) {\r\n\t// \t\treturn this._get(i)\r\n\t// \t}\r\n\t// \tconst itemHeight = this._measureItemHeight(i, firstShownItemIndex)\r\n\t// \tif (itemHeight) {\r\n\t// \t\tthis._set(i, itemHeight)\r\n\t// \t\treturn itemHeight\r\n\t// \t}\r\n\t// \treturn this.getAverage()\r\n\t// }\r\n\r\n\t_measureItemHeight(i, firstShownItemIndex) {\r\n\t\treturn this.container.getNthRenderedItemHeight(i - firstShownItemIndex)\r\n\t}\r\n\r\n\t/**\r\n\t * Measures item heights:\r\n\t *\r\n\t * * For the items that haven't been previously measured,\r\n\t * measures them for the first time.\r\n\t *\r\n\t * * For the items that have been previoulsy measured,\r\n\t * validate that their previously measured height\r\n\t * is still equal to their current height.\r\n\t * The unequalness may not necessarily be caused by\r\n\t * incorrect use of `virtual-scroller`: there are\r\n\t * also some valid use cases when such unequalness\r\n\t * could happen (see the comments in the code).\r\n\t *\r\n\t * @param {number} firstShownItemIndex\r\n\t * @param {number} lastShownItemIndex\r\n\t * @return {number[]} The indexes of the items that have not previously been measured and have been measured now.\r\n\t */\r\n\tmeasureItemHeights(firstShownItemIndex, lastShownItemIndex) {\r\n\t\tlog('~ Measure item heights ~')\r\n\t\t// If no items are rendered, don't measure anything.\r\n\t\tif (firstShownItemIndex === undefined) {\r\n\t\t\treturn\r\n\t\t}\r\n\t\t// Reset `this.measuredItemsHeight` if it's not a \"continuous\" measured items list:\r\n\t\t// if a group of items has been measured previously, and now it has rendered a completely\r\n\t\t// different group of items, and there's a non-measured \"gap\" between those two groups,\r\n\t\t// then reset `this.measuredItemsHeight` and \"first measured\"/\"last measured\" item indexes.\r\n\t\t// For example, this could happen when `.setItems()` prepends a lot of new items.\r\n\t\tif (this.firstMeasuredItemIndex !== undefined) {\r\n\t\t\tif (\r\n\t\t\t\tfirstShownItemIndex > this.lastMeasuredItemIndex + 1 ||\r\n\t\t\t\tlastShownItemIndex < this.firstMeasuredItemIndex - 1\r\n\t\t\t) {\r\n\t\t\t\t// Reset.\r\n\t\t\t\tlog('Non-measured items gap detected. Reset first and last measured item indexes.')\r\n\t\t\t\tthis.reset()\r\n\t\t\t}\r\n\t\t}\r\n\t\tconst nonPreviouslyMeasuredItemIndexes = []\r\n\t\tconst previousFirstMeasuredItemIndex = this.firstMeasuredItemIndex\r\n\t\tconst previousLastMeasuredItemIndex = this.lastMeasuredItemIndex\r\n\t\tlet firstMeasuredItemIndexHasBeenUpdated = false\r\n\t\tlet i = firstShownItemIndex\r\n\t\twhile (i <= lastShownItemIndex) {\r\n\t\t\t// Measure item heights that haven't been measured previously.\r\n\t\t\t// Don't re-measure item heights that have been measured previously.\r\n\t\t\t// The rationale is that developers are supposed to manually call\r\n\t\t\t// `.onItemHeightChange()` every time an item's height changes.\r\n\t\t\t// If developers don't neglect that rule, item heights won't\r\n\t\t\t// change unexpectedly.\r\n\t\t\tif (this._get(i) === undefined) {\r\n\t\t\t\tnonPreviouslyMeasuredItemIndexes.push(i)\r\n\t\t\t\tconst height = this._measureItemHeight(i, firstShownItemIndex)\r\n\t\t\t\tlog('Item index', i, 'height', height)\r\n\t\t\t\tthis._set(i, height)\r\n\t\t\t\t// Update average item height calculation variables\r\n\t\t\t\t// related to the previously measured items\r\n\t\t\t\t// that're above the items currently being shown.\r\n\t\t\t\t// It is known to be a \"continuous\" measured items list,\r\n\t\t\t\t// because the code at the start of this function checks that.\r\n\t\t\t\tif (previousFirstMeasuredItemIndex === undefined || i < previousFirstMeasuredItemIndex) {\r\n\t\t\t\t\tthis.measuredItemsHeight += height\r\n\t\t\t\t\t// Update first measured item index.\r\n\t\t\t\t\tif (!firstMeasuredItemIndexHasBeenUpdated) {\r\n\t\t\t\t\t\t// log('Set first measured item index', i)\r\n\t\t\t\t\t\tthis.firstMeasuredItemIndex = i\r\n\t\t\t\t\t\tfirstMeasuredItemIndexHasBeenUpdated = true\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t// Update average item height calculation variables\r\n\t\t\t\t// related to the previously measured items\r\n\t\t\t\t// that're below the items currently being shown.\r\n\t\t\t\t// It is known to be a \"continuous\" measured items list,\r\n\t\t\t\t// because the code at the start of this function checks that.\r\n\t\t\t\tif (previousLastMeasuredItemIndex === undefined || i > previousLastMeasuredItemIndex) {\r\n\t\t\t\t\t// If `previousLastMeasuredItemIndex` is `undefined`\r\n\t\t\t\t\t// then `previousFirstMeasuredItemIndex` is also `undefined`\r\n\t\t\t\t\t// which means that the item's `height` has already been added\r\n\t\t\t\t\t// to `this.measuredItemsHeight` in the code above,\r\n\t\t\t\t\t// so this condition guards against counting the item's `height`\r\n\t\t\t\t\t// twice in `this.measuredItemsHeight`.\r\n\t\t\t\t\tif (previousLastMeasuredItemIndex !== undefined) {\r\n\t\t\t\t\t\t// Add newly shown item height.\r\n\t\t\t\t\t\tthis.measuredItemsHeight += height\r\n\t\t\t\t\t}\r\n\t\t\t\t\t// Update last measured item index.\r\n\t\t\t\t\tthis.lastMeasuredItemIndex = i\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\t// Validate that the item's height didn't change since it was last measured.\r\n\t\t\t\t// If it did, then display a warning and update the item's height\r\n\t\t\t\t// as an attempt to fix things.\r\n\t\t\t\t// If an item's height changes unexpectedly then it means that there'll\r\n\t\t\t\t// likely be \"content jumping\".\r\n\t\t\t\tconst previousHeight = this._get(i)\r\n\t\t\t\tconst height = this._measureItemHeight(i, firstShownItemIndex)\r\n\t\t\t\tif (previousHeight !== height) {\r\n\t\t\t\t\twarn('Item index', i, 'height changed unexpectedly: it was', previousHeight, 'before, but now it is', height, '. An item\\'s height is allowed to change only in two cases: when the item\\'s \"state\" changes and the developer calls `setItemState(i, newState)`, or when the item\\'s height changes for some other reason and the developer calls `onItemHeightChange(i)`. Perhaps you forgot to persist the item\\'s \"state\" by calling `setItemState(i, newState)` when it changed, and that \"state\" got lost when the item element was unmounted, which resulted in a different height when the item was shown again having its \"state\" reset.')\r\n\t\t\t\t\t// Update the item's height as an attempt to fix things.\r\n\t\t\t\t\tthis._set(i, height)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\ti++\r\n\t\t}\r\n\t\t// // Update average item height.\r\n\t\t// this.updateAverageItemHeight()\r\n\t\treturn nonPreviouslyMeasuredItemIndexes\r\n\t}\r\n\r\n\t/**\r\n\t * Re-measures item height.\r\n\t * @param {number} i — Item index.\r\n\t * @param {number} firstShownItemIndex\r\n\t */\r\n\tremeasureItemHeight(i, firstShownItemIndex) {\r\n\t\tconst previousHeight = this._get(i)\r\n\t\tconst height = this._measureItemHeight(i, firstShownItemIndex)\r\n\t\t// // Because this function is called from `.onItemHeightChange()`,\r\n\t\t// // there're no guarantees in which circumstances a developer calls it,\r\n\t\t// // and for which item indexes.\r\n\t\t// // Therefore, to guard against cases of incorrect usage,\r\n\t\t// // this function won't crash anything if the item isn't rendered\r\n\t\t// // or hasn't been previously rendered.\r\n\t\t// if (height !== undefined) {\r\n\t\t// \treportError(`\"onItemHeightChange()\" has been called for item ${i}, but that item isn't rendered.`)\r\n\t\t// \treturn\r\n\t\t// }\r\n\t\t// if (previousHeight === undefined) {\r\n\t\t// \treportError(`\"onItemHeightChange()\" has been called for item ${i}, but that item hasn't been rendered before.`)\r\n\t\t// \treturn\r\n\t\t// }\r\n\t\tthis._set(i, height)\r\n\t\tthis.measuredItemsHeight += height - previousHeight\r\n\t\treturn height\r\n\t}\r\n\r\n\t// /**\r\n\t// * \"Average\" item height is stored as an instance variable.\r\n\t// * For example, for caching, so that it isn't calculated every time it's requested.\r\n\t// * But that would be negligible performance gain, not really worth the extra code.\r\n\t// * Another thing it's stored for as an instance variable is\r\n\t// * keeping \"previous\" \"average\" item height, because it can be more precise\r\n\t// * than the newly calculated \"average\" item height, provided it had\r\n\t// * more \"samples\" (measured items). The newly calculated average item height\r\n\t// * could get less samples in a scenario when the scroll somehow jumps\r\n\t// * from one position to some other distant position: in that case previous\r\n\t// * \"total measured items height\" is discarded and the new one is initialized.\r\n\t// * Could such situation happen in real life? I guess, it's unlikely.\r\n\t// * So I'm commenting out this code, but still keeping it just in case.\r\n\t// */\r\n\t// updateAverageItemHeight() {\r\n\t// \tthis.averageItemHeightSamplesCount = this.lastMeasuredItemIndex - this.firstMeasuredItemIndex + 1\r\n\t// \tthis.averageItemHeight = this.measuredItemsHeight / this.averageItemHeightSamplesCount\r\n\t// }\r\n\t//\r\n\t// /**\r\n\t// * Public API: is called by `VirtualScroller`.\r\n\t// * @return {number}\r\n\t// */\r\n\t// getAverage() {\r\n\t// \t// Previously measured average item height might still be\r\n\t// \t// more precise if it contains more measured items (\"samples\").\r\n\t// \tif (this.previousAverageItemHeight) {\r\n\t// \t\tif (this.previousAverageItemHeightSamplesCount > this.averageItemHeightSamplesCount) {\r\n\t// \t\t\treturn this.previousAverageItemHeight\r\n\t// \t\t}\r\n\t// \t}\r\n\t// \treturn this.averageItemHeight || 0\r\n\t// }\r\n\r\n\t/**\r\n\t * Public API: is called by `VirtualScroller`.\r\n\t * @return {number}\r\n\t */\r\n\tgetAverage() {\r\n\t\tif (this.lastMeasuredItemIndex === undefined) {\r\n\t\t\treturn 0\r\n\t\t}\r\n\t\treturn this.measuredItemsHeight / (this.lastMeasuredItemIndex - this.firstMeasuredItemIndex + 1)\r\n\t}\r\n\r\n\tonPrepend(count) {\r\n\t\tif (this.firstMeasuredItemIndex !== undefined) {\r\n\t\t\tthis.firstMeasuredItemIndex += count\r\n\t\t\tthis.lastMeasuredItemIndex += count\r\n\t\t}\r\n\t}\r\n}"],"mappings":"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"}
|
|
@@ -57,6 +57,8 @@ function VirtualScrollerConstructor(getItemsContainerElement, items) {
|
|
|
57
57
|
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
58
58
|
var render = options.render,
|
|
59
59
|
state = options.state,
|
|
60
|
+
_options$getInitialIt = options.getInitialItemState,
|
|
61
|
+
getInitialItemState = _options$getInitialIt === void 0 ? function () {} : _options$getInitialIt,
|
|
60
62
|
onStateChange = options.onStateChange,
|
|
61
63
|
initialScrollPosition = options.initialScrollPosition,
|
|
62
64
|
onScrollPositionChange = options.onScrollPositionChange,
|
|
@@ -209,6 +211,7 @@ function VirtualScrollerConstructor(getItemsContainerElement, items) {
|
|
|
209
211
|
|
|
210
212
|
_VirtualScrollerState["default"].call(this, {
|
|
211
213
|
state: state,
|
|
214
|
+
getInitialItemState: getInitialItemState,
|
|
212
215
|
onStateChange: onStateChange,
|
|
213
216
|
render: render,
|
|
214
217
|
items: items
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VirtualScroller.constructor.js","names":["VirtualScrollerConstructor","getItemsContainerElement","items","options","render","state","onStateChange","initialScrollPosition","onScrollPositionChange","scrollableContainer","measureItemsBatchSize","getColumnsCount","getItemId","tbody","estimatedItemHeight","getEstimatedVisibleItemRowsCount","onItemInitialRender","onItemFirstRender","_useTimeoutInRenderLoop","_waitForScrollingToStop","engine","bypass","getEstimatedItemHeight","getScrollableContainer","log","DOMEngine","getState","setState","Error","supportsTbody","reportError","BROWSER_NOT_SUPPORTED_ERROR","isItemEqual","a","b","item","warn","i","indexOf","length","createStateHelpers","call","createVerticalSpacingHelpers","createColumnsHelpers","createLayoutHelpers","createOnRenderHelpers","createResizeHelpers","createItemsHelpers","createHelpers","waitForScrollingToStop","itemHeights","readItemHeightsFromState","beforeResize","initializeFromState","itemsContainer","createItemsContainer","clear","createScrollableContainer","ItemHeights","container","getItemHeight","setItemHeight","height","layout","Layout","getInitialEstimatedItemHeight","getInitialEstimatedVisibleItemRowsCount","getPrerenderMargin","getVerticalSpacing","getVerticalSpacingBeforeResize","getColumnsCountBeforeResize","columnsCount","getItemHeightBeforeResize","getBeforeResizeItemsCount","getAverageItemHeight","getAverage","getMaxVisibleAreaHeight","getHeight","getPreviouslyCalculatedLayout","previouslyCalculatedLayout","resize","Resize","getWidth","listenForResize","listener","onResize","onResizeStart","_isResizing","onResizeStop","undefined","onNoChange","onUpdateShownItemIndexes","reason","LAYOUT_REASON","VIEWPORT_SIZE_UNCHANGED","onHeightChange","VIEWPORT_HEIGHT_CHANGED","onWidthChange","prevWidth","newWidth","scroll","Scroll","onScroll","delayed","STOPPED_SCROLLING","SCROLL","isImmediateLayoutScheduled","Boolean","layoutTimer","hasNonRenderedItemsAtTheTop","firstShownItemIndex","hasNonRenderedItemsAtTheBottom","lastShownItemIndex","getItemsCount","getLatestLayoutVisibleArea","latestLayoutVisibleArea","getListTopOffset","getListTopOffsetInsideScrollableContainer","listHeightMeasurement","ListHeightMeasurement","watchListTopOffset","listTopOffsetWatcher","onListTopOffsetChange","TOP_OFFSET_CHANGED","BeforeResize"],"sources":["../source/VirtualScroller.constructor.js"],"sourcesContent":["import {\r\n\tsupportsTbody,\r\n\tBROWSER_NOT_SUPPORTED_ERROR\r\n} from './DOM/tbody.js'\r\n\r\nimport DOMEngine from './DOM/Engine.js'\r\n\r\nimport Layout, { LAYOUT_REASON } from './Layout.js'\r\nimport Resize from './Resize.js'\r\nimport BeforeResize from './BeforeResize.js'\r\nimport Scroll from './Scroll.js'\r\nimport ListHeightMeasurement from './ListHeightMeasurement.js'\r\nimport ItemHeights from './ItemHeights.js'\r\n\r\nimport log, { warn, isDebug, reportError } from './utility/debug.js'\r\n\r\nimport createStateHelpers from './VirtualScroller.state.js'\r\nimport createVerticalSpacingHelpers from './VirtualScroller.verticalSpacing.js'\r\nimport createColumnsHelpers from './VirtualScroller.columns.js'\r\nimport createLayoutHelpers from './VirtualScroller.layout.js'\r\nimport createOnRenderHelpers from './VirtualScroller.onRender.js'\r\nimport createResizeHelpers from './VirtualScroller.resize.js'\r\nimport createItemsHelpers from './VirtualScroller.items.js'\r\n\r\n/**\r\n * @param {function} getItemsContainerElement — Returns the container DOM `Element`.\r\n * @param {any[]} items — The list of items.\r\n * @param {Object} [options] — See README.md.\r\n * @return {VirtualScroller}\r\n */\r\nexport default function VirtualScrollerConstructor(\r\n\tgetItemsContainerElement,\r\n\titems,\r\n\toptions = {}\r\n) {\r\n\tconst {\r\n\t\trender,\r\n\t\tstate,\r\n\t\tonStateChange,\r\n\t\tinitialScrollPosition,\r\n\t\tonScrollPositionChange,\r\n\t\t// `scrollableContainer` option is deprecated.\r\n\t\t// Use `getScrollableContainer()` option instead.\r\n\t\tscrollableContainer,\r\n\t\tmeasureItemsBatchSize = 50,\r\n\t\tgetColumnsCount,\r\n\t\tgetItemId,\r\n\t\ttbody,\r\n\t\t// `estimatedItemHeight` is deprecated, use `getEstimatedItemHeight()` instead.\r\n\t\testimatedItemHeight,\r\n\t\tgetEstimatedVisibleItemRowsCount,\r\n\t\tonItemInitialRender,\r\n\t\t// `onItemFirstRender(i)` is deprecated, use `onItemInitialRender(item)` instead.\r\n\t\tonItemFirstRender,\r\n\t\t_useTimeoutInRenderLoop,\r\n\t\t_waitForScrollingToStop,\r\n\t\tengine\r\n\t} = options\r\n\r\n\tlet {\r\n\t\tbypass,\r\n\t\tgetEstimatedItemHeight,\r\n\t\tgetScrollableContainer\r\n\t} = options\r\n\r\n\tlog('~ Initialize ~')\r\n\r\n\t// Could support non-DOM rendering engines.\r\n\t// For example, React Native, `<canvas/>`, etc.\r\n\tthis.engine = engine || DOMEngine\r\n\r\n\tif (!getEstimatedItemHeight && typeof estimatedItemHeight === 'number') {\r\n\t\tgetEstimatedItemHeight = () => estimatedItemHeight\r\n\t}\r\n\r\n\t// `scrollableContainer` option is deprecated.\r\n\t// Use `getScrollableContainer()` option instead.\r\n\tif (!getScrollableContainer && scrollableContainer) {\r\n\t\tgetScrollableContainer = () => scrollableContainer\r\n\t}\r\n\r\n\t// Sometimes, when `new VirtualScroller()` instance is created,\r\n\t// `getItemsContainerElement()` might not be ready to return the \"container\" DOM Element yet\r\n\t// (for example, because it's not rendered yet). That's the reason why it's a getter function.\r\n\t// For example, in React `<VirtualScroller/>` component, a `VirtualScroller`\r\n\t// instance is created in the React component's `constructor()`, and at that time\r\n\t// the container Element is not yet available. The container Element is available\r\n\t// in `componentDidMount()`, but `componentDidMount()` is not executed on server,\r\n\t// which would mean that React `<VirtualScroller/>` wouldn't render at all\r\n\t// on server side, while with the `getItemsContainerElement()` approach, on server side,\r\n\t// it still \"renders\" a list with a predefined amount of items in it by default.\r\n\t// (`initiallyRenderedItemsCount`, or `1`).\r\n\tthis.getItemsContainerElement = getItemsContainerElement\r\n\r\n\t// if (prerenderMargin === undefined) {\r\n\t// \t// Renders items which are outside of the screen by this \"prerender margin\".\r\n\t// \t// Is the screen height by default: seems to be the optimal value\r\n\t// \t// for \"Page Up\" / \"Page Down\" navigation and optimized mouse wheel scrolling.\r\n\t// \tprerenderMargin = this.scrollableContainer ? this.scrollableContainer.getHeight() : 0\r\n\t// }\r\n\r\n\tif (options.getState || options.setState) {\r\n\t\tthrow new Error('[virtual-scroller] `getState`/`setState` options usage has changed in the new version. See the readme for more details.')\r\n\t}\r\n\r\n\t// Work around `<tbody/>` not being able to have `padding`.\r\n\t// https://gitlab.com/catamphetamine/virtual-scroller/-/issues/1\r\n\tif (tbody) {\r\n\t\tif (this.engine !== DOMEngine) {\r\n\t\t\tthrow new Error('[virtual-scroller] `tbody` option is only supported for DOM rendering engine')\r\n\t\t}\r\n\t\tlog('~ <tbody/> detected ~')\r\n\t\tthis.tbody = true\r\n\t\tif (!supportsTbody()) {\r\n\t\t\tlog('~ <tbody/> not supported ~')\r\n\t\t\treportError(BROWSER_NOT_SUPPORTED_ERROR)\r\n\t\t\tbypass = true\r\n\t\t}\r\n\t}\r\n\r\n\tif (bypass) {\r\n\t\tlog('~ \"bypass\" mode ~')\r\n\t}\r\n\r\n\t// In `bypass` mode, `VirtualScroller` doesn't wait\r\n\t// for the user to scroll down to render all items:\r\n\t// instead, it renders all items right away, as if\r\n\t// the list is rendered without using `VirtualScroller`.\r\n\t// It was added just to measure how much is the\r\n\t// performance difference between using a `VirtualScroller`\r\n\t// and not using a `VirtualScroller`.\r\n\t// It turned out that unmounting large React component trees\r\n\t// is a very long process, so `VirtualScroller` does seem to\r\n\t// make sense when used in a React application.\r\n\tthis.bypass = bypass\r\n\t// this.bypassBatchSize = bypassBatchSize || 10\r\n\r\n\t// Using `setTimeout()` in render loop is a workaround\r\n\t// for avoiding a React error message:\r\n\t// \"Maximum update depth exceeded.\r\n\t// This can happen when a component repeatedly calls\r\n\t// `.setState()` inside `componentWillUpdate()` or `componentDidUpdate()`.\r\n\t// React limits the number of nested updates to prevent infinite loops.\"\r\n\tthis._useTimeoutInRenderLoop = _useTimeoutInRenderLoop\r\n\r\n\tif (getItemId) {\r\n\t\tthis.isItemEqual = (a, b) => getItemId(a) === getItemId(b)\r\n\t} else {\r\n\t\tthis.isItemEqual = (a, b) => a === b\r\n\t}\r\n\r\n\tif (onItemInitialRender) {\r\n\t\tthis.onItemInitialRender = onItemInitialRender\r\n\t}\r\n\t// `onItemFirstRender(i)` is deprecated, use `onItemInitialRender(item)` instead.\r\n\telse if (onItemFirstRender) {\r\n\t\tthis.onItemInitialRender = (item) => {\r\n\t\t\twarn('`onItemFirstRender(i)` is deprecated, use `onItemInitialRender(item)` instead.')\r\n\t\t\tconst { items } = this.getState()\r\n\t\t\tconst i = items.indexOf(item)\r\n\t\t\t// The `item` could also be non-found due to the inconsistency bug:\r\n\t\t\t// The reason is that `i` can be non-consistent with the `items`\r\n\t\t\t// passed to `<VirtualScroller/>` in React due to `updateState()` not being\r\n\t\t\t// instanteneous: when new `items` are passed to `<VirtualScroller/>`,\r\n\t\t\t// `VirtualScroller.updateState({ items })` is called, and if `onItemFirstRender(i)`\r\n\t\t\t// is called after the aforementioned `updateState()` is called but before it finishes,\r\n\t\t\t// `i` would point to an index in \"previous\" `items` while the application\r\n\t\t\t// would assume that `i` points to an index in the \"new\" `items`,\r\n\t\t\t// resulting in an incorrect item being assumed by the application\r\n\t\t\t// or even in an \"array index out of bounds\" error.\r\n\t\t\tif (i >= 0) {\r\n\t\t\t\tonItemFirstRender(i)\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t// If initial `state` is passed then use `items` from `state`\r\n\t// instead of the `items` argument.\r\n\tif (state) {\r\n\t\titems = state.items\r\n\t}\r\n\r\n\tlog('Items count', items.length)\r\n\tif (getEstimatedItemHeight) {\r\n\t\tlog('Estimated item height', getEstimatedItemHeight())\r\n\t}\r\n\r\n\tcreateStateHelpers.call(this, { state, onStateChange, render, items })\r\n\r\n\tcreateVerticalSpacingHelpers.call(this)\r\n\tcreateColumnsHelpers.call(this, { getColumnsCount })\r\n\r\n\tcreateLayoutHelpers.call(this)\r\n\tcreateOnRenderHelpers.call(this)\r\n\tcreateResizeHelpers.call(this)\r\n\tcreateItemsHelpers.call(this)\r\n\r\n\tcreateHelpers.call(this, {\r\n\t\tgetScrollableContainer,\r\n\t\tgetEstimatedItemHeight,\r\n\t\tgetEstimatedVisibleItemRowsCount,\r\n\t\tmeasureItemsBatchSize,\r\n\t\tinitialScrollPosition,\r\n\t\tonScrollPositionChange,\r\n\t\twaitForScrollingToStop: _waitForScrollingToStop\r\n\t})\r\n\r\n\tif (state) {\r\n\t\t// Initialize `ItemHeights` from previously measured `state.itemHeights`.\r\n\t\tthis.itemHeights.readItemHeightsFromState(state)\r\n\r\n\t\t// Initialize some `BeforeResize` internal flags from a previously saved state.\r\n\t\tthis.beforeResize.initializeFromState(state)\r\n\t}\r\n}\r\n\r\nfunction createHelpers({\r\n\tgetScrollableContainer,\r\n\tgetEstimatedItemHeight,\r\n\tgetEstimatedVisibleItemRowsCount,\r\n\tmeasureItemsBatchSize,\r\n\tinitialScrollPosition,\r\n\tonScrollPositionChange,\r\n\twaitForScrollingToStop\r\n}) {\r\n\tthis.itemsContainer = this.engine.createItemsContainer(\r\n\t\tthis.getItemsContainerElement\r\n\t)\r\n\r\n\t// If the items \"container\" element is mounted at this stage,\r\n\t// remove any accidental text nodes from it (like whitespace).\r\n\t//\r\n\t// Also, this guards against cases when someone accidentally tries\r\n\t// using `VirtualScroller` on a non-empty element.\r\n\t//\r\n\tif (this.getItemsContainerElement()) {\r\n\t\tthis.itemsContainer.clear()\r\n\t}\r\n\r\n\tthis.scrollableContainer = this.engine.createScrollableContainer(\r\n\t\tgetScrollableContainer,\r\n\t\tthis.getItemsContainerElement\r\n\t)\r\n\r\n\t// Create `ItemHeights` instance.\r\n\tthis.itemHeights = new ItemHeights({\r\n\t\tcontainer: this.itemsContainer,\r\n\t\tgetItemHeight: (i) => this.getState().itemHeights[i],\r\n\t\tsetItemHeight: (i, height) => this.getState().itemHeights[i] = height\r\n\t})\r\n\r\n\tthis.layout = new Layout({\r\n\t\tbypass: this.bypass,\r\n\t\tgetInitialEstimatedItemHeight: getEstimatedItemHeight,\r\n\t\tgetInitialEstimatedVisibleItemRowsCount: getEstimatedVisibleItemRowsCount,\r\n\t\tmeasureItemsBatchSize,\r\n\t\tgetPrerenderMargin: () => this.getPrerenderMargin(),\r\n\t\tgetVerticalSpacing: () => this.getVerticalSpacing(),\r\n\t\tgetVerticalSpacingBeforeResize: () => this.getVerticalSpacingBeforeResize(),\r\n\t\tgetColumnsCount: () => this.getColumnsCount(),\r\n\t\tgetColumnsCountBeforeResize: () => this.getState().beforeResize && this.getState().beforeResize.columnsCount,\r\n\t\tgetItemHeight: (i) => this.getState().itemHeights[i],\r\n\t\tgetItemHeightBeforeResize: (i) => this.getState().beforeResize && this.getState().beforeResize.itemHeights[i],\r\n\t\tgetBeforeResizeItemsCount: () => this.getState().beforeResize ? this.getState().beforeResize.itemHeights.length : 0,\r\n\t\tgetAverageItemHeight: () => this.itemHeights.getAverage(),\r\n\t\t// `this.scrollableContainer` is gonna be `undefined` during server-side rendering.\r\n\t\t// https://gitlab.com/catamphetamine/virtual-scroller/-/issues/30\r\n\t\tgetMaxVisibleAreaHeight: () => this.scrollableContainer && this.scrollableContainer.getHeight(),\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\tgetPreviouslyCalculatedLayout: () => this.previouslyCalculatedLayout\r\n\t})\r\n\r\n\tthis.resize = new Resize({\r\n\t\tbypass: this.bypass,\r\n\t\tgetWidth: () => this.scrollableContainer.getWidth(),\r\n\t\tgetHeight: () => this.scrollableContainer.getHeight(),\r\n\t\tlistenForResize: (listener) => this.scrollableContainer.onResize(listener),\r\n\t\tonResizeStart: () => {\r\n\t\t\tlog('~ Scrollable container resize started ~')\r\n\t\t\tthis._isResizing = true\r\n\t\t},\r\n\t\tonResizeStop: () => {\r\n\t\t\tlog('~ Scrollable container resize finished ~')\r\n\t\t\tthis._isResizing = undefined\r\n\t\t},\r\n\t\tonNoChange: () => {\r\n\t\t\t// There might have been some missed `this.onUpdateShownItemIndexes()` calls\r\n\t\t\t// due to setting `this._isResizing` flag to `true` during the resize.\r\n\t\t\t// So, update shown item indexes just in case.\r\n\t\t\tthis.onUpdateShownItemIndexes({\r\n\t\t\t\treason: LAYOUT_REASON.VIEWPORT_SIZE_UNCHANGED\r\n\t\t\t})\r\n\t\t},\r\n\t\tonHeightChange: () => this.onUpdateShownItemIndexes({\r\n\t\t\treason: LAYOUT_REASON.VIEWPORT_HEIGHT_CHANGED\r\n\t\t}),\r\n\t\tonWidthChange: (prevWidth, newWidth) => {\r\n\t\t\tlog('~ Scrollable container width changed from', prevWidth, 'to', newWidth, '~')\r\n\t\t\tthis.onResize()\r\n\t\t}\r\n\t})\r\n\r\n\tthis.scroll = new Scroll({\r\n\t\tbypass: this.bypass,\r\n\t\tscrollableContainer: this.scrollableContainer,\r\n\t\titemsContainer: this.itemsContainer,\r\n\t\twaitForScrollingToStop,\r\n\t\tonScroll: ({ delayed } = {}) => {\r\n\t\t\tthis.onUpdateShownItemIndexes({\r\n\t\t\t\treason: delayed ? LAYOUT_REASON.STOPPED_SCROLLING : LAYOUT_REASON.SCROLL\r\n\t\t\t})\r\n\t\t},\r\n\t\tinitialScrollPosition,\r\n\t\tonScrollPositionChange,\r\n\t\tisImmediateLayoutScheduled: () => Boolean(this.layoutTimer),\r\n\t\thasNonRenderedItemsAtTheTop: () => this.getState().firstShownItemIndex > 0,\r\n\t\thasNonRenderedItemsAtTheBottom: () => this.getState().lastShownItemIndex < this.getItemsCount() - 1,\r\n\t\tgetLatestLayoutVisibleArea: () => this.latestLayoutVisibleArea,\r\n\t\tgetListTopOffset: this.getListTopOffsetInsideScrollableContainer,\r\n\t\tgetPrerenderMargin: () => this.getPrerenderMargin()\r\n\t})\r\n\r\n\tthis.listHeightMeasurement = new ListHeightMeasurement({\r\n\t\titemsContainer: this.itemsContainer,\r\n\t\tgetListTopOffset: this.getListTopOffsetInsideScrollableContainer\r\n\t})\r\n\r\n\tif (this.engine.watchListTopOffset) {\r\n\t\tthis.listTopOffsetWatcher = this.engine.watchListTopOffset({\r\n\t\t\tgetListTopOffset: this.getListTopOffsetInsideScrollableContainer,\r\n\t\t\tonListTopOffsetChange: ({ reason }) => this.onUpdateShownItemIndexes({\r\n\t\t\t\treason: LAYOUT_REASON.TOP_OFFSET_CHANGED\r\n\t\t\t})\r\n\t\t})\r\n\t}\r\n\r\n\tthis.beforeResize = new BeforeResize({\r\n\t\tgetState: this.getState,\r\n\t\tgetVerticalSpacing: this.getVerticalSpacing,\r\n\t\tgetColumnsCount: this.getColumnsCount\r\n\t})\r\n}"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"VirtualScroller.constructor.js","names":["VirtualScrollerConstructor","getItemsContainerElement","items","options","render","state","getInitialItemState","onStateChange","initialScrollPosition","onScrollPositionChange","scrollableContainer","measureItemsBatchSize","getColumnsCount","getItemId","tbody","estimatedItemHeight","getEstimatedVisibleItemRowsCount","onItemInitialRender","onItemFirstRender","_useTimeoutInRenderLoop","_waitForScrollingToStop","engine","bypass","getEstimatedItemHeight","getScrollableContainer","log","DOMEngine","getState","setState","Error","supportsTbody","reportError","BROWSER_NOT_SUPPORTED_ERROR","isItemEqual","a","b","item","warn","i","indexOf","length","createStateHelpers","call","createVerticalSpacingHelpers","createColumnsHelpers","createLayoutHelpers","createOnRenderHelpers","createResizeHelpers","createItemsHelpers","createHelpers","waitForScrollingToStop","itemHeights","readItemHeightsFromState","beforeResize","initializeFromState","itemsContainer","createItemsContainer","clear","createScrollableContainer","ItemHeights","container","getItemHeight","setItemHeight","height","layout","Layout","getInitialEstimatedItemHeight","getInitialEstimatedVisibleItemRowsCount","getPrerenderMargin","getVerticalSpacing","getVerticalSpacingBeforeResize","getColumnsCountBeforeResize","columnsCount","getItemHeightBeforeResize","getBeforeResizeItemsCount","getAverageItemHeight","getAverage","getMaxVisibleAreaHeight","getHeight","getPreviouslyCalculatedLayout","previouslyCalculatedLayout","resize","Resize","getWidth","listenForResize","listener","onResize","onResizeStart","_isResizing","onResizeStop","undefined","onNoChange","onUpdateShownItemIndexes","reason","LAYOUT_REASON","VIEWPORT_SIZE_UNCHANGED","onHeightChange","VIEWPORT_HEIGHT_CHANGED","onWidthChange","prevWidth","newWidth","scroll","Scroll","onScroll","delayed","STOPPED_SCROLLING","SCROLL","isImmediateLayoutScheduled","Boolean","layoutTimer","hasNonRenderedItemsAtTheTop","firstShownItemIndex","hasNonRenderedItemsAtTheBottom","lastShownItemIndex","getItemsCount","getLatestLayoutVisibleArea","latestLayoutVisibleArea","getListTopOffset","getListTopOffsetInsideScrollableContainer","listHeightMeasurement","ListHeightMeasurement","watchListTopOffset","listTopOffsetWatcher","onListTopOffsetChange","TOP_OFFSET_CHANGED","BeforeResize"],"sources":["../source/VirtualScroller.constructor.js"],"sourcesContent":["import {\r\n\tsupportsTbody,\r\n\tBROWSER_NOT_SUPPORTED_ERROR\r\n} from './DOM/tbody.js'\r\n\r\nimport DOMEngine from './DOM/Engine.js'\r\n\r\nimport Layout, { LAYOUT_REASON } from './Layout.js'\r\nimport Resize from './Resize.js'\r\nimport BeforeResize from './BeforeResize.js'\r\nimport Scroll from './Scroll.js'\r\nimport ListHeightMeasurement from './ListHeightMeasurement.js'\r\nimport ItemHeights from './ItemHeights.js'\r\n\r\nimport log, { warn, isDebug, reportError } from './utility/debug.js'\r\n\r\nimport createStateHelpers from './VirtualScroller.state.js'\r\nimport createVerticalSpacingHelpers from './VirtualScroller.verticalSpacing.js'\r\nimport createColumnsHelpers from './VirtualScroller.columns.js'\r\nimport createLayoutHelpers from './VirtualScroller.layout.js'\r\nimport createOnRenderHelpers from './VirtualScroller.onRender.js'\r\nimport createResizeHelpers from './VirtualScroller.resize.js'\r\nimport createItemsHelpers from './VirtualScroller.items.js'\r\n\r\n/**\r\n * @param {function} getItemsContainerElement — Returns the container DOM `Element`.\r\n * @param {any[]} items — The list of items.\r\n * @param {Object} [options] — See README.md.\r\n * @return {VirtualScroller}\r\n */\r\nexport default function VirtualScrollerConstructor(\r\n\tgetItemsContainerElement,\r\n\titems,\r\n\toptions = {}\r\n) {\r\n\tconst {\r\n\t\trender,\r\n\t\tstate,\r\n\t\tgetInitialItemState = () => {},\r\n\t\tonStateChange,\r\n\t\tinitialScrollPosition,\r\n\t\tonScrollPositionChange,\r\n\t\t// `scrollableContainer` option is deprecated.\r\n\t\t// Use `getScrollableContainer()` option instead.\r\n\t\tscrollableContainer,\r\n\t\tmeasureItemsBatchSize = 50,\r\n\t\tgetColumnsCount,\r\n\t\tgetItemId,\r\n\t\ttbody,\r\n\t\t// `estimatedItemHeight` is deprecated, use `getEstimatedItemHeight()` instead.\r\n\t\testimatedItemHeight,\r\n\t\tgetEstimatedVisibleItemRowsCount,\r\n\t\tonItemInitialRender,\r\n\t\t// `onItemFirstRender(i)` is deprecated, use `onItemInitialRender(item)` instead.\r\n\t\tonItemFirstRender,\r\n\t\t_useTimeoutInRenderLoop,\r\n\t\t_waitForScrollingToStop,\r\n\t\tengine\r\n\t} = options\r\n\r\n\tlet {\r\n\t\tbypass,\r\n\t\tgetEstimatedItemHeight,\r\n\t\tgetScrollableContainer\r\n\t} = options\r\n\r\n\tlog('~ Initialize ~')\r\n\r\n\t// Could support non-DOM rendering engines.\r\n\t// For example, React Native, `<canvas/>`, etc.\r\n\tthis.engine = engine || DOMEngine\r\n\r\n\tif (!getEstimatedItemHeight && typeof estimatedItemHeight === 'number') {\r\n\t\tgetEstimatedItemHeight = () => estimatedItemHeight\r\n\t}\r\n\r\n\t// `scrollableContainer` option is deprecated.\r\n\t// Use `getScrollableContainer()` option instead.\r\n\tif (!getScrollableContainer && scrollableContainer) {\r\n\t\tgetScrollableContainer = () => scrollableContainer\r\n\t}\r\n\r\n\t// Sometimes, when `new VirtualScroller()` instance is created,\r\n\t// `getItemsContainerElement()` might not be ready to return the \"container\" DOM Element yet\r\n\t// (for example, because it's not rendered yet). That's the reason why it's a getter function.\r\n\t// For example, in React `<VirtualScroller/>` component, a `VirtualScroller`\r\n\t// instance is created in the React component's `constructor()`, and at that time\r\n\t// the container Element is not yet available. The container Element is available\r\n\t// in `componentDidMount()`, but `componentDidMount()` is not executed on server,\r\n\t// which would mean that React `<VirtualScroller/>` wouldn't render at all\r\n\t// on server side, while with the `getItemsContainerElement()` approach, on server side,\r\n\t// it still \"renders\" a list with a predefined amount of items in it by default.\r\n\t// (`initiallyRenderedItemsCount`, or `1`).\r\n\tthis.getItemsContainerElement = getItemsContainerElement\r\n\r\n\t// if (prerenderMargin === undefined) {\r\n\t// \t// Renders items which are outside of the screen by this \"prerender margin\".\r\n\t// \t// Is the screen height by default: seems to be the optimal value\r\n\t// \t// for \"Page Up\" / \"Page Down\" navigation and optimized mouse wheel scrolling.\r\n\t// \tprerenderMargin = this.scrollableContainer ? this.scrollableContainer.getHeight() : 0\r\n\t// }\r\n\r\n\tif (options.getState || options.setState) {\r\n\t\tthrow new Error('[virtual-scroller] `getState`/`setState` options usage has changed in the new version. See the readme for more details.')\r\n\t}\r\n\r\n\t// Work around `<tbody/>` not being able to have `padding`.\r\n\t// https://gitlab.com/catamphetamine/virtual-scroller/-/issues/1\r\n\tif (tbody) {\r\n\t\tif (this.engine !== DOMEngine) {\r\n\t\t\tthrow new Error('[virtual-scroller] `tbody` option is only supported for DOM rendering engine')\r\n\t\t}\r\n\t\tlog('~ <tbody/> detected ~')\r\n\t\tthis.tbody = true\r\n\t\tif (!supportsTbody()) {\r\n\t\t\tlog('~ <tbody/> not supported ~')\r\n\t\t\treportError(BROWSER_NOT_SUPPORTED_ERROR)\r\n\t\t\tbypass = true\r\n\t\t}\r\n\t}\r\n\r\n\tif (bypass) {\r\n\t\tlog('~ \"bypass\" mode ~')\r\n\t}\r\n\r\n\t// In `bypass` mode, `VirtualScroller` doesn't wait\r\n\t// for the user to scroll down to render all items:\r\n\t// instead, it renders all items right away, as if\r\n\t// the list is rendered without using `VirtualScroller`.\r\n\t// It was added just to measure how much is the\r\n\t// performance difference between using a `VirtualScroller`\r\n\t// and not using a `VirtualScroller`.\r\n\t// It turned out that unmounting large React component trees\r\n\t// is a very long process, so `VirtualScroller` does seem to\r\n\t// make sense when used in a React application.\r\n\tthis.bypass = bypass\r\n\t// this.bypassBatchSize = bypassBatchSize || 10\r\n\r\n\t// Using `setTimeout()` in render loop is a workaround\r\n\t// for avoiding a React error message:\r\n\t// \"Maximum update depth exceeded.\r\n\t// This can happen when a component repeatedly calls\r\n\t// `.setState()` inside `componentWillUpdate()` or `componentDidUpdate()`.\r\n\t// React limits the number of nested updates to prevent infinite loops.\"\r\n\tthis._useTimeoutInRenderLoop = _useTimeoutInRenderLoop\r\n\r\n\tif (getItemId) {\r\n\t\tthis.isItemEqual = (a, b) => getItemId(a) === getItemId(b)\r\n\t} else {\r\n\t\tthis.isItemEqual = (a, b) => a === b\r\n\t}\r\n\r\n\tif (onItemInitialRender) {\r\n\t\tthis.onItemInitialRender = onItemInitialRender\r\n\t}\r\n\t// `onItemFirstRender(i)` is deprecated, use `onItemInitialRender(item)` instead.\r\n\telse if (onItemFirstRender) {\r\n\t\tthis.onItemInitialRender = (item) => {\r\n\t\t\twarn('`onItemFirstRender(i)` is deprecated, use `onItemInitialRender(item)` instead.')\r\n\t\t\tconst { items } = this.getState()\r\n\t\t\tconst i = items.indexOf(item)\r\n\t\t\t// The `item` could also be non-found due to the inconsistency bug:\r\n\t\t\t// The reason is that `i` can be non-consistent with the `items`\r\n\t\t\t// passed to `<VirtualScroller/>` in React due to `updateState()` not being\r\n\t\t\t// instanteneous: when new `items` are passed to `<VirtualScroller/>`,\r\n\t\t\t// `VirtualScroller.updateState({ items })` is called, and if `onItemFirstRender(i)`\r\n\t\t\t// is called after the aforementioned `updateState()` is called but before it finishes,\r\n\t\t\t// `i` would point to an index in \"previous\" `items` while the application\r\n\t\t\t// would assume that `i` points to an index in the \"new\" `items`,\r\n\t\t\t// resulting in an incorrect item being assumed by the application\r\n\t\t\t// or even in an \"array index out of bounds\" error.\r\n\t\t\tif (i >= 0) {\r\n\t\t\t\tonItemFirstRender(i)\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t// If initial `state` is passed then use `items` from `state`\r\n\t// instead of the `items` argument.\r\n\tif (state) {\r\n\t\titems = state.items\r\n\t}\r\n\r\n\tlog('Items count', items.length)\r\n\tif (getEstimatedItemHeight) {\r\n\t\tlog('Estimated item height', getEstimatedItemHeight())\r\n\t}\r\n\r\n\tcreateStateHelpers.call(this, { state, getInitialItemState, onStateChange, render, items })\r\n\r\n\tcreateVerticalSpacingHelpers.call(this)\r\n\tcreateColumnsHelpers.call(this, { getColumnsCount })\r\n\r\n\tcreateLayoutHelpers.call(this)\r\n\tcreateOnRenderHelpers.call(this)\r\n\tcreateResizeHelpers.call(this)\r\n\tcreateItemsHelpers.call(this)\r\n\r\n\tcreateHelpers.call(this, {\r\n\t\tgetScrollableContainer,\r\n\t\tgetEstimatedItemHeight,\r\n\t\tgetEstimatedVisibleItemRowsCount,\r\n\t\tmeasureItemsBatchSize,\r\n\t\tinitialScrollPosition,\r\n\t\tonScrollPositionChange,\r\n\t\twaitForScrollingToStop: _waitForScrollingToStop\r\n\t})\r\n\r\n\tif (state) {\r\n\t\t// Initialize `ItemHeights` from previously measured `state.itemHeights`.\r\n\t\tthis.itemHeights.readItemHeightsFromState(state)\r\n\r\n\t\t// Initialize some `BeforeResize` internal flags from a previously saved state.\r\n\t\tthis.beforeResize.initializeFromState(state)\r\n\t}\r\n}\r\n\r\nfunction createHelpers({\r\n\tgetScrollableContainer,\r\n\tgetEstimatedItemHeight,\r\n\tgetEstimatedVisibleItemRowsCount,\r\n\tmeasureItemsBatchSize,\r\n\tinitialScrollPosition,\r\n\tonScrollPositionChange,\r\n\twaitForScrollingToStop\r\n}) {\r\n\tthis.itemsContainer = this.engine.createItemsContainer(\r\n\t\tthis.getItemsContainerElement\r\n\t)\r\n\r\n\t// If the items \"container\" element is mounted at this stage,\r\n\t// remove any accidental text nodes from it (like whitespace).\r\n\t//\r\n\t// Also, this guards against cases when someone accidentally tries\r\n\t// using `VirtualScroller` on a non-empty element.\r\n\t//\r\n\tif (this.getItemsContainerElement()) {\r\n\t\tthis.itemsContainer.clear()\r\n\t}\r\n\r\n\tthis.scrollableContainer = this.engine.createScrollableContainer(\r\n\t\tgetScrollableContainer,\r\n\t\tthis.getItemsContainerElement\r\n\t)\r\n\r\n\t// Create `ItemHeights` instance.\r\n\tthis.itemHeights = new ItemHeights({\r\n\t\tcontainer: this.itemsContainer,\r\n\t\tgetItemHeight: (i) => this.getState().itemHeights[i],\r\n\t\tsetItemHeight: (i, height) => this.getState().itemHeights[i] = height\r\n\t})\r\n\r\n\tthis.layout = new Layout({\r\n\t\tbypass: this.bypass,\r\n\t\tgetInitialEstimatedItemHeight: getEstimatedItemHeight,\r\n\t\tgetInitialEstimatedVisibleItemRowsCount: getEstimatedVisibleItemRowsCount,\r\n\t\tmeasureItemsBatchSize,\r\n\t\tgetPrerenderMargin: () => this.getPrerenderMargin(),\r\n\t\tgetVerticalSpacing: () => this.getVerticalSpacing(),\r\n\t\tgetVerticalSpacingBeforeResize: () => this.getVerticalSpacingBeforeResize(),\r\n\t\tgetColumnsCount: () => this.getColumnsCount(),\r\n\t\tgetColumnsCountBeforeResize: () => this.getState().beforeResize && this.getState().beforeResize.columnsCount,\r\n\t\tgetItemHeight: (i) => this.getState().itemHeights[i],\r\n\t\tgetItemHeightBeforeResize: (i) => this.getState().beforeResize && this.getState().beforeResize.itemHeights[i],\r\n\t\tgetBeforeResizeItemsCount: () => this.getState().beforeResize ? this.getState().beforeResize.itemHeights.length : 0,\r\n\t\tgetAverageItemHeight: () => this.itemHeights.getAverage(),\r\n\t\t// `this.scrollableContainer` is gonna be `undefined` during server-side rendering.\r\n\t\t// https://gitlab.com/catamphetamine/virtual-scroller/-/issues/30\r\n\t\tgetMaxVisibleAreaHeight: () => this.scrollableContainer && this.scrollableContainer.getHeight(),\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\tgetPreviouslyCalculatedLayout: () => this.previouslyCalculatedLayout\r\n\t})\r\n\r\n\tthis.resize = new Resize({\r\n\t\tbypass: this.bypass,\r\n\t\tgetWidth: () => this.scrollableContainer.getWidth(),\r\n\t\tgetHeight: () => this.scrollableContainer.getHeight(),\r\n\t\tlistenForResize: (listener) => this.scrollableContainer.onResize(listener),\r\n\t\tonResizeStart: () => {\r\n\t\t\tlog('~ Scrollable container resize started ~')\r\n\t\t\tthis._isResizing = true\r\n\t\t},\r\n\t\tonResizeStop: () => {\r\n\t\t\tlog('~ Scrollable container resize finished ~')\r\n\t\t\tthis._isResizing = undefined\r\n\t\t},\r\n\t\tonNoChange: () => {\r\n\t\t\t// There might have been some missed `this.onUpdateShownItemIndexes()` calls\r\n\t\t\t// due to setting `this._isResizing` flag to `true` during the resize.\r\n\t\t\t// So, update shown item indexes just in case.\r\n\t\t\tthis.onUpdateShownItemIndexes({\r\n\t\t\t\treason: LAYOUT_REASON.VIEWPORT_SIZE_UNCHANGED\r\n\t\t\t})\r\n\t\t},\r\n\t\tonHeightChange: () => this.onUpdateShownItemIndexes({\r\n\t\t\treason: LAYOUT_REASON.VIEWPORT_HEIGHT_CHANGED\r\n\t\t}),\r\n\t\tonWidthChange: (prevWidth, newWidth) => {\r\n\t\t\tlog('~ Scrollable container width changed from', prevWidth, 'to', newWidth, '~')\r\n\t\t\tthis.onResize()\r\n\t\t}\r\n\t})\r\n\r\n\tthis.scroll = new Scroll({\r\n\t\tbypass: this.bypass,\r\n\t\tscrollableContainer: this.scrollableContainer,\r\n\t\titemsContainer: this.itemsContainer,\r\n\t\twaitForScrollingToStop,\r\n\t\tonScroll: ({ delayed } = {}) => {\r\n\t\t\tthis.onUpdateShownItemIndexes({\r\n\t\t\t\treason: delayed ? LAYOUT_REASON.STOPPED_SCROLLING : LAYOUT_REASON.SCROLL\r\n\t\t\t})\r\n\t\t},\r\n\t\tinitialScrollPosition,\r\n\t\tonScrollPositionChange,\r\n\t\tisImmediateLayoutScheduled: () => Boolean(this.layoutTimer),\r\n\t\thasNonRenderedItemsAtTheTop: () => this.getState().firstShownItemIndex > 0,\r\n\t\thasNonRenderedItemsAtTheBottom: () => this.getState().lastShownItemIndex < this.getItemsCount() - 1,\r\n\t\tgetLatestLayoutVisibleArea: () => this.latestLayoutVisibleArea,\r\n\t\tgetListTopOffset: this.getListTopOffsetInsideScrollableContainer,\r\n\t\tgetPrerenderMargin: () => this.getPrerenderMargin()\r\n\t})\r\n\r\n\tthis.listHeightMeasurement = new ListHeightMeasurement({\r\n\t\titemsContainer: this.itemsContainer,\r\n\t\tgetListTopOffset: this.getListTopOffsetInsideScrollableContainer\r\n\t})\r\n\r\n\tif (this.engine.watchListTopOffset) {\r\n\t\tthis.listTopOffsetWatcher = this.engine.watchListTopOffset({\r\n\t\t\tgetListTopOffset: this.getListTopOffsetInsideScrollableContainer,\r\n\t\t\tonListTopOffsetChange: ({ reason }) => this.onUpdateShownItemIndexes({\r\n\t\t\t\treason: LAYOUT_REASON.TOP_OFFSET_CHANGED\r\n\t\t\t})\r\n\t\t})\r\n\t}\r\n\r\n\tthis.beforeResize = new BeforeResize({\r\n\t\tgetState: this.getState,\r\n\t\tgetVerticalSpacing: this.getVerticalSpacing,\r\n\t\tgetColumnsCount: this.getColumnsCount\r\n\t})\r\n}"],"mappings":"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"}
|
|
@@ -11,6 +11,8 @@ var _debug = _interopRequireWildcard(require("./utility/debug.js"));
|
|
|
11
11
|
|
|
12
12
|
var _getItemsDiff = _interopRequireDefault(require("./getItemsDiff.js"));
|
|
13
13
|
|
|
14
|
+
var _fillArray = _interopRequireDefault(require("./utility/fillArray.js"));
|
|
15
|
+
|
|
14
16
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
|
15
17
|
|
|
16
18
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
@@ -97,11 +99,9 @@ function _default() {
|
|
|
97
99
|
if (prependedItemsCount > 0) {
|
|
98
100
|
(0, _debug["default"])('Prepend', prependedItemsCount, 'items');
|
|
99
101
|
itemHeights = new Array(prependedItemsCount).concat(itemHeights);
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
} // Restore scroll position after prepending items (if requested).
|
|
104
|
-
|
|
102
|
+
itemStates = (0, _fillArray["default"])(new Array(prependedItemsCount), function (i) {
|
|
103
|
+
return _this.getInitialItemState(newItems[i]);
|
|
104
|
+
}).concat(itemStates); // Restore scroll position after prepending items (if requested).
|
|
105
105
|
|
|
106
106
|
if (shouldRestoreScrollPosition) {
|
|
107
107
|
(0, _debug["default"])('Will restore scroll position');
|
|
@@ -146,10 +146,9 @@ function _default() {
|
|
|
146
146
|
if (appendedItemsCount > 0) {
|
|
147
147
|
(0, _debug["default"])('Append', appendedItemsCount, 'items');
|
|
148
148
|
itemHeights = itemHeights.concat(new Array(appendedItemsCount));
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
}
|
|
149
|
+
itemStates = itemStates.concat((0, _fillArray["default"])(new Array(appendedItemsCount), function (i) {
|
|
150
|
+
return _this.getInitialItemState(newItems[prependedItemsCount + previousItems.length + i]);
|
|
151
|
+
}));
|
|
153
152
|
}
|
|
154
153
|
|
|
155
154
|
itemsUpdateInfo = {
|
|
@@ -162,7 +161,9 @@ function _default() {
|
|
|
162
161
|
(0, _debug["default"])('New items', newItems); // Reset item heights and item states.
|
|
163
162
|
|
|
164
163
|
itemHeights = new Array(newItems.length);
|
|
165
|
-
itemStates = new Array(newItems.length)
|
|
164
|
+
itemStates = (0, _fillArray["default"])(new Array(newItems.length), function (i) {
|
|
165
|
+
return _this.getInitialItemState(newItems[i]);
|
|
166
|
+
});
|
|
166
167
|
layoutUpdate = _this.layout.getInitialLayoutValues({
|
|
167
168
|
itemsCount: newItems.length,
|
|
168
169
|
columnsCount: _this.getActualColumnsCount()
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VirtualScroller.items.js","names":["getItemsCount","getState","items","length","_setItems","newItems","options","previousItems","itemStates","widthHasChanged","stateUpdate","itemHeights","log","layoutUpdate","itemsUpdateInfo","itemsDiff","getItemsDiff","firstShownItemIndex","lastShownItemIndex","beforeItemsHeight","afterItemsHeight","shouldRestoreScrollPosition","preserveScrollPositionOnPrependItems","preserveScrollPosition","prependedItemsCount","appendedItemsCount","shouldResetGridLayout","layout","getLayoutUpdateForItemsDiff","itemsCount","columnsCount","getActualColumnsCount","onResetGridLayout","Array","concat","listHeightMeasurement","snapshotListHeightBeforeAddingNewItems","firstNonMeasuredItemIndex","undefined","getInitialLayoutValues","prepend","append","reset","replace","onBeforeShowItems","newItemsWillBeRendered","count","newState","beforeResize","shouldIncludeBeforeResizeValuesInState","shouldDiscardBeforeResizeItemHeights","_isSettingNewItems","updateState","isItemEqual"],"sources":["../source/VirtualScroller.items.js"],"sourcesContent":["import log, { isDebug } from './utility/debug.js'\r\nimport getItemsDiff from './getItemsDiff.js'\r\n\r\nexport default function() {\r\n\tthis.getItemsCount = () => {\r\n\t\treturn this.getState().items.length\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\tthis._setItems = (newItems, options = {}) => {\r\n\t\tconst {\r\n\t\t\titems: previousItems\r\n\t\t} = this.getState()\r\n\r\n\t\t// Even if `newItems` are equal to `this.state.items`,\r\n\t\t// still perform a `updateState()` call, because, if `updateState()` calls\r\n\t\t// were \"asynchronous\", there could be a situation when a developer\r\n\t\t// first calls `setItems(newItems)` and then `setItems(oldItems)`:\r\n\t\t// if this function did `return` `if (newItems === this.state.items)`\r\n\t\t// then `updateState({ items: newItems })` would be scheduled as part of\r\n\t\t// `setItems(newItems)` call, but the subsequent `setItems(oldItems)` call\r\n\t\t// wouldn't do anything resulting in `newItems` being set as a result,\r\n\t\t// and that wouldn't be what the developer intended.\r\n\r\n\t\tlet { itemStates } = this.getState()\r\n\t\tlet { itemHeights } = this.widthHasChanged\r\n\t\t\t? this.widthHasChanged.stateUpdate\r\n\t\t\t: this.getState()\r\n\r\n\t\tlog('~ Update items ~')\r\n\r\n\t\tlet layoutUpdate\r\n\t\tlet itemsUpdateInfo\r\n\r\n\t\t// Compare the new items to the current items.\r\n\t\tconst itemsDiff = this.getItemsDiff(previousItems, newItems)\r\n\r\n\t\t// See if it's an \"incremental\" items update.\r\n\t\tif (itemsDiff) {\r\n\t\t\tconst {\r\n\t\t\t\tfirstShownItemIndex,\r\n\t\t\t\tlastShownItemIndex,\r\n\t\t\t\tbeforeItemsHeight,\r\n\t\t\t\tafterItemsHeight\r\n\t\t\t} = this.widthHasChanged\r\n\t\t\t\t? this.widthHasChanged.stateUpdate\r\n\t\t\t\t: this.getState()\r\n\r\n\t\t\tconst shouldRestoreScrollPosition = firstShownItemIndex === 0 &&\r\n\t\t\t\t// `preserveScrollPosition` option name is deprecated,\r\n\t\t\t\t// use `preserveScrollPositionOnPrependItems` instead.\r\n\t\t\t\t(options.preserveScrollPositionOnPrependItems || options.preserveScrollPosition)\r\n\r\n\t\t\tconst {\r\n\t\t\t\tprependedItemsCount,\r\n\t\t\t\tappendedItemsCount\r\n\t\t\t} = itemsDiff\r\n\r\n\t\t\tlet shouldResetGridLayout\r\n\r\n\t\t\tlayoutUpdate = this.layout.getLayoutUpdateForItemsDiff({\r\n\t\t\t\tfirstShownItemIndex,\r\n\t\t\t\tlastShownItemIndex,\r\n\t\t\t\tbeforeItemsHeight,\r\n\t\t\t\tafterItemsHeight\r\n\t\t\t}, {\r\n\t\t\t\tprependedItemsCount,\r\n\t\t\t\tappendedItemsCount\r\n\t\t\t}, {\r\n\t\t\t\titemsCount: newItems.length,\r\n\t\t\t\tcolumnsCount: this.getActualColumnsCount(),\r\n\t\t\t\tshouldRestoreScrollPosition,\r\n\t\t\t\tonResetGridLayout: () => shouldResetGridLayout = true\r\n\t\t\t})\r\n\r\n\t\t\tif (prependedItemsCount > 0) {\r\n\t\t\t\tlog('Prepend', prependedItemsCount, 'items')\r\n\r\n\t\t\t\titemHeights = new Array(prependedItemsCount).concat(itemHeights)\r\n\r\n\t\t\t\tif (itemStates) {\r\n\t\t\t\t\titemStates = new Array(prependedItemsCount).concat(itemStates)\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Restore scroll position after prepending items (if requested).\r\n\t\t\t\tif (shouldRestoreScrollPosition) {\r\n\t\t\t\t\tlog('Will restore scroll position')\r\n\t\t\t\t\tthis.listHeightMeasurement.snapshotListHeightBeforeAddingNewItems({\r\n\t\t\t\t\t\tpreviousItems,\r\n\t\t\t\t\t\tnewItems,\r\n\t\t\t\t\t\tprependedItemsCount\r\n\t\t\t\t\t})\r\n\t\t\t\t\t// \"Seamless prepend\" scenario doesn't result in a re-layout,\r\n\t\t\t\t\t// so if any \"non measured item\" is currently pending,\r\n\t\t\t\t\t// it doesn't get reset and will be handled after `state` is updated.\r\n\t\t\t\t\tif (this.firstNonMeasuredItemIndex !== undefined) {\r\n\t\t\t\t\t\tthis.firstNonMeasuredItemIndex += prependedItemsCount\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\tlog('Reset layout')\r\n\t\t\t\t\tif (shouldResetGridLayout) {\r\n\t\t\t\t\t\tlog('Reason: Prepended items count', prependedItemsCount, 'is not divisible by Columns Count', this.getActualColumnsCount())\r\n\t\t\t\t\t\t// Reset item heights because the whole grid is going to be rebalanced\r\n\t\t\t\t\t\t// and re-rendered in a different configuration.\r\n\t\t\t\t\t\titemHeights = new Array(newItems.length)\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\t// Reset layout because none of the prepended items have been measured.\r\n\t\t\t\t\t\tlog('Reason: Prepended items\\' heights are unknown')\r\n\t\t\t\t\t}\r\n\t\t\t\t\tlayoutUpdate = this.layout.getInitialLayoutValues({\r\n\t\t\t\t\t\titemsCount: newItems.length,\r\n\t\t\t\t\t\tcolumnsCount: this.getActualColumnsCount()\r\n\t\t\t\t\t})\r\n\t\t\t\t\t// Unschedule a potentially scheduled layout update\r\n\t\t\t\t\t// after measuring a previously non-measured item\r\n\t\t\t\t\t// because the list will be re-layout anyway\r\n\t\t\t\t\t// due to the new items being set.\r\n\t\t\t\t\tthis.firstNonMeasuredItemIndex = undefined\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (appendedItemsCount > 0) {\r\n\t\t\t\tlog('Append', appendedItemsCount, 'items')\r\n\t\t\t\titemHeights = itemHeights.concat(new Array(appendedItemsCount))\r\n\t\t\t\tif (itemStates) {\r\n\t\t\t\t\titemStates = itemStates.concat(new Array(appendedItemsCount))\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\titemsUpdateInfo = {\r\n\t\t\t\tprepend: prependedItemsCount > 0,\r\n\t\t\t\tappend: appendedItemsCount > 0\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tlog('Items have changed, and', (itemsDiff ? 'a re-layout from scratch has been requested.' : 'it\\'s not a simple append and/or prepend.'), 'Rerender the entire list from scratch.')\r\n\t\t\tlog('Previous items', previousItems)\r\n\t\t\tlog('New items', newItems)\r\n\r\n\t\t\t// Reset item heights and item states.\r\n\t\t\titemHeights = new Array(newItems.length)\r\n\t\t\titemStates = new Array(newItems.length)\r\n\r\n\t\t\tlayoutUpdate = this.layout.getInitialLayoutValues({\r\n\t\t\t\titemsCount: newItems.length,\r\n\t\t\t\tcolumnsCount: this.getActualColumnsCount()\r\n\t\t\t})\r\n\r\n\t\t\t// Unschedule a potentially scheduled layout update\r\n\t\t\t// after measuring a previously non-measured item\r\n\t\t\t// because the list will be re-layout from scratch\r\n\t\t\t// due to the new items being set.\r\n\t\t\tthis.firstNonMeasuredItemIndex = undefined\r\n\r\n\t\t\t// Also reset any potential pending scroll position restoration.\r\n\t\t\t// For example, imagine a developer first called `.setItems(incrementalItemsUpdate)`\r\n\t\t\t// and then called `.setItems(differentItems)` and there was no state update\r\n\t\t\t// in between those two calls. This could happen because state updates aren't\r\n\t\t\t// required to be \"synchronous\". On other words, calling `this.updateState()`\r\n\t\t\t// doesn't necessarily mean that the state is applied immediately.\r\n\t\t\t// Imagine also that such \"delayed\" state updates could be batched,\r\n\t\t\t// like they do in React inside event handlers (though that doesn't apply to this case):\r\n\t\t\t// https://github.com/facebook/react/issues/10231#issuecomment-316644950\r\n\t\t\t// If `this.listHeightMeasurement` wasn't reset on `.setItems(differentItems)`\r\n\t\t\t// and if the second `this.updateState()` call overwrites the first one\r\n\t\t\t// then it would attempt to restore scroll position in a situation when\r\n\t\t\t// it should no longer do that. Hence the reset here.\r\n\t\t\tthis.listHeightMeasurement.reset()\r\n\r\n\t\t\titemsUpdateInfo = {\r\n\t\t\t\treplace: true\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tlog('~ Update state ~')\r\n\r\n\t\t// const layoutValuesAfterUpdate = {\r\n\t\t// \t...this.getState(),\r\n\t\t// \t...layoutUpdate\r\n\t\t// }\r\n\r\n\t\t// `layoutUpdate` is equivalent to `layoutValuesAfterUpdate` because\r\n\t\t// `layoutUpdate` contains all the relevant properties.\r\n\t\tlog('First shown item index', layoutUpdate.firstShownItemIndex)\r\n\t\tlog('Last shown item index', layoutUpdate.lastShownItemIndex)\r\n\t\tlog('Before items height', layoutUpdate.beforeItemsHeight)\r\n\t\tlog('After items height (actual or estimated)', layoutUpdate.afterItemsHeight)\r\n\r\n\t\t// Optionally preload items to be rendered.\r\n\t\t//\r\n\t\t// `layoutUpdate` is equivalent to `layoutValuesAfterUpdate` because\r\n\t\t// `layoutUpdate` contains all the relevant properties.\r\n\t\t//\r\n\t\tthis.onBeforeShowItems(\r\n\t\t\tnewItems,\r\n\t\t\titemHeights,\r\n\t\t\tlayoutUpdate.firstShownItemIndex,\r\n\t\t\tlayoutUpdate.lastShownItemIndex\r\n\t\t)\r\n\r\n\t\t// `this.newItemsWillBeRendered` signals that new `items` are being rendered,\r\n\t\t// and that `VirtualScroller` should temporarily stop all other updates.\r\n\t\t//\r\n\t\t// `this.newItemsWillBeRendered` is cleared in `onRender()`.\r\n\t\t//\r\n\t\t// The values in `this.newItemsWillBeRendered` are used, for example,\r\n\t\t// in `.onResize()` handler in order to not break state consistency when\r\n\t\t// state updates are \"asynchronous\" (delayed) and there's a window resize event\r\n\t\t// in between calling `updateState()` below and that call actually being applied.\r\n\t\t//\r\n\t\tthis.newItemsWillBeRendered = {\r\n\t\t\t...itemsUpdateInfo,\r\n\t\t\tcount: newItems.length,\r\n\t\t\t// `layoutUpdate` now contains all layout-related properties, even if those that\r\n\t\t\t// didn't change. So `firstShownItemIndex` is always in `this.newItemsWillBeRendered`.\r\n\t\t\tlayout: layoutUpdate\r\n\t\t}\r\n\r\n\t\t// `layoutUpdate` now contains all layout-related properties, even if those that\r\n\t\t// didn't change. So this part is no longer relevant.\r\n\t\t//\r\n\t\t// // If `firstShownItemIndex` is gonna be modified as a result of setting new items\r\n\t\t// // then keep that \"new\" `firstShownItemIndex` in order for it to be used by\r\n\t\t// // `onResize()` handler when it calculates \"new\" `firstShownItemIndex`\r\n\t\t// // based on the new columns count (corresponding to the new window width).\r\n\t\t// if (layoutUpdate.firstShownItemIndex !== undefined) {\r\n\t\t// \tthis.newItemsWillBeRendered = {\r\n\t\t// \t\t...this.newItemsWillBeRendered,\r\n\t\t// \t\tfirstShownItemIndex: layoutUpdate.firstShownItemIndex\r\n\t\t// \t}\r\n\t\t// }\r\n\r\n\t\t// Update `VirtualScroller` state.\r\n\t\t//\r\n\t\t// This state update should overwrite all the `state` properties\r\n\t\t// that are also updated in the \"on scroll\" handler (`getShownItemIndexes()`):\r\n\t\t//\r\n\t\t// * `firstShownItemIndex`\r\n\t\t// * `lastShownItemIndex`\r\n\t\t// * `beforeItemsHeight`\r\n\t\t// * `afterItemsHeight`\r\n\t\t//\r\n\t\t// That's because this `updateState()` update has a higher priority\r\n\t\t// than that of the \"on scroll\" handler, so it should overwrite\r\n\t\t// any potential state changes dispatched by the \"on scroll\" handler.\r\n\t\t//\r\n\t\tconst newState = {\r\n\t\t\t...layoutUpdate,\r\n\t\t\titems: newItems,\r\n\t\t\titemStates,\r\n\t\t\titemHeights\r\n\t\t}\r\n\r\n\t\t// Introduced `shouldIncludeBeforeResizeValuesInState()` getter just to prevent\r\n\t\t// cluttering `state` with `beforeResize: undefined` property if `beforeResize`\r\n\t\t// hasn't ever been set in `state` previously.\r\n\t\tif (this.beforeResize.shouldIncludeBeforeResizeValuesInState()) {\r\n\t\t\tif (this.shouldDiscardBeforeResizeItemHeights()) {\r\n\t\t\t\t// Reset \"before resize\" item heights because now there're new items prepended\r\n\t\t\t\t// with unknown heights, or completely new items with unknown heights, so\r\n\t\t\t\t// `beforeItemsHeight` value won't be preserved anyway.\r\n\t\t\t\tnewState.beforeResize = undefined\r\n\t\t\t}\r\n\t\t\telse {\r\n\t\t\t\t// Overwrite `beforeResize` property in `state` even if it wasn't modified\r\n\t\t\t\t// because state updates could be \"asynchronous\" and in that case there could be\r\n\t\t\t\t// some previous `updateState()` call from some previous `setItems()` call that\r\n\t\t\t\t// hasn't yet been applied, and that previous call might have scheduled setting\r\n\t\t\t\t// `state.beforeResize` property to `undefined` in order to reset it, but this\r\n\t\t\t\t// next `updateState()` call might not require resetting `state.beforeResize` property\r\n\t\t\t\t// so it should undo resetting it by simply overwriting it with its normal value.\r\n\t\t\t\tnewState.beforeResize = this.widthHasChanged\r\n\t\t\t\t\t? this.widthHasChanged.stateUpdate.beforeResize\r\n\t\t\t\t\t: this.getState().beforeResize\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// `newState` should also overwrite all `state` properties that're updated in `onResize()`\r\n\t\t// because `setItems()`'s state updates always overwrite `onResize()`'s state updates.\r\n\t\t// (The least-priority ones are `onScroll()` state updates, but those're simply skipped\r\n\t\t// if there's a pending `setItems()` or `onResize()` update).\r\n\t\t//\r\n\t\t// `state` property exceptions:\r\n\t\t//\r\n\t\t// `verticalSpacing` property is not updated here because it's fine setting it to\r\n\t\t// `undefined` in `onResize()` — it will simply be re-measured after the component re-renders.\r\n\t\t//\r\n\t\t// `columnsCount` property is also not updated here because by definition it's only\r\n\t\t// updated in `onResize()`.\r\n\r\n\t\t// Render.\r\n\t\tthis._isSettingNewItems = true\r\n\t\tthis.updateState(newState)\r\n\t}\r\n\r\n\tthis.getItemsDiff = (previousItems, newItems) => {\r\n\t\treturn getItemsDiff(previousItems, newItems, this.isItemEqual)\r\n\t}\r\n}"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"VirtualScroller.items.js","names":["getItemsCount","getState","items","length","_setItems","newItems","options","previousItems","itemStates","widthHasChanged","stateUpdate","itemHeights","log","layoutUpdate","itemsUpdateInfo","itemsDiff","getItemsDiff","firstShownItemIndex","lastShownItemIndex","beforeItemsHeight","afterItemsHeight","shouldRestoreScrollPosition","preserveScrollPositionOnPrependItems","preserveScrollPosition","prependedItemsCount","appendedItemsCount","shouldResetGridLayout","layout","getLayoutUpdateForItemsDiff","itemsCount","columnsCount","getActualColumnsCount","onResetGridLayout","Array","concat","fillArray","i","getInitialItemState","listHeightMeasurement","snapshotListHeightBeforeAddingNewItems","firstNonMeasuredItemIndex","undefined","getInitialLayoutValues","prepend","append","reset","replace","onBeforeShowItems","newItemsWillBeRendered","count","newState","beforeResize","shouldIncludeBeforeResizeValuesInState","shouldDiscardBeforeResizeItemHeights","_isSettingNewItems","updateState","isItemEqual"],"sources":["../source/VirtualScroller.items.js"],"sourcesContent":["import log, { isDebug } from './utility/debug.js'\r\nimport getItemsDiff from './getItemsDiff.js'\r\nimport fillArray from './utility/fillArray.js'\r\n\r\nexport default function() {\r\n\tthis.getItemsCount = () => {\r\n\t\treturn this.getState().items.length\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\tthis._setItems = (newItems, options = {}) => {\r\n\t\tconst {\r\n\t\t\titems: previousItems\r\n\t\t} = this.getState()\r\n\r\n\t\t// Even if `newItems` are equal to `this.state.items`,\r\n\t\t// still perform a `updateState()` call, because, if `updateState()` calls\r\n\t\t// were \"asynchronous\", there could be a situation when a developer\r\n\t\t// first calls `setItems(newItems)` and then `setItems(oldItems)`:\r\n\t\t// if this function did `return` `if (newItems === this.state.items)`\r\n\t\t// then `updateState({ items: newItems })` would be scheduled as part of\r\n\t\t// `setItems(newItems)` call, but the subsequent `setItems(oldItems)` call\r\n\t\t// wouldn't do anything resulting in `newItems` being set as a result,\r\n\t\t// and that wouldn't be what the developer intended.\r\n\r\n\t\tlet { itemStates } = this.getState()\r\n\t\tlet { itemHeights } = this.widthHasChanged\r\n\t\t\t? this.widthHasChanged.stateUpdate\r\n\t\t\t: this.getState()\r\n\r\n\t\tlog('~ Update items ~')\r\n\r\n\t\tlet layoutUpdate\r\n\t\tlet itemsUpdateInfo\r\n\r\n\t\t// Compare the new items to the current items.\r\n\t\tconst itemsDiff = this.getItemsDiff(previousItems, newItems)\r\n\r\n\t\t// See if it's an \"incremental\" items update.\r\n\t\tif (itemsDiff) {\r\n\t\t\tconst {\r\n\t\t\t\tfirstShownItemIndex,\r\n\t\t\t\tlastShownItemIndex,\r\n\t\t\t\tbeforeItemsHeight,\r\n\t\t\t\tafterItemsHeight\r\n\t\t\t} = this.widthHasChanged\r\n\t\t\t\t? this.widthHasChanged.stateUpdate\r\n\t\t\t\t: this.getState()\r\n\r\n\t\t\tconst shouldRestoreScrollPosition = firstShownItemIndex === 0 &&\r\n\t\t\t\t// `preserveScrollPosition` option name is deprecated,\r\n\t\t\t\t// use `preserveScrollPositionOnPrependItems` instead.\r\n\t\t\t\t(options.preserveScrollPositionOnPrependItems || options.preserveScrollPosition)\r\n\r\n\t\t\tconst {\r\n\t\t\t\tprependedItemsCount,\r\n\t\t\t\tappendedItemsCount\r\n\t\t\t} = itemsDiff\r\n\r\n\t\t\tlet shouldResetGridLayout\r\n\r\n\t\t\tlayoutUpdate = this.layout.getLayoutUpdateForItemsDiff({\r\n\t\t\t\tfirstShownItemIndex,\r\n\t\t\t\tlastShownItemIndex,\r\n\t\t\t\tbeforeItemsHeight,\r\n\t\t\t\tafterItemsHeight\r\n\t\t\t}, {\r\n\t\t\t\tprependedItemsCount,\r\n\t\t\t\tappendedItemsCount\r\n\t\t\t}, {\r\n\t\t\t\titemsCount: newItems.length,\r\n\t\t\t\tcolumnsCount: this.getActualColumnsCount(),\r\n\t\t\t\tshouldRestoreScrollPosition,\r\n\t\t\t\tonResetGridLayout: () => shouldResetGridLayout = true\r\n\t\t\t})\r\n\r\n\t\t\tif (prependedItemsCount > 0) {\r\n\t\t\t\tlog('Prepend', prependedItemsCount, 'items')\r\n\r\n\t\t\t\titemHeights = new Array(prependedItemsCount).concat(itemHeights)\r\n\t\t\t\titemStates = fillArray(\r\n\t\t\t\t\tnew Array(prependedItemsCount),\r\n\t\t\t\t\t(i) => this.getInitialItemState(newItems[i])\r\n\t\t\t\t)\r\n\t\t\t\t\t.concat(itemStates)\r\n\r\n\t\t\t\t// Restore scroll position after prepending items (if requested).\r\n\t\t\t\tif (shouldRestoreScrollPosition) {\r\n\t\t\t\t\tlog('Will restore scroll position')\r\n\t\t\t\t\tthis.listHeightMeasurement.snapshotListHeightBeforeAddingNewItems({\r\n\t\t\t\t\t\tpreviousItems,\r\n\t\t\t\t\t\tnewItems,\r\n\t\t\t\t\t\tprependedItemsCount\r\n\t\t\t\t\t})\r\n\t\t\t\t\t// \"Seamless prepend\" scenario doesn't result in a re-layout,\r\n\t\t\t\t\t// so if any \"non measured item\" is currently pending,\r\n\t\t\t\t\t// it doesn't get reset and will be handled after `state` is updated.\r\n\t\t\t\t\tif (this.firstNonMeasuredItemIndex !== undefined) {\r\n\t\t\t\t\t\tthis.firstNonMeasuredItemIndex += prependedItemsCount\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\tlog('Reset layout')\r\n\t\t\t\t\tif (shouldResetGridLayout) {\r\n\t\t\t\t\t\tlog('Reason: Prepended items count', prependedItemsCount, 'is not divisible by Columns Count', this.getActualColumnsCount())\r\n\t\t\t\t\t\t// Reset item heights because the whole grid is going to be rebalanced\r\n\t\t\t\t\t\t// and re-rendered in a different configuration.\r\n\t\t\t\t\t\titemHeights = new Array(newItems.length)\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\t// Reset layout because none of the prepended items have been measured.\r\n\t\t\t\t\t\tlog('Reason: Prepended items\\' heights are unknown')\r\n\t\t\t\t\t}\r\n\t\t\t\t\tlayoutUpdate = this.layout.getInitialLayoutValues({\r\n\t\t\t\t\t\titemsCount: newItems.length,\r\n\t\t\t\t\t\tcolumnsCount: this.getActualColumnsCount()\r\n\t\t\t\t\t})\r\n\t\t\t\t\t// Unschedule a potentially scheduled layout update\r\n\t\t\t\t\t// after measuring a previously non-measured item\r\n\t\t\t\t\t// because the list will be re-layout anyway\r\n\t\t\t\t\t// due to the new items being set.\r\n\t\t\t\t\tthis.firstNonMeasuredItemIndex = undefined\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (appendedItemsCount > 0) {\r\n\t\t\t\tlog('Append', appendedItemsCount, 'items')\r\n\t\t\t\titemHeights = itemHeights.concat(new Array(appendedItemsCount))\r\n\t\t\t\titemStates = itemStates.concat(\r\n\t\t\t\t\tfillArray(\r\n\t\t\t\t\t\tnew Array(appendedItemsCount),\r\n\t\t\t\t\t\t(i) => this.getInitialItemState(newItems[prependedItemsCount + previousItems.length + i])\r\n\t\t\t\t\t)\r\n\t\t\t\t)\r\n\t\t\t}\r\n\r\n\t\t\titemsUpdateInfo = {\r\n\t\t\t\tprepend: prependedItemsCount > 0,\r\n\t\t\t\tappend: appendedItemsCount > 0\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tlog('Items have changed, and', (itemsDiff ? 'a re-layout from scratch has been requested.' : 'it\\'s not a simple append and/or prepend.'), 'Rerender the entire list from scratch.')\r\n\t\t\tlog('Previous items', previousItems)\r\n\t\t\tlog('New items', newItems)\r\n\r\n\t\t\t// Reset item heights and item states.\r\n\t\t\titemHeights = new Array(newItems.length)\r\n\t\t\titemStates = fillArray(\r\n\t\t\t\tnew Array(newItems.length),\r\n\t\t\t\t(i) => this.getInitialItemState(newItems[i])\r\n\t\t\t)\r\n\r\n\t\t\tlayoutUpdate = this.layout.getInitialLayoutValues({\r\n\t\t\t\titemsCount: newItems.length,\r\n\t\t\t\tcolumnsCount: this.getActualColumnsCount()\r\n\t\t\t})\r\n\r\n\t\t\t// Unschedule a potentially scheduled layout update\r\n\t\t\t// after measuring a previously non-measured item\r\n\t\t\t// because the list will be re-layout from scratch\r\n\t\t\t// due to the new items being set.\r\n\t\t\tthis.firstNonMeasuredItemIndex = undefined\r\n\r\n\t\t\t// Also reset any potential pending scroll position restoration.\r\n\t\t\t// For example, imagine a developer first called `.setItems(incrementalItemsUpdate)`\r\n\t\t\t// and then called `.setItems(differentItems)` and there was no state update\r\n\t\t\t// in between those two calls. This could happen because state updates aren't\r\n\t\t\t// required to be \"synchronous\". On other words, calling `this.updateState()`\r\n\t\t\t// doesn't necessarily mean that the state is applied immediately.\r\n\t\t\t// Imagine also that such \"delayed\" state updates could be batched,\r\n\t\t\t// like they do in React inside event handlers (though that doesn't apply to this case):\r\n\t\t\t// https://github.com/facebook/react/issues/10231#issuecomment-316644950\r\n\t\t\t// If `this.listHeightMeasurement` wasn't reset on `.setItems(differentItems)`\r\n\t\t\t// and if the second `this.updateState()` call overwrites the first one\r\n\t\t\t// then it would attempt to restore scroll position in a situation when\r\n\t\t\t// it should no longer do that. Hence the reset here.\r\n\t\t\tthis.listHeightMeasurement.reset()\r\n\r\n\t\t\titemsUpdateInfo = {\r\n\t\t\t\treplace: true\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tlog('~ Update state ~')\r\n\r\n\t\t// const layoutValuesAfterUpdate = {\r\n\t\t// \t...this.getState(),\r\n\t\t// \t...layoutUpdate\r\n\t\t// }\r\n\r\n\t\t// `layoutUpdate` is equivalent to `layoutValuesAfterUpdate` because\r\n\t\t// `layoutUpdate` contains all the relevant properties.\r\n\t\tlog('First shown item index', layoutUpdate.firstShownItemIndex)\r\n\t\tlog('Last shown item index', layoutUpdate.lastShownItemIndex)\r\n\t\tlog('Before items height', layoutUpdate.beforeItemsHeight)\r\n\t\tlog('After items height (actual or estimated)', layoutUpdate.afterItemsHeight)\r\n\r\n\t\t// Optionally preload items to be rendered.\r\n\t\t//\r\n\t\t// `layoutUpdate` is equivalent to `layoutValuesAfterUpdate` because\r\n\t\t// `layoutUpdate` contains all the relevant properties.\r\n\t\t//\r\n\t\tthis.onBeforeShowItems(\r\n\t\t\tnewItems,\r\n\t\t\titemHeights,\r\n\t\t\tlayoutUpdate.firstShownItemIndex,\r\n\t\t\tlayoutUpdate.lastShownItemIndex\r\n\t\t)\r\n\r\n\t\t// `this.newItemsWillBeRendered` signals that new `items` are being rendered,\r\n\t\t// and that `VirtualScroller` should temporarily stop all other updates.\r\n\t\t//\r\n\t\t// `this.newItemsWillBeRendered` is cleared in `onRender()`.\r\n\t\t//\r\n\t\t// The values in `this.newItemsWillBeRendered` are used, for example,\r\n\t\t// in `.onResize()` handler in order to not break state consistency when\r\n\t\t// state updates are \"asynchronous\" (delayed) and there's a window resize event\r\n\t\t// in between calling `updateState()` below and that call actually being applied.\r\n\t\t//\r\n\t\tthis.newItemsWillBeRendered = {\r\n\t\t\t...itemsUpdateInfo,\r\n\t\t\tcount: newItems.length,\r\n\t\t\t// `layoutUpdate` now contains all layout-related properties, even if those that\r\n\t\t\t// didn't change. So `firstShownItemIndex` is always in `this.newItemsWillBeRendered`.\r\n\t\t\tlayout: layoutUpdate\r\n\t\t}\r\n\r\n\t\t// `layoutUpdate` now contains all layout-related properties, even if those that\r\n\t\t// didn't change. So this part is no longer relevant.\r\n\t\t//\r\n\t\t// // If `firstShownItemIndex` is gonna be modified as a result of setting new items\r\n\t\t// // then keep that \"new\" `firstShownItemIndex` in order for it to be used by\r\n\t\t// // `onResize()` handler when it calculates \"new\" `firstShownItemIndex`\r\n\t\t// // based on the new columns count (corresponding to the new window width).\r\n\t\t// if (layoutUpdate.firstShownItemIndex !== undefined) {\r\n\t\t// \tthis.newItemsWillBeRendered = {\r\n\t\t// \t\t...this.newItemsWillBeRendered,\r\n\t\t// \t\tfirstShownItemIndex: layoutUpdate.firstShownItemIndex\r\n\t\t// \t}\r\n\t\t// }\r\n\r\n\t\t// Update `VirtualScroller` state.\r\n\t\t//\r\n\t\t// This state update should overwrite all the `state` properties\r\n\t\t// that are also updated in the \"on scroll\" handler (`getShownItemIndexes()`):\r\n\t\t//\r\n\t\t// * `firstShownItemIndex`\r\n\t\t// * `lastShownItemIndex`\r\n\t\t// * `beforeItemsHeight`\r\n\t\t// * `afterItemsHeight`\r\n\t\t//\r\n\t\t// That's because this `updateState()` update has a higher priority\r\n\t\t// than that of the \"on scroll\" handler, so it should overwrite\r\n\t\t// any potential state changes dispatched by the \"on scroll\" handler.\r\n\t\t//\r\n\t\tconst newState = {\r\n\t\t\t...layoutUpdate,\r\n\t\t\titems: newItems,\r\n\t\t\titemStates,\r\n\t\t\titemHeights\r\n\t\t}\r\n\r\n\t\t// Introduced `shouldIncludeBeforeResizeValuesInState()` getter just to prevent\r\n\t\t// cluttering `state` with `beforeResize: undefined` property if `beforeResize`\r\n\t\t// hasn't ever been set in `state` previously.\r\n\t\tif (this.beforeResize.shouldIncludeBeforeResizeValuesInState()) {\r\n\t\t\tif (this.shouldDiscardBeforeResizeItemHeights()) {\r\n\t\t\t\t// Reset \"before resize\" item heights because now there're new items prepended\r\n\t\t\t\t// with unknown heights, or completely new items with unknown heights, so\r\n\t\t\t\t// `beforeItemsHeight` value won't be preserved anyway.\r\n\t\t\t\tnewState.beforeResize = undefined\r\n\t\t\t}\r\n\t\t\telse {\r\n\t\t\t\t// Overwrite `beforeResize` property in `state` even if it wasn't modified\r\n\t\t\t\t// because state updates could be \"asynchronous\" and in that case there could be\r\n\t\t\t\t// some previous `updateState()` call from some previous `setItems()` call that\r\n\t\t\t\t// hasn't yet been applied, and that previous call might have scheduled setting\r\n\t\t\t\t// `state.beforeResize` property to `undefined` in order to reset it, but this\r\n\t\t\t\t// next `updateState()` call might not require resetting `state.beforeResize` property\r\n\t\t\t\t// so it should undo resetting it by simply overwriting it with its normal value.\r\n\t\t\t\tnewState.beforeResize = this.widthHasChanged\r\n\t\t\t\t\t? this.widthHasChanged.stateUpdate.beforeResize\r\n\t\t\t\t\t: this.getState().beforeResize\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// `newState` should also overwrite all `state` properties that're updated in `onResize()`\r\n\t\t// because `setItems()`'s state updates always overwrite `onResize()`'s state updates.\r\n\t\t// (The least-priority ones are `onScroll()` state updates, but those're simply skipped\r\n\t\t// if there's a pending `setItems()` or `onResize()` update).\r\n\t\t//\r\n\t\t// `state` property exceptions:\r\n\t\t//\r\n\t\t// `verticalSpacing` property is not updated here because it's fine setting it to\r\n\t\t// `undefined` in `onResize()` — it will simply be re-measured after the component re-renders.\r\n\t\t//\r\n\t\t// `columnsCount` property is also not updated here because by definition it's only\r\n\t\t// updated in `onResize()`.\r\n\r\n\t\t// Render.\r\n\t\tthis._isSettingNewItems = true\r\n\t\tthis.updateState(newState)\r\n\t}\r\n\r\n\tthis.getItemsDiff = (previousItems, newItems) => {\r\n\t\treturn getItemsDiff(previousItems, newItems, this.isItemEqual)\r\n\t}\r\n}"],"mappings":"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"}
|
|
@@ -248,11 +248,18 @@ var VirtualScroller = /*#__PURE__*/function () {
|
|
|
248
248
|
*/
|
|
249
249
|
|
|
250
250
|
}, {
|
|
251
|
-
key: "
|
|
252
|
-
value: function
|
|
251
|
+
key: "setItemState",
|
|
252
|
+
value: function setItemState(i, newItemState) {
|
|
253
253
|
this.hasToBeStarted();
|
|
254
254
|
|
|
255
|
-
this.
|
|
255
|
+
this._setItemState(i, newItemState);
|
|
256
|
+
} // (deprecated)
|
|
257
|
+
// Use `.setItemState()` method name instead.
|
|
258
|
+
|
|
259
|
+
}, {
|
|
260
|
+
key: "onItemStateChange",
|
|
261
|
+
value: function onItemStateChange(i, newItemState) {
|
|
262
|
+
this.setItemState(i, newItemState);
|
|
256
263
|
}
|
|
257
264
|
/**
|
|
258
265
|
* Updates `items`. For example, can prepend or append new items to the list.
|
|
@@ -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","_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","_onItemHeightChange","newItemState","_onItemStateChange","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 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\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 * Forces a re-measure of an item's height.\r\n\t * @param {number} i — Item index\r\n\t */\r\n\tonItemHeightChange(i) {\r\n\t\tthis.hasToBeStarted()\r\n\t\tthis._onItemHeightChange(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\tonItemStateChange(i, newItemState) {\r\n\t\tthis.hasToBeStarted()\r\n\t\tthis._onItemStateChange(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","_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","_onItemHeightChange","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 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\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 * Forces a re-measure of an item's height.\r\n\t * @param {number} i — Item index\r\n\t */\r\n\tonItemHeightChange(i) {\r\n\t\tthis.hasToBeStarted()\r\n\t\tthis._onItemHeightChange(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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"}
|
|
@@ -122,7 +122,7 @@ function _default() {
|
|
|
122
122
|
// or an "Expand YouTube video" button, which would result
|
|
123
123
|
// in the actual height of the list item being different
|
|
124
124
|
// from what has been initially measured in `this.itemHeights[i]`,
|
|
125
|
-
// if the developer didn't call `.
|
|
125
|
+
// if the developer didn't call `.setItemState(i, newState)` and `.onItemHeightChange(i)`.
|
|
126
126
|
|
|
127
127
|
|
|
128
128
|
if (!validateWillBeHiddenItemHeightsAreAccurate.call(this, firstShownItemIndex, lastShownItemIndex)) {
|
|
@@ -281,7 +281,7 @@ function _default() {
|
|
|
281
281
|
* or an "Expand YouTube video" button, which would result
|
|
282
282
|
* in the actual height of the list item being different
|
|
283
283
|
* from what has been initially measured in `this.itemHeights[i]`,
|
|
284
|
-
* if the developer didn't call `.
|
|
284
|
+
* if the developer didn't call `.setItemState(i, newState)` and `.onItemHeightChange(i)`.
|
|
285
285
|
*/
|
|
286
286
|
|
|
287
287
|
|