virtual-scroller 1.12.4 → 1.12.6

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.
@@ -9,27 +9,67 @@ function getVerticalSpacing(_ref) {
9
9
  var itemsContainer = _ref.itemsContainer,
10
10
  renderedItemsCount = _ref.renderedItemsCount;
11
11
 
12
+ // If there's more than a single item rendered, it becomes potentially possible
13
+ // to measure vertical spacing.
12
14
  if (renderedItemsCount > 1) {
15
+ // Measure the first item of the first rendered row: top offset and height.
13
16
  var firstShownRowTopOffset = itemsContainer.getNthRenderedItemTopOffset(0);
14
- var firstShownRowHeight = itemsContainer.getNthRenderedItemHeight(0);
17
+ var firstShownRowHeight = itemsContainer.getNthRenderedItemHeight(0); // Measure next items until a new row is started, at which point
18
+ // it becomes possible to calculate the vertical spacing between the rows.
19
+
15
20
  var i = 1;
16
21
 
17
22
  while (i < renderedItemsCount) {
23
+ // Measure item: top offset and height.
18
24
  var itemTopOffset = itemsContainer.getNthRenderedItemTopOffset(i);
19
- var itemHeight = itemsContainer.getNthRenderedItemHeight(i); // See if the item is on the next row.
20
- // Simply checking for `itemTopOffset !== firstShownRowTopOffset` wouldn't work
21
- // because items in a row aren't required to be aligned to the top border.
25
+ var itemHeight = itemsContainer.getNthRenderedItemHeight(i); // See if the item is already on the next row. If yes, then can calculate
26
+ // vertical spacing between the rows.
27
+ //
28
+ // To detect next row, it uses a `>=` operator rather than just a `!==` operator.
29
+ // The reason is that simply checking for `itemTopOffset !== firstShownRowTopOffset`
30
+ // wouldn't work because items in a row aren't required to be aligned to the top edge of the row.
31
+ //
32
+ // Also, it uses rounding here to work around a bug that manifests when a web browser
33
+ // renders the web page with a scale value other than 100%. In that case, even when
34
+ // different identical items would've had equal heights, they'd have slightly different heights
35
+ // to the point of ~0.00001 because of the non-100% scale calculation imprecision.
36
+ //
37
+ // The result would be incorrect detection of same/next row, which would result in
38
+ // returning a huge vertical spacing that is equal to a height of an item,
39
+ // which would then result in a glitchy behavior of `virtual-scroller` when scrolling.
40
+ //
41
+ // To work around that bug, it rounds up to the closest higher `1px`
42
+ // and only then performs the `>=` comparison to detect same/next row.
43
+ //
22
44
 
23
- if (itemTopOffset >= firstShownRowTopOffset + firstShownRowHeight) {
24
- // Measure inter-row spacing.
45
+ if (itemTopOffset + PAGE_ZOOM_ROUNDING_PRECISION_FIX_INCREMENT >= firstShownRowTopOffset + firstShownRowHeight) {
46
+ // Next row is detected. Measure inter-row spacing.
25
47
  // Can't be "negative" with the current `if` condition.
26
48
  return itemTopOffset - (firstShownRowTopOffset + firstShownRowHeight);
27
- } // A row height is the maximum of its item heights.
49
+ } // Not at the next row yet. Re-measure the current row height.
50
+ // The rationale for re-measuring is that there can be items of variable height
51
+ // in a given row, so the row's height is not known until all items in it are measured.
52
+ // A row height is the maximum of its items' heights.
53
+
28
54
 
55
+ firstShownRowHeight = Math.max(firstShownRowHeight, itemHeight); // Proceed to the next item.
29
56
 
30
- firstShownRowHeight = Math.max(firstShownRowHeight, itemHeight);
31
57
  i++;
32
58
  }
33
59
  }
34
- }
60
+ } // There's a rounding precision error when a web browser has a non-100% scale
61
+ // when viewing a page. I dunno what's the source of the imprecision.
62
+ // The thing is: previousRow.top + previousRow.height !== nextRow.top.
63
+ // The two parts of the equation above differ by a magnitude of 0.0001.
64
+ // To fix that, when performing a `>=` comparison, an additional increment is added.
65
+ //
66
+ // This value of the increment is set to `0.9px` for no real reason.
67
+ // It could be `1px` or `0.99px` and it would most likely work the same way.
68
+ // The rationale for the `0.9px` value is that a minimum height of a DOM element
69
+ // is assumed to be `1px` so having a value less than `1px` would theoretically be
70
+ // less buggy in a way that it wouldn't skip the rows that're `1px` high.
71
+ //
72
+
73
+
74
+ var PAGE_ZOOM_ROUNDING_PRECISION_FIX_INCREMENT = 0.9;
35
75
  //# sourceMappingURL=getVerticalSpacing.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"getVerticalSpacing.js","names":["getVerticalSpacing","itemsContainer","renderedItemsCount","firstShownRowTopOffset","getNthRenderedItemTopOffset","firstShownRowHeight","getNthRenderedItemHeight","i","itemTopOffset","itemHeight","Math","max"],"sources":["../source/getVerticalSpacing.js"],"sourcesContent":["export default function getVerticalSpacing({ itemsContainer, renderedItemsCount }) {\r\n\tif (renderedItemsCount > 1) {\r\n\t\tconst firstShownRowTopOffset = itemsContainer.getNthRenderedItemTopOffset(0)\r\n\t\tlet firstShownRowHeight = itemsContainer.getNthRenderedItemHeight(0)\r\n\t\tlet i = 1\r\n\t\twhile (i < renderedItemsCount) {\r\n\t\t\tconst itemTopOffset = itemsContainer.getNthRenderedItemTopOffset(i)\r\n\t\t\tconst itemHeight = itemsContainer.getNthRenderedItemHeight(i)\r\n\t\t\t// See if the item is on the next row.\r\n\t\t\t// Simply checking for `itemTopOffset !== firstShownRowTopOffset` wouldn't work\r\n\t\t\t// because items in a row aren't required to be aligned to the top border.\r\n\t\t\tif (itemTopOffset >= firstShownRowTopOffset + firstShownRowHeight) {\r\n\t\t\t\t// Measure inter-row spacing.\r\n\t\t\t\t// Can't be \"negative\" with the current `if` condition.\r\n\t\t\t\treturn itemTopOffset - (firstShownRowTopOffset + firstShownRowHeight)\r\n\t\t\t}\r\n\t\t\t// A row height is the maximum of its item heights.\r\n\t\t\tfirstShownRowHeight = Math.max(firstShownRowHeight, itemHeight)\r\n\t\t\ti++\r\n\t\t}\r\n\t}\r\n}"],"mappings":";;;;;;;AAAe,SAASA,kBAAT,OAAoE;EAAA,IAAtCC,cAAsC,QAAtCA,cAAsC;EAAA,IAAtBC,kBAAsB,QAAtBA,kBAAsB;;EAClF,IAAIA,kBAAkB,GAAG,CAAzB,EAA4B;IAC3B,IAAMC,sBAAsB,GAAGF,cAAc,CAACG,2BAAf,CAA2C,CAA3C,CAA/B;IACA,IAAIC,mBAAmB,GAAGJ,cAAc,CAACK,wBAAf,CAAwC,CAAxC,CAA1B;IACA,IAAIC,CAAC,GAAG,CAAR;;IACA,OAAOA,CAAC,GAAGL,kBAAX,EAA+B;MAC9B,IAAMM,aAAa,GAAGP,cAAc,CAACG,2BAAf,CAA2CG,CAA3C,CAAtB;MACA,IAAME,UAAU,GAAGR,cAAc,CAACK,wBAAf,CAAwCC,CAAxC,CAAnB,CAF8B,CAG9B;MACA;MACA;;MACA,IAAIC,aAAa,IAAIL,sBAAsB,GAAGE,mBAA9C,EAAmE;QAClE;QACA;QACA,OAAOG,aAAa,IAAIL,sBAAsB,GAAGE,mBAA7B,CAApB;MACA,CAV6B,CAW9B;;;MACAA,mBAAmB,GAAGK,IAAI,CAACC,GAAL,CAASN,mBAAT,EAA8BI,UAA9B,CAAtB;MACAF,CAAC;IACD;EACD;AACD"}
1
+ {"version":3,"file":"getVerticalSpacing.js","names":["getVerticalSpacing","itemsContainer","renderedItemsCount","firstShownRowTopOffset","getNthRenderedItemTopOffset","firstShownRowHeight","getNthRenderedItemHeight","i","itemTopOffset","itemHeight","PAGE_ZOOM_ROUNDING_PRECISION_FIX_INCREMENT","Math","max"],"sources":["../source/getVerticalSpacing.js"],"sourcesContent":["export default function getVerticalSpacing({ itemsContainer, renderedItemsCount }) {\r\n\t// If there's more than a single item rendered, it becomes potentially possible\r\n\t// to measure vertical spacing.\r\n\tif (renderedItemsCount > 1) {\r\n\t\t// Measure the first item of the first rendered row: top offset and height.\r\n\t\tconst firstShownRowTopOffset = itemsContainer.getNthRenderedItemTopOffset(0)\r\n\t\tlet firstShownRowHeight = itemsContainer.getNthRenderedItemHeight(0)\r\n\r\n\t\t// Measure next items until a new row is started, at which point\r\n\t\t// it becomes possible to calculate the vertical spacing between the rows.\r\n\t\tlet i = 1\r\n\t\twhile (i < renderedItemsCount) {\r\n\t\t\t// Measure item: top offset and height.\r\n\t\t\tconst itemTopOffset = itemsContainer.getNthRenderedItemTopOffset(i)\r\n\t\t\tconst itemHeight = itemsContainer.getNthRenderedItemHeight(i)\r\n\r\n\t\t\t// See if the item is already on the next row. If yes, then can calculate\r\n\t\t\t// vertical spacing between the rows.\r\n\t\t\t//\r\n\t\t\t// To detect next row, it uses a `>=` operator rather than just a `!==` operator.\r\n\t\t\t// The reason is that simply checking for `itemTopOffset !== firstShownRowTopOffset`\r\n\t\t\t// wouldn't work because items in a row aren't required to be aligned to the top edge of the row.\r\n\t\t\t//\r\n\t\t\t// Also, it uses rounding here to work around a bug that manifests when a web browser\r\n\t\t\t// renders the web page with a scale value other than 100%. In that case, even when\r\n\t\t\t// different identical items would've had equal heights, they'd have slightly different heights\r\n\t\t\t// to the point of ~0.00001 because of the non-100% scale calculation imprecision.\r\n\t\t\t//\r\n\t\t\t// The result would be incorrect detection of same/next row, which would result in\r\n\t\t\t// returning a huge vertical spacing that is equal to a height of an item,\r\n\t\t\t// which would then result in a glitchy behavior of `virtual-scroller` when scrolling.\r\n\t\t\t//\r\n\t\t\t// To work around that bug, it rounds up to the closest higher `1px`\r\n\t\t\t// and only then performs the `>=` comparison to detect same/next row.\r\n\t\t\t//\r\n\t\t\tif (itemTopOffset + PAGE_ZOOM_ROUNDING_PRECISION_FIX_INCREMENT >= firstShownRowTopOffset + firstShownRowHeight) {\r\n\t\t\t\t// Next row is detected. Measure inter-row spacing.\r\n\t\t\t\t// Can't be \"negative\" with the current `if` condition.\r\n\t\t\t\treturn itemTopOffset - (firstShownRowTopOffset + firstShownRowHeight)\r\n\t\t\t}\r\n\r\n\t\t\t// Not at the next row yet. Re-measure the current row height.\r\n\t\t\t// The rationale for re-measuring is that there can be items of variable height\r\n\t\t\t// in a given row, so the row's height is not known until all items in it are measured.\r\n\t\t\t// A row height is the maximum of its items' heights.\r\n\t\t\tfirstShownRowHeight = Math.max(firstShownRowHeight, itemHeight)\r\n\r\n\t\t\t// Proceed to the next item.\r\n\t\t\ti++\r\n\t\t}\r\n\t}\r\n}\r\n\r\n// There's a rounding precision error when a web browser has a non-100% scale\r\n// when viewing a page. I dunno what's the source of the imprecision.\r\n// The thing is: previousRow.top + previousRow.height !== nextRow.top.\r\n// The two parts of the equation above differ by a magnitude of 0.0001.\r\n// To fix that, when performing a `>=` comparison, an additional increment is added.\r\n//\r\n// This value of the increment is set to `0.9px` for no real reason.\r\n// It could be `1px` or `0.99px` and it would most likely work the same way.\r\n// The rationale for the `0.9px` value is that a minimum height of a DOM element\r\n// is assumed to be `1px` so having a value less than `1px` would theoretically be\r\n// less buggy in a way that it wouldn't skip the rows that're `1px` high.\r\n//\r\nconst PAGE_ZOOM_ROUNDING_PRECISION_FIX_INCREMENT = 0.9"],"mappings":";;;;;;;AAAe,SAASA,kBAAT,OAAoE;EAAA,IAAtCC,cAAsC,QAAtCA,cAAsC;EAAA,IAAtBC,kBAAsB,QAAtBA,kBAAsB;;EAClF;EACA;EACA,IAAIA,kBAAkB,GAAG,CAAzB,EAA4B;IAC3B;IACA,IAAMC,sBAAsB,GAAGF,cAAc,CAACG,2BAAf,CAA2C,CAA3C,CAA/B;IACA,IAAIC,mBAAmB,GAAGJ,cAAc,CAACK,wBAAf,CAAwC,CAAxC,CAA1B,CAH2B,CAK3B;IACA;;IACA,IAAIC,CAAC,GAAG,CAAR;;IACA,OAAOA,CAAC,GAAGL,kBAAX,EAA+B;MAC9B;MACA,IAAMM,aAAa,GAAGP,cAAc,CAACG,2BAAf,CAA2CG,CAA3C,CAAtB;MACA,IAAME,UAAU,GAAGR,cAAc,CAACK,wBAAf,CAAwCC,CAAxC,CAAnB,CAH8B,CAK9B;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;;MACA,IAAIC,aAAa,GAAGE,0CAAhB,IAA8DP,sBAAsB,GAAGE,mBAA3F,EAAgH;QAC/G;QACA;QACA,OAAOG,aAAa,IAAIL,sBAAsB,GAAGE,mBAA7B,CAApB;MACA,CA5B6B,CA8B9B;MACA;MACA;MACA;;;MACAA,mBAAmB,GAAGM,IAAI,CAACC,GAAL,CAASP,mBAAT,EAA8BI,UAA9B,CAAtB,CAlC8B,CAoC9B;;MACAF,CAAC;IACD;EACD;AACD,C,CAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AACA,IAAMG,0CAA0C,GAAG,GAAnD"}
@@ -2,27 +2,66 @@ export default function getVerticalSpacing(_ref) {
2
2
  var itemsContainer = _ref.itemsContainer,
3
3
  renderedItemsCount = _ref.renderedItemsCount;
4
4
 
5
+ // If there's more than a single item rendered, it becomes potentially possible
6
+ // to measure vertical spacing.
5
7
  if (renderedItemsCount > 1) {
8
+ // Measure the first item of the first rendered row: top offset and height.
6
9
  var firstShownRowTopOffset = itemsContainer.getNthRenderedItemTopOffset(0);
7
- var firstShownRowHeight = itemsContainer.getNthRenderedItemHeight(0);
10
+ var firstShownRowHeight = itemsContainer.getNthRenderedItemHeight(0); // Measure next items until a new row is started, at which point
11
+ // it becomes possible to calculate the vertical spacing between the rows.
12
+
8
13
  var i = 1;
9
14
 
10
15
  while (i < renderedItemsCount) {
16
+ // Measure item: top offset and height.
11
17
  var itemTopOffset = itemsContainer.getNthRenderedItemTopOffset(i);
12
- var itemHeight = itemsContainer.getNthRenderedItemHeight(i); // See if the item is on the next row.
13
- // Simply checking for `itemTopOffset !== firstShownRowTopOffset` wouldn't work
14
- // because items in a row aren't required to be aligned to the top border.
18
+ var itemHeight = itemsContainer.getNthRenderedItemHeight(i); // See if the item is already on the next row. If yes, then can calculate
19
+ // vertical spacing between the rows.
20
+ //
21
+ // To detect next row, it uses a `>=` operator rather than just a `!==` operator.
22
+ // The reason is that simply checking for `itemTopOffset !== firstShownRowTopOffset`
23
+ // wouldn't work because items in a row aren't required to be aligned to the top edge of the row.
24
+ //
25
+ // Also, it uses rounding here to work around a bug that manifests when a web browser
26
+ // renders the web page with a scale value other than 100%. In that case, even when
27
+ // different identical items would've had equal heights, they'd have slightly different heights
28
+ // to the point of ~0.00001 because of the non-100% scale calculation imprecision.
29
+ //
30
+ // The result would be incorrect detection of same/next row, which would result in
31
+ // returning a huge vertical spacing that is equal to a height of an item,
32
+ // which would then result in a glitchy behavior of `virtual-scroller` when scrolling.
33
+ //
34
+ // To work around that bug, it rounds up to the closest higher `1px`
35
+ // and only then performs the `>=` comparison to detect same/next row.
36
+ //
15
37
 
16
- if (itemTopOffset >= firstShownRowTopOffset + firstShownRowHeight) {
17
- // Measure inter-row spacing.
38
+ if (itemTopOffset + PAGE_ZOOM_ROUNDING_PRECISION_FIX_INCREMENT >= firstShownRowTopOffset + firstShownRowHeight) {
39
+ // Next row is detected. Measure inter-row spacing.
18
40
  // Can't be "negative" with the current `if` condition.
19
41
  return itemTopOffset - (firstShownRowTopOffset + firstShownRowHeight);
20
- } // A row height is the maximum of its item heights.
42
+ } // Not at the next row yet. Re-measure the current row height.
43
+ // The rationale for re-measuring is that there can be items of variable height
44
+ // in a given row, so the row's height is not known until all items in it are measured.
45
+ // A row height is the maximum of its items' heights.
46
+
21
47
 
48
+ firstShownRowHeight = Math.max(firstShownRowHeight, itemHeight); // Proceed to the next item.
22
49
 
23
- firstShownRowHeight = Math.max(firstShownRowHeight, itemHeight);
24
50
  i++;
25
51
  }
26
52
  }
27
- }
53
+ } // There's a rounding precision error when a web browser has a non-100% scale
54
+ // when viewing a page. I dunno what's the source of the imprecision.
55
+ // The thing is: previousRow.top + previousRow.height !== nextRow.top.
56
+ // The two parts of the equation above differ by a magnitude of 0.0001.
57
+ // To fix that, when performing a `>=` comparison, an additional increment is added.
58
+ //
59
+ // This value of the increment is set to `0.9px` for no real reason.
60
+ // It could be `1px` or `0.99px` and it would most likely work the same way.
61
+ // The rationale for the `0.9px` value is that a minimum height of a DOM element
62
+ // is assumed to be `1px` so having a value less than `1px` would theoretically be
63
+ // less buggy in a way that it wouldn't skip the rows that're `1px` high.
64
+ //
65
+
66
+ var PAGE_ZOOM_ROUNDING_PRECISION_FIX_INCREMENT = 0.9;
28
67
  //# sourceMappingURL=getVerticalSpacing.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"getVerticalSpacing.js","names":["getVerticalSpacing","itemsContainer","renderedItemsCount","firstShownRowTopOffset","getNthRenderedItemTopOffset","firstShownRowHeight","getNthRenderedItemHeight","i","itemTopOffset","itemHeight","Math","max"],"sources":["../source/getVerticalSpacing.js"],"sourcesContent":["export default function getVerticalSpacing({ itemsContainer, renderedItemsCount }) {\r\n\tif (renderedItemsCount > 1) {\r\n\t\tconst firstShownRowTopOffset = itemsContainer.getNthRenderedItemTopOffset(0)\r\n\t\tlet firstShownRowHeight = itemsContainer.getNthRenderedItemHeight(0)\r\n\t\tlet i = 1\r\n\t\twhile (i < renderedItemsCount) {\r\n\t\t\tconst itemTopOffset = itemsContainer.getNthRenderedItemTopOffset(i)\r\n\t\t\tconst itemHeight = itemsContainer.getNthRenderedItemHeight(i)\r\n\t\t\t// See if the item is on the next row.\r\n\t\t\t// Simply checking for `itemTopOffset !== firstShownRowTopOffset` wouldn't work\r\n\t\t\t// because items in a row aren't required to be aligned to the top border.\r\n\t\t\tif (itemTopOffset >= firstShownRowTopOffset + firstShownRowHeight) {\r\n\t\t\t\t// Measure inter-row spacing.\r\n\t\t\t\t// Can't be \"negative\" with the current `if` condition.\r\n\t\t\t\treturn itemTopOffset - (firstShownRowTopOffset + firstShownRowHeight)\r\n\t\t\t}\r\n\t\t\t// A row height is the maximum of its item heights.\r\n\t\t\tfirstShownRowHeight = Math.max(firstShownRowHeight, itemHeight)\r\n\t\t\ti++\r\n\t\t}\r\n\t}\r\n}"],"mappings":"AAAA,eAAe,SAASA,kBAAT,OAAoE;EAAA,IAAtCC,cAAsC,QAAtCA,cAAsC;EAAA,IAAtBC,kBAAsB,QAAtBA,kBAAsB;;EAClF,IAAIA,kBAAkB,GAAG,CAAzB,EAA4B;IAC3B,IAAMC,sBAAsB,GAAGF,cAAc,CAACG,2BAAf,CAA2C,CAA3C,CAA/B;IACA,IAAIC,mBAAmB,GAAGJ,cAAc,CAACK,wBAAf,CAAwC,CAAxC,CAA1B;IACA,IAAIC,CAAC,GAAG,CAAR;;IACA,OAAOA,CAAC,GAAGL,kBAAX,EAA+B;MAC9B,IAAMM,aAAa,GAAGP,cAAc,CAACG,2BAAf,CAA2CG,CAA3C,CAAtB;MACA,IAAME,UAAU,GAAGR,cAAc,CAACK,wBAAf,CAAwCC,CAAxC,CAAnB,CAF8B,CAG9B;MACA;MACA;;MACA,IAAIC,aAAa,IAAIL,sBAAsB,GAAGE,mBAA9C,EAAmE;QAClE;QACA;QACA,OAAOG,aAAa,IAAIL,sBAAsB,GAAGE,mBAA7B,CAApB;MACA,CAV6B,CAW9B;;;MACAA,mBAAmB,GAAGK,IAAI,CAACC,GAAL,CAASN,mBAAT,EAA8BI,UAA9B,CAAtB;MACAF,CAAC;IACD;EACD;AACD"}
1
+ {"version":3,"file":"getVerticalSpacing.js","names":["getVerticalSpacing","itemsContainer","renderedItemsCount","firstShownRowTopOffset","getNthRenderedItemTopOffset","firstShownRowHeight","getNthRenderedItemHeight","i","itemTopOffset","itemHeight","PAGE_ZOOM_ROUNDING_PRECISION_FIX_INCREMENT","Math","max"],"sources":["../source/getVerticalSpacing.js"],"sourcesContent":["export default function getVerticalSpacing({ itemsContainer, renderedItemsCount }) {\r\n\t// If there's more than a single item rendered, it becomes potentially possible\r\n\t// to measure vertical spacing.\r\n\tif (renderedItemsCount > 1) {\r\n\t\t// Measure the first item of the first rendered row: top offset and height.\r\n\t\tconst firstShownRowTopOffset = itemsContainer.getNthRenderedItemTopOffset(0)\r\n\t\tlet firstShownRowHeight = itemsContainer.getNthRenderedItemHeight(0)\r\n\r\n\t\t// Measure next items until a new row is started, at which point\r\n\t\t// it becomes possible to calculate the vertical spacing between the rows.\r\n\t\tlet i = 1\r\n\t\twhile (i < renderedItemsCount) {\r\n\t\t\t// Measure item: top offset and height.\r\n\t\t\tconst itemTopOffset = itemsContainer.getNthRenderedItemTopOffset(i)\r\n\t\t\tconst itemHeight = itemsContainer.getNthRenderedItemHeight(i)\r\n\r\n\t\t\t// See if the item is already on the next row. If yes, then can calculate\r\n\t\t\t// vertical spacing between the rows.\r\n\t\t\t//\r\n\t\t\t// To detect next row, it uses a `>=` operator rather than just a `!==` operator.\r\n\t\t\t// The reason is that simply checking for `itemTopOffset !== firstShownRowTopOffset`\r\n\t\t\t// wouldn't work because items in a row aren't required to be aligned to the top edge of the row.\r\n\t\t\t//\r\n\t\t\t// Also, it uses rounding here to work around a bug that manifests when a web browser\r\n\t\t\t// renders the web page with a scale value other than 100%. In that case, even when\r\n\t\t\t// different identical items would've had equal heights, they'd have slightly different heights\r\n\t\t\t// to the point of ~0.00001 because of the non-100% scale calculation imprecision.\r\n\t\t\t//\r\n\t\t\t// The result would be incorrect detection of same/next row, which would result in\r\n\t\t\t// returning a huge vertical spacing that is equal to a height of an item,\r\n\t\t\t// which would then result in a glitchy behavior of `virtual-scroller` when scrolling.\r\n\t\t\t//\r\n\t\t\t// To work around that bug, it rounds up to the closest higher `1px`\r\n\t\t\t// and only then performs the `>=` comparison to detect same/next row.\r\n\t\t\t//\r\n\t\t\tif (itemTopOffset + PAGE_ZOOM_ROUNDING_PRECISION_FIX_INCREMENT >= firstShownRowTopOffset + firstShownRowHeight) {\r\n\t\t\t\t// Next row is detected. Measure inter-row spacing.\r\n\t\t\t\t// Can't be \"negative\" with the current `if` condition.\r\n\t\t\t\treturn itemTopOffset - (firstShownRowTopOffset + firstShownRowHeight)\r\n\t\t\t}\r\n\r\n\t\t\t// Not at the next row yet. Re-measure the current row height.\r\n\t\t\t// The rationale for re-measuring is that there can be items of variable height\r\n\t\t\t// in a given row, so the row's height is not known until all items in it are measured.\r\n\t\t\t// A row height is the maximum of its items' heights.\r\n\t\t\tfirstShownRowHeight = Math.max(firstShownRowHeight, itemHeight)\r\n\r\n\t\t\t// Proceed to the next item.\r\n\t\t\ti++\r\n\t\t}\r\n\t}\r\n}\r\n\r\n// There's a rounding precision error when a web browser has a non-100% scale\r\n// when viewing a page. I dunno what's the source of the imprecision.\r\n// The thing is: previousRow.top + previousRow.height !== nextRow.top.\r\n// The two parts of the equation above differ by a magnitude of 0.0001.\r\n// To fix that, when performing a `>=` comparison, an additional increment is added.\r\n//\r\n// This value of the increment is set to `0.9px` for no real reason.\r\n// It could be `1px` or `0.99px` and it would most likely work the same way.\r\n// The rationale for the `0.9px` value is that a minimum height of a DOM element\r\n// is assumed to be `1px` so having a value less than `1px` would theoretically be\r\n// less buggy in a way that it wouldn't skip the rows that're `1px` high.\r\n//\r\nconst PAGE_ZOOM_ROUNDING_PRECISION_FIX_INCREMENT = 0.9"],"mappings":"AAAA,eAAe,SAASA,kBAAT,OAAoE;EAAA,IAAtCC,cAAsC,QAAtCA,cAAsC;EAAA,IAAtBC,kBAAsB,QAAtBA,kBAAsB;;EAClF;EACA;EACA,IAAIA,kBAAkB,GAAG,CAAzB,EAA4B;IAC3B;IACA,IAAMC,sBAAsB,GAAGF,cAAc,CAACG,2BAAf,CAA2C,CAA3C,CAA/B;IACA,IAAIC,mBAAmB,GAAGJ,cAAc,CAACK,wBAAf,CAAwC,CAAxC,CAA1B,CAH2B,CAK3B;IACA;;IACA,IAAIC,CAAC,GAAG,CAAR;;IACA,OAAOA,CAAC,GAAGL,kBAAX,EAA+B;MAC9B;MACA,IAAMM,aAAa,GAAGP,cAAc,CAACG,2BAAf,CAA2CG,CAA3C,CAAtB;MACA,IAAME,UAAU,GAAGR,cAAc,CAACK,wBAAf,CAAwCC,CAAxC,CAAnB,CAH8B,CAK9B;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;;MACA,IAAIC,aAAa,GAAGE,0CAAhB,IAA8DP,sBAAsB,GAAGE,mBAA3F,EAAgH;QAC/G;QACA;QACA,OAAOG,aAAa,IAAIL,sBAAsB,GAAGE,mBAA7B,CAApB;MACA,CA5B6B,CA8B9B;MACA;MACA;MACA;;;MACAA,mBAAmB,GAAGM,IAAI,CAACC,GAAL,CAASP,mBAAT,EAA8BI,UAA9B,CAAtB,CAlC8B,CAoC9B;;MACAF,CAAC;IACD;EACD;AACD,C,CAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AACA,IAAMG,0CAA0C,GAAG,GAAnD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "virtual-scroller",
3
- "version": "1.12.4",
3
+ "version": "1.12.6",
4
4
  "description": "A component for efficiently rendering large lists of variable height items",
5
5
  "main": "index.cjs",
6
6
  "module": "index.js",
@@ -1,22 +1,66 @@
1
1
  export default function getVerticalSpacing({ itemsContainer, renderedItemsCount }) {
2
+ // If there's more than a single item rendered, it becomes potentially possible
3
+ // to measure vertical spacing.
2
4
  if (renderedItemsCount > 1) {
5
+ // Measure the first item of the first rendered row: top offset and height.
3
6
  const firstShownRowTopOffset = itemsContainer.getNthRenderedItemTopOffset(0)
4
7
  let firstShownRowHeight = itemsContainer.getNthRenderedItemHeight(0)
8
+
9
+ // Measure next items until a new row is started, at which point
10
+ // it becomes possible to calculate the vertical spacing between the rows.
5
11
  let i = 1
6
12
  while (i < renderedItemsCount) {
13
+ // Measure item: top offset and height.
7
14
  const itemTopOffset = itemsContainer.getNthRenderedItemTopOffset(i)
8
15
  const itemHeight = itemsContainer.getNthRenderedItemHeight(i)
9
- // See if the item is on the next row.
10
- // Simply checking for `itemTopOffset !== firstShownRowTopOffset` wouldn't work
11
- // because items in a row aren't required to be aligned to the top border.
12
- if (itemTopOffset >= firstShownRowTopOffset + firstShownRowHeight) {
13
- // Measure inter-row spacing.
16
+
17
+ // See if the item is already on the next row. If yes, then can calculate
18
+ // vertical spacing between the rows.
19
+ //
20
+ // To detect next row, it uses a `>=` operator rather than just a `!==` operator.
21
+ // The reason is that simply checking for `itemTopOffset !== firstShownRowTopOffset`
22
+ // wouldn't work because items in a row aren't required to be aligned to the top edge of the row.
23
+ //
24
+ // Also, it uses rounding here to work around a bug that manifests when a web browser
25
+ // renders the web page with a scale value other than 100%. In that case, even when
26
+ // different identical items would've had equal heights, they'd have slightly different heights
27
+ // to the point of ~0.00001 because of the non-100% scale calculation imprecision.
28
+ //
29
+ // The result would be incorrect detection of same/next row, which would result in
30
+ // returning a huge vertical spacing that is equal to a height of an item,
31
+ // which would then result in a glitchy behavior of `virtual-scroller` when scrolling.
32
+ //
33
+ // To work around that bug, it rounds up to the closest higher `1px`
34
+ // and only then performs the `>=` comparison to detect same/next row.
35
+ //
36
+ if (itemTopOffset + PAGE_ZOOM_ROUNDING_PRECISION_FIX_INCREMENT >= firstShownRowTopOffset + firstShownRowHeight) {
37
+ // Next row is detected. Measure inter-row spacing.
14
38
  // Can't be "negative" with the current `if` condition.
15
39
  return itemTopOffset - (firstShownRowTopOffset + firstShownRowHeight)
16
40
  }
17
- // A row height is the maximum of its item heights.
41
+
42
+ // Not at the next row yet. Re-measure the current row height.
43
+ // The rationale for re-measuring is that there can be items of variable height
44
+ // in a given row, so the row's height is not known until all items in it are measured.
45
+ // A row height is the maximum of its items' heights.
18
46
  firstShownRowHeight = Math.max(firstShownRowHeight, itemHeight)
47
+
48
+ // Proceed to the next item.
19
49
  i++
20
50
  }
21
51
  }
22
- }
52
+ }
53
+
54
+ // There's a rounding precision error when a web browser has a non-100% scale
55
+ // when viewing a page. I dunno what's the source of the imprecision.
56
+ // The thing is: previousRow.top + previousRow.height !== nextRow.top.
57
+ // The two parts of the equation above differ by a magnitude of 0.0001.
58
+ // To fix that, when performing a `>=` comparison, an additional increment is added.
59
+ //
60
+ // This value of the increment is set to `0.9px` for no real reason.
61
+ // It could be `1px` or `0.99px` and it would most likely work the same way.
62
+ // The rationale for the `0.9px` value is that a minimum height of a DOM element
63
+ // is assumed to be `1px` so having a value less than `1px` would theoretically be
64
+ // less buggy in a way that it wouldn't skip the rows that're `1px` high.
65
+ //
66
+ const PAGE_ZOOM_ROUNDING_PRECISION_FIX_INCREMENT = 0.9