textbrowser 0.45.2 → 0.46.1
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/.eslintrc.cjs +3 -0
- package/CHANGES.md +13 -0
- package/README.md +19 -15
- package/dist/WorkInfo-es.js +2118 -3640
- package/dist/index-es.js +11279 -12611
- package/dist/index-es.min.js +11 -16
- package/locales/ar.json +211 -209
- package/locales/en-US.json +212 -209
- package/locales/fa.json +211 -209
- package/locales/ru.json +211 -209
- package/package.json +45 -46
- package/resources/index.js +72 -50
- package/resources/resultsDisplay.js +40 -30
- package/resources/templates/index.js +133 -120
- package/resources/templates/resultsDisplayClient.js +2 -0
- package/resources/templates/workDisplay.js +195 -174
- package/resources/templates/workSelect.js +7 -7
- package/resources/user-sample.js +0 -2
- package/resources/user.js +0 -2
- package/resources/utils/IntlURLSearchParams.js +1 -1
- package/resources/utils/Languages.js +9 -4
- package/resources/utils/Metadata.js +13 -8
- package/resources/utils/Params.js +11 -9
- package/resources/utils/Plugin.js +4 -4
- package/resources/utils/WorkInfo.js +28 -13
- package/resources/utils/dialogs.js +8 -6
- package/resources/utils/getLocaleFallbackResults.js +26 -0
- package/resources/vendor/json-refs-min.js +15 -0
- package/resources/workDisplay.js +52 -46
- package/resources/workSelect.js +44 -23
- package/server/main.js +40 -32
- package/sw-sample.js +1 -1
- package/resources/utils/getIMFFallbackResults.js +0 -47
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {jml, $} from 'jamilih';
|
|
3
3
|
import {deserialize as formDeserialize} from 'form-serialization';
|
|
4
4
|
|
|
5
|
-
export default ({groups,
|
|
5
|
+
export default ({groups, workI18n, getNextAlias, $p, followParams}) => {
|
|
6
6
|
const form = jml(
|
|
7
7
|
'form',
|
|
8
8
|
{id: 'workSelect', class: 'focus', $on: {
|
|
@@ -10,11 +10,11 @@ export default ({groups, lf, getNextAlias, $p, followParams}) => {
|
|
|
10
10
|
e.preventDefault();
|
|
11
11
|
}
|
|
12
12
|
}},
|
|
13
|
-
groups.map((group, i) =>
|
|
14
|
-
['div', [
|
|
13
|
+
groups.map((group, i) => {
|
|
14
|
+
return ['div', [
|
|
15
15
|
i > 0 ? ['br', 'br', 'br'] : '',
|
|
16
16
|
['div', [
|
|
17
|
-
|
|
17
|
+
workI18n(group.directions.localeKey)
|
|
18
18
|
]],
|
|
19
19
|
['br'],
|
|
20
20
|
['select', {
|
|
@@ -40,14 +40,14 @@ export default ({groups, lf, getNextAlias, $p, followParams}) => {
|
|
|
40
40
|
['option', {value: ''}, ['--']],
|
|
41
41
|
...group.files.map(({name: fileName}) =>
|
|
42
42
|
['option', {
|
|
43
|
-
value:
|
|
43
|
+
value: workI18n(['workNames', group.id, fileName])
|
|
44
44
|
}, [getNextAlias()]]
|
|
45
45
|
)
|
|
46
46
|
]]
|
|
47
47
|
// Todo: Add in Go button (with 'submitgo' localization string) to
|
|
48
48
|
// avoid need for pull-down if using first selection?
|
|
49
|
-
]]
|
|
50
|
-
),
|
|
49
|
+
]];
|
|
50
|
+
}),
|
|
51
51
|
$('#main')
|
|
52
52
|
);
|
|
53
53
|
if (history.state && typeof history.state === 'object') {
|
package/resources/user-sample.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import TextBrowser from '../node_modules/textbrowser/dist/index-es.js';
|
|
2
2
|
|
|
3
|
-
(async () => {
|
|
4
3
|
const tb = new TextBrowser({
|
|
5
4
|
// languages: 'node_modules/textbrowser/appdata/languages.json', // Default
|
|
6
5
|
// serviceWorkerPath: 'sw.js', // Default
|
|
@@ -20,4 +19,3 @@ const tb = new TextBrowser({
|
|
|
20
19
|
// , interlinearSeparator: '<hr />' // Defaults to `<br /><br />`
|
|
21
20
|
});
|
|
22
21
|
await tb.init();
|
|
23
|
-
})();
|
package/resources/user.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import TextBrowser from '../dist/index-es.js';
|
|
2
2
|
|
|
3
|
-
(async () => {
|
|
4
3
|
const tb = new TextBrowser({
|
|
5
4
|
languages: 'appdata/languages.json', // Default
|
|
6
5
|
// serviceWorkerPath: 'sw.js', // Default
|
|
@@ -19,4 +18,3 @@ const tb = new TextBrowser({
|
|
|
19
18
|
// , interlinearSeparator: '<hr />' // Defaults to `<br /><br />`
|
|
20
19
|
});
|
|
21
20
|
await tb.init();
|
|
22
|
-
})();
|
|
@@ -24,22 +24,27 @@ export class Languages {
|
|
|
24
24
|
constructor ({langData}) {
|
|
25
25
|
this.langData = langData;
|
|
26
26
|
}
|
|
27
|
-
localeFromLangData (
|
|
28
|
-
return this.langData['localization-strings'][
|
|
27
|
+
localeFromLangData (langCode) {
|
|
28
|
+
return this.langData['localization-strings'][langCode];
|
|
29
29
|
}
|
|
30
30
|
getLanguageFromCode (code) {
|
|
31
31
|
return this.localeFromLangData(code).languages[code];
|
|
32
|
+
// Could add something like this in place or as fallback, though need to pass in locale
|
|
33
|
+
// || new Intl.DisplayNames([locale], {type: 'language'}).of(code);
|
|
32
34
|
}
|
|
33
35
|
getFieldNameFromPluginNameAndLocales ({
|
|
34
|
-
pluginName, locales,
|
|
36
|
+
pluginName, locales, workI18n, targetLanguage, applicableFieldI18N, meta, metaApplicableField
|
|
35
37
|
}) {
|
|
36
|
-
return
|
|
38
|
+
return workI18n(['plugins', pluginName, 'fieldname'], {
|
|
37
39
|
...meta,
|
|
38
40
|
...metaApplicableField,
|
|
39
41
|
applicableField: applicableFieldI18N,
|
|
40
42
|
targetLanguage: targetLanguage
|
|
41
43
|
? this.getLanguageFromCode(targetLanguage)
|
|
42
44
|
: ''
|
|
45
|
+
}, {
|
|
46
|
+
// We provide more than may be desired by the plugin
|
|
47
|
+
throwOnExtraSuppliedFormatters: false
|
|
43
48
|
});
|
|
44
49
|
}
|
|
45
50
|
getLanguageInfo ({$p}) {
|
|
@@ -64,13 +64,22 @@ export const getFieldNameAndValueAliases = function ({
|
|
|
64
64
|
);
|
|
65
65
|
const fieldSchema = schemaItems[fieldSchemaIndex];
|
|
66
66
|
|
|
67
|
+
const fieldInfo = metadataObj.fields[field];
|
|
68
|
+
|
|
67
69
|
const ret = {
|
|
68
70
|
// field,
|
|
69
|
-
|
|
71
|
+
aliases: null,
|
|
72
|
+
fieldValueAliasMap: null,
|
|
73
|
+
rawFieldValueAliasMap: null,
|
|
74
|
+
fieldName: getFieldAliasOrName(field),
|
|
75
|
+
fieldSchema,
|
|
76
|
+
fieldSchemaIndex,
|
|
77
|
+
preferAlias: fieldInfo.prefer_alias,
|
|
78
|
+
lang: fieldInfo.lang
|
|
70
79
|
};
|
|
71
80
|
|
|
72
|
-
const fieldInfo = metadataObj.fields[field];
|
|
73
81
|
let fieldValueAliasMap = fieldInfo && fieldInfo['fieldvalue-aliases'];
|
|
82
|
+
|
|
74
83
|
if (fieldValueAliasMap) {
|
|
75
84
|
if (fieldValueAliasMap.localeKey) {
|
|
76
85
|
fieldValueAliasMap = getMetaProp(
|
|
@@ -123,10 +132,6 @@ export const getFieldNameAndValueAliases = function ({
|
|
|
123
132
|
ret.fieldValueAliasMap = JSON.parse(JSON.stringify(fieldValueAliasMap));
|
|
124
133
|
// ret.aliases.sort();
|
|
125
134
|
}
|
|
126
|
-
ret.fieldSchema = fieldSchema;
|
|
127
|
-
ret.fieldSchemaIndex = fieldSchemaIndex;
|
|
128
|
-
ret.preferAlias = fieldInfo.prefer_alias;
|
|
129
|
-
ret.lang = fieldInfo.lang;
|
|
130
135
|
return ret;
|
|
131
136
|
};
|
|
132
137
|
|
|
@@ -144,7 +149,7 @@ export const getBrowseFieldData = function ({
|
|
|
144
149
|
const setName = browseFieldSetObject.name;
|
|
145
150
|
const fieldSets = browseFieldSetObject.set;
|
|
146
151
|
const {presort} = browseFieldSetObject;
|
|
147
|
-
// Todo: Deal with ['td', [['h3', [
|
|
152
|
+
// Todo: Deal with ['td', [['h3', [lDirectional(browseFieldObject.name)]]]]
|
|
148
153
|
// as kind of fieldset
|
|
149
154
|
|
|
150
155
|
const browseFields = fieldSets.map((field) =>
|
|
@@ -154,7 +159,7 @@ export const getBrowseFieldData = function ({
|
|
|
154
159
|
getFieldAliasOrName
|
|
155
160
|
})
|
|
156
161
|
);
|
|
157
|
-
callback({setName, browseFields, i, presort}); // eslint-disable-line
|
|
162
|
+
callback({setName, browseFields, i, presort}); // eslint-disable-line n/no-callback-literal
|
|
158
163
|
});
|
|
159
164
|
};
|
|
160
165
|
|
|
@@ -14,8 +14,10 @@ export const getSerializeParamsAsURL = function (...args) {
|
|
|
14
14
|
};
|
|
15
15
|
};
|
|
16
16
|
|
|
17
|
-
export const getParamsSetter = function ({l,
|
|
18
|
-
return function ({form, random = {
|
|
17
|
+
export const getParamsSetter = function ({l, lParam, $p}) {
|
|
18
|
+
return function ({form, random = {
|
|
19
|
+
checked: false
|
|
20
|
+
}, checkboxes, type, fieldAliasOrNames = [], workName}) {
|
|
19
21
|
const paramsCopy = new URLSearchParams($p.params);
|
|
20
22
|
const formParamsHash = formSerialize(form, {hash: true, empty: true});
|
|
21
23
|
|
|
@@ -24,8 +26,8 @@ export const getParamsSetter = function ({l, il, $p}) {
|
|
|
24
26
|
});
|
|
25
27
|
|
|
26
28
|
// Follow the same style (and order) for checkboxes
|
|
27
|
-
paramsCopy.delete(
|
|
28
|
-
paramsCopy.set(
|
|
29
|
+
paramsCopy.delete(lParam('rand'));
|
|
30
|
+
paramsCopy.set(lParam('rand'), random.checked ? l('yes') : l('no'));
|
|
29
31
|
|
|
30
32
|
// We want checkboxes to typically show by default, so we cannot use the
|
|
31
33
|
// standard serialization
|
|
@@ -60,11 +62,11 @@ export const getParamsSetter = function ({l, il, $p}) {
|
|
|
60
62
|
case 'saveSettings': {
|
|
61
63
|
// In case it was added previously on
|
|
62
64
|
// this page, let's remove it.
|
|
63
|
-
paramsCopy.delete(
|
|
65
|
+
paramsCopy.delete(lParam('rand'));
|
|
64
66
|
break;
|
|
65
67
|
}
|
|
66
68
|
case 'shortcutResult': {
|
|
67
|
-
paramsCopy.delete(
|
|
69
|
+
paramsCopy.delete(lParam('rand'));
|
|
68
70
|
let num = 1;
|
|
69
71
|
while (paramsCopy.has(`anchorfield${num}`, true)) {
|
|
70
72
|
paramsCopy.delete(`anchorfield${num}`, true);
|
|
@@ -100,10 +102,10 @@ export const getParamsSetter = function ({l, il, $p}) {
|
|
|
100
102
|
// In case it was added previously on this page,
|
|
101
103
|
// let's put random again toward the end.
|
|
102
104
|
if (type === 'randomResult' || random.checked) {
|
|
103
|
-
paramsCopy.delete(
|
|
104
|
-
paramsCopy.set(
|
|
105
|
+
paramsCopy.delete(lParam('rand'));
|
|
106
|
+
paramsCopy.set(lParam('rand'), l('yes'));
|
|
105
107
|
}
|
|
106
|
-
paramsCopy.set(
|
|
108
|
+
paramsCopy.set(lParam('result'), l('yes'));
|
|
107
109
|
break;
|
|
108
110
|
}
|
|
109
111
|
default: {
|
|
@@ -51,7 +51,7 @@ export class PluginsForWork {
|
|
|
51
51
|
onByDefault: onByDefaultDefault, lang: pluginLang, meta
|
|
52
52
|
}] = this.pluginsInWork[i];
|
|
53
53
|
const plugin = this.getPluginObject(pluginName);
|
|
54
|
-
cb({ // eslint-disable-line
|
|
54
|
+
cb({ // eslint-disable-line n/no-callback-literal
|
|
55
55
|
plugin,
|
|
56
56
|
placement,
|
|
57
57
|
applicableFields,
|
|
@@ -71,11 +71,11 @@ export class PluginsForWork {
|
|
|
71
71
|
}]) => {
|
|
72
72
|
if (Array.isArray(targetLanguage)) {
|
|
73
73
|
targetLanguage.forEach((targetLanguage) => {
|
|
74
|
-
cb({applicableField, targetLanguage, onByDefault, metaApplicableField}); // eslint-disable-line
|
|
74
|
+
cb({applicableField, targetLanguage, onByDefault, metaApplicableField}); // eslint-disable-line n/no-callback-literal
|
|
75
75
|
});
|
|
76
76
|
} else {
|
|
77
|
-
// eslint-disable-next-line
|
|
78
|
-
cb({applicableField, targetLanguage, onByDefault, metaApplicableField}); // eslint-disable-line
|
|
77
|
+
// eslint-disable-next-line n/callback-return
|
|
78
|
+
cb({applicableField, targetLanguage, onByDefault, metaApplicableField}); // eslint-disable-line n/no-callback-literal
|
|
79
79
|
}
|
|
80
80
|
});
|
|
81
81
|
return true;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {getJSON} from 'simple-get-json';
|
|
2
|
-
import {
|
|
2
|
+
import {i18n} from 'intl-dom';
|
|
3
3
|
import {getMetaProp, getMetadata, Metadata} from './Metadata.js';
|
|
4
4
|
import {PluginsForWork, escapePlugin} from './Plugin.js';
|
|
5
5
|
|
|
@@ -37,27 +37,42 @@ export const getWorkData = async function ({
|
|
|
37
37
|
languages, preferredLocale
|
|
38
38
|
}) {
|
|
39
39
|
const filesObj = await getJSON(files);
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
40
|
+
const localizationStrings = filesObj['localization-strings'];
|
|
41
|
+
|
|
42
|
+
const workI18n = await i18n({
|
|
43
|
+
messageStyle: 'plainNested',
|
|
44
|
+
locales: lang,
|
|
45
|
+
defaultLocales: fallbackLanguages,
|
|
46
|
+
// Todo: Could at least share this with `index.js`
|
|
47
|
+
localeStringFinder ({
|
|
48
|
+
locales, defaultLocales
|
|
49
|
+
}) {
|
|
50
|
+
const locale = [...locales, ...defaultLocales].find((language) => {
|
|
51
|
+
return language in localizationStrings;
|
|
52
|
+
});
|
|
53
|
+
return {
|
|
54
|
+
locale,
|
|
55
|
+
strings: {
|
|
56
|
+
head: {},
|
|
57
|
+
body: localizationStrings[locale]
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
}
|
|
45
61
|
});
|
|
46
|
-
const lf = imfFile.getFormatter();
|
|
47
62
|
|
|
48
63
|
let fileData;
|
|
49
64
|
const fileGroup = filesObj.groups.find((fg) => {
|
|
50
65
|
fileData = fg.files.find((file) =>
|
|
51
|
-
work ===
|
|
66
|
+
work === workI18n(['workNames', fg.id, file.name])
|
|
52
67
|
);
|
|
53
68
|
return Boolean(fileData);
|
|
54
69
|
});
|
|
55
70
|
// This is not specific to the work, but we export it anyways
|
|
56
71
|
const groupsToWorks = filesObj.groups.map((fg) => {
|
|
57
72
|
return {
|
|
58
|
-
name:
|
|
73
|
+
name: workI18n(fg.name.localeKey),
|
|
59
74
|
workNames: fg.files.map((file) => {
|
|
60
|
-
return
|
|
75
|
+
return workI18n(['workNames', fg.id, file.name]);
|
|
61
76
|
}),
|
|
62
77
|
shortcuts: fg.files.map((file) => file.shortcut)
|
|
63
78
|
};
|
|
@@ -191,7 +206,7 @@ export const getWorkData = async function ({
|
|
|
191
206
|
const fieldAliasOrName = plugin.getFieldAliasOrName
|
|
192
207
|
? plugin.getFieldAliasOrName({
|
|
193
208
|
locales: lang,
|
|
194
|
-
|
|
209
|
+
workI18n,
|
|
195
210
|
targetLanguage,
|
|
196
211
|
applicableField,
|
|
197
212
|
applicableFieldI18N,
|
|
@@ -202,7 +217,7 @@ export const getWorkData = async function ({
|
|
|
202
217
|
: languages.getFieldNameFromPluginNameAndLocales({
|
|
203
218
|
pluginName,
|
|
204
219
|
locales: lang,
|
|
205
|
-
|
|
220
|
+
workI18n,
|
|
206
221
|
targetLanguage,
|
|
207
222
|
applicableFieldI18N,
|
|
208
223
|
// Todo: Should have formal way to i18nize meta
|
|
@@ -239,7 +254,7 @@ export const getWorkData = async function ({
|
|
|
239
254
|
});
|
|
240
255
|
}
|
|
241
256
|
return {
|
|
242
|
-
fileData,
|
|
257
|
+
fileData, workI18n, getFieldAliasOrName, metadataObj,
|
|
243
258
|
schemaObj, schemaItems, fieldInfo,
|
|
244
259
|
pluginsForWork, groupsToWorks, metadata
|
|
245
260
|
};
|
|
@@ -21,7 +21,9 @@ class Dialog {
|
|
|
21
21
|
...localeObject
|
|
22
22
|
};
|
|
23
23
|
}
|
|
24
|
-
makeDialog ({atts = {
|
|
24
|
+
makeDialog ({atts = {
|
|
25
|
+
$on: null
|
|
26
|
+
}, children = [], close, remove = true}) {
|
|
25
27
|
if (close) {
|
|
26
28
|
if (!atts.$on) {
|
|
27
29
|
atts.$on = {};
|
|
@@ -30,7 +32,7 @@ class Dialog {
|
|
|
30
32
|
atts.$on.close = close;
|
|
31
33
|
}
|
|
32
34
|
}
|
|
33
|
-
const dialog = jml('dialog', atts, children, $('#main'));
|
|
35
|
+
const dialog = /** @type {HTMLDialogElement} */ (jml('dialog', atts, children, $('#main')));
|
|
34
36
|
dialog.showModal();
|
|
35
37
|
if (remove) {
|
|
36
38
|
dialog.addEventListener('close', () => {
|
|
@@ -93,7 +95,7 @@ class Dialog {
|
|
|
93
95
|
submitClass = 'submit'
|
|
94
96
|
} = message;
|
|
95
97
|
return new Promise((resolve, reject) => {
|
|
96
|
-
const dialog = jml('dialog', [
|
|
98
|
+
const dialog = /** @type {HTMLDialogElement} */ (jml('dialog', [
|
|
97
99
|
msg,
|
|
98
100
|
...(includeOk
|
|
99
101
|
? ([
|
|
@@ -106,7 +108,7 @@ class Dialog {
|
|
|
106
108
|
]]
|
|
107
109
|
])
|
|
108
110
|
: [])
|
|
109
|
-
], $('#main'));
|
|
111
|
+
], $('#main')));
|
|
110
112
|
dialog.showModal();
|
|
111
113
|
});
|
|
112
114
|
}
|
|
@@ -141,7 +143,7 @@ class Dialog {
|
|
|
141
143
|
message = typeof message === 'string' ? {message} : message;
|
|
142
144
|
const {message: msg, submitClass = 'submit'} = message;
|
|
143
145
|
return new Promise((resolve, reject) => {
|
|
144
|
-
const dialog = jml('dialog', [
|
|
146
|
+
const dialog = /** @type {HTMLDialogElement} */ (jml('dialog', [
|
|
145
147
|
msg,
|
|
146
148
|
['br'], ['br'],
|
|
147
149
|
['div', {class: submitClass}, [
|
|
@@ -155,7 +157,7 @@ class Dialog {
|
|
|
155
157
|
reject(new Error('cancelled'));
|
|
156
158
|
}}}, [this.localeStrings.cancel]]
|
|
157
159
|
]]
|
|
158
|
-
], $('#main'));
|
|
160
|
+
], $('#main')));
|
|
159
161
|
dialog.showModal();
|
|
160
162
|
});
|
|
161
163
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import {i18n} from 'intl-dom';
|
|
2
|
+
|
|
3
|
+
export default async function getLocaleFallbackResults ({
|
|
4
|
+
$p,
|
|
5
|
+
lang, langs, langData, fallbackLanguages,
|
|
6
|
+
basePath = ''
|
|
7
|
+
}) {
|
|
8
|
+
const l = await i18n({
|
|
9
|
+
messageStyle: 'plainNested',
|
|
10
|
+
locales: lang,
|
|
11
|
+
defaultLocales: fallbackLanguages,
|
|
12
|
+
localeResolver (localesBasePath, code) {
|
|
13
|
+
// Todo: For editing of locales, we might instead resolve all
|
|
14
|
+
// `$ref` (as with <https://github.com/whitlockjc/json-refs>) and
|
|
15
|
+
// replace `loadLocales` behavior with our own now resolved
|
|
16
|
+
// locales; see https://github.com/jdorn/json-editor/issues/132
|
|
17
|
+
return basePath + (langData.localeFileBasePath) + langs.find((l) =>
|
|
18
|
+
l.code === code
|
|
19
|
+
).locale.$ref;
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
if (!$p.l10n) {
|
|
23
|
+
$p.l10n = l;
|
|
24
|
+
}
|
|
25
|
+
return l;
|
|
26
|
+
}
|