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
@@ -0,0 +1,68 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>
6
+ VirtualScroller scrollable container test
7
+ </title>
8
+ <style>
9
+ tr {
10
+ background: #fff
11
+ }
12
+
13
+ th, td {
14
+ padding-left: 1em;
15
+ padding-right: 1em;
16
+ padding-top: 0.2em;
17
+ padding-bottom: 0.2em;
18
+ }
19
+
20
+ table {
21
+ width: 100%;
22
+ }
23
+
24
+ #scrollableContainer {
25
+ margin-top: 20vh;
26
+ max-height: 60vh;
27
+ overflow: auto;
28
+ }
29
+ </style>
30
+ <script src="./virtual-scroller-dom.js"></script>
31
+ <link rel="stylesheet" href="./style.css"/>
32
+ </head>
33
+ <body>
34
+ <div id="scrollableContainer">
35
+ <table>
36
+ <tbody id="container">
37
+ </tbody>
38
+ </table>
39
+ </div>
40
+ <script>
41
+ window.VirtualScrollerDebug = true
42
+
43
+ const rows = [];
44
+ for (var i = 1; i <= 10000; i++) {
45
+ rows.push(i);
46
+ }
47
+
48
+ function renderRow(i) {
49
+ var tr = document.createElement('tr');
50
+ var td = document.createElement('td')
51
+ td.innerText = i
52
+ tr.appendChild(td)
53
+ return tr
54
+ }
55
+
56
+ new VirtualScroller(
57
+ document.getElementById('container'),
58
+ rows,
59
+ renderRow,
60
+ {
61
+ getScrollableContainer() {
62
+ return document.getElementById('scrollableContainer')
63
+ }
64
+ }
65
+ )
66
+ </script>
67
+ </body>
68
+ </html>
@@ -0,0 +1,55 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>
6
+ VirtualScroller scrollable container test
7
+ </title>
8
+ <style>
9
+ tr {
10
+ background: #fff
11
+ }
12
+
13
+ th, td {
14
+ padding-left: 1em;
15
+ padding-right: 1em;
16
+ padding-top: 0.2em;
17
+ padding-bottom: 0.2em;
18
+ }
19
+
20
+ table {
21
+ width: 100%;
22
+ }
23
+ </style>
24
+ <script src="./virtual-scroller-dom.js"></script>
25
+ <link rel="stylesheet" href="./style.css"/>
26
+ </head>
27
+ <body>
28
+ <table>
29
+ <tbody id="container">
30
+ </tbody>
31
+ </table>
32
+ <script>
33
+ window.VirtualScrollerDebug = true
34
+
35
+ const rows = [];
36
+ for (var i = 1; i <= 10000; i++) {
37
+ rows.push(i);
38
+ }
39
+
40
+ function renderRow(i) {
41
+ var tr = document.createElement('tr');
42
+ var td = document.createElement('td')
43
+ td.innerText = i
44
+ tr.appendChild(td)
45
+ return tr
46
+ }
47
+
48
+ new VirtualScroller(
49
+ document.getElementById('container'),
50
+ rows,
51
+ renderRow
52
+ )
53
+ </script>
54
+ </body>
55
+ </html>
@@ -1,33 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports["default"] = void 0;
7
-
8
- var _Screen = _interopRequireDefault(require("./Screen"));
9
-
10
- var _ScrollableContainer = _interopRequireWildcard(require("./ScrollableContainer"));
11
-
12
- function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj["default"] = obj; return newObj; } }
13
-
14
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
15
-
16
- var _default = {
17
- name: 'DOM',
18
- createScreen: function createScreen() {
19
- return new _Screen["default"]();
20
- },
21
- // Create `scrollableContainer`.
22
- // On client side, `scrollableContainer` is always created.
23
- // On server side, `scrollableContainer` is not created (and not used).
24
- createScrollableContainer: function createScrollableContainer(scrollableContainer) {
25
- if (scrollableContainer) {
26
- return new _ScrollableContainer["default"](scrollableContainer);
27
- } else if (typeof window !== 'undefined') {
28
- return new _ScrollableContainer.ScrollableWindowContainer();
29
- }
30
- }
31
- };
32
- exports["default"] = _default;
33
- //# sourceMappingURL=RenderingEngine.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../source/DOM/RenderingEngine.js"],"names":["name","createScreen","Screen","createScrollableContainer","scrollableContainer","ScrollableContainer","window","ScrollableWindowContainer"],"mappings":";;;;;;;AAAA;;AAEA;;;;;;eAIe;AACdA,EAAAA,IAAI,EAAE,KADQ;AAEdC,EAAAA,YAFc,0BAEC;AACd,WAAO,IAAIC,kBAAJ,EAAP;AACA,GAJa;AAKd;AACA;AACA;AACAC,EAAAA,yBARc,qCAQYC,mBARZ,EAQiC;AAC9C,QAAIA,mBAAJ,EAAyB;AACxB,aAAO,IAAIC,+BAAJ,CAAwBD,mBAAxB,CAAP;AACA,KAFD,MAEO,IAAI,OAAOE,MAAP,KAAkB,WAAtB,EAAmC;AACzC,aAAO,IAAIC,8CAAJ,EAAP;AACA;AACD;AAda,C","sourcesContent":["import Screen from './Screen'\r\n\r\nimport ScrollableContainer, {\r\n\tScrollableWindowContainer\r\n} from './ScrollableContainer'\r\n\r\nexport default {\r\n\tname: 'DOM',\r\n\tcreateScreen() {\r\n\t\treturn new Screen()\r\n\t},\r\n\t// Create `scrollableContainer`.\r\n\t// On client side, `scrollableContainer` is always created.\r\n\t// On server side, `scrollableContainer` is not created (and not used).\r\n\tcreateScrollableContainer(scrollableContainer) {\r\n\t\tif (scrollableContainer) {\r\n\t\t\treturn new ScrollableContainer(scrollableContainer)\r\n\t\t} else if (typeof window !== 'undefined') {\r\n\t\t\treturn new ScrollableWindowContainer()\r\n\t\t}\r\n\t}\r\n}"],"file":"RenderingEngine.js"}
@@ -1,87 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports["default"] = void 0;
7
-
8
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
9
-
10
- function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
11
-
12
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
13
-
14
- var Screen =
15
- /*#__PURE__*/
16
- function () {
17
- function Screen() {
18
- _classCallCheck(this, Screen);
19
- }
20
-
21
- _createClass(Screen, [{
22
- key: "getChildElementTopOffset",
23
-
24
- /**
25
- * Returns a child element's "top offset", relative to the `parentElement`'s top edge.
26
- * @param {Element} parentElement
27
- * @param {number} childElementIndex
28
- * @return {number}
29
- */
30
- value: function getChildElementTopOffset(parentElement, childElementIndex) {
31
- return parentElement.childNodes[childElementIndex].getBoundingClientRect().top;
32
- }
33
- /**
34
- * Returns a child element's height.
35
- * @param {Element} parentElement
36
- * @param {number} childElementIndex
37
- * @return {number}
38
- */
39
-
40
- }, {
41
- key: "getChildElementHeight",
42
- value: function getChildElementHeight(parentElement, childElementIndex) {
43
- return this.getElementHeight(parentElement.childNodes[childElementIndex]);
44
- }
45
- /**
46
- * Returns the count of child elements of an element.
47
- * @param {Element} parentElement
48
- * @return {number}
49
- */
50
-
51
- }, {
52
- key: "getChildElementsCount",
53
- value: function getChildElementsCount(parentElement) {
54
- return parentElement.childNodes.length;
55
- }
56
- /**
57
- * Removes all child elements of an element.
58
- * @param {Element} element
59
- */
60
-
61
- }, {
62
- key: "clearElement",
63
- value: function clearElement(element) {
64
- while (element.firstChild) {
65
- element.removeChild(element.firstChild);
66
- }
67
- }
68
- /**
69
- * Returns an element's height.
70
- * @param {Element} element
71
- * @return {number}
72
- */
73
-
74
- }, {
75
- key: "getElementHeight",
76
- value: function getElementHeight(element) {
77
- // `offsetHeight` is not precise enough (doesn't return fractional pixels).
78
- // return element.offsetHeight
79
- return element.getBoundingClientRect().height;
80
- }
81
- }]);
82
-
83
- return Screen;
84
- }();
85
-
86
- exports["default"] = Screen;
87
- //# sourceMappingURL=Screen.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../source/DOM/Screen.js"],"names":["Screen","parentElement","childElementIndex","childNodes","getBoundingClientRect","top","getElementHeight","length","element","firstChild","removeChild","height"],"mappings":";;;;;;;;;;;;;IAAqBA,M;;;;;;;;;;AACpB;;;;;;6CAMyBC,a,EAAeC,iB,EAAmB;AAC1D,aAAOD,aAAa,CAACE,UAAd,CAAyBD,iBAAzB,EAA4CE,qBAA5C,GAAoEC,GAA3E;AACA;AAED;;;;;;;;;0CAMsBJ,a,EAAeC,iB,EAAmB;AACvD,aAAO,KAAKI,gBAAL,CAAsBL,aAAa,CAACE,UAAd,CAAyBD,iBAAzB,CAAtB,CAAP;AACA;AAED;;;;;;;;0CAKsBD,a,EAAe;AACpC,aAAOA,aAAa,CAACE,UAAd,CAAyBI,MAAhC;AACA;AAED;;;;;;;iCAIaC,O,EAAS;AACrB,aAAOA,OAAO,CAACC,UAAf,EAA2B;AAC1BD,QAAAA,OAAO,CAACE,WAAR,CAAoBF,OAAO,CAACC,UAA5B;AACA;AACD;AAED;;;;;;;;qCAKiBD,O,EAAS;AACzB;AACA;AACA,aAAOA,OAAO,CAACJ,qBAAR,GAAgCO,MAAvC;AACA","sourcesContent":["export default class Screen {\r\n\t/**\r\n\t * Returns a child element's \"top offset\", relative to the `parentElement`'s top edge.\r\n\t * @param {Element} parentElement\r\n\t * @param {number} childElementIndex\r\n\t * @return {number}\r\n\t */\r\n\tgetChildElementTopOffset(parentElement, childElementIndex) {\r\n\t\treturn parentElement.childNodes[childElementIndex].getBoundingClientRect().top\r\n\t}\r\n\r\n\t/**\r\n\t * Returns a child element's height.\r\n\t * @param {Element} parentElement\r\n\t * @param {number} childElementIndex\r\n\t * @return {number}\r\n\t */\r\n\tgetChildElementHeight(parentElement, childElementIndex) {\r\n\t\treturn this.getElementHeight(parentElement.childNodes[childElementIndex])\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the count of child elements of an element.\r\n\t * @param {Element} parentElement\r\n\t * @return {number}\r\n\t */\r\n\tgetChildElementsCount(parentElement) {\r\n\t\treturn parentElement.childNodes.length\r\n\t}\r\n\r\n\t/**\r\n\t * Removes all child elements of an element.\r\n\t * @param {Element} element\r\n\t */\r\n\tclearElement(element) {\r\n\t\twhile (element.firstChild) {\r\n\t\t\telement.removeChild(element.firstChild)\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Returns an element's height.\r\n\t * @param {Element} element\r\n\t * @return {number}\r\n\t */\r\n\tgetElementHeight(element) {\r\n\t\t// `offsetHeight` is not precise enough (doesn't return fractional pixels).\r\n\t\t// return element.offsetHeight\r\n\t\treturn element.getBoundingClientRect().height\r\n\t}\r\n}"],"file":"Screen.js"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../source/DOM/WaitForStylesToLoad.js"],"names":["WaitForStylesToLoad","updateLayout","getListTopOffsetInsideScrollableContainer","listTopOffset","listTopOffsetInsideScrollableContainer","undefined","start","isRendered","watchListTopOffset","watchListTopOffsetTimer","startedAt","Date","now","check","reason","LAYOUT_REASON","TOP_OFFSET_CHANGED","WATCH_LIST_TOP_OFFSET_MAX_DURATION","WATCH_LIST_TOP_OFFSET_INTERVAL"],"mappings":";;;;;;;AAIA;;AAEA;;;;;;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;IACqBA,mB;;;AACpB,qCAGG;AAAA,QAFFC,YAEE,QAFFA,YAEE;AAAA,QADFC,yCACE,QADFA,yCACE;;AAAA;;AACF,SAAKD,YAAL,GAAoBA,YAApB;AACA,SAAKC,yCAAL,GAAiDA,yCAAjD;AACA;;;;uCAEkBC,a,EAAe;AACjC,UAAI,KAAKC,sCAAL,KAAgDC,SAApD,EAA+D;AAC9D;AACA;AACA;AACA;AACA,aAAKC,KAAL;AACA;;AACD,WAAKF,sCAAL,GAA8CD,aAA9C;AACA;;;4BAEO;AACP,WAAKI,UAAL,GAAkB,IAAlB;AACA,WAAKC,kBAAL;AACA;;;2BAEM;AACN,WAAKD,UAAL,GAAkB,KAAlB;AACA,sDAAa,KAAKE,uBAAlB;AACA;;;yCAEoB;AAAA;;AACpB,UAAMC,SAAS,GAAGC,IAAI,CAACC,GAAL,EAAlB;;AACA,UAAMC,KAAK,GAAG,SAARA,KAAQ,GAAM;AACnB;AACA;AACA,YAAI,CAAC,KAAI,CAACN,UAAV,EAAsB;AACrB;AACA,SALkB,CAMnB;AACA;;;AACA,YAAI,KAAI,CAACH,sCAAL,KAAgDC,SAApD,EAA+D;AAC9D;AACA;AACA;AACA,cAAI,KAAI,CAACH,yCAAL,OAAqD,KAAI,CAACE,sCAA9D,EAAsG;AACrG,YAAA,KAAI,CAACH,YAAL,CAAkB;AAAEa,cAAAA,MAAM,EAAEC,sBAAcC;AAAxB,aAAlB;AACA;AACD,SAfkB,CAgBnB;AACA;AACA;AACA;AACA;AACA;AACA;;;AACA,YAAIL,IAAI,CAACC,GAAL,KAAaF,SAAb,GAAyBO,kCAA7B,EAAiE;AAChE,UAAA,KAAI,CAACR,uBAAL,GAA+B,8CAAWI,KAAX,EAAkBK,8BAAlB,CAA/B;AACA;AACD,OA1BD,CAFoB,CA6BpB;;;AACAL,MAAAA,KAAK;AACL;;;;;;;AAGF,IAAMK,8BAA8B,GAAG,GAAvC;AACA,IAAMD,kCAAkC,GAAG,IAA3C","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\n\r\n// `VirtualScroller` calls `this.layout.layOut()` on mount,\r\n// but if the page styles are applied after `VirtualScroller` mounts\r\n// (for example, if styles are applied via javascript, like Webpack does)\r\n// then the list might not render correctly and will only show the first item.\r\n// The reason for that would be that calling `.getListTopOffsetInsideScrollableContainer()`\r\n// on mount returns \"incorrect\" `top` position because the styles haven't been applied yet.\r\n// For example, consider a page:\r\n// <div class=\"page\">\r\n// <nav class=\"sidebar\">...</nav>\r\n// <main>...</main>\r\n// </div>\r\n// The sidebar is styled as `position: fixed`, but until\r\n// the page styles have been applied it's gonna be a regular `<div/>`\r\n// meaning that `<main/>` will be rendered below the sidebar\r\n// and will appear offscreen and so it will only render the first item.\r\n// Then, the page styles are loaded and applied and the sidebar\r\n// is now `position: fixed` so `<main/>` is now rendered at the top of the page\r\n// but `VirtualScroller`'s `.render()` has already been called\r\n// and it won't re-render until the user scrolls or the window is resized.\r\n// This type of a bug doesn't occur in production, but it can appear\r\n// in development mode when using Webpack. The workaround `VirtualScroller`\r\n// implements for such cases is calling `.getListTopOffsetInsideScrollableContainer()`\r\n// on the list container DOM element periodically (every second) to check\r\n// if the `top` coordinate has changed as a result of CSS being applied:\r\n// if it has then it recalculates the shown item indexes.\r\nexport default class WaitForStylesToLoad {\r\n\tconstructor({\r\n\t\tupdateLayout,\r\n\t\tgetListTopOffsetInsideScrollableContainer\r\n\t}) {\r\n\t\tthis.updateLayout = updateLayout\r\n\t\tthis.getListTopOffsetInsideScrollableContainer = getListTopOffsetInsideScrollableContainer\r\n\t}\r\n\r\n\tonGotListTopOffset(listTopOffset) {\r\n\t\tif (this.listTopOffsetInsideScrollableContainer === undefined) {\r\n\t\t\t// Start periodical checks of the list's top offset\r\n\t\t\t// in order to perform a re-layout in case it changes.\r\n\t\t\t// See the comments in `WaitForStylesToLoad.js` file\r\n\t\t\t// on why can the list's top offset change, and in which circumstances.\r\n\t\t\tthis.start()\r\n\t\t}\r\n\t\tthis.listTopOffsetInsideScrollableContainer = listTopOffset\r\n\t}\r\n\r\n\tstart() {\r\n\t\tthis.isRendered = true\r\n\t\tthis.watchListTopOffset()\r\n\t}\r\n\r\n\tstop() {\r\n\t\tthis.isRendered = false\r\n\t\tclearTimeout(this.watchListTopOffsetTimer)\r\n\t}\r\n\r\n\twatchListTopOffset() {\r\n\t\tconst startedAt = Date.now()\r\n\t\tconst check = () => {\r\n\t\t\t// If `VirtualScroller` has been unmounted\r\n\t\t\t// while `setTimeout()` was waiting, then exit.\r\n\t\t\tif (!this.isRendered) {\r\n\t\t\t\treturn\r\n\t\t\t}\r\n\t\t\t// Skip comparing `top` coordinate of the list\r\n\t\t\t// when this function is called for the first time.\r\n\t\t\tif (this.listTopOffsetInsideScrollableContainer !== undefined) {\r\n\t\t\t\t// Calling `this.getListTopOffsetInsideScrollableContainer()`\r\n\t\t\t\t// on an element is about 0.003 milliseconds on a modern desktop CPU,\r\n\t\t\t\t// so I guess it's fine calling it twice a second.\r\n\t\t\t\tif (this.getListTopOffsetInsideScrollableContainer() !== this.listTopOffsetInsideScrollableContainer) {\r\n\t\t\t\t\tthis.updateLayout({ reason: LAYOUT_REASON.TOP_OFFSET_CHANGED })\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t// Compare `top` coordinate of the list twice a second\r\n\t\t\t// to find out if it has changed as a result of loading CSS styles.\r\n\t\t\t// The total duration of 3 seconds would be enough for any styles to load, I guess.\r\n\t\t\t// There could be other cases changing the `top` coordinate\r\n\t\t\t// of the list (like collapsing an \"accordeon\" panel above the list\r\n\t\t\t// without scrolling the page), but those cases should be handled\r\n\t\t\t// by manually calling `.updateLayout()` instance method on `VirtualScroller` instance.\r\n\t\t\tif (Date.now() - startedAt < WATCH_LIST_TOP_OFFSET_MAX_DURATION) {\r\n\t\t\t\tthis.watchListTopOffsetTimer = setTimeout(check, WATCH_LIST_TOP_OFFSET_INTERVAL)\r\n\t\t\t}\r\n\t\t}\r\n\t\t// Run the cycle.\r\n\t\tcheck()\r\n\t}\r\n}\r\n\r\nconst WATCH_LIST_TOP_OFFSET_INTERVAL = 500\r\nconst WATCH_LIST_TOP_OFFSET_MAX_DURATION = 3000"],"file":"WaitForStylesToLoad.js"}
@@ -1,118 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports["default"] = void 0;
7
-
8
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
9
-
10
- function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
11
-
12
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
13
-
14
- var RestoreScroll =
15
- /*#__PURE__*/
16
- function () {
17
- function RestoreScroll(_ref) {
18
- var screen = _ref.screen,
19
- getContainerElement = _ref.getContainerElement,
20
- scrollBy = _ref.scrollBy;
21
-
22
- _classCallCheck(this, RestoreScroll);
23
-
24
- this.screen = screen;
25
- this.getContainerElement = getContainerElement;
26
- this.scrollBy = scrollBy;
27
- }
28
- /**
29
- * `<ReactVirtualScroller/>` calls this method.
30
- * @param {any[]} previousItems
31
- * @param {any[]} newItems
32
- * @param {number} prependedItemsCount
33
- */
34
-
35
-
36
- _createClass(RestoreScroll, [{
37
- key: "captureScroll",
38
- value: function captureScroll(_ref2) {
39
- var previousItems = _ref2.previousItems,
40
- newItems = _ref2.newItems,
41
- prependedItemsCount = _ref2.prependedItemsCount;
42
-
43
- // If there were no items in the list
44
- // then there's no point in restoring scroll position.
45
- if (previousItems.length === 0) {
46
- return;
47
- } // If no items were prepended then no need to restore scroll position.
48
-
49
-
50
- if (prependedItemsCount === 0) {
51
- return;
52
- }
53
-
54
- var container = this.getContainerElement();
55
- var firstItemTopOffset = this.screen.getChildElementTopOffset(container, 0); // The first item is supposed to be shown when the user clicks
56
- // "Show previous items" button. If it isn't shown though,
57
- // could still calculate the first item's top position using
58
- // the values from `itemHeights` and `verticalSpacing`.
59
- // But that would be a weird non-realistic scenario.
60
- // if (firstShownItemIndex > 0) {
61
- // let i = firstShownItemIndex - 1
62
- // while (i >= 0) {
63
- // firstItemTopOffset += itemHeights[i] + verticalSpacing
64
- // i--
65
- // }
66
- // }
67
- // If the scroll position has already been captured for restoration,
68
- // then don't capture it the second time.
69
- // Capturing scroll position could happen when using `<ReactVirtualScroller/>`
70
- // because it calls `.captureScroll()` inside `ReactVirtualScroller.render()`
71
- // which is followed by `<VirtualScroller/>`'s `.componentDidUpdate()`
72
- // that also calls `.captureScroll()` with the same arguments,
73
- // so that second call to `.captureScroll()` is ignored.
74
- // Calling `.captureScroll()` inside `ReactVirtualScroller.render()`
75
- // is done to prevent scroll Y position from jumping
76
- // when showing the first page of the "Previous items".
77
- // See the long section of comments in `ReactVirtualScroller.render()`
78
- // method for more info on why is `.captureScroll()` called there.
79
-
80
- if (this.restoreScrollAfterRenderValues && this.restoreScrollAfterRenderValues.previousItems === previousItems && this.restoreScrollAfterRenderValues.newItems === newItems) {
81
- return;
82
- }
83
-
84
- this.restoreScrollAfterRenderValues = {
85
- previousItems: previousItems,
86
- newItems: newItems,
87
- index: prependedItemsCount,
88
- visibleAreaTop: firstItemTopOffset
89
- };
90
- }
91
- }, {
92
- key: "getAnchorItemIndex",
93
- value: function getAnchorItemIndex() {
94
- return this.restoreScrollAfterRenderValues.index;
95
- }
96
- }, {
97
- key: "shouldRestoreScrollAfterRender",
98
- value: function shouldRestoreScrollAfterRender() {
99
- return this.restoreScrollAfterRenderValues !== undefined;
100
- }
101
- }, {
102
- key: "getScrollDifference",
103
- value: function getScrollDifference() {
104
- var _this$restoreScrollAf = this.restoreScrollAfterRenderValues,
105
- index = _this$restoreScrollAf.index,
106
- visibleAreaTop = _this$restoreScrollAf.visibleAreaTop;
107
- this.restoreScrollAfterRenderValues = undefined; // `firstShownItemIndex` is supposed to be `0` here.
108
-
109
- var newVisibleAreaTop = this.screen.getChildElementTopOffset(this.getContainerElement(), index);
110
- return newVisibleAreaTop - visibleAreaTop;
111
- }
112
- }]);
113
-
114
- return RestoreScroll;
115
- }();
116
-
117
- exports["default"] = RestoreScroll;
118
- //# sourceMappingURL=RestoreScroll.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../source/RestoreScroll.js"],"names":["RestoreScroll","screen","getContainerElement","scrollBy","previousItems","newItems","prependedItemsCount","length","container","firstItemTopOffset","getChildElementTopOffset","restoreScrollAfterRenderValues","index","visibleAreaTop","undefined","newVisibleAreaTop"],"mappings":";;;;;;;;;;;;;IAAqBA,a;;;AACpB,+BAIG;AAAA,QAHFC,MAGE,QAHFA,MAGE;AAAA,QAFFC,mBAEE,QAFFA,mBAEE;AAAA,QADFC,QACE,QADFA,QACE;;AAAA;;AACF,SAAKF,MAAL,GAAcA,MAAd;AACA,SAAKC,mBAAL,GAA2BA,mBAA3B;AACA,SAAKC,QAAL,GAAgBA,QAAhB;AACA;AAED;;;;;;;;;;yCAUG;AAAA,UAHFC,aAGE,SAHFA,aAGE;AAAA,UAFFC,QAEE,SAFFA,QAEE;AAAA,UADFC,mBACE,SADFA,mBACE;;AACF;AACA;AACA,UAAIF,aAAa,CAACG,MAAd,KAAyB,CAA7B,EAAgC;AAC/B;AACA,OALC,CAMF;;;AACA,UAAID,mBAAmB,KAAK,CAA5B,EAA+B;AAC9B;AACA;;AACD,UAAME,SAAS,GAAG,KAAKN,mBAAL,EAAlB;AACA,UAAMO,kBAAkB,GAAG,KAAKR,MAAL,CAAYS,wBAAZ,CAAqCF,SAArC,EAAgD,CAAhD,CAA3B,CAXE,CAYF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AACA,UAAI,KAAKG,8BAAL,IACH,KAAKA,8BAAL,CAAoCP,aAApC,KAAsDA,aADnD,IAEH,KAAKO,8BAAL,CAAoCN,QAApC,KAAiDA,QAFlD,EAE4D;AAC3D;AACA;;AACD,WAAKM,8BAAL,GAAsC;AACrCP,QAAAA,aAAa,EAAbA,aADqC;AAErCC,QAAAA,QAAQ,EAARA,QAFqC;AAGrCO,QAAAA,KAAK,EAAEN,mBAH8B;AAIrCO,QAAAA,cAAc,EAAEJ;AAJqB,OAAtC;AAMA;;;yCAEoB;AACpB,aAAO,KAAKE,8BAAL,CAAoCC,KAA3C;AACA;;;qDAEgC;AAChC,aAAO,KAAKD,8BAAL,KAAwCG,SAA/C;AACA;;;0CAEqB;AAAA,kCACa,KAAKH,8BADlB;AAAA,UACbC,KADa,yBACbA,KADa;AAAA,UACNC,cADM,yBACNA,cADM;AAErB,WAAKF,8BAAL,GAAsCG,SAAtC,CAFqB,CAGrB;;AACA,UAAMC,iBAAiB,GAAG,KAAKd,MAAL,CAAYS,wBAAZ,CAAqC,KAAKR,mBAAL,EAArC,EAAiEU,KAAjE,CAA1B;AACA,aAAOG,iBAAiB,GAAGF,cAA3B;AACA","sourcesContent":["export default class RestoreScroll {\r\n\tconstructor({\r\n\t\tscreen,\r\n\t\tgetContainerElement,\r\n\t\tscrollBy\r\n\t}) {\r\n\t\tthis.screen = screen\r\n\t\tthis.getContainerElement = getContainerElement\r\n\t\tthis.scrollBy = scrollBy\r\n\t}\r\n\r\n\t/**\r\n\t * `<ReactVirtualScroller/>` calls this method.\r\n\t * @param {any[]} previousItems\r\n\t * @param {any[]} newItems\r\n\t * @param {number} prependedItemsCount\r\n\t */\r\n\tcaptureScroll({\r\n\t\tpreviousItems,\r\n\t\tnewItems,\r\n\t\tprependedItemsCount\r\n\t}) {\r\n\t\t// If there were no items in the list\r\n\t\t// then there's no point in restoring scroll position.\r\n\t\tif (previousItems.length === 0) {\r\n\t\t\treturn\r\n\t\t}\r\n\t\t// If no items were prepended then no need to restore scroll position.\r\n\t\tif (prependedItemsCount === 0) {\r\n\t\t\treturn\r\n\t\t}\r\n\t\tconst container = this.getContainerElement()\r\n\t\tconst firstItemTopOffset = this.screen.getChildElementTopOffset(container, 0)\r\n\t\t// The first item is supposed to be shown when the user clicks\r\n\t\t// \"Show previous items\" button. If it isn't shown though,\r\n\t\t// could still calculate the first item's top position using\r\n\t\t// the values from `itemHeights` and `verticalSpacing`.\r\n\t\t// But that would be a weird non-realistic scenario.\r\n\t\t// if (firstShownItemIndex > 0) {\r\n\t\t// \tlet i = firstShownItemIndex - 1\r\n\t\t// \twhile (i >= 0) {\r\n\t\t// \t\tfirstItemTopOffset += itemHeights[i] + verticalSpacing\r\n\t\t// \t\ti--\r\n\t\t// \t}\r\n\t\t// }\r\n\t\t// If the scroll position has already been captured for restoration,\r\n\t\t// then don't capture it the second time.\r\n\t\t// Capturing scroll position could happen when using `<ReactVirtualScroller/>`\r\n\t\t// because it calls `.captureScroll()` inside `ReactVirtualScroller.render()`\r\n\t\t// which is followed by `<VirtualScroller/>`'s `.componentDidUpdate()`\r\n\t\t// that also calls `.captureScroll()` with the same arguments,\r\n\t\t// so that second call to `.captureScroll()` is ignored.\r\n\t\t// Calling `.captureScroll()` inside `ReactVirtualScroller.render()`\r\n\t\t// is done to prevent scroll Y position from jumping\r\n\t\t// when showing the first page of the \"Previous items\".\r\n\t\t// See the long section of comments in `ReactVirtualScroller.render()`\r\n\t\t// method for more info on why is `.captureScroll()` called there.\r\n\t\tif (this.restoreScrollAfterRenderValues &&\r\n\t\t\tthis.restoreScrollAfterRenderValues.previousItems === previousItems &&\r\n\t\t\tthis.restoreScrollAfterRenderValues.newItems === newItems) {\r\n\t\t\treturn\r\n\t\t}\r\n\t\tthis.restoreScrollAfterRenderValues = {\r\n\t\t\tpreviousItems,\r\n\t\t\tnewItems,\r\n\t\t\tindex: prependedItemsCount,\r\n\t\t\tvisibleAreaTop: firstItemTopOffset\r\n\t\t}\r\n\t}\r\n\r\n\tgetAnchorItemIndex() {\r\n\t\treturn this.restoreScrollAfterRenderValues.index\r\n\t}\r\n\r\n\tshouldRestoreScrollAfterRender() {\r\n\t\treturn this.restoreScrollAfterRenderValues !== undefined\r\n\t}\r\n\r\n\tgetScrollDifference() {\r\n\t\tconst { index, visibleAreaTop } = this.restoreScrollAfterRenderValues\r\n\t\tthis.restoreScrollAfterRenderValues = undefined\r\n\t\t// `firstShownItemIndex` is supposed to be `0` here.\r\n\t\tconst newVisibleAreaTop = this.screen.getChildElementTopOffset(this.getContainerElement(), index)\r\n\t\treturn newVisibleAreaTop - visibleAreaTop\r\n\t}\r\n}"],"file":"RestoreScroll.js"}
@@ -1,19 +0,0 @@
1
- import Screen from './Screen';
2
- import ScrollableContainer, { ScrollableWindowContainer } from './ScrollableContainer';
3
- export default {
4
- name: 'DOM',
5
- createScreen: function createScreen() {
6
- return new Screen();
7
- },
8
- // Create `scrollableContainer`.
9
- // On client side, `scrollableContainer` is always created.
10
- // On server side, `scrollableContainer` is not created (and not used).
11
- createScrollableContainer: function createScrollableContainer(scrollableContainer) {
12
- if (scrollableContainer) {
13
- return new ScrollableContainer(scrollableContainer);
14
- } else if (typeof window !== 'undefined') {
15
- return new ScrollableWindowContainer();
16
- }
17
- }
18
- };
19
- //# sourceMappingURL=RenderingEngine.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../source/DOM/RenderingEngine.js"],"names":["Screen","ScrollableContainer","ScrollableWindowContainer","name","createScreen","createScrollableContainer","scrollableContainer","window"],"mappings":"AAAA,OAAOA,MAAP,MAAmB,UAAnB;AAEA,OAAOC,mBAAP,IACCC,yBADD,QAEO,uBAFP;AAIA,eAAe;AACdC,EAAAA,IAAI,EAAE,KADQ;AAEdC,EAAAA,YAFc,0BAEC;AACd,WAAO,IAAIJ,MAAJ,EAAP;AACA,GAJa;AAKd;AACA;AACA;AACAK,EAAAA,yBARc,qCAQYC,mBARZ,EAQiC;AAC9C,QAAIA,mBAAJ,EAAyB;AACxB,aAAO,IAAIL,mBAAJ,CAAwBK,mBAAxB,CAAP;AACA,KAFD,MAEO,IAAI,OAAOC,MAAP,KAAkB,WAAtB,EAAmC;AACzC,aAAO,IAAIL,yBAAJ,EAAP;AACA;AACD;AAda,CAAf","sourcesContent":["import Screen from './Screen'\r\n\r\nimport ScrollableContainer, {\r\n\tScrollableWindowContainer\r\n} from './ScrollableContainer'\r\n\r\nexport default {\r\n\tname: 'DOM',\r\n\tcreateScreen() {\r\n\t\treturn new Screen()\r\n\t},\r\n\t// Create `scrollableContainer`.\r\n\t// On client side, `scrollableContainer` is always created.\r\n\t// On server side, `scrollableContainer` is not created (and not used).\r\n\tcreateScrollableContainer(scrollableContainer) {\r\n\t\tif (scrollableContainer) {\r\n\t\t\treturn new ScrollableContainer(scrollableContainer)\r\n\t\t} else if (typeof window !== 'undefined') {\r\n\t\t\treturn new ScrollableWindowContainer()\r\n\t\t}\r\n\t}\r\n}"],"file":"RenderingEngine.js"}
@@ -1,80 +0,0 @@
1
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2
-
3
- function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
4
-
5
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
6
-
7
- var Screen =
8
- /*#__PURE__*/
9
- function () {
10
- function Screen() {
11
- _classCallCheck(this, Screen);
12
- }
13
-
14
- _createClass(Screen, [{
15
- key: "getChildElementTopOffset",
16
-
17
- /**
18
- * Returns a child element's "top offset", relative to the `parentElement`'s top edge.
19
- * @param {Element} parentElement
20
- * @param {number} childElementIndex
21
- * @return {number}
22
- */
23
- value: function getChildElementTopOffset(parentElement, childElementIndex) {
24
- return parentElement.childNodes[childElementIndex].getBoundingClientRect().top;
25
- }
26
- /**
27
- * Returns a child element's height.
28
- * @param {Element} parentElement
29
- * @param {number} childElementIndex
30
- * @return {number}
31
- */
32
-
33
- }, {
34
- key: "getChildElementHeight",
35
- value: function getChildElementHeight(parentElement, childElementIndex) {
36
- return this.getElementHeight(parentElement.childNodes[childElementIndex]);
37
- }
38
- /**
39
- * Returns the count of child elements of an element.
40
- * @param {Element} parentElement
41
- * @return {number}
42
- */
43
-
44
- }, {
45
- key: "getChildElementsCount",
46
- value: function getChildElementsCount(parentElement) {
47
- return parentElement.childNodes.length;
48
- }
49
- /**
50
- * Removes all child elements of an element.
51
- * @param {Element} element
52
- */
53
-
54
- }, {
55
- key: "clearElement",
56
- value: function clearElement(element) {
57
- while (element.firstChild) {
58
- element.removeChild(element.firstChild);
59
- }
60
- }
61
- /**
62
- * Returns an element's height.
63
- * @param {Element} element
64
- * @return {number}
65
- */
66
-
67
- }, {
68
- key: "getElementHeight",
69
- value: function getElementHeight(element) {
70
- // `offsetHeight` is not precise enough (doesn't return fractional pixels).
71
- // return element.offsetHeight
72
- return element.getBoundingClientRect().height;
73
- }
74
- }]);
75
-
76
- return Screen;
77
- }();
78
-
79
- export { Screen as default };
80
- //# sourceMappingURL=Screen.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../source/DOM/Screen.js"],"names":["Screen","parentElement","childElementIndex","childNodes","getBoundingClientRect","top","getElementHeight","length","element","firstChild","removeChild","height"],"mappings":";;;;;;IAAqBA,M;;;;;;;;;;AACpB;;;;;;6CAMyBC,a,EAAeC,iB,EAAmB;AAC1D,aAAOD,aAAa,CAACE,UAAd,CAAyBD,iBAAzB,EAA4CE,qBAA5C,GAAoEC,GAA3E;AACA;AAED;;;;;;;;;0CAMsBJ,a,EAAeC,iB,EAAmB;AACvD,aAAO,KAAKI,gBAAL,CAAsBL,aAAa,CAACE,UAAd,CAAyBD,iBAAzB,CAAtB,CAAP;AACA;AAED;;;;;;;;0CAKsBD,a,EAAe;AACpC,aAAOA,aAAa,CAACE,UAAd,CAAyBI,MAAhC;AACA;AAED;;;;;;;iCAIaC,O,EAAS;AACrB,aAAOA,OAAO,CAACC,UAAf,EAA2B;AAC1BD,QAAAA,OAAO,CAACE,WAAR,CAAoBF,OAAO,CAACC,UAA5B;AACA;AACD;AAED;;;;;;;;qCAKiBD,O,EAAS;AACzB;AACA;AACA,aAAOA,OAAO,CAACJ,qBAAR,GAAgCO,MAAvC;AACA;;;;;;SAjDmBX,M","sourcesContent":["export default class Screen {\r\n\t/**\r\n\t * Returns a child element's \"top offset\", relative to the `parentElement`'s top edge.\r\n\t * @param {Element} parentElement\r\n\t * @param {number} childElementIndex\r\n\t * @return {number}\r\n\t */\r\n\tgetChildElementTopOffset(parentElement, childElementIndex) {\r\n\t\treturn parentElement.childNodes[childElementIndex].getBoundingClientRect().top\r\n\t}\r\n\r\n\t/**\r\n\t * Returns a child element's height.\r\n\t * @param {Element} parentElement\r\n\t * @param {number} childElementIndex\r\n\t * @return {number}\r\n\t */\r\n\tgetChildElementHeight(parentElement, childElementIndex) {\r\n\t\treturn this.getElementHeight(parentElement.childNodes[childElementIndex])\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the count of child elements of an element.\r\n\t * @param {Element} parentElement\r\n\t * @return {number}\r\n\t */\r\n\tgetChildElementsCount(parentElement) {\r\n\t\treturn parentElement.childNodes.length\r\n\t}\r\n\r\n\t/**\r\n\t * Removes all child elements of an element.\r\n\t * @param {Element} element\r\n\t */\r\n\tclearElement(element) {\r\n\t\twhile (element.firstChild) {\r\n\t\t\telement.removeChild(element.firstChild)\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Returns an element's height.\r\n\t * @param {Element} element\r\n\t * @return {number}\r\n\t */\r\n\tgetElementHeight(element) {\r\n\t\t// `offsetHeight` is not precise enough (doesn't return fractional pixels).\r\n\t\t// return element.offsetHeight\r\n\t\treturn element.getBoundingClientRect().height\r\n\t}\r\n}"],"file":"Screen.js"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../source/DOM/WaitForStylesToLoad.js"],"names":["setTimeout","clearTimeout","LAYOUT_REASON","WaitForStylesToLoad","updateLayout","getListTopOffsetInsideScrollableContainer","listTopOffset","listTopOffsetInsideScrollableContainer","undefined","start","isRendered","watchListTopOffset","watchListTopOffsetTimer","startedAt","Date","now","check","reason","TOP_OFFSET_CHANGED","WATCH_LIST_TOP_OFFSET_MAX_DURATION","WATCH_LIST_TOP_OFFSET_INTERVAL"],"mappings":";;;;;;AAAA;AACA;AACA;AACA;AACA,SAASA,UAAT,EAAqBC,YAArB,QAAyC,iCAAzC;AAEA,SAASC,aAAT,QAA8B,WAA9B,C,CAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;IACqBC,mB;;;AACpB,qCAGG;AAAA,QAFFC,YAEE,QAFFA,YAEE;AAAA,QADFC,yCACE,QADFA,yCACE;;AAAA;;AACF,SAAKD,YAAL,GAAoBA,YAApB;AACA,SAAKC,yCAAL,GAAiDA,yCAAjD;AACA;;;;uCAEkBC,a,EAAe;AACjC,UAAI,KAAKC,sCAAL,KAAgDC,SAApD,EAA+D;AAC9D;AACA;AACA;AACA;AACA,aAAKC,KAAL;AACA;;AACD,WAAKF,sCAAL,GAA8CD,aAA9C;AACA;;;4BAEO;AACP,WAAKI,UAAL,GAAkB,IAAlB;AACA,WAAKC,kBAAL;AACA;;;2BAEM;AACN,WAAKD,UAAL,GAAkB,KAAlB;AACAT,MAAAA,YAAY,CAAC,KAAKW,uBAAN,CAAZ;AACA;;;yCAEoB;AAAA;;AACpB,UAAMC,SAAS,GAAGC,IAAI,CAACC,GAAL,EAAlB;;AACA,UAAMC,KAAK,GAAG,SAARA,KAAQ,GAAM;AACnB;AACA;AACA,YAAI,CAAC,KAAI,CAACN,UAAV,EAAsB;AACrB;AACA,SALkB,CAMnB;AACA;;;AACA,YAAI,KAAI,CAACH,sCAAL,KAAgDC,SAApD,EAA+D;AAC9D;AACA;AACA;AACA,cAAI,KAAI,CAACH,yCAAL,OAAqD,KAAI,CAACE,sCAA9D,EAAsG;AACrG,YAAA,KAAI,CAACH,YAAL,CAAkB;AAAEa,cAAAA,MAAM,EAAEf,aAAa,CAACgB;AAAxB,aAAlB;AACA;AACD,SAfkB,CAgBnB;AACA;AACA;AACA;AACA;AACA;AACA;;;AACA,YAAIJ,IAAI,CAACC,GAAL,KAAaF,SAAb,GAAyBM,kCAA7B,EAAiE;AAChE,UAAA,KAAI,CAACP,uBAAL,GAA+BZ,UAAU,CAACgB,KAAD,EAAQI,8BAAR,CAAzC;AACA;AACD,OA1BD,CAFoB,CA6BpB;;;AACAJ,MAAAA,KAAK;AACL;;;;;;SA7DmBb,mB;AAgErB,IAAMiB,8BAA8B,GAAG,GAAvC;AACA,IAAMD,kCAAkC,GAAG,IAA3C","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\n\r\n// `VirtualScroller` calls `this.layout.layOut()` on mount,\r\n// but if the page styles are applied after `VirtualScroller` mounts\r\n// (for example, if styles are applied via javascript, like Webpack does)\r\n// then the list might not render correctly and will only show the first item.\r\n// The reason for that would be that calling `.getListTopOffsetInsideScrollableContainer()`\r\n// on mount returns \"incorrect\" `top` position because the styles haven't been applied yet.\r\n// For example, consider a page:\r\n// <div class=\"page\">\r\n// <nav class=\"sidebar\">...</nav>\r\n// <main>...</main>\r\n// </div>\r\n// The sidebar is styled as `position: fixed`, but until\r\n// the page styles have been applied it's gonna be a regular `<div/>`\r\n// meaning that `<main/>` will be rendered below the sidebar\r\n// and will appear offscreen and so it will only render the first item.\r\n// Then, the page styles are loaded and applied and the sidebar\r\n// is now `position: fixed` so `<main/>` is now rendered at the top of the page\r\n// but `VirtualScroller`'s `.render()` has already been called\r\n// and it won't re-render until the user scrolls or the window is resized.\r\n// This type of a bug doesn't occur in production, but it can appear\r\n// in development mode when using Webpack. The workaround `VirtualScroller`\r\n// implements for such cases is calling `.getListTopOffsetInsideScrollableContainer()`\r\n// on the list container DOM element periodically (every second) to check\r\n// if the `top` coordinate has changed as a result of CSS being applied:\r\n// if it has then it recalculates the shown item indexes.\r\nexport default class WaitForStylesToLoad {\r\n\tconstructor({\r\n\t\tupdateLayout,\r\n\t\tgetListTopOffsetInsideScrollableContainer\r\n\t}) {\r\n\t\tthis.updateLayout = updateLayout\r\n\t\tthis.getListTopOffsetInsideScrollableContainer = getListTopOffsetInsideScrollableContainer\r\n\t}\r\n\r\n\tonGotListTopOffset(listTopOffset) {\r\n\t\tif (this.listTopOffsetInsideScrollableContainer === undefined) {\r\n\t\t\t// Start periodical checks of the list's top offset\r\n\t\t\t// in order to perform a re-layout in case it changes.\r\n\t\t\t// See the comments in `WaitForStylesToLoad.js` file\r\n\t\t\t// on why can the list's top offset change, and in which circumstances.\r\n\t\t\tthis.start()\r\n\t\t}\r\n\t\tthis.listTopOffsetInsideScrollableContainer = listTopOffset\r\n\t}\r\n\r\n\tstart() {\r\n\t\tthis.isRendered = true\r\n\t\tthis.watchListTopOffset()\r\n\t}\r\n\r\n\tstop() {\r\n\t\tthis.isRendered = false\r\n\t\tclearTimeout(this.watchListTopOffsetTimer)\r\n\t}\r\n\r\n\twatchListTopOffset() {\r\n\t\tconst startedAt = Date.now()\r\n\t\tconst check = () => {\r\n\t\t\t// If `VirtualScroller` has been unmounted\r\n\t\t\t// while `setTimeout()` was waiting, then exit.\r\n\t\t\tif (!this.isRendered) {\r\n\t\t\t\treturn\r\n\t\t\t}\r\n\t\t\t// Skip comparing `top` coordinate of the list\r\n\t\t\t// when this function is called for the first time.\r\n\t\t\tif (this.listTopOffsetInsideScrollableContainer !== undefined) {\r\n\t\t\t\t// Calling `this.getListTopOffsetInsideScrollableContainer()`\r\n\t\t\t\t// on an element is about 0.003 milliseconds on a modern desktop CPU,\r\n\t\t\t\t// so I guess it's fine calling it twice a second.\r\n\t\t\t\tif (this.getListTopOffsetInsideScrollableContainer() !== this.listTopOffsetInsideScrollableContainer) {\r\n\t\t\t\t\tthis.updateLayout({ reason: LAYOUT_REASON.TOP_OFFSET_CHANGED })\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t// Compare `top` coordinate of the list twice a second\r\n\t\t\t// to find out if it has changed as a result of loading CSS styles.\r\n\t\t\t// The total duration of 3 seconds would be enough for any styles to load, I guess.\r\n\t\t\t// There could be other cases changing the `top` coordinate\r\n\t\t\t// of the list (like collapsing an \"accordeon\" panel above the list\r\n\t\t\t// without scrolling the page), but those cases should be handled\r\n\t\t\t// by manually calling `.updateLayout()` instance method on `VirtualScroller` instance.\r\n\t\t\tif (Date.now() - startedAt < WATCH_LIST_TOP_OFFSET_MAX_DURATION) {\r\n\t\t\t\tthis.watchListTopOffsetTimer = setTimeout(check, WATCH_LIST_TOP_OFFSET_INTERVAL)\r\n\t\t\t}\r\n\t\t}\r\n\t\t// Run the cycle.\r\n\t\tcheck()\r\n\t}\r\n}\r\n\r\nconst WATCH_LIST_TOP_OFFSET_INTERVAL = 500\r\nconst WATCH_LIST_TOP_OFFSET_MAX_DURATION = 3000"],"file":"WaitForStylesToLoad.js"}
@@ -1,111 +0,0 @@
1
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2
-
3
- function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
4
-
5
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
6
-
7
- var RestoreScroll =
8
- /*#__PURE__*/
9
- function () {
10
- function RestoreScroll(_ref) {
11
- var screen = _ref.screen,
12
- getContainerElement = _ref.getContainerElement,
13
- scrollBy = _ref.scrollBy;
14
-
15
- _classCallCheck(this, RestoreScroll);
16
-
17
- this.screen = screen;
18
- this.getContainerElement = getContainerElement;
19
- this.scrollBy = scrollBy;
20
- }
21
- /**
22
- * `<ReactVirtualScroller/>` calls this method.
23
- * @param {any[]} previousItems
24
- * @param {any[]} newItems
25
- * @param {number} prependedItemsCount
26
- */
27
-
28
-
29
- _createClass(RestoreScroll, [{
30
- key: "captureScroll",
31
- value: function captureScroll(_ref2) {
32
- var previousItems = _ref2.previousItems,
33
- newItems = _ref2.newItems,
34
- prependedItemsCount = _ref2.prependedItemsCount;
35
-
36
- // If there were no items in the list
37
- // then there's no point in restoring scroll position.
38
- if (previousItems.length === 0) {
39
- return;
40
- } // If no items were prepended then no need to restore scroll position.
41
-
42
-
43
- if (prependedItemsCount === 0) {
44
- return;
45
- }
46
-
47
- var container = this.getContainerElement();
48
- var firstItemTopOffset = this.screen.getChildElementTopOffset(container, 0); // The first item is supposed to be shown when the user clicks
49
- // "Show previous items" button. If it isn't shown though,
50
- // could still calculate the first item's top position using
51
- // the values from `itemHeights` and `verticalSpacing`.
52
- // But that would be a weird non-realistic scenario.
53
- // if (firstShownItemIndex > 0) {
54
- // let i = firstShownItemIndex - 1
55
- // while (i >= 0) {
56
- // firstItemTopOffset += itemHeights[i] + verticalSpacing
57
- // i--
58
- // }
59
- // }
60
- // If the scroll position has already been captured for restoration,
61
- // then don't capture it the second time.
62
- // Capturing scroll position could happen when using `<ReactVirtualScroller/>`
63
- // because it calls `.captureScroll()` inside `ReactVirtualScroller.render()`
64
- // which is followed by `<VirtualScroller/>`'s `.componentDidUpdate()`
65
- // that also calls `.captureScroll()` with the same arguments,
66
- // so that second call to `.captureScroll()` is ignored.
67
- // Calling `.captureScroll()` inside `ReactVirtualScroller.render()`
68
- // is done to prevent scroll Y position from jumping
69
- // when showing the first page of the "Previous items".
70
- // See the long section of comments in `ReactVirtualScroller.render()`
71
- // method for more info on why is `.captureScroll()` called there.
72
-
73
- if (this.restoreScrollAfterRenderValues && this.restoreScrollAfterRenderValues.previousItems === previousItems && this.restoreScrollAfterRenderValues.newItems === newItems) {
74
- return;
75
- }
76
-
77
- this.restoreScrollAfterRenderValues = {
78
- previousItems: previousItems,
79
- newItems: newItems,
80
- index: prependedItemsCount,
81
- visibleAreaTop: firstItemTopOffset
82
- };
83
- }
84
- }, {
85
- key: "getAnchorItemIndex",
86
- value: function getAnchorItemIndex() {
87
- return this.restoreScrollAfterRenderValues.index;
88
- }
89
- }, {
90
- key: "shouldRestoreScrollAfterRender",
91
- value: function shouldRestoreScrollAfterRender() {
92
- return this.restoreScrollAfterRenderValues !== undefined;
93
- }
94
- }, {
95
- key: "getScrollDifference",
96
- value: function getScrollDifference() {
97
- var _this$restoreScrollAf = this.restoreScrollAfterRenderValues,
98
- index = _this$restoreScrollAf.index,
99
- visibleAreaTop = _this$restoreScrollAf.visibleAreaTop;
100
- this.restoreScrollAfterRenderValues = undefined; // `firstShownItemIndex` is supposed to be `0` here.
101
-
102
- var newVisibleAreaTop = this.screen.getChildElementTopOffset(this.getContainerElement(), index);
103
- return newVisibleAreaTop - visibleAreaTop;
104
- }
105
- }]);
106
-
107
- return RestoreScroll;
108
- }();
109
-
110
- export { RestoreScroll as default };
111
- //# sourceMappingURL=RestoreScroll.js.map