textbrowser 0.46.2 → 0.47.0-beta.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/.eslintignore CHANGED
@@ -1,3 +1,3 @@
1
- files-to-incorporate-and-delete
2
1
  node_modules
3
2
  dist
3
+ resources/vendor
package/.eslintrc.cjs CHANGED
@@ -64,7 +64,7 @@ module.exports = {
64
64
  }
65
65
  }, {
66
66
  files: ['test/index.html'],
67
- extends: ['ash-nazg/sauron-node-script-overrides'],
67
+ extends: ['ash-nazg/sauron-node-overrides'],
68
68
  globals: {
69
69
  mocha: false
70
70
  },
@@ -73,7 +73,7 @@ module.exports = {
73
73
  }
74
74
  }, {
75
75
  files: ['test/textbrowserTests.js'],
76
- extends: ['ash-nazg/sauron-node-script-overrides']
76
+ extends: ['ash-nazg/sauron-node-overrides']
77
77
  }, {
78
78
  files: ['server/**', 'resources/utils/WorkInfo.js'],
79
79
  globals: {
package/CHANGES.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # CHANGES to `textbrowser`
2
2
 
3
+ ## 0.47.0 (beta 0)
4
+
5
+ - BREAKING fix: drop schemas now moved to textbrowser-data-schemas
6
+ - fix: adjust paths per new expected locations
7
+
8
+ ## 0.46.3
9
+
10
+ - fix: update `intl-dom` (affecting fallbacks for non-English locales)
11
+
3
12
  ## 0.46.2
4
13
 
5
14
  - fix: ensure `fetch` is set on server for locale retrieval for `/textbrowser`
package/README.md CHANGED
@@ -153,19 +153,6 @@ Run the following from your project root.
153
153
  npm install textbrowser --save
154
154
  ```
155
155
 
156
- You can also target the latest code in `master` with the following:
157
-
158
- ```json
159
- "dependencies": {
160
- "textbrowser": "git@github.com:brettz9/textbrowser.git#master"
161
- }
162
- ```
163
-
164
- And then run `npm install` on your project path.
165
-
166
- (To update, you can remove `node_modules/textbrowser/` from your project
167
- and reinstall.)
168
-
169
156
  ## Usage
170
157
 
171
158
  The following instructions are aimed at those adding *TextBrowser* as a
@@ -173,8 +160,9 @@ dependency of their own project.
173
160
 
174
161
  If you would like to see a sample package implementing the
175
162
  following, see the
176
- [bahaiwritings](https://bitbucket.org/brettz9/bahaiwritings)
177
- project.
163
+ [bahai-browser](https://github.com/bahaidev/bahai-browser)
164
+ project or for a project just implementing the JSON files, see
165
+ [bahaiwritings](https://github.com/bahaidev/bahaiwritings).
178
166
 
179
167
  Projects derivative to *TextBrowser* will need to adhere to the following:
180
168
 
@@ -269,128 +257,8 @@ more cumbersome though standards-track
269
257
 
270
258
  ### Work-Specific JSON
271
259
 
272
- JSON data files, the individual JSON schema file against which the data
273
- file can be validated (and enhanced in a standard manner with type
274
- information), and our custom JSON metadata format file for indicating
275
- information such as designating fields for browsing ranges, are covered
276
- in this section.
277
-
278
- #### JSON Data
279
-
280
- JSON data files to represent your data (e.g.,
281
- [this file](https://bitbucket.org/brettz9/bahaiwritings/src/6b07fb41d11ed76570f7da03ffc9d11aa8ff0a5d/data/writings/peace.json?at=master&fileviewer=file-view-default))
282
- expect 3 fields (per the simple
283
- [schema](https://github.com/brettz9/textbrowser/blob/master/general-schemas/table-container.jsonschema)
284
- and its simple
285
- [array-of-arrays subschema](https://github.com/brettz9/textbrowser/blob/master/general-schemas/array-of-arrays.jsonschema)
286
- to which they adhere):
287
-
288
- 1. A `schema` JSON reference pointer to your data's JSON schema.
289
- See [JSON Schema](#json-schema).
290
- 2. A `metadata` JSON reference pointer to your data's JSON metadata.
291
- See [JSON Metadata](#json-metadata).
292
- 3. A `data` property which is an an array of arrays containing your tabular
293
- text itself. This property must adhere to the specific JSON schema
294
- referenced in the `schema` property above for this file.
295
-
296
- #### JSON Schema
297
-
298
- This document must itself be a valid
299
- [JSON Schema](http://json-schema.org/documentation.html)
300
- and must, moreover, adhere to the
301
- [table format schema](https://github.com/brettz9/textbrowser/blob/master/general-schemas/table.jsonschema).
302
-
303
- This simple document, besides including the text content, designates a more precise JSON schema to indicate precise column types (e.g.,
304
- [this one](https://bitbucket.org/brettz9/bahaiwritings/src/6b07fb41d11ed76570f7da03ffc9d11aa8ff0a5d/data/writings/schemas/Bible.jsonschema?at=master&fileviewer=file-view-default)).
305
-
306
- This schema is expected to designate an array of arrays, with the items
307
- of the inner arrays being more flexible JSON schemas representing individual
308
- fields of your works, but expecting a `type` and `title` in all cases.
309
-
310
- It may, for integers, optionally also have `minimum` and `maximum` properties
311
- which can be used to set numeric inputs (assuming the min or max is not
312
- dependent on another value, as often will be paragraph numbers within
313
- chapters).
314
-
315
- For strings, an optional `"format": "html"` can be present, though raw HTML in
316
- the so-designated fields will only be output in the results display as HTML
317
- if the `TextBrowser` option `trustFormatHTML` is set to `true`. This
318
- is for security reasons in case an untrusted schema is being deployed, but
319
- one will probably normally wish to set this to `true` for trusted data.
320
-
321
- Also for string type fields may one use `enum`, and its values are
322
- currently used to determine field values (looking in the metadata
323
- file under the localized `fieldvalue` object whose key is the column in which
324
- the value occurs) which are used in place of the original content within
325
- pull-down menus for selecting verse ranges and in the corresponding
326
- column for the field of the results display. (The `fieldvalue-aliases`
327
- property of the specific field key of the main `fields` property will
328
- also be checked in that file for indicating optional aliases of the given
329
- field value.)
330
-
331
- #### JSON Metadata
332
-
333
- [Meta-data JSON](https://github.com/brettz9/textbrowser/blob/master/general-schemas/metadata.jsonschema) (e.g.,
334
- [this one](https://bitbucket.org/brettz9/bahaiwritings/src/6b07fb41d11ed76570f7da03ffc9d11aa8ff0a5d/data/writings/metadata/Bible.metadata?at=master&fileviewer=file-view-default))
335
- is required so as for you to indicate for the app how the multilinear text
336
- is to be browsed (e.g., which fields can be used as sequential
337
- chapter/paragraph/verse numbers, how its columns should be translated, etc.).
338
-
339
- This file has two main properties, `table` and `fields`.
340
-
341
- `table` has two properties, `browse_fields` and `default_view`.
342
-
343
- `browse_fields` is a name-set object or an array of string field names or
344
- name-set objects. Name-set objects have an optional `name` string, a `set`
345
- array of field name strings, and an optional `presort` boolean to
346
- indicate whether the table must first sort the elements (in order of
347
- listing); the default is to follow the original array order.
348
-
349
- The keys of `default_view` are field names which point to a string or
350
- integer, or array thereof. These are *not currently in use*, but are intended
351
- to indicate the values that will be used for a default range when a user makes
352
- a form submission without supplying a range.
353
-
354
- For `fields`, the `lang` string property indicates the language code for the
355
- content of this field. It is used for letting the user quickly enable
356
- fields which match their desired locale language(s). It is also used for
357
- setting HTML table column `lang` values to properly display fonts for
358
- languages that leverage it, such as the CJK languages.
359
-
360
- One other set of types for `fields` are `name` and `alias` strings (or
361
- `localeKey` pointing to strings). The `name` points to the regular
362
- name for the column, whereas `alias` is currently used to point to an
363
- alias name of the field (more specifically to an alternate name after
364
- converting its values via `fieldvalue-aliases`). The boolean or string
365
- `prefer_alias` property in turn determines whether this alias will be
366
- used by default (currently if it is `false`, it is not used at all).
367
- This functionality might be moved into a plug-in in the future.
368
-
369
- Also in `fields`, `fieldvalue-aliases` can after any `localeKey` processing,
370
- be an object of field name keys pointing to an array of alias names (as
371
- strings or integers) or to an object whose keys indicating the type of
372
- alias and string values. This can provide alternate values for what is
373
- actually present in the data table (e.g., replacing numeric codes with
374
- human-readable strings).
375
-
376
- For `fields`, the `primary_text_field` and `orig_lang_field` booleans
377
- and `orig_langs` array of string language codes are *not currently in use*
378
- but intended to indicate the main work under consideration (as opposed
379
- to translations), whether it is the source of translations or a target
380
- translation, and what its source languages are (if not itself marked as
381
- an original language).
382
-
383
- The `roman` property of `fields` is intended to indicate Roman numerals.
384
- It is *not currently in use* and where not automated from Arabic numerals,
385
- it might be indicated in the future via a language code and more generic
386
- `numeric` property (so as to support multiple non-Arabic counting systems
387
- which are hard-coded as opposed to built via an automated plug-in).
388
-
389
- As with other files, there is also a `localization-strings` key object, keyed
390
- to language code, which is keyed to an object of keys (which can be strings
391
- (e.g., `heading` or `alias`), arrays of strings, or other objects of keys,
392
- including specifically for JSON metadata, `fieldnames`, `fieldaliases`,
393
- `fieldvalue`, and `fieldvalue-aliases`).
260
+ The specific works adhere to particular schemas. See [textbrowser-data-schemas](https://github.com/bahaidev/textbrowser-data-schemas).
261
+ for more details.
394
262
 
395
263
  ### Application-wide JSON files
396
264
 
@@ -400,8 +268,9 @@ whole.
400
268
 
401
269
  #### `files.json`
402
270
 
403
- This format is defined by [this](https://github.com/brettz9/textbrowser/blob/master/general-schemas/files.jsonschema).
404
- See [this file](https://bitbucket.org/brettz9/bahaiwritings/src/5f2602f122134d2013e013a477ae94ee29548a13/files.json?at=master&fileviewer=file-view-default) for an example.
271
+ This format is defined by [this](https://github.com/bahaidev/textbrowser/blob/main/general-schemas/files.jsonschema).
272
+ See [this file](https://github.com/bahaidev/bahai-browser/blob/main/files.json)
273
+ for an example.
405
274
 
406
275
  It allows you to point the application to the data files you desire for
407
276
  inclusion (e.g., any kept in `data/`).
@@ -419,7 +288,7 @@ a `name` string or localization key (or a file group display name),
419
288
  `schemaFile` and `metadataFile` string file paths (resolved relative to the
420
289
  respective base path properties), and `file` which is an reference to a
421
290
  specific JSON data file
422
- [table-container.jsonschema](https://github.com/brettz9/textbrowser/blob/master/general-schemas/table-container.jsonschema)).
291
+ [table-container.jsonschema](https://github.com/bahaidev/textbrowser-data-schemas/blob/main/schemas/table-container.jsonschema)).
423
292
  There can also be a `shortcut` property which is used for indicating the
424
293
  keyword to use when the "Generate bookmarks" button in Preferences or
425
294
  "Copy shortcut URL" is used to build URL keyword shortcuts (what Chrome
@@ -467,8 +336,8 @@ localization, you may supply a `languages` property when creating the
467
336
  choosing (see the [JavaScript API](#javascript-api)).
468
337
 
469
338
  *TextBrowser* comes with the `languages.json` file at
470
- [`appdata/languages.json`](https://github.com/brettz9/textbrowser/blob/master/appdata/languages.json) which, as mentioned, is used by default. It adheres to
471
- [this schema](https://github.com/brettz9/textbrowser/blob/master/general-schemas/languages.jsonschema)
339
+ [`appdata/languages.json`](https://github.com/bahaidev/textbrowser/blob/main/appdata/languages.json) which, as mentioned, is used by default. It adheres to
340
+ [this schema](https://github.com/bahaidev/textbrowser/blob/main/general-schemas/languages.jsonschema)
472
341
 
473
342
  If you need to implement your own, the properties include the string
474
343
  `localeFileBasePath` and the property `languages` which is an array
@@ -481,7 +350,8 @@ arrays of strings, or other objects of keys).
481
350
 
482
351
  The locale files referenced by the `locale` property within `languages.json`
483
352
  (by default, those at `locales/`, e.g., `locales/en-US.json`), adhere to
484
- [this schema](https://github.com/brettz9/textbrowser/blob/master/general-schemas/locale.jsonschema).
353
+ [this schema](https://github.com/bahaidev/textbrowser-data-schemas/blob/main/schemas/locale.jsonschema).
354
+ This schema is also used for localization within metadata files. See [textbrowser-data-schemas](https://github.com/bahaidev/textbrowser-data-schemas).
485
355
 
486
356
  Locales are an object of keys (which may be strings, arrays of strings, or
487
357
  are themselves objects).
@@ -733,6 +603,8 @@ The properties are:
733
603
  recommended files:
734
604
  `['/', 'index.html', 'files.json', 'site.json', 'resources/user.js']`
735
605
 
606
+ This user JSON follows the [user-json schema](https://github.com/bahaidev/textbrowser-data-schemas/blob/main/schemas/user-json.jsonschema).
607
+
736
608
  ## Server API
737
609
 
738
610
  The `textbrowser` server API offers the same arguments as the `TextBrowser`
@@ -965,7 +837,7 @@ it supports the following arguments:
965
837
  put it as a mouseover)
966
838
  1. Allow for dynamic addition of JSON overlay sources or metadata
967
839
  to work selection/work display files?
968
- 1. See bahaiwritings project re: using Firefox's
840
+ 1. See bahai-browser project re: using Firefox's
969
841
  [Browser API](https://developer.mozilla.org/en-US/docs/Web/API/Using_the_Browser_API)
970
842
  to allow independent navigation controls for each iframe (and
971
843
  side-by-side viewing of verses/lines and commentary)
@@ -1123,18 +995,13 @@ it supports the following arguments:
1123
995
 
1124
996
  ## To-dos (Lower priority)
1125
997
 
1126
- 1. Use or publish [rollup-plugin-postprocess](git+https://github.com/brettz9/rollup-plugin-postprocess.git#update)
1127
- as stable version?
1128
- 1. Check if still getting superagent warning:
1129
- <https://github.com/whitlockjc/path-loader/issues/17> (if `json-refs` can
1130
- be updated to stable version)
1131
998
  1. Use [i18nizeElement](https://github.com/brettz9/i18nizeElement)? (probably
1132
999
  not as need RTL detection for more than setting on element)
1133
1000
  1. **Remember columns enabled**, etc. since last visit, and/or saved as
1134
1001
  preferences.
1135
1002
  1. Allow copy-pasting a search as a custom web protocol (make
1136
1003
  site-configurable), e.g., to support `web+bahaiwritings:` links per
1137
- [bahai-writings-handler](https://github.com/brettz9/bahai-writings-handler)
1004
+ [bahai-writings-handler](https://github.com/bahaidev/bahai-writings-handler)
1138
1005
  ([demo](https://bahai-library.com/test-bahai-web-protocol/test-bahai-web-protocol.html));
1139
1006
  could even use last visit or preferences status to tweak the resulting
1140
1007
  appearance, column selection, etc.
@@ -1185,7 +1052,7 @@ npm test
1185
1052
  ```
1186
1053
 
1187
1054
  Note, however, that much of testing will depend on a particular
1188
- application. The [bahaiwritings](https://bitbucket.org/brettz9/bahaiwritings/)
1055
+ application. The [bahai-browser](https://github.com/bahaidev/bahai-browser)
1189
1056
  project hosts validation of specific files expected by TextBrowser, such as
1190
1057
  `files.json` and specific schemas and meta-data files needed for that project.
1191
1058
 
@@ -223,7 +223,7 @@ let nodeFetch;
223
223
  * @returns {getJSONCallback}
224
224
  */
225
225
 
226
- function _invoke(body, then) {
226
+ function _invoke$2(body, then) {
227
227
  var result = body();
228
228
 
229
229
  if (result && result.then) {
@@ -264,11 +264,11 @@ function buildGetJSON({
264
264
  baseURL,
265
265
  cwd: basePath
266
266
  } = {}) {
267
- const _fetch = typeof fetch !== 'undefined' ? fetch : _async$2(function (jsonURL) {
267
+ const _fetch = typeof window !== 'undefined' ? window.fetch : _async$2(function (jsonURL) {
268
268
  let _exit = false;
269
- return _invoke(function () {
269
+ return _invoke$2(function () {
270
270
  if (/^https?:/u.test(jsonURL)) {
271
- return _invoke(function () {
271
+ return _invoke$2(function () {
272
272
  if (!nodeFetch) {
273
273
  return _await$3(import('node-fetch'), function (_import) {
274
274
  nodeFetch = _import;
@@ -282,10 +282,10 @@ function buildGetJSON({
282
282
  });
283
283
  }
284
284
  }, function (_result) {
285
- return _exit ? _result : _invoke(function () {
285
+ return _exit ? _result : _invoke$2(function () {
286
286
  if (!basePath) {
287
287
  return _call(setDirname, function () {
288
- basePath = baseURL ? getDirectoryForURL(baseURL) : typeof fetch === 'undefined' && process.cwd();
288
+ basePath = baseURL ? getDirectoryForURL(baseURL) : typeof window === 'undefined' && process.cwd();
289
289
  });
290
290
  }
291
291
  }, function () {
@@ -2083,9 +2083,7 @@ var getStringFromMessageAndDefaults = function getStringFromMessageAndDefaults()
2083
2083
  } else if (defaults === false || defaults === undefined || defaults === null) {
2084
2084
  str = false;
2085
2085
  } else if (defaults && _typeof(defaults) === 'object') {
2086
- str = messageForKey({
2087
- body: defaults
2088
- }, key);
2086
+ str = messageForKey(defaults, key);
2089
2087
  if (str) {
2090
2088
  str = str.value;
2091
2089
  }
@@ -2369,7 +2367,7 @@ var _findLocale = _async(function (_ref4) {
2369
2367
  } else if (typeof localeMatcher !== 'function') {
2370
2368
  throw new TypeError('`localeMatcher` must be "lookup" or a function!');
2371
2369
  }
2372
- return promiseChainForValues([].concat(_toConsumableArray(locales), _toConsumableArray(defaultLocales)), getLocale, 'No matching locale found!');
2370
+ return promiseChainForValues([].concat(_toConsumableArray(locales), _toConsumableArray(defaultLocales)), getLocale, 'No matching locale found for ' + [].concat(_toConsumableArray(locales), _toConsumableArray(defaultLocales)).join(', '));
2373
2371
  });
2374
2372
 
2375
2373
  /**
@@ -2440,6 +2438,14 @@ function _await(value, then, direct) {
2440
2438
  * @param {boolean} [cfg.throwOnExtraSuppliedFormatters=true]
2441
2439
  * @returns {Promise<I18NCallback>} Rejects if no suitable locale is found.
2442
2440
  */
2441
+
2442
+ function _invoke(body, then) {
2443
+ var result = body();
2444
+ if (result && result.then) {
2445
+ return result.then(then);
2446
+ }
2447
+ return then(result);
2448
+ }
2443
2449
  var i18nServer = function i18nServer(_ref) {
2444
2450
  var strings = _ref.strings,
2445
2451
  resolvedLocale = _ref.resolvedLocale,
@@ -2555,20 +2561,39 @@ var i18n = function i18n() {
2555
2561
  }), function (_ref4) {
2556
2562
  var strings = _ref4.strings,
2557
2563
  resolvedLocale = _ref4.locale;
2558
- return i18nServer({
2559
- strings: strings,
2560
- resolvedLocale: resolvedLocale,
2561
- messageStyle: messageStyle,
2562
- allSubstitutions: allSubstitutions,
2563
- insertNodes: insertNodes,
2564
- keyCheckerConverter: keyCheckerConverter,
2565
- defaults: defaults,
2566
- substitutions: substitutions,
2567
- maximumLocalNestingDepth: maximumLocalNestingDepth,
2568
- dom: dom,
2569
- forceNodeReturn: forceNodeReturn,
2570
- throwOnMissingSuppliedFormatters: throwOnMissingSuppliedFormatters,
2571
- throwOnExtraSuppliedFormatters: throwOnExtraSuppliedFormatters
2564
+ return _invoke(function () {
2565
+ if (!defaults && defaultLocales) {
2566
+ var defaultLocale;
2567
+ return _await(localeStringFinder({
2568
+ locales: defaultLocales,
2569
+ defaultLocales: [],
2570
+ localeResolver: localeResolver,
2571
+ localesBasePath: localesBasePath,
2572
+ localeMatcher: localeMatcher
2573
+ }), function (_localeStringFinder) {
2574
+ defaults = _localeStringFinder.strings;
2575
+ defaultLocale = _localeStringFinder.locale;
2576
+ if (defaultLocale === resolvedLocale) {
2577
+ defaults = null; // No need to fall back
2578
+ }
2579
+ });
2580
+ }
2581
+ }, function () {
2582
+ return i18nServer({
2583
+ strings: strings,
2584
+ resolvedLocale: resolvedLocale,
2585
+ messageStyle: messageStyle,
2586
+ allSubstitutions: allSubstitutions,
2587
+ insertNodes: insertNodes,
2588
+ keyCheckerConverter: keyCheckerConverter,
2589
+ defaults: defaults,
2590
+ substitutions: substitutions,
2591
+ maximumLocalNestingDepth: maximumLocalNestingDepth,
2592
+ dom: dom,
2593
+ forceNodeReturn: forceNodeReturn,
2594
+ throwOnMissingSuppliedFormatters: throwOnMissingSuppliedFormatters,
2595
+ throwOnExtraSuppliedFormatters: throwOnExtraSuppliedFormatters
2596
+ });
2572
2597
  });
2573
2598
  });
2574
2599
  } catch (e) {
package/dist/index-es.js CHANGED
@@ -259,7 +259,7 @@ let nodeFetch;
259
259
  * @returns {getJSONCallback}
260
260
  */
261
261
 
262
- function _invoke(body, then) {
262
+ function _invoke$2(body, then) {
263
263
  var result = body();
264
264
  if (result && result.then) {
265
265
  return result.then(then);
@@ -293,11 +293,11 @@ function buildGetJSON({
293
293
  baseURL,
294
294
  cwd: basePath
295
295
  } = {}) {
296
- const _fetch = typeof fetch !== 'undefined' ? fetch : _async$2(function (jsonURL) {
296
+ const _fetch = typeof window !== 'undefined' ? window.fetch : _async$2(function (jsonURL) {
297
297
  let _exit = false;
298
- return _invoke(function () {
298
+ return _invoke$2(function () {
299
299
  if (/^https?:/u.test(jsonURL)) {
300
- return _invoke(function () {
300
+ return _invoke$2(function () {
301
301
  if (!nodeFetch) {
302
302
  return _await$3(import('node-fetch'), function (_import) {
303
303
  nodeFetch = _import;
@@ -310,10 +310,10 @@ function buildGetJSON({
310
310
  });
311
311
  }
312
312
  }, function (_result) {
313
- return _exit ? _result : _invoke(function () {
313
+ return _exit ? _result : _invoke$2(function () {
314
314
  if (!basePath) {
315
315
  return _call(setDirname, function () {
316
- basePath = baseURL ? getDirectoryForURL(baseURL) : typeof fetch === 'undefined' && process.cwd();
316
+ basePath = baseURL ? getDirectoryForURL(baseURL) : typeof window === 'undefined' && process.cwd();
317
317
  });
318
318
  }
319
319
  }, function () {
@@ -2106,9 +2106,7 @@ var getStringFromMessageAndDefaults = function getStringFromMessageAndDefaults()
2106
2106
  } else if (defaults === false || defaults === undefined || defaults === null) {
2107
2107
  str = false;
2108
2108
  } else if (defaults && _typeof$1(defaults) === 'object') {
2109
- str = messageForKey({
2110
- body: defaults
2111
- }, key);
2109
+ str = messageForKey(defaults, key);
2112
2110
  if (str) {
2113
2111
  str = str.value;
2114
2112
  }
@@ -2391,7 +2389,7 @@ var _findLocale = _async(function (_ref4) {
2391
2389
  } else if (typeof localeMatcher !== 'function') {
2392
2390
  throw new TypeError('`localeMatcher` must be "lookup" or a function!');
2393
2391
  }
2394
- return promiseChainForValues([].concat(_toConsumableArray$1(locales), _toConsumableArray$1(defaultLocales)), getLocale, 'No matching locale found!');
2392
+ return promiseChainForValues([].concat(_toConsumableArray$1(locales), _toConsumableArray$1(defaultLocales)), getLocale, 'No matching locale found for ' + [].concat(_toConsumableArray$1(locales), _toConsumableArray$1(defaultLocales)).join(', '));
2395
2393
  });
2396
2394
 
2397
2395
  /**
@@ -2462,6 +2460,14 @@ function _await(value, then, direct) {
2462
2460
  * @param {boolean} [cfg.throwOnExtraSuppliedFormatters=true]
2463
2461
  * @returns {Promise<I18NCallback>} Rejects if no suitable locale is found.
2464
2462
  */
2463
+
2464
+ function _invoke(body, then) {
2465
+ var result = body();
2466
+ if (result && result.then) {
2467
+ return result.then(then);
2468
+ }
2469
+ return then(result);
2470
+ }
2465
2471
  var i18nServer = function i18nServer(_ref) {
2466
2472
  var strings = _ref.strings,
2467
2473
  resolvedLocale = _ref.resolvedLocale,
@@ -2577,20 +2583,39 @@ var i18n = function i18n() {
2577
2583
  }), function (_ref4) {
2578
2584
  var strings = _ref4.strings,
2579
2585
  resolvedLocale = _ref4.locale;
2580
- return i18nServer({
2581
- strings: strings,
2582
- resolvedLocale: resolvedLocale,
2583
- messageStyle: messageStyle,
2584
- allSubstitutions: allSubstitutions,
2585
- insertNodes: insertNodes,
2586
- keyCheckerConverter: keyCheckerConverter,
2587
- defaults: defaults,
2588
- substitutions: substitutions,
2589
- maximumLocalNestingDepth: maximumLocalNestingDepth,
2590
- dom: dom,
2591
- forceNodeReturn: forceNodeReturn,
2592
- throwOnMissingSuppliedFormatters: throwOnMissingSuppliedFormatters,
2593
- throwOnExtraSuppliedFormatters: throwOnExtraSuppliedFormatters
2586
+ return _invoke(function () {
2587
+ if (!defaults && defaultLocales) {
2588
+ var defaultLocale;
2589
+ return _await(localeStringFinder({
2590
+ locales: defaultLocales,
2591
+ defaultLocales: [],
2592
+ localeResolver: localeResolver,
2593
+ localesBasePath: localesBasePath,
2594
+ localeMatcher: localeMatcher
2595
+ }), function (_localeStringFinder) {
2596
+ defaults = _localeStringFinder.strings;
2597
+ defaultLocale = _localeStringFinder.locale;
2598
+ if (defaultLocale === resolvedLocale) {
2599
+ defaults = null; // No need to fall back
2600
+ }
2601
+ });
2602
+ }
2603
+ }, function () {
2604
+ return i18nServer({
2605
+ strings: strings,
2606
+ resolvedLocale: resolvedLocale,
2607
+ messageStyle: messageStyle,
2608
+ allSubstitutions: allSubstitutions,
2609
+ insertNodes: insertNodes,
2610
+ keyCheckerConverter: keyCheckerConverter,
2611
+ defaults: defaults,
2612
+ substitutions: substitutions,
2613
+ maximumLocalNestingDepth: maximumLocalNestingDepth,
2614
+ dom: dom,
2615
+ forceNodeReturn: forceNodeReturn,
2616
+ throwOnMissingSuppliedFormatters: throwOnMissingSuppliedFormatters,
2617
+ throwOnExtraSuppliedFormatters: throwOnExtraSuppliedFormatters
2618
+ });
2594
2619
  });
2595
2620
  });
2596
2621
  } catch (e) {