From c1e96f79e23a907c6f3e911d7413d4847c647335 Mon Sep 17 00:00:00 2001 From: Joren Broekema Date: Tue, 20 Aug 2019 11:50:03 +0200 Subject: [PATCH] chore(localize): deprecate language-only locales --- packages/input-email/stories/index.stories.js | 2 +- packages/localize/RATIONALE.md | 2 ++ packages/localize/README.md | 2 ++ packages/localize/src/LocalizeManager.js | 8 ++++++++ .../localize/test/LocalizeManager.test.js | 19 +++++++++++++++++++ .../localize/test/date/formatDate.test.js | 2 +- 6 files changed, 33 insertions(+), 2 deletions(-) diff --git a/packages/input-email/stories/index.stories.js b/packages/input-email/stories/index.stories.js index 7afe548d7..2cf9e9741 100644 --- a/packages/input-email/stories/index.stories.js +++ b/packages/input-email/stories/index.stories.js @@ -19,7 +19,7 @@ storiesOf('Forms|Input Email', module) ) .add('Use own validator', () => { const gmailOnly = modelValue => ({ gmailOnly: modelValue.indexOf('gmail.com') !== -1 }); - localize.locale = 'en'; + localize.locale = 'en-GB'; try { localize.addData('en', 'lion-validate+gmailOnly', { diff --git a/packages/localize/RATIONALE.md b/packages/localize/RATIONALE.md index 19746fb8d..dbd19d3fe 100644 --- a/packages/localize/RATIONALE.md +++ b/packages/localize/RATIONALE.md @@ -46,6 +46,8 @@ We chose `Intl MessageFormat` as a format for translation parts because: ### Fallbacks +> Important: language-only locales are now deprecated, and cause a warning. This is because language only locales cause bugs with date and number formatting. It also makes writing locale based tooling harder and more cumbersome. Usage is highly discouraged. + We decided to have a fallback mechanism in case a dialect (e.g. `nl-NL.js`) is not defined, but generic language (e.g. `nl.js`) is, because we wanted to support legacy applications which used [Polymer's AppLocalizeBehavior](https://polymer-library.polymer-project.org/3.0/docs/apps/localize) and could not instantly switch to using full dialects. We decided to have a fallback locale (`en-GB` by default): diff --git a/packages/localize/README.md b/packages/localize/README.md index 312a02735..d673e2593 100644 --- a/packages/localize/README.md +++ b/packages/localize/README.md @@ -177,6 +177,8 @@ Due to the need to develop application code with not everything translated (yet) By default the fallback is `en-GB`, meaning that if some namespace does not have data for the current page locale, the `en-GB` will be loaded, making it an important foundation for all other locales data. In addition to that the fallback is a necessary mechanism to allow some features of the browsers like Google Chrome translate to work and use the same original data for translations into all not officially supported languages. +> We highly discourage using fallback locales as a user, because it is bug-prone with things like date and number formatting. Please use full locales whenever possible. + ### Rendering data When all necessary data are loaded and you want to show localized content on the page you need to format the data. diff --git a/packages/localize/src/LocalizeManager.js b/packages/localize/src/LocalizeManager.js index b6ac25a34..938322c20 100644 --- a/packages/localize/src/LocalizeManager.js +++ b/packages/localize/src/LocalizeManager.js @@ -42,6 +42,14 @@ export class LocalizeManager extends LionSingleton { document.documentElement.lang = value; this._setupHtmlLangAttributeObserver(); + if (!value.includes('-')) { + console.warn(` + Locale was set to ${value}. + Language only locales are deprecated, please use the full language locale e.g. 'en-GB' instead of 'en'. + See https://github.com/ing-bank/lion/issues/187 for more information. + `); + } + this._onLocaleChanged(value, oldLocale); } diff --git a/packages/localize/test/LocalizeManager.test.js b/packages/localize/test/LocalizeManager.test.js index 8f494bde2..48fef29c5 100644 --- a/packages/localize/test/LocalizeManager.test.js +++ b/packages/localize/test/LocalizeManager.test.js @@ -302,6 +302,25 @@ describe('LocalizeManager', () => { throw new Error('did not throw'); }); + + it('throws a warning if the locale set by the user is not a full language locale', async () => { + const spy = sinon.spy(console, 'warn'); + manager = new LocalizeManager(); + manager.locale = 'nl'; + + expect(spy.callCount).to.equal(1); + console.warn.restore(); + }); + + it('does not throw a warning if locale was set through the html lang attribute', async () => { + const spy = sinon.spy(console, 'warn'); + manager = new LocalizeManager(); + document.documentElement.lang = 'nl'; + await aTimeout(50); // wait for mutation observer to be called + + expect(spy.callCount).to.equal(0); + console.warn.restore(); + }); }); }); diff --git a/packages/localize/test/date/formatDate.test.js b/packages/localize/test/date/formatDate.test.js index 1acb2a62b..e0d68de1c 100644 --- a/packages/localize/test/date/formatDate.test.js +++ b/packages/localize/test/date/formatDate.test.js @@ -56,7 +56,7 @@ describe('formatDate', () => { day: '2-digit', locale: 'en-US', }; - localize.locale = 'bg'; + localize.locale = 'bg-BG'; let date = parseDate('29-12-2017'); expect(formatDate(date)).to.equal('29.12.2017 г.');