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.
- package/.ncurc.cjs +3 -0
- package/CHANGES.md +13 -0
- package/dist/WorkInfo-es.js +655 -165
- package/dist/activateCallback-es.js +81 -10
- package/dist/dist/WorkInfo-es.d.ts +331 -0
- package/dist/dist/WorkInfo-es.d.ts.map +1 -0
- package/dist/dist/activateCallback-es.d.ts +17 -0
- package/dist/dist/activateCallback-es.d.ts.map +1 -0
- package/dist/dist/index-es.d.ts +619 -0
- package/dist/dist/index-es.d.ts.map +1 -0
- package/dist/dist/sw-helper.d.ts +3 -0
- package/dist/dist/sw-helper.d.ts.map +1 -0
- package/dist/eslint.config.d.ts +126 -0
- package/dist/eslint.config.d.ts.map +1 -0
- package/dist/index-es.js +3449 -1848
- package/dist/index-es.min.js +4 -4
- package/dist/resources/activateCallback.d.ts +23 -0
- package/dist/resources/activateCallback.d.ts.map +1 -0
- package/dist/resources/index.d.ts +128 -0
- package/dist/resources/index.d.ts.map +1 -0
- package/dist/resources/resultsDisplay.d.ts +110 -0
- package/dist/resources/resultsDisplay.d.ts.map +1 -0
- package/dist/resources/templates/index.d.ts +59 -0
- package/dist/resources/templates/index.d.ts.map +1 -0
- package/dist/resources/templates/languageSelect.d.ts +18 -0
- package/dist/resources/templates/languageSelect.d.ts.map +1 -0
- package/dist/resources/templates/resultsDisplayClient.d.ts +26 -0
- package/dist/resources/templates/resultsDisplayClient.d.ts.map +1 -0
- package/dist/resources/templates/resultsDisplayServerOrClient.d.ts +131 -0
- package/dist/resources/templates/resultsDisplayServerOrClient.d.ts.map +1 -0
- package/dist/resources/templates/utils/dom.d.ts +15 -0
- package/dist/resources/templates/utils/dom.d.ts.map +1 -0
- package/dist/resources/templates/utils/html.d.ts +3 -0
- package/dist/resources/templates/utils/html.d.ts.map +1 -0
- package/dist/resources/templates/workDisplay.d.ts +183 -0
- package/dist/resources/templates/workDisplay.d.ts.map +1 -0
- package/dist/resources/templates/workSelect.d.ts +18 -0
- package/dist/resources/templates/workSelect.d.ts.map +1 -0
- package/dist/resources/user-sample.d.ts +2 -0
- package/dist/resources/user-sample.d.ts.map +1 -0
- package/dist/resources/user.d.ts +2 -0
- package/dist/resources/user.d.ts.map +1 -0
- package/dist/resources/utils/IntlURLSearchParams.d.ts +56 -0
- package/dist/resources/utils/IntlURLSearchParams.d.ts.map +1 -0
- package/dist/resources/utils/Languages.d.ts +81 -0
- package/dist/resources/utils/Languages.d.ts.map +1 -0
- package/dist/resources/utils/Metadata.d.ts +133 -0
- package/dist/resources/utils/Metadata.d.ts.map +1 -0
- package/dist/resources/utils/Params.d.ts +30 -0
- package/dist/resources/utils/Params.d.ts.map +1 -0
- package/dist/resources/utils/Plugin.d.ts +278 -0
- package/dist/resources/utils/Plugin.d.ts.map +1 -0
- package/dist/resources/utils/ServiceWorker.d.ts +26 -0
- package/dist/resources/utils/ServiceWorker.d.ts.map +1 -0
- package/dist/resources/utils/WorkInfo.d.ts +104 -0
- package/dist/resources/utils/WorkInfo.d.ts.map +1 -0
- package/dist/resources/utils/dialogs.d.ts +155 -0
- package/dist/resources/utils/dialogs.d.ts.map +1 -0
- package/dist/resources/utils/getLocaleFallbackResults.d.ts +19 -0
- package/dist/resources/utils/getLocaleFallbackResults.d.ts.map +1 -0
- package/dist/resources/utils/sanitize.d.ts +6 -0
- package/dist/resources/utils/sanitize.d.ts.map +1 -0
- package/dist/resources/vendor/json-refs-min.d.ts +3 -0
- package/dist/resources/vendor/json-refs-min.d.ts.map +1 -0
- package/dist/resources/workDisplay.d.ts +81 -0
- package/dist/resources/workDisplay.d.ts.map +1 -0
- package/dist/resources/workSelect.d.ts +17 -0
- package/dist/resources/workSelect.d.ts.map +1 -0
- package/dist/rollup.config.d.ts +19 -0
- package/dist/rollup.config.d.ts.map +1 -0
- package/dist/server/main.d.ts +47 -0
- package/dist/server/main.d.ts.map +1 -0
- package/dist/sw-helper.d.ts +3 -0
- package/dist/sw-helper.d.ts.map +1 -0
- package/dist/sw-helper.js +52 -12
- package/dist/sw-sample.d.ts +2 -0
- package/dist/sw-sample.d.ts.map +1 -0
- package/general-schemas/files.jsonschema +6 -0
- package/package.json +32 -19
- package/resources/activateCallback.js +81 -10
- package/resources/index.js +169 -58
- package/resources/resultsDisplay.js +520 -153
- package/resources/templates/index.js +39 -17
- package/resources/templates/languageSelect.js +14 -1
- package/resources/templates/resultsDisplayClient.js +22 -3
- package/resources/templates/resultsDisplayServerOrClient.js +188 -49
- package/resources/templates/utils/dom.js +13 -2
- package/resources/templates/workDisplay.js +299 -76
- package/resources/templates/workSelect.js +16 -3
- package/resources/user-sample.js +1 -0
- package/resources/utils/IntlURLSearchParams.js +46 -4
- package/resources/utils/Languages.js +71 -4
- package/resources/utils/Metadata.js +222 -23
- package/resources/utils/Params.js +70 -23
- package/resources/utils/Plugin.js +175 -1
- package/resources/utils/ServiceWorker.js +49 -21
- package/resources/utils/WorkInfo.js +256 -44
- package/resources/utils/dialogs.js +105 -7
- package/resources/utils/getLocaleFallbackResults.js +15 -3
- package/resources/utils/sanitize.js +4 -0
- package/resources/workDisplay.js +151 -25
- package/resources/workSelect.js +37 -17
- package/server/main.js +118 -20
- package/sw-sample.js +2 -1
- package/tsconfig.json +30 -0
- 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).
|
|
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 ||
|
|
88
|
-
|
|
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 {
|
|
128
|
-
*
|
|
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]
|
|
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
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
//
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
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
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
//
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
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
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
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
|
|
412
|
+
return part === rowIDPart;
|
|
237
413
|
})) {
|
|
238
|
-
|
|
239
|
-
|
|
414
|
+
foundState.end = true;
|
|
415
|
+
} else if (foundState.end) { // If no longer matching, trigger end of the table
|
|
416
|
+
return true;
|
|
240
417
|
}
|
|
241
|
-
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
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
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
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 + (
|
|
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
|
-
|
|
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
|
-
|
|
376
|
-
|
|
377
|
-
|
|
584
|
+
Templates.resultsDisplayServerOrClient.fieldValueAlias({
|
|
585
|
+
key, value: val[preferAlias]
|
|
586
|
+
});
|
|
378
587
|
} else {
|
|
379
588
|
Object.entries(val).forEach(([k, value]) => {
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
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
|
-
|
|
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
|
-
|
|
403
|
-
|
|
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
|
-
|
|
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(
|
|
744
|
+
const applicableFieldLang = metadata.getFieldLang(
|
|
745
|
+
/** @type {string} */ (applicableField)
|
|
746
|
+
);
|
|
490
747
|
if (plugin.getTargetLanguage) {
|
|
491
748
|
targetLanguage = plugin.getTargetLanguage({
|
|
492
|
-
|
|
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(
|
|
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
|
-
|
|
511
|
-
|
|
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
|
-
|
|
515
|
-
|
|
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
|
-
|
|
522
|
-
|
|
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
|
-
|
|
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
|
-
|
|
580
|
-
|
|
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
|
-
|
|
583
|
-
|
|
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
|
-
|
|
586
|
-
|
|
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
|
-
|
|
589
|
-
|
|
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
|
-
|
|
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 = (
|
|
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.
|
|
731
|
-
|
|
732
|
-
|
|
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
|
|
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
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
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
|
|
1190
|
+
fieldValueAliasMapPreferred, escapeColumnIndexes
|
|
1191
|
+
// escapeHTML
|
|
825
1192
|
}),
|
|
826
1193
|
checkedAndInterlinearFieldInfo: getCheckedAndInterlinearFieldInfo({
|
|
827
1194
|
localizedFieldNames
|