virtual-scroller 1.7.6 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. package/CHANGELOG.md +29 -1
  2. package/README.md +139 -33
  3. package/babel.config.js +25 -0
  4. package/babel.js +5 -0
  5. package/bundle/index-bypass.html +1 -1
  6. package/bundle/index-dom.html +1 -1
  7. package/bundle/index-grid.html +1 -2
  8. package/bundle/index-scrollableContainer.html +1 -1
  9. package/bundle/index-tbody-scrollableContainer.html +2 -0
  10. package/bundle/index-tbody.html +2 -0
  11. package/bundle/virtual-scroller-dom.js +1 -1
  12. package/bundle/virtual-scroller-dom.js.map +1 -1
  13. package/bundle/virtual-scroller-react.js +1 -1
  14. package/bundle/virtual-scroller-react.js.map +1 -1
  15. package/bundle/virtual-scroller.js +1 -1
  16. package/bundle/virtual-scroller.js.map +1 -1
  17. package/commonjs/BeforeResize.js +319 -0
  18. package/commonjs/BeforeResize.js.map +1 -0
  19. package/commonjs/DOM/Engine.js +46 -0
  20. package/commonjs/DOM/Engine.js.map +1 -0
  21. package/commonjs/DOM/ItemsContainer.js +78 -0
  22. package/commonjs/DOM/ItemsContainer.js.map +1 -0
  23. package/commonjs/DOM/{WaitForStylesToLoad.js → ListTopOffsetWatcher.js} +56 -35
  24. package/commonjs/DOM/ListTopOffsetWatcher.js.map +1 -0
  25. package/commonjs/DOM/ScrollableContainer.js +56 -81
  26. package/commonjs/DOM/ScrollableContainer.js.map +1 -1
  27. package/commonjs/DOM/VirtualScroller.js +20 -15
  28. package/commonjs/DOM/VirtualScroller.js.map +1 -1
  29. package/commonjs/DOM/tbody.js +2 -2
  30. package/commonjs/ItemHeights.js +13 -20
  31. package/commonjs/ItemHeights.js.map +1 -1
  32. package/commonjs/Layout.js +588 -215
  33. package/commonjs/Layout.js.map +1 -1
  34. package/commonjs/Layout.test.js +191 -0
  35. package/commonjs/Layout.test.js.map +1 -0
  36. package/commonjs/ListHeightChangeWatcher.js +126 -0
  37. package/commonjs/ListHeightChangeWatcher.js.map +1 -0
  38. package/commonjs/Resize.js +22 -21
  39. package/commonjs/Resize.js.map +1 -1
  40. package/commonjs/Scroll.js +148 -88
  41. package/commonjs/Scroll.js.map +1 -1
  42. package/commonjs/VirtualScroller.js +1269 -390
  43. package/commonjs/VirtualScroller.js.map +1 -1
  44. package/commonjs/getItemCoordinates.js.map +1 -1
  45. package/commonjs/getItemsDiff.js.map +1 -1
  46. package/commonjs/getVerticalSpacing.js +8 -8
  47. package/commonjs/getVerticalSpacing.js.map +1 -1
  48. package/commonjs/react/VirtualScroller.js +31 -37
  49. package/commonjs/react/VirtualScroller.js.map +1 -1
  50. package/commonjs/utility/debounce.js +26 -4
  51. package/commonjs/utility/debounce.js.map +1 -1
  52. package/commonjs/utility/debug.js +51 -12
  53. package/commonjs/utility/debug.js.map +1 -1
  54. package/commonjs/utility/getStateSnapshot.js +50 -0
  55. package/commonjs/utility/getStateSnapshot.js.map +1 -0
  56. package/commonjs/utility/px.js +1 -1
  57. package/commonjs/utility/px.js.map +1 -1
  58. package/commonjs/utility/px.test.js +14 -0
  59. package/commonjs/utility/px.test.js.map +1 -0
  60. package/commonjs/utility/shallowEqual.js +1 -1
  61. package/commonjs/utility/shallowEqual.js.map +1 -1
  62. package/commonjs/utility/throttle.js.map +1 -1
  63. package/dom/index.d.ts +23 -0
  64. package/index.d.ts +84 -0
  65. package/modules/BeforeResize.js +310 -0
  66. package/modules/BeforeResize.js.map +1 -0
  67. package/modules/DOM/Engine.js +27 -0
  68. package/modules/DOM/Engine.js.map +1 -0
  69. package/modules/DOM/ItemsContainer.js +71 -0
  70. package/modules/DOM/ItemsContainer.js.map +1 -0
  71. package/modules/DOM/{WaitForStylesToLoad.js → ListTopOffsetWatcher.js} +57 -35
  72. package/modules/DOM/ListTopOffsetWatcher.js.map +1 -0
  73. package/modules/DOM/ScrollableContainer.js +55 -80
  74. package/modules/DOM/ScrollableContainer.js.map +1 -1
  75. package/modules/DOM/VirtualScroller.js +15 -14
  76. package/modules/DOM/VirtualScroller.js.map +1 -1
  77. package/modules/ItemHeights.js +8 -19
  78. package/modules/ItemHeights.js.map +1 -1
  79. package/modules/Layout.js +582 -213
  80. package/modules/Layout.js.map +1 -1
  81. package/modules/Layout.test.js +185 -0
  82. package/modules/Layout.test.js.map +1 -0
  83. package/modules/ListHeightChangeWatcher.js +119 -0
  84. package/modules/ListHeightChangeWatcher.js.map +1 -0
  85. package/modules/Resize.js +21 -20
  86. package/modules/Resize.js.map +1 -1
  87. package/modules/Scroll.js +148 -87
  88. package/modules/Scroll.js.map +1 -1
  89. package/modules/VirtualScroller.js +1263 -390
  90. package/modules/VirtualScroller.js.map +1 -1
  91. package/modules/getItemCoordinates.js.map +1 -1
  92. package/modules/getItemsDiff.js.map +1 -1
  93. package/modules/getVerticalSpacing.js +8 -8
  94. package/modules/getVerticalSpacing.js.map +1 -1
  95. package/modules/react/VirtualScroller.js +31 -37
  96. package/modules/react/VirtualScroller.js.map +1 -1
  97. package/modules/utility/debounce.js +26 -4
  98. package/modules/utility/debounce.js.map +1 -1
  99. package/modules/utility/debug.js +47 -10
  100. package/modules/utility/debug.js.map +1 -1
  101. package/modules/utility/getStateSnapshot.js +43 -0
  102. package/modules/utility/getStateSnapshot.js.map +1 -0
  103. package/modules/utility/px.js +1 -1
  104. package/modules/utility/px.js.map +1 -1
  105. package/modules/utility/px.test.js +9 -0
  106. package/modules/utility/px.test.js.map +1 -0
  107. package/modules/utility/shallowEqual.js +1 -1
  108. package/modules/utility/shallowEqual.js.map +1 -1
  109. package/modules/utility/throttle.js.map +1 -1
  110. package/package.json +24 -22
  111. package/react/index.d.ts +27 -0
  112. package/source/BeforeResize.js +317 -0
  113. package/source/DOM/Engine.js +32 -0
  114. package/source/DOM/ItemsContainer.js +48 -0
  115. package/source/DOM/{WaitForStylesToLoad.js → ListTopOffsetWatcher.js} +48 -22
  116. package/source/DOM/ScrollableContainer.js +39 -56
  117. package/source/DOM/VirtualScroller.js +6 -7
  118. package/source/ItemHeights.js +10 -15
  119. package/source/Layout.js +626 -252
  120. package/source/Layout.test.js +171 -0
  121. package/source/ListHeightChangeWatcher.js +94 -0
  122. package/source/Resize.js +23 -15
  123. package/source/Scroll.js +139 -78
  124. package/source/VirtualScroller.js +1240 -286
  125. package/source/getVerticalSpacing.js +7 -7
  126. package/source/react/VirtualScroller.js +2 -18
  127. package/source/utility/debounce.js +20 -3
  128. package/source/utility/debug.js +34 -3
  129. package/source/utility/getStateSnapshot.js +36 -0
  130. package/source/utility/px.js +1 -1
  131. package/source/utility/px.test.js +9 -0
  132. package/website/index-bypass.html +195 -0
  133. package/website/index-grid.html +0 -1
  134. package/website/index-scrollableContainer.html +208 -0
  135. package/website/index-tbody-scrollableContainer.html +68 -0
  136. package/website/index-tbody.html +55 -0
  137. package/commonjs/DOM/RenderingEngine.js +0 -33
  138. package/commonjs/DOM/RenderingEngine.js.map +0 -1
  139. package/commonjs/DOM/Screen.js +0 -87
  140. package/commonjs/DOM/Screen.js.map +0 -1
  141. package/commonjs/DOM/WaitForStylesToLoad.js.map +0 -1
  142. package/commonjs/RestoreScroll.js +0 -118
  143. package/commonjs/RestoreScroll.js.map +0 -1
  144. package/modules/DOM/RenderingEngine.js +0 -19
  145. package/modules/DOM/RenderingEngine.js.map +0 -1
  146. package/modules/DOM/Screen.js +0 -80
  147. package/modules/DOM/Screen.js.map +0 -1
  148. package/modules/DOM/WaitForStylesToLoad.js.map +0 -1
  149. package/modules/RestoreScroll.js +0 -111
  150. package/modules/RestoreScroll.js.map +0 -1
  151. package/source/DOM/RenderingEngine.js +0 -22
  152. package/source/DOM/Screen.js +0 -51
  153. package/source/RestoreScroll.js +0 -86
@@ -1 +1 @@
1
- {"version":3,"sources":["../source/Resize.js"],"names":["Resize","bypass","scrollableContainer","getContainerElement","updateLayout","resetStateAndLayout","isRendered","prevScrollableContainerWidth","scrollableContainerWidth","prevScrollableContainerHeight","scrollableContainerHeight","getWidth","getHeight","reason","LAYOUT_REASON","RESIZE","SCROLLABLE_CONTAINER_RESIZE_DEBOUNCE_INTERVAL","scrollableContainerUnlistenResize","onResize","container"],"mappings":";;;;;;;AAAA;;AACA;;;;;;;;;;;;IAEqBA,M;;;AACpB,wBAMG;AAAA;;AAAA,QALFC,MAKE,QALFA,MAKE;AAAA,QAJFC,mBAIE,QAJFA,mBAIE;AAAA,QAHFC,mBAGE,QAHFA,mBAGE;AAAA,QAFFC,YAEE,QAFFA,YAEE;AAAA,QADFC,mBACE,QADFA,mBACE;;AAAA;;AAAA,sCA8BQ,0BAAS,YAAM;AACzB;AACA;AACA,UAAI,CAAC,KAAI,CAACC,UAAV,EAAsB;AACrB;AACA;;AACD,UAAMC,4BAA4B,GAAG,KAAI,CAACC,wBAA1C;AACA,UAAMC,6BAA6B,GAAG,KAAI,CAACC,yBAA3C;AACA,MAAA,KAAI,CAACF,wBAAL,GAAgC,KAAI,CAACN,mBAAL,CAAyBS,QAAzB,EAAhC;AACA,MAAA,KAAI,CAACD,yBAAL,GAAiC,KAAI,CAACR,mBAAL,CAAyBU,SAAzB,EAAjC;;AACA,UAAI,KAAI,CAACJ,wBAAL,KAAkCD,4BAAtC,EAAoE;AACnE,YAAI,KAAI,CAACG,yBAAL,KAAmCD,6BAAvC,EAAsE;AACrE;AACA;AACA;AACA,SAJD,MAIO;AACN;AACA;AACA;AACA,UAAA,KAAI,CAACL,YAAL,CAAkB;AAAES,YAAAA,MAAM,EAAEC,sBAAcC;AAAxB,WAAlB;AACA;AACD,OAXD,MAWO;AACN;AACA;AACA;AACA;AACA,QAAA,KAAI,CAACV,mBAAL;AACA;AACD,KA5BU,EA4BRW,6CA5BQ,CA9BR;;AACF,SAAKf,MAAL,GAAcA,MAAd;AACA,SAAKC,mBAAL,GAA2BA,mBAA3B;AACA,SAAKC,mBAAL,GAA2BA,mBAA3B;AACA,SAAKC,YAAL,GAAoBA,YAApB;AACA,SAAKC,mBAAL,GAA2BA,mBAA3B;AACA;;;;6BAEQ;AACR,UAAI,KAAKJ,MAAT,EAAiB;AAChB;AACA;;AACD,WAAKK,UAAL,GAAkB,IAAlB;AACA,WAAKE,wBAAL,GAAgC,KAAKN,mBAAL,CAAyBS,QAAzB,EAAhC;AACA,WAAKD,yBAAL,GAAiC,KAAKR,mBAAL,CAAyBU,SAAzB,EAAjC;AACA,WAAKK,iCAAL,GAAyC,KAAKf,mBAAL,CAAyBgB,QAAzB,CAAkC,KAAKA,QAAvC,EAAiD;AACzFC,QAAAA,SAAS,EAAE,KAAKhB,mBAAL;AAD8E,OAAjD,CAAzC;AAGA;;;2BAEM;AACN,WAAKG,UAAL,GAAkB,KAAlB;;AACA,UAAI,KAAKW,iCAAT,EAA4C;AAC3C,aAAKA,iCAAL;AACA;AACD;AAED;;;;;;;;;;AAkCD,IAAMD,6CAA6C,GAAG,GAAtD","sourcesContent":["import { LAYOUT_REASON } from './Layout'\r\nimport debounce from './utility/debounce'\r\n\r\nexport default class Resize {\r\n\tconstructor({\r\n\t\tbypass,\r\n\t\tscrollableContainer,\r\n\t\tgetContainerElement,\r\n\t\tupdateLayout,\r\n\t\tresetStateAndLayout\r\n\t}) {\r\n\t\tthis.bypass = bypass\r\n\t\tthis.scrollableContainer = scrollableContainer\r\n\t\tthis.getContainerElement = getContainerElement\r\n\t\tthis.updateLayout = updateLayout\r\n\t\tthis.resetStateAndLayout = resetStateAndLayout\r\n\t}\r\n\r\n\tlisten() {\r\n\t\tif (this.bypass) {\r\n\t\t\treturn\r\n\t\t}\r\n\t\tthis.isRendered = true\r\n\t\tthis.scrollableContainerWidth = this.scrollableContainer.getWidth()\r\n\t\tthis.scrollableContainerHeight = this.scrollableContainer.getHeight()\r\n\t\tthis.scrollableContainerUnlistenResize = this.scrollableContainer.onResize(this.onResize, {\r\n\t\t\tcontainer: this.getContainerElement()\r\n\t\t})\r\n\t}\r\n\r\n\tstop() {\r\n\t\tthis.isRendered = false\r\n\t\tif (this.scrollableContainerUnlistenResize) {\r\n\t\t\tthis.scrollableContainerUnlistenResize()\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * On scrollable container resize.\r\n\t */\r\n\tonResize = debounce(() => {\r\n\t\t// If `VirtualScroller` has been unmounted\r\n\t\t// while `debounce()`'s `setTimeout()` was waiting, then exit.\r\n\t\tif (!this.isRendered) {\r\n\t\t\treturn\r\n\t\t}\r\n\t\tconst prevScrollableContainerWidth = this.scrollableContainerWidth\r\n\t\tconst prevScrollableContainerHeight = this.scrollableContainerHeight\r\n\t\tthis.scrollableContainerWidth = this.scrollableContainer.getWidth()\r\n\t\tthis.scrollableContainerHeight = this.scrollableContainer.getHeight()\r\n\t\tif (this.scrollableContainerWidth === prevScrollableContainerWidth) {\r\n\t\t\tif (this.scrollableContainerHeight === prevScrollableContainerHeight) {\r\n\t\t\t\t// The dimensions of the container didn't change,\r\n\t\t\t\t// so there's no need to re-layout anything.\r\n\t\t\t\treturn\r\n\t\t\t} else {\r\n\t\t\t\t// Scrollable container height has changed,\r\n\t\t\t\t// so just recalculate shown item indexes.\r\n\t\t\t\t// No need to perform a re-layout from scratch.\r\n\t\t\t\tthis.updateLayout({ reason: LAYOUT_REASON.RESIZE })\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\t// Reset item heights, because if scrollable container's width (or height)\r\n\t\t\t// has changed, then the list width (or height) most likely also has changed,\r\n\t\t\t// and also some CSS `@media()` rules might have been added or removed.\r\n\t\t\t// So re-render the list entirely.\r\n\t\t\tthis.resetStateAndLayout()\r\n\t\t}\r\n\t}, SCROLLABLE_CONTAINER_RESIZE_DEBOUNCE_INTERVAL)\r\n}\r\n\r\nconst SCROLLABLE_CONTAINER_RESIZE_DEBOUNCE_INTERVAL = 250"],"file":"Resize.js"}
1
+ {"version":3,"sources":["../source/Resize.js"],"names":["Resize","bypass","scrollableContainer","onStart","onStop","onHeightChange","onWidthChange","onNoChange","isRendered","prevScrollableContainerWidth","scrollableContainerWidth","prevScrollableContainerHeight","scrollableContainerHeight","getWidth","getHeight","onResize","_onResize","SCROLLABLE_CONTAINER_RESIZE_DEBOUNCE_INTERVAL","scrollableContainerUnlistenResize","undefined"],"mappings":";;;;;;;AAAA;;AACA;;;;;;;;;;;;IAEqBA,M;AACpB,wBAQG;AAAA;;AAAA,QAPFC,MAOE,QAPFA,MAOE;AAAA,QANFC,mBAME,QANFA,mBAME;AAAA,QALFC,OAKE,QALFA,OAKE;AAAA,QAJFC,MAIE,QAJFA,MAIE;AAAA,QAHFC,cAGE,QAHFA,cAGE;AAAA,QAFFC,aAEE,QAFFA,aAEE;AAAA,QADFC,UACE,QADFA,UACE;;AAAA;;AAAA,uCAoCS,YAAM;AACjB;AACA;AACA,UAAI,CAAC,KAAI,CAACC,UAAV,EAAsB;AACrB;AACA;;AACD,UAAMC,4BAA4B,GAAG,KAAI,CAACC,wBAA1C;AACA,UAAMC,6BAA6B,GAAG,KAAI,CAACC,yBAA3C;AACA,MAAA,KAAI,CAACF,wBAAL,GAAgC,KAAI,CAACR,mBAAL,CAAyBW,QAAzB,EAAhC;AACA,MAAA,KAAI,CAACD,yBAAL,GAAiC,KAAI,CAACV,mBAAL,CAAyBY,SAAzB,EAAjC;;AACA,UAAI,KAAI,CAACJ,wBAAL,KAAkCD,4BAAtC,EAAoE;AACnE,YAAI,KAAI,CAACG,yBAAL,KAAmCD,6BAAvC,EAAsE;AACrE;AACA;AACA,UAAA,KAAI,CAACJ,UAAL;AACA,SAJD,MAIO;AACN;AACA;AACA;AACA,UAAA,KAAI,CAACF,cAAL,CAAoBM,6BAApB,EAAmD,KAAI,CAACC,yBAAxD;AACA;AACD,OAXD,MAWO;AACN;AACA;AACA;AACA;AACA,QAAA,KAAI,CAACN,aAAL,CAAmBG,4BAAnB,EAAiD,KAAI,CAACC,wBAAtD;AACA;AACD,KAhEE;;AACF,SAAKT,MAAL,GAAcA,MAAd;AACA,SAAKC,mBAAL,GAA2BA,mBAA3B;AAEA,SAAKG,cAAL,GAAsBA,cAAtB;AACA,SAAKC,aAAL,GAAqBA,aAArB;AACA,SAAKC,UAAL,GAAkBA,UAAlB;AAEA,SAAKQ,QAAL,GAAgB,0BACf,KAAKC,SADU,EAEfC,6CAFe,EAGf;AAAEd,MAAAA,OAAO,EAAPA,OAAF;AAAWC,MAAAA,MAAM,EAANA;AAAX,KAHe,CAAhB;AAKA;;;;WAED,kBAAS;AACR,UAAI,KAAKH,MAAT,EAAiB;AAChB;AACA;;AACD,WAAKO,UAAL,GAAkB,IAAlB;AACA,WAAKE,wBAAL,GAAgC,KAAKR,mBAAL,CAAyBW,QAAzB,EAAhC;AACA,WAAKD,yBAAL,GAAiC,KAAKV,mBAAL,CAAyBY,SAAzB,EAAjC;AACA,WAAKI,iCAAL,GAAyC,KAAKhB,mBAAL,CAAyBa,QAAzB,CAAkC,KAAKA,QAAvC,CAAzC;AACA;;;WAED,gBAAO;AACN,WAAKP,UAAL,GAAkB,KAAlB;;AACA,UAAI,KAAKU,iCAAT,EAA4C;AAC3C,aAAKA,iCAAL;AACA,aAAKA,iCAAL,GAAyCC,SAAzC;AACA;AACD;AAED;AACD;AACA;;;;;;;;AAgCA,IAAMF,6CAA6C,GAAG,GAAtD","sourcesContent":["import debounce from './utility/debounce'\r\nimport log from './utility/debug'\r\n\r\nexport default class Resize {\r\n\tconstructor({\r\n\t\tbypass,\r\n\t\tscrollableContainer,\r\n\t\tonStart,\r\n\t\tonStop,\r\n\t\tonHeightChange,\r\n\t\tonWidthChange,\r\n\t\tonNoChange\r\n\t}) {\r\n\t\tthis.bypass = bypass\r\n\t\tthis.scrollableContainer = scrollableContainer\r\n\r\n\t\tthis.onHeightChange = onHeightChange\r\n\t\tthis.onWidthChange = onWidthChange\r\n\t\tthis.onNoChange = onNoChange\r\n\r\n\t\tthis.onResize = debounce(\r\n\t\t\tthis._onResize,\r\n\t\t\tSCROLLABLE_CONTAINER_RESIZE_DEBOUNCE_INTERVAL,\r\n\t\t\t{ onStart, onStop }\r\n\t\t)\r\n\t}\r\n\r\n\tlisten() {\r\n\t\tif (this.bypass) {\r\n\t\t\treturn\r\n\t\t}\r\n\t\tthis.isRendered = true\r\n\t\tthis.scrollableContainerWidth = this.scrollableContainer.getWidth()\r\n\t\tthis.scrollableContainerHeight = this.scrollableContainer.getHeight()\r\n\t\tthis.scrollableContainerUnlistenResize = this.scrollableContainer.onResize(this.onResize)\r\n\t}\r\n\r\n\tstop() {\r\n\t\tthis.isRendered = false\r\n\t\tif (this.scrollableContainerUnlistenResize) {\r\n\t\t\tthis.scrollableContainerUnlistenResize()\r\n\t\t\tthis.scrollableContainerUnlistenResize = undefined\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * On scrollable container resize.\r\n\t */\r\n\t_onResize = () => {\r\n\t\t// If `VirtualScroller` has been unmounted\r\n\t\t// while `debounce()`'s `setTimeout()` was waiting, then exit.\r\n\t\tif (!this.isRendered) {\r\n\t\t\treturn\r\n\t\t}\r\n\t\tconst prevScrollableContainerWidth = this.scrollableContainerWidth\r\n\t\tconst prevScrollableContainerHeight = this.scrollableContainerHeight\r\n\t\tthis.scrollableContainerWidth = this.scrollableContainer.getWidth()\r\n\t\tthis.scrollableContainerHeight = this.scrollableContainer.getHeight()\r\n\t\tif (this.scrollableContainerWidth === prevScrollableContainerWidth) {\r\n\t\t\tif (this.scrollableContainerHeight === prevScrollableContainerHeight) {\r\n\t\t\t\t// The dimensions of the container didn't change,\r\n\t\t\t\t// so there's no need to re-layout anything.\r\n\t\t\t\tthis.onNoChange()\r\n\t\t\t} else {\r\n\t\t\t\t// Scrollable container height has changed,\r\n\t\t\t\t// so just recalculate shown item indexes.\r\n\t\t\t\t// No need to perform a re-layout from scratch.\r\n\t\t\t\tthis.onHeightChange(prevScrollableContainerHeight, this.scrollableContainerHeight)\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\t// Reset item heights, because if scrollable container's width (or height)\r\n\t\t\t// has changed, then the list width (or height) most likely also has changed,\r\n\t\t\t// and also some CSS `@media()` rules might have been added or removed.\r\n\t\t\t// So re-render the list entirely.\r\n\t\t\tthis.onWidthChange(prevScrollableContainerWidth, this.scrollableContainerWidth)\r\n\t\t}\r\n\t}\r\n}\r\n\r\nconst SCROLLABLE_CONTAINER_RESIZE_DEBOUNCE_INTERVAL = 250"],"file":"Resize.js"}
@@ -7,8 +7,6 @@ exports["default"] = void 0;
7
7
 
8
8
  var _requestAnimationFrameTimeout = require("request-animation-frame-timeout");
9
9
 
10
- var _Layout = require("./Layout");
11
-
12
10
  var _debug = _interopRequireDefault(require("./utility/debug"));
13
11
 
14
12
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
@@ -21,100 +19,120 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
21
19
 
22
20
  function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
23
21
 
24
- var Scroll =
25
- /*#__PURE__*/
26
- function () {
22
+ var Scroll = /*#__PURE__*/function () {
27
23
  function Scroll(_ref) {
28
24
  var _this = this;
29
25
 
30
26
  var bypass = _ref.bypass,
31
27
  scrollableContainer = _ref.scrollableContainer,
32
- updateLayout = _ref.updateLayout,
28
+ itemsContainer = _ref.itemsContainer,
29
+ onScroll = _ref.onScroll,
33
30
  initialScrollPosition = _ref.initialScrollPosition,
34
31
  onScrollPositionChange = _ref.onScrollPositionChange,
35
32
  isImmediateLayoutScheduled = _ref.isImmediateLayoutScheduled,
36
33
  hasNonRenderedItemsAtTheTop = _ref.hasNonRenderedItemsAtTheTop,
37
34
  hasNonRenderedItemsAtTheBottom = _ref.hasNonRenderedItemsAtTheBottom,
38
- getLatestLayoutVisibleAreaIncludingMargins = _ref.getLatestLayoutVisibleAreaIncludingMargins,
39
- preserveScrollPositionOfTheBottomOfTheListOnMount = _ref.preserveScrollPositionOfTheBottomOfTheListOnMount;
35
+ getLatestLayoutVisibleArea = _ref.getLatestLayoutVisibleArea,
36
+ getListTopOffset = _ref.getListTopOffset,
37
+ getPrerenderMargin = _ref.getPrerenderMargin,
38
+ onScrolledToTop = _ref.onScrolledToTop,
39
+ waitForScrollingToStop = _ref.waitForScrollingToStop;
40
40
 
41
41
  _classCallCheck(this, Scroll);
42
42
 
43
- _defineProperty(this, "updateScrollPosition", function () {
44
- _this.onScrollPositionChange(_this.getScrollY());
43
+ _defineProperty(this, "scrollByY", function (scrollByY) {
44
+ _this.scrollToY(_this.getScrollY() + scrollByY);
45
45
  });
46
46
 
47
- _defineProperty(this, "onScroll", function () {
48
- // Prefer not performing a re-layout while the user is scrolling (if possible).
47
+ _defineProperty(this, "onScrollListener", function () {
48
+ if (_this.onScrollPositionChange) {
49
+ _this.onScrollPositionChange(_this.getScrollY());
50
+ } // If the user has scrolled up to the top of the items container.
51
+ // (this option isn't currently used)
52
+
53
+
54
+ if (_this.onScrolledToTop) {
55
+ if (_this.getScrollY() < _this.getListTopOffset()) {
56
+ _this.onScrolledToTop();
57
+ }
58
+ }
59
+
60
+ if (_this.bypass) {
61
+ return;
62
+ }
63
+
64
+ if (_this.ignoreScrollEvents) {
65
+ return;
66
+ } // Prefer not performing a re-layout while the user is scrolling (if possible).
49
67
  // If the user doesn't scroll too far and then stops for a moment,
50
68
  // then a mid-scroll re-layout could be delayed until such a brief stop:
51
69
  // presumably, this results in better (smoother) scrolling performance,
52
70
  // delaying the work to when it doesn't introduce any stutter or "jank".
53
- // Reset `this.onUserStopsScrollingTimer` (will be re-created below).
54
- _this.cancelOnUserStopsScrollingTimer(); // See whether rendering "new" previous/next items is required
55
- // right now, or it can wait until the user stops scrolling.
71
+ // Reset `this.onStopScrollingTimer` (will be re-created below).
72
+
73
+
74
+ _this.cancelOnStopScrollingTimer(); // See if the latest "layout" (the currently rendered set of items)
75
+ // is still sufficient in order to show all the items that're
76
+ // currently inside the viewport. If there're some non-rendered items
77
+ // that're visible in the current viewport, then those items
78
+ // should be rendered "immediately" rather than waiting until
79
+ // the user stops scrolling.
56
80
 
57
81
 
58
82
  var forceUpdate = // If the items have been rendered at least once
59
- _this.getLatestLayoutVisibleAreaIncludingMargins() && ( // If the user has scrolled up past the extra "margin"
60
- _this.getScrollY() < _this.getLatestLayoutVisibleAreaIncludingMargins().top && // and if there're any previous non-rendered items to render.
61
- _this.hasNonRenderedItemsAtTheTop() || // If the user has scrolled down past the extra "margin"
62
- _this.getScrollY() + _this.scrollableContainer.getHeight() > _this.getLatestLayoutVisibleAreaIncludingMargins().bottom && // and if there're any next non-rendered items to render.
63
- _this.hasNonRenderedItemsAtTheBottom());
83
+ _this.getLatestLayoutVisibleArea() && ( // If the user has scrolled up past the "prerender margin"
84
+ // and there're some non-rendered items at the top,
85
+ // then force a re-layout.
86
+ //
87
+ // (during these calculations we assume that the list's top coordinate
88
+ // hasn't changed since previous layout; even if that's not exactly true,
89
+ // the items will be re-layout when the user stops scrolling anyway)
90
+ //
91
+ _this.getScrollY() < _this.getLatestLayoutVisibleArea().top - _this.getPrerenderMargin() && _this.hasNonRenderedItemsAtTheTop() || // If the user has scrolled down past the "prerender margin"
92
+ // and there're any non-rendered items left at the end,
93
+ // then force a re-layout.
94
+ //
95
+ // (during these calculations we assume that the list's top coordinate
96
+ // hasn't changed since previous layout; even if that's not exactly true,
97
+ // the items will be re-layout when the user stops scrolling anyway)
98
+ //
99
+ _this.getScrollY() + _this.scrollableContainer.getHeight() > _this.getLatestLayoutVisibleArea().bottom + _this.getPrerenderMargin() && _this.hasNonRenderedItemsAtTheBottom());
64
100
 
65
101
  if (forceUpdate) {
66
- (0, _debug["default"])('The user has scrolled far enough: force re-layout');
102
+ (0, _debug["default"])('The user has scrolled far enough: perform a re-layout');
67
103
  } else {
68
- (0, _debug["default"])('The user hasn\'t scrolled too much: delay re-layout');
104
+ (0, _debug["default"])('The user is scrolling: perform a re-layout when they stop scrolling');
69
105
  }
70
106
 
71
- if (!forceUpdate) {
72
- // If a re-layout is already scheduled at the next "frame",
73
- // don't schedule a "re-layout when user stops scrolling" timer.
74
- if (_this.isImmediateLayoutScheduled()) {
75
- return;
76
- }
107
+ if (forceUpdate || _this.waitForScrollingToStop === false) {
108
+ return _this.onScroll();
109
+ } // If a re-layout is already scheduled at the next "frame",
110
+ // don't schedule a "re-layout when user stops scrolling" timer.
77
111
 
78
- _this.onUserStopsScrollingTimer = (0, _requestAnimationFrameTimeout.setTimeout)(function () {
79
- _this.onUserStopsScrollingTimer = undefined;
80
112
 
81
- _this.updateLayout({
82
- reason: _Layout.LAYOUT_REASON.STOPPED_SCROLLING
83
- });
84
- }, // "scroll" events are usually dispatched every 16 milliseconds
85
- // for 60fps refresh rate, so waiting for 100 milliseconds feels
86
- // reasonable: that would be about 6 frames of inactivity period,
87
- // which could mean that either the user has stopped scrolling
88
- // (for a moment) or the browser is lagging and stuttering
89
- // (skipping frames due to high load).
90
- // If the user continues scrolling then this timeout is constantly
91
- // refreshed (cancelled and then re-created).
92
- WAIT_FOR_USER_TO_STOP_SCROLLING_TIMEOUT);
113
+ if (_this.isImmediateLayoutScheduled()) {
93
114
  return;
94
115
  }
95
116
 
96
- _this.updateLayout({
97
- reason: _Layout.LAYOUT_REASON.SCROLL
98
- });
117
+ _this.onScrollOnStopScrolling = true;
118
+
119
+ _this.watchOnStopScrolling();
99
120
  });
100
121
 
101
122
  this.bypass = bypass;
102
123
  this.scrollableContainer = scrollableContainer;
103
- this.updateLayout = updateLayout;
124
+ this.itemsContainer = itemsContainer;
125
+ this.onScroll = onScroll;
104
126
  this.initialScrollPosition = initialScrollPosition;
105
127
  this.onScrollPositionChange = onScrollPositionChange;
106
128
  this.isImmediateLayoutScheduled = isImmediateLayoutScheduled;
107
129
  this.hasNonRenderedItemsAtTheTop = hasNonRenderedItemsAtTheTop;
108
130
  this.hasNonRenderedItemsAtTheBottom = hasNonRenderedItemsAtTheBottom;
109
- this.getLatestLayoutVisibleAreaIncludingMargins = getLatestLayoutVisibleAreaIncludingMargins;
110
-
111
- if (preserveScrollPositionOfTheBottomOfTheListOnMount) {
112
- if (scrollableContainer) {
113
- this.preserveScrollPositionOfTheBottomOfTheListOnMount = {
114
- scrollableContainerContentHeight: scrollableContainer.getContentHeight()
115
- };
116
- }
117
- }
131
+ this.getLatestLayoutVisibleArea = getLatestLayoutVisibleArea;
132
+ this.getListTopOffset = getListTopOffset;
133
+ this.getPrerenderMargin = getPrerenderMargin;
134
+ this.onScrolledToTop = onScrolledToTop;
135
+ this.waitForScrollingToStop = waitForScrollingToStop;
118
136
  }
119
137
 
120
138
  _createClass(Scroll, [{
@@ -125,71 +143,113 @@ function () {
125
143
  }
126
144
 
127
145
  if (this.onScrollPositionChange) {
128
- this.updateScrollPosition();
129
- this.removeScrollPositionListener = this.scrollableContainer.addScrollListener(this.updateScrollPosition);
146
+ this.onScrollPositionChange(this.getScrollY());
130
147
  }
131
148
 
132
- if (!this.bypass) {
133
- this.removeScrollListener = this.scrollableContainer.addScrollListener(this.onScroll);
134
- }
135
-
136
- if (this.preserveScrollPositionOfTheBottomOfTheListOnMount) {
137
- this.scrollToY(this.getScrollY() + (this.scrollableContainer.getContentHeight() - this.preserveScrollPositionOfTheBottomOfTheListOnMount.scrollableContainerContentHeight));
138
- }
149
+ this.stopListeningToScroll = this.scrollableContainer.onScroll(this.onScrollListener);
139
150
  }
140
151
  }, {
141
152
  key: "stop",
142
153
  value: function stop() {
143
- if (this.removeScrollPositionListener) {
144
- this.removeScrollPositionListener();
154
+ if (this.stopReportingScrollPositionChange) {
155
+ this.stopReportingScrollPositionChange();
156
+ this.stopReportingScrollPositionChange = undefined;
157
+ }
158
+
159
+ if (this.stopListeningToScroll) {
160
+ this.stopListeningToScroll();
161
+ this.stopListeningToScroll = undefined;
145
162
  }
146
163
 
147
- if (this.removeScrollListener) {
148
- this.removeScrollListener();
164
+ if (this.onStopScrollingListener) {
165
+ this.onStopScrollingListener = undefined;
149
166
  }
150
167
 
151
- this.cancelOnUserStopsScrollingTimer();
168
+ if (this.onScrollOnStopScrolling) {
169
+ this.onScrollOnStopScrolling = undefined;
170
+ }
171
+
172
+ this.cancelOnStopScrollingTimer();
152
173
  }
153
174
  }, {
154
175
  key: "scrollToY",
155
176
  value: function scrollToY(scrollY) {
177
+ this.ignoreScrollEvents = true;
156
178
  this.scrollableContainer.scrollToY(scrollY);
157
- }
158
- }, {
159
- key: "scrollByY",
160
- value: function scrollByY(_scrollByY) {
161
- this.scrollToY(this.getScrollY() + _scrollByY);
179
+ this.ignoreScrollEvents = undefined;
162
180
  }
163
181
  }, {
164
182
  key: "getScrollY",
165
183
  value: function getScrollY() {
166
184
  return this.scrollableContainer.getScrollY();
167
185
  }
168
- /**
169
- * Updates the current scroll Y position in state.
170
- */
171
-
172
186
  }, {
173
- key: "cancelOnUserStopsScrollingTimer",
174
- value: function cancelOnUserStopsScrollingTimer() {
175
- if (this.onUserStopsScrollingTimer) {
176
- (0, _requestAnimationFrameTimeout.clearTimeout)(this.onUserStopsScrollingTimer);
177
- this.onUserStopsScrollingTimer = undefined;
187
+ key: "cancelOnStopScrollingTimer",
188
+ value: function cancelOnStopScrollingTimer() {
189
+ if (this.onStopScrollingTimer) {
190
+ (0, _requestAnimationFrameTimeout.clearTimeout)(this.onStopScrollingTimer);
191
+ this.onStopScrollingTimer = undefined;
178
192
  }
179
193
  }
180
194
  }, {
181
- key: "onLayout",
182
- value: function onLayout() {
195
+ key: "cancelScheduledLayout",
196
+ value: function cancelScheduledLayout() {
183
197
  // Cancel a "re-layout when user stops scrolling" timer.
184
- this.cancelOnUserStopsScrollingTimer();
198
+ this.cancelOnStopScrollingTimer();
185
199
  }
186
200
  }, {
187
- key: "getVisibleAreaBounds",
201
+ key: "watchOnStopScrolling",
202
+ value: function watchOnStopScrolling() {
203
+ var _this2 = this;
204
+
205
+ this.onStopScrollingTimer = (0, _requestAnimationFrameTimeout.setTimeout)(function () {
206
+ _this2.onStopScrollingTimer = undefined;
188
207
 
208
+ if (_this2.onScrollOnStopScrolling) {
209
+ _this2.onScrollOnStopScrolling = undefined;
210
+
211
+ _this2.onScroll({
212
+ delayed: true
213
+ });
214
+ }
215
+
216
+ if (_this2.onStopScrollingListener) {
217
+ var onStopScrollingListener = _this2.onStopScrollingListener;
218
+ _this2.onStopScrollingListener = undefined; // `onStopScrollingListener()` may hypothetically schedule
219
+ // another `onStopScrolling()` listener, so set
220
+ // `this.onStopScrollingListener` to `undefined` before
221
+ // calling it rather than after.
222
+
223
+ (0, _debug["default"])('~ The user has stopped scrolling ~');
224
+ onStopScrollingListener();
225
+ }
226
+ }, // "scroll" events are usually dispatched every 16 milliseconds
227
+ // for 60fps refresh rate, so waiting for 100 milliseconds feels
228
+ // reasonable: that would be about 6 frames of inactivity period,
229
+ // which could mean that either the user has stopped scrolling
230
+ // (for a moment) or the browser is lagging and stuttering
231
+ // (skipping frames due to high load).
232
+ // If the user continues scrolling then this timeout is constantly
233
+ // refreshed (cancelled and then re-created).
234
+ ON_STOP_SCROLLING_INACTIVE_PERIOD);
235
+ } // (this function isn't currently used)
236
+
237
+ }, {
238
+ key: "onStopScrolling",
239
+ value: function onStopScrolling(onStopScrollingListener) {
240
+ this.onStopScrollingListener = onStopScrollingListener;
241
+
242
+ if (!this.onStopScrollingTimer) {
243
+ this.watchOnStopScrolling();
244
+ }
245
+ }
189
246
  /**
190
247
  * Returns visible area coordinates relative to the scrollable container.
191
248
  * @return {object} `{ top: number, bottom: number }`
192
249
  */
250
+
251
+ }, {
252
+ key: "getVisibleAreaBounds",
193
253
  value: function getVisibleAreaBounds() {
194
254
  var scrollY = this.getScrollY();
195
255
  return {
@@ -205,5 +265,5 @@ function () {
205
265
  }();
206
266
 
207
267
  exports["default"] = Scroll;
208
- var WAIT_FOR_USER_TO_STOP_SCROLLING_TIMEOUT = 100;
268
+ var ON_STOP_SCROLLING_INACTIVE_PERIOD = 100;
209
269
  //# sourceMappingURL=Scroll.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../source/Scroll.js"],"names":["Scroll","bypass","scrollableContainer","updateLayout","initialScrollPosition","onScrollPositionChange","isImmediateLayoutScheduled","hasNonRenderedItemsAtTheTop","hasNonRenderedItemsAtTheBottom","getLatestLayoutVisibleAreaIncludingMargins","preserveScrollPositionOfTheBottomOfTheListOnMount","getScrollY","cancelOnUserStopsScrollingTimer","forceUpdate","top","getHeight","bottom","onUserStopsScrollingTimer","undefined","reason","LAYOUT_REASON","STOPPED_SCROLLING","WAIT_FOR_USER_TO_STOP_SCROLLING_TIMEOUT","SCROLL","scrollableContainerContentHeight","getContentHeight","scrollToY","updateScrollPosition","removeScrollPositionListener","addScrollListener","removeScrollListener","onScroll","scrollY","scrollByY"],"mappings":"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","sourcesContent":["// For some weird reason, in Chrome, `setTimeout()` would lag up to a second (or more) behind.\r\n// Turns out, Chrome developers have deprecated `setTimeout()` API entirely without asking anyone.\r\n// Replacing `setTimeout()` with `requestAnimationFrame()` can work around that Chrome bug.\r\n// https://github.com/bvaughn/react-virtualized/issues/722\r\nimport { setTimeout, clearTimeout } from 'request-animation-frame-timeout'\r\n\r\nimport { LAYOUT_REASON } from './Layout'\r\nimport log from './utility/debug'\r\n\r\nexport default class Scroll {\r\n\tconstructor({\r\n\t\tbypass,\r\n\t\tscrollableContainer,\r\n\t\tupdateLayout,\r\n\t\tinitialScrollPosition,\r\n\t\tonScrollPositionChange,\r\n\t\tisImmediateLayoutScheduled,\r\n\t\thasNonRenderedItemsAtTheTop,\r\n\t\thasNonRenderedItemsAtTheBottom,\r\n\t\tgetLatestLayoutVisibleAreaIncludingMargins,\r\n\t\tpreserveScrollPositionOfTheBottomOfTheListOnMount\r\n\t}) {\r\n\t\tthis.bypass = bypass\r\n\t\tthis.scrollableContainer = scrollableContainer\r\n\t\tthis.updateLayout = updateLayout\r\n\t\tthis.initialScrollPosition = initialScrollPosition\r\n\t\tthis.onScrollPositionChange = onScrollPositionChange\r\n\t\tthis.isImmediateLayoutScheduled = isImmediateLayoutScheduled\r\n\t\tthis.hasNonRenderedItemsAtTheTop = hasNonRenderedItemsAtTheTop\r\n\t\tthis.hasNonRenderedItemsAtTheBottom = hasNonRenderedItemsAtTheBottom\r\n\t\tthis.getLatestLayoutVisibleAreaIncludingMargins = getLatestLayoutVisibleAreaIncludingMargins\r\n\r\n\t\tif (preserveScrollPositionOfTheBottomOfTheListOnMount) {\r\n\t\t\tif (scrollableContainer) {\r\n\t\t\t\tthis.preserveScrollPositionOfTheBottomOfTheListOnMount = {\r\n\t\t\t\t\tscrollableContainerContentHeight: scrollableContainer.getContentHeight()\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tlisten() {\r\n\t\tif (this.initialScrollPosition !== undefined) {\r\n\t\t\tthis.scrollToY(this.initialScrollPosition)\r\n\t\t}\r\n\t\tif (this.onScrollPositionChange) {\r\n\t\t\tthis.updateScrollPosition()\r\n\t\t\tthis.removeScrollPositionListener = this.scrollableContainer.addScrollListener(this.updateScrollPosition)\r\n\t\t}\r\n\t\tif (!this.bypass) {\r\n\t\t\tthis.removeScrollListener = this.scrollableContainer.addScrollListener(this.onScroll)\r\n\t\t}\r\n\t\tif (this.preserveScrollPositionOfTheBottomOfTheListOnMount) {\r\n\t\t\tthis.scrollToY(this.getScrollY() + (this.scrollableContainer.getContentHeight() - this.preserveScrollPositionOfTheBottomOfTheListOnMount.scrollableContainerContentHeight))\r\n\t\t}\r\n\t}\r\n\r\n\tstop() {\r\n\t\tif (this.removeScrollPositionListener) {\r\n\t\t\tthis.removeScrollPositionListener()\r\n\t\t}\r\n\t\tif (this.removeScrollListener) {\r\n\t\t\tthis.removeScrollListener()\r\n\t\t}\r\n\t\tthis.cancelOnUserStopsScrollingTimer()\r\n\t}\r\n\r\n\tscrollToY(scrollY) {\r\n\t\tthis.scrollableContainer.scrollToY(scrollY)\r\n\t}\r\n\r\n\tscrollByY(scrollByY) {\r\n\t\tthis.scrollToY(this.getScrollY() + scrollByY)\r\n\t}\r\n\r\n\tgetScrollY() {\r\n\t\treturn this.scrollableContainer.getScrollY()\r\n\t}\r\n\r\n\t/**\r\n\t * Updates the current scroll Y position in state.\r\n\t */\r\n\tupdateScrollPosition = () => {\r\n\t\tthis.onScrollPositionChange(this.getScrollY())\r\n\t}\r\n\r\n\tcancelOnUserStopsScrollingTimer() {\r\n\t\tif (this.onUserStopsScrollingTimer) {\r\n\t\t\tclearTimeout(this.onUserStopsScrollingTimer)\r\n\t\t\tthis.onUserStopsScrollingTimer = undefined\r\n\t\t}\r\n\t}\r\n\r\n\tonLayout() {\r\n\t\t// Cancel a \"re-layout when user stops scrolling\" timer.\r\n\t\tthis.cancelOnUserStopsScrollingTimer()\r\n\t}\r\n\r\n\tonScroll = () => {\r\n\t\t// Prefer not performing a re-layout while the user is scrolling (if possible).\r\n\t\t// If the user doesn't scroll too far and then stops for a moment,\r\n\t\t// then a mid-scroll re-layout could be delayed until such a brief stop:\r\n\t\t// presumably, this results in better (smoother) scrolling performance,\r\n\t\t// delaying the work to when it doesn't introduce any stutter or \"jank\".\r\n\r\n\t\t// Reset `this.onUserStopsScrollingTimer` (will be re-created below).\r\n\t\tthis.cancelOnUserStopsScrollingTimer()\r\n\r\n\t\t// See whether rendering \"new\" previous/next items is required\r\n\t\t// right now, or it can wait until the user stops scrolling.\r\n\t\tconst forceUpdate =\r\n\t\t\t// If the items have been rendered at least once\r\n\t\t\tthis.getLatestLayoutVisibleAreaIncludingMargins() && (\r\n\t\t\t\t(\r\n\t\t\t\t\t// If the user has scrolled up past the extra \"margin\"\r\n\t\t\t\t\t(this.getScrollY() < this.getLatestLayoutVisibleAreaIncludingMargins().top) &&\r\n\t\t\t\t\t// and if there're any previous non-rendered items to render.\r\n\t\t\t\t\tthis.hasNonRenderedItemsAtTheTop()\r\n\t\t\t\t)\r\n\t\t\t\t||\r\n\t\t\t\t(\r\n\t\t\t\t\t// If the user has scrolled down past the extra \"margin\"\r\n\t\t\t\t\t(this.getScrollY() + this.scrollableContainer.getHeight() > this.getLatestLayoutVisibleAreaIncludingMargins().bottom) &&\r\n\t\t\t\t\t// and if there're any next non-rendered items to render.\r\n\t\t\t\t\tthis.hasNonRenderedItemsAtTheBottom()\r\n\t\t\t\t)\r\n\t\t\t)\r\n\r\n\t\tif (forceUpdate) {\r\n\t\t\tlog('The user has scrolled far enough: force re-layout')\r\n\t\t} else {\r\n\t\t\tlog('The user hasn\\'t scrolled too much: delay re-layout')\r\n\t\t}\r\n\r\n\t\tif (!forceUpdate) {\r\n\t\t\t// If a re-layout is already scheduled at the next \"frame\",\r\n\t\t\t// don't schedule a \"re-layout when user stops scrolling\" timer.\r\n\t\t\tif (this.isImmediateLayoutScheduled()) {\r\n\t\t\t\treturn\r\n\t\t\t}\r\n\t\t\tthis.onUserStopsScrollingTimer = setTimeout(\r\n\t\t\t\t() => {\r\n\t\t\t\t\tthis.onUserStopsScrollingTimer = undefined\r\n\t\t\t\t\tthis.updateLayout({ reason: LAYOUT_REASON.STOPPED_SCROLLING })\r\n\t\t\t\t},\r\n\t\t\t\t// \"scroll\" events are usually dispatched every 16 milliseconds\r\n\t\t\t\t// for 60fps refresh rate, so waiting for 100 milliseconds feels\r\n\t\t\t\t// reasonable: that would be about 6 frames of inactivity period,\r\n\t\t\t\t// which could mean that either the user has stopped scrolling\r\n\t\t\t\t// (for a moment) or the browser is lagging and stuttering\r\n\t\t\t\t// (skipping frames due to high load).\r\n\t\t\t\t// If the user continues scrolling then this timeout is constantly\r\n\t\t\t\t// refreshed (cancelled and then re-created).\r\n\t\t\t\tWAIT_FOR_USER_TO_STOP_SCROLLING_TIMEOUT\r\n\t\t\t)\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\tthis.updateLayout({ reason: LAYOUT_REASON.SCROLL })\r\n\t}\r\n\r\n\t/**\r\n\t * Returns visible area coordinates relative to the scrollable container.\r\n\t * @return {object} `{ top: number, bottom: number }`\r\n\t */\r\n\tgetVisibleAreaBounds() {\r\n\t\tconst scrollY = this.getScrollY()\r\n\t\treturn {\r\n\t\t\t// The first pixel of the screen.\r\n\t\t\ttop: scrollY,\r\n\t\t\t// The pixel after the last pixel of the screen.\r\n\t\t\tbottom: scrollY + this.scrollableContainer.getHeight()\r\n\t\t}\r\n\t}\r\n}\r\n\r\nconst WAIT_FOR_USER_TO_STOP_SCROLLING_TIMEOUT = 100"],"file":"Scroll.js"}
1
+ {"version":3,"sources":["../source/Scroll.js"],"names":["Scroll","bypass","scrollableContainer","itemsContainer","onScroll","initialScrollPosition","onScrollPositionChange","isImmediateLayoutScheduled","hasNonRenderedItemsAtTheTop","hasNonRenderedItemsAtTheBottom","getLatestLayoutVisibleArea","getListTopOffset","getPrerenderMargin","onScrolledToTop","waitForScrollingToStop","scrollByY","scrollToY","getScrollY","ignoreScrollEvents","cancelOnStopScrollingTimer","forceUpdate","top","getHeight","bottom","onScrollOnStopScrolling","watchOnStopScrolling","undefined","stopListeningToScroll","onScrollListener","stopReportingScrollPositionChange","onStopScrollingListener","scrollY","onStopScrollingTimer","delayed","ON_STOP_SCROLLING_INACTIVE_PERIOD"],"mappings":"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","sourcesContent":["// For some weird reason, in Chrome, `setTimeout()` would lag up to a second (or more) behind.\r\n// Turns out, Chrome developers have deprecated `setTimeout()` API entirely without asking anyone.\r\n// Replacing `setTimeout()` with `requestAnimationFrame()` can work around that Chrome bug.\r\n// https://github.com/bvaughn/react-virtualized/issues/722\r\nimport { setTimeout, clearTimeout } from 'request-animation-frame-timeout'\r\n\r\nimport log from './utility/debug'\r\n\r\nexport default class Scroll {\r\n\tconstructor({\r\n\t\tbypass,\r\n\t\tscrollableContainer,\r\n\t\titemsContainer,\r\n\t\tonScroll,\r\n\t\tinitialScrollPosition,\r\n\t\tonScrollPositionChange,\r\n\t\tisImmediateLayoutScheduled,\r\n\t\thasNonRenderedItemsAtTheTop,\r\n\t\thasNonRenderedItemsAtTheBottom,\r\n\t\tgetLatestLayoutVisibleArea,\r\n\t\tgetListTopOffset,\r\n\t\tgetPrerenderMargin,\r\n\t\tonScrolledToTop,\r\n\t\twaitForScrollingToStop\r\n\t}) {\r\n\t\tthis.bypass = bypass\r\n\t\tthis.scrollableContainer = scrollableContainer\r\n\t\tthis.itemsContainer = itemsContainer\r\n\t\tthis.onScroll = onScroll\r\n\t\tthis.initialScrollPosition = initialScrollPosition\r\n\t\tthis.onScrollPositionChange = onScrollPositionChange\r\n\t\tthis.isImmediateLayoutScheduled = isImmediateLayoutScheduled\r\n\t\tthis.hasNonRenderedItemsAtTheTop = hasNonRenderedItemsAtTheTop\r\n\t\tthis.hasNonRenderedItemsAtTheBottom = hasNonRenderedItemsAtTheBottom\r\n\t\tthis.getLatestLayoutVisibleArea = getLatestLayoutVisibleArea\r\n\t\tthis.getListTopOffset = getListTopOffset\r\n\t\tthis.getPrerenderMargin = getPrerenderMargin\r\n\t\tthis.onScrolledToTop = onScrolledToTop\r\n\t\tthis.waitForScrollingToStop = waitForScrollingToStop\r\n\t}\r\n\r\n\tlisten() {\r\n\t\tif (this.initialScrollPosition !== undefined) {\r\n\t\t\tthis.scrollToY(this.initialScrollPosition)\r\n\t\t}\r\n\t\tif (this.onScrollPositionChange) {\r\n\t\t\tthis.onScrollPositionChange(this.getScrollY())\r\n\t\t}\r\n\t\tthis.stopListeningToScroll = this.scrollableContainer.onScroll(this.onScrollListener)\r\n\t}\r\n\r\n\tstop() {\r\n\t\tif (this.stopReportingScrollPositionChange) {\r\n\t\t\tthis.stopReportingScrollPositionChange()\r\n\t\t\tthis.stopReportingScrollPositionChange = undefined\r\n\t\t}\r\n\t\tif (this.stopListeningToScroll) {\r\n\t\t\tthis.stopListeningToScroll()\r\n\t\t\tthis.stopListeningToScroll = undefined\r\n\t\t}\r\n\t\tif (this.onStopScrollingListener) {\r\n\t\t\tthis.onStopScrollingListener = undefined\r\n\t\t}\r\n\t\tif (this.onScrollOnStopScrolling) {\r\n\t\t\tthis.onScrollOnStopScrolling = undefined\r\n\t\t}\r\n\t\tthis.cancelOnStopScrollingTimer()\r\n\t}\r\n\r\n\tscrollToY(scrollY) {\r\n\t\tthis.ignoreScrollEvents = true\r\n\t\tthis.scrollableContainer.scrollToY(scrollY)\r\n\t\tthis.ignoreScrollEvents = undefined\r\n\t}\r\n\r\n\tscrollByY = (scrollByY) => {\r\n\t\tthis.scrollToY(this.getScrollY() + scrollByY)\r\n\t}\r\n\r\n\tgetScrollY() {\r\n\t\treturn this.scrollableContainer.getScrollY()\r\n\t}\r\n\r\n\tcancelOnStopScrollingTimer() {\r\n\t\tif (this.onStopScrollingTimer) {\r\n\t\t\tclearTimeout(this.onStopScrollingTimer)\r\n\t\t\tthis.onStopScrollingTimer = undefined\r\n\t\t}\r\n\t}\r\n\r\n\tcancelScheduledLayout() {\r\n\t\t// Cancel a \"re-layout when user stops scrolling\" timer.\r\n\t\tthis.cancelOnStopScrollingTimer()\r\n\t}\r\n\r\n\tonScrollListener = () => {\r\n\t\tif (this.onScrollPositionChange) {\r\n\t\t\tthis.onScrollPositionChange(this.getScrollY())\r\n\t\t}\r\n\r\n\t\t// If the user has scrolled up to the top of the items container.\r\n\t\t// (this option isn't currently used)\r\n\t\tif (this.onScrolledToTop) {\r\n\t\t\tif (this.getScrollY() < this.getListTopOffset()) {\r\n\t\t\t\tthis.onScrolledToTop()\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (this.bypass) {\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\tif (this.ignoreScrollEvents) {\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\t// Prefer not performing a re-layout while the user is scrolling (if possible).\r\n\t\t// If the user doesn't scroll too far and then stops for a moment,\r\n\t\t// then a mid-scroll re-layout could be delayed until such a brief stop:\r\n\t\t// presumably, this results in better (smoother) scrolling performance,\r\n\t\t// delaying the work to when it doesn't introduce any stutter or \"jank\".\r\n\r\n\t\t// Reset `this.onStopScrollingTimer` (will be re-created below).\r\n\t\tthis.cancelOnStopScrollingTimer()\r\n\r\n\t\t// See if the latest \"layout\" (the currently rendered set of items)\r\n\t\t// is still sufficient in order to show all the items that're\r\n\t\t// currently inside the viewport. If there're some non-rendered items\r\n\t\t// that're visible in the current viewport, then those items\r\n\t\t// should be rendered \"immediately\" rather than waiting until\r\n\t\t// the user stops scrolling.\r\n\t\tconst forceUpdate =\r\n\t\t\t// If the items have been rendered at least once\r\n\t\t\tthis.getLatestLayoutVisibleArea() && (\r\n\t\t\t\t(\r\n\t\t\t\t\t// If the user has scrolled up past the \"prerender margin\"\r\n\t\t\t\t\t// and there're some non-rendered items at the top,\r\n\t\t\t\t\t// then force a re-layout.\r\n\t\t\t\t\t//\r\n\t\t\t\t\t// (during these calculations we assume that the list's top coordinate\r\n\t\t\t\t\t// hasn't changed since previous layout; even if that's not exactly true,\r\n\t\t\t\t\t// the items will be re-layout when the user stops scrolling anyway)\r\n\t\t\t\t\t//\r\n\t\t\t\t\t(this.getScrollY() < this.getLatestLayoutVisibleArea().top - this.getPrerenderMargin()) &&\r\n\t\t\t\t\tthis.hasNonRenderedItemsAtTheTop()\r\n\t\t\t\t)\r\n\t\t\t\t||\r\n\t\t\t\t(\r\n\t\t\t\t\t// If the user has scrolled down past the \"prerender margin\"\r\n\t\t\t\t\t// and there're any non-rendered items left at the end,\r\n\t\t\t\t\t// then force a re-layout.\r\n\t\t\t\t\t//\r\n\t\t\t\t\t// (during these calculations we assume that the list's top coordinate\r\n\t\t\t\t\t// hasn't changed since previous layout; even if that's not exactly true,\r\n\t\t\t\t\t// the items will be re-layout when the user stops scrolling anyway)\r\n\t\t\t\t\t//\r\n\t\t\t\t\t(this.getScrollY() + this.scrollableContainer.getHeight() > this.getLatestLayoutVisibleArea().bottom + this.getPrerenderMargin()) &&\r\n\t\t\t\t\tthis.hasNonRenderedItemsAtTheBottom()\r\n\t\t\t\t)\r\n\t\t\t)\r\n\r\n\t\tif (forceUpdate) {\r\n\t\t\tlog('The user has scrolled far enough: perform a re-layout')\r\n\t\t} else {\r\n\t\t\tlog('The user is scrolling: perform a re-layout when they stop scrolling')\r\n\t\t}\r\n\r\n\t\tif (forceUpdate || this.waitForScrollingToStop === false) {\r\n\t\t\treturn this.onScroll()\r\n\t\t}\r\n\r\n\t\t// If a re-layout is already scheduled at the next \"frame\",\r\n\t\t// don't schedule a \"re-layout when user stops scrolling\" timer.\r\n\t\tif (this.isImmediateLayoutScheduled()) {\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\tthis.onScrollOnStopScrolling = true\r\n\t\tthis.watchOnStopScrolling()\r\n\t}\r\n\r\n\twatchOnStopScrolling() {\r\n\t\tthis.onStopScrollingTimer = setTimeout(\r\n\t\t\t() => {\r\n\t\t\t\tthis.onStopScrollingTimer = undefined\r\n\r\n\t\t\t\tif (this.onScrollOnStopScrolling) {\r\n\t\t\t\t\tthis.onScrollOnStopScrolling = undefined\r\n\t\t\t\t\tthis.onScroll({ delayed: true })\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (this.onStopScrollingListener) {\r\n\t\t\t\t\tconst onStopScrollingListener = this.onStopScrollingListener\r\n\t\t\t\t\tthis.onStopScrollingListener = undefined\r\n\t\t\t\t\t// `onStopScrollingListener()` may hypothetically schedule\r\n\t\t\t\t\t// another `onStopScrolling()` listener, so set\r\n\t\t\t\t\t// `this.onStopScrollingListener` to `undefined` before\r\n\t\t\t\t\t// calling it rather than after.\r\n\t\t\t\t\tlog('~ The user has stopped scrolling ~')\r\n\t\t\t\t\tonStopScrollingListener()\r\n\t\t\t\t}\r\n\t\t\t},\r\n\t\t\t// \"scroll\" events are usually dispatched every 16 milliseconds\r\n\t\t\t// for 60fps refresh rate, so waiting for 100 milliseconds feels\r\n\t\t\t// reasonable: that would be about 6 frames of inactivity period,\r\n\t\t\t// which could mean that either the user has stopped scrolling\r\n\t\t\t// (for a moment) or the browser is lagging and stuttering\r\n\t\t\t// (skipping frames due to high load).\r\n\t\t\t// If the user continues scrolling then this timeout is constantly\r\n\t\t\t// refreshed (cancelled and then re-created).\r\n\t\t\tON_STOP_SCROLLING_INACTIVE_PERIOD\r\n\t\t)\r\n\t}\r\n\r\n\t// (this function isn't currently used)\r\n\tonStopScrolling(onStopScrollingListener) {\r\n\t\tthis.onStopScrollingListener = onStopScrollingListener\r\n\t\tif (!this.onStopScrollingTimer) {\r\n\t\t\tthis.watchOnStopScrolling()\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Returns visible area coordinates relative to the scrollable container.\r\n\t * @return {object} `{ top: number, bottom: number }`\r\n\t */\r\n\tgetVisibleAreaBounds() {\r\n\t\tconst scrollY = this.getScrollY()\r\n\t\treturn {\r\n\t\t\t// The first pixel of the screen.\r\n\t\t\ttop: scrollY,\r\n\t\t\t// The pixel after the last pixel of the screen.\r\n\t\t\tbottom: scrollY + this.scrollableContainer.getHeight()\r\n\t\t}\r\n\t}\r\n}\r\n\r\nconst ON_STOP_SCROLLING_INACTIVE_PERIOD = 100"],"file":"Scroll.js"}