textbrowser 0.50.0 → 0.51.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 +8 -0
- package/dist/WorkInfo-es.js +361 -111
- package/dist/activateCallback-es.js +72 -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 +959 -195
- package/dist/index-es.min.js +2 -2
- 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 +274 -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 +46 -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 +21 -8
- package/resources/activateCallback.js +75 -10
- package/resources/index.js +161 -49
- package/resources/resultsDisplay.js +517 -152
- package/resources/templates/index.js +39 -16
- 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 -75
- package/resources/templates/workSelect.js +16 -3
- package/resources/utils/IntlURLSearchParams.js +46 -4
- package/resources/utils/Languages.js +71 -4
- package/resources/utils/Metadata.js +219 -22
- package/resources/utils/Params.js +70 -23
- package/resources/utils/Plugin.js +169 -1
- package/resources/utils/ServiceWorker.js +48 -19
- package/resources/utils/WorkInfo.js +255 -43
- package/resources/utils/dialogs.js +105 -7
- package/resources/utils/getLocaleFallbackResults.js +12 -2
- package/resources/utils/sanitize.js +4 -0
- package/resources/workDisplay.js +151 -25
- package/resources/workSelect.js +37 -17
- package/server/main.js +111 -19
- package/tsconfig.json +30 -0
- package/resources/user.js +0 -20
|
@@ -16,7 +16,7 @@ const Templates = {
|
|
|
16
16
|
// We empty rather than `replaceWith` as our Jamilih `body`
|
|
17
17
|
// aliases expect the old instance
|
|
18
18
|
while (body.hasChildNodes()) {
|
|
19
|
-
body.firstChild
|
|
19
|
+
body.firstChild?.remove();
|
|
20
20
|
}
|
|
21
21
|
return jml('div', {
|
|
22
22
|
id: 'main', role: 'main'
|
|
@@ -24,19 +24,25 @@ const Templates = {
|
|
|
24
24
|
},
|
|
25
25
|
permissions: {
|
|
26
26
|
versionChange () {
|
|
27
|
-
|
|
27
|
+
/** @type {HTMLDialogElement} */
|
|
28
|
+
($('#versionChange'))?.showModal();
|
|
28
29
|
},
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @param {{text: string}} cfg
|
|
33
|
+
*/
|
|
29
34
|
addLogEntry ({text}) {
|
|
30
35
|
const installationDialog = $('#installationLogContainer');
|
|
31
36
|
try {
|
|
32
|
-
|
|
33
|
-
|
|
37
|
+
/** @type {HTMLDialogElement} */
|
|
38
|
+
(installationDialog).showModal();
|
|
39
|
+
const container = /** @type {HTMLElement} */ ($('#dialogContainer'));
|
|
34
40
|
container.hidden = false;
|
|
35
41
|
// eslint-disable-next-line no-unused-vars -- Ok
|
|
36
42
|
} catch (err) {
|
|
37
43
|
// May already be open
|
|
38
44
|
}
|
|
39
|
-
$('#installationLog').append(text + '\n');
|
|
45
|
+
/** @type {HTMLElement} */ ($('#installationLog')).append(text + '\n');
|
|
40
46
|
},
|
|
41
47
|
exitDialogs () {
|
|
42
48
|
const container = $('#dialogContainer');
|
|
@@ -44,6 +50,12 @@ const Templates = {
|
|
|
44
50
|
container.hidden = true;
|
|
45
51
|
}
|
|
46
52
|
},
|
|
53
|
+
/**
|
|
54
|
+
* @param {{
|
|
55
|
+
* type: string,
|
|
56
|
+
* escapedErrorMessage: string
|
|
57
|
+
* }} cfg
|
|
58
|
+
*/
|
|
47
59
|
dbError ({type, escapedErrorMessage}) {
|
|
48
60
|
if (type) {
|
|
49
61
|
jml('span', [
|
|
@@ -51,26 +63,33 @@ const Templates = {
|
|
|
51
63
|
escapedErrorMessage
|
|
52
64
|
], $('#dbError'));
|
|
53
65
|
}
|
|
54
|
-
|
|
66
|
+
/** @type {HTMLDialogElement} */
|
|
67
|
+
($('#dbError')).showModal();
|
|
55
68
|
},
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* @param {string} escapedErrorMessage
|
|
72
|
+
*/
|
|
56
73
|
errorRegistering (escapedErrorMessage) {
|
|
57
74
|
if (escapedErrorMessage) {
|
|
58
75
|
jml('span', [escapedErrorMessage], $('#errorRegistering'));
|
|
59
76
|
}
|
|
60
|
-
|
|
77
|
+
/** @type {HTMLDialogElement} */
|
|
78
|
+
($('#errorRegistering')).showModal();
|
|
61
79
|
},
|
|
62
80
|
browserNotGrantingPersistence () {
|
|
63
|
-
|
|
81
|
+
/** @type {HTMLDialogElement} */
|
|
82
|
+
($('#browserNotGrantingPersistence')).showModal();
|
|
64
83
|
},
|
|
65
84
|
/**
|
|
66
|
-
* @param {
|
|
67
|
-
* @param {I18NCallback} cfg.siteI18n
|
|
68
|
-
* @param {() => Promise<void>} cfg.ok
|
|
69
|
-
* @param {() => void} cfg.refuse
|
|
70
|
-
* @param {() => Promise<void>} cfg.close
|
|
71
|
-
* @param {() => void} cfg.closeBrowserNotGranting
|
|
85
|
+
* @param {object} cfg
|
|
86
|
+
* @param {import('intl-dom').I18NCallback} cfg.siteI18n
|
|
87
|
+
* @param {() => Promise<void>} [cfg.ok]
|
|
88
|
+
* @param {() => void} [cfg.refuse]
|
|
89
|
+
* @param {() => Promise<void>} [cfg.close]
|
|
90
|
+
* @param {() => void} [cfg.closeBrowserNotGranting]
|
|
72
91
|
* @returns {[
|
|
73
|
-
* HTMLDialogElement, HTMLDialogElement, HTMLDialogElement,
|
|
92
|
+
* HTMLDialogElement, HTMLDialogElement|"", HTMLDialogElement|"",
|
|
74
93
|
* HTMLDialogElement, HTMLDialogElement, HTMLDialogElement
|
|
75
94
|
* ]}
|
|
76
95
|
*/
|
|
@@ -89,8 +108,10 @@ const Templates = {
|
|
|
89
108
|
]]
|
|
90
109
|
// ['textarea', {readonly: true, style: 'width: 80%; height: 80%;'}]
|
|
91
110
|
]);
|
|
111
|
+
|
|
112
|
+
/** @type {""|HTMLDialogElement} */
|
|
92
113
|
let requestPermissionsDialog = '';
|
|
93
|
-
if (ok) {
|
|
114
|
+
if (ok && refuse && close) {
|
|
94
115
|
requestPermissionsDialog = jml(
|
|
95
116
|
'dialog', {
|
|
96
117
|
id: 'willRequestStoragePermissions',
|
|
@@ -121,6 +142,8 @@ const Templates = {
|
|
|
121
142
|
]]
|
|
122
143
|
]
|
|
123
144
|
);
|
|
145
|
+
|
|
146
|
+
/** @type {""|HTMLDialogElement} */
|
|
124
147
|
let browserNotGrantingPersistenceAlert = '';
|
|
125
148
|
if (closeBrowserNotGranting) {
|
|
126
149
|
browserNotGrantingPersistenceAlert = jml(
|
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
import {jml, $} from 'jamilih';
|
|
2
|
+
|
|
3
|
+
// @ts-expect-error Missing TS types
|
|
2
4
|
import {deserialize as formDeserialize} from 'form-serialization';
|
|
3
5
|
|
|
4
6
|
export default {
|
|
7
|
+
/**
|
|
8
|
+
* @param {{
|
|
9
|
+
* langs: import('../../server/main.js').LanguageInfo[]
|
|
10
|
+
* languages: import('../utils/Languages.js').Languages
|
|
11
|
+
* followParams: (formSelector: string, cb: () => void) => void
|
|
12
|
+
* $p: import('../utils/IntlURLSearchParams.js').default
|
|
13
|
+
* }} cfg
|
|
14
|
+
*/
|
|
5
15
|
main ({langs, languages, followParams, $p}) {
|
|
6
16
|
jml('form', {class: 'focus', id: 'languageSelectionContainer', $on: {
|
|
7
17
|
submit (e) {
|
|
@@ -12,7 +22,10 @@ export default {
|
|
|
12
22
|
name: 'lang',
|
|
13
23
|
size: langs.length,
|
|
14
24
|
$on: {
|
|
15
|
-
click ({target: {parentNode: {
|
|
25
|
+
click ({target: {parentNode: {
|
|
26
|
+
// @ts-expect-error Ok
|
|
27
|
+
selectedOptions
|
|
28
|
+
}}}) {
|
|
16
29
|
followParams('#languageSelectionContainer', () => {
|
|
17
30
|
$p.set('lang', selectedOptions[0].value, true);
|
|
18
31
|
});
|
|
@@ -3,9 +3,20 @@ import Templates from './index.js';
|
|
|
3
3
|
import {dialogs} from '../utils/dialogs.js';
|
|
4
4
|
|
|
5
5
|
export default {
|
|
6
|
+
/**
|
|
7
|
+
* @param {{
|
|
8
|
+
* anchorRowCol: string
|
|
9
|
+
* }} cfg
|
|
10
|
+
*/
|
|
6
11
|
anchorRowCol ({anchorRowCol}) {
|
|
7
12
|
return $('#' + anchorRowCol);
|
|
8
13
|
},
|
|
14
|
+
/**
|
|
15
|
+
* @param {{
|
|
16
|
+
* escapedRow: string
|
|
17
|
+
* escapedCol: string|undefined
|
|
18
|
+
* }} cfg
|
|
19
|
+
*/
|
|
9
20
|
anchors ({escapedRow, escapedCol}) {
|
|
10
21
|
const sel = 'tr[data-row="' + escapedRow + '"]' +
|
|
11
22
|
(escapedCol
|
|
@@ -13,16 +24,24 @@ export default {
|
|
|
13
24
|
: '');
|
|
14
25
|
return $(sel);
|
|
15
26
|
},
|
|
16
|
-
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @param {import('./resultsDisplayServerOrClient.js').ResultsDisplayServerOrClientArgs} args
|
|
30
|
+
*/
|
|
31
|
+
main (args) {
|
|
17
32
|
let html;
|
|
18
33
|
try {
|
|
19
|
-
html =
|
|
20
|
-
|
|
34
|
+
html = /** @type {import('jamilih').JamilihArray} */ (
|
|
35
|
+
Templates.resultsDisplayServerOrClient.main(args)
|
|
36
|
+
);
|
|
37
|
+
} catch (error) {
|
|
38
|
+
const err = /** @type {Error} */ (error);
|
|
21
39
|
if (err.message === 'JSON support is currently not available') {
|
|
22
40
|
dialogs.alert(err.message);
|
|
23
41
|
} else {
|
|
24
42
|
console.error(err);
|
|
25
43
|
}
|
|
44
|
+
return;
|
|
26
45
|
}
|
|
27
46
|
jml(...html, $('#main'));
|
|
28
47
|
}
|
|
@@ -1,26 +1,96 @@
|
|
|
1
1
|
import Templates from './index.js';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* @typedef {number} Integer
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* @typedef {{
|
|
8
|
+
* interlinearSeparator?: string,
|
|
9
|
+
* showEmptyInterlinear?: boolean,
|
|
10
|
+
* showTitleOnSingleInterlinear?: boolean,
|
|
11
|
+
* tableData: (string|Integer)[][],
|
|
12
|
+
* $p: import('../utils/IntlURLSearchParams.js').default,
|
|
13
|
+
* $pRaw: (key: string, avoidLog?: boolean) => string,
|
|
14
|
+
* $pRawEsc: (str: string) => string,
|
|
15
|
+
* $pEscArbitrary: (str: string) => string,
|
|
16
|
+
* escapeQuotedCSS: (str: string) => string,
|
|
17
|
+
* escapeCSS: (str: string) => string,
|
|
18
|
+
* escapeHTML: (str: string) => string,
|
|
19
|
+
* l: import('intl-dom').I18NCallback,
|
|
20
|
+
* localizedFieldNames: (string|string[]|import('../../server/main.js').LocalizationStrings)[],
|
|
21
|
+
* fieldLangs: (string|null)[],
|
|
22
|
+
* fieldDirs: (string | null)[],
|
|
23
|
+
* caption?: string,
|
|
24
|
+
* hasCaption: boolean,
|
|
25
|
+
* showInterlinTitles: boolean,
|
|
26
|
+
* determineEnd: import('../resultsDisplay.js').DetermineEnd,
|
|
27
|
+
* getCanonicalID: import('../resultsDisplay.js').GetCanonicalID,
|
|
28
|
+
* canonicalBrowseFieldSetName: string,
|
|
29
|
+
* getCellValue: import('../resultsDisplay.js').GetCellValue,
|
|
30
|
+
* checkedAndInterlinearFieldInfo: [string[], number[], ("" | number[] | null)[]]
|
|
31
|
+
* }} ResultsDisplayServerOrClientArgs
|
|
32
|
+
*/
|
|
33
|
+
|
|
3
34
|
export default {
|
|
35
|
+
/**
|
|
36
|
+
* @param {{
|
|
37
|
+
* heading: string,
|
|
38
|
+
* ranges: string
|
|
39
|
+
* }} cfg
|
|
40
|
+
*/
|
|
4
41
|
caption ({heading, ranges}) {
|
|
5
42
|
return heading + ' ' + ranges;
|
|
6
43
|
},
|
|
44
|
+
/**
|
|
45
|
+
* @param {{
|
|
46
|
+
* l: import('intl-dom').I18NCallback
|
|
47
|
+
* }} cfg
|
|
48
|
+
* @returns {string}
|
|
49
|
+
*/
|
|
7
50
|
startSeparator ({l}) {
|
|
8
|
-
return l('colon');
|
|
51
|
+
return /** @type {string} */ (l('colon'));
|
|
9
52
|
},
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* @param {{
|
|
56
|
+
* l: import('intl-dom').I18NCallback
|
|
57
|
+
* }} cfg
|
|
58
|
+
*/
|
|
10
59
|
innerBrowseFieldSeparator ({l}) {
|
|
11
|
-
return l('comma-space');
|
|
60
|
+
return /** @type {string} */ (l('comma-space'));
|
|
12
61
|
},
|
|
62
|
+
/**
|
|
63
|
+
* @param {{
|
|
64
|
+
* l: import('intl-dom').I18NCallback,
|
|
65
|
+
* startRange: string,
|
|
66
|
+
* endVals: string[],
|
|
67
|
+
* rangeNames: string
|
|
68
|
+
* }} cfg
|
|
69
|
+
*/
|
|
13
70
|
ranges ({l, startRange, endVals, rangeNames}) {
|
|
14
71
|
return startRange +
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
72
|
+
// l('to').toLowerCase() + ' ' +
|
|
73
|
+
'-' +
|
|
74
|
+
endVals.join(
|
|
75
|
+
Templates.resultsDisplayServerOrClient.startSeparator({l})
|
|
76
|
+
) + ' (' + rangeNames + ')';
|
|
20
77
|
},
|
|
78
|
+
/**
|
|
79
|
+
* @param {{
|
|
80
|
+
* key: string,
|
|
81
|
+
* value: string|number
|
|
82
|
+
* }} cfg
|
|
83
|
+
*/
|
|
21
84
|
fieldValueAlias ({key, value}) {
|
|
22
85
|
return value + ' (' + key + ')';
|
|
23
86
|
},
|
|
87
|
+
/**
|
|
88
|
+
* @param {{
|
|
89
|
+
* lang?: string|null,
|
|
90
|
+
* dir?: string|null,
|
|
91
|
+
* html: string
|
|
92
|
+
* }} cfg
|
|
93
|
+
*/
|
|
24
94
|
interlinearSegment ({lang, dir, html}) {
|
|
25
95
|
return `<span${
|
|
26
96
|
lang ? ` lang="${lang}"` : ''
|
|
@@ -28,10 +98,30 @@ export default {
|
|
|
28
98
|
dir ? ` dir="${dir}"` : ''
|
|
29
99
|
}>${html}</span>`;
|
|
30
100
|
},
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* @param {{
|
|
104
|
+
* l: import('intl-dom').I18NCallback,
|
|
105
|
+
* val: string
|
|
106
|
+
* }} cfg
|
|
107
|
+
*/
|
|
31
108
|
interlinearTitle ({l, val}) {
|
|
32
109
|
const colonSpace = l('colon-space');
|
|
33
110
|
return `<span class="interlintitle">${val}</span>${colonSpace}`;
|
|
34
111
|
},
|
|
112
|
+
/**
|
|
113
|
+
* @param {{
|
|
114
|
+
* $p: import('../utils/IntlURLSearchParams.js').default,
|
|
115
|
+
* $pRaw: (key: string, avoidLog?: boolean) => string,
|
|
116
|
+
* $pRawEsc: (str: string) => string,
|
|
117
|
+
* $pEscArbitrary: (str: string) => string,
|
|
118
|
+
* escapeCSS: (str: string) => string,
|
|
119
|
+
* tableWithFixedHeaderAndFooter: boolean,
|
|
120
|
+
* checkedFieldIndexes: number[],
|
|
121
|
+
* hasCaption: boolean
|
|
122
|
+
* }} cfg
|
|
123
|
+
* @returns {import('jamilih').JamilihArray}
|
|
124
|
+
*/
|
|
35
125
|
styles ({
|
|
36
126
|
$p, $pRaw, $pRawEsc, $pEscArbitrary, // escapeQuotedCSS,
|
|
37
127
|
escapeCSS,
|
|
@@ -176,16 +266,32 @@ body {
|
|
|
176
266
|
: '')
|
|
177
267
|
]];
|
|
178
268
|
},
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* @param {ResultsDisplayServerOrClientArgs} args
|
|
272
|
+
* @returns {import('jamilih').JamilihArray}
|
|
273
|
+
*/
|
|
179
274
|
main ({
|
|
180
275
|
tableData, $p, $pRaw, $pRawEsc, $pEscArbitrary,
|
|
181
276
|
// Todo: escaping should be done in business logic!
|
|
182
|
-
escapeQuotedCSS,
|
|
277
|
+
// escapeQuotedCSS,
|
|
278
|
+
escapeCSS, escapeHTML,
|
|
183
279
|
l, localizedFieldNames, fieldLangs, fieldDirs,
|
|
184
280
|
caption, hasCaption, showInterlinTitles,
|
|
185
281
|
determineEnd, getCanonicalID, canonicalBrowseFieldSetName,
|
|
186
282
|
getCellValue, checkedAndInterlinearFieldInfo,
|
|
283
|
+
showEmptyInterlinear,
|
|
284
|
+
showTitleOnSingleInterlinear,
|
|
187
285
|
interlinearSeparator = '<br /><br />'
|
|
188
286
|
}) {
|
|
287
|
+
/**
|
|
288
|
+
* @type {{
|
|
289
|
+
* table: [string, (import('jamilih').JamilihAttributes | undefined)?][],
|
|
290
|
+
* div: [string, (import('jamilih').JamilihAttributes | undefined)?][],
|
|
291
|
+
* "json-array": "json",
|
|
292
|
+
* "json-object": "json"
|
|
293
|
+
* }}
|
|
294
|
+
*/
|
|
189
295
|
const tableOptions = {
|
|
190
296
|
table: [
|
|
191
297
|
['table', {class: 'table', border: $pRaw('border') || '0'}],
|
|
@@ -214,7 +320,7 @@ body {
|
|
|
214
320
|
'json-array': 'json',
|
|
215
321
|
'json-object': 'json'
|
|
216
322
|
};
|
|
217
|
-
const outputmode = $p.get('outputmode', true); // Why not $pRaw?
|
|
323
|
+
const outputmode = /** @type {"json-object"|"json-array"|"table"|"div"} */ ($p.get('outputmode', true)); // Why not $pRaw?
|
|
218
324
|
|
|
219
325
|
switch (outputmode) {
|
|
220
326
|
case 'json-object': // Can later fall through if supporting
|
|
@@ -227,7 +333,7 @@ body {
|
|
|
227
333
|
}
|
|
228
334
|
|
|
229
335
|
const tableElems = tableOptions[
|
|
230
|
-
Object.
|
|
336
|
+
Object.hasOwn(tableOptions, outputmode) && outputmode
|
|
231
337
|
? outputmode
|
|
232
338
|
: 'table' // Default
|
|
233
339
|
];
|
|
@@ -236,9 +342,13 @@ body {
|
|
|
236
342
|
] = tableElems; // colgroupElem, colElem
|
|
237
343
|
|
|
238
344
|
const [checkedFields, checkedFieldIndexes, allInterlinearColIndexes] =
|
|
239
|
-
|
|
345
|
+
checkedAndInterlinearFieldInfo;
|
|
240
346
|
|
|
241
347
|
const tableWithFixedHeaderAndFooter = $pRaw('headerfooterfixed') === 'yes';
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* @param {import('jamilih').JamilihChildren} children
|
|
351
|
+
*/
|
|
242
352
|
const tableWrap = (children) => {
|
|
243
353
|
return tableWithFixedHeaderAndFooter
|
|
244
354
|
? ['div', {class: 'table-responsive anchor-table-header zupa'}, [
|
|
@@ -247,30 +357,44 @@ body {
|
|
|
247
357
|
: ['div', {class: 'table-responsive'}, children];
|
|
248
358
|
};
|
|
249
359
|
|
|
360
|
+
/**
|
|
361
|
+
* @param {import('jamilih').JamilihArray} el
|
|
362
|
+
* @param {import('jamilih').JamilihChildren} children
|
|
363
|
+
*/
|
|
250
364
|
const addChildren = (el, children) => {
|
|
251
365
|
// eslint-disable-next-line unicorn/prefer-structured-clone -- Need JSON
|
|
252
366
|
el = JSON.parse(JSON.stringify(el));
|
|
253
367
|
el.push(children);
|
|
254
368
|
return el;
|
|
255
369
|
};
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* @param {[string, import('jamilih').JamilihAttributes?]} elAtts
|
|
373
|
+
* @param {import('jamilih').JamilihAttributes} newAtts
|
|
374
|
+
* @returns {import('jamilih').JamilihArray}
|
|
375
|
+
*/
|
|
256
376
|
const addAtts = ([el, atts], newAtts) => [el, {...atts, ...newAtts}];
|
|
257
377
|
|
|
258
378
|
const foundState = {
|
|
259
379
|
start: false,
|
|
260
380
|
end: false
|
|
261
381
|
};
|
|
262
|
-
const outArr = [];
|
|
263
382
|
|
|
264
|
-
|
|
383
|
+
/** @type {import('jamilih').JamilihArray[]} */
|
|
384
|
+
const outArr = [];
|
|
265
385
|
|
|
386
|
+
/**
|
|
387
|
+
* @param {string} tdVal
|
|
388
|
+
* @param {boolean} [htmlEscaped]
|
|
389
|
+
*/
|
|
266
390
|
const checkEmpty = (tdVal, htmlEscaped) => {
|
|
267
391
|
if (!showEmptyInterlinear) {
|
|
268
392
|
if (!htmlEscaped) {
|
|
269
|
-
|
|
270
|
-
[...
|
|
393
|
+
const tdValElem = new DOMParser().parseFromString(tdVal, 'text/html').body;
|
|
394
|
+
[...tdValElem.querySelectorAll('br')].forEach((br) => {
|
|
271
395
|
br.remove();
|
|
272
396
|
});
|
|
273
|
-
tdVal =
|
|
397
|
+
tdVal = tdValElem.innerHTML;
|
|
274
398
|
}
|
|
275
399
|
if (!tdVal.trim()) {
|
|
276
400
|
return true;
|
|
@@ -302,7 +426,11 @@ body {
|
|
|
302
426
|
// Need to get a new one
|
|
303
427
|
const {tdVal, htmlEscaped} = getCellValue({tr, idx});
|
|
304
428
|
console.log('showEmptyInterlinear', showEmptyInterlinear, htmlEscaped);
|
|
305
|
-
const isEmpty = checkEmpty(
|
|
429
|
+
const isEmpty = checkEmpty(
|
|
430
|
+
/** @type {string} */
|
|
431
|
+
(tdVal),
|
|
432
|
+
htmlEscaped
|
|
433
|
+
);
|
|
306
434
|
if (isEmpty) {
|
|
307
435
|
return '';
|
|
308
436
|
}
|
|
@@ -313,7 +441,7 @@ body {
|
|
|
313
441
|
dir: fieldDirs[idx],
|
|
314
442
|
html: (showInterlinTitles
|
|
315
443
|
? Templates.resultsDisplayServerOrClient.interlinearTitle({
|
|
316
|
-
l, val: localizedFieldNames[idx]
|
|
444
|
+
l, val: /** @type {string} */ (localizedFieldNames[idx])
|
|
317
445
|
})
|
|
318
446
|
: '') + tdVal
|
|
319
447
|
})
|
|
@@ -327,36 +455,41 @@ body {
|
|
|
327
455
|
lang: fieldLangs[idx],
|
|
328
456
|
dir: fieldDirs[idx],
|
|
329
457
|
dataset: {
|
|
330
|
-
col: localizedFieldNames[idx]
|
|
458
|
+
col: /** @type {string} */ (localizedFieldNames[idx])
|
|
331
459
|
},
|
|
332
460
|
innerHTML:
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
461
|
+
(showInterlins && !checkEmpty(
|
|
462
|
+
/** @type {string} */
|
|
463
|
+
(tdVal),
|
|
464
|
+
htmlEscaped
|
|
465
|
+
) &&
|
|
466
|
+
(showTitleOnSingleInterlinear || interlins?.length)
|
|
467
|
+
? Templates.resultsDisplayServerOrClient.interlinearSegment({
|
|
468
|
+
lang: fieldLangs[idx],
|
|
469
|
+
html: (showInterlinTitles
|
|
470
|
+
? Templates.resultsDisplayServerOrClient.interlinearTitle({
|
|
471
|
+
l, val: /** @type {string} */ (localizedFieldNames[idx])
|
|
472
|
+
})
|
|
473
|
+
: '') + tdVal
|
|
474
|
+
})
|
|
475
|
+
: tdVal
|
|
476
|
+
) +
|
|
477
|
+
(interlinearColIndexes && interlins && interlins.length
|
|
478
|
+
? interlinearSeparator +
|
|
479
|
+
interlins.join(interlinearSeparator)
|
|
480
|
+
: ''
|
|
481
|
+
)
|
|
350
482
|
});
|
|
351
483
|
})
|
|
352
484
|
));
|
|
353
485
|
return false;
|
|
354
486
|
});
|
|
355
487
|
|
|
356
|
-
return ['div', [
|
|
488
|
+
return /** @type {import('jamilih').JamilihArray} */ (['div', [
|
|
357
489
|
Templates.resultsDisplayServerOrClient.styles({
|
|
358
490
|
$p, $pRaw, $pRawEsc, $pEscArbitrary,
|
|
359
|
-
escapeQuotedCSS,
|
|
491
|
+
// escapeQuotedCSS,
|
|
492
|
+
escapeCSS, tableWithFixedHeaderAndFooter,
|
|
360
493
|
checkedFieldIndexes, hasCaption
|
|
361
494
|
}),
|
|
362
495
|
tableWrap([
|
|
@@ -374,14 +507,14 @@ body {
|
|
|
374
507
|
])
|
|
375
508
|
: ''),
|
|
376
509
|
/*
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
510
|
+
// Works but quirky, e.g., `color` doesn't work (as also
|
|
511
|
+
// confirmed per https://quirksmode.org/css/css2/columns.html)
|
|
512
|
+
addChildren(colgroupElem,
|
|
513
|
+
checkedFieldIndexes.map((idx, i) =>
|
|
514
|
+
addAtts(colElem, {style: $pRaw('css' + (idx + 1))})
|
|
515
|
+
)
|
|
516
|
+
),
|
|
517
|
+
*/
|
|
385
518
|
($pRaw('header') !== '0'
|
|
386
519
|
? addChildren(theadElem, [
|
|
387
520
|
addChildren(
|
|
@@ -391,7 +524,10 @@ body {
|
|
|
391
524
|
cf = escapeHTML(cf) + (interlinearColIndexes
|
|
392
525
|
? l('comma-space') + interlinearColIndexes.map((idx) => {
|
|
393
526
|
return localizedFieldNames[idx];
|
|
394
|
-
}).join(
|
|
527
|
+
}).join(
|
|
528
|
+
/** @type {string} */
|
|
529
|
+
(l('comma-space'))
|
|
530
|
+
)
|
|
395
531
|
: ''
|
|
396
532
|
);
|
|
397
533
|
return addChildren(thElem, [
|
|
@@ -418,7 +554,10 @@ body {
|
|
|
418
554
|
cf = escapeHTML(cf) + (interlinearColIndexes
|
|
419
555
|
? l('comma-space') + interlinearColIndexes.map((idx) => {
|
|
420
556
|
return localizedFieldNames[idx];
|
|
421
|
-
}).join(
|
|
557
|
+
}).join(
|
|
558
|
+
/** @type {string} */
|
|
559
|
+
(l('comma-space'))
|
|
560
|
+
)
|
|
422
561
|
: ''
|
|
423
562
|
);
|
|
424
563
|
return addChildren(thElem, [
|
|
@@ -439,6 +578,6 @@ body {
|
|
|
439
578
|
addChildren(tbodyElem, outArr)
|
|
440
579
|
])
|
|
441
580
|
])
|
|
442
|
-
]];
|
|
581
|
+
]]);
|
|
443
582
|
}
|
|
444
583
|
};
|
|
@@ -1,10 +1,21 @@
|
|
|
1
1
|
const nbsp = '\u00A0';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @param {string} sel
|
|
5
|
+
*/
|
|
2
6
|
const $ = (sel) => document.querySelector(sel);
|
|
7
|
+
/**
|
|
8
|
+
* @param {string} sel
|
|
9
|
+
*/
|
|
3
10
|
const $$ = (sel) => [...document.querySelectorAll(sel)];
|
|
4
11
|
|
|
12
|
+
/**
|
|
13
|
+
* @param {string|HTMLElement} el
|
|
14
|
+
* @param {string} descendentsSel
|
|
15
|
+
*/
|
|
5
16
|
const $e = (el, descendentsSel) => {
|
|
6
|
-
|
|
7
|
-
return
|
|
17
|
+
const elem = typeof el === 'string' ? $(el) : el;
|
|
18
|
+
return elem?.querySelector(descendentsSel);
|
|
8
19
|
};
|
|
9
20
|
|
|
10
21
|
export {nbsp, $, $$, $e};
|