mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[web] Move EmbeddingStrategy and DimensionsProvider out of FlutterViewEmbedder (flutter/engine#48025)
Part of https://github.com/flutter/flutter/issues/134443 Part of https://github.com/flutter/flutter/issues/117098
This commit is contained in:
parent
ab53a52abc
commit
4bb1a74025
@ -14,9 +14,7 @@ import 'platform_dispatcher.dart';
|
||||
import 'pointer_binding.dart';
|
||||
import 'semantics.dart';
|
||||
import 'text_editing/text_editing.dart';
|
||||
import 'view_embedder/dimensions_provider/dimensions_provider.dart';
|
||||
import 'view_embedder/dom_manager.dart';
|
||||
import 'view_embedder/embedding_strategy/embedding_strategy.dart';
|
||||
import 'view_embedder/style_manager.dart';
|
||||
import 'window.dart';
|
||||
|
||||
@ -40,30 +38,10 @@ import 'window.dart';
|
||||
/// multiple instances in a multi-view scenario. (One ViewEmbedder per FlutterView).
|
||||
class FlutterViewEmbedder {
|
||||
/// Creates a FlutterViewEmbedder.
|
||||
///
|
||||
/// The incoming [hostElement] parameter specifies the root element in the DOM
|
||||
/// into which Flutter will be rendered.
|
||||
///
|
||||
/// The hostElement is abstracted by an [EmbeddingStrategy] instance, which has
|
||||
/// different behavior depending on the `hostElement` value:
|
||||
///
|
||||
/// - A `null` `hostElement` will cause Flutter to take over the whole page.
|
||||
/// - A non-`null` `hostElement` will render flutter inside that element.
|
||||
FlutterViewEmbedder({DomElement? hostElement})
|
||||
: _embeddingStrategy =
|
||||
EmbeddingStrategy.create(hostElement: hostElement) {
|
||||
// Configure the EngineWindow so it knows how to measure itself.
|
||||
// TODO(dit): Refactor ownership according to new design, https://github.com/flutter/flutter/issues/117098
|
||||
window.configureDimensionsProvider(DimensionsProvider.create(
|
||||
hostElement: hostElement,
|
||||
));
|
||||
|
||||
FlutterViewEmbedder() {
|
||||
reset();
|
||||
}
|
||||
|
||||
/// Abstracts all the DOM manipulations required to embed a Flutter app in an user-supplied `hostElement`.
|
||||
final EmbeddingStrategy _embeddingStrategy;
|
||||
|
||||
/// The element that contains the [sceneElement].
|
||||
///
|
||||
/// This element is created and inserted in the HTML DOM once. It is never
|
||||
@ -139,7 +117,7 @@ class FlutterViewEmbedder {
|
||||
: 'requested explicitly';
|
||||
|
||||
// Initializes the embeddingStrategy so it can host a single-view Flutter app.
|
||||
_embeddingStrategy.initialize(
|
||||
window.embeddingStrategy.initialize(
|
||||
hostElementAttributes: <String, String>{
|
||||
'flt-renderer': '${renderer.rendererTag} ($rendererSelection)',
|
||||
'flt-build-mode': buildMode,
|
||||
@ -158,7 +136,7 @@ class FlutterViewEmbedder {
|
||||
//
|
||||
// The embeddingStrategy will take care of cleaning up the glassPane on hot
|
||||
// restart.
|
||||
_embeddingStrategy.attachGlassPane(_flutterViewElement);
|
||||
window.embeddingStrategy.attachGlassPane(_flutterViewElement);
|
||||
_flutterViewElement.appendChild(_glassPaneElement);
|
||||
|
||||
if (getJsProperty<Object?>(_glassPaneElement, 'attachShadow') == null) {
|
||||
@ -270,7 +248,7 @@ class FlutterViewEmbedder {
|
||||
..style.visibility = 'hidden';
|
||||
if (isWebKit) {
|
||||
// The resourcesHost *must* be a sibling of the glassPaneElement.
|
||||
_embeddingStrategy.attachResourcesHost(resourcesHost,
|
||||
window.embeddingStrategy.attachResourcesHost(resourcesHost,
|
||||
nextTo: _flutterViewElement);
|
||||
} else {
|
||||
_glassPaneShadow.insertBefore(resourcesHost, _glassPaneShadow.firstChild);
|
||||
@ -312,10 +290,9 @@ FlutterViewEmbedder? _flutterViewEmbedder;
|
||||
/// Initializes the [FlutterViewEmbedder], if it's not already initialized.
|
||||
FlutterViewEmbedder ensureFlutterViewEmbedderInitialized() {
|
||||
// FlutterViewEmbedder needs the implicit view to be initialized because it
|
||||
// uses some of its methods e.g. `configureDimensionsProvider`, `onResize`.
|
||||
// uses some of its members e.g. `embeddingStrategy`, `onResize`.
|
||||
ensureImplicitViewInitialized();
|
||||
return _flutterViewEmbedder ??=
|
||||
FlutterViewEmbedder(hostElement: configuration.hostElement);
|
||||
return _flutterViewEmbedder ??= FlutterViewEmbedder();
|
||||
}
|
||||
|
||||
/// Creates a node to host text editing elements and applies a stylesheet
|
||||
|
||||
@ -218,7 +218,7 @@ Future<void> initializeEngineUi() async {
|
||||
_initializationState = DebugEngineInitializationState.initializingUi;
|
||||
|
||||
RawKeyboard.initialize(onMacOs: operatingSystem == OperatingSystem.macOs);
|
||||
ensureImplicitViewInitialized();
|
||||
ensureImplicitViewInitialized(hostElement: configuration.hostElement);
|
||||
ensureFlutterViewEmbedderInitialized();
|
||||
_initializationState = DebugEngineInitializationState.initialized;
|
||||
}
|
||||
|
||||
@ -26,6 +26,7 @@ import 'semantics/accessibility.dart';
|
||||
import 'services.dart';
|
||||
import 'util.dart';
|
||||
import 'view_embedder/dom_manager.dart';
|
||||
import 'view_embedder/embedding_strategy/embedding_strategy.dart';
|
||||
|
||||
typedef _HandleMessageCallBack = Future<bool> Function();
|
||||
|
||||
@ -40,15 +41,25 @@ const int kImplicitViewId = 0;
|
||||
/// In addition to everything defined in [ui.FlutterView], this class adds
|
||||
/// a few web-specific properties.
|
||||
base class EngineFlutterView implements ui.FlutterView {
|
||||
/// Creates a [ui.FlutterView] that can be used in multi-view mode.
|
||||
///
|
||||
/// The [hostElement] parameter specifies the container in the DOM into which
|
||||
/// the Flutter view will be rendered.
|
||||
factory EngineFlutterView(
|
||||
int viewId,
|
||||
EnginePlatformDispatcher platformDispatcher,
|
||||
DomElement hostElement,
|
||||
) = _EngineFlutterViewImpl;
|
||||
|
||||
EngineFlutterView._(
|
||||
this.viewId,
|
||||
this.platformDispatcher,
|
||||
);
|
||||
// This is nullable to accommodate the legacy `EngineFlutterWindow`. In
|
||||
// multi-view mode, the host element is required for each view (as reflected
|
||||
// by the public `EngineFlutterView` constructor).
|
||||
DomElement? hostElement,
|
||||
) : embeddingStrategy = EmbeddingStrategy.create(hostElement: hostElement),
|
||||
_dimensionsProvider = DimensionsProvider.create(hostElement: hostElement);
|
||||
|
||||
@override
|
||||
final int viewId;
|
||||
@ -56,6 +67,9 @@ base class EngineFlutterView implements ui.FlutterView {
|
||||
@override
|
||||
final EnginePlatformDispatcher platformDispatcher;
|
||||
|
||||
/// Abstracts all the DOM manipulations required to embed a Flutter view in a user-supplied `hostElement`.
|
||||
final EmbeddingStrategy embeddingStrategy;
|
||||
|
||||
final ViewConfiguration _viewConfiguration = const ViewConfiguration();
|
||||
|
||||
@override
|
||||
@ -143,19 +157,17 @@ base class EngineFlutterView implements ui.FlutterView {
|
||||
@override
|
||||
double get devicePixelRatio => display.devicePixelRatio;
|
||||
|
||||
late DimensionsProvider _dimensionsProvider;
|
||||
void configureDimensionsProvider(DimensionsProvider dimensionsProvider) {
|
||||
_dimensionsProvider = dimensionsProvider;
|
||||
}
|
||||
final DimensionsProvider _dimensionsProvider;
|
||||
|
||||
Stream<ui.Size?> get onResize => _dimensionsProvider.onResize;
|
||||
}
|
||||
|
||||
final class _EngineFlutterViewImpl extends EngineFlutterView {
|
||||
_EngineFlutterViewImpl(
|
||||
int viewId,
|
||||
EnginePlatformDispatcher platformDispatcher,
|
||||
) : super._(viewId, platformDispatcher) {
|
||||
super.viewId,
|
||||
super.platformDispatcher,
|
||||
super.hostElement,
|
||||
) : super._() {
|
||||
platformDispatcher.registerView(this);
|
||||
registerHotRestartListener(() {
|
||||
// TODO(harryterkelsen): What should we do about this in multi-view?
|
||||
@ -168,9 +180,10 @@ final class _EngineFlutterViewImpl extends EngineFlutterView {
|
||||
/// The Web implementation of [ui.SingletonFlutterWindow].
|
||||
final class EngineFlutterWindow extends EngineFlutterView implements ui.SingletonFlutterWindow {
|
||||
EngineFlutterWindow(
|
||||
int viewId,
|
||||
EnginePlatformDispatcher platformDispatcher,
|
||||
) : super._(viewId, platformDispatcher) {
|
||||
super.viewId,
|
||||
super.platformDispatcher,
|
||||
super.hostElement,
|
||||
) : super._() {
|
||||
platformDispatcher.registerView(this);
|
||||
if (ui_web.isCustomUrlStrategySet) {
|
||||
_browserHistory = createHistoryForExistingState(ui_web.urlStrategy);
|
||||
@ -585,9 +598,14 @@ EngineFlutterWindow? _window;
|
||||
|
||||
/// Initializes the [window] (aka the implicit view), if it's not already
|
||||
/// initialized.
|
||||
EngineFlutterWindow ensureImplicitViewInitialized() {
|
||||
return _window ??=
|
||||
EngineFlutterWindow(kImplicitViewId, EnginePlatformDispatcher.instance);
|
||||
EngineFlutterWindow ensureImplicitViewInitialized({
|
||||
DomElement? hostElement,
|
||||
}) {
|
||||
return _window ??= EngineFlutterWindow(
|
||||
kImplicitViewId,
|
||||
EnginePlatformDispatcher.instance,
|
||||
hostElement,
|
||||
);
|
||||
}
|
||||
|
||||
/// The Web implementation of [ui.ViewPadding].
|
||||
|
||||
@ -37,7 +37,7 @@ void testMain() {
|
||||
|
||||
setUp(() {
|
||||
savedWindow = EnginePlatformDispatcher.instance.implicitView;
|
||||
myWindow = EngineFlutterWindow(0, EnginePlatformDispatcher.instance);
|
||||
myWindow = EngineFlutterWindow(0, EnginePlatformDispatcher.instance, createDomHTMLDivElement());
|
||||
});
|
||||
|
||||
tearDown(() async {
|
||||
|
||||
@ -14,7 +14,11 @@ import '../../common/matchers.dart';
|
||||
import '../../common/test_initialization.dart';
|
||||
|
||||
const MethodCodec codec = StandardMethodCodec();
|
||||
final EngineFlutterWindow window = EngineFlutterWindow(0, EnginePlatformDispatcher.instance);
|
||||
final EngineFlutterWindow window = EngineFlutterWindow(
|
||||
0,
|
||||
EnginePlatformDispatcher.instance,
|
||||
createDomHTMLDivElement(),
|
||||
);
|
||||
|
||||
void main() {
|
||||
internalBootstrapBrowserTest(() => testMain);
|
||||
|
||||
@ -27,7 +27,7 @@ Future<void> testMain() async {
|
||||
late EngineFlutterWindow myWindow;
|
||||
|
||||
setUp(() {
|
||||
myWindow = EngineFlutterWindow(99, EnginePlatformDispatcher.instance);
|
||||
myWindow = EngineFlutterWindow(99, EnginePlatformDispatcher.instance, createDomHTMLDivElement());
|
||||
});
|
||||
|
||||
tearDown(() async {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user