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.
@@ -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, lf, getNextAlias, $p, followParams}) => {
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
- lf({key: group.directions.localeKey, fallback: true})
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: lf(['workNames', group.id, fileName])
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') {
@@ -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
- })();
@@ -2,7 +2,7 @@
2
2
  *
3
3
  * @param {string} param
4
4
  * @param {boolean} skip
5
- * @this IntlURLSearchParams
5
+ * @this {IntlURLSearchParams}
6
6
  * @returns {string}
7
7
  */
8
8
  function _prepareParam (param, skip) {
@@ -24,22 +24,27 @@ export class Languages {
24
24
  constructor ({langData}) {
25
25
  this.langData = langData;
26
26
  }
27
- localeFromLangData (lan) {
28
- return this.langData['localization-strings'][lan];
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, lf, targetLanguage, applicableFieldI18N, meta, metaApplicableField
36
+ pluginName, locales, workI18n, targetLanguage, applicableFieldI18N, meta, metaApplicableField
35
37
  }) {
36
- return lf(['plugins', pluginName, 'fieldname'], {
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
- fieldName: getFieldAliasOrName(field)
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', [ld(browseFieldObject.name)]]]]
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 node/no-callback-literal
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, il, $p}) {
18
- return function ({form, random = {}, checkboxes, type, fieldAliasOrNames = [], workName}) {
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(il('rand'));
28
- paramsCopy.set(il('rand'), random.checked ? l('yes') : l('no'));
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(il('rand'));
65
+ paramsCopy.delete(lParam('rand'));
64
66
  break;
65
67
  }
66
68
  case 'shortcutResult': {
67
- paramsCopy.delete(il('rand'));
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(il('rand'));
104
- paramsCopy.set(il('rand'), l('yes'));
105
+ paramsCopy.delete(lParam('rand'));
106
+ paramsCopy.set(lParam('rand'), l('yes'));
105
107
  }
106
- paramsCopy.set(il('result'), l('yes'));
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 node/no-callback-literal
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 node/no-callback-literal
74
+ cb({applicableField, targetLanguage, onByDefault, metaApplicableField}); // eslint-disable-line n/no-callback-literal
75
75
  });
76
76
  } else {
77
- // eslint-disable-next-line node/callback-return
78
- cb({applicableField, targetLanguage, onByDefault, metaApplicableField}); // eslint-disable-line node/no-callback-literal
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 {IMF} from 'imf';
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 localeFromFileData = (lan) =>
41
- filesObj['localization-strings'][lan];
42
- const imfFile = IMF({
43
- locales: lang.map(localeFromFileData),
44
- fallbackLocales: fallbackLanguages.map(localeFromFileData)
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 === lf(['workNames', fg.id, file.name])
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: lf({key: fg.name.localeKey, fallback: true}),
73
+ name: workI18n(fg.name.localeKey),
59
74
  workNames: fg.files.map((file) => {
60
- return lf(['workNames', fg.id, file.name]);
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
- lf,
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
- lf,
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, lf, getFieldAliasOrName, metadataObj,
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 = {}, children = [], close, remove = true}) {
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
+ }