From d2ad4419bb07ef4ee7bd401c1c3e0d6fd6187127 Mon Sep 17 00:00:00 2001 From: Greg Spencer Date: Tue, 1 Dec 2020 09:54:56 -0800 Subject: [PATCH] Fix PlatformDispatcher.locale to return something meaningful when there are no locales. (#22608) Returns an "undefined" locale (language code "und") from PlatformDispatcher.locale when no locales are defined. --- lib/ui/platform_dispatcher.dart | 11 ++++++++--- 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 | 13 +++++++++++++ 4 files changed, 27 insertions(+), 4 deletions(-) diff --git a/lib/ui/platform_dispatcher.dart b/lib/ui/platform_dispatcher.dart index a218b283e..dc7223b79 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. /// @@ -1318,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/lib/web_ui/lib/src/engine/platform_dispatcher.dart b/lib/web_ui/lib/src/engine/platform_dispatcher.dart index 78e912436..7f6ce039c 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 04ae42243..6dc9497c0 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 27b2da80d..91c2036db 100644 --- a/testing/dart/window_hooks_integration_test.dart +++ b/testing/dart/window_hooks_integration_test.dart @@ -426,4 +426,17 @@ 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', () { + late Locale locale; + runZoned(() { + window.onLocaleChanged = () { + locale = PlatformDispatcher.instance.locale; + }; + }); + + _updateLocales([]); + expectEquals(locale, const Locale.fromSubtags()); + expectEquals(locale.languageCode, 'und'); + }); } -- GitLab