Make the App's title optional on web (#152003)
Title (in web) results in updating the [title element][1] which is a global property. This is problematic in embedded and multiview modes as title should be managed by host apps. This PR makes the title optional, hence if not provided it won't result in the website title being updated.
This commit is contained in:
parent
b7997cba54
commit
af834eed23
@ -166,7 +166,7 @@ class CupertinoApp extends StatefulWidget {
|
|||||||
this.onNavigationNotification,
|
this.onNavigationNotification,
|
||||||
List<NavigatorObserver> this.navigatorObservers = const <NavigatorObserver>[],
|
List<NavigatorObserver> this.navigatorObservers = const <NavigatorObserver>[],
|
||||||
this.builder,
|
this.builder,
|
||||||
this.title = '',
|
this.title,
|
||||||
this.onGenerateTitle,
|
this.onGenerateTitle,
|
||||||
this.color,
|
this.color,
|
||||||
this.locale,
|
this.locale,
|
||||||
@ -207,7 +207,7 @@ class CupertinoApp extends StatefulWidget {
|
|||||||
this.routerConfig,
|
this.routerConfig,
|
||||||
this.theme,
|
this.theme,
|
||||||
this.builder,
|
this.builder,
|
||||||
this.title = '',
|
this.title,
|
||||||
this.onGenerateTitle,
|
this.onGenerateTitle,
|
||||||
this.onNavigationNotification,
|
this.onNavigationNotification,
|
||||||
this.color,
|
this.color,
|
||||||
@ -303,7 +303,7 @@ class CupertinoApp extends StatefulWidget {
|
|||||||
/// {@macro flutter.widgets.widgetsApp.title}
|
/// {@macro flutter.widgets.widgetsApp.title}
|
||||||
///
|
///
|
||||||
/// This value is passed unmodified to [WidgetsApp.title].
|
/// This value is passed unmodified to [WidgetsApp.title].
|
||||||
final String title;
|
final String? title;
|
||||||
|
|
||||||
/// {@macro flutter.widgets.widgetsApp.onGenerateTitle}
|
/// {@macro flutter.widgets.widgetsApp.onGenerateTitle}
|
||||||
///
|
///
|
||||||
|
@ -275,7 +275,7 @@ class MaterialApp extends StatefulWidget {
|
|||||||
this.routerConfig,
|
this.routerConfig,
|
||||||
this.backButtonDispatcher,
|
this.backButtonDispatcher,
|
||||||
this.builder,
|
this.builder,
|
||||||
this.title = '',
|
this.title,
|
||||||
this.onGenerateTitle,
|
this.onGenerateTitle,
|
||||||
this.onNavigationNotification,
|
this.onNavigationNotification,
|
||||||
this.color,
|
this.color,
|
||||||
@ -386,7 +386,7 @@ class MaterialApp extends StatefulWidget {
|
|||||||
/// {@macro flutter.widgets.widgetsApp.title}
|
/// {@macro flutter.widgets.widgetsApp.title}
|
||||||
///
|
///
|
||||||
/// This value is passed unmodified to [WidgetsApp.title].
|
/// This value is passed unmodified to [WidgetsApp.title].
|
||||||
final String title;
|
final String? title;
|
||||||
|
|
||||||
/// {@macro flutter.widgets.widgetsApp.onGenerateTitle}
|
/// {@macro flutter.widgets.widgetsApp.onGenerateTitle}
|
||||||
///
|
///
|
||||||
|
@ -328,7 +328,7 @@ class WidgetsApp extends StatefulWidget {
|
|||||||
this.home,
|
this.home,
|
||||||
Map<String, WidgetBuilder> this.routes = const <String, WidgetBuilder>{},
|
Map<String, WidgetBuilder> this.routes = const <String, WidgetBuilder>{},
|
||||||
this.builder,
|
this.builder,
|
||||||
this.title = '',
|
this.title,
|
||||||
this.onGenerateTitle,
|
this.onGenerateTitle,
|
||||||
this.textStyle,
|
this.textStyle,
|
||||||
required this.color,
|
required this.color,
|
||||||
@ -425,7 +425,7 @@ class WidgetsApp extends StatefulWidget {
|
|||||||
this.routerConfig,
|
this.routerConfig,
|
||||||
this.backButtonDispatcher,
|
this.backButtonDispatcher,
|
||||||
this.builder,
|
this.builder,
|
||||||
this.title = '',
|
this.title,
|
||||||
this.onGenerateTitle,
|
this.onGenerateTitle,
|
||||||
this.onNavigationNotification,
|
this.onNavigationNotification,
|
||||||
this.textStyle,
|
this.textStyle,
|
||||||
@ -828,7 +828,7 @@ class WidgetsApp extends StatefulWidget {
|
|||||||
///
|
///
|
||||||
/// To provide a localized title instead, use [onGenerateTitle].
|
/// To provide a localized title instead, use [onGenerateTitle].
|
||||||
/// {@endtemplate}
|
/// {@endtemplate}
|
||||||
final String title;
|
final String? title;
|
||||||
|
|
||||||
/// {@template flutter.widgets.widgetsApp.onGenerateTitle}
|
/// {@template flutter.widgets.widgetsApp.onGenerateTitle}
|
||||||
/// If non-null this callback function is called to produce the app's
|
/// If non-null this callback function is called to produce the app's
|
||||||
@ -1771,7 +1771,7 @@ class _WidgetsAppState extends State<WidgetsApp> with WidgetsBindingObserver {
|
|||||||
return true;
|
return true;
|
||||||
}());
|
}());
|
||||||
|
|
||||||
final Widget title;
|
final Widget? title;
|
||||||
if (widget.onGenerateTitle != null) {
|
if (widget.onGenerateTitle != null) {
|
||||||
title = Builder(
|
title = Builder(
|
||||||
// This Builder exists to provide a context below the Localizations widget.
|
// This Builder exists to provide a context below the Localizations widget.
|
||||||
@ -1786,9 +1786,14 @@ class _WidgetsAppState extends State<WidgetsApp> with WidgetsBindingObserver {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
} else if (widget.title == null && kIsWeb) {
|
||||||
|
// Updating the <title /> element in the DOM is problematic in embedded
|
||||||
|
// and multiview modes as title should be managed by host apps.
|
||||||
|
// Refer to https://github.com/flutter/flutter/pull/152003 for more info.
|
||||||
|
title = null;
|
||||||
} else {
|
} else {
|
||||||
title = Title(
|
title = Title(
|
||||||
title: widget.title,
|
title: widget.title ?? '',
|
||||||
color: widget.color.withOpacity(1.0),
|
color: widget.color.withOpacity(1.0),
|
||||||
child: result,
|
child: result,
|
||||||
);
|
);
|
||||||
@ -1823,7 +1828,7 @@ class _WidgetsAppState extends State<WidgetsApp> with WidgetsBindingObserver {
|
|||||||
child: Localizations(
|
child: Localizations(
|
||||||
locale: appLocale,
|
locale: appLocale,
|
||||||
delegates: _localizationsDelegates.toList(),
|
delegates: _localizationsDelegates.toList(),
|
||||||
child: title,
|
child: title ?? result,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -70,6 +70,7 @@ void main() {
|
|||||||
);
|
);
|
||||||
await tester.pumpWidget(const CupertinoApp(
|
await tester.pumpWidget(const CupertinoApp(
|
||||||
theme: CupertinoThemeData(brightness: Brightness.light),
|
theme: CupertinoThemeData(brightness: Brightness.light),
|
||||||
|
title: '',
|
||||||
color: dynamicColor,
|
color: dynamicColor,
|
||||||
home: Placeholder(),
|
home: Placeholder(),
|
||||||
));
|
));
|
||||||
@ -79,6 +80,7 @@ void main() {
|
|||||||
await tester.pumpWidget(const CupertinoApp(
|
await tester.pumpWidget(const CupertinoApp(
|
||||||
theme: CupertinoThemeData(brightness: Brightness.dark),
|
theme: CupertinoThemeData(brightness: Brightness.dark),
|
||||||
color: dynamicColor,
|
color: dynamicColor,
|
||||||
|
title: '',
|
||||||
home: Placeholder(),
|
home: Placeholder(),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -153,6 +153,17 @@ void main() {
|
|||||||
expect(checked, isTrue);
|
expect(checked, isTrue);
|
||||||
}, variant: KeySimulatorTransitModeVariant.all());
|
}, variant: KeySimulatorTransitModeVariant.all());
|
||||||
|
|
||||||
|
testWidgets('Title is not created if title is not passed and kIsweb', (WidgetTester tester) async {
|
||||||
|
await tester.pumpWidget(
|
||||||
|
WidgetsApp(
|
||||||
|
color: const Color(0xFF123456),
|
||||||
|
builder: (BuildContext context, Widget? child) => Container(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(find.byType(Title), kIsWeb ? findsNothing : findsOneWidget);
|
||||||
|
});
|
||||||
|
|
||||||
group('error control test', () {
|
group('error control test', () {
|
||||||
Future<void> expectFlutterError({
|
Future<void> expectFlutterError({
|
||||||
required GlobalKey<NavigatorState> key,
|
required GlobalKey<NavigatorState> key,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user