@docpensieve/shared 0.5.0-beta.1 → 0.5.0-beta.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@docpensieve/shared",
3
- "version": "0.5.0-beta.1",
3
+ "version": "0.5.0-beta.2",
4
4
  "description": "Utilities, constants and errors shared by the DocPensieve packages",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/ui-strings.js CHANGED
@@ -176,3 +176,45 @@ export function textDirection(lang) {
176
176
  return 'ltr';
177
177
  }
178
178
  }
179
+
180
+ /**
181
+ * Whether a string names a language, as BCP 47 and CLDR understand it.
182
+ *
183
+ * The standard is BCP 47, and `Intl` carries it: a regex of our own refused
184
+ * `zh-Hans-CN`, which is valid, and accepted shapes that are not. Well formed
185
+ * is not the same as real, though — BCP 47 allows a language subtag of five
186
+ * to eight letters, so `francais` passes that check and would land in the
187
+ * markup as `lang="francais"`, a value no browser maps to a language. CLDR
188
+ * knows which tags name one; the subtag alone is asked, so that a region, a
189
+ * script or a private extension does not get in the way.
190
+ *
191
+ * @param {string} value
192
+ * @returns {boolean}
193
+ */
194
+ export function isLanguageCode(value) {
195
+ try {
196
+ Intl.getCanonicalLocales(value);
197
+ const names = new Intl.DisplayNames(['en'], { type: 'language', fallback: 'none' });
198
+ return names.of(new Intl.Locale(value).language) !== undefined;
199
+ } catch {
200
+ return false;
201
+ }
202
+ }
203
+
204
+ /**
205
+ * Name of a language, written in a language.
206
+ *
207
+ * @param {string} code Language code.
208
+ * @param {string} [inLang] Language the name is written in.
209
+ * @returns {string} The name, or the code itself when nothing names it.
210
+ */
211
+ export function languageName(code, inLang = DEFAULT_LANGUAGE) {
212
+ try {
213
+ // The default fallback returns the code itself rather than nothing, so
214
+ // `?? code` only answers to the type: `of` is declared as possibly
215
+ // undefined, which it is only with `fallback: 'none'`.
216
+ return new Intl.DisplayNames([inLang], { type: 'language' }).of(code) ?? code;
217
+ } catch {
218
+ return code;
219
+ }
220
+ }
@@ -194,3 +194,26 @@ export declare function pageCount(count: number, strings: UiStrings, lang?: stri
194
194
  * default, and what every page did before this existed.
195
195
  */
196
196
  export declare function textDirection(lang?: string): 'ltr' | 'rtl';
197
+ /**
198
+ * Whether a string names a language, as BCP 47 and CLDR understand it.
199
+ *
200
+ * The standard is BCP 47, and `Intl` carries it: a regex of our own refused
201
+ * `zh-Hans-CN`, which is valid, and accepted shapes that are not. Well formed
202
+ * is not the same as real, though — BCP 47 allows a language subtag of five
203
+ * to eight letters, so `francais` passes that check and would land in the
204
+ * markup as `lang="francais"`, a value no browser maps to a language. CLDR
205
+ * knows which tags name one; the subtag alone is asked, so that a region, a
206
+ * script or a private extension does not get in the way.
207
+ *
208
+ * @param {string} value
209
+ * @returns {boolean}
210
+ */
211
+ export declare function isLanguageCode(value: string): boolean;
212
+ /**
213
+ * Name of a language, written in a language.
214
+ *
215
+ * @param {string} code Language code.
216
+ * @param {string} [inLang] Language the name is written in.
217
+ * @returns {string} The name, or the code itself when nothing names it.
218
+ */
219
+ export declare function languageName(code: string, inLang?: string): string;