textbrowser 0.50.0 → 0.52.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 (106) hide show
  1. package/.ncurc.cjs +3 -0
  2. package/CHANGES.md +13 -0
  3. package/dist/WorkInfo-es.js +655 -165
  4. package/dist/activateCallback-es.js +81 -10
  5. package/dist/dist/WorkInfo-es.d.ts +331 -0
  6. package/dist/dist/WorkInfo-es.d.ts.map +1 -0
  7. package/dist/dist/activateCallback-es.d.ts +17 -0
  8. package/dist/dist/activateCallback-es.d.ts.map +1 -0
  9. package/dist/dist/index-es.d.ts +619 -0
  10. package/dist/dist/index-es.d.ts.map +1 -0
  11. package/dist/dist/sw-helper.d.ts +3 -0
  12. package/dist/dist/sw-helper.d.ts.map +1 -0
  13. package/dist/eslint.config.d.ts +126 -0
  14. package/dist/eslint.config.d.ts.map +1 -0
  15. package/dist/index-es.js +3449 -1848
  16. package/dist/index-es.min.js +4 -4
  17. package/dist/resources/activateCallback.d.ts +23 -0
  18. package/dist/resources/activateCallback.d.ts.map +1 -0
  19. package/dist/resources/index.d.ts +128 -0
  20. package/dist/resources/index.d.ts.map +1 -0
  21. package/dist/resources/resultsDisplay.d.ts +110 -0
  22. package/dist/resources/resultsDisplay.d.ts.map +1 -0
  23. package/dist/resources/templates/index.d.ts +59 -0
  24. package/dist/resources/templates/index.d.ts.map +1 -0
  25. package/dist/resources/templates/languageSelect.d.ts +18 -0
  26. package/dist/resources/templates/languageSelect.d.ts.map +1 -0
  27. package/dist/resources/templates/resultsDisplayClient.d.ts +26 -0
  28. package/dist/resources/templates/resultsDisplayClient.d.ts.map +1 -0
  29. package/dist/resources/templates/resultsDisplayServerOrClient.d.ts +131 -0
  30. package/dist/resources/templates/resultsDisplayServerOrClient.d.ts.map +1 -0
  31. package/dist/resources/templates/utils/dom.d.ts +15 -0
  32. package/dist/resources/templates/utils/dom.d.ts.map +1 -0
  33. package/dist/resources/templates/utils/html.d.ts +3 -0
  34. package/dist/resources/templates/utils/html.d.ts.map +1 -0
  35. package/dist/resources/templates/workDisplay.d.ts +183 -0
  36. package/dist/resources/templates/workDisplay.d.ts.map +1 -0
  37. package/dist/resources/templates/workSelect.d.ts +18 -0
  38. package/dist/resources/templates/workSelect.d.ts.map +1 -0
  39. package/dist/resources/user-sample.d.ts +2 -0
  40. package/dist/resources/user-sample.d.ts.map +1 -0
  41. package/dist/resources/user.d.ts +2 -0
  42. package/dist/resources/user.d.ts.map +1 -0
  43. package/dist/resources/utils/IntlURLSearchParams.d.ts +56 -0
  44. package/dist/resources/utils/IntlURLSearchParams.d.ts.map +1 -0
  45. package/dist/resources/utils/Languages.d.ts +81 -0
  46. package/dist/resources/utils/Languages.d.ts.map +1 -0
  47. package/dist/resources/utils/Metadata.d.ts +133 -0
  48. package/dist/resources/utils/Metadata.d.ts.map +1 -0
  49. package/dist/resources/utils/Params.d.ts +30 -0
  50. package/dist/resources/utils/Params.d.ts.map +1 -0
  51. package/dist/resources/utils/Plugin.d.ts +278 -0
  52. package/dist/resources/utils/Plugin.d.ts.map +1 -0
  53. package/dist/resources/utils/ServiceWorker.d.ts +26 -0
  54. package/dist/resources/utils/ServiceWorker.d.ts.map +1 -0
  55. package/dist/resources/utils/WorkInfo.d.ts +104 -0
  56. package/dist/resources/utils/WorkInfo.d.ts.map +1 -0
  57. package/dist/resources/utils/dialogs.d.ts +155 -0
  58. package/dist/resources/utils/dialogs.d.ts.map +1 -0
  59. package/dist/resources/utils/getLocaleFallbackResults.d.ts +19 -0
  60. package/dist/resources/utils/getLocaleFallbackResults.d.ts.map +1 -0
  61. package/dist/resources/utils/sanitize.d.ts +6 -0
  62. package/dist/resources/utils/sanitize.d.ts.map +1 -0
  63. package/dist/resources/vendor/json-refs-min.d.ts +3 -0
  64. package/dist/resources/vendor/json-refs-min.d.ts.map +1 -0
  65. package/dist/resources/workDisplay.d.ts +81 -0
  66. package/dist/resources/workDisplay.d.ts.map +1 -0
  67. package/dist/resources/workSelect.d.ts +17 -0
  68. package/dist/resources/workSelect.d.ts.map +1 -0
  69. package/dist/rollup.config.d.ts +19 -0
  70. package/dist/rollup.config.d.ts.map +1 -0
  71. package/dist/server/main.d.ts +47 -0
  72. package/dist/server/main.d.ts.map +1 -0
  73. package/dist/sw-helper.d.ts +3 -0
  74. package/dist/sw-helper.d.ts.map +1 -0
  75. package/dist/sw-helper.js +52 -12
  76. package/dist/sw-sample.d.ts +2 -0
  77. package/dist/sw-sample.d.ts.map +1 -0
  78. package/general-schemas/files.jsonschema +6 -0
  79. package/package.json +32 -19
  80. package/resources/activateCallback.js +81 -10
  81. package/resources/index.js +169 -58
  82. package/resources/resultsDisplay.js +520 -153
  83. package/resources/templates/index.js +39 -17
  84. package/resources/templates/languageSelect.js +14 -1
  85. package/resources/templates/resultsDisplayClient.js +22 -3
  86. package/resources/templates/resultsDisplayServerOrClient.js +188 -49
  87. package/resources/templates/utils/dom.js +13 -2
  88. package/resources/templates/workDisplay.js +299 -76
  89. package/resources/templates/workSelect.js +16 -3
  90. package/resources/user-sample.js +1 -0
  91. package/resources/utils/IntlURLSearchParams.js +46 -4
  92. package/resources/utils/Languages.js +71 -4
  93. package/resources/utils/Metadata.js +222 -23
  94. package/resources/utils/Params.js +70 -23
  95. package/resources/utils/Plugin.js +175 -1
  96. package/resources/utils/ServiceWorker.js +49 -21
  97. package/resources/utils/WorkInfo.js +256 -44
  98. package/resources/utils/dialogs.js +105 -7
  99. package/resources/utils/getLocaleFallbackResults.js +15 -3
  100. package/resources/utils/sanitize.js +4 -0
  101. package/resources/workDisplay.js +151 -25
  102. package/resources/workSelect.js +37 -17
  103. package/server/main.js +118 -20
  104. package/sw-sample.js +2 -1
  105. package/tsconfig.json +30 -0
  106. package/resources/user.js +0 -20
@@ -10,19 +10,95 @@ import {
10
10
  import {Languages} from './utils/Languages.js';
11
11
  import {getWorkData} from './utils/WorkInfo.js';
12
12
 
13
+ /**
14
+ * @callback GetCanonicalID
15
+ * @param {{
16
+ * tr: (string|Integer)[]
17
+ * }} cfg
18
+ * @returns {string}
19
+ */
20
+ /**
21
+ * @callback DetermineEnd
22
+ * @param {{
23
+ * tr: (string|Integer)[]
24
+ * foundState: {
25
+ * start: boolean,
26
+ * end: boolean
27
+ * }
28
+ * }} cfg
29
+ * @returns {string|boolean}
30
+ */
31
+
32
+ /**
33
+ * @typedef {import('./utils/Plugin.js').PluginObject} Plugin
34
+ */
35
+
36
+ /**
37
+ * @typedef {{
38
+ * field?: string,
39
+ * fieldAliasOrName: string|string[]|import('../server/main.js').LocalizationStrings,
40
+ * escapeColumn: boolean,
41
+ * fieldLang: string,
42
+ * plugin?: Plugin,
43
+ * applicableField?: string,
44
+ * meta?: {[key: string]: string},
45
+ * j?: number,
46
+ * placement?: number
47
+ * metaApplicableField?: {
48
+ * [key: string]: string
49
+ * },
50
+ * onByDefault?: boolean
51
+ * }[]} FieldInfo
52
+ */
53
+
54
+ /**
55
+ * @typedef {import('./utils/Metadata.js').FieldValueAliases} FieldValueAliases
56
+ */
57
+ /* eslint-disable jsdoc/reject-any-type -- Arbitrary */
58
+ /**
59
+ * @typedef {any} AnyValue
60
+ */
61
+ /* eslint-enable jsdoc/reject-any-type -- Arbitrary */
62
+ /**
63
+ * @param {AnyValue} val
64
+ * @returns {val is null | undefined}
65
+ */
66
+ const isNullish = (val) => {
67
+ return val === null || val === undefined;
68
+ };
69
+
70
+ /**
71
+ * @typedef {number} Integer
72
+ */
73
+ /**
74
+ * @param {string} locale
75
+ */
13
76
  const getLangDir = (locale) => {
14
- const {direction} = new Locale(locale).textInfo;
77
+ const {direction} = new Locale(locale).getTextInfo();
15
78
  return direction;
16
79
  };
17
80
 
18
81
  const fieldValueAliasRegex = /^.* \((.*?)\)$/;
19
82
 
83
+ /**
84
+ * @param {string} v
85
+ */
20
86
  const getRawFieldValue = (v) => {
21
87
  return typeof v === 'string'
22
88
  ? v.replace(fieldValueAliasRegex, '$1')
23
89
  : v;
24
90
  };
25
91
 
92
+ /**
93
+ * @param {{
94
+ * applicableBrowseFieldSet: import('./utils/Metadata.js').BrowseFields,
95
+ * fieldValueAliasMapPreferred: (FieldValueAliases|null|undefined)[],
96
+ * lParamRaw: (key: string, suffix?: string) => string,
97
+ * lIndexedParam: (key: string) => string,
98
+ * max: number,
99
+ * $p: import('./utils/IntlURLSearchParams.js').default
100
+ * }} cfg
101
+ */
26
102
  const setAnchor = ({
27
103
  applicableBrowseFieldSet,
28
104
  fieldValueAliasMapPreferred, lParamRaw, lIndexedParam, max, $p
@@ -40,6 +116,8 @@ const setAnchor = ({
40
116
  }
41
117
  if (!anchor) {
42
118
  const anchors = [];
119
+
120
+ /** @type {string|null} */
43
121
  let anchorField = '';
44
122
  // eslint-disable-next-line sonarjs/misplaced-loop-counter -- Ok
45
123
  for (let i = 1, breakout; !breakout && !anchors.length; i++) {
@@ -65,6 +143,9 @@ const setAnchor = ({
65
143
  }
66
144
  }
67
145
  if (anchors.length) {
146
+ /**
147
+ * @param {string} str
148
+ */
68
149
  const escapeSelectorAttValue = (str) => (str || '').replaceAll(
69
150
  /["\\]/g, String.raw`\$&`
70
151
  );
@@ -82,10 +163,17 @@ const setAnchor = ({
82
163
  }
83
164
  };
84
165
 
166
+ /**
167
+ * @this {import('./index.js').default}
168
+ * @param {Omit<ResultsDisplayServerOrClientArg, "skipIndexedDB"|"prefI18n">} args
169
+ */
85
170
  export const resultsDisplayClient = async function resultsDisplayClient (args) {
86
171
  const persistent = await navigator.storage.persisted();
87
- const skipIndexedDB = this.skipIndexedDB || !persistent || !navigator.serviceWorker.controller;
88
- const prefI18n = localStorage.getItem(this.namespace + '-localizeParamNames');
172
+ const skipIndexedDB = this.skipIndexedDB || !persistent ||
173
+ !navigator.serviceWorker.controller;
174
+ const prefI18n = /** @type {"true"|"false"|null} */ (
175
+ localStorage.getItem(this.namespace + '-localizeParamNames')
176
+ );
89
177
 
90
178
  const {
91
179
  fieldInfo, $p,
@@ -97,14 +185,14 @@ export const resultsDisplayClient = async function resultsDisplayClient (args) {
97
185
  } = await resultsDisplayServerOrClient.call(this, {
98
186
  ...args, skipIndexedDB, prefI18n
99
187
  });
100
- document.title = workI18n(
188
+ document.title = /** @type {string} */ (workI18n(
101
189
  'browserfile-resultsdisplay',
102
190
  {
103
191
  work: fileData
104
- ? getMetaProp(lang, metadataObj, 'alias')
192
+ ? /** @type {string} */ (getMetaProp(lang, metadataObj, 'alias'))
105
193
  : ''
106
194
  }
107
- );
195
+ ));
108
196
  Templates.resultsDisplayClient.main(templateArgs);
109
197
  setAnchor({
110
198
  applicableBrowseFieldSet,
@@ -123,9 +211,12 @@ export const resultsDisplayClient = async function resultsDisplayClient (args) {
123
211
  };
124
212
 
125
213
  /**
214
+ * @this {import('../server/main.js').ResultsDisplayServerContext}
126
215
  * This is server-only code, but kept here as the function is similar.
127
- * @param {{serverOutput: "jamilih"|"html"|"json"}} args
128
- * @returns {Promise<Array|string>}
216
+ * @param {ResultsDisplayServerOrClientArg & {
217
+ * serverOutput?: "jamilih"|"html"|"json"|null
218
+ * }} args
219
+ * @returns {Promise<import('jamilih').JamilihArray|string|(string | number)[][]>}
129
220
  */
130
221
  export const resultsDisplayServer = async function resultsDisplayServer (args) {
131
222
  const {
@@ -149,17 +240,61 @@ export const resultsDisplayServer = async function resultsDisplayServer (args) {
149
240
  }
150
241
  };
151
242
 
243
+ /**
244
+ * @typedef {(info: {
245
+ * tr: (string|Integer)[],
246
+ * idx: number,
247
+ * }) => {
248
+ * tdVal: string|Integer,
249
+ * htmlEscaped: boolean
250
+ * }|{
251
+ * tdVal: string|Integer,
252
+ * htmlEscaped?: undefined
253
+ * }} GetCellValue
254
+ */
255
+
256
+ /**
257
+ * @todo For `locales`, should export `LocaleObject` from intl-dom
258
+ * @typedef {{
259
+ * l: import('intl-dom').I18NCallback,
260
+ * lang: string[],
261
+ * fallbackLanguages: string[]|undefined,
262
+ * locales: {head?: AnyValue, body: AnyValue},
263
+ * $p: import('./utils/IntlURLSearchParams.js').default,
264
+ * skipIndexedDB: boolean,
265
+ * noIndexedDB?: boolean,
266
+ * prefI18n: "true"|"false"|null,
267
+ * files?: string,
268
+ * allowPlugins?: boolean,
269
+ * langData: import('../server/main.js').LanguagesData,
270
+ * basePath: string,
271
+ * dynamicBasePath?: string
272
+ * }} ResultsDisplayServerOrClientArg
273
+ */
274
+
275
+ /**
276
+ * @this {import('../server/main.js').ResultsDisplayServerContext|import('./index.js').default}
277
+ * @param {ResultsDisplayServerOrClientArg} cfg
278
+ */
152
279
  export const resultsDisplayServerOrClient = async function resultsDisplayServerOrClient ({
153
280
  l, lang, fallbackLanguages, locales, $p, skipIndexedDB, noIndexedDB, prefI18n,
154
281
  files, allowPlugins, langData, basePath = '', dynamicBasePath = ''
155
282
  }) {
156
283
  const languages = new Languages({langData});
284
+
285
+ /**
286
+ * @param {{
287
+ * fieldValueAliasMapPreferred: (FieldValueAliases|null|undefined)[],
288
+ * escapeColumnIndexes: boolean[]
289
+ * }} cfg
290
+ * @returns {GetCellValue}
291
+ */
157
292
  const getCellValue = ({
158
293
  fieldValueAliasMapPreferred, escapeColumnIndexes
159
294
  }) => ({
160
295
  tr, idx
161
296
  }) => {
162
- let tdVal = (fieldValueAliasMapPreferred[idx] !== undefined
297
+ let tdVal = (!isNullish(fieldValueAliasMapPreferred[idx])
163
298
  ? fieldValueAliasMapPreferred[idx][tr[idx]]
164
299
  : tr[idx]
165
300
  );
@@ -167,90 +302,130 @@ export const resultsDisplayServerOrClient = async function resultsDisplayServerO
167
302
  tdVal = Object.values(tdVal);
168
303
  }
169
304
  if (Array.isArray(tdVal)) {
170
- tdVal = tdVal.join(l('comma-space'));
305
+ tdVal = tdVal.join(/** @type {string} */ (l('comma-space')));
171
306
  }
172
307
  return ((escapeColumnIndexes[idx] || !this.trustFormatHTML) &&
173
308
  typeof tdVal === 'string')
174
309
  ? {tdVal: escapeHTML(tdVal), htmlEscaped: true}
175
310
  : {tdVal};
176
311
  };
312
+
313
+ /**
314
+ * @param {{
315
+ * fieldValueAliasMap: (FieldValueAliases|null|undefined)[],
316
+ * fieldValueAliasMapPreferred: (FieldValueAliases|null|undefined)[],
317
+ * localizedFieldNames: (string | string[]|import('../server/main.js').LocalizationStrings)[],
318
+ * canonicalBrowseFieldNames: string[]
319
+ * }} cfg
320
+ */
177
321
  const getCanonicalID = ({
178
322
  fieldValueAliasMap, fieldValueAliasMapPreferred, localizedFieldNames,
179
323
  canonicalBrowseFieldNames
180
- }) => ({
181
- tr // , foundState
182
- }) => {
183
- return canonicalBrowseFieldNames.map((fieldName) => {
184
- const idx = localizedFieldNames.indexOf(fieldName);
185
- // This works to put alias in anchor but this includes
186
- // our ending parenthetical, the alias may be harder
187
- // to remember and/or automated than original (e.g.,
188
- // for a number representing a book); we may wish to
189
- // switch this (and also for other browse field-based
190
- // items).
191
- if (
192
- fieldValueAliasMap[idx] !== undefined &&
193
- // Added this condition after imf->intl-dom conversion; concealing a
194
- // bug?
195
- fieldValueAliasMap[idx] !== null
196
- ) {
197
- return fieldValueAliasMapPreferred[idx][tr[idx]];
198
- }
199
- return tr[idx];
200
- }).join('-'); // rowID;
201
- };
324
+ }) =>
325
+ /** @type {GetCanonicalID} */
326
+ // eslint-disable-next-line @stylistic/implicit-arrow-linebreak -- Ok
327
+ ({
328
+ tr // , foundState
329
+ }) => {
330
+ return canonicalBrowseFieldNames.map((fieldName) => {
331
+ const idx = localizedFieldNames.indexOf(fieldName);
332
+ // This works to put alias in anchor but this includes
333
+ // our ending parenthetical, the alias may be harder
334
+ // to remember and/or automated than original (e.g.,
335
+ // for a number representing a book); we may wish to
336
+ // switch this (and also for other browse field-based
337
+ // items).
338
+ if (
339
+ fieldValueAliasMap[idx] !== undefined &&
340
+ // Added this condition after imf->intl-dom conversion; concealing a
341
+ // bug?
342
+ fieldValueAliasMap[idx] !== null
343
+ ) {
344
+ return /** @type {FieldValueAliases} */ (
345
+ fieldValueAliasMapPreferred[idx]
346
+ )[tr[idx]];
347
+ }
348
+ return tr[idx];
349
+ }).join('-'); // rowID;
350
+ };
351
+
352
+ /**
353
+ * @param {{
354
+ * fieldValueAliasMap: (FieldValueAliases|null|undefined)[],
355
+ * fieldValueAliasMapPreferred: (FieldValueAliases|null|undefined)[],
356
+ * localizedFieldNames: (string|string[]|import('../server/main.js').LocalizationStrings)[],
357
+ * applicableBrowseFieldNames: string[],
358
+ * startsRaw: (string|Integer)[],
359
+ * endsRaw: (string|Integer)[]
360
+ * }} cfg
361
+ */
202
362
  const determineEnd = ({
203
363
  fieldValueAliasMap, fieldValueAliasMapPreferred, localizedFieldNames,
204
364
  applicableBrowseFieldNames, startsRaw, endsRaw
205
- }) => ({
206
- tr, foundState
207
- }) => {
208
- const rowIDPartsPreferred = [];
209
- const rowIDParts = applicableBrowseFieldNames.map((fieldName) => {
210
- const idx = localizedFieldNames.indexOf(fieldName);
211
- // This works to put alias in anchor but this includes
212
- // our ending parenthetical, the alias may be harder
213
- // to remember and/or automated than original (e.g.,
214
- // for a number representing a book), and there could
215
- // be multiple aliases for a value; we may wish to
216
- // switch this (and also for other browse field-based
217
- // items).
218
- if (
219
- fieldValueAliasMap[idx] !== undefined &&
220
- // Added this condition after imf->intl-dom conversion; concealing a
221
- // bug?
222
- fieldValueAliasMap[idx] !== null
223
- ) {
224
- rowIDPartsPreferred.push(fieldValueAliasMapPreferred[idx][tr[idx]]);
225
- } else {
226
- rowIDPartsPreferred.push(tr[idx]);
227
- }
228
- return tr[idx];
229
- });
365
+ }) =>
366
+ /** @type {DetermineEnd} */
367
+ // eslint-disable-next-line @stylistic/implicit-arrow-linebreak -- Ok
368
+ ({
369
+ tr, foundState
370
+ }) => {
371
+ const rowIDPartsPreferred = /** @type {(string|Integer)[]} */ ([]);
372
+ const rowIDParts = applicableBrowseFieldNames.map((fieldName) => {
373
+ const idx = localizedFieldNames.indexOf(fieldName);
374
+ // This works to put alias in anchor but this includes
375
+ // our ending parenthetical, the alias may be harder
376
+ // to remember and/or automated than original (e.g.,
377
+ // for a number representing a book), and there could
378
+ // be multiple aliases for a value; we may wish to
379
+ // switch this (and also for other browse field-based
380
+ // items).
381
+ if (
382
+ fieldValueAliasMap[idx] !== undefined &&
383
+ // Added this condition after imf->intl-dom conversion; concealing a
384
+ // bug?
385
+ fieldValueAliasMap[idx] !== null
386
+ ) {
387
+ rowIDPartsPreferred.push(
388
+ /** @type {string|Integer} */
389
+ (fieldValueAliasMapPreferred[idx]?.[tr[idx]])
390
+ );
391
+ } else {
392
+ rowIDPartsPreferred.push(tr[idx]);
393
+ }
394
+ return tr[idx];
395
+ });
230
396
 
231
- // Todo: Use schema to determine field type and use `Number.parseInt`
232
- // on other value instead of `String` conversions
233
- if (!foundState.start) {
234
- if (startsRaw.some((part, i) => {
397
+ // Todo: Use schema to determine field type and use `Number.parseInt`
398
+ // on other value instead of `String` conversions
399
+ if (!foundState.start) {
400
+ if (startsRaw.some((part, i) => {
401
+ const rowIDPart = rowIDParts[i];
402
+ return part !== rowIDPart;
403
+ })) {
404
+ // Trigger skip of this row
405
+ return false;
406
+ }
407
+ foundState.start = true;
408
+ }
409
+ // This doesn't go in an `else` for the above in case the start is the end
410
+ if (endsRaw.every((part, i) => {
235
411
  const rowIDPart = rowIDParts[i];
236
- return part !== rowIDPart;
412
+ return part === rowIDPart;
237
413
  })) {
238
- // Trigger skip of this row
239
- return false;
414
+ foundState.end = true;
415
+ } else if (foundState.end) { // If no longer matching, trigger end of the table
416
+ return true;
240
417
  }
241
- foundState.start = true;
242
- }
243
- // This doesn't go in an `else` for the above in case the start is the end
244
- if (endsRaw.every((part, i) => {
245
- const rowIDPart = rowIDParts[i];
246
- return part === rowIDPart;
247
- })) {
248
- foundState.end = true;
249
- } else if (foundState.end) { // If no longer matching, trigger end of the table
250
- return true;
251
- }
252
- return rowIDPartsPreferred.join('-'); // rowID;
253
- };
418
+ return rowIDPartsPreferred.join('-'); // rowID;
419
+ };
420
+
421
+ /**
422
+ * @param {{
423
+ * localizedFieldNames: (
424
+ * string|string[]|import('../server/main.js').LocalizationStrings
425
+ * )[],
426
+ * }} cfg
427
+ * @returns {[string[], number[], ("" | number[] | null)[]]}
428
+ */
254
429
  const getCheckedAndInterlinearFieldInfo = ({
255
430
  localizedFieldNames
256
431
  }) => {
@@ -279,35 +454,46 @@ export const resultsDisplayServerOrClient = async function resultsDisplayServerO
279
454
  });
280
455
  return [checkedFields, checkedFieldIndexes, allInterlinearColIndexes];
281
456
  };
457
+
458
+ /**
459
+ * @param {{
460
+ * starts: string[],
461
+ * ends: string[],
462
+ * applicableBrowseFieldNames: string[],
463
+ * heading: string
464
+ * }} cfg
465
+ * @returns {[boolean, string|undefined]}
466
+ */
282
467
  const getCaption = ({starts, ends, applicableBrowseFieldNames, heading}) => {
283
468
  let caption;
284
469
  const hasCaption = $pRaw('caption') !== '0';
285
470
  if (hasCaption) {
286
471
  /*
287
- // Works but displays in parentheses browse fields which
288
- // may be non-applicable
289
- const buildRangePoint = (startOrEnd) => escapeHTML(
290
- browseFieldSets.reduce((txt, bfs, i) =>
291
- (txt ? txt + ' (' : '') + bfs.map((bf, j) =>
292
- (j > 0 ? l('comma-space') : '') + bf + ' ' +
293
- $pRaw(startOrEnd + (i + 1) + '-' + (j + 1))
294
- ).join('') + (txt ? ')' : ''), '')
295
- );
296
- */
297
- /*
298
- // Works but overly long
299
- const buildRangePoint = (startOrEnd) => escapeHTML(
300
- applicableBrowseFieldSet.map((bf, j) =>
472
+ // Works but displays in parentheses browse fields which
473
+ // may be non-applicable
474
+ const buildRangePoint = (startOrEnd) => escapeHTML(
475
+ browseFieldSets.reduce((txt, bfs, i) =>
476
+ (txt ? txt + ' (' : '') + bfs.map((bf, j) =>
301
477
  (j > 0 ? l('comma-space') : '') + bf + ' ' +
302
- $pRaw(startOrEnd + (browseFieldSetIdx + 1) + '-' + (j + 1))
303
- ).join('')
304
- );
305
- */
478
+ $pRaw(startOrEnd + (i + 1) + '-' + (j + 1))
479
+ ).join('') + (txt ? ')' : ''), '')
480
+ );
481
+ */
482
+ /*
483
+ // Works but overly long
484
+ const buildRangePoint = (startOrEnd) => escapeHTML(
485
+ applicableBrowseFieldSet.map((bf, j) =>
486
+ (j > 0 ? l('comma-space') : '') + bf + ' ' +
487
+ $pRaw(startOrEnd + (browseFieldSetIdx + 1) + '-' + (j + 1))
488
+ ).join('')
489
+ );
490
+ */
306
491
  const startSep = Templates.resultsDisplayServerOrClient.startSeparator({l});
307
492
  const innerBrowseFieldSeparator = Templates.resultsDisplayServerOrClient.
308
493
  innerBrowseFieldSeparator({l});
309
494
 
310
495
  const buildRanges = () => {
496
+ /** @type {string[]} */
311
497
  const endVals = [];
312
498
  const startRange = starts.reduce((str, startFieldValue, i) => {
313
499
  const ret = str + startFieldValue;
@@ -332,11 +518,20 @@ export const resultsDisplayServerOrClient = async function resultsDisplayServerO
332
518
  }
333
519
  return [hasCaption, caption];
334
520
  };
521
+
522
+ /**
523
+ * @param {{
524
+ * presort: boolean|undefined,
525
+ * tableData: (string|Integer)[][],
526
+ * applicableBrowseFieldNames: string[],
527
+ * localizedFieldNames: (string|string[]|import('../server/main.js').LocalizationStrings)[]
528
+ * }} cfg
529
+ */
335
530
  const runPresort = ({presort, tableData, applicableBrowseFieldNames, localizedFieldNames}) => {
336
531
  // Todo: Ought to be checking against an aliased table
337
532
  if (presort) {
338
533
  tableData.sort((rowA, rowB) => {
339
- let precedence;
534
+ let precedence = 0;
340
535
  applicableBrowseFieldNames.some((fieldName) => {
341
536
  const idx = localizedFieldNames.indexOf(fieldName);
342
537
  const rowAFirst = rowA[idx] < rowB[idx];
@@ -348,6 +543,18 @@ export const resultsDisplayServerOrClient = async function resultsDisplayServerO
348
543
  });
349
544
  }
350
545
  };
546
+
547
+ /**
548
+ * @param {{
549
+ * schemaItems: {title: string, type: string}[],
550
+ * fieldInfo: FieldInfo,
551
+ * metadataObj: import('./utils/Metadata.js').MetadataObj,
552
+ * getFieldAliasOrName: (
553
+ * field: string
554
+ * ) => string|string[]|import('../server/main.js').LocalizationStrings,
555
+ * usePreferAlias: boolean
556
+ * }} cfg
557
+ */
351
558
  const getFieldValueAliasMap = ({
352
559
  schemaItems, fieldInfo, metadataObj, getFieldAliasOrName, usePreferAlias
353
560
  }) => {
@@ -356,7 +563,9 @@ export const resultsDisplayServerOrClient = async function resultsDisplayServerO
356
563
  return undefined;
357
564
  }
358
565
  const {preferAlias, fieldValueAliasMap} = getFieldNameAndValueAliases({
359
- field, schemaItems, metadataObj, getFieldAliasOrName, lang
566
+ // eslint-disable-next-line object-shorthand -- TS
567
+ field: /** @type {string} */ (field),
568
+ schemaItems, metadataObj, getFieldAliasOrName, lang
360
569
  });
361
570
  if (!usePreferAlias) {
362
571
  return preferAlias !== false ? fieldValueAliasMap : undefined;
@@ -372,36 +581,49 @@ export const resultsDisplayServerOrClient = async function resultsDisplayServerO
372
581
  if (val && typeof val === 'object') {
373
582
  if (typeof preferAlias === 'string') {
374
583
  fieldValueAliasMap[key] =
375
- Templates.resultsDisplayServerOrClient.fieldValueAlias({
376
- key, value: val[preferAlias]
377
- });
584
+ Templates.resultsDisplayServerOrClient.fieldValueAlias({
585
+ key, value: val[preferAlias]
586
+ });
378
587
  } else {
379
588
  Object.entries(val).forEach(([k, value]) => {
380
- fieldValueAliasMap[key][k] =
381
- Templates.resultsDisplayServerOrClient.fieldValueAlias({
382
- key, value
383
- });
589
+ /** @type {{[key: string]: string|number}} */
590
+ (fieldValueAliasMap[key])[k] =
591
+ Templates.resultsDisplayServerOrClient.fieldValueAlias({
592
+ key, value
593
+ });
384
594
  });
385
595
  }
386
596
  return;
387
597
  }
388
598
  fieldValueAliasMap[key] =
389
- Templates.resultsDisplayServerOrClient.fieldValueAlias({key, value: val});
599
+ Templates.resultsDisplayServerOrClient.fieldValueAlias({key, value: val});
390
600
  });
391
601
  return preferAlias !== false ? fieldValueAliasMap : undefined;
392
602
  }
393
603
  return undefined;
394
604
  });
395
605
  };
606
+
607
+ /**
608
+ * @param {string} param
609
+ * @param {boolean} [avoidLog]
610
+ */
396
611
  const $pRaw = (param, avoidLog) => {
397
612
  // Todo: Should work with i18n=true (if names i18nized, need reverse look-up)
613
+
614
+ /** @type {string} */
398
615
  let key;
399
616
  const p = $p.get(param, true);
400
617
  /**
401
- *
402
- * @param {GenericArray|PlainObject} locale
403
- * @returns {boolean}
404
- */
618
+ * @typedef {{
619
+ * [key: string]: string|LocaleObj
620
+ * }} LocaleObj
621
+ */
622
+ /**
623
+ *
624
+ * @param {LocaleObj[]|LocaleObj} locale
625
+ * @returns {boolean}
626
+ */
405
627
  function reverseLocaleLookup (locale) {
406
628
  if (Array.isArray(locale)) {
407
629
  return locale.some(reverseLocaleLookup);
@@ -419,17 +641,33 @@ export const resultsDisplayServerOrClient = async function resultsDisplayServerO
419
641
  });
420
642
  }
421
643
  reverseLocaleLookup(locales);
644
+ // @ts-expect-error TS defect
422
645
  if (!key && !avoidLog) {
423
646
  console.log('Bad param/value', param, '::', p);
424
647
  }
648
+ // @ts-expect-error TS defect
425
649
  return key; // || p; // $p.get(param, true);
426
650
  };
427
651
 
428
652
  const escapeCSS = escapeHTML;
653
+
654
+ /**
655
+ * @param {string} param
656
+ */
429
657
  const $pRawEsc = (param) => escapeHTML($pRaw(param));
430
- const $pEscArbitrary = (param) => escapeHTML($p.get(param, true));
658
+ /**
659
+ * @param {string} param
660
+ */
661
+ const $pEscArbitrary = (param) => escapeHTML(
662
+ /** @type {string} */
663
+ ($p.get(param, true))
664
+ );
431
665
 
432
666
  // Not currently in use
667
+
668
+ /**
669
+ * @param {string} s
670
+ */
433
671
  const escapeQuotedCSS = (s) => s.replaceAll('\\', '\\\\').replaceAll(
434
672
  '"', String.raw`\"`
435
673
  );
@@ -437,6 +675,7 @@ export const resultsDisplayServerOrClient = async function resultsDisplayServerO
437
675
  const {
438
676
  fileData, workI18n, getFieldAliasOrName, schemaObj, metadataObj,
439
677
  pluginsForWork
678
+ // @ts-expect-error Not using `this` given no `languages` arg is passed
440
679
  } = await getWorkData({
441
680
  files: files || this.files,
442
681
  allowPlugins: typeof allowPlugins === 'boolean' ? allowPlugins : this.allowPlugins,
@@ -446,11 +685,15 @@ export const resultsDisplayServerOrClient = async function resultsDisplayServerO
446
685
  });
447
686
  console.log('pluginsForWork', pluginsForWork);
448
687
 
449
- const heading = getMetaProp(lang, metadataObj, 'heading');
688
+ const heading = /** @type {string} */ (getMetaProp(lang, metadataObj, 'heading'));
450
689
  const schemaItems = schemaObj.items.items;
451
690
 
691
+ /** @type {string[]} */
452
692
  const setNames = [];
693
+ /** @type {(boolean|undefined)[]} */
453
694
  const presorts = [];
695
+
696
+ /** @type {import('./utils/Metadata.js').BrowseFields[]} */
454
697
  const browseFieldSets = [];
455
698
  getBrowseFieldData({
456
699
  metadataObj, schemaItems, getFieldAliasOrName, lang,
@@ -461,6 +704,7 @@ export const resultsDisplayServerOrClient = async function resultsDisplayServerO
461
704
  }
462
705
  });
463
706
 
707
+ /** @type {FieldInfo} */
464
708
  const fieldInfo = schemaItems.map(({title: field, format}) => {
465
709
  return {
466
710
  field,
@@ -484,12 +728,26 @@ export const resultsDisplayServerOrClient = async function resultsDisplayServerO
484
728
  placement = placement === 'end'
485
729
  ? Number.POSITIVE_INFINITY // push
486
730
  : placement;
731
+
732
+ /**
733
+ * @param {{
734
+ * applicableField?: string,
735
+ * targetLanguage?: string,
736
+ * onByDefault?: boolean,
737
+ * metaApplicableField?: {
738
+ * [key: string]: string
739
+ * },
740
+ * }} [cfg]
741
+ */
487
742
  const processField = ({applicableField, targetLanguage, onByDefault, metaApplicableField} = {}) => {
488
743
  const plugin = pluginsForWork.getPluginObject(pluginName) || {};
489
- const applicableFieldLang = metadata.getFieldLang(applicableField);
744
+ const applicableFieldLang = metadata.getFieldLang(
745
+ /** @type {string} */ (applicableField)
746
+ );
490
747
  if (plugin.getTargetLanguage) {
491
748
  targetLanguage = plugin.getTargetLanguage({
492
- applicableField,
749
+ // eslint-disable-next-line object-shorthand -- TS
750
+ applicableField: /** @type {string} */ (applicableField),
493
751
  targetLanguage,
494
752
  // Default lang for plug-in (from files.json)
495
753
  pluginLang,
@@ -502,27 +760,47 @@ export const resultsDisplayServerOrClient = async function resultsDisplayServerO
502
760
  if (targetLanguage === '{locale}') {
503
761
  targetLanguage = preferredLocale;
504
762
  }
505
- const applicableFieldI18N = getMetaProp(lang, metadataObj, ['fieldnames', applicableField]);
763
+ const applicableFieldI18N = getMetaProp(
764
+ lang,
765
+ metadataObj,
766
+ [
767
+ 'fieldnames',
768
+ /** @type {string} */
769
+ (applicableField)
770
+ ]
771
+ );
506
772
  const fieldAliasOrName = plugin.getFieldAliasOrName
507
773
  ? plugin.getFieldAliasOrName({
508
774
  locales: lang,
509
775
  workI18n,
510
- targetLanguage,
511
- applicableField,
776
+ // eslint-disable-next-line object-shorthand -- TS
777
+ targetLanguage: /** @type {string} */ (targetLanguage),
778
+ // eslint-disable-next-line object-shorthand -- TS
779
+ applicableField: /** @type {string} */ (applicableField),
512
780
  applicableFieldI18N,
513
781
  meta,
514
- metaApplicableField,
515
- targetLanguageI18N: languages.getLanguageFromCode(targetLanguage)
782
+ // eslint-disable-next-line object-shorthand -- TS
783
+ metaApplicableField: /** @type {{[key: string]: string }} */ (
784
+ metaApplicableField
785
+ ),
786
+ targetLanguageI18N: languages.getLanguageFromCode(
787
+ /** @type {string} */ (targetLanguage)
788
+ )
516
789
  })
517
790
  : languages.getFieldNameFromPluginNameAndLocales({
518
791
  pluginName,
519
- locales: lang,
792
+ // locales: lang,
520
793
  workI18n,
521
- targetLanguage,
522
- applicableFieldI18N,
794
+ // eslint-disable-next-line object-shorthand -- TS
795
+ targetLanguage: /** @type {string} */ (targetLanguage),
796
+ // eslint-disable-next-line object-shorthand -- TS
797
+ applicableFieldI18N: /** @type {string|string[]} */ (applicableFieldI18N),
523
798
  // Todo: Should have formal way to i18nize meta
524
799
  meta,
525
- metaApplicableField
800
+ // eslint-disable-next-line object-shorthand -- TS
801
+ metaApplicableField: /** @type {{[key: string]: string }} */ (
802
+ metaApplicableField
803
+ )
526
804
  });
527
805
  fieldInfo.splice(
528
806
  // Todo: Allow default placement overriding for
@@ -546,7 +824,7 @@ export const resultsDisplayServerOrClient = async function resultsDisplayServerO
546
824
  // not need here)
547
825
  applicableField,
548
826
  metaApplicableField,
549
- fieldLang: targetLanguage
827
+ fieldLang: /** @type {string} */ (targetLanguage)
550
828
  }
551
829
  );
552
830
  };
@@ -576,21 +854,81 @@ export const resultsDisplayServerOrClient = async function resultsDisplayServerO
576
854
  prefI18n !== 'false' && this.localizeParamNames
577
855
  );
578
856
  const lParam = localizeParamNames
579
- ? (key) => l(['params', key])
580
- : (key) => key;
857
+ // eslint-disable-next-line @stylistic/operator-linebreak -- Ok
858
+ ?
859
+ /**
860
+ * @param {string} key
861
+ * @returns {string}
862
+ */
863
+ (key) => /** @type {string} */ (l(['params', key]))
864
+ // eslint-disable-next-line @stylistic/operator-linebreak -- Ok
865
+ :
866
+ /**
867
+ * @param {string} key
868
+ * @returns {string}
869
+ */
870
+ (key) => key;
581
871
  const lIndexedParam = localizeParamNames
582
- ? (key) => l(['params', 'indexed', key])
583
- : (key) => key;
872
+ // eslint-disable-next-line @stylistic/operator-linebreak -- Ok
873
+ ?
874
+ /**
875
+ * @param {string} key
876
+ * @returns {string}
877
+ */
878
+ (key) => /** @type {string} */ (l(['params', 'indexed', key]))
879
+ // eslint-disable-next-line @stylistic/operator-linebreak -- Ok
880
+ :
881
+ /**
882
+ * @param {string} key
883
+ * @returns {string}
884
+ */
885
+ (key) => key;
584
886
  const lParamRaw = localizeParamNames
585
- ? (key, suffix = '') => $p.get(lParam(key) + suffix, true)
586
- : (key, suffix = '') => $p.get(key + suffix, true);
887
+ // eslint-disable-next-line @stylistic/operator-linebreak -- Ok
888
+ ?
889
+ /**
890
+ * @param {string} key
891
+ * @param {string} [suffix]
892
+ * @returns {string}
893
+ */
894
+ (key, suffix = '') => /** @type {string} */ (
895
+ $p.get(lParam(key) + suffix, true)
896
+ )
897
+ // eslint-disable-next-line @stylistic/operator-linebreak -- Ok
898
+ :
899
+ /**
900
+ * @param {string} key
901
+ * @param {string} [suffix]
902
+ * @returns {string}
903
+ */
904
+ (key, suffix = '') => /** @type {string} */ (
905
+ $p.get(key + suffix, true)
906
+ );
587
907
  const lIndexedParamRaw = localizeParamNames
588
- ? (key, suffix = '') => $p.get($p.get('work') + '-' + lIndexedParam(key) + suffix, true)
589
- : (key, suffix = '') => $p.get($p.get('work') + '-' + key + suffix, true);
908
+ // eslint-disable-next-line @stylistic/operator-linebreak -- Ok
909
+ ?
910
+ /**
911
+ * @param {string} key
912
+ * @param {string} [suffix]
913
+ * @returns {string}
914
+ */
915
+ (key, suffix = '') => /** @type {string} */ (
916
+ $p.get($p.get('work') + '-' + lIndexedParam(key) + suffix, true)
917
+ )
918
+ // eslint-disable-next-line @stylistic/operator-linebreak -- Ok
919
+ :
920
+ /**
921
+ * @param {string} key
922
+ * @param {string} [suffix]
923
+ * @returns {string}
924
+ */
925
+ (key, suffix = '') => /** @type {string} */ (
926
+ $p.get($p.get('work') + '-' + key + suffix, true)
927
+ );
590
928
 
591
929
  // Now that we know `browseFieldSets`, we can parse `startEnd`
592
930
  const browseFieldSetStartEndIdx = browseFieldSets.findIndex((item, i) => {
593
- return lIndexedParamRaw('startEnd', (i + 1));
931
+ return lIndexedParamRaw('startEnd', String(i + 1));
594
932
  });
595
933
  if (browseFieldSetStartEndIdx !== -1) {
596
934
  // Todo: i18nize (by work and/or by whole app?)
@@ -603,7 +941,7 @@ export const resultsDisplayServerOrClient = async function resultsDisplayServerO
603
941
  // Todo: Change query beginning at 0 to 1 if none present?
604
942
  // Todo: Support i18nized or canonical aliases (but don't
605
943
  // over-trim in such cases)
606
- const rawSearch = (lIndexedParamRaw('startEnd', browseFieldSetStartEndIdx + 1) || '').trim();
944
+ const rawSearch = (lIndexedParamRaw('startEnd', String(browseFieldSetStartEndIdx + 1)) || '').trim();
607
945
  const [startFull, endFull] = rawSearch.split(rangeSep);
608
946
  if (endFull !== undefined) {
609
947
  const startPartVals = startFull.split(partSep);
@@ -642,12 +980,16 @@ export const resultsDisplayServerOrClient = async function resultsDisplayServerO
642
980
  });
643
981
 
644
982
  const fieldSchemaTypes = applicableBrowseFieldSet.map((abfs) => abfs.fieldSchema.type);
983
+
984
+ /**
985
+ * @param {"start"|"end"} startOrEnd
986
+ */
645
987
  const buildRangePoint = (startOrEnd) => {
646
988
  return applicableBrowseFieldNames.map((bfn, j) => {
647
- return $p.get(
989
+ return /** @type {string} */ ($p.get(
648
990
  $p.get('work') + '-' + startOrEnd + (browseFieldSetIdx + 1) + '-' + (j + 1),
649
991
  true
650
- );
992
+ ));
651
993
  });
652
994
  };
653
995
  const starts = buildRangePoint('start');
@@ -660,6 +1002,11 @@ export const resultsDisplayServerOrClient = async function resultsDisplayServerO
660
1002
 
661
1003
  console.log('rand', lParamRaw('rand') === 'yes');
662
1004
 
1005
+ /**
1006
+ * @param {string} v
1007
+ * @param {Integer} i
1008
+ * @returns {Integer|string}
1009
+ */
663
1010
  const stripToRawFieldValue = (v, i) => {
664
1011
  let val;
665
1012
  if ((/^\d+$/).test(v) || fieldValueAliasRegex.test(v)) {
@@ -672,7 +1019,7 @@ export const resultsDisplayServerOrClient = async function resultsDisplayServerO
672
1019
  const fvEntries = Object.entries(rawFieldValueAliasMap);
673
1020
  if (Array.isArray(fvEntries[0][1])) {
674
1021
  fvEntries.some(([key, arr]) => {
675
- if (arr.includes(v)) {
1022
+ if (/** @type {(string | number)[]} */ (arr).includes(v)) {
676
1023
  dealiased = key;
677
1024
  return true;
678
1025
  }
@@ -699,7 +1046,9 @@ export const resultsDisplayServerOrClient = async function resultsDisplayServerO
699
1046
  const startsRaw = starts.map(stripToRawFieldValue);
700
1047
  const endsRaw = ends.map(stripToRawFieldValue);
701
1048
 
702
- let tableData, usingServerData = false;
1049
+ /** @type {(string|Integer)[][]} */
1050
+ let tableData;
1051
+ let usingServerData = false;
703
1052
  // Site owner may have configured to skip (e.g., testing)
704
1053
  if (!skipIndexedDB &&
705
1054
  // User may have refused, not yet agreed, or are visiting the
@@ -713,7 +1062,8 @@ export const resultsDisplayServerOrClient = async function resultsDisplayServerO
713
1062
  // Todo: Fetch the work in code based on the non-localized `datafileName`
714
1063
  const dbName = this.namespace + '-textbrowser-cache-data';
715
1064
  const req = indexedDB.open(dbName);
716
- req.onsuccess = ({target: {result: db}}) => {
1065
+ req.onsuccess = (e) => {
1066
+ const db = /** @type {EventTarget & {result: IDBDatabase}} */ (e.target).result;
717
1067
  const storeName = 'files-to-cache-' + unlocalizedWorkName;
718
1068
  const trans = db.transaction(storeName);
719
1069
  const store = trans.objectStore(storeName);
@@ -727,10 +1077,22 @@ export const resultsDisplayServerOrClient = async function resultsDisplayServerO
727
1077
  // console.log('applicableBrowseFieldSetName', 'browseFields-' + applicableBrowseFieldSetName);
728
1078
 
729
1079
  const r = index.getAll(IDBKeyRange.bound(startsRaw, endsRaw));
730
- r.onsuccess = ({target: {result}}) => {
731
- const converted = result.map((r) => r.value);
732
- resolve(converted);
733
- };
1080
+ r.addEventListener(
1081
+ 'success',
1082
+ /**
1083
+ * @param {Event} e
1084
+ * @returns {void}
1085
+ */
1086
+ (e) => {
1087
+ // eslint-disable-next-line prefer-destructuring -- TS
1088
+ const result =
1089
+ /** @type {EventTarget & {result: {value: (string|Integer)[]}[]}} */ (
1090
+ e.target
1091
+ ).result;
1092
+ const converted = result.map((r) => r.value);
1093
+ resolve(converted);
1094
+ }
1095
+ );
734
1096
  };
735
1097
  });
736
1098
  } else {
@@ -742,18 +1104,19 @@ export const resultsDisplayServerOrClient = async function resultsDisplayServerO
742
1104
  // needed
743
1105
  // if (presort || this.noDynamic) {
744
1106
  if (this.noDynamic) {
745
- ({
746
- resolved: {data: tableData}
747
- } = await JsonRefs.resolveRefs(fileData.file));
1107
+ const {
1108
+ resolved
1109
+ } = await JsonRefs.resolveRefs(fileData.file);
1110
+ (tableData = /** @type {{data: (string|Integer)[][]}} */ (resolved).data);
748
1111
  runPresort({presort, tableData, applicableBrowseFieldNames, localizedFieldNames});
749
1112
  } else {
750
1113
  /*
751
- const jsonURL = Object.entries({
752
- prefI18n, unlocalizedWorkName, startsRaw, endsRaw
753
- }).reduce((url, [arg, argVal]) => {
754
- return url + '&' + arg + '=' + encodeURIComponent((argVal));
755
- }, `${dynamicBasePath}textbrowser?`);
756
- */
1114
+ const jsonURL = Object.entries({
1115
+ prefI18n, unlocalizedWorkName, startsRaw, endsRaw
1116
+ }).reduce((url, [arg, argVal]) => {
1117
+ return url + '&' + arg + '=' + encodeURIComponent((argVal));
1118
+ }, `${dynamicBasePath}textbrowser?`);
1119
+ */
757
1120
  const jsonURL = `${dynamicBasePath}textbrowser?${$p.toString()}`;
758
1121
  tableData = await (await fetch(jsonURL)).json();
759
1122
  usingServerData = true;
@@ -767,8 +1130,9 @@ export const resultsDisplayServerOrClient = async function resultsDisplayServerO
767
1130
  tableData.forEach((tr) => {
768
1131
  // Todo: We should pass on other arguments (like `meta` but on `applicableFields`)
769
1132
  tr.splice(
770
- placement,
1133
+ placement ?? 0,
771
1134
  0,
1135
+ // @ts-expect-error Only used for `plugin` type?
772
1136
  null // `${i}-${j}`);
773
1137
  );
774
1138
  });
@@ -808,6 +1172,8 @@ export const resultsDisplayServerOrClient = async function resultsDisplayServerO
808
1172
  escapeQuotedCSS, escapeCSS, escapeHTML,
809
1173
  l, localizedFieldNames, fieldLangs, fieldDirs,
810
1174
  caption, hasCaption, showInterlinTitles,
1175
+ showEmptyInterlinear: this.showEmptyInterlinear,
1176
+ showTitleOnSingleInterlinear: this.showTitleOnSingleInterlinear,
811
1177
  determineEnd: determineEnd({
812
1178
  applicableBrowseFieldNames,
813
1179
  fieldValueAliasMap, fieldValueAliasMapPreferred,
@@ -821,7 +1187,8 @@ export const resultsDisplayServerOrClient = async function resultsDisplayServerO
821
1187
  localizedFieldNames
822
1188
  }),
823
1189
  getCellValue: getCellValue({
824
- fieldValueAliasMapPreferred, escapeColumnIndexes, escapeHTML
1190
+ fieldValueAliasMapPreferred, escapeColumnIndexes
1191
+ // escapeHTML
825
1192
  }),
826
1193
  checkedAndInterlinearFieldInfo: getCheckedAndInterlinearFieldInfo({
827
1194
  localizedFieldNames