@teleporthq/teleport-plugin-next-data-source 0.43.75 → 0.44.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 (136) hide show
  1. package/__tests__/_helpers/pagination-widget-fixture.ts +87 -4
  2. package/__tests__/booking-item-transform.test.ts +120 -0
  3. package/__tests__/browser-row-policy.test.ts +8 -2
  4. package/__tests__/fetchers.test.ts +1 -1
  5. package/__tests__/fixed-list-sort.test.ts +1 -1
  6. package/__tests__/infinite-scroll.test.ts +154 -5
  7. package/__tests__/list-sort-order.test.ts +61 -0
  8. package/__tests__/null-filter-where.test.ts +132 -0
  9. package/__tests__/pg-date-parser.test.ts +73 -0
  10. package/__tests__/plain-list-sort.test.ts +1 -1
  11. package/__tests__/product-price-sort.ts +11 -6
  12. package/__tests__/range-control.test.ts +159 -0
  13. package/__tests__/search-input-marker.test.ts +86 -0
  14. package/__tests__/search-url-sync.test.ts +34 -8
  15. package/__tests__/table-read-route-protected-tables.test.ts +33 -3
  16. package/dist/cjs/count-effect.d.ts +7 -1
  17. package/dist/cjs/count-effect.d.ts.map +1 -1
  18. package/dist/cjs/count-effect.js +15 -5
  19. package/dist/cjs/count-effect.js.map +1 -1
  20. package/dist/cjs/fetchers/pg-client-import.d.ts +12 -0
  21. package/dist/cjs/fetchers/pg-client-import.d.ts.map +1 -0
  22. package/dist/cjs/fetchers/pg-client-import.js +15 -0
  23. package/dist/cjs/fetchers/pg-client-import.js.map +1 -0
  24. package/dist/cjs/fetchers/postgresql.d.ts.map +1 -1
  25. package/dist/cjs/fetchers/postgresql.js +3 -1
  26. package/dist/cjs/fetchers/postgresql.js.map +1 -1
  27. package/dist/cjs/fetchers/raw-query.d.ts.map +1 -1
  28. package/dist/cjs/fetchers/raw-query.js +2 -1
  29. package/dist/cjs/fetchers/raw-query.js.map +1 -1
  30. package/dist/cjs/fetchers/teleport.d.ts.map +1 -1
  31. package/dist/cjs/fetchers/teleport.js +4 -2
  32. package/dist/cjs/fetchers/teleport.js.map +1 -1
  33. package/dist/cjs/infinite-scroll.d.ts +25 -2
  34. package/dist/cjs/infinite-scroll.d.ts.map +1 -1
  35. package/dist/cjs/infinite-scroll.js +144 -33
  36. package/dist/cjs/infinite-scroll.js.map +1 -1
  37. package/dist/cjs/list-sort-order.d.ts +14 -0
  38. package/dist/cjs/list-sort-order.d.ts.map +1 -0
  39. package/dist/cjs/list-sort-order.js +36 -0
  40. package/dist/cjs/list-sort-order.js.map +1 -0
  41. package/dist/cjs/pagination-controls.d.ts +22 -3
  42. package/dist/cjs/pagination-controls.d.ts.map +1 -1
  43. package/dist/cjs/pagination-controls.js +29 -3
  44. package/dist/cjs/pagination-controls.js.map +1 -1
  45. package/dist/cjs/pagination-plugin.d.ts.map +1 -1
  46. package/dist/cjs/pagination-plugin.js +137 -101
  47. package/dist/cjs/pagination-plugin.js.map +1 -1
  48. package/dist/cjs/range-control.d.ts +45 -0
  49. package/dist/cjs/range-control.d.ts.map +1 -0
  50. package/dist/cjs/range-control.js +165 -0
  51. package/dist/cjs/range-control.js.map +1 -0
  52. package/dist/cjs/row-order.d.ts +3 -2
  53. package/dist/cjs/row-order.d.ts.map +1 -1
  54. package/dist/cjs/row-order.js +5 -4
  55. package/dist/cjs/row-order.js.map +1 -1
  56. package/dist/cjs/search-input.d.ts +42 -0
  57. package/dist/cjs/search-input.d.ts.map +1 -0
  58. package/dist/cjs/search-input.js +158 -0
  59. package/dist/cjs/search-input.js.map +1 -0
  60. package/dist/cjs/transformations/booking-item.d.ts +24 -0
  61. package/dist/cjs/transformations/booking-item.d.ts.map +1 -0
  62. package/dist/cjs/transformations/booking-item.js +27 -0
  63. package/dist/cjs/transformations/booking-item.js.map +1 -0
  64. package/dist/cjs/transformations/index.d.ts +4 -2
  65. package/dist/cjs/transformations/index.d.ts.map +1 -1
  66. package/dist/cjs/transformations/index.js +14 -5
  67. package/dist/cjs/transformations/index.js.map +1 -1
  68. package/dist/cjs/tsconfig.tsbuildinfo +1 -1
  69. package/dist/esm/count-effect.d.ts +7 -1
  70. package/dist/esm/count-effect.d.ts.map +1 -1
  71. package/dist/esm/count-effect.js +15 -5
  72. package/dist/esm/count-effect.js.map +1 -1
  73. package/dist/esm/fetchers/pg-client-import.d.ts +12 -0
  74. package/dist/esm/fetchers/pg-client-import.d.ts.map +1 -0
  75. package/dist/esm/fetchers/pg-client-import.js +12 -0
  76. package/dist/esm/fetchers/pg-client-import.js.map +1 -0
  77. package/dist/esm/fetchers/postgresql.d.ts.map +1 -1
  78. package/dist/esm/fetchers/postgresql.js +3 -1
  79. package/dist/esm/fetchers/postgresql.js.map +1 -1
  80. package/dist/esm/fetchers/raw-query.d.ts.map +1 -1
  81. package/dist/esm/fetchers/raw-query.js +2 -1
  82. package/dist/esm/fetchers/raw-query.js.map +1 -1
  83. package/dist/esm/fetchers/teleport.d.ts.map +1 -1
  84. package/dist/esm/fetchers/teleport.js +4 -2
  85. package/dist/esm/fetchers/teleport.js.map +1 -1
  86. package/dist/esm/infinite-scroll.d.ts +25 -2
  87. package/dist/esm/infinite-scroll.d.ts.map +1 -1
  88. package/dist/esm/infinite-scroll.js +142 -32
  89. package/dist/esm/infinite-scroll.js.map +1 -1
  90. package/dist/esm/list-sort-order.d.ts +14 -0
  91. package/dist/esm/list-sort-order.d.ts.map +1 -0
  92. package/dist/esm/list-sort-order.js +32 -0
  93. package/dist/esm/list-sort-order.js.map +1 -0
  94. package/dist/esm/pagination-controls.d.ts +22 -3
  95. package/dist/esm/pagination-controls.d.ts.map +1 -1
  96. package/dist/esm/pagination-controls.js +28 -2
  97. package/dist/esm/pagination-controls.js.map +1 -1
  98. package/dist/esm/pagination-plugin.d.ts.map +1 -1
  99. package/dist/esm/pagination-plugin.js +138 -102
  100. package/dist/esm/pagination-plugin.js.map +1 -1
  101. package/dist/esm/range-control.d.ts +45 -0
  102. package/dist/esm/range-control.d.ts.map +1 -0
  103. package/dist/esm/range-control.js +137 -0
  104. package/dist/esm/range-control.js.map +1 -0
  105. package/dist/esm/row-order.d.ts +3 -2
  106. package/dist/esm/row-order.d.ts.map +1 -1
  107. package/dist/esm/row-order.js +5 -4
  108. package/dist/esm/row-order.js.map +1 -1
  109. package/dist/esm/search-input.d.ts +42 -0
  110. package/dist/esm/search-input.d.ts.map +1 -0
  111. package/dist/esm/search-input.js +129 -0
  112. package/dist/esm/search-input.js.map +1 -0
  113. package/dist/esm/transformations/booking-item.d.ts +24 -0
  114. package/dist/esm/transformations/booking-item.d.ts.map +1 -0
  115. package/dist/esm/transformations/booking-item.js +23 -0
  116. package/dist/esm/transformations/booking-item.js.map +1 -0
  117. package/dist/esm/transformations/index.d.ts +4 -2
  118. package/dist/esm/transformations/index.d.ts.map +1 -1
  119. package/dist/esm/transformations/index.js +14 -5
  120. package/dist/esm/transformations/index.js.map +1 -1
  121. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  122. package/package.json +5 -5
  123. package/src/count-effect.ts +31 -8
  124. package/src/fetchers/pg-client-import.ts +16 -0
  125. package/src/fetchers/postgresql.ts +15 -9
  126. package/src/fetchers/raw-query.ts +2 -1
  127. package/src/fetchers/teleport.ts +11 -8
  128. package/src/infinite-scroll.ts +240 -79
  129. package/src/list-sort-order.ts +34 -0
  130. package/src/pagination-controls.ts +26 -3
  131. package/src/pagination-plugin.ts +163 -135
  132. package/src/range-control.ts +207 -0
  133. package/src/row-order.ts +5 -4
  134. package/src/search-input.ts +190 -0
  135. package/src/transformations/booking-item.ts +71 -0
  136. package/src/transformations/index.ts +25 -2
@@ -15,9 +15,27 @@ export declare const PAGINATION_CONTROL_ATTR = "data-tq-pagination-control";
15
15
  * `'pages'` is the container the page-number buttons are repeated into and
16
16
  * `'page'` the single template button inside it. `'ellipsis'` and `'sentinel'`
17
17
  * are reserved for an authored gap marker / scroll sentinel; until a builder
18
- * emits them both runtimes fall back to generating their own.
18
+ * emits them both runtimes fall back to generating their own. `'range'` is a
19
+ * TEXT element ("Showing 1–8 of 12") both runtimes fill with the live row
20
+ * range — see `range-control.ts`.
19
21
  */
20
- export type PaginationControlKind = 'first' | 'previous' | 'pages' | 'page' | 'ellipsis' | 'next' | 'last' | 'load-more' | 'sentinel';
22
+ export type PaginationControlKind = 'first' | 'previous' | 'pages' | 'page' | 'ellipsis' | 'next' | 'last' | 'load-more' | 'sentinel' | 'range';
23
+ /**
24
+ * Which mapper a `range` control belongs to, when it does not sit inside that
25
+ * mapper's pagination container: the array mapper's editor node id, which the
26
+ * UIDL carries as `nodeId` on the `cms-list-repeater`. A template's footer
27
+ * ("Showing 1–8 of 12") is laid out by the author, not inside a widget, so the
28
+ * container-ownership rule the buttons use cannot reach it.
29
+ *
30
+ * ⛔ Both attribute names must stay identical to the editor's
31
+ * (`array-mapper-pagination-settings.ts`) and the canvas renderer's
32
+ * (`array-mapper-pagination.ts`) copies.
33
+ */
34
+ export declare const PAGINATION_FOR_ATTR = "data-tq-pagination-for";
35
+ /** The words of a `range` control, with `{from}`, `{to}` and `{total}` placeholders. */
36
+ export declare const RANGE_TEMPLATE_ATTR = "data-tq-range-template";
37
+ /** What a `range` control reads when it carries no template. */
38
+ export declare const DEFAULT_RANGE_TEMPLATE = "{from}\u2013{to} of {total}";
21
39
  export declare function readJSXAttributeString(node: any, attrName: string): string;
22
40
  /**
23
41
  * Depth-first search for one authored pagination control.
@@ -49,7 +67,8 @@ export declare function removeJSXAttribute(node: any, attrName: string): void;
49
67
  *
50
68
  * Children carrying NO marker are always kept: they are the author's own
51
69
  * additions (a page counter, a spacer) and the generator has no business
52
- * deciding whether they belong.
70
+ * deciding whether they belong. A `range` text is kept in every mode too: the
71
+ * row range is meaningful whether the list pages or appends.
53
72
  */
54
73
  export declare function dropInactivePaginationControls(paginationNode: any, activeKinds: PaginationControlKind[]): void;
55
74
  //# sourceMappingURL=pagination-controls.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pagination-controls.d.ts","sourceRoot":"","sources":["../../src/pagination-controls.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AAErC;;;;;;;;;;GAUG;AACH,eAAO,MAAM,uBAAuB,+BAA+B,CAAA;AAEnE;;;;;GAKG;AACH,MAAM,MAAM,qBAAqB,GAC7B,OAAO,GACP,UAAU,GACV,OAAO,GACP,MAAM,GACN,UAAU,GACV,MAAM,GACN,MAAM,GACN,WAAW,GACX,UAAU,CAAA;AAOd,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAK1E;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,GAAG,EACT,IAAI,EAAE,qBAAqB,EAC3B,eAAe,CAAC,EAAE,MAAM,GACvB,GAAG,CA2BL;AAED,6GAA6G;AAC7G,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,qBAAqB,GAAG,GAAG,EAAE,CAkBvF;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI,CAWtD;AAED,wEAAwE;AACxE,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,GAAG,EACT,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,KAAK,CAAC,UAAU,GAC3B,IAAI,CAON;AAED,0CAA0C;AAC1C,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAIpE;AAED;;;;;;;;GAQG;AACH,wBAAgB,8BAA8B,CAC5C,cAAc,EAAE,GAAG,EACnB,WAAW,EAAE,qBAAqB,EAAE,GACnC,IAAI,CAgBN"}
1
+ {"version":3,"file":"pagination-controls.d.ts","sourceRoot":"","sources":["../../src/pagination-controls.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AAErC;;;;;;;;;;GAUG;AACH,eAAO,MAAM,uBAAuB,+BAA+B,CAAA;AAEnE;;;;;;;GAOG;AACH,MAAM,MAAM,qBAAqB,GAC7B,OAAO,GACP,UAAU,GACV,OAAO,GACP,MAAM,GACN,UAAU,GACV,MAAM,GACN,MAAM,GACN,WAAW,GACX,UAAU,GACV,OAAO,CAAA;AAEX;;;;;;;;;;GAUG;AACH,eAAO,MAAM,mBAAmB,2BAA2B,CAAA;AAE3D,wFAAwF;AACxF,eAAO,MAAM,mBAAmB,2BAA2B,CAAA;AAE3D,gEAAgE;AAChE,eAAO,MAAM,sBAAsB,gCAA2B,CAAA;AAO9D,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAK1E;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,GAAG,EACT,IAAI,EAAE,qBAAqB,EAC3B,eAAe,CAAC,EAAE,MAAM,GACvB,GAAG,CA2BL;AAED,6GAA6G;AAC7G,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,qBAAqB,GAAG,GAAG,EAAE,CAkBvF;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI,CAWtD;AAED,wEAAwE;AACxE,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,GAAG,EACT,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,KAAK,CAAC,UAAU,GAC3B,IAAI,CAON;AAED,0CAA0C;AAC1C,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAIpE;AAED;;;;;;;;;GASG;AACH,wBAAgB,8BAA8B,CAC5C,cAAc,EAAE,GAAG,EACnB,WAAW,EAAE,qBAAqB,EAAE,GACnC,IAAI,CAgBN"}
@@ -1,3 +1,12 @@
1
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
2
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
3
+ if (ar || !(i in from)) {
4
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
5
+ ar[i] = from[i];
6
+ }
7
+ }
8
+ return to.concat(ar || Array.prototype.slice.call(from));
9
+ };
1
10
  import * as types from '@babel/types';
2
11
  /**
3
12
  * How the generator recognises the pagination controls the builder authored.
@@ -11,6 +20,22 @@ import * as types from '@babel/types';
11
20
  * pagination-scroll runtime already identifies its own nodes.
12
21
  */
13
22
  export var PAGINATION_CONTROL_ATTR = 'data-tq-pagination-control';
23
+ /**
24
+ * Which mapper a `range` control belongs to, when it does not sit inside that
25
+ * mapper's pagination container: the array mapper's editor node id, which the
26
+ * UIDL carries as `nodeId` on the `cms-list-repeater`. A template's footer
27
+ * ("Showing 1–8 of 12") is laid out by the author, not inside a widget, so the
28
+ * container-ownership rule the buttons use cannot reach it.
29
+ *
30
+ * ⛔ Both attribute names must stay identical to the editor's
31
+ * (`array-mapper-pagination-settings.ts`) and the canvas renderer's
32
+ * (`array-mapper-pagination.ts`) copies.
33
+ */
34
+ export var PAGINATION_FOR_ATTR = 'data-tq-pagination-for';
35
+ /** The words of a `range` control, with `{from}`, `{to}` and `{total}` placeholders. */
36
+ export var RANGE_TEMPLATE_ATTR = 'data-tq-range-template';
37
+ /** What a `range` control reads when it carries no template. */
38
+ export var DEFAULT_RANGE_TEMPLATE = '{from}–{to} of {total}';
14
39
  // tslint:disable:no-any
15
40
  // Reads a JSX attribute's literal string value, covering both the plain
16
41
  // `attr="value"` form and the `attr={'value'}` container the UIDL printer emits
@@ -104,10 +129,11 @@ export function removeJSXAttribute(node, attrName) {
104
129
  *
105
130
  * Children carrying NO marker are always kept: they are the author's own
106
131
  * additions (a page counter, a spacer) and the generator has no business
107
- * deciding whether they belong.
132
+ * deciding whether they belong. A `range` text is kept in every mode too: the
133
+ * row range is meaningful whether the list pages or appends.
108
134
  */
109
135
  export function dropInactivePaginationControls(paginationNode, activeKinds) {
110
- var active = new Set(activeKinds);
136
+ var active = new Set(__spreadArray(__spreadArray([], activeKinds, true), ['range'], false));
111
137
  var prune = function (node) {
112
138
  if (!node || !Array.isArray(node.children)) {
113
139
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"pagination-controls.js","sourceRoot":"","sources":["../../src/pagination-controls.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pagination-controls.js","sourceRoot":"","sources":["../../src/pagination-controls.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"pagination-plugin.d.ts","sourceRoot":"","sources":["../../src/pagination-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,sBAAsB,EAGvB,MAAM,4BAA4B,CAAA;AAooCnC,eAAO,MAAM,qCAAqC,EAAE,sBAAsB,CAAC,EAAE,CAq1B5E,CAAA"}
1
+ {"version":3,"file":"pagination-plugin.d.ts","sourceRoot":"","sources":["../../src/pagination-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,sBAAsB,EAGvB,MAAM,4BAA4B,CAAA;AA6pCnC,eAAO,MAAM,qCAAqC,EAAE,sBAAsB,CAAC,EAAE,CAg3B5E,CAAA"}
@@ -58,11 +58,13 @@ import { resolveRepeaterPerPage } from './repeater-page-size';
58
58
  import { applyLoadingStateToDataProvider, buildLoadingStateDeclarations, getLoadingStateVars, } from './loading-state';
59
59
  import { mergeServerCacheOptions, resolveCacheFromRepeaterContent } from './cache/config';
60
60
  import { buildCacheHydrationEffect, buildCacheStoreThen, buildCachedFetchBody, buildCachedParamsDeclarations, registerCacheClientImports, } from './cache/ast';
61
- import { convertControlToButton, dropInactivePaginationControls, findPaginationControl, setJSXExpressionAttribute, } from './pagination-controls';
61
+ import { convertControlToButton, dropInactivePaginationControls, findAllPaginationControls, findPaginationControl, PAGINATION_FOR_ATTR, readJSXAttributeString, setJSXExpressionAttribute, } from './pagination-controls';
62
+ import { findRangeControls, wireRangeControl } from './range-control';
63
+ import { findAllSearchInputsInJSX, pairSearchInputs, wireSearchInput } from './search-input';
62
64
  import { buildCountFetchEffect, buildCountSeqDeclaration } from './count-effect';
63
65
  import { findAllSearchClearButtonsInJSX, findSiblingSearchInput, wireSearchClearButton, } from './search-clear';
64
66
  import { buildPageTokensDeclaration, wireNumberedPagination, } from './numbered-pagination';
65
- import { buildAccumulatingResponseHandler, buildInfiniteScrollDeclarations, buildSentinelElement, buildSentinelObserverEffect, getInfiniteScrollVars, } from './infinite-scroll';
67
+ import { buildAccumulatingRequestMark, buildAccumulatingResponseHandler, buildInfiniteScrollDeclarations, buildSentinelElement, buildSentinelObserverEffect, getInfiniteScrollVars, } from './infinite-scroll';
66
68
  import { buildFilterSortPageResetEffect, buildPageResetRefDeclaration, hasNoPageResetDeps, } from './page-reset';
67
69
  import { buildPageUrlRefDeclaration, buildPageUrlSyncEffect } from './page-url-sync';
68
70
  import { isLocalizedProject } from './content-localization';
@@ -407,6 +409,7 @@ function buildStateRegistry(uidlNode) {
407
409
  index: index++,
408
410
  dataSourceIdentifier: parentDataSource.identifier,
409
411
  arrayMapperRenderProp: arrayMapperRenderProp,
412
+ nodeId: typeof content.nodeId === 'string' ? content.nodeId : undefined,
410
413
  resourceDefinition: {
411
414
  dataSourceId: parentDataSource.resourceDef.dataSourceId || '',
412
415
  tableName: parentDataSource.resourceDef.tableName || '',
@@ -502,6 +505,8 @@ function getStateVarsForUsage(usage) {
502
505
  setPageStateVar: "setDs_".concat(idx, "_page"),
503
506
  maxPagesStateVar: "ds_".concat(idx, "_maxPages"),
504
507
  setMaxPagesStateVar: "setDs_".concat(idx, "_maxPages"),
508
+ totalStateVar: "ds_".concat(idx, "_total"),
509
+ setTotalStateVar: "setDs_".concat(idx, "_total"),
505
510
  searchQueryVar: "ds_".concat(idx, "_searchQuery"),
506
511
  setSearchQueryVar: "setDs_".concat(idx, "_searchQuery"),
507
512
  debouncedSearchQueryVar: "ds_".concat(idx, "_debouncedQuery"),
@@ -579,19 +584,27 @@ function pushSearchUrlSyncEffects(effectStatements, usage, vars) {
579
584
  effectStatements.push(URLSearchParamSync.buildUrlWriteBackEffect(usage.searchUrlParamKey, buildDebouncedValueExpr(), buildDebouncedValueExpr(), undefined, adoptedRefVar));
580
585
  // read-back: `?<searchUrlParamKey>=` → the input AND the applied query at once
581
586
  // (`ds_N_adoptUrlSearch`), so an address is not a typed change: it skips the
582
- // debounce and keeps the page — `?searchKeyword=x&page=3` lands on page 3.
587
+ // debounce and keeps a page the address carries — `?searchKeyword=x&page=3`
588
+ // lands on page 3.
583
589
  effectStatements.push(URLSearchParamSync.buildUrlReadBackEffect(usage.searchUrlParamKey, adopterVar, undefined, adoptedRefVar));
584
590
  }
585
591
  // `const ds_N_adoptUrlSearch = (update) => { … }`: the setter the search's URL
586
592
  // read-back calls with its `(prev) => next` updater. It moves the input and the
587
- // applied (debounced) query together; the combined paginated state keeps its
588
- // page, which a typed change resets to 1 in the debounce effect.
593
+ // applied (debounced) query together. A list whose page is in the address
594
+ // keeps its page — the page sync sets it from the same address. Any other
595
+ // list starts the new query on page 1, as a typed change does in the debounce
596
+ // effect: an appending list has usually advanced past page 1 by the time the
597
+ // router is ready, and the query's first answer would otherwise be its page 2
598
+ // — empty for a query only a few rows match.
589
599
  function buildUrlSearchAdopter(adopterVar, usage, vars) {
590
600
  var update = types.identifier('update');
601
+ var pageReset = usageHasPageUrlSync(usage)
602
+ ? []
603
+ : [types.objectProperty(types.identifier('page'), types.numericLiteral(1))];
591
604
  var applyToDebounced = usage.category === 'paginated+search'
592
605
  ? // setDs_N_state((state) => {
593
606
  // const next = update(state.debouncedQuery)
594
- // return next === state.debouncedQuery ? state : { ...state, debouncedQuery: next }
607
+ // return next === state.debouncedQuery ? state : { ...state, page: 1, debouncedQuery: next }
595
608
  // })
596
609
  types.callExpression(types.identifier(vars.setCombinedStateVar), [
597
610
  types.arrowFunctionExpression([types.identifier('state')], types.blockStatement([
@@ -600,10 +613,11 @@ function buildUrlSearchAdopter(adopterVar, usage, vars) {
600
613
  types.memberExpression(types.identifier('state'), types.identifier('debouncedQuery')),
601
614
  ])),
602
615
  ]),
603
- types.returnStatement(types.conditionalExpression(types.binaryExpression('===', types.identifier('next'), types.memberExpression(types.identifier('state'), types.identifier('debouncedQuery'))), types.identifier('state'), types.objectExpression([
604
- types.spreadElement(types.identifier('state')),
616
+ types.returnStatement(types.conditionalExpression(types.binaryExpression('===', types.identifier('next'), types.memberExpression(types.identifier('state'), types.identifier('debouncedQuery'))), types.identifier('state'), types.objectExpression(__spreadArray(__spreadArray([
617
+ types.spreadElement(types.identifier('state'))
618
+ ], pageReset, true), [
605
619
  types.objectProperty(types.identifier('debouncedQuery'), types.identifier('next')),
606
- ]))),
620
+ ], false)))),
607
621
  ])),
608
622
  ])
609
623
  : types.callExpression(types.identifier(vars.setDebouncedSearchQueryVar), [update]);
@@ -766,7 +780,7 @@ function pushFilterSortPageResetEffect(stateDeclarations, effectStatements, usag
766
780
  // ==================== MAIN PLUGIN ====================
767
781
  export var createNextArrayMapperPaginationPlugin = function () {
768
782
  var paginationPlugin = function (structure) { return __awaiter(void 0, void 0, void 0, function () {
769
- var uidl, chunks, dependencies, options, componentChunk, variableDeclaration, declarator, arrowFunction, blockStatement, registry, getStaticPropsChunk, isPage, localized, stateDeclarations, effectStatements, needsUseRouter, returnIndex, insertIndex, dataProviders, dataProvidersWithRepeaters, usageIndexByDataSourceId, loadingStateDeclarations, usagesWithLoadingState, usageByProviderNode, cacheDeclarations, sharedOptions, cachedScopes, dataProvidersWithoutRepeaters, searchInputs, searchEnabledUsages, usageBySearchInput;
783
+ var uidl, chunks, dependencies, options, componentChunk, variableDeclaration, declarator, arrowFunction, blockStatement, rangeControls, hasRangeControl, registry, getStaticPropsChunk, isPage, localized, stateDeclarations, effectStatements, needsUseRouter, returnIndex, insertIndex, dataProviders, dataProvidersWithRepeaters, usageIndexByDataSourceId, loadingStateDeclarations, usagesWithLoadingState, usageByProviderNode, cacheDeclarations, sharedOptions, cachedScopes, dataProvidersWithoutRepeaters, searchInputs, usageBySearchInput, _i, searchInputs_1, input, usage;
770
784
  var _a, _b;
771
785
  return __generator(this, function (_c) {
772
786
  uidl = structure.uidl, chunks = structure.chunks, dependencies = structure.dependencies, options = structure.options;
@@ -790,6 +804,8 @@ export var createNextArrayMapperPaginationPlugin = function () {
790
804
  return [2 /*return*/, structure];
791
805
  }
792
806
  blockStatement = arrowFunction.body;
807
+ rangeControls = findRangeControls(blockStatement);
808
+ hasRangeControl = rangeControls.length > 0;
793
809
  registry = buildStateRegistry(uidl.node);
794
810
  if (registry.usages.length === 0) {
795
811
  return [2 /*return*/, structure];
@@ -958,11 +974,15 @@ export var createNextArrayMapperPaginationPlugin = function () {
958
974
  pushPropIdsAsDeps(countEffectDeps, countEffectSeen, usage.filterPropIds);
959
975
  // Same goes for URL-driven filters (already documented above).
960
976
  pushUrlSearchParamMemoDeps(countEffectDeps, usage);
977
+ if (hasRangeControl) {
978
+ stateDeclarations.push(buildTotalDeclaration(vars));
979
+ }
961
980
  stateDeclarations.push(buildCountSeqDeclaration(vars.countSeqRefVar));
962
981
  effectStatements.push(buildCountFetchEffect({
963
982
  fileName: fileName,
964
983
  perPage: usage.perPage,
965
984
  setMaxPagesVar: vars.setMaxPagesStateVar,
985
+ setTotalVar: hasRangeControl ? vars.setTotalStateVar : undefined,
966
986
  urlParams: urlParams,
967
987
  deps: countEffectDeps,
968
988
  countSeqRefVar: vars.countSeqRefVar,
@@ -1004,7 +1024,9 @@ export var createNextArrayMapperPaginationPlugin = function () {
1004
1024
  // "Next" button, but not to label a numbered strip or to know when an
1005
1025
  // infinite list has reached its end, so those two modes fetch a live
1006
1026
  // count as well.
1007
- var needsLiveCount = !isPage || usage.paginationMode === 'numbered' || usage.infiniteScroll;
1027
+ // A range text needs the live count too: the build-time count only
1028
+ // ever became a page count, never the total it shows.
1029
+ var needsLiveCount = !isPage || usage.paginationMode === 'numbered' || usage.infiniteScroll || hasRangeControl;
1008
1030
  if (needsLiveCount) {
1009
1031
  var fileName = generateSafeFileName(usage.resourceDefinition.dataSourceType, usage.resourceDefinition.tableName, usage.resourceDefinition.dataSourceId);
1010
1032
  // ⛔ This list has no search input, so no `query` param — but it may
@@ -1026,11 +1048,15 @@ export var createNextArrayMapperPaginationPlugin = function () {
1026
1048
  pushStateIdsAsDeps(countDeps, countDepsSeen, usage.filterStateIds);
1027
1049
  pushPropIdsAsDeps(countDeps, countDepsSeen, usage.filterPropIds);
1028
1050
  pushUrlSearchParamMemoDeps(countDeps, usage);
1051
+ if (hasRangeControl) {
1052
+ stateDeclarations.push(buildTotalDeclaration(vars));
1053
+ }
1029
1054
  stateDeclarations.push(buildCountSeqDeclaration(vars.countSeqRefVar));
1030
1055
  effectStatements.push(buildCountFetchEffect({
1031
1056
  fileName: fileName,
1032
1057
  perPage: usage.perPage,
1033
1058
  setMaxPagesVar: vars.setMaxPagesStateVar,
1059
+ setTotalVar: hasRangeControl ? vars.setTotalStateVar : undefined,
1034
1060
  urlParams: countUrlParams,
1035
1061
  deps: countDeps,
1036
1062
  countSeqRefVar: vars.countSeqRefVar,
@@ -1161,7 +1187,9 @@ export var createNextArrayMapperPaginationPlugin = function () {
1161
1187
  // An auto-loading list needs something at the end of the rows for its
1162
1188
  // IntersectionObserver to watch.
1163
1189
  if (usage.infiniteScroll && usage.paginated && !usage.infiniteScrollLoadMore) {
1164
- insertSentinelAfterProvider(blockStatement, dp, buildSentinelElement(getInfiniteScrollVars(usage.index)));
1190
+ insertSentinelAfterProvider(blockStatement, dp, function (parentTag) {
1191
+ return buildSentinelElement(getInfiniteScrollVars(usage.index), parentTag);
1192
+ });
1165
1193
  }
1166
1194
  // Create API route for all categories (including 'plain' for components)
1167
1195
  ensureAPIRouteExists(options.extractedResources, usage, options.dataSources, buildProductTransformOptions(options));
@@ -1203,17 +1231,14 @@ export var createNextArrayMapperPaginationPlugin = function () {
1203
1231
  stabilizeDataProviderWithoutRepeater(dp);
1204
1232
  });
1205
1233
  searchInputs = findAllSearchInputsInJSX(blockStatement);
1206
- searchEnabledUsages = registry.usages.filter(function (u) { return u.searchEnabled; });
1207
- usageBySearchInput = new Map();
1208
- searchInputs.forEach(function (input, idx) {
1209
- if (idx >= searchEnabledUsages.length) {
1210
- return;
1234
+ usageBySearchInput = pairSearchInputs(searchInputs, registry.usages);
1235
+ for (_i = 0, searchInputs_1 = searchInputs; _i < searchInputs_1.length; _i++) {
1236
+ input = searchInputs_1[_i];
1237
+ usage = usageBySearchInput.get(input.node);
1238
+ if (usage) {
1239
+ wireSearchInput(input, getStateVarsForUsage(usage));
1211
1240
  }
1212
- var usage = searchEnabledUsages[idx];
1213
- var vars = getStateVarsForUsage(usage);
1214
- wireSearchInput(input.node, vars);
1215
- usageBySearchInput.set(input.node, usage);
1216
- });
1241
+ }
1217
1242
  // STEP 4.5: Wire the clear buttons, each to the input it shares a parent with.
1218
1243
  findAllSearchClearButtonsInJSX(blockStatement).forEach(function (button) {
1219
1244
  var input = findSiblingSearchInput(button, searchInputs.map(function (entry) { return entry.node; }));
@@ -1240,6 +1265,24 @@ export var createNextArrayMapperPaginationPlugin = function () {
1240
1265
  }
1241
1266
  wirePaginationWidget(node, usage, getStateVarsForUsage(usage), usagesWithLoadingState.has(usage.index));
1242
1267
  });
1268
+ // STEP 5b: Wire the range texts that name their mapper.
1269
+ //
1270
+ // A `range` control carrying `data-tq-pagination-for` belongs to the mapper
1271
+ // whose editor node id it names, wherever it sits — a template's footer or
1272
+ // toolbar is laid out by the author, not inside a pagination container, so
1273
+ // the container-ownership rule above cannot reach it. One without the
1274
+ // attribute was wired by its container in STEP 5; one naming a mapper this
1275
+ // component does not render stays as drawn.
1276
+ rangeControls.forEach(function (control) {
1277
+ var ownerNodeId = readJSXAttributeString(control, PAGINATION_FOR_ATTR);
1278
+ if (!ownerNodeId) {
1279
+ return;
1280
+ }
1281
+ var owner = registry.usages.find(function (usage) { return usage.nodeId === ownerNodeId; });
1282
+ if (owner) {
1283
+ wireRangeControlFor(control, owner, getStateVarsForUsage(owner));
1284
+ }
1285
+ });
1243
1286
  // STEP 6: Update getStaticProps if this is a page
1244
1287
  if (isPage) {
1245
1288
  updateGetStaticProps(chunks, registry, dependencies, (_b = uidl.outputOptions) === null || _b === void 0 ? void 0 : _b.folderPath, localized);
@@ -1257,39 +1300,59 @@ export var createNextArrayMapperPaginationPlugin = function () {
1257
1300
  * It has to be a sibling: the provider's own child is a render-prop function,
1258
1301
  * and anything placed inside it would be re-created on every fetch — the
1259
1302
  * observer would then be watching an element that is no longer in the document.
1303
+ * The sentinel is built for the element it lands in (`buildSentinelElement`):
1304
+ * a fragment is transparent, a component's children may go anywhere.
1260
1305
  *
1261
1306
  * Returns false when the provider has no element parent to splice into (a
1262
1307
  * provider returned directly from the component), leaving the list on its
1263
1308
  * count-driven `hasMore` rather than injecting a stray node.
1264
1309
  */
1265
- function insertSentinelAfterProvider(blockStatement, provider, sentinel) {
1310
+ function insertSentinelAfterProvider(blockStatement, provider, buildSentinel) {
1266
1311
  var inserted = false;
1267
- var traverse = function (node) {
1312
+ var elementTagOf = function (node, enclosing) {
1313
+ var _a;
1314
+ if ((node === null || node === void 0 ? void 0 : node.type) === 'JSXFragment') {
1315
+ return enclosing;
1316
+ }
1317
+ if ((node === null || node === void 0 ? void 0 : node.type) !== 'JSXElement') {
1318
+ return enclosing;
1319
+ }
1320
+ var name = (_a = node.openingElement) === null || _a === void 0 ? void 0 : _a.name;
1321
+ if ((name === null || name === void 0 ? void 0 : name.type) !== 'JSXIdentifier') {
1322
+ return null;
1323
+ }
1324
+ if (name.name === 'Fragment') {
1325
+ return enclosing;
1326
+ }
1327
+ return /^[a-z]/.test(name.name) ? name.name : null;
1328
+ };
1329
+ var traverse = function (node, enclosing) {
1268
1330
  if (!node || inserted) {
1269
1331
  return;
1270
1332
  }
1333
+ var tag = elementTagOf(node, enclosing);
1271
1334
  if (Array.isArray(node.children)) {
1272
1335
  var at = node.children.indexOf(provider);
1273
1336
  if (at !== -1) {
1274
- node.children.splice(at + 1, 0, sentinel);
1337
+ node.children.splice(at + 1, 0, buildSentinel(tag));
1275
1338
  inserted = true;
1276
1339
  return;
1277
1340
  }
1278
- node.children.forEach(traverse);
1341
+ node.children.forEach(function (child) { return traverse(child, tag); });
1279
1342
  }
1280
1343
  if (node.body) {
1281
1344
  if (Array.isArray(node.body)) {
1282
- node.body.forEach(traverse);
1345
+ node.body.forEach(function (child) { return traverse(child, tag); });
1283
1346
  }
1284
1347
  else {
1285
- traverse(node.body);
1348
+ traverse(node.body, tag);
1286
1349
  }
1287
1350
  }
1288
1351
  if (node.consequent) {
1289
- traverse(node.consequent);
1352
+ traverse(node.consequent, tag);
1290
1353
  }
1291
1354
  if (node.alternate) {
1292
- traverse(node.alternate);
1355
+ traverse(node.alternate, tag);
1293
1356
  }
1294
1357
  // `{activeTabIndex === 0 && (<div>…<DataProvider/>…</div>)}` — a tab
1295
1358
  // panel, a gated section: the provider sits on the RIGHT of a logical
@@ -1297,22 +1360,22 @@ function insertSentinelAfterProvider(blockStatement, provider, sentinel) {
1297
1360
  // an argument. Left unvisited, the products list under the first tab of
1298
1361
  // a shop was never paginated or seeded, and rendered nothing.
1299
1362
  if (node.left) {
1300
- traverse(node.left);
1363
+ traverse(node.left, tag);
1301
1364
  }
1302
1365
  if (node.right) {
1303
- traverse(node.right);
1366
+ traverse(node.right, tag);
1304
1367
  }
1305
1368
  if (node.test) {
1306
- traverse(node.test);
1369
+ traverse(node.test, tag);
1307
1370
  }
1308
1371
  if (node.expression) {
1309
- traverse(node.expression);
1372
+ traverse(node.expression, tag);
1310
1373
  }
1311
1374
  if (node.argument) {
1312
- traverse(node.argument);
1375
+ traverse(node.argument, tag);
1313
1376
  }
1314
1377
  };
1315
- traverse(blockStatement);
1378
+ traverse(blockStatement, null);
1316
1379
  return inserted;
1317
1380
  }
1318
1381
  function findAllDataProvidersInJSX(blockStatement) {
@@ -1407,61 +1470,6 @@ function findArrayMapperRenderPropInDataProvider(dataProvider) {
1407
1470
  }
1408
1471
  return renderItemAttr.value.expression.params[0].name;
1409
1472
  }
1410
- function findAllSearchInputsInJSX(blockStatement) {
1411
- var results = [];
1412
- var traverse = function (node) {
1413
- var _a, _b, _c, _d, _e, _f;
1414
- if (!node) {
1415
- return;
1416
- }
1417
- if (node.type === 'JSXElement' && ((_b = (_a = node.openingElement) === null || _a === void 0 ? void 0 : _a.name) === null || _b === void 0 ? void 0 : _b.name) === 'input') {
1418
- var classAttr = (_c = node.openingElement.attributes) === null || _c === void 0 ? void 0 : _c.find(function (attr) { return attr.type === 'JSXAttribute' && attr.name.name === 'className'; });
1419
- var className = ((_d = classAttr === null || classAttr === void 0 ? void 0 : classAttr.value) === null || _d === void 0 ? void 0 : _d.value) || ((_f = (_e = classAttr === null || classAttr === void 0 ? void 0 : classAttr.value) === null || _e === void 0 ? void 0 : _e.expression) === null || _f === void 0 ? void 0 : _f.value) || '';
1420
- if (className.includes('search-input')) {
1421
- results.push({ node: node, className: className });
1422
- }
1423
- }
1424
- if (node.children && Array.isArray(node.children)) {
1425
- node.children.forEach(function (c) { return traverse(c); });
1426
- }
1427
- if (node.body) {
1428
- if (Array.isArray(node.body)) {
1429
- node.body.forEach(function (s) { return traverse(s); });
1430
- }
1431
- else {
1432
- traverse(node.body);
1433
- }
1434
- }
1435
- if (node.consequent) {
1436
- traverse(node.consequent);
1437
- }
1438
- if (node.alternate) {
1439
- traverse(node.alternate);
1440
- }
1441
- // `{activeTabIndex === 0 && (<div>…<DataProvider/>…</div>)}` — a tab
1442
- // panel, a gated section: the provider sits on the RIGHT of a logical
1443
- // expression (or in a ternary's `test`), which is not a child, a body or
1444
- // an argument. Left unvisited, the products list under the first tab of
1445
- // a shop was never paginated or seeded, and rendered nothing.
1446
- if (node.left) {
1447
- traverse(node.left);
1448
- }
1449
- if (node.right) {
1450
- traverse(node.right);
1451
- }
1452
- if (node.test) {
1453
- traverse(node.test);
1454
- }
1455
- if (node.expression) {
1456
- traverse(node.expression);
1457
- }
1458
- if (node.argument) {
1459
- traverse(node.argument);
1460
- }
1461
- };
1462
- traverse(blockStatement);
1463
- return results;
1464
- }
1465
1473
  /**
1466
1474
  * Every pagination widget in the JSX, paired with the mapper it belongs to.
1467
1475
  *
@@ -1906,21 +1914,18 @@ accumulate) {
1906
1914
  ? buildCacheStoreThen(cache)
1907
1915
  : uncachedTail;
1908
1916
  var networkChain = types.callExpression(types.memberExpression(parsedJson, types.identifier('then')), [responseTail]);
1917
+ // An appending list records the request it now stands on before making it
1918
+ // (see `buildAccumulatingRequestMark`).
1909
1919
  var arrow = cache
1910
1920
  ? types.arrowFunctionExpression([types.identifier('params')], buildCachedFetchBody(networkChain, cache))
1911
- : types.arrowFunctionExpression([types.identifier('params')], networkChain);
1921
+ : accumulate
1922
+ ? types.arrowFunctionExpression([types.identifier('params')], types.blockStatement([
1923
+ buildAccumulatingRequestMark(getInfiniteScrollVars(accumulate.usage.index)),
1924
+ types.returnStatement(networkChain),
1925
+ ]))
1926
+ : types.arrowFunctionExpression([types.identifier('params')], networkChain);
1912
1927
  return types.jsxAttribute(types.jsxIdentifier('fetchData'), types.jsxExpressionContainer(types.callExpression(types.identifier('useCallback'), [arrow, types.arrayExpression([])])));
1913
1928
  }
1914
- function wireSearchInput(inputNode, vars) {
1915
- // Remove existing onChange and value
1916
- inputNode.openingElement.attributes = inputNode.openingElement.attributes.filter(function (attr) { var _a; return !['onChange', 'value'].includes((_a = attr.name) === null || _a === void 0 ? void 0 : _a.name); });
1917
- // Add onChange
1918
- inputNode.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('onChange'), types.jsxExpressionContainer(types.arrowFunctionExpression([types.identifier('e')], types.callExpression(types.identifier(vars.setSearchQueryVar), [
1919
- types.memberExpression(types.memberExpression(types.identifier('e'), types.identifier('target')), types.identifier('value')),
1920
- ])))));
1921
- // Add value
1922
- inputNode.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('value'), types.jsxExpressionContainer(types.identifier(vars.searchQueryVar))));
1923
- }
1924
1929
  /**
1925
1930
  * The `fetchData` attribute for one paginated usage.
1926
1931
  *
@@ -1936,6 +1941,32 @@ function buildFetchDataForUsage(fileName, usage) {
1936
1941
  }
1937
1942
  return createFetchDataAttribute(fileName, ((_a = usage.cache) === null || _a === void 0 ? void 0 : _a.client) ? usage.cache : undefined);
1938
1943
  }
1944
+ /** `const [ds_N_total, setDs_N_total] = useState(null)` — declared only beside a range control. */
1945
+ function buildTotalDeclaration(vars) {
1946
+ return types.variableDeclaration('const', [
1947
+ types.variableDeclarator(types.arrayPattern([
1948
+ types.identifier(vars.totalStateVar),
1949
+ types.identifier(vars.setTotalStateVar),
1950
+ ]), types.callExpression(types.identifier('useState'), [types.nullLiteral()])),
1951
+ ]);
1952
+ }
1953
+ /**
1954
+ * Fills one `range` text with the live row range of `usage` (see
1955
+ * `range-control.ts`). A mapper that does not page has no count to show, so
1956
+ * its range text is left as drawn.
1957
+ */
1958
+ function wireRangeControlFor(control, usage, vars) {
1959
+ if (!usage.paginated) {
1960
+ return;
1961
+ }
1962
+ var currentPageExpr = getPageAccessors(usage, vars).currentPageExpr;
1963
+ wireRangeControl(control, {
1964
+ totalVar: vars.totalStateVar,
1965
+ currentPageExpr: currentPageExpr(),
1966
+ perPage: usage.perPage,
1967
+ infiniteScroll: usage.infiniteScroll,
1968
+ });
1969
+ }
1939
1970
  /**
1940
1971
  * Wires the authored Load More button of an appending list.
1941
1972
  *
@@ -1975,6 +2006,11 @@ function wireLoadMoreButton(paginationNode, usage, vars, hasLoadingState) {
1975
2006
  * buttons beside its Load More.
1976
2007
  */
1977
2008
  function wirePaginationWidget(paginationNode, usage, vars, hasLoadingState) {
2009
+ // A range text inside the container takes the container's owner, like the
2010
+ // buttons beside it; one naming its own mapper is wired in STEP 5b instead.
2011
+ findAllPaginationControls(paginationNode, 'range')
2012
+ .filter(function (control) { return !readJSXAttributeString(control, PAGINATION_FOR_ATTR); })
2013
+ .forEach(function (control) { return wireRangeControlFor(control, usage, vars); });
1978
2014
  if (usage.infiniteScroll) {
1979
2015
  // Only the Load More button survives; page controls make no sense for a
1980
2016
  // list the visitor never leaves.