virtual-scroller
Advanced tools
Comparing version 1.0.18 to 1.0.19
@@ -1,2 +0,2 @@ | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).VirtualScroller=t()}(this,function(){"use strict";function e(t){return(e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(t)}var t=Object.prototype.hasOwnProperty;function n(e,t){return e===t?0!==e||0!==t||1/e==1/t:e!=e&&t!=t}function i(e){var t=e.getBoundingClientRect(),n=document.clientLeft||document.body.clientLeft||0,i=document.clientTop||document.body.clientTop||0,r=window.pageYOffset,o=window.pageXOffset;return{top:t.top+r-i,left:t.left+o-n,width:t.width,height:t.height}}function r(){return window.pageYOffset}function o(){return window.innerHeight}function s(e){return function(e){if(Array.isArray(e)){for(var t=0,n=new Array(e.length);t<e.length;t++)n[t]=e[t];return n}}(e)||function(e){if(Symbol.iterator in Object(e)||"[object Arguments]"===Object.prototype.toString.call(e))return Array.from(e)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance")}()}function a(){if(h()){for(var e,t=arguments.length,n=new Array(t),i=0;i<t;i++)n[i]=arguments[i];(e=console).log.apply(e,s(["[virtual-scroller]"].concat(n)))}}function h(){return"undefined"!=typeof window&&window.VirtualScrollerDebug}function u(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}var d=function(){function e(t,n){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.getContainerNode=t,this.getState=n,this.reset()}var t,n,i;return t=e,(n=[{key:"reset",value:function(){this.measuredItemsHeight=0,this.firstMeasuredItemIndex=void 0,this.lastMeasuredItemIndex=void 0}},{key:"onInitItemHeights",value:function(){this.reset();for(var e=0;e<this.getState().itemHeights.length;){if(null==this.getState().itemHeights[e]){if(void 0!==this.firstMeasuredItemIndex){this.lastMeasuredItemIndex=e-1;break}}else void 0===this.firstMeasuredItemIndex&&(this.firstMeasuredItemIndex=e),this.measuredItemsHeight+=this.getState().itemHeights[e];e++}}},{key:"_getItemHeight",value:function(e,t){var n=this.getContainerNode();if(n){var i=e-t;if(i>=0&&i<n.childNodes.length)return n.childNodes[i].getBoundingClientRect().height}}},{key:"getItemSpacing",value:function(){var e=this.getContainerNode();if(e&&e.childNodes.length>1){var t=e.childNodes[0],n=e.childNodes[1],i=t.getBoundingClientRect(),r=n.getBoundingClientRect().top-(i.top+i.height);return window.VirtualScrollerDebug&&a("Item spacing",r),r}}},{key:"update",value:function(e,t,n){void 0===this.getState().itemSpacing&&(this.getState().itemSpacing=this.getItemSpacing()),void 0!==this.firstMeasuredItemIndex&&(e>this.lastMeasuredItemIndex+1||t<this.firstMeasuredItemIndex-1)&&this.reset();for(var i=this.firstMeasuredItemIndex,r=this.lastMeasuredItemIndex,o=!1,s=e;s<=t;){var a=this._getItemHeight(s,n);void 0!==a&&(this.set(s,a),(void 0===i||s<i)&&(this.measuredItemsHeight+=a,o||(this.firstMeasuredItemIndex=s,o=!0)),(void 0===r||s>r)&&(void 0!==r&&(this.measuredItemsHeight+=a),this.lastMeasuredItemIndex=s)),s++}}},{key:"updateItemHeight",value:function(e,t){var n=this.get(e),i=this._getItemHeight(e,t);void 0!==n&&void 0!==i&&(this.set(e,i),this.measuredItemsHeight+=i-n)}},{key:"getAverage",value:function(){return this.measuredItemsHeight?this.measuredItemsHeight/(this.lastMeasuredItemIndex-this.firstMeasuredItemIndex+1):0}},{key:"get",value:function(e){return this.getState().itemHeights[e]}},{key:"set",value:function(e,t){this.getState().itemHeights[e]=t}},{key:"onPrepend",value:function(e){void 0!==this.firstMeasuredItemIndex&&(this.firstMeasuredItemIndex+=e,this.lastMeasuredItemIndex+=e)}}])&&u(t.prototype,n),i&&u(t,i),e}();function m(e){return e.toFixed(2)+"px"}function l(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{},i=Object.keys(n);"function"==typeof Object.getOwnPropertySymbols&&(i=i.concat(Object.getOwnPropertySymbols(n).filter(function(e){return Object.getOwnPropertyDescriptor(n,e).enumerable}))),i.forEach(function(t){I(e,t,n[t])})}return e}function g(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}function I(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var c=200,f=function(){function s(i,u){var m,g,f,S,v,p=this,y=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,s),I(this,"layout",function(){return p.onUpdateShownItemIndexes({reason:"manual"})}),I(this,"onScroll",function(){return p.onUpdateShownItemIndexes({reason:"scroll"})}),I(this,"onResize",(m=function(){p.setState(p.getInitialLayoutState(),function(){p.onInitialRender("resize")})},g=c,S=0,v=function(){f=void 0,S=Date.now(),m()},function(){var e=Date.now(),t=g-(e-S);t<=0?(f&&(clearTimeout(f),f=void 0),S=e,m()):f||(f=setTimeout(v,t))})),I(this,"updateShownItemIndexes",function(e){var t=p.getShownItemIndexes(),n=t.firstShownItemIndex,i=t.lastShownItemIndex,r=t.redoLayoutAfterRender,o=p.getBeforeItemsHeight(n,i),s=p.getAfterItemsHeight(n,i);p.updateWillBeHiddenItemHeightsAndState(n,i),a("~ Layout results "+(p.bypass?"(bypass) ":"")+"~"),a("First shown item index",n),a("Last shown item index",i),a("Before items height",o),a("After items height",s),a("Average item height (calculated on previous render)",p.itemHeights.getAverage()),h()&&(a("Item heights",p.getState().itemHeights.slice()),a("Item states",p.getState().itemStates.slice())),r&&a("Redo layout after render"),void 0!==p.firstSeenItemIndex&&(n>p.lastSeenItemIndex+1||i<p.firstSeenItemIndex-1)&&(p.firstSeenItemIndex=void 0,p.lastSeenItemIndex=void 0),p.onBeforeShowItems(n,i),p.setState({firstShownItemIndex:n,lastShownItemIndex:i,beforeItemsHeight:o,afterItemsHeight:s},function(){return e(r)})}),I(this,"updateShownItemIndexesRecursive",function(){p.updateShownItemIndexes(function(e){e?setTimeout(function(){p.isMounted?p.updateShownItemIndexesRecursive():p.onDoneUpdatingItemIndexes()},0):p.onDoneUpdatingItemIndexes()})}),I(this,"restoreScroll",function(){var e=p.restoreScrollAfterPrepend,t=e.index,n=e.screenTop;p.restoreScrollAfterPrepend=void 0;var i=p.getItemElement(t).getBoundingClientRect().top-n;0!==i&&(a("Restore scroll position: scroll by",i),window.scrollTo(0,r()+i))}),I(this,"onUpdateShownItemIndexes",function(e){var t=e.reason;e.force;if(0!==p.getItemsCount()&&!p.isUpdatingItemIndexes){if(clearTimeout(p.onUserStopsScrollingTimeout),"scroll"===t){var n=void 0!==p.latestLayoutScreenTopAfterMargin&&r()<p.latestLayoutScreenTopAfterMargin&&p.getState().firstShownItemIndex>0||void 0!==p.latestLayoutScreenBottomAfterMargin&&r()+o()>p.latestLayoutScreenBottomAfterMargin&&p.getState().lastShownItemIndex<p.getItemsCount()-1;if(a(n?"The user has scrolled far enough: force re-render":"The user hasn't scrolled too much: delay re-render"),!n)return p.onUserStopsScrollingTimeout=setTimeout(p.onUserStoppedScrolling,100)}p.updateLayout(t)}}),I(this,"onUserStoppedScrolling",function(){p.isMounted&&p.updateLayout("stopped scrolling")});var w=y.getState,x=y.setState,b=y.onStateChange,H=y.preserveScrollPositionAtBottomOnMount,C=y.bypass,k=y.bypassBatchSize,A=y.estimatedItemHeight,O=y.onItemFirstRender,M=y.state;a("~ Initialize ~"),M&&(u=M.items),this.bypass=C,this.bypassBatchSize=k||10,this.initialItems=u,this.estimatedItemHeight=A,O&&(this.onItemFirstRender=O),i()&&function(e){for(;e.firstChild;)e.removeChild(e.firstChild)}(i()),x?(this.getState=w,this.setState=x):(this.getState=function(){return p.state},this.setState=function(i,r){var o=p.state;p.state=l({},o,i),function(i,r){if(n(i,r))return!0;if("object"!==e(i)||null===i||"object"!==e(r)||null===r)return!1;var o=Object.keys(i),s=Object.keys(r);if(o.length!==s.length)return!1;for(var a=0;a<o.length;a++)if(!t.call(r,o[a])||!n(i[o[a]],r[o[a]]))return!1;return!0}(p.state,o)||(b&&b(p.state,o),p.isMounted&&p.onUpdate(o)),r&&r()}),M&&a("Initial state (passed)",M),this.getContainerNode=i,this.itemHeights=new d(i,this.getState),H&&(this.preserveScrollPositionAtBottomOnMount={documentHeight:document.documentElement.scrollHeight}),this.setState(M||this.getInitialState(),function(){p.itemHeights.onInitItemHeights()}),a("Items count",u.length),A&&a("Estimated item height",A)}var u,m,f;return u=s,(m=[{key:"getInitialState",value:function(e){var t=this.initialItems.length,n=l({},e,this.getInitialLayoutState(),{items:this.initialItems,itemStates:new Array(t)});return a("Initial state (created)",n),a("First shown item index",n.firstShownItemIndex),a("Last shown item index",n.lastShownItemIndex),n}},{key:"getInitialLayoutState",value:function(){var e,t,n=this.initialItems.length;return n>0&&(e=Math.min(0,n-1),t=this.getLastShownItemIndex(e,n)),this.preserveScrollPositionAtBottomOnMount&&(e=0,t=n-1),this.onBeforeShowItems(e,t),{itemHeights:new Array(n),itemSpacing:void 0,beforeItemsHeight:0,afterItemsHeight:0,firstShownItemIndex:e,lastShownItemIndex:t}}},{key:"getEstimatedItemHeight",value:function(){return this.itemHeights&&this.itemHeights.getAverage()||this.estimatedItemHeight||0}},{key:"getItemSpacing",value:function(){return this.getState().itemSpacing||0}},{key:"getEstimatedItemsCount",value:function(e){return this.getEstimatedItemHeight()?Math.ceil((e+this.getItemSpacing())/(this.getEstimatedItemHeight()+this.getItemSpacing())):1}},{key:"getEstimatedItemsCountOnScreen",value:function(){return"undefined"!=typeof window?this.getEstimatedItemsCount(window.innerHeight):1}},{key:"getLastShownItemIndex",value:function(e,t){return Math.min(e+(this.getEstimatedItemsCountOnScreen()-1),t-1)}},{key:"getItemsCount",value:function(){return this.getState().items.length}},{key:"getMargin",value:function(){return window.innerHeight}},{key:"onBeforeShowItems",value:function(e,t){if(this.onItemFirstRender)if(void 0===this.firstSeenItemIndex){for(var n=e;n<=t;)this.onItemFirstRender(n),n++;this.firstSeenItemIndex=e,this.lastSeenItemIndex=t}else{if(e<this.firstSeenItemIndex){for(var i=e,r=Math.min(t,this.firstSeenItemIndex-1),o=i;o<=r;)this.onItemFirstRender(o),o++;this.firstSeenItemIndex=e}if(t>this.lastSeenItemIndex){for(var s=t,a=Math.max(e,this.lastSeenItemIndex+1);a<=s;)this.onItemFirstRender(a),a++;this.lastSeenItemIndex=t}}}},{key:"onMount",value:function(){this.onInitialRender("mount"),this.isMounted=!0,this.bypass||(window.addEventListener("scroll",this.onScroll),window.addEventListener("resize",this.onResize))}},{key:"onInitialRender",value:function(e){var t=this.getState(),n=t.firstShownItemIndex,i=t.lastShownItemIndex;this.getItemsCount()>0&&this.updateItemHeights(n,i),this.preserveScrollPositionAtBottomOnMount?window.scrollTo(0,window.pageYOffset+(document.documentElement.scrollHeight-this.preserveScrollPositionAtBottomOnMount.documentHeight)):this.onUpdateShownItemIndexes({reason:e})}},{key:"onUnmount",value:function(){this.isMounted=!1,this.bypass||(window.removeEventListener("scroll",this.onScroll),window.removeEventListener("resize",this.onResize),clearTimeout(this.onUserStopsScrollingTimeout),clearTimeout(this.watchContainerElementTopCoordinateTimer))}},{key:"onUpdate",value:function(e){var t=this.getState(),n=t.items,i=t.firstShownItemIndex,r=t.lastShownItemIndex;i===e.firstShownItemIndex&&r===e.lastShownItemIndex&&n===e.items||this.updateItemHeights(i,r)}},{key:"updateItemHeights",value:function(e,t){var n=this.getState().firstShownItemIndex;void 0!==e&&(a("~ Measure item heights after layout ~"),this.itemHeights.update(e,t,n),h()&&a("Item heights",this.getState().itemHeights.slice()))}},{key:"updateItemHeight",value:function(e){var t=this.getState().firstShownItemIndex;this.itemHeights.updateItemHeight(e,t)}},{key:"onItemStateChange",value:function(e,t){h()&&(a("~ Item state changed ~"),a("Item",e),a("Previous state\n"+JSON.stringify(this.getState().itemStates[e],null,2)),a("New state\n"+JSON.stringify(t,null,2))),this.getState().itemStates[e]=t}},{key:"onItemHeightChange",value:function(e){var t=this.getState().itemHeights,n=t[e];this.updateItemHeight(e);var i=t[e];n!==i&&(a("~ Item height changed ~"),a("Item",e),a("Previous height",n),a("New height",i),this.onUpdateShownItemIndexes({reason:"item height change"}))}},{key:"getItemCoordinates",value:function(e){for(var t=i(this.getContainerNode()).top,n=0;n<e;)t+=this.getState().itemHeights[n],t+=this.getItemSpacing(),n++;return{top:t,bottom:t+this.getState().itemHeights[e],height:this.getState().itemHeights[n]}}},{key:"getVisibleItemIndexes",value:function(e,t,n){for(var i,r,o=0,s=!1,h=0;h<this.getItemsCount();){var u=this.itemHeights.get(h);if(void 0===u){a("Item ".concat(h," height hasn't been measured yet: render and redo layout")),void 0===i&&(i=h);var d=t-(n+o);r=Math.min(h+(this.getEstimatedItemsCount(d)-1),this.getItemsCount()-1),s=!0;break}if(o+=u,void 0===i&&n+o>e&&(a("First visible item index (including margin)",h),i=h),h<this.getItemsCount()-1&&(o+=this.getItemSpacing()),n+o>t){a("Last visible item index (including margin)",h),void 0!==i&&(r=h);break}h++}return void 0!==i&&void 0===r&&a("Last item index (is fully visible)",r=this.getItemsCount()-1),this.restoreScrollAfterPrepend&&(r<this.restoreScrollAfterPrepend.index&&(r=this.restoreScrollAfterPrepend.index),s=!1),{firstShownItemIndex:i,lastShownItemIndex:r,redoLayoutAfterRender:s}}},{key:"getOffscreenListShownItemIndexes",value:function(){return{firstShownItemIndex:0,lastShownItemIndex:0,redoLayoutAfterRender:void 0===this.itemHeights.get(0)}}},{key:"getItemIndexes",value:function(e,t,n,i){if(!(i>e&&n<t))return this.getOffscreenListShownItemIndexes();var r=this.getVisibleItemIndexes(e,t,n);return void 0===r.firstShownItemIndex?this.getOffscreenListShownItemIndexes():r}},{key:"getBeforeItemsHeight",value:function(e,t){for(var n=0,i=0;i<e;)n+=this.itemHeights.get(i)||this.itemHeights.getAverage(),n+=this.getItemSpacing(),i++;return n}},{key:"getAfterItemsHeight",value:function(e,t){for(var n=0,i=t+1;i<this.getItemsCount();)n+=this.getItemSpacing(),n+=this.itemHeights.get(i)||this.itemHeights.getAverage(),i++;return n}},{key:"updateWillBeHiddenItemHeightsAndState",value:function(e,t){for(var n=this.getState().firstShownItemIndex;n<=this.getState().lastShownItemIndex;)n>=e&&n<=t||this.updateItemHeight(n),n++}},{key:"watchContainerElementTopCoordinate",value:function(){var e=this,t=Date.now();!function n(){void 0!==e.top&&i(e.getContainerNode()).top!==e.top&&e.onUpdateShownItemIndexes({reason:"top offset change"});Date.now()-t<3e3&&(e.watchContainerElementTopCoordinateTimer=setTimeout(n,500))}()}},{key:"getShownItemIndexes",value:function(){if(this.bypass){var e=this.getState().firstShownItemIndex,t=this.getState().lastShownItemIndex;return{firstShownItemIndex:e,lastShownItemIndex:t=Math.min(t+this.bypassBatchSize,this.getItemsCount()-1),redoLayoutAfterRender:t<this.getItemsCount()-1}}var n=i(this.getContainerNode()),s=n.top,a=n.height;void 0===this.top&&this.watchContainerElementTopCoordinate(),this.top=s;var h=function(){var e=o();return{top:r(),bottom:r()+e,height:e}}(),u=h.top,d=h.bottom;return this.latestLayoutScreenTopAfterMargin=u-this.getMargin(),this.latestLayoutScreenBottomAfterMargin=d+this.getMargin(),this.getItemIndexes(u-this.getMargin(),d+this.getMargin(),s,s+a)}},{key:"onDoneUpdatingItemIndexes",value:function(){this.isUpdatingItemIndexes=!1,this.restoreScrollAfterPrepend&&this.restoreScroll()}},{key:"captureScroll",value:function(e,t,n){0!==e.length&&(void 0===n&&(n=t.indexOf(e[0])),n<0||0!==n&&(this.getState().firstShownItemIndex>0||this.restoreScrollAfterPrepend&&this.restoreScrollAfterPrepend.previousItems===e&&this.restoreScrollAfterPrepend.nextItems===t||(this.restoreScrollAfterPrepend={previousItems:e,nextItems:t,index:n,screenTop:this.getItemElement(0).getBoundingClientRect().top})))}},{key:"updateLayout",value:function(e){a("~ Update layout (".concat(e,") ~")),this.isUpdatingItemIndexes=!0,this.updateShownItemIndexesRecursive()}},{key:"updateItems",value:function(e,t){return this.setItems(e,t)}},{key:"setItems",value:function(e){var t=this,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=this.getState().items,r=this.getState(),o=r.firstShownItemIndex,s=r.lastShownItemIndex,h=r.beforeItemsHeight,u=r.afterItemsHeight,d=r.itemStates,m=r.itemHeights;r.itemSpacing;a("~ Update items ~");var g=function(e,t){var n=-1,i=-1;e.length>0&&(n=t.indexOf(e[0]))>=0&&function(e,t,n){var i=0;for(;i<e.length;){if(t.length<=n+i||t[n+i]!==e[i])return!1;i++}return!0}(e,t,n)&&(i=n+e.length-1);if(n>=0&&i>=0)return{prependedItemsCount:n,appendedItemsCount:t.length-(i+1)};return{prependedItemsCount:-1,appendedItemsCount:-1}}(i,e),I=g.prependedItemsCount,c=g.appendedItemsCount,f=I>0||c>0;f?(I>0&&(a("Prepended items count",I),m=new Array(I).concat(m),this.itemHeights.onPrepend(I),d&&(d=new Array(I).concat(d)),(n.preserveScrollPositionOnPrependItems||n.preserveScrollPosition)&&this.captureScroll(i,e,I)),c>0&&(a("Appended items count",c),m=m.concat(new Array(c)),d&&(d=d.concat(new Array(c)))),void 0!==this.firstSeenItemIndex&&(this.firstSeenItemIndex+=I,this.lastSeenItemIndex+=I),o+=I,s+=I,h+=this.itemHeights.getAverage()*I,u+=this.itemHeights.getAverage()*c):(a("Non-incremental items update"),a("Previous items",i),a("New items",e),m=new Array(e.length),d=new Array(e.length),this.firstSeenItemIndex=void 0,this.lastSeenItemIndex=void 0,0===e.length?(o=void 0,s=void 0):(o=0,s=this.getLastShownItemIndex(o,e.length)),h=0,u=0),a("First shown item index",o),a("Last shown item index",s),a("Before items height",h),a("After items height",u),this.onBeforeShowItems(o,s),this.setState(l({},void 0,{items:e,itemStates:d,itemHeights:m,firstShownItemIndex:o,lastShownItemIndex:s,beforeItemsHeight:h,afterItemsHeight:u}),function(){f||t.itemHeights.onInitItemHeights(),t.onUpdateShownItemIndexes({reason:"update items",force:!0})})}},{key:"getItemElement",value:function(e){return this.getContainerNode().childNodes[e]}}])&&g(u.prototype,m),f&&g(u,f),s}();function S(e,t){if(null==e)return{};var n,i,r=function(e,t){if(null==e)return{};var n,i,r={},o=Object.keys(e);for(i=0;i<o.length;i++)n=o[i],t.indexOf(n)>=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i<o.length;i++)n=o[i],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}function v(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}function p(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}return function(){function e(t,n,i){var r=this,o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),p(this,"onStateChange",function(e,t){var n=e.items,i=e.firstShownItemIndex,o=e.lastShownItemIndex,s=e.beforeItemsHeight,h=e.afterItemsHeight;a("~ On state change ~"),a("Previous state",t),a("New state",e),r.container.style.paddingTop=m(s),r.container.style.paddingBottom=m(h);var u=t&&n===t.items&&t.items.length>0;if(u){a("Incremental render");for(var d=t.lastShownItemIndex;d>=t.firstShownItemIndex;){if(d>=i&&d<=o);else{a("Remove item",d);var l=r.container.childNodes[d-t.firstShownItemIndex];r.container.removeChild(l)}d--}}else for(a("Clean render");r.container.firstChild;)r.container.removeChild(r.container.firstChild);for(var g=u,I=g&&r.container.firstChild,c=i;c<=o;){if(u&&c>=t.firstShownItemIndex&&c<=t.lastShownItemIndex)g&&(g=!1);else{var f=r.renderItem(n[c]);g?(a("Prepend item",c),r.container.insertBefore(f,I)):(a("Append item",c),r.container.appendChild(f))}c++}}),p(this,"onUnmount",function(){r.virtualScroller.onUnmount()}),this.container=t,this.renderItem=i;var s=o.onMount,h=S(o,["onMount"]);this.virtualScroller=new f(function(){return r.container},n,function(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{},i=Object.keys(n);"function"==typeof Object.getOwnPropertySymbols&&(i=i.concat(Object.getOwnPropertySymbols(n).filter(function(e){return Object.getOwnPropertyDescriptor(n,e).enumerable}))),i.forEach(function(t){p(e,t,n[t])})}return e}({},h,{onStateChange:this.onStateChange})),s&&s(),this.virtualScroller.onMount()}var t,n,i;return t=e,(n=[{key:"onItemHeightChange",value:function(e){this.virtualScroller.onItemHeightChange(e)}},{key:"updateItems",value:function(e,t){this.setItems(e,t)}},{key:"setItems",value:function(e,t){this.virtualScroller.setItems(e,t)}},{key:"getItemCoordinates",value:function(e){return this.virtualScroller.getItemCoordinates(e)}}])&&v(t.prototype,n),i&&v(t,i),e}()}); | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).VirtualScroller=t()}(this,function(){"use strict";function e(t){return(e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(t)}var t=Object.prototype.hasOwnProperty;function n(e,t){return e===t?0!==e||0!==t||1/e==1/t:e!=e&&t!=t}function i(e){var t=e.getBoundingClientRect(),n=document.clientLeft||document.body.clientLeft||0,i=document.clientTop||document.body.clientTop||0,r=window.pageYOffset,o=window.pageXOffset;return{top:t.top+r-i,left:t.left+o-n,width:t.width,height:t.height}}function r(){return window.pageYOffset}function o(){return window.innerHeight}function s(e){return function(e){if(Array.isArray(e)){for(var t=0,n=new Array(e.length);t<e.length;t++)n[t]=e[t];return n}}(e)||function(e){if(Symbol.iterator in Object(e)||"[object Arguments]"===Object.prototype.toString.call(e))return Array.from(e)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance")}()}function a(){if(h()){for(var e,t=arguments.length,n=new Array(t),i=0;i<t;i++)n[i]=arguments[i];(e=console).log.apply(e,s(["[virtual-scroller]"].concat(n)))}}function h(){return"undefined"!=typeof window&&window.VirtualScrollerDebug}function u(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}var d=function(){function e(t,n){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.getContainerNode=t,this.getState=n,this.reset()}var t,n,i;return t=e,(n=[{key:"reset",value:function(){this.measuredItemsHeight=0,this.firstMeasuredItemIndex=void 0,this.lastMeasuredItemIndex=void 0}},{key:"onInitItemHeights",value:function(){this.reset();for(var e=0;e<this.getState().itemHeights.length;){if(null==this.getState().itemHeights[e]){if(void 0!==this.firstMeasuredItemIndex){this.lastMeasuredItemIndex=e-1;break}}else void 0===this.firstMeasuredItemIndex&&(this.firstMeasuredItemIndex=e),this.measuredItemsHeight+=this.getState().itemHeights[e];e++}}},{key:"_getItemHeight",value:function(e,t){var n=this.getContainerNode();if(n){var i=e-t;if(i>=0&&i<n.childNodes.length)return n.childNodes[i].getBoundingClientRect().height}}},{key:"getItemSpacing",value:function(){var e=this.getContainerNode();if(e&&e.childNodes.length>1){var t=e.childNodes[0],n=e.childNodes[1],i=t.getBoundingClientRect(),r=n.getBoundingClientRect().top-(i.top+i.height);return window.VirtualScrollerDebug&&a("Item spacing",r),r}}},{key:"update",value:function(e,t,n){void 0===this.getState().itemSpacing&&(this.getState().itemSpacing=this.getItemSpacing()),void 0!==this.firstMeasuredItemIndex&&(e>this.lastMeasuredItemIndex+1||t<this.firstMeasuredItemIndex-1)&&this.reset();for(var i=this.firstMeasuredItemIndex,r=this.lastMeasuredItemIndex,o=!1,s=e;s<=t;){var a=this._getItemHeight(s,n);void 0!==a&&(this.set(s,a),(void 0===i||s<i)&&(this.measuredItemsHeight+=a,o||(this.firstMeasuredItemIndex=s,o=!0)),(void 0===r||s>r)&&(void 0!==r&&(this.measuredItemsHeight+=a),this.lastMeasuredItemIndex=s)),s++}}},{key:"updateItemHeight",value:function(e,t){var n=this.get(e),i=this._getItemHeight(e,t);void 0!==n&&void 0!==i&&(this.set(e,i),this.measuredItemsHeight+=i-n)}},{key:"getAverage",value:function(){return this.measuredItemsHeight?this.measuredItemsHeight/(this.lastMeasuredItemIndex-this.firstMeasuredItemIndex+1):0}},{key:"get",value:function(e){return this.getState().itemHeights[e]}},{key:"set",value:function(e,t){this.getState().itemHeights[e]=t}},{key:"onPrepend",value:function(e){void 0!==this.firstMeasuredItemIndex&&(this.firstMeasuredItemIndex+=e,this.lastMeasuredItemIndex+=e)}}])&&u(t.prototype,n),i&&u(t,i),e}();function m(e){return e.toFixed(2)+"px"}function l(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{},i=Object.keys(n);"function"==typeof Object.getOwnPropertySymbols&&(i=i.concat(Object.getOwnPropertySymbols(n).filter(function(e){return Object.getOwnPropertyDescriptor(n,e).enumerable}))),i.forEach(function(t){I(e,t,n[t])})}return e}function g(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}function I(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var c=200,f=function(){function s(i,u){var m,g,f,S,v,p=this,y=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,s),I(this,"layout",function(){return p.onUpdateShownItemIndexes({reason:"manual"})}),I(this,"onScroll",function(){return p.onUpdateShownItemIndexes({reason:"scroll"})}),I(this,"onResize",(m=function(){p.setState(p.getInitialLayoutState(),function(){p.onInitialRender("resize")})},g=c,S=0,v=function(){f=void 0,S=Date.now(),m()},function(){var e=Date.now(),t=g-(e-S);t<=0?(f&&(clearTimeout(f),f=void 0),S=e,m()):f||(f=setTimeout(v,t))})),I(this,"updateShownItemIndexes",function(e){var t=p.getShownItemIndexes(),n=t.firstShownItemIndex,i=t.lastShownItemIndex,r=t.redoLayoutAfterRender,o=p.getBeforeItemsHeight(n,i),s=p.getAfterItemsHeight(n,i);p.updateWillBeHiddenItemHeightsAndState(n,i),a("~ Layout results "+(p.bypass?"(bypass) ":"")+"~"),a("First shown item index",n),a("Last shown item index",i),a("Before items height",o),a("After items height",s),a("Average item height (calculated on previous render)",p.itemHeights.getAverage()),h()&&(a("Item heights",p.getState().itemHeights.slice()),a("Item states",p.getState().itemStates.slice())),r&&a("Redo layout after render"),void 0!==p.firstSeenItemIndex&&(n>p.lastSeenItemIndex+1||i<p.firstSeenItemIndex-1)&&(p.firstSeenItemIndex=void 0,p.lastSeenItemIndex=void 0),p.onBeforeShowItems(n,i),p.setState({firstShownItemIndex:n,lastShownItemIndex:i,beforeItemsHeight:o,afterItemsHeight:s},function(){return e(r)})}),I(this,"updateShownItemIndexesRecursive",function(){p.updateShownItemIndexes(function(e){e?setTimeout(function(){p.isMounted?p.updateShownItemIndexesRecursive():p.onDoneUpdatingItemIndexes()},0):p.onDoneUpdatingItemIndexes()})}),I(this,"restoreScroll",function(){var e=p.restoreScrollAfterPrepend,t=e.index,n=e.screenTop;p.restoreScrollAfterPrepend=void 0;var i=p.getItemElement(t).getBoundingClientRect().top-n;0!==i&&(a("Restore scroll position: scroll by",i),window.scrollTo(0,r()+i))}),I(this,"onUpdateShownItemIndexes",function(e){var t=e.reason;e.force;if(0!==p.getItemsCount()&&!p.isUpdatingItemIndexes){if(clearTimeout(p.onUserStopsScrollingTimeout),"scroll"===t){var n=void 0!==p.latestLayoutScreenTopAfterMargin&&r()<p.latestLayoutScreenTopAfterMargin&&p.getState().firstShownItemIndex>0||void 0!==p.latestLayoutScreenBottomAfterMargin&&r()+o()>p.latestLayoutScreenBottomAfterMargin&&p.getState().lastShownItemIndex<p.getItemsCount()-1;if(a(n?"The user has scrolled far enough: force re-render":"The user hasn't scrolled too much: delay re-render"),!n)return p.onUserStopsScrollingTimeout=setTimeout(p.onUserStoppedScrolling,100)}p.updateLayout(t)}}),I(this,"onUserStoppedScrolling",function(){p.isMounted&&p.updateLayout("stopped scrolling")});var w=y.getState,x=y.setState,b=y.onStateChange,H=y.preserveScrollPositionAtBottomOnMount,C=y.measureItemsBatchSize,k=y.bypass,A=y.bypassBatchSize,O=y.estimatedItemHeight,M=y.onItemFirstRender,P=y.state;a("~ Initialize ~"),P&&(u=P.items),this.bypass=k,this.bypassBatchSize=A||10,this.initialItems=u,this.estimatedItemHeight=O,this.measureItemsBatchSize=void 0===C?50:C,M&&(this.onItemFirstRender=M),i()&&function(e){for(;e.firstChild;)e.removeChild(e.firstChild)}(i()),x?(this.getState=w,this.setState=x):(this.getState=function(){return p.state},this.setState=function(i,r){var o=p.state;p.state=l({},o,i),function(i,r){if(n(i,r))return!0;if("object"!==e(i)||null===i||"object"!==e(r)||null===r)return!1;var o=Object.keys(i),s=Object.keys(r);if(o.length!==s.length)return!1;for(var a=0;a<o.length;a++)if(!t.call(r,o[a])||!n(i[o[a]],r[o[a]]))return!1;return!0}(p.state,o)||(b&&b(p.state,o),p.isMounted&&p.onUpdate(o)),r&&r()}),P&&a("Initial state (passed)",P),this.getContainerNode=i,this.itemHeights=new d(i,this.getState),H&&(this.preserveScrollPositionAtBottomOnMount={documentHeight:document.documentElement.scrollHeight}),this.setState(P||this.getInitialState(),function(){p.itemHeights.onInitItemHeights()}),a("Items count",u.length),O&&a("Estimated item height",O)}var u,m,f;return u=s,(m=[{key:"getInitialState",value:function(e){var t=this.initialItems.length,n=l({},e,this.getInitialLayoutState(),{items:this.initialItems,itemStates:new Array(t)});return a("Initial state (created)",n),a("First shown item index",n.firstShownItemIndex),a("Last shown item index",n.lastShownItemIndex),n}},{key:"getInitialLayoutState",value:function(){var e,t,n=this.initialItems.length;return n>0&&(e=Math.min(0,n-1),t=this.getLastShownItemIndex(e,n)),this.preserveScrollPositionAtBottomOnMount&&(e=0,t=n-1),this.onBeforeShowItems(e,t),{itemHeights:new Array(n),itemSpacing:void 0,beforeItemsHeight:0,afterItemsHeight:0,firstShownItemIndex:e,lastShownItemIndex:t}}},{key:"getEstimatedItemHeight",value:function(){return this.itemHeights&&this.itemHeights.getAverage()||this.estimatedItemHeight||0}},{key:"getItemSpacing",value:function(){return this.getState().itemSpacing||0}},{key:"getEstimatedItemsCount",value:function(e){return this.getEstimatedItemHeight()?Math.ceil((e+this.getItemSpacing())/(this.getEstimatedItemHeight()+this.getItemSpacing())):1}},{key:"getEstimatedItemsCountOnScreen",value:function(){return"undefined"!=typeof window?this.getEstimatedItemsCount(window.innerHeight):1}},{key:"getLastShownItemIndex",value:function(e,t){return Math.min(e+(this.getEstimatedItemsCountOnScreen()-1),t-1)}},{key:"getItemsCount",value:function(){return this.getState().items.length}},{key:"getMargin",value:function(){return window.innerHeight}},{key:"onBeforeShowItems",value:function(e,t){if(this.onItemFirstRender)if(void 0===this.firstSeenItemIndex){for(var n=e;n<=t;)this.onItemFirstRender(n),n++;this.firstSeenItemIndex=e,this.lastSeenItemIndex=t}else{if(e<this.firstSeenItemIndex){for(var i=e,r=Math.min(t,this.firstSeenItemIndex-1),o=i;o<=r;)this.onItemFirstRender(o),o++;this.firstSeenItemIndex=e}if(t>this.lastSeenItemIndex){for(var s=t,a=Math.max(e,this.lastSeenItemIndex+1);a<=s;)this.onItemFirstRender(a),a++;this.lastSeenItemIndex=t}}}},{key:"onMount",value:function(){this.onInitialRender("mount"),this.isMounted=!0,this.bypass||(window.addEventListener("scroll",this.onScroll),window.addEventListener("resize",this.onResize))}},{key:"onInitialRender",value:function(e){var t=this.getState(),n=t.firstShownItemIndex,i=t.lastShownItemIndex;this.getItemsCount()>0&&this.updateItemHeights(n,i),this.preserveScrollPositionAtBottomOnMount?window.scrollTo(0,window.pageYOffset+(document.documentElement.scrollHeight-this.preserveScrollPositionAtBottomOnMount.documentHeight)):this.onUpdateShownItemIndexes({reason:e})}},{key:"onUnmount",value:function(){this.isMounted=!1,this.bypass||(window.removeEventListener("scroll",this.onScroll),window.removeEventListener("resize",this.onResize),clearTimeout(this.onUserStopsScrollingTimeout),clearTimeout(this.watchContainerElementTopCoordinateTimer))}},{key:"onUpdate",value:function(e){var t=this.getState(),n=t.items,i=t.firstShownItemIndex,r=t.lastShownItemIndex;i===e.firstShownItemIndex&&r===e.lastShownItemIndex&&n===e.items||this.updateItemHeights(i,r)}},{key:"updateItemHeights",value:function(e,t){var n=this.getState().firstShownItemIndex;void 0!==e&&(a("~ Measure item heights after layout ~"),this.itemHeights.update(e,t,n),h()&&a("Item heights",this.getState().itemHeights.slice()))}},{key:"updateItemHeight",value:function(e){var t=this.getState().firstShownItemIndex;this.itemHeights.updateItemHeight(e,t)}},{key:"onItemStateChange",value:function(e,t){h()&&(a("~ Item state changed ~"),a("Item",e),a("Previous state\n"+JSON.stringify(this.getState().itemStates[e],null,2)),a("New state\n"+JSON.stringify(t,null,2))),this.getState().itemStates[e]=t}},{key:"onItemHeightChange",value:function(e){var t=this.getState().itemHeights,n=t[e];this.updateItemHeight(e);var i=t[e];n!==i&&(a("~ Item height changed ~"),a("Item",e),a("Previous height",n),a("New height",i),this.onUpdateShownItemIndexes({reason:"item height change"}))}},{key:"getItemCoordinates",value:function(e){for(var t=i(this.getContainerNode()).top,n=0;n<e;)t+=this.getState().itemHeights[n],t+=this.getItemSpacing(),n++;return{top:t,bottom:t+this.getState().itemHeights[e],height:this.getState().itemHeights[n]}}},{key:"getVisibleItemIndexes",value:function(e,t,n){for(var i,r,o=0,s=!1,h=0;h<this.getItemsCount();){var u=this.itemHeights.get(h);if(void 0===u){a("Item ".concat(h," height hasn't been measured yet: render and redo layout")),void 0===i&&(i=h);var d=t-(n+o);r=Math.min(h+(this.getEstimatedItemsCount(d)-1),this.getItemsCount()-1),s=!0;break}if(o+=u,void 0===i&&n+o>e&&(a("First visible item index (including margin)",h),i=h),h<this.getItemsCount()-1&&(o+=this.getItemSpacing()),n+o>t){a("Last visible item index (including margin)",h),void 0!==i&&(r=h);break}h++}return void 0!==i&&void 0===r&&a("Last item index (is fully visible)",r=this.getItemsCount()-1),this.restoreScrollAfterPrepend&&(r<this.restoreScrollAfterPrepend.index&&(r=this.restoreScrollAfterPrepend.index),s=!1),s&&this.measureItemsBatchSize&&(r=Math.min(r,i+this.measureItemsBatchSize)),{firstShownItemIndex:i,lastShownItemIndex:r,redoLayoutAfterRender:s}}},{key:"getOffscreenListShownItemIndexes",value:function(){return{firstShownItemIndex:0,lastShownItemIndex:0,redoLayoutAfterRender:void 0===this.itemHeights.get(0)}}},{key:"getItemIndexes",value:function(e,t,n,i){if(!(i>e&&n<t))return this.getOffscreenListShownItemIndexes();var r=this.getVisibleItemIndexes(e,t,n);return void 0===r.firstShownItemIndex?this.getOffscreenListShownItemIndexes():r}},{key:"getBeforeItemsHeight",value:function(e,t){for(var n=0,i=0;i<e;)n+=this.itemHeights.get(i)||this.itemHeights.getAverage(),n+=this.getItemSpacing(),i++;return n}},{key:"getAfterItemsHeight",value:function(e,t){for(var n=0,i=t+1;i<this.getItemsCount();)n+=this.getItemSpacing(),n+=this.itemHeights.get(i)||this.itemHeights.getAverage(),i++;return n}},{key:"updateWillBeHiddenItemHeightsAndState",value:function(e,t){for(var n=this.getState().firstShownItemIndex;n<=this.getState().lastShownItemIndex;)n>=e&&n<=t||this.updateItemHeight(n),n++}},{key:"watchContainerElementTopCoordinate",value:function(){var e=this,t=Date.now();!function n(){void 0!==e.top&&i(e.getContainerNode()).top!==e.top&&e.onUpdateShownItemIndexes({reason:"top offset change"});Date.now()-t<3e3&&(e.watchContainerElementTopCoordinateTimer=setTimeout(n,500))}()}},{key:"getShownItemIndexes",value:function(){if(this.bypass){var e=this.getState().firstShownItemIndex,t=this.getState().lastShownItemIndex;return{firstShownItemIndex:e,lastShownItemIndex:t=Math.min(t+this.bypassBatchSize,this.getItemsCount()-1),redoLayoutAfterRender:t<this.getItemsCount()-1}}var n=i(this.getContainerNode()),s=n.top,a=n.height;void 0===this.top&&this.watchContainerElementTopCoordinate(),this.top=s;var h=function(){var e=o();return{top:r(),bottom:r()+e,height:e}}(),u=h.top,d=h.bottom;return this.latestLayoutScreenTopAfterMargin=u-this.getMargin(),this.latestLayoutScreenBottomAfterMargin=d+this.getMargin(),this.getItemIndexes(u-this.getMargin(),d+this.getMargin(),s,s+a)}},{key:"onDoneUpdatingItemIndexes",value:function(){this.isUpdatingItemIndexes=!1,this.restoreScrollAfterPrepend&&this.restoreScroll()}},{key:"captureScroll",value:function(e,t,n){0!==e.length&&(void 0===n&&(n=t.indexOf(e[0])),n<0||0!==n&&(this.getState().firstShownItemIndex>0||this.restoreScrollAfterPrepend&&this.restoreScrollAfterPrepend.previousItems===e&&this.restoreScrollAfterPrepend.nextItems===t||(this.restoreScrollAfterPrepend={previousItems:e,nextItems:t,index:n,screenTop:this.getItemElement(0).getBoundingClientRect().top})))}},{key:"updateLayout",value:function(e){a("~ Update layout (".concat(e,") ~")),this.isUpdatingItemIndexes=!0,this.updateShownItemIndexesRecursive()}},{key:"updateItems",value:function(e,t){return this.setItems(e,t)}},{key:"setItems",value:function(e){var t=this,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=this.getState().items,r=this.getState(),o=r.firstShownItemIndex,s=r.lastShownItemIndex,h=r.beforeItemsHeight,u=r.afterItemsHeight,d=r.itemStates,m=r.itemHeights;r.itemSpacing;a("~ Update items ~");var g=function(e,t){var n=-1,i=-1;e.length>0&&(n=t.indexOf(e[0]))>=0&&function(e,t,n){var i=0;for(;i<e.length;){if(t.length<=n+i||t[n+i]!==e[i])return!1;i++}return!0}(e,t,n)&&(i=n+e.length-1);if(n>=0&&i>=0)return{prependedItemsCount:n,appendedItemsCount:t.length-(i+1)};return{prependedItemsCount:-1,appendedItemsCount:-1}}(i,e),I=g.prependedItemsCount,c=g.appendedItemsCount,f=I>0||c>0;f?(I>0&&(a("Prepended items count",I),m=new Array(I).concat(m),this.itemHeights.onPrepend(I),d&&(d=new Array(I).concat(d)),(n.preserveScrollPositionOnPrependItems||n.preserveScrollPosition)&&this.captureScroll(i,e,I)),c>0&&(a("Appended items count",c),m=m.concat(new Array(c)),d&&(d=d.concat(new Array(c)))),void 0!==this.firstSeenItemIndex&&(this.firstSeenItemIndex+=I,this.lastSeenItemIndex+=I),o+=I,s+=I,h+=this.itemHeights.getAverage()*I,u+=this.itemHeights.getAverage()*c):(a("Non-incremental items update"),a("Previous items",i),a("New items",e),m=new Array(e.length),d=new Array(e.length),this.firstSeenItemIndex=void 0,this.lastSeenItemIndex=void 0,0===e.length?(o=void 0,s=void 0):(o=0,s=this.getLastShownItemIndex(o,e.length)),h=0,u=0),a("First shown item index",o),a("Last shown item index",s),a("Before items height",h),a("After items height",u),this.onBeforeShowItems(o,s),this.setState(l({},void 0,{items:e,itemStates:d,itemHeights:m,firstShownItemIndex:o,lastShownItemIndex:s,beforeItemsHeight:h,afterItemsHeight:u}),function(){f||t.itemHeights.onInitItemHeights(),t.onUpdateShownItemIndexes({reason:"update items",force:!0})})}},{key:"getItemElement",value:function(e){return this.getContainerNode().childNodes[e]}}])&&g(u.prototype,m),f&&g(u,f),s}();function S(e,t){if(null==e)return{};var n,i,r=function(e,t){if(null==e)return{};var n,i,r={},o=Object.keys(e);for(i=0;i<o.length;i++)n=o[i],t.indexOf(n)>=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i<o.length;i++)n=o[i],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}function v(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}function p(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}return function(){function e(t,n,i){var r=this,o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),p(this,"onStateChange",function(e,t){var n=e.items,i=e.firstShownItemIndex,o=e.lastShownItemIndex,s=e.beforeItemsHeight,h=e.afterItemsHeight;a("~ On state change ~"),a("Previous state",t),a("New state",e),r.container.style.paddingTop=m(s),r.container.style.paddingBottom=m(h);var u=t&&n===t.items&&t.items.length>0;if(u){a("Incremental render");for(var d=t.lastShownItemIndex;d>=t.firstShownItemIndex;){if(d>=i&&d<=o);else{a("Remove item",d);var l=r.container.childNodes[d-t.firstShownItemIndex];r.container.removeChild(l)}d--}}else for(a("Clean render");r.container.firstChild;)r.container.removeChild(r.container.firstChild);for(var g=u,I=g&&r.container.firstChild,c=i;c<=o;){if(u&&c>=t.firstShownItemIndex&&c<=t.lastShownItemIndex)g&&(g=!1);else{var f=r.renderItem(n[c]);g?(a("Prepend item",c),r.container.insertBefore(f,I)):(a("Append item",c),r.container.appendChild(f))}c++}}),p(this,"onUnmount",function(){r.virtualScroller.onUnmount()}),this.container=t,this.renderItem=i;var s=o.onMount,h=S(o,["onMount"]);this.virtualScroller=new f(function(){return r.container},n,function(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{},i=Object.keys(n);"function"==typeof Object.getOwnPropertySymbols&&(i=i.concat(Object.getOwnPropertySymbols(n).filter(function(e){return Object.getOwnPropertyDescriptor(n,e).enumerable}))),i.forEach(function(t){p(e,t,n[t])})}return e}({},h,{onStateChange:this.onStateChange})),s&&s(),this.virtualScroller.onMount()}var t,n,i;return t=e,(n=[{key:"onItemHeightChange",value:function(e){this.virtualScroller.onItemHeightChange(e)}},{key:"updateItems",value:function(e,t){this.setItems(e,t)}},{key:"setItems",value:function(e,t){this.virtualScroller.setItems(e,t)}},{key:"getItemCoordinates",value:function(e){return this.virtualScroller.getItemCoordinates(e)}}])&&v(t.prototype,n),i&&v(t,i),e}()}); | ||
//# sourceMappingURL=virtual-scroller-dom.js.map |
@@ -1,2 +0,2 @@ | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("react"),require("prop-types")):"function"==typeof define&&define.amd?define(["react","prop-types"],t):(e=e||self).VirtualScroller=t(e.React,e.PropTypes)}(this,function(e,t){"use strict";function n(e){return(n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}e=e&&e.hasOwnProperty("default")?e.default:e,t=t&&t.hasOwnProperty("default")?t.default:t;var i=Object.prototype.hasOwnProperty;function r(e,t){return e===t?0!==e||0!==t||1/e==1/t:e!=e&&t!=t}function o(e,t){if(r(e,t))return!0;if("object"!==n(e)||null===e||"object"!==n(t)||null===t)return!1;var o=Object.keys(e),s=Object.keys(t);if(o.length!==s.length)return!1;for(var a=0;a<o.length;a++)if(!i.call(t,o[a])||!r(e[o[a]],t[o[a]]))return!1;return!0}function s(e){var t=e.getBoundingClientRect(),n=document.clientLeft||document.body.clientLeft||0,i=document.clientTop||document.body.clientTop||0,r=window.pageYOffset,o=window.pageXOffset;return{top:t.top+r-i,left:t.left+o-n,width:t.width,height:t.height}}function a(){return window.pageYOffset}function h(){return window.innerHeight}function u(e){return function(e){if(Array.isArray(e)){for(var t=0,n=new Array(e.length);t<e.length;t++)n[t]=e[t];return n}}(e)||function(e){if(Symbol.iterator in Object(e)||"[object Arguments]"===Object.prototype.toString.call(e))return Array.from(e)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance")}()}function m(){if(l()){for(var e,t=arguments.length,n=new Array(t),i=0;i<t;i++)n[i]=arguments[i];(e=console).log.apply(e,u(["[virtual-scroller]"].concat(n)))}}function l(){return"undefined"!=typeof window&&window.VirtualScrollerDebug}function d(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}var c=function(){function e(t,n){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.getContainerNode=t,this.getState=n,this.reset()}var t,n,i;return t=e,(n=[{key:"reset",value:function(){this.measuredItemsHeight=0,this.firstMeasuredItemIndex=void 0,this.lastMeasuredItemIndex=void 0}},{key:"onInitItemHeights",value:function(){this.reset();for(var e=0;e<this.getState().itemHeights.length;){if(null==this.getState().itemHeights[e]){if(void 0!==this.firstMeasuredItemIndex){this.lastMeasuredItemIndex=e-1;break}}else void 0===this.firstMeasuredItemIndex&&(this.firstMeasuredItemIndex=e),this.measuredItemsHeight+=this.getState().itemHeights[e];e++}}},{key:"_getItemHeight",value:function(e,t){var n=this.getContainerNode();if(n){var i=e-t;if(i>=0&&i<n.childNodes.length)return n.childNodes[i].getBoundingClientRect().height}}},{key:"getItemSpacing",value:function(){var e=this.getContainerNode();if(e&&e.childNodes.length>1){var t=e.childNodes[0],n=e.childNodes[1],i=t.getBoundingClientRect(),r=n.getBoundingClientRect().top-(i.top+i.height);return window.VirtualScrollerDebug&&m("Item spacing",r),r}}},{key:"update",value:function(e,t,n){void 0===this.getState().itemSpacing&&(this.getState().itemSpacing=this.getItemSpacing()),void 0!==this.firstMeasuredItemIndex&&(e>this.lastMeasuredItemIndex+1||t<this.firstMeasuredItemIndex-1)&&this.reset();for(var i=this.firstMeasuredItemIndex,r=this.lastMeasuredItemIndex,o=!1,s=e;s<=t;){var a=this._getItemHeight(s,n);void 0!==a&&(this.set(s,a),(void 0===i||s<i)&&(this.measuredItemsHeight+=a,o||(this.firstMeasuredItemIndex=s,o=!0)),(void 0===r||s>r)&&(void 0!==r&&(this.measuredItemsHeight+=a),this.lastMeasuredItemIndex=s)),s++}}},{key:"updateItemHeight",value:function(e,t){var n=this.get(e),i=this._getItemHeight(e,t);void 0!==n&&void 0!==i&&(this.set(e,i),this.measuredItemsHeight+=i-n)}},{key:"getAverage",value:function(){return this.measuredItemsHeight?this.measuredItemsHeight/(this.lastMeasuredItemIndex-this.firstMeasuredItemIndex+1):0}},{key:"get",value:function(e){return this.getState().itemHeights[e]}},{key:"set",value:function(e,t){this.getState().itemHeights[e]=t}},{key:"onPrepend",value:function(e){void 0!==this.firstMeasuredItemIndex&&(this.firstMeasuredItemIndex+=e,this.lastMeasuredItemIndex+=e)}}])&&d(t.prototype,n),i&&d(t,i),e}();function f(e){return e.toFixed(2)+"px"}function g(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{},i=Object.keys(n);"function"==typeof Object.getOwnPropertySymbols&&(i=i.concat(Object.getOwnPropertySymbols(n).filter(function(e){return Object.getOwnPropertyDescriptor(n,e).enumerable}))),i.forEach(function(t){p(e,t,n[t])})}return e}function I(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}function p(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var S=200,v=function(){function e(t,n){var i,r,s,u,d,f=this,I=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),p(this,"layout",function(){return f.onUpdateShownItemIndexes({reason:"manual"})}),p(this,"onScroll",function(){return f.onUpdateShownItemIndexes({reason:"scroll"})}),p(this,"onResize",(i=function(){f.setState(f.getInitialLayoutState(),function(){f.onInitialRender("resize")})},r=S,u=0,d=function(){s=void 0,u=Date.now(),i()},function(){var e=Date.now(),t=r-(e-u);t<=0?(s&&(clearTimeout(s),s=void 0),u=e,i()):s||(s=setTimeout(d,t))})),p(this,"updateShownItemIndexes",function(e){var t=f.getShownItemIndexes(),n=t.firstShownItemIndex,i=t.lastShownItemIndex,r=t.redoLayoutAfterRender,o=f.getBeforeItemsHeight(n,i),s=f.getAfterItemsHeight(n,i);f.updateWillBeHiddenItemHeightsAndState(n,i),m("~ Layout results "+(f.bypass?"(bypass) ":"")+"~"),m("First shown item index",n),m("Last shown item index",i),m("Before items height",o),m("After items height",s),m("Average item height (calculated on previous render)",f.itemHeights.getAverage()),l()&&(m("Item heights",f.getState().itemHeights.slice()),m("Item states",f.getState().itemStates.slice())),r&&m("Redo layout after render"),void 0!==f.firstSeenItemIndex&&(n>f.lastSeenItemIndex+1||i<f.firstSeenItemIndex-1)&&(f.firstSeenItemIndex=void 0,f.lastSeenItemIndex=void 0),f.onBeforeShowItems(n,i),f.setState({firstShownItemIndex:n,lastShownItemIndex:i,beforeItemsHeight:o,afterItemsHeight:s},function(){return e(r)})}),p(this,"updateShownItemIndexesRecursive",function(){f.updateShownItemIndexes(function(e){e?setTimeout(function(){f.isMounted?f.updateShownItemIndexesRecursive():f.onDoneUpdatingItemIndexes()},0):f.onDoneUpdatingItemIndexes()})}),p(this,"restoreScroll",function(){var e=f.restoreScrollAfterPrepend,t=e.index,n=e.screenTop;f.restoreScrollAfterPrepend=void 0;var i=f.getItemElement(t).getBoundingClientRect().top-n;0!==i&&(m("Restore scroll position: scroll by",i),window.scrollTo(0,a()+i))}),p(this,"onUpdateShownItemIndexes",function(e){var t=e.reason;e.force;if(0!==f.getItemsCount()&&!f.isUpdatingItemIndexes){if(clearTimeout(f.onUserStopsScrollingTimeout),"scroll"===t){var n=void 0!==f.latestLayoutScreenTopAfterMargin&&a()<f.latestLayoutScreenTopAfterMargin&&f.getState().firstShownItemIndex>0||void 0!==f.latestLayoutScreenBottomAfterMargin&&a()+h()>f.latestLayoutScreenBottomAfterMargin&&f.getState().lastShownItemIndex<f.getItemsCount()-1;if(m(n?"The user has scrolled far enough: force re-render":"The user hasn't scrolled too much: delay re-render"),!n)return f.onUserStopsScrollingTimeout=setTimeout(f.onUserStoppedScrolling,100)}f.updateLayout(t)}}),p(this,"onUserStoppedScrolling",function(){f.isMounted&&f.updateLayout("stopped scrolling")});var v=I.getState,y=I.setState,w=I.onStateChange,x=I.preserveScrollPositionAtBottomOnMount,b=I.bypass,H=I.bypassBatchSize,C=I.estimatedItemHeight,O=I.onItemFirstRender,P=I.state;m("~ Initialize ~"),P&&(n=P.items),this.bypass=b,this.bypassBatchSize=H||10,this.initialItems=n,this.estimatedItemHeight=C,O&&(this.onItemFirstRender=O),t()&&function(e){for(;e.firstChild;)e.removeChild(e.firstChild)}(t()),y?(this.getState=v,this.setState=y):(this.getState=function(){return f.state},this.setState=function(e,t){var n=f.state;f.state=g({},n,e),o(f.state,n)||(w&&w(f.state,n),f.isMounted&&f.onUpdate(n)),t&&t()}),P&&m("Initial state (passed)",P),this.getContainerNode=t,this.itemHeights=new c(t,this.getState),x&&(this.preserveScrollPositionAtBottomOnMount={documentHeight:document.documentElement.scrollHeight}),this.setState(P||this.getInitialState(),function(){f.itemHeights.onInitItemHeights()}),m("Items count",n.length),C&&m("Estimated item height",C)}var t,n,i;return t=e,(n=[{key:"getInitialState",value:function(e){var t=this.initialItems.length,n=g({},e,this.getInitialLayoutState(),{items:this.initialItems,itemStates:new Array(t)});return m("Initial state (created)",n),m("First shown item index",n.firstShownItemIndex),m("Last shown item index",n.lastShownItemIndex),n}},{key:"getInitialLayoutState",value:function(){var e,t,n=this.initialItems.length;return n>0&&(e=Math.min(0,n-1),t=this.getLastShownItemIndex(e,n)),this.preserveScrollPositionAtBottomOnMount&&(e=0,t=n-1),this.onBeforeShowItems(e,t),{itemHeights:new Array(n),itemSpacing:void 0,beforeItemsHeight:0,afterItemsHeight:0,firstShownItemIndex:e,lastShownItemIndex:t}}},{key:"getEstimatedItemHeight",value:function(){return this.itemHeights&&this.itemHeights.getAverage()||this.estimatedItemHeight||0}},{key:"getItemSpacing",value:function(){return this.getState().itemSpacing||0}},{key:"getEstimatedItemsCount",value:function(e){return this.getEstimatedItemHeight()?Math.ceil((e+this.getItemSpacing())/(this.getEstimatedItemHeight()+this.getItemSpacing())):1}},{key:"getEstimatedItemsCountOnScreen",value:function(){return"undefined"!=typeof window?this.getEstimatedItemsCount(window.innerHeight):1}},{key:"getLastShownItemIndex",value:function(e,t){return Math.min(e+(this.getEstimatedItemsCountOnScreen()-1),t-1)}},{key:"getItemsCount",value:function(){return this.getState().items.length}},{key:"getMargin",value:function(){return window.innerHeight}},{key:"onBeforeShowItems",value:function(e,t){if(this.onItemFirstRender)if(void 0===this.firstSeenItemIndex){for(var n=e;n<=t;)this.onItemFirstRender(n),n++;this.firstSeenItemIndex=e,this.lastSeenItemIndex=t}else{if(e<this.firstSeenItemIndex){for(var i=e,r=Math.min(t,this.firstSeenItemIndex-1),o=i;o<=r;)this.onItemFirstRender(o),o++;this.firstSeenItemIndex=e}if(t>this.lastSeenItemIndex){for(var s=t,a=Math.max(e,this.lastSeenItemIndex+1);a<=s;)this.onItemFirstRender(a),a++;this.lastSeenItemIndex=t}}}},{key:"onMount",value:function(){this.onInitialRender("mount"),this.isMounted=!0,this.bypass||(window.addEventListener("scroll",this.onScroll),window.addEventListener("resize",this.onResize))}},{key:"onInitialRender",value:function(e){var t=this.getState(),n=t.firstShownItemIndex,i=t.lastShownItemIndex;this.getItemsCount()>0&&this.updateItemHeights(n,i),this.preserveScrollPositionAtBottomOnMount?window.scrollTo(0,window.pageYOffset+(document.documentElement.scrollHeight-this.preserveScrollPositionAtBottomOnMount.documentHeight)):this.onUpdateShownItemIndexes({reason:e})}},{key:"onUnmount",value:function(){this.isMounted=!1,this.bypass||(window.removeEventListener("scroll",this.onScroll),window.removeEventListener("resize",this.onResize),clearTimeout(this.onUserStopsScrollingTimeout),clearTimeout(this.watchContainerElementTopCoordinateTimer))}},{key:"onUpdate",value:function(e){var t=this.getState(),n=t.items,i=t.firstShownItemIndex,r=t.lastShownItemIndex;i===e.firstShownItemIndex&&r===e.lastShownItemIndex&&n===e.items||this.updateItemHeights(i,r)}},{key:"updateItemHeights",value:function(e,t){var n=this.getState().firstShownItemIndex;void 0!==e&&(m("~ Measure item heights after layout ~"),this.itemHeights.update(e,t,n),l()&&m("Item heights",this.getState().itemHeights.slice()))}},{key:"updateItemHeight",value:function(e){var t=this.getState().firstShownItemIndex;this.itemHeights.updateItemHeight(e,t)}},{key:"onItemStateChange",value:function(e,t){l()&&(m("~ Item state changed ~"),m("Item",e),m("Previous state\n"+JSON.stringify(this.getState().itemStates[e],null,2)),m("New state\n"+JSON.stringify(t,null,2))),this.getState().itemStates[e]=t}},{key:"onItemHeightChange",value:function(e){var t=this.getState().itemHeights,n=t[e];this.updateItemHeight(e);var i=t[e];n!==i&&(m("~ Item height changed ~"),m("Item",e),m("Previous height",n),m("New height",i),this.onUpdateShownItemIndexes({reason:"item height change"}))}},{key:"getItemCoordinates",value:function(e){for(var t=s(this.getContainerNode()).top,n=0;n<e;)t+=this.getState().itemHeights[n],t+=this.getItemSpacing(),n++;return{top:t,bottom:t+this.getState().itemHeights[e],height:this.getState().itemHeights[n]}}},{key:"getVisibleItemIndexes",value:function(e,t,n){for(var i,r,o=0,s=!1,a=0;a<this.getItemsCount();){var h=this.itemHeights.get(a);if(void 0===h){m("Item ".concat(a," height hasn't been measured yet: render and redo layout")),void 0===i&&(i=a);var u=t-(n+o);r=Math.min(a+(this.getEstimatedItemsCount(u)-1),this.getItemsCount()-1),s=!0;break}if(o+=h,void 0===i&&n+o>e&&(m("First visible item index (including margin)",a),i=a),a<this.getItemsCount()-1&&(o+=this.getItemSpacing()),n+o>t){m("Last visible item index (including margin)",a),void 0!==i&&(r=a);break}a++}return void 0!==i&&void 0===r&&m("Last item index (is fully visible)",r=this.getItemsCount()-1),this.restoreScrollAfterPrepend&&(r<this.restoreScrollAfterPrepend.index&&(r=this.restoreScrollAfterPrepend.index),s=!1),{firstShownItemIndex:i,lastShownItemIndex:r,redoLayoutAfterRender:s}}},{key:"getOffscreenListShownItemIndexes",value:function(){return{firstShownItemIndex:0,lastShownItemIndex:0,redoLayoutAfterRender:void 0===this.itemHeights.get(0)}}},{key:"getItemIndexes",value:function(e,t,n,i){if(!(i>e&&n<t))return this.getOffscreenListShownItemIndexes();var r=this.getVisibleItemIndexes(e,t,n);return void 0===r.firstShownItemIndex?this.getOffscreenListShownItemIndexes():r}},{key:"getBeforeItemsHeight",value:function(e,t){for(var n=0,i=0;i<e;)n+=this.itemHeights.get(i)||this.itemHeights.getAverage(),n+=this.getItemSpacing(),i++;return n}},{key:"getAfterItemsHeight",value:function(e,t){for(var n=0,i=t+1;i<this.getItemsCount();)n+=this.getItemSpacing(),n+=this.itemHeights.get(i)||this.itemHeights.getAverage(),i++;return n}},{key:"updateWillBeHiddenItemHeightsAndState",value:function(e,t){for(var n=this.getState().firstShownItemIndex;n<=this.getState().lastShownItemIndex;)n>=e&&n<=t||this.updateItemHeight(n),n++}},{key:"watchContainerElementTopCoordinate",value:function(){var e=this,t=Date.now();!function n(){void 0!==e.top&&s(e.getContainerNode()).top!==e.top&&e.onUpdateShownItemIndexes({reason:"top offset change"});Date.now()-t<3e3&&(e.watchContainerElementTopCoordinateTimer=setTimeout(n,500))}()}},{key:"getShownItemIndexes",value:function(){if(this.bypass){var e=this.getState().firstShownItemIndex,t=this.getState().lastShownItemIndex;return{firstShownItemIndex:e,lastShownItemIndex:t=Math.min(t+this.bypassBatchSize,this.getItemsCount()-1),redoLayoutAfterRender:t<this.getItemsCount()-1}}var n=s(this.getContainerNode()),i=n.top,r=n.height;void 0===this.top&&this.watchContainerElementTopCoordinate(),this.top=i;var o=function(){var e=h();return{top:a(),bottom:a()+e,height:e}}(),u=o.top,m=o.bottom;return this.latestLayoutScreenTopAfterMargin=u-this.getMargin(),this.latestLayoutScreenBottomAfterMargin=m+this.getMargin(),this.getItemIndexes(u-this.getMargin(),m+this.getMargin(),i,i+r)}},{key:"onDoneUpdatingItemIndexes",value:function(){this.isUpdatingItemIndexes=!1,this.restoreScrollAfterPrepend&&this.restoreScroll()}},{key:"captureScroll",value:function(e,t,n){0!==e.length&&(void 0===n&&(n=t.indexOf(e[0])),n<0||0!==n&&(this.getState().firstShownItemIndex>0||this.restoreScrollAfterPrepend&&this.restoreScrollAfterPrepend.previousItems===e&&this.restoreScrollAfterPrepend.nextItems===t||(this.restoreScrollAfterPrepend={previousItems:e,nextItems:t,index:n,screenTop:this.getItemElement(0).getBoundingClientRect().top})))}},{key:"updateLayout",value:function(e){m("~ Update layout (".concat(e,") ~")),this.isUpdatingItemIndexes=!0,this.updateShownItemIndexesRecursive()}},{key:"updateItems",value:function(e,t){return this.setItems(e,t)}},{key:"setItems",value:function(e){var t=this,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=this.getState().items,r=this.getState(),o=r.firstShownItemIndex,s=r.lastShownItemIndex,a=r.beforeItemsHeight,h=r.afterItemsHeight,u=r.itemStates,l=r.itemHeights;r.itemSpacing;m("~ Update items ~");var d=y(i,e),c=d.prependedItemsCount,f=d.appendedItemsCount,I=c>0||f>0;I?(c>0&&(m("Prepended items count",c),l=new Array(c).concat(l),this.itemHeights.onPrepend(c),u&&(u=new Array(c).concat(u)),(n.preserveScrollPositionOnPrependItems||n.preserveScrollPosition)&&this.captureScroll(i,e,c)),f>0&&(m("Appended items count",f),l=l.concat(new Array(f)),u&&(u=u.concat(new Array(f)))),void 0!==this.firstSeenItemIndex&&(this.firstSeenItemIndex+=c,this.lastSeenItemIndex+=c),o+=c,s+=c,a+=this.itemHeights.getAverage()*c,h+=this.itemHeights.getAverage()*f):(m("Non-incremental items update"),m("Previous items",i),m("New items",e),l=new Array(e.length),u=new Array(e.length),this.firstSeenItemIndex=void 0,this.lastSeenItemIndex=void 0,0===e.length?(o=void 0,s=void 0):(o=0,s=this.getLastShownItemIndex(o,e.length)),a=0,h=0),m("First shown item index",o),m("Last shown item index",s),m("Before items height",a),m("After items height",h),this.onBeforeShowItems(o,s),this.setState(g({},void 0,{items:e,itemStates:u,itemHeights:l,firstShownItemIndex:o,lastShownItemIndex:s,beforeItemsHeight:a,afterItemsHeight:h}),function(){I||t.itemHeights.onInitItemHeights(),t.onUpdateShownItemIndexes({reason:"update items",force:!0})})}},{key:"getItemElement",value:function(e){return this.getContainerNode().childNodes[e]}}])&&I(t.prototype,n),i&&I(t,i),e}();function y(e,t){var n=-1,i=-1;return e.length>0&&(n=t.indexOf(e[0]))>=0&&function(e,t,n){var i=0;for(;i<e.length;){if(t.length<=n+i||t[n+i]!==e[i])return!1;i++}return!0}(e,t,n)&&(i=n+e.length-1),n>=0&&i>=0?{prependedItemsCount:n,appendedItemsCount:t.length-(i+1)}:{prependedItemsCount:-1,appendedItemsCount:-1}}function w(e){return(w="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function x(){return(x=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(e[i]=n[i])}return e}).apply(this,arguments)}function b(e,t){if(null==e)return{};var n,i,r=function(e,t){if(null==e)return{};var n,i,r={},o=Object.keys(e);for(i=0;i<o.length;i++)n=o[i],t.indexOf(n)>=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i<o.length;i++)n=o[i],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}function H(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}function C(e){return(C=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function O(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function P(e,t){return(P=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function k(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var A=t.elementType||t.oneOfType([t.func,t.object]),M=function(t){function n(t){var i,r,o;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,n),r=this,o=C(n).call(this,t),i=!o||"object"!==w(o)&&"function"!=typeof o?O(r):o,k(O(i),"container",e.createRef()),k(O(i),"onItemStateChange",new Array(i.props.items.length)),k(O(i),"onItemHeightChange",new Array(i.props.items.length)),k(O(i),"itemRefs",new Array(i.props.items.length)),k(O(i),"uniquePrefixes",[]),k(O(i),"layout",function(){return i.virtualScroller.layout()}),k(O(i),"onItemFirstRender",function(){var e=i.props.onItemFirstRender;e&&e.apply(void 0,arguments)}),k(O(i),"onStateChange",function(){var e=i.props.onStateChange;e&&e.apply(void 0,arguments)});var s=i.props,a=s.items,h=s.initialState,u=s.estimatedItemHeight,m=s.preserveScrollPositionAtBottomOnMount,l=s.bypass,d=s.bypassBatchSize;return i.previousItemsProperty=a,i.virtualScroller=new v(function(){return i.container.current},a,{estimatedItemHeight:u,bypass:l,bypassBatchSize:d,onItemFirstRender:i.onItemFirstRender,preserveScrollPositionAtBottomOnMount:m,state:h,getState:function(){return i.state},setState:function(e,t){i.state?i.setState(e,t):(i.state=e,i.onStateChange(e))}}),i.generateUniquePrefix(),i}var i,r,s;return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&P(e,t)}(n,e.Component),i=n,(r=[{key:"shouldUseRefs",value:function(){var e,t=this.props.itemComponent;return(e=t).prototype&&e.prototype.isReactComponent}},{key:"getItemCoordinates",value:function(e){return this.virtualScroller.getItemCoordinates(e)}},{key:"updateItem",value:function(e){return this.renderItem(e)}},{key:"renderItem",value:function(e){var t=this;if(!this.shouldUseRefs())return console.error("[virtual-scroller] `.renderItem(i)` has been called but the `component` doesn't allow `ref`s. Only `component`s that're `React.Component`s support this feature.");if(this.itemRefs[e]&&this.itemRefs[e].current){var n=this.props.items,i=n[e];this.itemRefs[e].current.forceUpdate(function(){if(t._isMounted){var e=n.indexOf(i);e>=0&&t.virtualScroller.onItemHeightChange(e)}})}}},{key:"getItemRef",value:function(t){return this.itemRefs[t]||(this.itemRefs[t]=e.createRef()),this.itemRefs[t]}},{key:"getOnItemStateChange",value:function(e){var t=this;return this.onItemStateChange[e]||(this.onItemStateChange[e]=function(n){return t.virtualScroller.onItemStateChange(e,n)}),this.onItemStateChange[e]}},{key:"getOnItemHeightChange",value:function(e){var t=this;return this.onItemHeightChange[e]||(this.onItemHeightChange[e]=function(){return t.virtualScroller.onItemHeightChange(e)}),this.onItemHeightChange[e]}},{key:"generateUniquePrefix",value:function(){var e=String(Math.random()).slice(2);if(this.uniquePrefixes.indexOf(e)>=0)return this.generateUniquePrefix();this.uniquePrefixes.push(e),this.uniquePrefix=e}},{key:"componentDidMount",value:function(){var e=this.props.onMount;e&&e(),this.virtualScroller.onMount(),this._isMounted=!0}},{key:"componentDidUpdate",value:function(e,t){var n=this.props.onStateChange;n&&(o(this.state,t)||n(this.state,t)),this.virtualScroller.onUpdate(t);var i=this.props,r=i.items,s=i.preserveScrollPosition,a=i.preserveScrollPositionOnPrependItems;r!==e.items&&this.virtualScroller.setItems(r,{preserveScrollPositionOnPrependItems:a||s})}},{key:"componentWillUnmount",value:function(){this.virtualScroller.onUnmount(),this._isMounted=!1}},{key:"render",value:function(){var t=this,n=this.props,i=n.itemComponent,r=n.itemComponentProps,o=(n.items,n.estimatedItemHeight,n.bypass,n.bypassBatchSize,n.preserveScrollPositionOnPrependItems),s=n.preserveScrollPosition,a=(n.preserveScrollPositionAtBottomOnMount,n.initialState,n.onStateChange,n.onItemFirstRender,n.onMount,b(n,["itemComponent","itemComponentProps","items","estimatedItemHeight","bypass","bypassBatchSize","preserveScrollPositionOnPrependItems","preserveScrollPosition","preserveScrollPositionAtBottomOnMount","initialState","onStateChange","onItemFirstRender","onMount"])),h=this.virtualScroller.getState(),u=h.items,m=h.itemStates,l=h.firstShownItemIndex,d=h.lastShownItemIndex,c=h.beforeItemsHeight,g=h.afterItemsHeight,I=this.props.items,p=u;if(this.itemsPropertyWasChanged||(this.itemsPropertyWasChanged=this.props.items!==this.previousItemsProperty),this.previousItemsProperty=this.props.items,this.itemsPropertyWasChanged&&I!==p){var S=y(p,I),v=S.prependedItemsCount,w=S.appendedItemsCount;0===v&&w>0||((o||s)&&this.virtualScroller.captureScroll(p,I),this.generateUniquePrefix(),this.onItemStateChange=new Array(I.length),this.onItemHeightChange=new Array(I.length),this.itemRefs=new Array(I.length))}return e.createElement("div",x({},a,{ref:this.container,style:{paddingTop:f(c),paddingBottom:f(g)}}),u.map(function(n,o){return o>=l&&o<=d?e.createElement(i,x({},r,{ref:t.shouldUseRefs()?t.getItemRef(o):void 0,key:"".concat(t.uniquePrefix,":").concat(o),state:m&&m[o],onStateChange:t.getOnItemStateChange(o),onHeightChange:t.getOnItemHeightChange(o)}),n):null}))}}])&&H(i.prototype,r),s&&H(i,s),n}();return k(M,"propTypes",{items:t.arrayOf(t.object).isRequired,itemComponent:A.isRequired,itemComponentProps:t.object,estimatedItemHeight:t.number,bypass:t.bool,bypassBatchSize:t.number,preserveScrollPositionOnPrependItems:t.bool,preserveScrollPosition:t.bool,preserveScrollPositionAtBottomOnMount:t.bool,onMount:t.func,onItemFirstRender:t.func,onStateChange:t.func,initialState:t.shape({items:t.arrayOf(t.object).isRequired,itemStates:t.arrayOf(t.any),firstShownItemIndex:t.number.isRequired,lastShownItemIndex:t.number.isRequired,beforeItemsHeight:t.number.isRequired,afterItemsHeight:t.number.isRequired,itemHeights:t.arrayOf(t.number).isRequired,itemSpacing:t.number})}),M}); | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("react"),require("prop-types")):"function"==typeof define&&define.amd?define(["react","prop-types"],t):(e=e||self).VirtualScroller=t(e.React,e.PropTypes)}(this,function(e,t){"use strict";function n(e){return(n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}e=e&&e.hasOwnProperty("default")?e.default:e,t=t&&t.hasOwnProperty("default")?t.default:t;var i=Object.prototype.hasOwnProperty;function r(e,t){return e===t?0!==e||0!==t||1/e==1/t:e!=e&&t!=t}function o(e,t){if(r(e,t))return!0;if("object"!==n(e)||null===e||"object"!==n(t)||null===t)return!1;var o=Object.keys(e),s=Object.keys(t);if(o.length!==s.length)return!1;for(var a=0;a<o.length;a++)if(!i.call(t,o[a])||!r(e[o[a]],t[o[a]]))return!1;return!0}function s(e){var t=e.getBoundingClientRect(),n=document.clientLeft||document.body.clientLeft||0,i=document.clientTop||document.body.clientTop||0,r=window.pageYOffset,o=window.pageXOffset;return{top:t.top+r-i,left:t.left+o-n,width:t.width,height:t.height}}function a(){return window.pageYOffset}function h(){return window.innerHeight}function u(e){return function(e){if(Array.isArray(e)){for(var t=0,n=new Array(e.length);t<e.length;t++)n[t]=e[t];return n}}(e)||function(e){if(Symbol.iterator in Object(e)||"[object Arguments]"===Object.prototype.toString.call(e))return Array.from(e)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance")}()}function m(){if(l()){for(var e,t=arguments.length,n=new Array(t),i=0;i<t;i++)n[i]=arguments[i];(e=console).log.apply(e,u(["[virtual-scroller]"].concat(n)))}}function l(){return"undefined"!=typeof window&&window.VirtualScrollerDebug}function d(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}var c=function(){function e(t,n){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.getContainerNode=t,this.getState=n,this.reset()}var t,n,i;return t=e,(n=[{key:"reset",value:function(){this.measuredItemsHeight=0,this.firstMeasuredItemIndex=void 0,this.lastMeasuredItemIndex=void 0}},{key:"onInitItemHeights",value:function(){this.reset();for(var e=0;e<this.getState().itemHeights.length;){if(null==this.getState().itemHeights[e]){if(void 0!==this.firstMeasuredItemIndex){this.lastMeasuredItemIndex=e-1;break}}else void 0===this.firstMeasuredItemIndex&&(this.firstMeasuredItemIndex=e),this.measuredItemsHeight+=this.getState().itemHeights[e];e++}}},{key:"_getItemHeight",value:function(e,t){var n=this.getContainerNode();if(n){var i=e-t;if(i>=0&&i<n.childNodes.length)return n.childNodes[i].getBoundingClientRect().height}}},{key:"getItemSpacing",value:function(){var e=this.getContainerNode();if(e&&e.childNodes.length>1){var t=e.childNodes[0],n=e.childNodes[1],i=t.getBoundingClientRect(),r=n.getBoundingClientRect().top-(i.top+i.height);return window.VirtualScrollerDebug&&m("Item spacing",r),r}}},{key:"update",value:function(e,t,n){void 0===this.getState().itemSpacing&&(this.getState().itemSpacing=this.getItemSpacing()),void 0!==this.firstMeasuredItemIndex&&(e>this.lastMeasuredItemIndex+1||t<this.firstMeasuredItemIndex-1)&&this.reset();for(var i=this.firstMeasuredItemIndex,r=this.lastMeasuredItemIndex,o=!1,s=e;s<=t;){var a=this._getItemHeight(s,n);void 0!==a&&(this.set(s,a),(void 0===i||s<i)&&(this.measuredItemsHeight+=a,o||(this.firstMeasuredItemIndex=s,o=!0)),(void 0===r||s>r)&&(void 0!==r&&(this.measuredItemsHeight+=a),this.lastMeasuredItemIndex=s)),s++}}},{key:"updateItemHeight",value:function(e,t){var n=this.get(e),i=this._getItemHeight(e,t);void 0!==n&&void 0!==i&&(this.set(e,i),this.measuredItemsHeight+=i-n)}},{key:"getAverage",value:function(){return this.measuredItemsHeight?this.measuredItemsHeight/(this.lastMeasuredItemIndex-this.firstMeasuredItemIndex+1):0}},{key:"get",value:function(e){return this.getState().itemHeights[e]}},{key:"set",value:function(e,t){this.getState().itemHeights[e]=t}},{key:"onPrepend",value:function(e){void 0!==this.firstMeasuredItemIndex&&(this.firstMeasuredItemIndex+=e,this.lastMeasuredItemIndex+=e)}}])&&d(t.prototype,n),i&&d(t,i),e}();function f(e){return e.toFixed(2)+"px"}function g(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{},i=Object.keys(n);"function"==typeof Object.getOwnPropertySymbols&&(i=i.concat(Object.getOwnPropertySymbols(n).filter(function(e){return Object.getOwnPropertyDescriptor(n,e).enumerable}))),i.forEach(function(t){p(e,t,n[t])})}return e}function I(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}function p(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var S=200,v=function(){function e(t,n){var i,r,s,u,d,f=this,I=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),p(this,"layout",function(){return f.onUpdateShownItemIndexes({reason:"manual"})}),p(this,"onScroll",function(){return f.onUpdateShownItemIndexes({reason:"scroll"})}),p(this,"onResize",(i=function(){f.setState(f.getInitialLayoutState(),function(){f.onInitialRender("resize")})},r=S,u=0,d=function(){s=void 0,u=Date.now(),i()},function(){var e=Date.now(),t=r-(e-u);t<=0?(s&&(clearTimeout(s),s=void 0),u=e,i()):s||(s=setTimeout(d,t))})),p(this,"updateShownItemIndexes",function(e){var t=f.getShownItemIndexes(),n=t.firstShownItemIndex,i=t.lastShownItemIndex,r=t.redoLayoutAfterRender,o=f.getBeforeItemsHeight(n,i),s=f.getAfterItemsHeight(n,i);f.updateWillBeHiddenItemHeightsAndState(n,i),m("~ Layout results "+(f.bypass?"(bypass) ":"")+"~"),m("First shown item index",n),m("Last shown item index",i),m("Before items height",o),m("After items height",s),m("Average item height (calculated on previous render)",f.itemHeights.getAverage()),l()&&(m("Item heights",f.getState().itemHeights.slice()),m("Item states",f.getState().itemStates.slice())),r&&m("Redo layout after render"),void 0!==f.firstSeenItemIndex&&(n>f.lastSeenItemIndex+1||i<f.firstSeenItemIndex-1)&&(f.firstSeenItemIndex=void 0,f.lastSeenItemIndex=void 0),f.onBeforeShowItems(n,i),f.setState({firstShownItemIndex:n,lastShownItemIndex:i,beforeItemsHeight:o,afterItemsHeight:s},function(){return e(r)})}),p(this,"updateShownItemIndexesRecursive",function(){f.updateShownItemIndexes(function(e){e?setTimeout(function(){f.isMounted?f.updateShownItemIndexesRecursive():f.onDoneUpdatingItemIndexes()},0):f.onDoneUpdatingItemIndexes()})}),p(this,"restoreScroll",function(){var e=f.restoreScrollAfterPrepend,t=e.index,n=e.screenTop;f.restoreScrollAfterPrepend=void 0;var i=f.getItemElement(t).getBoundingClientRect().top-n;0!==i&&(m("Restore scroll position: scroll by",i),window.scrollTo(0,a()+i))}),p(this,"onUpdateShownItemIndexes",function(e){var t=e.reason;e.force;if(0!==f.getItemsCount()&&!f.isUpdatingItemIndexes){if(clearTimeout(f.onUserStopsScrollingTimeout),"scroll"===t){var n=void 0!==f.latestLayoutScreenTopAfterMargin&&a()<f.latestLayoutScreenTopAfterMargin&&f.getState().firstShownItemIndex>0||void 0!==f.latestLayoutScreenBottomAfterMargin&&a()+h()>f.latestLayoutScreenBottomAfterMargin&&f.getState().lastShownItemIndex<f.getItemsCount()-1;if(m(n?"The user has scrolled far enough: force re-render":"The user hasn't scrolled too much: delay re-render"),!n)return f.onUserStopsScrollingTimeout=setTimeout(f.onUserStoppedScrolling,100)}f.updateLayout(t)}}),p(this,"onUserStoppedScrolling",function(){f.isMounted&&f.updateLayout("stopped scrolling")});var v=I.getState,y=I.setState,w=I.onStateChange,x=I.preserveScrollPositionAtBottomOnMount,b=I.measureItemsBatchSize,H=I.bypass,C=I.bypassBatchSize,O=I.estimatedItemHeight,P=I.onItemFirstRender,k=I.state;m("~ Initialize ~"),k&&(n=k.items),this.bypass=H,this.bypassBatchSize=C||10,this.initialItems=n,this.estimatedItemHeight=O,this.measureItemsBatchSize=void 0===b?50:b,P&&(this.onItemFirstRender=P),t()&&function(e){for(;e.firstChild;)e.removeChild(e.firstChild)}(t()),y?(this.getState=v,this.setState=y):(this.getState=function(){return f.state},this.setState=function(e,t){var n=f.state;f.state=g({},n,e),o(f.state,n)||(w&&w(f.state,n),f.isMounted&&f.onUpdate(n)),t&&t()}),k&&m("Initial state (passed)",k),this.getContainerNode=t,this.itemHeights=new c(t,this.getState),x&&(this.preserveScrollPositionAtBottomOnMount={documentHeight:document.documentElement.scrollHeight}),this.setState(k||this.getInitialState(),function(){f.itemHeights.onInitItemHeights()}),m("Items count",n.length),O&&m("Estimated item height",O)}var t,n,i;return t=e,(n=[{key:"getInitialState",value:function(e){var t=this.initialItems.length,n=g({},e,this.getInitialLayoutState(),{items:this.initialItems,itemStates:new Array(t)});return m("Initial state (created)",n),m("First shown item index",n.firstShownItemIndex),m("Last shown item index",n.lastShownItemIndex),n}},{key:"getInitialLayoutState",value:function(){var e,t,n=this.initialItems.length;return n>0&&(e=Math.min(0,n-1),t=this.getLastShownItemIndex(e,n)),this.preserveScrollPositionAtBottomOnMount&&(e=0,t=n-1),this.onBeforeShowItems(e,t),{itemHeights:new Array(n),itemSpacing:void 0,beforeItemsHeight:0,afterItemsHeight:0,firstShownItemIndex:e,lastShownItemIndex:t}}},{key:"getEstimatedItemHeight",value:function(){return this.itemHeights&&this.itemHeights.getAverage()||this.estimatedItemHeight||0}},{key:"getItemSpacing",value:function(){return this.getState().itemSpacing||0}},{key:"getEstimatedItemsCount",value:function(e){return this.getEstimatedItemHeight()?Math.ceil((e+this.getItemSpacing())/(this.getEstimatedItemHeight()+this.getItemSpacing())):1}},{key:"getEstimatedItemsCountOnScreen",value:function(){return"undefined"!=typeof window?this.getEstimatedItemsCount(window.innerHeight):1}},{key:"getLastShownItemIndex",value:function(e,t){return Math.min(e+(this.getEstimatedItemsCountOnScreen()-1),t-1)}},{key:"getItemsCount",value:function(){return this.getState().items.length}},{key:"getMargin",value:function(){return window.innerHeight}},{key:"onBeforeShowItems",value:function(e,t){if(this.onItemFirstRender)if(void 0===this.firstSeenItemIndex){for(var n=e;n<=t;)this.onItemFirstRender(n),n++;this.firstSeenItemIndex=e,this.lastSeenItemIndex=t}else{if(e<this.firstSeenItemIndex){for(var i=e,r=Math.min(t,this.firstSeenItemIndex-1),o=i;o<=r;)this.onItemFirstRender(o),o++;this.firstSeenItemIndex=e}if(t>this.lastSeenItemIndex){for(var s=t,a=Math.max(e,this.lastSeenItemIndex+1);a<=s;)this.onItemFirstRender(a),a++;this.lastSeenItemIndex=t}}}},{key:"onMount",value:function(){this.onInitialRender("mount"),this.isMounted=!0,this.bypass||(window.addEventListener("scroll",this.onScroll),window.addEventListener("resize",this.onResize))}},{key:"onInitialRender",value:function(e){var t=this.getState(),n=t.firstShownItemIndex,i=t.lastShownItemIndex;this.getItemsCount()>0&&this.updateItemHeights(n,i),this.preserveScrollPositionAtBottomOnMount?window.scrollTo(0,window.pageYOffset+(document.documentElement.scrollHeight-this.preserveScrollPositionAtBottomOnMount.documentHeight)):this.onUpdateShownItemIndexes({reason:e})}},{key:"onUnmount",value:function(){this.isMounted=!1,this.bypass||(window.removeEventListener("scroll",this.onScroll),window.removeEventListener("resize",this.onResize),clearTimeout(this.onUserStopsScrollingTimeout),clearTimeout(this.watchContainerElementTopCoordinateTimer))}},{key:"onUpdate",value:function(e){var t=this.getState(),n=t.items,i=t.firstShownItemIndex,r=t.lastShownItemIndex;i===e.firstShownItemIndex&&r===e.lastShownItemIndex&&n===e.items||this.updateItemHeights(i,r)}},{key:"updateItemHeights",value:function(e,t){var n=this.getState().firstShownItemIndex;void 0!==e&&(m("~ Measure item heights after layout ~"),this.itemHeights.update(e,t,n),l()&&m("Item heights",this.getState().itemHeights.slice()))}},{key:"updateItemHeight",value:function(e){var t=this.getState().firstShownItemIndex;this.itemHeights.updateItemHeight(e,t)}},{key:"onItemStateChange",value:function(e,t){l()&&(m("~ Item state changed ~"),m("Item",e),m("Previous state\n"+JSON.stringify(this.getState().itemStates[e],null,2)),m("New state\n"+JSON.stringify(t,null,2))),this.getState().itemStates[e]=t}},{key:"onItemHeightChange",value:function(e){var t=this.getState().itemHeights,n=t[e];this.updateItemHeight(e);var i=t[e];n!==i&&(m("~ Item height changed ~"),m("Item",e),m("Previous height",n),m("New height",i),this.onUpdateShownItemIndexes({reason:"item height change"}))}},{key:"getItemCoordinates",value:function(e){for(var t=s(this.getContainerNode()).top,n=0;n<e;)t+=this.getState().itemHeights[n],t+=this.getItemSpacing(),n++;return{top:t,bottom:t+this.getState().itemHeights[e],height:this.getState().itemHeights[n]}}},{key:"getVisibleItemIndexes",value:function(e,t,n){for(var i,r,o=0,s=!1,a=0;a<this.getItemsCount();){var h=this.itemHeights.get(a);if(void 0===h){m("Item ".concat(a," height hasn't been measured yet: render and redo layout")),void 0===i&&(i=a);var u=t-(n+o);r=Math.min(a+(this.getEstimatedItemsCount(u)-1),this.getItemsCount()-1),s=!0;break}if(o+=h,void 0===i&&n+o>e&&(m("First visible item index (including margin)",a),i=a),a<this.getItemsCount()-1&&(o+=this.getItemSpacing()),n+o>t){m("Last visible item index (including margin)",a),void 0!==i&&(r=a);break}a++}return void 0!==i&&void 0===r&&m("Last item index (is fully visible)",r=this.getItemsCount()-1),this.restoreScrollAfterPrepend&&(r<this.restoreScrollAfterPrepend.index&&(r=this.restoreScrollAfterPrepend.index),s=!1),s&&this.measureItemsBatchSize&&(r=Math.min(r,i+this.measureItemsBatchSize)),{firstShownItemIndex:i,lastShownItemIndex:r,redoLayoutAfterRender:s}}},{key:"getOffscreenListShownItemIndexes",value:function(){return{firstShownItemIndex:0,lastShownItemIndex:0,redoLayoutAfterRender:void 0===this.itemHeights.get(0)}}},{key:"getItemIndexes",value:function(e,t,n,i){if(!(i>e&&n<t))return this.getOffscreenListShownItemIndexes();var r=this.getVisibleItemIndexes(e,t,n);return void 0===r.firstShownItemIndex?this.getOffscreenListShownItemIndexes():r}},{key:"getBeforeItemsHeight",value:function(e,t){for(var n=0,i=0;i<e;)n+=this.itemHeights.get(i)||this.itemHeights.getAverage(),n+=this.getItemSpacing(),i++;return n}},{key:"getAfterItemsHeight",value:function(e,t){for(var n=0,i=t+1;i<this.getItemsCount();)n+=this.getItemSpacing(),n+=this.itemHeights.get(i)||this.itemHeights.getAverage(),i++;return n}},{key:"updateWillBeHiddenItemHeightsAndState",value:function(e,t){for(var n=this.getState().firstShownItemIndex;n<=this.getState().lastShownItemIndex;)n>=e&&n<=t||this.updateItemHeight(n),n++}},{key:"watchContainerElementTopCoordinate",value:function(){var e=this,t=Date.now();!function n(){void 0!==e.top&&s(e.getContainerNode()).top!==e.top&&e.onUpdateShownItemIndexes({reason:"top offset change"});Date.now()-t<3e3&&(e.watchContainerElementTopCoordinateTimer=setTimeout(n,500))}()}},{key:"getShownItemIndexes",value:function(){if(this.bypass){var e=this.getState().firstShownItemIndex,t=this.getState().lastShownItemIndex;return{firstShownItemIndex:e,lastShownItemIndex:t=Math.min(t+this.bypassBatchSize,this.getItemsCount()-1),redoLayoutAfterRender:t<this.getItemsCount()-1}}var n=s(this.getContainerNode()),i=n.top,r=n.height;void 0===this.top&&this.watchContainerElementTopCoordinate(),this.top=i;var o=function(){var e=h();return{top:a(),bottom:a()+e,height:e}}(),u=o.top,m=o.bottom;return this.latestLayoutScreenTopAfterMargin=u-this.getMargin(),this.latestLayoutScreenBottomAfterMargin=m+this.getMargin(),this.getItemIndexes(u-this.getMargin(),m+this.getMargin(),i,i+r)}},{key:"onDoneUpdatingItemIndexes",value:function(){this.isUpdatingItemIndexes=!1,this.restoreScrollAfterPrepend&&this.restoreScroll()}},{key:"captureScroll",value:function(e,t,n){0!==e.length&&(void 0===n&&(n=t.indexOf(e[0])),n<0||0!==n&&(this.getState().firstShownItemIndex>0||this.restoreScrollAfterPrepend&&this.restoreScrollAfterPrepend.previousItems===e&&this.restoreScrollAfterPrepend.nextItems===t||(this.restoreScrollAfterPrepend={previousItems:e,nextItems:t,index:n,screenTop:this.getItemElement(0).getBoundingClientRect().top})))}},{key:"updateLayout",value:function(e){m("~ Update layout (".concat(e,") ~")),this.isUpdatingItemIndexes=!0,this.updateShownItemIndexesRecursive()}},{key:"updateItems",value:function(e,t){return this.setItems(e,t)}},{key:"setItems",value:function(e){var t=this,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=this.getState().items,r=this.getState(),o=r.firstShownItemIndex,s=r.lastShownItemIndex,a=r.beforeItemsHeight,h=r.afterItemsHeight,u=r.itemStates,l=r.itemHeights;r.itemSpacing;m("~ Update items ~");var d=y(i,e),c=d.prependedItemsCount,f=d.appendedItemsCount,I=c>0||f>0;I?(c>0&&(m("Prepended items count",c),l=new Array(c).concat(l),this.itemHeights.onPrepend(c),u&&(u=new Array(c).concat(u)),(n.preserveScrollPositionOnPrependItems||n.preserveScrollPosition)&&this.captureScroll(i,e,c)),f>0&&(m("Appended items count",f),l=l.concat(new Array(f)),u&&(u=u.concat(new Array(f)))),void 0!==this.firstSeenItemIndex&&(this.firstSeenItemIndex+=c,this.lastSeenItemIndex+=c),o+=c,s+=c,a+=this.itemHeights.getAverage()*c,h+=this.itemHeights.getAverage()*f):(m("Non-incremental items update"),m("Previous items",i),m("New items",e),l=new Array(e.length),u=new Array(e.length),this.firstSeenItemIndex=void 0,this.lastSeenItemIndex=void 0,0===e.length?(o=void 0,s=void 0):(o=0,s=this.getLastShownItemIndex(o,e.length)),a=0,h=0),m("First shown item index",o),m("Last shown item index",s),m("Before items height",a),m("After items height",h),this.onBeforeShowItems(o,s),this.setState(g({},void 0,{items:e,itemStates:u,itemHeights:l,firstShownItemIndex:o,lastShownItemIndex:s,beforeItemsHeight:a,afterItemsHeight:h}),function(){I||t.itemHeights.onInitItemHeights(),t.onUpdateShownItemIndexes({reason:"update items",force:!0})})}},{key:"getItemElement",value:function(e){return this.getContainerNode().childNodes[e]}}])&&I(t.prototype,n),i&&I(t,i),e}();function y(e,t){var n=-1,i=-1;return e.length>0&&(n=t.indexOf(e[0]))>=0&&function(e,t,n){var i=0;for(;i<e.length;){if(t.length<=n+i||t[n+i]!==e[i])return!1;i++}return!0}(e,t,n)&&(i=n+e.length-1),n>=0&&i>=0?{prependedItemsCount:n,appendedItemsCount:t.length-(i+1)}:{prependedItemsCount:-1,appendedItemsCount:-1}}function w(e){return(w="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function x(){return(x=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(e[i]=n[i])}return e}).apply(this,arguments)}function b(e,t){if(null==e)return{};var n,i,r=function(e,t){if(null==e)return{};var n,i,r={},o=Object.keys(e);for(i=0;i<o.length;i++)n=o[i],t.indexOf(n)>=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i<o.length;i++)n=o[i],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}function H(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}function C(e){return(C=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function O(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function P(e,t){return(P=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function k(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var A=t.elementType||t.oneOfType([t.func,t.object]),M=function(t){function n(t){var i,r,o;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,n),r=this,o=C(n).call(this,t),i=!o||"object"!==w(o)&&"function"!=typeof o?O(r):o,k(O(i),"container",e.createRef()),k(O(i),"onItemStateChange",new Array(i.props.items.length)),k(O(i),"onItemHeightChange",new Array(i.props.items.length)),k(O(i),"itemRefs",new Array(i.props.items.length)),k(O(i),"uniquePrefixes",[]),k(O(i),"layout",function(){return i.virtualScroller.layout()}),k(O(i),"onItemFirstRender",function(){var e=i.props.onItemFirstRender;e&&e.apply(void 0,arguments)}),k(O(i),"onStateChange",function(){var e=i.props.onStateChange;e&&e.apply(void 0,arguments)});var s=i.props,a=s.items,h=s.initialState,u=s.estimatedItemHeight,m=s.preserveScrollPositionAtBottomOnMount,l=s.measureItemsBatchSize,d=s.bypass,c=s.bypassBatchSize;return i.previousItemsProperty=a,i.virtualScroller=new v(function(){return i.container.current},a,{estimatedItemHeight:u,bypass:d,bypassBatchSize:c,onItemFirstRender:i.onItemFirstRender,preserveScrollPositionAtBottomOnMount:m,measureItemsBatchSize:l,state:h,getState:function(){return i.state},setState:function(e,t){i.state?i.setState(e,t):(i.state=e,i.onStateChange(e))}}),i.generateUniquePrefix(),i}var i,r,s;return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&P(e,t)}(n,e.Component),i=n,(r=[{key:"shouldUseRefs",value:function(){var e,t=this.props.itemComponent;return(e=t).prototype&&e.prototype.isReactComponent}},{key:"getItemCoordinates",value:function(e){return this.virtualScroller.getItemCoordinates(e)}},{key:"updateItem",value:function(e){return this.renderItem(e)}},{key:"renderItem",value:function(e){var t=this;if(!this.shouldUseRefs())return console.error("[virtual-scroller] `.renderItem(i)` has been called but the `component` doesn't allow `ref`s. Only `component`s that're `React.Component`s support this feature.");if(this.itemRefs[e]&&this.itemRefs[e].current){var n=this.props.items,i=n[e];this.itemRefs[e].current.forceUpdate(function(){if(t._isMounted){var e=n.indexOf(i);e>=0&&t.virtualScroller.onItemHeightChange(e)}})}}},{key:"getItemRef",value:function(t){return this.itemRefs[t]||(this.itemRefs[t]=e.createRef()),this.itemRefs[t]}},{key:"getOnItemStateChange",value:function(e){var t=this;return this.onItemStateChange[e]||(this.onItemStateChange[e]=function(n){return t.virtualScroller.onItemStateChange(e,n)}),this.onItemStateChange[e]}},{key:"getOnItemHeightChange",value:function(e){var t=this;return this.onItemHeightChange[e]||(this.onItemHeightChange[e]=function(){return t.virtualScroller.onItemHeightChange(e)}),this.onItemHeightChange[e]}},{key:"generateUniquePrefix",value:function(){var e=String(Math.random()).slice(2);if(this.uniquePrefixes.indexOf(e)>=0)return this.generateUniquePrefix();this.uniquePrefixes.push(e),this.uniquePrefix=e}},{key:"componentDidMount",value:function(){var e=this.props.onMount;e&&e(),this.virtualScroller.onMount(),this._isMounted=!0}},{key:"componentDidUpdate",value:function(e,t){var n=this.props.onStateChange;n&&(o(this.state,t)||n(this.state,t)),this.virtualScroller.onUpdate(t);var i=this.props,r=i.items,s=i.preserveScrollPosition,a=i.preserveScrollPositionOnPrependItems;r!==e.items&&this.virtualScroller.setItems(r,{preserveScrollPositionOnPrependItems:a||s})}},{key:"componentWillUnmount",value:function(){this.virtualScroller.onUnmount(),this._isMounted=!1}},{key:"render",value:function(){var t=this,n=this.props,i=n.itemComponent,r=n.itemComponentProps,o=(n.items,n.estimatedItemHeight,n.bypass,n.bypassBatchSize,n.preserveScrollPositionOnPrependItems),s=n.preserveScrollPosition,a=(n.preserveScrollPositionAtBottomOnMount,n.measureItemsBatchSize,n.initialState,n.onStateChange,n.onItemFirstRender,n.onMount,b(n,["itemComponent","itemComponentProps","items","estimatedItemHeight","bypass","bypassBatchSize","preserveScrollPositionOnPrependItems","preserveScrollPosition","preserveScrollPositionAtBottomOnMount","measureItemsBatchSize","initialState","onStateChange","onItemFirstRender","onMount"])),h=this.virtualScroller.getState(),u=h.items,m=h.itemStates,l=h.firstShownItemIndex,d=h.lastShownItemIndex,c=h.beforeItemsHeight,g=h.afterItemsHeight,I=this.props.items,p=u;if(this.itemsPropertyWasChanged||(this.itemsPropertyWasChanged=this.props.items!==this.previousItemsProperty),this.previousItemsProperty=this.props.items,this.itemsPropertyWasChanged&&I!==p){var S=y(p,I),v=S.prependedItemsCount,w=S.appendedItemsCount;0===v&&w>0||((o||s)&&this.virtualScroller.captureScroll(p,I),this.generateUniquePrefix(),this.onItemStateChange=new Array(I.length),this.onItemHeightChange=new Array(I.length),this.itemRefs=new Array(I.length))}return e.createElement("div",x({},a,{ref:this.container,style:{paddingTop:f(c),paddingBottom:f(g)}}),u.map(function(n,o){return o>=l&&o<=d?e.createElement(i,x({},r,{ref:t.shouldUseRefs()?t.getItemRef(o):void 0,key:"".concat(t.uniquePrefix,":").concat(o),state:m&&m[o],onStateChange:t.getOnItemStateChange(o),onHeightChange:t.getOnItemHeightChange(o)}),n):null}))}}])&&H(i.prototype,r),s&&H(i,s),n}();return k(M,"propTypes",{items:t.arrayOf(t.object).isRequired,itemComponent:A.isRequired,itemComponentProps:t.object,estimatedItemHeight:t.number,bypass:t.bool,bypassBatchSize:t.number,preserveScrollPositionOnPrependItems:t.bool,preserveScrollPosition:t.bool,preserveScrollPositionAtBottomOnMount:t.bool,measureItemsBatchSize:t.number,onMount:t.func,onItemFirstRender:t.func,onStateChange:t.func,initialState:t.shape({items:t.arrayOf(t.object).isRequired,itemStates:t.arrayOf(t.any),firstShownItemIndex:t.number.isRequired,lastShownItemIndex:t.number.isRequired,beforeItemsHeight:t.number.isRequired,afterItemsHeight:t.number.isRequired,itemHeights:t.arrayOf(t.number).isRequired,itemSpacing:t.number})}),M}); | ||
//# sourceMappingURL=virtual-scroller-react.js.map |
@@ -1,2 +0,2 @@ | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).VirtualScroller=t()}(this,function(){"use strict";function e(t){return(e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(t)}var t=Object.prototype.hasOwnProperty;function n(e,t){return e===t?0!==e||0!==t||1/e==1/t:e!=e&&t!=t}function i(e){var t=e.getBoundingClientRect(),n=document.clientLeft||document.body.clientLeft||0,i=document.clientTop||document.body.clientTop||0,s=window.pageYOffset,o=window.pageXOffset;return{top:t.top+s-i,left:t.left+o-n,width:t.width,height:t.height}}function s(){return window.pageYOffset}function o(){return window.innerHeight}function r(e){return function(e){if(Array.isArray(e)){for(var t=0,n=new Array(e.length);t<e.length;t++)n[t]=e[t];return n}}(e)||function(e){if(Symbol.iterator in Object(e)||"[object Arguments]"===Object.prototype.toString.call(e))return Array.from(e)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance")}()}function a(){if(h()){for(var e,t=arguments.length,n=new Array(t),i=0;i<t;i++)n[i]=arguments[i];(e=console).log.apply(e,r(["[virtual-scroller]"].concat(n)))}}function h(){return"undefined"!=typeof window&&window.VirtualScrollerDebug}function d(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}var u=function(){function e(t,n){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.getContainerNode=t,this.getState=n,this.reset()}var t,n,i;return t=e,(n=[{key:"reset",value:function(){this.measuredItemsHeight=0,this.firstMeasuredItemIndex=void 0,this.lastMeasuredItemIndex=void 0}},{key:"onInitItemHeights",value:function(){this.reset();for(var e=0;e<this.getState().itemHeights.length;){if(null==this.getState().itemHeights[e]){if(void 0!==this.firstMeasuredItemIndex){this.lastMeasuredItemIndex=e-1;break}}else void 0===this.firstMeasuredItemIndex&&(this.firstMeasuredItemIndex=e),this.measuredItemsHeight+=this.getState().itemHeights[e];e++}}},{key:"_getItemHeight",value:function(e,t){var n=this.getContainerNode();if(n){var i=e-t;if(i>=0&&i<n.childNodes.length)return n.childNodes[i].getBoundingClientRect().height}}},{key:"getItemSpacing",value:function(){var e=this.getContainerNode();if(e&&e.childNodes.length>1){var t=e.childNodes[0],n=e.childNodes[1],i=t.getBoundingClientRect(),s=n.getBoundingClientRect().top-(i.top+i.height);return window.VirtualScrollerDebug&&a("Item spacing",s),s}}},{key:"update",value:function(e,t,n){void 0===this.getState().itemSpacing&&(this.getState().itemSpacing=this.getItemSpacing()),void 0!==this.firstMeasuredItemIndex&&(e>this.lastMeasuredItemIndex+1||t<this.firstMeasuredItemIndex-1)&&this.reset();for(var i=this.firstMeasuredItemIndex,s=this.lastMeasuredItemIndex,o=!1,r=e;r<=t;){var a=this._getItemHeight(r,n);void 0!==a&&(this.set(r,a),(void 0===i||r<i)&&(this.measuredItemsHeight+=a,o||(this.firstMeasuredItemIndex=r,o=!0)),(void 0===s||r>s)&&(void 0!==s&&(this.measuredItemsHeight+=a),this.lastMeasuredItemIndex=r)),r++}}},{key:"updateItemHeight",value:function(e,t){var n=this.get(e),i=this._getItemHeight(e,t);void 0!==n&&void 0!==i&&(this.set(e,i),this.measuredItemsHeight+=i-n)}},{key:"getAverage",value:function(){return this.measuredItemsHeight?this.measuredItemsHeight/(this.lastMeasuredItemIndex-this.firstMeasuredItemIndex+1):0}},{key:"get",value:function(e){return this.getState().itemHeights[e]}},{key:"set",value:function(e,t){this.getState().itemHeights[e]=t}},{key:"onPrepend",value:function(e){void 0!==this.firstMeasuredItemIndex&&(this.firstMeasuredItemIndex+=e,this.lastMeasuredItemIndex+=e)}}])&&d(t.prototype,n),i&&d(t,i),e}();function m(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{},i=Object.keys(n);"function"==typeof Object.getOwnPropertySymbols&&(i=i.concat(Object.getOwnPropertySymbols(n).filter(function(e){return Object.getOwnPropertyDescriptor(n,e).enumerable}))),i.forEach(function(t){g(e,t,n[t])})}return e}function l(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}function g(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var I=200;return function(){function r(i,d){var l,f,c,S,p,v=this,y=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,r),g(this,"layout",function(){return v.onUpdateShownItemIndexes({reason:"manual"})}),g(this,"onScroll",function(){return v.onUpdateShownItemIndexes({reason:"scroll"})}),g(this,"onResize",(l=function(){v.setState(v.getInitialLayoutState(),function(){v.onInitialRender("resize")})},f=I,S=0,p=function(){c=void 0,S=Date.now(),l()},function(){var e=Date.now(),t=f-(e-S);t<=0?(c&&(clearTimeout(c),c=void 0),S=e,l()):c||(c=setTimeout(p,t))})),g(this,"updateShownItemIndexes",function(e){var t=v.getShownItemIndexes(),n=t.firstShownItemIndex,i=t.lastShownItemIndex,s=t.redoLayoutAfterRender,o=v.getBeforeItemsHeight(n,i),r=v.getAfterItemsHeight(n,i);v.updateWillBeHiddenItemHeightsAndState(n,i),a("~ Layout results "+(v.bypass?"(bypass) ":"")+"~"),a("First shown item index",n),a("Last shown item index",i),a("Before items height",o),a("After items height",r),a("Average item height (calculated on previous render)",v.itemHeights.getAverage()),h()&&(a("Item heights",v.getState().itemHeights.slice()),a("Item states",v.getState().itemStates.slice())),s&&a("Redo layout after render"),void 0!==v.firstSeenItemIndex&&(n>v.lastSeenItemIndex+1||i<v.firstSeenItemIndex-1)&&(v.firstSeenItemIndex=void 0,v.lastSeenItemIndex=void 0),v.onBeforeShowItems(n,i),v.setState({firstShownItemIndex:n,lastShownItemIndex:i,beforeItemsHeight:o,afterItemsHeight:r},function(){return e(s)})}),g(this,"updateShownItemIndexesRecursive",function(){v.updateShownItemIndexes(function(e){e?setTimeout(function(){v.isMounted?v.updateShownItemIndexesRecursive():v.onDoneUpdatingItemIndexes()},0):v.onDoneUpdatingItemIndexes()})}),g(this,"restoreScroll",function(){var e=v.restoreScrollAfterPrepend,t=e.index,n=e.screenTop;v.restoreScrollAfterPrepend=void 0;var i=v.getItemElement(t).getBoundingClientRect().top-n;0!==i&&(a("Restore scroll position: scroll by",i),window.scrollTo(0,s()+i))}),g(this,"onUpdateShownItemIndexes",function(e){var t=e.reason;e.force;if(0!==v.getItemsCount()&&!v.isUpdatingItemIndexes){if(clearTimeout(v.onUserStopsScrollingTimeout),"scroll"===t){var n=void 0!==v.latestLayoutScreenTopAfterMargin&&s()<v.latestLayoutScreenTopAfterMargin&&v.getState().firstShownItemIndex>0||void 0!==v.latestLayoutScreenBottomAfterMargin&&s()+o()>v.latestLayoutScreenBottomAfterMargin&&v.getState().lastShownItemIndex<v.getItemsCount()-1;if(a(n?"The user has scrolled far enough: force re-render":"The user hasn't scrolled too much: delay re-render"),!n)return v.onUserStopsScrollingTimeout=setTimeout(v.onUserStoppedScrolling,100)}v.updateLayout(t)}}),g(this,"onUserStoppedScrolling",function(){v.isMounted&&v.updateLayout("stopped scrolling")});var w=y.getState,x=y.setState,H=y.onStateChange,b=y.preserveScrollPositionAtBottomOnMount,A=y.bypass,C=y.bypassBatchSize,k=y.estimatedItemHeight,M=y.onItemFirstRender,O=y.state;a("~ Initialize ~"),O&&(d=O.items),this.bypass=A,this.bypassBatchSize=C||10,this.initialItems=d,this.estimatedItemHeight=k,M&&(this.onItemFirstRender=M),i()&&function(e){for(;e.firstChild;)e.removeChild(e.firstChild)}(i()),x?(this.getState=w,this.setState=x):(this.getState=function(){return v.state},this.setState=function(i,s){var o=v.state;v.state=m({},o,i),function(i,s){if(n(i,s))return!0;if("object"!==e(i)||null===i||"object"!==e(s)||null===s)return!1;var o=Object.keys(i),r=Object.keys(s);if(o.length!==r.length)return!1;for(var a=0;a<o.length;a++)if(!t.call(s,o[a])||!n(i[o[a]],s[o[a]]))return!1;return!0}(v.state,o)||(H&&H(v.state,o),v.isMounted&&v.onUpdate(o)),s&&s()}),O&&a("Initial state (passed)",O),this.getContainerNode=i,this.itemHeights=new u(i,this.getState),b&&(this.preserveScrollPositionAtBottomOnMount={documentHeight:document.documentElement.scrollHeight}),this.setState(O||this.getInitialState(),function(){v.itemHeights.onInitItemHeights()}),a("Items count",d.length),k&&a("Estimated item height",k)}var d,f,c;return d=r,(f=[{key:"getInitialState",value:function(e){var t=this.initialItems.length,n=m({},e,this.getInitialLayoutState(),{items:this.initialItems,itemStates:new Array(t)});return a("Initial state (created)",n),a("First shown item index",n.firstShownItemIndex),a("Last shown item index",n.lastShownItemIndex),n}},{key:"getInitialLayoutState",value:function(){var e,t,n=this.initialItems.length;return n>0&&(e=Math.min(0,n-1),t=this.getLastShownItemIndex(e,n)),this.preserveScrollPositionAtBottomOnMount&&(e=0,t=n-1),this.onBeforeShowItems(e,t),{itemHeights:new Array(n),itemSpacing:void 0,beforeItemsHeight:0,afterItemsHeight:0,firstShownItemIndex:e,lastShownItemIndex:t}}},{key:"getEstimatedItemHeight",value:function(){return this.itemHeights&&this.itemHeights.getAverage()||this.estimatedItemHeight||0}},{key:"getItemSpacing",value:function(){return this.getState().itemSpacing||0}},{key:"getEstimatedItemsCount",value:function(e){return this.getEstimatedItemHeight()?Math.ceil((e+this.getItemSpacing())/(this.getEstimatedItemHeight()+this.getItemSpacing())):1}},{key:"getEstimatedItemsCountOnScreen",value:function(){return"undefined"!=typeof window?this.getEstimatedItemsCount(window.innerHeight):1}},{key:"getLastShownItemIndex",value:function(e,t){return Math.min(e+(this.getEstimatedItemsCountOnScreen()-1),t-1)}},{key:"getItemsCount",value:function(){return this.getState().items.length}},{key:"getMargin",value:function(){return window.innerHeight}},{key:"onBeforeShowItems",value:function(e,t){if(this.onItemFirstRender)if(void 0===this.firstSeenItemIndex){for(var n=e;n<=t;)this.onItemFirstRender(n),n++;this.firstSeenItemIndex=e,this.lastSeenItemIndex=t}else{if(e<this.firstSeenItemIndex){for(var i=e,s=Math.min(t,this.firstSeenItemIndex-1),o=i;o<=s;)this.onItemFirstRender(o),o++;this.firstSeenItemIndex=e}if(t>this.lastSeenItemIndex){for(var r=t,a=Math.max(e,this.lastSeenItemIndex+1);a<=r;)this.onItemFirstRender(a),a++;this.lastSeenItemIndex=t}}}},{key:"onMount",value:function(){this.onInitialRender("mount"),this.isMounted=!0,this.bypass||(window.addEventListener("scroll",this.onScroll),window.addEventListener("resize",this.onResize))}},{key:"onInitialRender",value:function(e){var t=this.getState(),n=t.firstShownItemIndex,i=t.lastShownItemIndex;this.getItemsCount()>0&&this.updateItemHeights(n,i),this.preserveScrollPositionAtBottomOnMount?window.scrollTo(0,window.pageYOffset+(document.documentElement.scrollHeight-this.preserveScrollPositionAtBottomOnMount.documentHeight)):this.onUpdateShownItemIndexes({reason:e})}},{key:"onUnmount",value:function(){this.isMounted=!1,this.bypass||(window.removeEventListener("scroll",this.onScroll),window.removeEventListener("resize",this.onResize),clearTimeout(this.onUserStopsScrollingTimeout),clearTimeout(this.watchContainerElementTopCoordinateTimer))}},{key:"onUpdate",value:function(e){var t=this.getState(),n=t.items,i=t.firstShownItemIndex,s=t.lastShownItemIndex;i===e.firstShownItemIndex&&s===e.lastShownItemIndex&&n===e.items||this.updateItemHeights(i,s)}},{key:"updateItemHeights",value:function(e,t){var n=this.getState().firstShownItemIndex;void 0!==e&&(a("~ Measure item heights after layout ~"),this.itemHeights.update(e,t,n),h()&&a("Item heights",this.getState().itemHeights.slice()))}},{key:"updateItemHeight",value:function(e){var t=this.getState().firstShownItemIndex;this.itemHeights.updateItemHeight(e,t)}},{key:"onItemStateChange",value:function(e,t){h()&&(a("~ Item state changed ~"),a("Item",e),a("Previous state\n"+JSON.stringify(this.getState().itemStates[e],null,2)),a("New state\n"+JSON.stringify(t,null,2))),this.getState().itemStates[e]=t}},{key:"onItemHeightChange",value:function(e){var t=this.getState().itemHeights,n=t[e];this.updateItemHeight(e);var i=t[e];n!==i&&(a("~ Item height changed ~"),a("Item",e),a("Previous height",n),a("New height",i),this.onUpdateShownItemIndexes({reason:"item height change"}))}},{key:"getItemCoordinates",value:function(e){for(var t=i(this.getContainerNode()).top,n=0;n<e;)t+=this.getState().itemHeights[n],t+=this.getItemSpacing(),n++;return{top:t,bottom:t+this.getState().itemHeights[e],height:this.getState().itemHeights[n]}}},{key:"getVisibleItemIndexes",value:function(e,t,n){for(var i,s,o=0,r=!1,h=0;h<this.getItemsCount();){var d=this.itemHeights.get(h);if(void 0===d){a("Item ".concat(h," height hasn't been measured yet: render and redo layout")),void 0===i&&(i=h);var u=t-(n+o);s=Math.min(h+(this.getEstimatedItemsCount(u)-1),this.getItemsCount()-1),r=!0;break}if(o+=d,void 0===i&&n+o>e&&(a("First visible item index (including margin)",h),i=h),h<this.getItemsCount()-1&&(o+=this.getItemSpacing()),n+o>t){a("Last visible item index (including margin)",h),void 0!==i&&(s=h);break}h++}return void 0!==i&&void 0===s&&a("Last item index (is fully visible)",s=this.getItemsCount()-1),this.restoreScrollAfterPrepend&&(s<this.restoreScrollAfterPrepend.index&&(s=this.restoreScrollAfterPrepend.index),r=!1),{firstShownItemIndex:i,lastShownItemIndex:s,redoLayoutAfterRender:r}}},{key:"getOffscreenListShownItemIndexes",value:function(){return{firstShownItemIndex:0,lastShownItemIndex:0,redoLayoutAfterRender:void 0===this.itemHeights.get(0)}}},{key:"getItemIndexes",value:function(e,t,n,i){if(!(i>e&&n<t))return this.getOffscreenListShownItemIndexes();var s=this.getVisibleItemIndexes(e,t,n);return void 0===s.firstShownItemIndex?this.getOffscreenListShownItemIndexes():s}},{key:"getBeforeItemsHeight",value:function(e,t){for(var n=0,i=0;i<e;)n+=this.itemHeights.get(i)||this.itemHeights.getAverage(),n+=this.getItemSpacing(),i++;return n}},{key:"getAfterItemsHeight",value:function(e,t){for(var n=0,i=t+1;i<this.getItemsCount();)n+=this.getItemSpacing(),n+=this.itemHeights.get(i)||this.itemHeights.getAverage(),i++;return n}},{key:"updateWillBeHiddenItemHeightsAndState",value:function(e,t){for(var n=this.getState().firstShownItemIndex;n<=this.getState().lastShownItemIndex;)n>=e&&n<=t||this.updateItemHeight(n),n++}},{key:"watchContainerElementTopCoordinate",value:function(){var e=this,t=Date.now();!function n(){void 0!==e.top&&i(e.getContainerNode()).top!==e.top&&e.onUpdateShownItemIndexes({reason:"top offset change"});Date.now()-t<3e3&&(e.watchContainerElementTopCoordinateTimer=setTimeout(n,500))}()}},{key:"getShownItemIndexes",value:function(){if(this.bypass){var e=this.getState().firstShownItemIndex,t=this.getState().lastShownItemIndex;return{firstShownItemIndex:e,lastShownItemIndex:t=Math.min(t+this.bypassBatchSize,this.getItemsCount()-1),redoLayoutAfterRender:t<this.getItemsCount()-1}}var n=i(this.getContainerNode()),r=n.top,a=n.height;void 0===this.top&&this.watchContainerElementTopCoordinate(),this.top=r;var h=function(){var e=o();return{top:s(),bottom:s()+e,height:e}}(),d=h.top,u=h.bottom;return this.latestLayoutScreenTopAfterMargin=d-this.getMargin(),this.latestLayoutScreenBottomAfterMargin=u+this.getMargin(),this.getItemIndexes(d-this.getMargin(),u+this.getMargin(),r,r+a)}},{key:"onDoneUpdatingItemIndexes",value:function(){this.isUpdatingItemIndexes=!1,this.restoreScrollAfterPrepend&&this.restoreScroll()}},{key:"captureScroll",value:function(e,t,n){0!==e.length&&(void 0===n&&(n=t.indexOf(e[0])),n<0||0!==n&&(this.getState().firstShownItemIndex>0||this.restoreScrollAfterPrepend&&this.restoreScrollAfterPrepend.previousItems===e&&this.restoreScrollAfterPrepend.nextItems===t||(this.restoreScrollAfterPrepend={previousItems:e,nextItems:t,index:n,screenTop:this.getItemElement(0).getBoundingClientRect().top})))}},{key:"updateLayout",value:function(e){a("~ Update layout (".concat(e,") ~")),this.isUpdatingItemIndexes=!0,this.updateShownItemIndexesRecursive()}},{key:"updateItems",value:function(e,t){return this.setItems(e,t)}},{key:"setItems",value:function(e){var t=this,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=this.getState().items,s=this.getState(),o=s.firstShownItemIndex,r=s.lastShownItemIndex,h=s.beforeItemsHeight,d=s.afterItemsHeight,u=s.itemStates,l=s.itemHeights;s.itemSpacing;a("~ Update items ~");var g=function(e,t){var n=-1,i=-1;e.length>0&&(n=t.indexOf(e[0]))>=0&&function(e,t,n){var i=0;for(;i<e.length;){if(t.length<=n+i||t[n+i]!==e[i])return!1;i++}return!0}(e,t,n)&&(i=n+e.length-1);if(n>=0&&i>=0)return{prependedItemsCount:n,appendedItemsCount:t.length-(i+1)};return{prependedItemsCount:-1,appendedItemsCount:-1}}(i,e),I=g.prependedItemsCount,f=g.appendedItemsCount,c=I>0||f>0;c?(I>0&&(a("Prepended items count",I),l=new Array(I).concat(l),this.itemHeights.onPrepend(I),u&&(u=new Array(I).concat(u)),(n.preserveScrollPositionOnPrependItems||n.preserveScrollPosition)&&this.captureScroll(i,e,I)),f>0&&(a("Appended items count",f),l=l.concat(new Array(f)),u&&(u=u.concat(new Array(f)))),void 0!==this.firstSeenItemIndex&&(this.firstSeenItemIndex+=I,this.lastSeenItemIndex+=I),o+=I,r+=I,h+=this.itemHeights.getAverage()*I,d+=this.itemHeights.getAverage()*f):(a("Non-incremental items update"),a("Previous items",i),a("New items",e),l=new Array(e.length),u=new Array(e.length),this.firstSeenItemIndex=void 0,this.lastSeenItemIndex=void 0,0===e.length?(o=void 0,r=void 0):(o=0,r=this.getLastShownItemIndex(o,e.length)),h=0,d=0),a("First shown item index",o),a("Last shown item index",r),a("Before items height",h),a("After items height",d),this.onBeforeShowItems(o,r),this.setState(m({},void 0,{items:e,itemStates:u,itemHeights:l,firstShownItemIndex:o,lastShownItemIndex:r,beforeItemsHeight:h,afterItemsHeight:d}),function(){c||t.itemHeights.onInitItemHeights(),t.onUpdateShownItemIndexes({reason:"update items",force:!0})})}},{key:"getItemElement",value:function(e){return this.getContainerNode().childNodes[e]}}])&&l(d.prototype,f),c&&l(d,c),r}()}); | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).VirtualScroller=t()}(this,function(){"use strict";function e(t){return(e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(t)}var t=Object.prototype.hasOwnProperty;function n(e,t){return e===t?0!==e||0!==t||1/e==1/t:e!=e&&t!=t}function i(e){var t=e.getBoundingClientRect(),n=document.clientLeft||document.body.clientLeft||0,i=document.clientTop||document.body.clientTop||0,s=window.pageYOffset,o=window.pageXOffset;return{top:t.top+s-i,left:t.left+o-n,width:t.width,height:t.height}}function s(){return window.pageYOffset}function o(){return window.innerHeight}function r(e){return function(e){if(Array.isArray(e)){for(var t=0,n=new Array(e.length);t<e.length;t++)n[t]=e[t];return n}}(e)||function(e){if(Symbol.iterator in Object(e)||"[object Arguments]"===Object.prototype.toString.call(e))return Array.from(e)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance")}()}function a(){if(h()){for(var e,t=arguments.length,n=new Array(t),i=0;i<t;i++)n[i]=arguments[i];(e=console).log.apply(e,r(["[virtual-scroller]"].concat(n)))}}function h(){return"undefined"!=typeof window&&window.VirtualScrollerDebug}function d(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}var m=function(){function e(t,n){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.getContainerNode=t,this.getState=n,this.reset()}var t,n,i;return t=e,(n=[{key:"reset",value:function(){this.measuredItemsHeight=0,this.firstMeasuredItemIndex=void 0,this.lastMeasuredItemIndex=void 0}},{key:"onInitItemHeights",value:function(){this.reset();for(var e=0;e<this.getState().itemHeights.length;){if(null==this.getState().itemHeights[e]){if(void 0!==this.firstMeasuredItemIndex){this.lastMeasuredItemIndex=e-1;break}}else void 0===this.firstMeasuredItemIndex&&(this.firstMeasuredItemIndex=e),this.measuredItemsHeight+=this.getState().itemHeights[e];e++}}},{key:"_getItemHeight",value:function(e,t){var n=this.getContainerNode();if(n){var i=e-t;if(i>=0&&i<n.childNodes.length)return n.childNodes[i].getBoundingClientRect().height}}},{key:"getItemSpacing",value:function(){var e=this.getContainerNode();if(e&&e.childNodes.length>1){var t=e.childNodes[0],n=e.childNodes[1],i=t.getBoundingClientRect(),s=n.getBoundingClientRect().top-(i.top+i.height);return window.VirtualScrollerDebug&&a("Item spacing",s),s}}},{key:"update",value:function(e,t,n){void 0===this.getState().itemSpacing&&(this.getState().itemSpacing=this.getItemSpacing()),void 0!==this.firstMeasuredItemIndex&&(e>this.lastMeasuredItemIndex+1||t<this.firstMeasuredItemIndex-1)&&this.reset();for(var i=this.firstMeasuredItemIndex,s=this.lastMeasuredItemIndex,o=!1,r=e;r<=t;){var a=this._getItemHeight(r,n);void 0!==a&&(this.set(r,a),(void 0===i||r<i)&&(this.measuredItemsHeight+=a,o||(this.firstMeasuredItemIndex=r,o=!0)),(void 0===s||r>s)&&(void 0!==s&&(this.measuredItemsHeight+=a),this.lastMeasuredItemIndex=r)),r++}}},{key:"updateItemHeight",value:function(e,t){var n=this.get(e),i=this._getItemHeight(e,t);void 0!==n&&void 0!==i&&(this.set(e,i),this.measuredItemsHeight+=i-n)}},{key:"getAverage",value:function(){return this.measuredItemsHeight?this.measuredItemsHeight/(this.lastMeasuredItemIndex-this.firstMeasuredItemIndex+1):0}},{key:"get",value:function(e){return this.getState().itemHeights[e]}},{key:"set",value:function(e,t){this.getState().itemHeights[e]=t}},{key:"onPrepend",value:function(e){void 0!==this.firstMeasuredItemIndex&&(this.firstMeasuredItemIndex+=e,this.lastMeasuredItemIndex+=e)}}])&&d(t.prototype,n),i&&d(t,i),e}();function u(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{},i=Object.keys(n);"function"==typeof Object.getOwnPropertySymbols&&(i=i.concat(Object.getOwnPropertySymbols(n).filter(function(e){return Object.getOwnPropertyDescriptor(n,e).enumerable}))),i.forEach(function(t){g(e,t,n[t])})}return e}function l(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}function g(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var I=200;return function(){function r(i,d){var l,c,f,S,v,p=this,y=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,r),g(this,"layout",function(){return p.onUpdateShownItemIndexes({reason:"manual"})}),g(this,"onScroll",function(){return p.onUpdateShownItemIndexes({reason:"scroll"})}),g(this,"onResize",(l=function(){p.setState(p.getInitialLayoutState(),function(){p.onInitialRender("resize")})},c=I,S=0,v=function(){f=void 0,S=Date.now(),l()},function(){var e=Date.now(),t=c-(e-S);t<=0?(f&&(clearTimeout(f),f=void 0),S=e,l()):f||(f=setTimeout(v,t))})),g(this,"updateShownItemIndexes",function(e){var t=p.getShownItemIndexes(),n=t.firstShownItemIndex,i=t.lastShownItemIndex,s=t.redoLayoutAfterRender,o=p.getBeforeItemsHeight(n,i),r=p.getAfterItemsHeight(n,i);p.updateWillBeHiddenItemHeightsAndState(n,i),a("~ Layout results "+(p.bypass?"(bypass) ":"")+"~"),a("First shown item index",n),a("Last shown item index",i),a("Before items height",o),a("After items height",r),a("Average item height (calculated on previous render)",p.itemHeights.getAverage()),h()&&(a("Item heights",p.getState().itemHeights.slice()),a("Item states",p.getState().itemStates.slice())),s&&a("Redo layout after render"),void 0!==p.firstSeenItemIndex&&(n>p.lastSeenItemIndex+1||i<p.firstSeenItemIndex-1)&&(p.firstSeenItemIndex=void 0,p.lastSeenItemIndex=void 0),p.onBeforeShowItems(n,i),p.setState({firstShownItemIndex:n,lastShownItemIndex:i,beforeItemsHeight:o,afterItemsHeight:r},function(){return e(s)})}),g(this,"updateShownItemIndexesRecursive",function(){p.updateShownItemIndexes(function(e){e?setTimeout(function(){p.isMounted?p.updateShownItemIndexesRecursive():p.onDoneUpdatingItemIndexes()},0):p.onDoneUpdatingItemIndexes()})}),g(this,"restoreScroll",function(){var e=p.restoreScrollAfterPrepend,t=e.index,n=e.screenTop;p.restoreScrollAfterPrepend=void 0;var i=p.getItemElement(t).getBoundingClientRect().top-n;0!==i&&(a("Restore scroll position: scroll by",i),window.scrollTo(0,s()+i))}),g(this,"onUpdateShownItemIndexes",function(e){var t=e.reason;e.force;if(0!==p.getItemsCount()&&!p.isUpdatingItemIndexes){if(clearTimeout(p.onUserStopsScrollingTimeout),"scroll"===t){var n=void 0!==p.latestLayoutScreenTopAfterMargin&&s()<p.latestLayoutScreenTopAfterMargin&&p.getState().firstShownItemIndex>0||void 0!==p.latestLayoutScreenBottomAfterMargin&&s()+o()>p.latestLayoutScreenBottomAfterMargin&&p.getState().lastShownItemIndex<p.getItemsCount()-1;if(a(n?"The user has scrolled far enough: force re-render":"The user hasn't scrolled too much: delay re-render"),!n)return p.onUserStopsScrollingTimeout=setTimeout(p.onUserStoppedScrolling,100)}p.updateLayout(t)}}),g(this,"onUserStoppedScrolling",function(){p.isMounted&&p.updateLayout("stopped scrolling")});var w=y.getState,x=y.setState,H=y.onStateChange,b=y.preserveScrollPositionAtBottomOnMount,A=y.measureItemsBatchSize,C=y.bypass,k=y.bypassBatchSize,M=y.estimatedItemHeight,O=y.onItemFirstRender,L=y.state;a("~ Initialize ~"),L&&(d=L.items),this.bypass=C,this.bypassBatchSize=k||10,this.initialItems=d,this.estimatedItemHeight=M,this.measureItemsBatchSize=void 0===A?50:A,O&&(this.onItemFirstRender=O),i()&&function(e){for(;e.firstChild;)e.removeChild(e.firstChild)}(i()),x?(this.getState=w,this.setState=x):(this.getState=function(){return p.state},this.setState=function(i,s){var o=p.state;p.state=u({},o,i),function(i,s){if(n(i,s))return!0;if("object"!==e(i)||null===i||"object"!==e(s)||null===s)return!1;var o=Object.keys(i),r=Object.keys(s);if(o.length!==r.length)return!1;for(var a=0;a<o.length;a++)if(!t.call(s,o[a])||!n(i[o[a]],s[o[a]]))return!1;return!0}(p.state,o)||(H&&H(p.state,o),p.isMounted&&p.onUpdate(o)),s&&s()}),L&&a("Initial state (passed)",L),this.getContainerNode=i,this.itemHeights=new m(i,this.getState),b&&(this.preserveScrollPositionAtBottomOnMount={documentHeight:document.documentElement.scrollHeight}),this.setState(L||this.getInitialState(),function(){p.itemHeights.onInitItemHeights()}),a("Items count",d.length),M&&a("Estimated item height",M)}var d,c,f;return d=r,(c=[{key:"getInitialState",value:function(e){var t=this.initialItems.length,n=u({},e,this.getInitialLayoutState(),{items:this.initialItems,itemStates:new Array(t)});return a("Initial state (created)",n),a("First shown item index",n.firstShownItemIndex),a("Last shown item index",n.lastShownItemIndex),n}},{key:"getInitialLayoutState",value:function(){var e,t,n=this.initialItems.length;return n>0&&(e=Math.min(0,n-1),t=this.getLastShownItemIndex(e,n)),this.preserveScrollPositionAtBottomOnMount&&(e=0,t=n-1),this.onBeforeShowItems(e,t),{itemHeights:new Array(n),itemSpacing:void 0,beforeItemsHeight:0,afterItemsHeight:0,firstShownItemIndex:e,lastShownItemIndex:t}}},{key:"getEstimatedItemHeight",value:function(){return this.itemHeights&&this.itemHeights.getAverage()||this.estimatedItemHeight||0}},{key:"getItemSpacing",value:function(){return this.getState().itemSpacing||0}},{key:"getEstimatedItemsCount",value:function(e){return this.getEstimatedItemHeight()?Math.ceil((e+this.getItemSpacing())/(this.getEstimatedItemHeight()+this.getItemSpacing())):1}},{key:"getEstimatedItemsCountOnScreen",value:function(){return"undefined"!=typeof window?this.getEstimatedItemsCount(window.innerHeight):1}},{key:"getLastShownItemIndex",value:function(e,t){return Math.min(e+(this.getEstimatedItemsCountOnScreen()-1),t-1)}},{key:"getItemsCount",value:function(){return this.getState().items.length}},{key:"getMargin",value:function(){return window.innerHeight}},{key:"onBeforeShowItems",value:function(e,t){if(this.onItemFirstRender)if(void 0===this.firstSeenItemIndex){for(var n=e;n<=t;)this.onItemFirstRender(n),n++;this.firstSeenItemIndex=e,this.lastSeenItemIndex=t}else{if(e<this.firstSeenItemIndex){for(var i=e,s=Math.min(t,this.firstSeenItemIndex-1),o=i;o<=s;)this.onItemFirstRender(o),o++;this.firstSeenItemIndex=e}if(t>this.lastSeenItemIndex){for(var r=t,a=Math.max(e,this.lastSeenItemIndex+1);a<=r;)this.onItemFirstRender(a),a++;this.lastSeenItemIndex=t}}}},{key:"onMount",value:function(){this.onInitialRender("mount"),this.isMounted=!0,this.bypass||(window.addEventListener("scroll",this.onScroll),window.addEventListener("resize",this.onResize))}},{key:"onInitialRender",value:function(e){var t=this.getState(),n=t.firstShownItemIndex,i=t.lastShownItemIndex;this.getItemsCount()>0&&this.updateItemHeights(n,i),this.preserveScrollPositionAtBottomOnMount?window.scrollTo(0,window.pageYOffset+(document.documentElement.scrollHeight-this.preserveScrollPositionAtBottomOnMount.documentHeight)):this.onUpdateShownItemIndexes({reason:e})}},{key:"onUnmount",value:function(){this.isMounted=!1,this.bypass||(window.removeEventListener("scroll",this.onScroll),window.removeEventListener("resize",this.onResize),clearTimeout(this.onUserStopsScrollingTimeout),clearTimeout(this.watchContainerElementTopCoordinateTimer))}},{key:"onUpdate",value:function(e){var t=this.getState(),n=t.items,i=t.firstShownItemIndex,s=t.lastShownItemIndex;i===e.firstShownItemIndex&&s===e.lastShownItemIndex&&n===e.items||this.updateItemHeights(i,s)}},{key:"updateItemHeights",value:function(e,t){var n=this.getState().firstShownItemIndex;void 0!==e&&(a("~ Measure item heights after layout ~"),this.itemHeights.update(e,t,n),h()&&a("Item heights",this.getState().itemHeights.slice()))}},{key:"updateItemHeight",value:function(e){var t=this.getState().firstShownItemIndex;this.itemHeights.updateItemHeight(e,t)}},{key:"onItemStateChange",value:function(e,t){h()&&(a("~ Item state changed ~"),a("Item",e),a("Previous state\n"+JSON.stringify(this.getState().itemStates[e],null,2)),a("New state\n"+JSON.stringify(t,null,2))),this.getState().itemStates[e]=t}},{key:"onItemHeightChange",value:function(e){var t=this.getState().itemHeights,n=t[e];this.updateItemHeight(e);var i=t[e];n!==i&&(a("~ Item height changed ~"),a("Item",e),a("Previous height",n),a("New height",i),this.onUpdateShownItemIndexes({reason:"item height change"}))}},{key:"getItemCoordinates",value:function(e){for(var t=i(this.getContainerNode()).top,n=0;n<e;)t+=this.getState().itemHeights[n],t+=this.getItemSpacing(),n++;return{top:t,bottom:t+this.getState().itemHeights[e],height:this.getState().itemHeights[n]}}},{key:"getVisibleItemIndexes",value:function(e,t,n){for(var i,s,o=0,r=!1,h=0;h<this.getItemsCount();){var d=this.itemHeights.get(h);if(void 0===d){a("Item ".concat(h," height hasn't been measured yet: render and redo layout")),void 0===i&&(i=h);var m=t-(n+o);s=Math.min(h+(this.getEstimatedItemsCount(m)-1),this.getItemsCount()-1),r=!0;break}if(o+=d,void 0===i&&n+o>e&&(a("First visible item index (including margin)",h),i=h),h<this.getItemsCount()-1&&(o+=this.getItemSpacing()),n+o>t){a("Last visible item index (including margin)",h),void 0!==i&&(s=h);break}h++}return void 0!==i&&void 0===s&&a("Last item index (is fully visible)",s=this.getItemsCount()-1),this.restoreScrollAfterPrepend&&(s<this.restoreScrollAfterPrepend.index&&(s=this.restoreScrollAfterPrepend.index),r=!1),r&&this.measureItemsBatchSize&&(s=Math.min(s,i+this.measureItemsBatchSize)),{firstShownItemIndex:i,lastShownItemIndex:s,redoLayoutAfterRender:r}}},{key:"getOffscreenListShownItemIndexes",value:function(){return{firstShownItemIndex:0,lastShownItemIndex:0,redoLayoutAfterRender:void 0===this.itemHeights.get(0)}}},{key:"getItemIndexes",value:function(e,t,n,i){if(!(i>e&&n<t))return this.getOffscreenListShownItemIndexes();var s=this.getVisibleItemIndexes(e,t,n);return void 0===s.firstShownItemIndex?this.getOffscreenListShownItemIndexes():s}},{key:"getBeforeItemsHeight",value:function(e,t){for(var n=0,i=0;i<e;)n+=this.itemHeights.get(i)||this.itemHeights.getAverage(),n+=this.getItemSpacing(),i++;return n}},{key:"getAfterItemsHeight",value:function(e,t){for(var n=0,i=t+1;i<this.getItemsCount();)n+=this.getItemSpacing(),n+=this.itemHeights.get(i)||this.itemHeights.getAverage(),i++;return n}},{key:"updateWillBeHiddenItemHeightsAndState",value:function(e,t){for(var n=this.getState().firstShownItemIndex;n<=this.getState().lastShownItemIndex;)n>=e&&n<=t||this.updateItemHeight(n),n++}},{key:"watchContainerElementTopCoordinate",value:function(){var e=this,t=Date.now();!function n(){void 0!==e.top&&i(e.getContainerNode()).top!==e.top&&e.onUpdateShownItemIndexes({reason:"top offset change"});Date.now()-t<3e3&&(e.watchContainerElementTopCoordinateTimer=setTimeout(n,500))}()}},{key:"getShownItemIndexes",value:function(){if(this.bypass){var e=this.getState().firstShownItemIndex,t=this.getState().lastShownItemIndex;return{firstShownItemIndex:e,lastShownItemIndex:t=Math.min(t+this.bypassBatchSize,this.getItemsCount()-1),redoLayoutAfterRender:t<this.getItemsCount()-1}}var n=i(this.getContainerNode()),r=n.top,a=n.height;void 0===this.top&&this.watchContainerElementTopCoordinate(),this.top=r;var h=function(){var e=o();return{top:s(),bottom:s()+e,height:e}}(),d=h.top,m=h.bottom;return this.latestLayoutScreenTopAfterMargin=d-this.getMargin(),this.latestLayoutScreenBottomAfterMargin=m+this.getMargin(),this.getItemIndexes(d-this.getMargin(),m+this.getMargin(),r,r+a)}},{key:"onDoneUpdatingItemIndexes",value:function(){this.isUpdatingItemIndexes=!1,this.restoreScrollAfterPrepend&&this.restoreScroll()}},{key:"captureScroll",value:function(e,t,n){0!==e.length&&(void 0===n&&(n=t.indexOf(e[0])),n<0||0!==n&&(this.getState().firstShownItemIndex>0||this.restoreScrollAfterPrepend&&this.restoreScrollAfterPrepend.previousItems===e&&this.restoreScrollAfterPrepend.nextItems===t||(this.restoreScrollAfterPrepend={previousItems:e,nextItems:t,index:n,screenTop:this.getItemElement(0).getBoundingClientRect().top})))}},{key:"updateLayout",value:function(e){a("~ Update layout (".concat(e,") ~")),this.isUpdatingItemIndexes=!0,this.updateShownItemIndexesRecursive()}},{key:"updateItems",value:function(e,t){return this.setItems(e,t)}},{key:"setItems",value:function(e){var t=this,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=this.getState().items,s=this.getState(),o=s.firstShownItemIndex,r=s.lastShownItemIndex,h=s.beforeItemsHeight,d=s.afterItemsHeight,m=s.itemStates,l=s.itemHeights;s.itemSpacing;a("~ Update items ~");var g=function(e,t){var n=-1,i=-1;e.length>0&&(n=t.indexOf(e[0]))>=0&&function(e,t,n){var i=0;for(;i<e.length;){if(t.length<=n+i||t[n+i]!==e[i])return!1;i++}return!0}(e,t,n)&&(i=n+e.length-1);if(n>=0&&i>=0)return{prependedItemsCount:n,appendedItemsCount:t.length-(i+1)};return{prependedItemsCount:-1,appendedItemsCount:-1}}(i,e),I=g.prependedItemsCount,c=g.appendedItemsCount,f=I>0||c>0;f?(I>0&&(a("Prepended items count",I),l=new Array(I).concat(l),this.itemHeights.onPrepend(I),m&&(m=new Array(I).concat(m)),(n.preserveScrollPositionOnPrependItems||n.preserveScrollPosition)&&this.captureScroll(i,e,I)),c>0&&(a("Appended items count",c),l=l.concat(new Array(c)),m&&(m=m.concat(new Array(c)))),void 0!==this.firstSeenItemIndex&&(this.firstSeenItemIndex+=I,this.lastSeenItemIndex+=I),o+=I,r+=I,h+=this.itemHeights.getAverage()*I,d+=this.itemHeights.getAverage()*c):(a("Non-incremental items update"),a("Previous items",i),a("New items",e),l=new Array(e.length),m=new Array(e.length),this.firstSeenItemIndex=void 0,this.lastSeenItemIndex=void 0,0===e.length?(o=void 0,r=void 0):(o=0,r=this.getLastShownItemIndex(o,e.length)),h=0,d=0),a("First shown item index",o),a("Last shown item index",r),a("Before items height",h),a("After items height",d),this.onBeforeShowItems(o,r),this.setState(u({},void 0,{items:e,itemStates:m,itemHeights:l,firstShownItemIndex:o,lastShownItemIndex:r,beforeItemsHeight:h,afterItemsHeight:d}),function(){f||t.itemHeights.onInitItemHeights(),t.onUpdateShownItemIndexes({reason:"update items",force:!0})})}},{key:"getItemElement",value:function(e){return this.getContainerNode().childNodes[e]}}])&&l(d.prototype,c),f&&l(d,f),r}()}); | ||
//# sourceMappingURL=virtual-scroller.js.map |
@@ -107,2 +107,3 @@ "use strict"; | ||
preserveScrollPositionAtBottomOnMount = _this$props.preserveScrollPositionAtBottomOnMount, | ||
measureItemsBatchSize = _this$props.measureItemsBatchSize, | ||
bypass = _this$props.bypass, | ||
@@ -122,2 +123,3 @@ bypassBatchSize = _this$props.bypassBatchSize; // `this.previousItemsProperty` is only used for comparing | ||
preserveScrollPositionAtBottomOnMount: preserveScrollPositionAtBottomOnMount, | ||
measureItemsBatchSize: measureItemsBatchSize, | ||
state: initialState, | ||
@@ -334,2 +336,3 @@ getState: function getState() { | ||
preserveScrollPositionAtBottomOnMount = _this$props3.preserveScrollPositionAtBottomOnMount, | ||
measureItemsBatchSize = _this$props3.measureItemsBatchSize, | ||
initialState = _this$props3.initialState, | ||
@@ -339,3 +342,3 @@ onStateChange = _this$props3.onStateChange, | ||
onMount = _this$props3.onMount, | ||
rest = _objectWithoutProperties(_this$props3, ["itemComponent", "itemComponentProps", "items", "estimatedItemHeight", "bypass", "bypassBatchSize", "preserveScrollPositionOnPrependItems", "preserveScrollPosition", "preserveScrollPositionAtBottomOnMount", "initialState", "onStateChange", "onItemFirstRender", "onMount"]); | ||
rest = _objectWithoutProperties(_this$props3, ["itemComponent", "itemComponentProps", "items", "estimatedItemHeight", "bypass", "bypassBatchSize", "preserveScrollPositionOnPrependItems", "preserveScrollPosition", "preserveScrollPositionAtBottomOnMount", "measureItemsBatchSize", "initialState", "onStateChange", "onItemFirstRender", "onMount"]); | ||
@@ -470,2 +473,3 @@ var _this$virtualScroller = this.virtualScroller.getState(), | ||
preserveScrollPositionAtBottomOnMount: _propTypes["default"].bool, | ||
measureItemsBatchSize: _propTypes["default"].number, | ||
onMount: _propTypes["default"].func, | ||
@@ -472,0 +476,0 @@ onItemFirstRender: _propTypes["default"].func, |
@@ -33,3 +33,2 @@ "use strict"; | ||
var START_FROM_INDEX = 0; | ||
var WATCH_CONTAINER_ELEMENT_TOP_COORDINATE_INTERVAL = 500; | ||
@@ -263,2 +262,3 @@ var WATCH_CONTAINER_ELEMENT_TOP_COORDINATE_MAX_DURATION = 3000; | ||
preserveScrollPositionAtBottomOnMount = options.preserveScrollPositionAtBottomOnMount, | ||
measureItemsBatchSize = options.measureItemsBatchSize, | ||
bypass = options.bypass, | ||
@@ -291,2 +291,4 @@ bypassBatchSize = options.bypassBatchSize; | ||
this.measureItemsBatchSize = measureItemsBatchSize === undefined ? 50 : measureItemsBatchSize; | ||
if (onItemFirstRender) { | ||
@@ -347,3 +349,3 @@ this.onItemFirstRender = onItemFirstRender; | ||
}); | ||
(0, _log["default"])('Items count', items.length); // log('Start from index', START_FROM_INDEX) | ||
(0, _log["default"])('Items count', items.length); | ||
@@ -384,3 +386,3 @@ if (estimatedItemHeight) { | ||
if (itemsCount > 0) { | ||
firstShownItemIndex = Math.min(START_FROM_INDEX, itemsCount - 1); | ||
firstShownItemIndex = Math.min(0, itemsCount - 1); | ||
lastShownItemIndex = this.getLastShownItemIndex(firstShownItemIndex, itemsCount); | ||
@@ -659,7 +661,7 @@ } | ||
value: function getVisibleItemIndexes(screenTop, screenBottom, listTop) { | ||
var showItemsFromIndex; | ||
var showItemsToIndex; | ||
var firstShownItemIndex; | ||
var lastShownItemIndex; | ||
var itemsHeight = 0; | ||
var redoLayoutAfterRender = false; | ||
var i = START_FROM_INDEX; | ||
var i = 0; | ||
@@ -673,8 +675,8 @@ while (i < this.getItemsCount()) { | ||
if (showItemsFromIndex === undefined) { | ||
showItemsFromIndex = i; | ||
if (firstShownItemIndex === undefined) { | ||
firstShownItemIndex = i; | ||
} | ||
var heightLeft = screenBottom - (listTop + itemsHeight); | ||
showItemsToIndex = Math.min(i + (this.getEstimatedItemsCount(heightLeft) - 1), // Guard against index overflow. | ||
lastShownItemIndex = Math.min(i + (this.getEstimatedItemsCount(heightLeft) - 1), // Guard against index overflow. | ||
this.getItemsCount() - 1); | ||
@@ -688,6 +690,6 @@ redoLayoutAfterRender = true; | ||
if (showItemsFromIndex === undefined) { | ||
if (firstShownItemIndex === undefined) { | ||
if (listTop + itemsHeight > screenTop) { | ||
(0, _log["default"])('First visible item index (including margin)', i); | ||
showItemsFromIndex = i; | ||
firstShownItemIndex = i; | ||
} | ||
@@ -706,6 +708,6 @@ } // Items can have spacing. | ||
// to be in the viewport in reality the list isn't visible | ||
// in which case `showItemsFromIndex` will be `undefined`. | ||
// in which case `firstShownItemIndex` will be `undefined`. | ||
if (showItemsFromIndex !== undefined) { | ||
showItemsToIndex = i; | ||
if (firstShownItemIndex !== undefined) { | ||
lastShownItemIndex = i; | ||
} | ||
@@ -720,27 +722,43 @@ | ||
if (showItemsFromIndex !== undefined && showItemsToIndex === undefined) { | ||
showItemsToIndex = this.getItemsCount() - 1; | ||
(0, _log["default"])('Last item index (is fully visible)', showItemsToIndex); | ||
} // If scroll position is scheduled to be restored | ||
// after render then the anchor item must be rendered | ||
// and all the prepended items before it. | ||
if (firstShownItemIndex !== undefined && lastShownItemIndex === undefined) { | ||
lastShownItemIndex = this.getItemsCount() - 1; | ||
(0, _log["default"])('Last item index (is fully visible)', lastShownItemIndex); | ||
} // If scroll position is scheduled to be restored after render | ||
// then the anchor item must be rendered, and all the prepended | ||
// items before it, all in a single pass. This way, all the | ||
// prepended items could be measured right after the render | ||
// and the scroll position can then be immediately restored. | ||
if (this.restoreScrollAfterPrepend) { | ||
if (showItemsToIndex < this.restoreScrollAfterPrepend.index) { | ||
showItemsToIndex = this.restoreScrollAfterPrepend.index; | ||
} // `showItemsFromIndex` is always `0` when prepending items. | ||
// No need to redo layout after render because all | ||
// prepended items are rendered in a single pass. | ||
// It removes the visual jitter otherwise happening | ||
// due to scroll position restoration waiting for | ||
// two layout cycles instead of one. | ||
if (lastShownItemIndex < this.restoreScrollAfterPrepend.index) { | ||
lastShownItemIndex = this.restoreScrollAfterPrepend.index; | ||
} // `firstShownItemIndex` is always `0` when prepending items. | ||
// And `lastShownItemIndex` always covers all prepended items in this case. | ||
// None of the prepended items have been rendered before, | ||
// so their heights are unknown. The code at the start of this function | ||
// did therefore set `redoLayoutAfterRender` to `true` | ||
// in order to render just the first prepended item in order to | ||
// measure it, and only then make a decision on how many other | ||
// prepended items to render. But since we've instructed the code | ||
// to show all of the prepended items at once, then no need to | ||
// "redo layout after render". Additionally, if `redoLayoutAfterRender` | ||
// was left `true` then there would be a short the visual "jitter" | ||
// happening due to scroll position restoration waiting for two | ||
// layout cycles instead of one. | ||
redoLayoutAfterRender = false; | ||
} // If some items will be rendered in order to measure their height, | ||
// and it's not a `preserveScrollPositionOnPrependItems` case, | ||
// then limit the amount of such items being measured in a single pass. | ||
if (redoLayoutAfterRender && this.measureItemsBatchSize) { | ||
lastShownItemIndex = Math.min(lastShownItemIndex, firstShownItemIndex + this.measureItemsBatchSize); | ||
} | ||
return { | ||
firstShownItemIndex: showItemsFromIndex, | ||
lastShownItemIndex: showItemsToIndex, | ||
firstShownItemIndex: firstShownItemIndex, | ||
lastShownItemIndex: lastShownItemIndex, | ||
redoLayoutAfterRender: redoLayoutAfterRender | ||
@@ -752,7 +770,6 @@ }; | ||
value: function getOffscreenListShownItemIndexes() { | ||
var i = START_FROM_INDEX; | ||
return { | ||
firstShownItemIndex: i, | ||
lastShownItemIndex: i, | ||
redoLayoutAfterRender: this.itemHeights.get(i) === undefined | ||
firstShownItemIndex: 0, | ||
lastShownItemIndex: 0, | ||
redoLayoutAfterRender: this.itemHeights.get(0) === undefined | ||
}; | ||
@@ -793,3 +810,3 @@ } | ||
var i = START_FROM_INDEX; | ||
var i = 0; | ||
@@ -796,0 +813,0 @@ while (i < firstShownItemIndex) { |
@@ -91,2 +91,3 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } | ||
preserveScrollPositionAtBottomOnMount = _this$props.preserveScrollPositionAtBottomOnMount, | ||
measureItemsBatchSize = _this$props.measureItemsBatchSize, | ||
bypass = _this$props.bypass, | ||
@@ -106,2 +107,3 @@ bypassBatchSize = _this$props.bypassBatchSize; // `this.previousItemsProperty` is only used for comparing | ||
preserveScrollPositionAtBottomOnMount: preserveScrollPositionAtBottomOnMount, | ||
measureItemsBatchSize: measureItemsBatchSize, | ||
state: initialState, | ||
@@ -318,2 +320,3 @@ getState: function getState() { | ||
preserveScrollPositionAtBottomOnMount = _this$props3.preserveScrollPositionAtBottomOnMount, | ||
measureItemsBatchSize = _this$props3.measureItemsBatchSize, | ||
initialState = _this$props3.initialState, | ||
@@ -323,3 +326,3 @@ onStateChange = _this$props3.onStateChange, | ||
onMount = _this$props3.onMount, | ||
rest = _objectWithoutProperties(_this$props3, ["itemComponent", "itemComponentProps", "items", "estimatedItemHeight", "bypass", "bypassBatchSize", "preserveScrollPositionOnPrependItems", "preserveScrollPosition", "preserveScrollPositionAtBottomOnMount", "initialState", "onStateChange", "onItemFirstRender", "onMount"]); | ||
rest = _objectWithoutProperties(_this$props3, ["itemComponent", "itemComponentProps", "items", "estimatedItemHeight", "bypass", "bypassBatchSize", "preserveScrollPositionOnPrependItems", "preserveScrollPosition", "preserveScrollPositionAtBottomOnMount", "measureItemsBatchSize", "initialState", "onStateChange", "onItemFirstRender", "onMount"]); | ||
@@ -452,2 +455,3 @@ var _this$virtualScroller = this.virtualScroller.getState(), | ||
preserveScrollPositionAtBottomOnMount: PropTypes.bool, | ||
measureItemsBatchSize: PropTypes.number, | ||
onMount: PropTypes.func, | ||
@@ -454,0 +458,0 @@ onItemFirstRender: PropTypes.func, |
@@ -16,3 +16,2 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; } | ||
import { throttle } from './utility'; | ||
var START_FROM_INDEX = 0; | ||
var WATCH_CONTAINER_ELEMENT_TOP_COORDINATE_INTERVAL = 500; | ||
@@ -246,2 +245,3 @@ var WATCH_CONTAINER_ELEMENT_TOP_COORDINATE_MAX_DURATION = 3000; | ||
preserveScrollPositionAtBottomOnMount = options.preserveScrollPositionAtBottomOnMount, | ||
measureItemsBatchSize = options.measureItemsBatchSize, | ||
bypass = options.bypass, | ||
@@ -274,2 +274,4 @@ bypassBatchSize = options.bypassBatchSize; | ||
this.measureItemsBatchSize = measureItemsBatchSize === undefined ? 50 : measureItemsBatchSize; | ||
if (onItemFirstRender) { | ||
@@ -330,3 +332,3 @@ this.onItemFirstRender = onItemFirstRender; | ||
}); | ||
log('Items count', items.length); // log('Start from index', START_FROM_INDEX) | ||
log('Items count', items.length); | ||
@@ -367,3 +369,3 @@ if (estimatedItemHeight) { | ||
if (itemsCount > 0) { | ||
firstShownItemIndex = Math.min(START_FROM_INDEX, itemsCount - 1); | ||
firstShownItemIndex = Math.min(0, itemsCount - 1); | ||
lastShownItemIndex = this.getLastShownItemIndex(firstShownItemIndex, itemsCount); | ||
@@ -642,7 +644,7 @@ } | ||
value: function getVisibleItemIndexes(screenTop, screenBottom, listTop) { | ||
var showItemsFromIndex; | ||
var showItemsToIndex; | ||
var firstShownItemIndex; | ||
var lastShownItemIndex; | ||
var itemsHeight = 0; | ||
var redoLayoutAfterRender = false; | ||
var i = START_FROM_INDEX; | ||
var i = 0; | ||
@@ -656,8 +658,8 @@ while (i < this.getItemsCount()) { | ||
if (showItemsFromIndex === undefined) { | ||
showItemsFromIndex = i; | ||
if (firstShownItemIndex === undefined) { | ||
firstShownItemIndex = i; | ||
} | ||
var heightLeft = screenBottom - (listTop + itemsHeight); | ||
showItemsToIndex = Math.min(i + (this.getEstimatedItemsCount(heightLeft) - 1), // Guard against index overflow. | ||
lastShownItemIndex = Math.min(i + (this.getEstimatedItemsCount(heightLeft) - 1), // Guard against index overflow. | ||
this.getItemsCount() - 1); | ||
@@ -671,6 +673,6 @@ redoLayoutAfterRender = true; | ||
if (showItemsFromIndex === undefined) { | ||
if (firstShownItemIndex === undefined) { | ||
if (listTop + itemsHeight > screenTop) { | ||
log('First visible item index (including margin)', i); | ||
showItemsFromIndex = i; | ||
firstShownItemIndex = i; | ||
} | ||
@@ -689,6 +691,6 @@ } // Items can have spacing. | ||
// to be in the viewport in reality the list isn't visible | ||
// in which case `showItemsFromIndex` will be `undefined`. | ||
// in which case `firstShownItemIndex` will be `undefined`. | ||
if (showItemsFromIndex !== undefined) { | ||
showItemsToIndex = i; | ||
if (firstShownItemIndex !== undefined) { | ||
lastShownItemIndex = i; | ||
} | ||
@@ -703,27 +705,43 @@ | ||
if (showItemsFromIndex !== undefined && showItemsToIndex === undefined) { | ||
showItemsToIndex = this.getItemsCount() - 1; | ||
log('Last item index (is fully visible)', showItemsToIndex); | ||
} // If scroll position is scheduled to be restored | ||
// after render then the anchor item must be rendered | ||
// and all the prepended items before it. | ||
if (firstShownItemIndex !== undefined && lastShownItemIndex === undefined) { | ||
lastShownItemIndex = this.getItemsCount() - 1; | ||
log('Last item index (is fully visible)', lastShownItemIndex); | ||
} // If scroll position is scheduled to be restored after render | ||
// then the anchor item must be rendered, and all the prepended | ||
// items before it, all in a single pass. This way, all the | ||
// prepended items could be measured right after the render | ||
// and the scroll position can then be immediately restored. | ||
if (this.restoreScrollAfterPrepend) { | ||
if (showItemsToIndex < this.restoreScrollAfterPrepend.index) { | ||
showItemsToIndex = this.restoreScrollAfterPrepend.index; | ||
} // `showItemsFromIndex` is always `0` when prepending items. | ||
// No need to redo layout after render because all | ||
// prepended items are rendered in a single pass. | ||
// It removes the visual jitter otherwise happening | ||
// due to scroll position restoration waiting for | ||
// two layout cycles instead of one. | ||
if (lastShownItemIndex < this.restoreScrollAfterPrepend.index) { | ||
lastShownItemIndex = this.restoreScrollAfterPrepend.index; | ||
} // `firstShownItemIndex` is always `0` when prepending items. | ||
// And `lastShownItemIndex` always covers all prepended items in this case. | ||
// None of the prepended items have been rendered before, | ||
// so their heights are unknown. The code at the start of this function | ||
// did therefore set `redoLayoutAfterRender` to `true` | ||
// in order to render just the first prepended item in order to | ||
// measure it, and only then make a decision on how many other | ||
// prepended items to render. But since we've instructed the code | ||
// to show all of the prepended items at once, then no need to | ||
// "redo layout after render". Additionally, if `redoLayoutAfterRender` | ||
// was left `true` then there would be a short the visual "jitter" | ||
// happening due to scroll position restoration waiting for two | ||
// layout cycles instead of one. | ||
redoLayoutAfterRender = false; | ||
} // If some items will be rendered in order to measure their height, | ||
// and it's not a `preserveScrollPositionOnPrependItems` case, | ||
// then limit the amount of such items being measured in a single pass. | ||
if (redoLayoutAfterRender && this.measureItemsBatchSize) { | ||
lastShownItemIndex = Math.min(lastShownItemIndex, firstShownItemIndex + this.measureItemsBatchSize); | ||
} | ||
return { | ||
firstShownItemIndex: showItemsFromIndex, | ||
lastShownItemIndex: showItemsToIndex, | ||
firstShownItemIndex: firstShownItemIndex, | ||
lastShownItemIndex: lastShownItemIndex, | ||
redoLayoutAfterRender: redoLayoutAfterRender | ||
@@ -735,7 +753,6 @@ }; | ||
value: function getOffscreenListShownItemIndexes() { | ||
var i = START_FROM_INDEX; | ||
return { | ||
firstShownItemIndex: i, | ||
lastShownItemIndex: i, | ||
redoLayoutAfterRender: this.itemHeights.get(i) === undefined | ||
firstShownItemIndex: 0, | ||
lastShownItemIndex: 0, | ||
redoLayoutAfterRender: this.itemHeights.get(0) === undefined | ||
}; | ||
@@ -776,3 +793,3 @@ } | ||
var i = START_FROM_INDEX; | ||
var i = 0; | ||
@@ -779,0 +796,0 @@ while (i < firstShownItemIndex) { |
{ | ||
"name": "virtual-scroller", | ||
"version": "1.0.18", | ||
"version": "1.0.19", | ||
"description": "A component for efficiently rendering large lists of variable height items", | ||
@@ -5,0 +5,0 @@ "main": "index.commonjs.js", |
@@ -77,5 +77,6 @@ # VirtualScroller | ||
* `onStateChange(newState, prevState)` — Is called whenever `VirtualScroller` `state` is updated (including setting the initial `state`) if `getState()` and `setState()` properties aren't defined. | ||
* `onItemFirstRender(i)` — Is called for each item the first time it's rendered. For example, consider a list of items that must be somehow preprocessed before being rendered and such preprocessing takes some time. In this case instead of preprocessing the whole list of items upfront a developer may only preprocess the items as they're being rendered. | ||
* `onItemFirstRender(i)` — Is called for each item the first time it's rendered. Is guaranteed to be called at least one time for each item rendered, though could also be called multiple times. For an example of using such feature, consider a list of items that must be somehow preprocessed (parsed, enhanced, etc) before being rendered, and such preprocessing puts some load on the CPU (and therefore takes some time). In such case, instead of preprocessing the whole list of items upfront, a developer could preprocess the items as they're being rendered thereby eliminating any associated lag/freezing and draining less battery. | ||
<!-- * `bypass` — Set to `true` to disable the "virtual scroller" behavior: it will (eventually) render the entire list on mount and won't hide items that go offscreen as the user scrolls. --> | ||
* `preserveScrollPositionAtBottomOnMount: boolean` — (optional) Set to `true` to preserve scroll position of the bottom of the list when it's first mounted. A possible use case: consider a forum thread only showing unread posts by default. If a user navigates to such thread, it could show "No new posts" message with a "Show previous" button above it. When the user clicks the "Show previous" button, a `<VirtualScroller/>` is mounted with a list of posts. If `preserveScrollPositionAtBottomOnMount: true` is set then, after the list of posts is show, page scroll will be restored so that the bottom of the list remain on screen so that the user could scroll up from the most recent posts to the oldest ones. | ||
* `preserveScrollPositionAtBottomOnMount: boolean` — (optional) (advanced) Set to `true` to preserve scroll position of the bottom of the list when it's first mounted. A possible use case: consider a forum thread only showing unread posts by default. If a user navigates to such thread, it could show "No new posts" message with a "Show previous" button above it. When the user clicks the "Show previous" button, a `<VirtualScroller/>` is mounted with a list of posts. If `preserveScrollPositionAtBottomOnMount: true` is set then, after the list of posts is show, page scroll will be restored so that the bottom of the list remain on screen so that the user could scroll up from the most recent posts to the oldest ones. | ||
* `measureItemsBatchSize: number` — (optional) (advanced) (experimental) Imagine a situation when a user doesn't gradually scroll through a huge list but instead hits an End key to scroll right to the end of such huge list: this will result in the whole list rendering at once (because an item needs to know the height of all previous items in order to render at correct scroll position) which could be CPU-intensive in some cases (for example, when using React due to its slow performance when initially rendering components on a page). To prevent freezing the UI in the process, a `measureItemsBatchSize` could be configured, that would limit the maximum count of items that're being rendered in a single pass for measuring their height: if `measureItemsBatchSize` is configured, then such items will be rendered and measured in batches. By default it's set to `100`. This is an experimental feature and could be removed in future non-major versions of this library. For example, the future React 17 will come with [Fiber](https://www.youtube.com/watch?v=ZCuYPiUIONs) rendering engine that is said to resolve such freezing issues internally. In that case, introducing this option may be reconsidered. | ||
@@ -231,2 +232,3 @@ `VirtualScroller` class instance provides methods: | ||
* `preserveScrollPositionAtBottomOnMount: boolean` — (optional) The `preserveScrollPositionAtBottomOnMount` option of `VirtualScroller`. | ||
* `measureItemsBatchSize: number` — (optional) The `measureItemsBatchSize` option of `VirtualScroller`. | ||
* `onMount()` — (optional) Is called after `<VirtualScroller/>` component has been mounted and before `VirtualScroller.onMount()` is called. Can be used in advanced cases: for example, to restore page scroll Y position for the corresponding `VirtualScroller` `state` on "Back" navigation. | ||
@@ -233,0 +235,0 @@ * `onItemFirstRender(i)` — (optional) The `onItemFirstRender` option of `VirtualScroller` class. |
@@ -28,2 +28,3 @@ import React from 'react' | ||
preserveScrollPositionAtBottomOnMount: PropTypes.bool, | ||
measureItemsBatchSize: PropTypes.number, | ||
onMount: PropTypes.func, | ||
@@ -77,2 +78,3 @@ onItemFirstRender: PropTypes.func, | ||
preserveScrollPositionAtBottomOnMount, | ||
measureItemsBatchSize, | ||
bypass, | ||
@@ -94,2 +96,3 @@ bypassBatchSize | ||
preserveScrollPositionAtBottomOnMount, | ||
measureItemsBatchSize, | ||
state: initialState, | ||
@@ -288,2 +291,3 @@ getState: () => this.state, | ||
preserveScrollPositionAtBottomOnMount, | ||
measureItemsBatchSize, | ||
initialState, | ||
@@ -290,0 +294,0 @@ onStateChange, |
@@ -7,3 +7,2 @@ import shallowEqual from './shallowEqual' | ||
const START_FROM_INDEX = 0 | ||
const WATCH_CONTAINER_ELEMENT_TOP_COORDINATE_INTERVAL = 500 | ||
@@ -30,2 +29,3 @@ const WATCH_CONTAINER_ELEMENT_TOP_COORDINATE_MAX_DURATION = 3000 | ||
preserveScrollPositionAtBottomOnMount, | ||
measureItemsBatchSize, | ||
bypass, | ||
@@ -70,2 +70,4 @@ bypassBatchSize | ||
this.measureItemsBatchSize = measureItemsBatchSize === undefined ? 50 : measureItemsBatchSize | ||
if (onItemFirstRender) { | ||
@@ -125,3 +127,2 @@ this.onItemFirstRender = onItemFirstRender | ||
log('Items count', items.length) | ||
// log('Start from index', START_FROM_INDEX) | ||
if (estimatedItemHeight) { | ||
@@ -157,3 +158,3 @@ log('Estimated item height', estimatedItemHeight) | ||
if (itemsCount > 0) { | ||
firstShownItemIndex = Math.min(START_FROM_INDEX, itemsCount - 1) | ||
firstShownItemIndex = Math.min(0, itemsCount - 1) | ||
lastShownItemIndex = this.getLastShownItemIndex(firstShownItemIndex, itemsCount) | ||
@@ -414,7 +415,7 @@ } | ||
getVisibleItemIndexes(screenTop, screenBottom, listTop) { | ||
let showItemsFromIndex | ||
let showItemsToIndex | ||
let firstShownItemIndex | ||
let lastShownItemIndex | ||
let itemsHeight = 0 | ||
let redoLayoutAfterRender = false | ||
let i = START_FROM_INDEX | ||
let i = 0 | ||
while (i < this.getItemsCount()) { | ||
@@ -426,7 +427,7 @@ const height = this.itemHeights.get(i) | ||
log(`Item ${i} height hasn't been measured yet: render and redo layout`) | ||
if (showItemsFromIndex === undefined) { | ||
showItemsFromIndex = i | ||
if (firstShownItemIndex === undefined) { | ||
firstShownItemIndex = i | ||
} | ||
const heightLeft = screenBottom - (listTop + itemsHeight) | ||
showItemsToIndex = Math.min( | ||
lastShownItemIndex = Math.min( | ||
i + (this.getEstimatedItemsCount(heightLeft) - 1), | ||
@@ -442,6 +443,6 @@ // Guard against index overflow. | ||
// then start showing items from it. | ||
if (showItemsFromIndex === undefined) { | ||
if (firstShownItemIndex === undefined) { | ||
if (listTop + itemsHeight > screenTop) { | ||
log('First visible item index (including margin)', i) | ||
showItemsFromIndex = i | ||
firstShownItemIndex = i | ||
} | ||
@@ -459,5 +460,5 @@ } | ||
// to be in the viewport in reality the list isn't visible | ||
// in which case `showItemsFromIndex` will be `undefined`. | ||
if (showItemsFromIndex !== undefined) { | ||
showItemsToIndex = i | ||
// in which case `firstShownItemIndex` will be `undefined`. | ||
if (firstShownItemIndex !== undefined) { | ||
lastShownItemIndex = i | ||
} | ||
@@ -469,24 +470,39 @@ break | ||
// If there're no more items then the last item is the last one to show. | ||
if (showItemsFromIndex !== undefined && showItemsToIndex === undefined) { | ||
showItemsToIndex = this.getItemsCount() - 1 | ||
log('Last item index (is fully visible)', showItemsToIndex) | ||
if (firstShownItemIndex !== undefined && lastShownItemIndex === undefined) { | ||
lastShownItemIndex = this.getItemsCount() - 1 | ||
log('Last item index (is fully visible)', lastShownItemIndex) | ||
} | ||
// If scroll position is scheduled to be restored | ||
// after render then the anchor item must be rendered | ||
// and all the prepended items before it. | ||
// If scroll position is scheduled to be restored after render | ||
// then the anchor item must be rendered, and all the prepended | ||
// items before it, all in a single pass. This way, all the | ||
// prepended items could be measured right after the render | ||
// and the scroll position can then be immediately restored. | ||
if (this.restoreScrollAfterPrepend) { | ||
if (showItemsToIndex < this.restoreScrollAfterPrepend.index) { | ||
showItemsToIndex = this.restoreScrollAfterPrepend.index | ||
if (lastShownItemIndex < this.restoreScrollAfterPrepend.index) { | ||
lastShownItemIndex = this.restoreScrollAfterPrepend.index | ||
} | ||
// `showItemsFromIndex` is always `0` when prepending items. | ||
// No need to redo layout after render because all | ||
// prepended items are rendered in a single pass. | ||
// It removes the visual jitter otherwise happening | ||
// due to scroll position restoration waiting for | ||
// two layout cycles instead of one. | ||
// `firstShownItemIndex` is always `0` when prepending items. | ||
// And `lastShownItemIndex` always covers all prepended items in this case. | ||
// None of the prepended items have been rendered before, | ||
// so their heights are unknown. The code at the start of this function | ||
// did therefore set `redoLayoutAfterRender` to `true` | ||
// in order to render just the first prepended item in order to | ||
// measure it, and only then make a decision on how many other | ||
// prepended items to render. But since we've instructed the code | ||
// to show all of the prepended items at once, then no need to | ||
// "redo layout after render". Additionally, if `redoLayoutAfterRender` | ||
// was left `true` then there would be a short the visual "jitter" | ||
// happening due to scroll position restoration waiting for two | ||
// layout cycles instead of one. | ||
redoLayoutAfterRender = false | ||
} | ||
// If some items will be rendered in order to measure their height, | ||
// and it's not a `preserveScrollPositionOnPrependItems` case, | ||
// then limit the amount of such items being measured in a single pass. | ||
if (redoLayoutAfterRender && this.measureItemsBatchSize) { | ||
lastShownItemIndex = Math.min(lastShownItemIndex, firstShownItemIndex + this.measureItemsBatchSize) | ||
} | ||
return { | ||
firstShownItemIndex: showItemsFromIndex, | ||
lastShownItemIndex: showItemsToIndex, | ||
firstShownItemIndex, | ||
lastShownItemIndex, | ||
redoLayoutAfterRender | ||
@@ -497,7 +513,6 @@ } | ||
getOffscreenListShownItemIndexes() { | ||
const i = START_FROM_INDEX | ||
return { | ||
firstShownItemIndex: i, | ||
lastShownItemIndex: i, | ||
redoLayoutAfterRender: this.itemHeights.get(i) === undefined | ||
firstShownItemIndex: 0, | ||
lastShownItemIndex: 0, | ||
redoLayoutAfterRender: this.itemHeights.get(0) === undefined | ||
} | ||
@@ -532,3 +547,3 @@ } | ||
// Add all "before" items height. | ||
let i = START_FROM_INDEX | ||
let i = 0 | ||
while (i < firstShownItemIndex) { | ||
@@ -535,0 +550,0 @@ beforeItemsHeight += (this.itemHeights.get(i) || this.itemHeights.getAverage()) |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1072865
6792
382