Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit a46bdc2

Browse files
committed
Inject contents of a platform view in the FlutterView of the current renderer, right before injecting its slot.
1 parent 362d0cb commit a46bdc2

File tree

4 files changed

+30
-3
lines changed

4 files changed

+30
-3
lines changed

lib/web_ui/lib/src/engine/canvaskit/embedded_views.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,10 @@ class HtmlViewEmbedder {
143143
}
144144

145145
void _compositeWithParams(int viewId, EmbeddedViewParams params) {
146+
// Ensure platform view with `viewId` is injected into the `rasterizer.view`
147+
// before rendering its shadow DOM `slot`.
148+
rasterizer.view.platformViewMessageHandler.injectPlatformView(viewId);
149+
146150
// If we haven't seen this viewId yet, cache it for clips/transforms.
147151
final ViewClipChain clipChain = _viewClipChains.putIfAbsent(viewId, () {
148152
return ViewClipChain(view: createPlatformViewSlot(viewId));

lib/web_ui/lib/src/engine/html/platform_view.dart

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

55
import '../dom.dart';
6+
import '../platform_dispatcher.dart';
67
import '../platform_views/slots.dart';
8+
import '../window.dart';
79
import 'surface.dart';
810

911
/// A surface containing a platform view, which is an HTML element.
@@ -18,6 +20,11 @@ class PersistedPlatformView extends PersistedLeafSurface {
1820

1921
@override
2022
DomElement createElement() {
23+
// Ensure platform view with `viewId` is injected into the `implicitView`
24+
// before rendering its shadow DOM `slot`.
25+
final EngineFlutterView implicitView = EnginePlatformDispatcher.instance.implicitView!;
26+
implicitView.platformViewMessageHandler.injectPlatformView(viewId);
27+
2128
return createPlatformViewSlot(viewId);
2229
}
2330

lib/web_ui/lib/src/engine/platform_views/content_manager.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ class PlatformViewManager {
6565
return _contents.containsKey(viewId);
6666
}
6767

68+
/// Returns the pre-rendered contents of [viewId], to inject them into the DOM.
69+
DomElement getContents(int viewId) {
70+
return _contents[viewId]!;
71+
}
72+
6873
/// Returns the HTML element created by a registered factory for [viewId].
6974
///
7075
/// Throws an [AssertionError] if [viewId] hasn't been rendered before.

lib/web_ui/lib/src/engine/platform_views/message_handler.dart

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,16 +88,27 @@ class PlatformViewMessageHandler {
8888
return;
8989
}
9090

91-
final DomElement content = _contentManager.renderContent(
91+
// Ensure the DomElement of the view is *created*, so programmers can
92+
// access it through `_contentManager.getViewById` (maybe not the DOM!).
93+
_contentManager.renderContent(
9294
platformViewType,
9395
platformViewId,
9496
params,
9597
);
9698

99+
callback(_codec.encodeSuccessEnvelope(null));
100+
}
101+
102+
/// Injects a platform view with [viewId] into this handler's `platformViewsContainer`.
103+
void injectPlatformView(int viewId) {
97104
// For now, we don't need anything fancier. If needed, this can be converted
98105
// to a PlatformViewStrategy class for each web-renderer backend?
99-
_platformViewsContainer.append(content);
100-
callback(_codec.encodeSuccessEnvelope(null));
106+
final DomElement pv = _contentManager.getContents(viewId);
107+
// If pv is a descendant of _platformViewsContainer -> noop
108+
if (_platformViewsContainer.contains(pv)) {
109+
return;
110+
}
111+
_platformViewsContainer.append(pv);
101112
}
102113

103114
/// Handle a `dispose` Platform View message.

0 commit comments

Comments
 (0)