Skip to content

Commit bcd359d

Browse files
authored
wires up set application locale to web engine (flutter#177284)
<!-- Thanks for filing a pull request! Reviewers are typically assigned within a week of filing a request. To learn more about code review, see our documentation on Tree Hygiene: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md --> fixes flutter#98948 ## Pre-launch Checklist - [ ] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [ ] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [ ] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [ ] I signed the [CLA]. - [ ] I listed at least one issue that this PR fixes in the description above. - [ ] I updated/added relevant documentation (doc comments with `///`). - [ ] I added new tests to check the change I am making, or this PR is [test-exempt]. - [ ] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [ ] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. **Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
1 parent e43443b commit bcd359d

File tree

6 files changed

+51
-0
lines changed

6 files changed

+51
-0
lines changed

engine/src/flutter/lib/web_ui/lib/src/engine/platform_dispatcher.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -799,6 +799,13 @@ class EnginePlatformDispatcher extends ui.PlatformDispatcher {
799799
implicitView?.semantics.updateSemantics(update);
800800
}
801801

802+
@override
803+
void setApplicationLocale(ui.Locale locale) {
804+
for (final EngineFlutterView view in views) {
805+
view.setLocale(locale);
806+
}
807+
}
808+
802809
/// This is equivalent to `locales.first`, except that it will provide an
803810
/// undefined (using the language tag "und") non-null locale if the [locales]
804811
/// list has not been set or is empty.

engine/src/flutter/lib/web_ui/lib/src/engine/view_embedder/embedding_strategy/custom_element_embedding_strategy.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// found in the LICENSE file.
44

55
import 'package:ui/src/engine/dom.dart';
6+
import 'package:ui/ui.dart' as ui;
67

78
import '../hot_restart_cache_handler.dart' show registerElementForCleanup;
89
import 'embedding_strategy.dart';
@@ -27,6 +28,11 @@ class CustomElementEmbeddingStrategy implements EmbeddingStrategy {
2728
/// The root element of the Flutter view.
2829
late final DomElement _rootElement;
2930

31+
@override
32+
void setLocale(ui.Locale locale) {
33+
hostElement.setAttribute('lang', locale.toLanguageTag());
34+
}
35+
3036
@override
3137
void attachViewRoot(DomElement rootElement) {
3238
rootElement

engine/src/flutter/lib/web_ui/lib/src/engine/view_embedder/embedding_strategy/embedding_strategy.dart

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// found in the LICENSE file.
44

55
import 'package:ui/src/engine/dom.dart';
6+
import 'package:ui/ui.dart' as ui;
67

78
import 'custom_element_embedding_strategy.dart';
89
import 'full_page_embedding_strategy.dart';
@@ -26,6 +27,14 @@ abstract class EmbeddingStrategy {
2627
}
2728
}
2829

30+
/// Sets the locale for the embedded view.
31+
///
32+
/// This method is typically called by the Flutter framework after it has
33+
/// resolved the application's locale. It configures the embedded view to
34+
/// reflect the given locale, which is important for accessibility and for
35+
/// the browser to select appropriate fonts and other locale-specific resources.
36+
void setLocale(ui.Locale locale);
37+
2938
/// The DOM element in which the Flutter view is embedded.
3039
/// This element is the direct parent element of the <flutter-view> element.
3140
DomElement get hostElement;

engine/src/flutter/lib/web_ui/lib/src/engine/view_embedder/embedding_strategy/full_page_embedding_strategy.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import 'package:ui/src/engine/dom.dart';
66
import 'package:ui/src/engine/util.dart';
7+
import 'package:ui/ui.dart' as ui;
78

89
import '../hot_restart_cache_handler.dart' show registerElementForCleanup;
910
import 'embedding_strategy.dart';
@@ -25,6 +26,11 @@ class FullPageEmbeddingStrategy implements EmbeddingStrategy {
2526
@override
2627
DomEventTarget get globalEventTarget => domWindow;
2728

29+
@override
30+
void setLocale(ui.Locale locale) {
31+
domDocument.documentElement!.setAttribute('lang', locale.toLanguageTag());
32+
}
33+
2834
@override
2935
void attachViewRoot(DomElement rootElement) {
3036
/// Tweaks style so the rootElement works well with the hostElement.

engine/src/flutter/lib/web_ui/lib/src/engine/window.dart

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,16 @@ class EngineFlutterView implements ui.FlutterView {
131131
semantics.updateSemantics(update);
132132
}
133133

134+
/// Sets the locale for this view.
135+
///
136+
/// This method is typically called by the Flutter framework after it has
137+
/// resolved the application's locale. It configures the view to reflect
138+
/// the given locale, which is important for accessibility and for the
139+
/// browser.
140+
void setLocale(ui.Locale locale) {
141+
embeddingStrategy.setLocale(locale);
142+
}
143+
134144
late final GlobalHtmlAttributes _globalHtmlAttributes = GlobalHtmlAttributes(
135145
rootElement: dom.rootElement,
136146
hostElement: embeddingStrategy.hostElement,

engine/src/flutter/lib/web_ui/test/engine/platform_dispatcher/platform_dispatcher_test.dart

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,19 @@ void testMain() {
229229
expect(codec.decodeEnvelope(response!), true);
230230
});
231231

232+
test('can set application locale', () async {
233+
final DomElement host1 = createDomHTMLDivElement();
234+
final EngineFlutterView view1 = EngineFlutterView(dispatcher, host1);
235+
final EngineFlutterView view2 = EngineFlutterView.implicit(dispatcher, null);
236+
dispatcher.viewManager
237+
..registerView(view1)
238+
..registerView(view2);
239+
240+
dispatcher.setApplicationLocale(const ui.Locale('es', 'MX'));
241+
expect(host1.getAttribute('lang'), 'es-MX');
242+
expect(domDocument.querySelector('html')!.getAttribute('lang'), 'es-MX');
243+
});
244+
232245
test('can find text scale factor', () async {
233246
const double deltaTolerance = 1e-5;
234247

0 commit comments

Comments
 (0)