From 6d95dda02e1adba22134fc5f6da22bd855586d11 Mon Sep 17 00:00:00 2001 From: Greg Spencer Date: Thu, 19 Nov 2020 10:02:18 -0800 Subject: [PATCH 1/2] Fix PlatformDispatcher.locale to return something meaningful when there are no locales. --- lib/ui/platform_dispatcher.dart | 7 ++++--- lib/web_ui/lib/src/engine/platform_dispatcher.dart | 6 +++++- lib/web_ui/test/engine/window_test.dart | 1 + testing/dart/window_hooks_integration_test.dart | 12 ++++++++++++ 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/lib/ui/platform_dispatcher.dart b/lib/ui/platform_dispatcher.dart index a218b283e5d16..de4fe45a1f2dd 100644 --- a/lib/ui/platform_dispatcher.dart +++ b/lib/ui/platform_dispatcher.dart @@ -549,9 +549,10 @@ class PlatformDispatcher { /// This is the first locale selected by the user and is the user's primary /// locale (the locale the device UI is displayed in) /// - /// This is equivalent to `locales.first` and will provide an empty non-null - /// locale if the [locales] list has not been set or is empty. - Locale get locale => locales.first; + /// This is equivalent to `locales.first`, except that it will provide an + /// undefined (using the language tag "und") non-null locale if the [locales] + /// list has not been set or is empty. + Locale get locale => locales.isEmpty ? const Locale.fromSubtags() : locales.first; /// The full system-reported supported locales of the device. /// diff --git a/lib/web_ui/lib/src/engine/platform_dispatcher.dart b/lib/web_ui/lib/src/engine/platform_dispatcher.dart index 78e9124361b52..7f6ce039c5a5c 100644 --- a/lib/web_ui/lib/src/engine/platform_dispatcher.dart +++ b/lib/web_ui/lib/src/engine/platform_dispatcher.dart @@ -546,6 +546,10 @@ class EnginePlatformDispatcher extends ui.PlatformDispatcher { EngineSemanticsOwner.instance.updateSemantics(update); } + /// This is equivalent to `locales.first`, except that it will provide an + /// undefined (using the language tag "und") non-null locale if the [locales] + /// list has not been set or is empty. + /// /// We use the first locale in the [locales] list instead of the browser's /// built-in `navigator.language` because browsers do not agree on the /// implementation. @@ -554,7 +558,7 @@ class EnginePlatformDispatcher extends ui.PlatformDispatcher { /// /// * https://developer.mozilla.org/en-US/docs/Web/API/NavigatorLanguage/languages, /// which explains browser quirks in the implementation notes. - ui.Locale get locale => locales.first; + ui.Locale get locale => locales.isEmpty ? const ui.Locale.fromSubtags() : locales.first; /// The full system-reported supported locales of the device. /// diff --git a/lib/web_ui/test/engine/window_test.dart b/lib/web_ui/test/engine/window_test.dart index 04ae42243e402..6dc9497c04c54 100644 --- a/lib/web_ui/test/engine/window_test.dart +++ b/lib/web_ui/test/engine/window_test.dart @@ -292,6 +292,7 @@ void testMain() { // that the list is populated again). EnginePlatformDispatcher.instance.debugResetLocales(); expect(window.locales, isEmpty); + expect(window.locale, equals(const ui.Locale.fromSubtags())); expect(localeChangedCount, 0); html.window.dispatchEvent(html.Event('languagechange')); expect(window.locales, isNotEmpty); diff --git a/testing/dart/window_hooks_integration_test.dart b/testing/dart/window_hooks_integration_test.dart index 27b2da80d8e9a..eba61ce53abff 100644 --- a/testing/dart/window_hooks_integration_test.dart +++ b/testing/dart/window_hooks_integration_test.dart @@ -426,4 +426,16 @@ void main() { expectEquals(window.padding.bottom, 0.0); expectEquals(window.systemGestureInsets.bottom, 44.0); }); + + test('PlatformDispatcher.locale returns unknown locale when locales is set to empty list', () { + Locale? locale; + runZoned(() { + window.onLocaleChanged = () { + locale = PlatformDispatcher.instance.locale; + }; + }); + + _updateLocales([]); + expectEquals(locale, const Locale.fromSubtags()); + }); } From 29e77ba16dd94cda1f0ff08946ed9fbfb9116358 Mon Sep 17 00:00:00 2001 From: Greg Spencer Date: Fri, 20 Nov 2020 15:32:16 -0800 Subject: [PATCH 2/2] Review Changes --- lib/ui/platform_dispatcher.dart | 4 ++++ testing/dart/window_hooks_integration_test.dart | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/ui/platform_dispatcher.dart b/lib/ui/platform_dispatcher.dart index de4fe45a1f2dd..dc7223b79cc5d 100644 --- a/lib/ui/platform_dispatcher.dart +++ b/lib/ui/platform_dispatcher.dart @@ -1319,6 +1319,10 @@ class Locale { /// [region](https://github.com/unicode-org/cldr/blob/master/common/validity/region.xml) for /// each of languageCode, scriptCode and countryCode respectively. /// + /// The [languageCode] subtag is optional. When there is no language subtag, + /// the parameter should be omitted or set to "und". When not supplied, the + /// [languageCode] defaults to "und", an undefined language code. + /// /// The [countryCode] subtag is optional. When there is no country subtag, /// the parameter should be omitted or passed `null` instead of an empty-string. /// diff --git a/testing/dart/window_hooks_integration_test.dart b/testing/dart/window_hooks_integration_test.dart index eba61ce53abff..91c2036dbda91 100644 --- a/testing/dart/window_hooks_integration_test.dart +++ b/testing/dart/window_hooks_integration_test.dart @@ -428,7 +428,7 @@ void main() { }); test('PlatformDispatcher.locale returns unknown locale when locales is set to empty list', () { - Locale? locale; + late Locale locale; runZoned(() { window.onLocaleChanged = () { locale = PlatformDispatcher.instance.locale; @@ -437,5 +437,6 @@ void main() { _updateLocales([]); expectEquals(locale, const Locale.fromSubtags()); + expectEquals(locale.languageCode, 'und'); }); }