From b367db4fd9c9f75d49615f220d2a6cb9321172b5 Mon Sep 17 00:00:00 2001 From: Miki Date: Tue, 8 Oct 2024 14:37:59 -0700 Subject: [PATCH 1/2] Implement correct normalization of locales in i18n Also: * Stop examining the fragment identifier for possible locale overrides Signed-off-by: Miki --- packages/osd-i18n/src/core/i18n.test.ts | 22 ++++-- packages/osd-i18n/src/core/i18n.ts | 22 +++++- packages/osd-i18n/src/loader.ts | 14 +++- .../public/application/scoped_history.test.ts | 60 ---------------- src/core/public/application/scoped_history.ts | 11 --- src/core/public/locale_helper.test.ts | 50 -------------- src/core/public/locale_helper.ts | 68 ------------------- src/core/public/osd_bootstrap.test.ts | 64 +---------------- src/core/public/osd_bootstrap.ts | 28 -------- .../rendering/rendering_service.test.ts | 43 ++++++++++++ .../server/rendering/rendering_service.tsx | 15 +++- src/legacy/ui/ui_render/ui_render_mixin.js | 10 +-- .../ui/ui_render/ui_render_mixin.test.js | 27 +++++--- 13 files changed, 128 insertions(+), 306 deletions(-) delete mode 100644 src/core/public/locale_helper.test.ts delete mode 100644 src/core/public/locale_helper.ts diff --git a/packages/osd-i18n/src/core/i18n.test.ts b/packages/osd-i18n/src/core/i18n.test.ts index ebfd546f8561..ad5ed920fd01 100644 --- a/packages/osd-i18n/src/core/i18n.test.ts +++ b/packages/osd-i18n/src/core/i18n.test.ts @@ -178,7 +178,7 @@ describe('I18n engine', () => { 'en-us' ); - expect(i18n.getLocale()).toBe('en-us'); + expect(i18n.getLocale()).toBe('en-US'); expect(i18n.getTranslation()).toEqual({ messages: { ['a.b.c']: 'bar', @@ -246,9 +246,19 @@ describe('I18n engine', () => { expect(i18n.getLocale()).toBe('foo'); }); - test('should normalize passed locale', () => { - i18n.setLocale('en-US'); - expect(i18n.getLocale()).toBe('en-us'); + test('should normalize basic locale', () => { + i18n.setLocale('It-iT'); + expect(i18n.getLocale()).toBe('it-IT'); + }); + + test('should normalize simple locale', () => { + i18n.setLocale('en-LATN-us_PRIVATE-variant'); + expect(i18n.getLocale()).toBe('en-Latn-US'); + }); + + test('should normalize complex locale', () => { + i18n.setLocale('FR-CA-X-FALLBACK-und-u@keyword=calendarKey'); + expect(i18n.getLocale()).toBe('fr-CA'); }); }); @@ -280,8 +290,8 @@ describe('I18n engine', () => { }); test('should normalize passed locale', () => { - i18n.setDefaultLocale('en-US'); - expect(i18n.getDefaultLocale()).toBe('en-us'); + i18n.setDefaultLocale('eN-uS'); + expect(i18n.getDefaultLocale()).toBe('en-US'); }); test('should set "en" locale as default for IntlMessageFormat and IntlRelativeFormat', () => { diff --git a/packages/osd-i18n/src/core/i18n.ts b/packages/osd-i18n/src/core/i18n.ts index 65da4931ef13..fc040bb834e6 100644 --- a/packages/osd-i18n/src/core/i18n.ts +++ b/packages/osd-i18n/src/core/i18n.ts @@ -44,6 +44,16 @@ const EN_LOCALE = 'en'; const translationsForLocale: Record = {}; const getMessageFormat = memoizeIntlConstructor(IntlMessageFormat); +/* A locale code is made of several components: + * * lang: The two- and three-letter lower-case language code follows the ISO 639-1 and ISO 639-2/3 standards, respectively. + * * script: The optional four-letter title-case code follows the ISO 15924 standard for representing writing systems. + * * region: The two-letter upper-case region code follows the ISO 3166-1 alpha-2 standard. + * + * Ref: https://www.rfc-editor.org/rfc/rfc5646.txt + * Note: While case carries no distinction with locale codes, proper formatting is recommended. + */ +const localeParser = /^(?[a-z]{2,3})(?:-(?