mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[web] Unify JS configuration. Make it available from initEngine. (flutter/engine#37187)
* Add the 'windows' parameter to the initializeEngine function. * Wire the initEngine configuration into the engine. * Extend configuration.dart * Reuse JsFlutterConfiguration JS-interop as the configuration source both for initEngine, and the window.flutterConfig object. * Add 'renderer' and 'targetElement' fields to the JsFlutterConfiguration object. * Modify the `FlutterConfiguration` object so that it supports more than one configuration source. Return the first non-null value that was most recently set, or fall back to a default. * Silence bootstrap initialization log to debug level. * targetElement to hostElement * jsParams -> runtimeConfiguration * Add configuration_test.dart * Add test to check init stores config. * Renamed test so it actually runs. * Update configuration object. Make it throwy at init/override. * Use new config object, tweak some docs. * Tweak warn/assert messages. * Some renaming: * runtimeConfig -> configuration (as unnamed function parameter) * runtimeConfiguration -> jsConfiguration (as named function parameter, to prevent clashes with the configuration singleton in the engine code) * initEngine -> initializeEngine (because no need to abbreviate that) * Ensure init test does not use global config. * Sort JsFlutterConfiguration getters alphabetically. * Addresses PR comments.
This commit is contained in:
parent
e815cda497
commit
0710f7aeee
@ -66,8 +66,8 @@ Future<void> webOnlyWarmupEngine({
|
||||
}) async {
|
||||
// Create the object that knows how to bootstrap an app from JS and Dart.
|
||||
final engine.AppBootstrap bootstrap = engine.AppBootstrap(
|
||||
initEngine: () async {
|
||||
await engine.initializeEngineServices();
|
||||
initializeEngine: ([engine.JsFlutterConfiguration? configuration]) async {
|
||||
await engine.initializeEngineServices(jsConfiguration: configuration);
|
||||
}, runApp: () async {
|
||||
if (registerPlugins != null) {
|
||||
registerPlugins();
|
||||
@ -86,11 +86,11 @@ Future<void> webOnlyWarmupEngine({
|
||||
}
|
||||
if (autoStart) {
|
||||
// The user does not want control of the app, bootstrap immediately.
|
||||
print('Flutter Web Bootstrap: Auto');
|
||||
engine.domWindow.console.debug('Flutter Web Bootstrap: Auto.');
|
||||
await bootstrap.autoStart();
|
||||
} else {
|
||||
// Yield control of the bootstrap procedure to the user.
|
||||
print('Flutter Web Bootstrap: Programmatic');
|
||||
engine.domWindow.console.debug('Flutter Web Bootstrap: Programmatic.');
|
||||
engine.didCreateEngineInitializer!(bootstrap.prepareEngineInitializer());
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,28 +4,33 @@
|
||||
|
||||
import 'package:js/js.dart';
|
||||
|
||||
import 'configuration.dart';
|
||||
import 'js_interop/js_loader.dart';
|
||||
import 'js_interop/js_promise.dart';
|
||||
|
||||
/// The type of a function that initializes an engine (in Dart).
|
||||
typedef InitEngineFn = Future<void> Function([JsFlutterConfiguration? params]);
|
||||
|
||||
/// A class that controls the coarse lifecycle of a Flutter app.
|
||||
class AppBootstrap {
|
||||
/// Construct a FlutterLoader
|
||||
AppBootstrap({required Function initEngine, required Function runApp}) :
|
||||
_initEngine = initEngine, _runApp = runApp;
|
||||
/// Construct an AppBootstrap.
|
||||
AppBootstrap({required InitEngineFn initializeEngine, required Function runApp}) :
|
||||
_initializeEngine = initializeEngine, _runApp = runApp;
|
||||
|
||||
// TODO(dit): Be more strict with the below typedefs, so we can add incoming params for each function.
|
||||
// A function to initialize the engine.
|
||||
final InitEngineFn _initializeEngine;
|
||||
|
||||
// A function to initialize the engine
|
||||
final Function _initEngine;
|
||||
|
||||
// A function to run the app
|
||||
// A function to run the app.
|
||||
//
|
||||
// TODO(dit): Be more strict with the typedef of this function, so we can add
|
||||
// typed params to the function. (See InitEngineFn).
|
||||
final Function _runApp;
|
||||
|
||||
/// Immediately bootstraps the app.
|
||||
///
|
||||
/// This calls `initEngine` and `runApp` in succession.
|
||||
Future<void> autoStart() async {
|
||||
await _initEngine();
|
||||
await _initializeEngine();
|
||||
await _runApp();
|
||||
}
|
||||
|
||||
@ -47,15 +52,14 @@ class AppBootstrap {
|
||||
}),
|
||||
// Calls [_initEngine], and returns a JS Promise that resolves to an
|
||||
// app runner object.
|
||||
initializeEngine: allowInterop(([InitializeEngineFnParameters? params]) {
|
||||
initializeEngine: allowInterop(([JsFlutterConfiguration? configuration]) {
|
||||
// `params` coming from Javascript may be used to configure the engine intialization.
|
||||
// The internal `initEngine` function must accept those params, and then this
|
||||
// code needs to be slightly modified to pass them to the initEngine call below.
|
||||
// The internal `initEngine` function must accept those params.
|
||||
return Promise<FlutterAppRunner>(allowInterop((
|
||||
PromiseResolver<FlutterAppRunner> resolve,
|
||||
PromiseRejecter _,
|
||||
) async {
|
||||
await _initEngine();
|
||||
await _initializeEngine(configuration);
|
||||
// Return an app runner object
|
||||
resolve(_prepareAppRunner());
|
||||
}));
|
||||
|
||||
@ -5,29 +5,48 @@
|
||||
/// JavaScript API a Flutter Web application can use to configure the Web
|
||||
/// Engine.
|
||||
///
|
||||
/// The configuration is a plain JavaScript object set as the
|
||||
/// `flutterConfiguration` property of the top-level `window` object.
|
||||
/// The configuration is passed from JavaScript to the engine as part of the
|
||||
/// bootstrap process, through the `FlutterEngineInitializer.initializeEngine`
|
||||
/// JS method, with an (optional) object of type [JsFlutterConfiguration].
|
||||
///
|
||||
/// This library also supports the legacy method of setting a plain JavaScript
|
||||
/// object set as the `flutterConfiguration` property of the top-level `window`
|
||||
/// object, but that approach is now deprecated and will warn users.
|
||||
///
|
||||
/// Both methods are **disallowed** to be used at the same time.
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/// <head>
|
||||
/// <script>
|
||||
/// window.flutterConfiguration = {
|
||||
/// canvasKitBaseUrl: "https://example.com/my-custom-canvaskit/"
|
||||
/// };
|
||||
/// </script>
|
||||
/// </head>
|
||||
/// _flutter.loader.loadEntrypoint({
|
||||
/// // ...
|
||||
/// onEntrypointLoaded: async function(engineInitializer) {
|
||||
/// let appRunner = await engineInitializer.initializeEngine({
|
||||
/// // JsFlutterConfiguration goes here...
|
||||
/// canvasKitBaseUrl: "https://example.com/my-custom-canvaskit/",
|
||||
/// });
|
||||
/// appRunner.runApp();
|
||||
/// }
|
||||
/// });
|
||||
///
|
||||
/// Configuration properties supplied via `window.flutterConfiguration`
|
||||
/// override those supplied using the corresponding environment variables. For
|
||||
/// example, if both `window.flutterConfiguration.canvasKitBaseUrl` and the
|
||||
/// `FLUTTER_WEB_CANVASKIT_URL` environment variables are provided,
|
||||
/// `window.flutterConfiguration.canvasKitBaseUrl` is used.
|
||||
/// Example of the **deprecated** style (this will issue a JS console warning!):
|
||||
///
|
||||
/// <script>
|
||||
/// window.flutterConfiguration = {
|
||||
/// canvasKitBaseUrl: "https://example.com/my-custom-canvaskit/"
|
||||
/// };
|
||||
/// </script>
|
||||
///
|
||||
/// Configuration properties supplied via this object override those supplied
|
||||
/// using the corresponding environment variables. For example, if both the
|
||||
/// `canvasKitBaseUrl` config entry and the `FLUTTER_WEB_CANVASKIT_URL`
|
||||
/// environment variables are provided, the `canvasKitBaseUrl` entry is used.
|
||||
|
||||
@JS()
|
||||
library configuration;
|
||||
|
||||
import 'package:js/js.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
import 'dom.dart';
|
||||
|
||||
/// The version of CanvasKit used by the web engine by default.
|
||||
// DO NOT EDIT THE NEXT LINE OF CODE MANUALLY
|
||||
@ -35,7 +54,8 @@ import 'package:js/js.dart';
|
||||
const String _canvaskitVersion = '0.37.0';
|
||||
|
||||
/// The Web Engine configuration for the current application.
|
||||
FlutterConfiguration get configuration => _configuration ??= FlutterConfiguration(_jsConfiguration);
|
||||
FlutterConfiguration get configuration =>
|
||||
_configuration ??= FlutterConfiguration.legacy(_jsConfiguration);
|
||||
FlutterConfiguration? _configuration;
|
||||
|
||||
/// Sets the given configuration as the current one.
|
||||
@ -43,22 +63,71 @@ FlutterConfiguration? _configuration;
|
||||
/// This must be called before the engine is initialized. Calling it after the
|
||||
/// engine is initialized will result in some of the properties not taking
|
||||
/// effect because they are consumed during initialization.
|
||||
@visibleForTesting
|
||||
void debugSetConfiguration(FlutterConfiguration configuration) {
|
||||
_configuration = configuration;
|
||||
}
|
||||
|
||||
/// Supplies Web Engine configuration properties.
|
||||
class FlutterConfiguration {
|
||||
/// Constructs a configuration from a JavaScript object containing
|
||||
/// runtime-supplied properties.
|
||||
FlutterConfiguration(this._js);
|
||||
/// Constructs an unitialized configuration object.
|
||||
@visibleForTesting
|
||||
FlutterConfiguration();
|
||||
|
||||
final JsFlutterConfiguration? _js;
|
||||
/// Constucts a "tainted by JS globals" configuration object.
|
||||
///
|
||||
/// This configuration style is deprecated. It will warn the user about the
|
||||
/// new API (if used)
|
||||
FlutterConfiguration.legacy(JsFlutterConfiguration? config) {
|
||||
if (config != null) {
|
||||
_usedLegacyConfigStyle = true;
|
||||
_configuration = config;
|
||||
}
|
||||
// Warn the user of the deprecated behavior.
|
||||
assert(() {
|
||||
if (config != null) {
|
||||
domWindow.console.warn('window.flutterConfiguration is now deprecated.\n'
|
||||
'Use engineInitializer.initializeEngine(config) instead.\n'
|
||||
'See: https://docs.flutter.dev/development/platform-integration/web/initialization');
|
||||
}
|
||||
if (_requestedRendererType != null) {
|
||||
domWindow.console.warn('window.flutterWebRenderer is now deprecated.\n'
|
||||
'Use engineInitializer.initializeEngine(config) instead.\n'
|
||||
'See: https://docs.flutter.dev/development/platform-integration/web/initialization');
|
||||
}
|
||||
return true;
|
||||
}());
|
||||
}
|
||||
|
||||
bool _usedLegacyConfigStyle = false;
|
||||
JsFlutterConfiguration? _configuration;
|
||||
|
||||
/// Sets a value for [_configuration].
|
||||
///
|
||||
/// This method is called by the engine initialization process, through the
|
||||
/// [initEngineServices] method.
|
||||
///
|
||||
/// This method throws an AssertionError, if the _configuration object has
|
||||
/// been set to anything non-null through the [FlutterConfiguration.legacy]
|
||||
/// constructor.
|
||||
void setUserConfiguration(JsFlutterConfiguration? configuration) {
|
||||
if (configuration != null) {
|
||||
assert(!_usedLegacyConfigStyle,
|
||||
'Use engineInitializer.initializeEngine(config) only. '
|
||||
'Using the (deprecated) window.flutterConfiguration and initializeEngine '
|
||||
'configuration simultaneously is not supported.');
|
||||
assert(_requestedRendererType == null || configuration.renderer == null,
|
||||
'Use engineInitializer.initializeEngine(config) only. '
|
||||
'Using the (deprecated) window.flutterWebRenderer and initializeEngine '
|
||||
'configuration simultaneously is not supported.');
|
||||
_configuration = configuration;
|
||||
}
|
||||
}
|
||||
|
||||
// Static constant parameters.
|
||||
//
|
||||
// These properties affect tree shaking and therefore cannot be supplied at
|
||||
// runtime. They must be static constants for the compiler to remove dead
|
||||
// runtime. They must be static constants for the compiler to remove dead code
|
||||
// effectively.
|
||||
|
||||
/// Auto detect which rendering backend to use.
|
||||
@ -110,7 +179,7 @@ class FlutterConfiguration {
|
||||
/// --web-renderer=canvaskit \
|
||||
/// --dart-define=FLUTTER_WEB_CANVASKIT_URL=https://example.com/custom-canvaskit-build/
|
||||
/// ```
|
||||
String get canvasKitBaseUrl => _js?.canvasKitBaseUrl ?? _defaultCanvasKitBaseUrl;
|
||||
String get canvasKitBaseUrl => _configuration?.canvasKitBaseUrl ?? _defaultCanvasKitBaseUrl;
|
||||
static const String _defaultCanvasKitBaseUrl = String.fromEnvironment(
|
||||
'FLUTTER_WEB_CANVASKIT_URL',
|
||||
defaultValue: 'https://unpkg.com/canvaskit-wasm@$_canvaskitVersion/bin/',
|
||||
@ -121,7 +190,7 @@ class FlutterConfiguration {
|
||||
///
|
||||
/// This is mainly used for testing or for apps that want to ensure they
|
||||
/// run on devices which don't support WebGL.
|
||||
bool get canvasKitForceCpuOnly => _js?.canvasKitForceCpuOnly ?? _defaultCanvasKitForceCpuOnly;
|
||||
bool get canvasKitForceCpuOnly => _configuration?.canvasKitForceCpuOnly ?? _defaultCanvasKitForceCpuOnly;
|
||||
static const bool _defaultCanvasKitForceCpuOnly = bool.fromEnvironment(
|
||||
'FLUTTER_WEB_CANVASKIT_FORCE_CPU_ONLY',
|
||||
);
|
||||
@ -135,7 +204,7 @@ class FlutterConfiguration {
|
||||
///
|
||||
/// This value can be specified using either the `FLUTTER_WEB_MAXIMUM_SURFACES`
|
||||
/// environment variable, or using the runtime configuration.
|
||||
int get canvasKitMaximumSurfaces => _js?.canvasKitMaximumSurfaces ?? _defaultCanvasKitMaximumSurfaces;
|
||||
int get canvasKitMaximumSurfaces => _configuration?.canvasKitMaximumSurfaces ?? _defaultCanvasKitMaximumSurfaces;
|
||||
static const int _defaultCanvasKitMaximumSurfaces = int.fromEnvironment(
|
||||
'FLUTTER_WEB_MAXIMUM_SURFACES',
|
||||
defaultValue: 8,
|
||||
@ -152,10 +221,23 @@ class FlutterConfiguration {
|
||||
/// ```
|
||||
/// flutter run -d chrome --profile --dart-define=FLUTTER_WEB_DEBUG_SHOW_SEMANTICS=true
|
||||
/// ```
|
||||
bool get debugShowSemanticsNodes => _js?.debugShowSemanticsNodes ?? _defaultDebugShowSemanticsNodes;
|
||||
bool get debugShowSemanticsNodes => _configuration?.debugShowSemanticsNodes ?? _defaultDebugShowSemanticsNodes;
|
||||
static const bool _defaultDebugShowSemanticsNodes = bool.fromEnvironment(
|
||||
'FLUTTER_WEB_DEBUG_SHOW_SEMANTICS',
|
||||
);
|
||||
|
||||
/// Returns the [hostElement] in which the Flutter Application is supposed
|
||||
/// to render, or `null` if the user hasn't specified anything.
|
||||
DomElement? get hostElement => _configuration?.hostElement;
|
||||
|
||||
/// Returns the [requestedRendererType] to be used with the current Flutter
|
||||
/// application, normally 'canvaskit' or 'auto'.
|
||||
///
|
||||
/// This value may come from the JS configuration, but also a specific JS value:
|
||||
/// `window.flutterWebRenderer`.
|
||||
///
|
||||
/// This is used by the Renderer class to decide how to initialize the engine.
|
||||
String? get requestedRendererType => _configuration?.renderer ?? _requestedRendererType;
|
||||
}
|
||||
|
||||
@JS('window.flutterConfiguration')
|
||||
@ -169,13 +251,13 @@ class JsFlutterConfiguration {}
|
||||
extension JsFlutterConfigurationExtension on JsFlutterConfiguration {
|
||||
external String? get canvasKitBaseUrl;
|
||||
external bool? get canvasKitForceCpuOnly;
|
||||
external bool? get debugShowSemanticsNodes;
|
||||
|
||||
external int? get canvasKitMaximumSurfaces;
|
||||
external set canvasKitMaximumSurfaces(int? maxSurfaces);
|
||||
external bool? get debugShowSemanticsNodes;
|
||||
external DomElement? get hostElement;
|
||||
external String? get renderer;
|
||||
}
|
||||
|
||||
/// A JavaScript entrypoint that allows developer to set rendering backend
|
||||
/// at runtime before launching the application.
|
||||
@JS('window.flutterWebRenderer')
|
||||
external String? get requestedRendererType;
|
||||
external String? get _requestedRendererType;
|
||||
|
||||
@ -77,6 +77,7 @@ class DomConsole {}
|
||||
extension DomConsoleExtension on DomConsole {
|
||||
external void warn(Object? arg);
|
||||
external void error(Object? arg);
|
||||
external void debug(Object? arg);
|
||||
}
|
||||
|
||||
@JS('window')
|
||||
|
||||
@ -7,6 +7,7 @@ import 'dart:developer' as developer;
|
||||
|
||||
import 'package:ui/src/engine/assets.dart';
|
||||
import 'package:ui/src/engine/browser_detection.dart';
|
||||
import 'package:ui/src/engine/configuration.dart';
|
||||
import 'package:ui/src/engine/embedder.dart';
|
||||
import 'package:ui/src/engine/mouse_cursor.dart';
|
||||
import 'package:ui/src/engine/navigation.dart';
|
||||
@ -126,6 +127,7 @@ void debugResetEngineInitializationState() {
|
||||
/// puts UI elements on the page.
|
||||
Future<void> initializeEngineServices({
|
||||
AssetManager? assetManager,
|
||||
JsFlutterConfiguration? jsConfiguration
|
||||
}) async {
|
||||
if (_initializationState != DebugEngineInitializationState.uninitialized) {
|
||||
assert(() {
|
||||
@ -139,6 +141,9 @@ Future<void> initializeEngineServices({
|
||||
}
|
||||
_initializationState = DebugEngineInitializationState.initializingServices;
|
||||
|
||||
// Store `jsConfiguration` so user settings are available to the engine.
|
||||
configuration.setUserConfiguration(jsConfiguration);
|
||||
|
||||
// Setup the hook that allows users to customize URL strategy before running
|
||||
// the app.
|
||||
_addUrlStrategyListener();
|
||||
|
||||
@ -7,6 +7,7 @@ library js_loader;
|
||||
|
||||
import 'package:js/js.dart';
|
||||
|
||||
import '../configuration.dart';
|
||||
import 'js_promise.dart';
|
||||
|
||||
/// Typedef for the function that notifies JS that the main entrypoint is up and running.
|
||||
@ -25,26 +26,6 @@ external Object? get loader;
|
||||
@JS('_flutter.loader.didCreateEngineInitializer')
|
||||
external DidCreateEngineInitializerFn? get didCreateEngineInitializer;
|
||||
|
||||
// /// window._flutter
|
||||
// @JS('_flutter')
|
||||
// external FlutterJsNamespace? get flutterjs;
|
||||
|
||||
// /// window._flutter.loader
|
||||
// @JS()
|
||||
// @anonymous
|
||||
// class FlutterJsNamespace {
|
||||
// external FlutterJsLoaderNamespace? get loader;
|
||||
// }
|
||||
|
||||
// /// The bits of window._flutter.loader that the Flutter Engine cares about.
|
||||
// @JS()
|
||||
// @anonymous
|
||||
// class FlutterJsLoaderNamespace {
|
||||
// /// A hook to notify JavaScript that Flutter is up and running!
|
||||
// /// This is setup by flutter.js when the main entrypoint bundle is injected.
|
||||
// external DidCreateEngineInitializerFn? get didCreateEngineInitializer;
|
||||
// }
|
||||
|
||||
// FlutterEngineInitializer
|
||||
|
||||
/// An object that allows the user to initialize the Engine of a Flutter App.
|
||||
@ -61,17 +42,12 @@ abstract class FlutterEngineInitializer{
|
||||
});
|
||||
}
|
||||
|
||||
/// The shape of the object that can be passed as parameter to the
|
||||
/// initializeEngine function of the FlutterEngineInitializer object
|
||||
/// (when called from JS).
|
||||
@JS()
|
||||
@anonymous
|
||||
@staticInterop
|
||||
abstract class InitializeEngineFnParameters {
|
||||
}
|
||||
|
||||
/// Typedef for the function that initializes the flutter engine.
|
||||
typedef InitializeEngineFn = Promise<FlutterAppRunner?> Function([InitializeEngineFnParameters?]);
|
||||
///
|
||||
/// [JsFlutterConfiguration] comes from `../configuration.dart`. It is the same
|
||||
/// object that can be used to configure flutter "inline", through the
|
||||
/// (to be deprecated) `window.flutterConfiguration` object.
|
||||
typedef InitializeEngineFn = Promise<FlutterAppRunner?> Function([JsFlutterConfiguration?]);
|
||||
|
||||
/// Typedef for the `autoStart` function that can be called straight from an engine initializer instance.
|
||||
/// (Similar to [RunAppFn], but taking no specific "runApp" parameters).
|
||||
|
||||
@ -32,8 +32,8 @@ abstract class Renderer {
|
||||
}
|
||||
bool useCanvasKit;
|
||||
if (FlutterConfiguration.flutterWebAutoDetect) {
|
||||
if (requestedRendererType != null) {
|
||||
useCanvasKit = requestedRendererType == 'canvaskit';
|
||||
if (configuration.requestedRendererType != null) {
|
||||
useCanvasKit = configuration.requestedRendererType == 'canvaskit';
|
||||
} else {
|
||||
// If requestedRendererType is not specified, use CanvasKit for desktop and
|
||||
// html for mobile.
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:js/js_util.dart' as js_util;
|
||||
import 'package:test/bootstrap/browser.dart';
|
||||
import 'package:test/test.dart';
|
||||
import 'package:ui/src/engine.dart';
|
||||
@ -804,8 +805,13 @@ void testMain() {
|
||||
|
||||
test('works correctly with max overlays == 2', () async {
|
||||
final Rasterizer rasterizer = CanvasKitRenderer.instance.rasterizer;
|
||||
debugSetConfiguration(FlutterConfiguration(
|
||||
JsFlutterConfiguration()..canvasKitMaximumSurfaces = 2));
|
||||
final FlutterConfiguration config = FlutterConfiguration()
|
||||
..setUserConfiguration(
|
||||
js_util.jsify(<String, Object?>{
|
||||
'canvasKitMaximumSurfaces': 2,
|
||||
}) as JsFlutterConfiguration);
|
||||
debugSetConfiguration(config);
|
||||
|
||||
SurfaceFactory.instance.debugClear();
|
||||
|
||||
expect(SurfaceFactory.instance.maximumSurfaces, 2);
|
||||
@ -847,7 +853,7 @@ void testMain() {
|
||||
]);
|
||||
|
||||
// Reset configuration
|
||||
debugSetConfiguration(FlutterConfiguration(null));
|
||||
debugSetConfiguration(FlutterConfiguration());
|
||||
});
|
||||
|
||||
test(
|
||||
|
||||
@ -0,0 +1,29 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:js/js_util.dart' as js_util;
|
||||
import 'package:test/bootstrap/browser.dart';
|
||||
import 'package:test/test.dart';
|
||||
import 'package:ui/src/engine.dart';
|
||||
|
||||
void main() {
|
||||
internalBootstrapBrowserTest(() => testMain);
|
||||
}
|
||||
|
||||
void testMain() {
|
||||
group('initializeEngineServices', () {
|
||||
test('stores user configuration', () async {
|
||||
// dev/test_platform.dart injects a global configuration object. Let's
|
||||
// fetch that, override one of its properties (under test), then delete it
|
||||
// from window (so our configuration asserts don't fire!)
|
||||
final JsFlutterConfiguration config = js_util.getProperty(domWindow, 'flutterConfiguration');
|
||||
js_util.setProperty(config, 'canvasKitMaximumSurfaces', 32);
|
||||
js_util.setProperty(domWindow, 'flutterConfiguration', null);
|
||||
|
||||
await initializeEngineServices(jsConfiguration: config);
|
||||
|
||||
expect(configuration.canvasKitMaximumSurfaces, 32);
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -26,7 +26,7 @@ void testMain() {
|
||||
runCalled = 0;
|
||||
});
|
||||
|
||||
Future<void> mockInit () async {
|
||||
Future<void> mockInit ([JsFlutterConfiguration? configuration]) async {
|
||||
initCalled = callOrder++;
|
||||
await Future<void>.delayed(const Duration(milliseconds: 1));
|
||||
}
|
||||
@ -37,7 +37,7 @@ void testMain() {
|
||||
|
||||
test('autoStart() immediately calls init and run', () async {
|
||||
final AppBootstrap bootstrap = AppBootstrap(
|
||||
initEngine: mockInit,
|
||||
initializeEngine: mockInit,
|
||||
runApp: mockRunApp,
|
||||
);
|
||||
|
||||
@ -49,7 +49,7 @@ void testMain() {
|
||||
|
||||
test('engineInitializer autoStart() does the same as Dart autoStart()', () async {
|
||||
final AppBootstrap bootstrap = AppBootstrap(
|
||||
initEngine: mockInit,
|
||||
initializeEngine: mockInit,
|
||||
runApp: mockRunApp,
|
||||
);
|
||||
|
||||
@ -66,7 +66,7 @@ void testMain() {
|
||||
|
||||
test('engineInitializer initEngine() calls init and returns an appRunner', () async {
|
||||
final AppBootstrap bootstrap = AppBootstrap(
|
||||
initEngine: mockInit,
|
||||
initializeEngine: mockInit,
|
||||
runApp: mockRunApp,
|
||||
);
|
||||
|
||||
@ -81,7 +81,7 @@ void testMain() {
|
||||
|
||||
test('appRunner runApp() calls run and returns a FlutterApp', () async {
|
||||
final AppBootstrap bootstrap = AppBootstrap(
|
||||
initEngine: mockInit,
|
||||
initializeEngine: mockInit,
|
||||
runApp: mockRunApp,
|
||||
);
|
||||
|
||||
|
||||
@ -0,0 +1,63 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
@TestOn('browser')
|
||||
|
||||
import 'package:js/js_util.dart' as js_util;
|
||||
|
||||
import 'package:test/bootstrap/browser.dart';
|
||||
import 'package:test/test.dart';
|
||||
import 'package:ui/src/engine.dart';
|
||||
|
||||
import '../matchers.dart';
|
||||
|
||||
void main() {
|
||||
internalBootstrapBrowserTest(() => testMain);
|
||||
}
|
||||
|
||||
void testMain() {
|
||||
group('FlutterConfiguration', () {
|
||||
test('initializes with null', () async {
|
||||
final FlutterConfiguration config = FlutterConfiguration.legacy(null);
|
||||
|
||||
expect(config.canvasKitMaximumSurfaces, 8); // _defaultCanvasKitMaximumSurfaces
|
||||
});
|
||||
|
||||
test('legacy constructor initializes with a Js Object', () async {
|
||||
final FlutterConfiguration config = FlutterConfiguration.legacy(
|
||||
js_util.jsify(<String, Object?>{
|
||||
'canvasKitMaximumSurfaces': 16,
|
||||
}) as JsFlutterConfiguration);
|
||||
|
||||
expect(config.canvasKitMaximumSurfaces, 16);
|
||||
});
|
||||
});
|
||||
|
||||
group('setUserConfiguration', () {
|
||||
test('throws assertion error if already initialized from JS', () async {
|
||||
final FlutterConfiguration config = FlutterConfiguration.legacy(
|
||||
js_util.jsify(<String, Object?>{
|
||||
'canvasKitMaximumSurfaces': 12,
|
||||
}) as JsFlutterConfiguration);
|
||||
|
||||
expect(() {
|
||||
config.setUserConfiguration(
|
||||
js_util.jsify(<String, Object?>{
|
||||
'canvasKitMaximumSurfaces': 16,
|
||||
}) as JsFlutterConfiguration);
|
||||
}, throwsAssertionError);
|
||||
});
|
||||
|
||||
test('stores config if JS configuration was null', () async {
|
||||
final FlutterConfiguration config = FlutterConfiguration.legacy(null);
|
||||
|
||||
config.setUserConfiguration(
|
||||
js_util.jsify(<String, Object?>{
|
||||
'canvasKitMaximumSurfaces': 16,
|
||||
}) as JsFlutterConfiguration);
|
||||
|
||||
expect(config.canvasKitMaximumSurfaces, 16);
|
||||
});
|
||||
});
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user