mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[canvaskit] remove the DOM node of unrendered platform view (flutter/engine#24001)
This commit is contained in:
parent
215433e318
commit
e88c847bbc
@ -359,14 +359,17 @@ class HtmlViewEmbedder {
|
||||
final Set<int> unusedViews = Set<int>.from(_activeCompositionOrder);
|
||||
_activeCompositionOrder.clear();
|
||||
|
||||
List<int>? debugInvalidViewIds;
|
||||
for (int i = 0; i < _compositionOrder.length; i++) {
|
||||
int viewId = _compositionOrder[i];
|
||||
|
||||
assert(
|
||||
_views.containsKey(viewId),
|
||||
'Cannot render platform view $viewId. '
|
||||
'It has not been created, or it has been deleted.',
|
||||
);
|
||||
if (assertionsEnabled) {
|
||||
if (!_views.containsKey(viewId)) {
|
||||
debugInvalidViewIds ??= <int>[];
|
||||
debugInvalidViewIds.add(viewId);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
unusedViews.remove(viewId);
|
||||
html.Element platformViewRoot = _rootViews[viewId]!;
|
||||
@ -381,6 +384,16 @@ class HtmlViewEmbedder {
|
||||
|
||||
for (final int unusedViewId in unusedViews) {
|
||||
_releaseOverlay(unusedViewId);
|
||||
_rootViews[unusedViewId]?.remove();
|
||||
}
|
||||
|
||||
if (assertionsEnabled) {
|
||||
if (debugInvalidViewIds != null && debugInvalidViewIds.isNotEmpty) {
|
||||
throw AssertionError(
|
||||
'Cannot render platform views: ${debugInvalidViewIds.join(', ')}. '
|
||||
'These views have not been created, or they have been deleted.',
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -476,6 +489,7 @@ class OverlayCache {
|
||||
for (final Surface overlay in _cache) {
|
||||
overlay.dispose();
|
||||
}
|
||||
_cache.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -287,9 +287,79 @@ void testMain() {
|
||||
} on AssertionError catch (error) {
|
||||
expect(
|
||||
error.toString(),
|
||||
'Assertion failed: "Cannot render platform view 0. It has not been created, or it has been deleted."',
|
||||
'Assertion failed: "Cannot render platform views: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. These views have not been created, or they have been deleted."',
|
||||
);
|
||||
}
|
||||
|
||||
// Frame 7:
|
||||
// Render: a platform view after error.
|
||||
// Expect: success. Just checking the system is not left in a corrupted state.
|
||||
await _createPlatformView(0, 'test-platform-view');
|
||||
renderTestScene(viewCount: 0);
|
||||
});
|
||||
|
||||
test('embeds and disposes of a platform view', () async {
|
||||
ui.platformViewRegistry.registerViewFactory(
|
||||
'test-platform-view',
|
||||
(viewId) => html.DivElement()..id = 'view-0',
|
||||
);
|
||||
await _createPlatformView(0, 'test-platform-view');
|
||||
|
||||
final EnginePlatformDispatcher dispatcher =
|
||||
ui.window.platformDispatcher as EnginePlatformDispatcher;
|
||||
|
||||
LayerSceneBuilder sb = LayerSceneBuilder();
|
||||
sb.pushOffset(0, 0);
|
||||
sb.addPlatformView(0, width: 10, height: 10);
|
||||
dispatcher.rasterizer!.draw(sb.build().layerTree);
|
||||
|
||||
expect(
|
||||
domRenderer.sceneElement!.querySelectorAll('#view-0'),
|
||||
hasLength(1),
|
||||
);
|
||||
|
||||
await _disposePlatformView(0);
|
||||
|
||||
sb = LayerSceneBuilder();
|
||||
sb.pushOffset(0, 0);
|
||||
dispatcher.rasterizer!.draw(sb.build().layerTree);
|
||||
|
||||
expect(
|
||||
domRenderer.sceneElement!.querySelectorAll('#view-0'),
|
||||
hasLength(0),
|
||||
);
|
||||
});
|
||||
|
||||
test('removed the DOM node of an unrendered platform view', () async {
|
||||
ui.platformViewRegistry.registerViewFactory(
|
||||
'test-platform-view',
|
||||
(viewId) => html.DivElement()..id = 'view-0',
|
||||
);
|
||||
await _createPlatformView(0, 'test-platform-view');
|
||||
|
||||
final EnginePlatformDispatcher dispatcher =
|
||||
ui.window.platformDispatcher as EnginePlatformDispatcher;
|
||||
|
||||
LayerSceneBuilder sb = LayerSceneBuilder();
|
||||
sb.pushOffset(0, 0);
|
||||
sb.addPlatformView(0, width: 10, height: 10);
|
||||
dispatcher.rasterizer!.draw(sb.build().layerTree);
|
||||
|
||||
expect(
|
||||
domRenderer.sceneElement!.querySelectorAll('#view-0'),
|
||||
hasLength(1),
|
||||
);
|
||||
|
||||
// Render a frame without a platform view, but also without disposing of
|
||||
// the platform view.
|
||||
sb = LayerSceneBuilder();
|
||||
sb.pushOffset(0, 0);
|
||||
dispatcher.rasterizer!.draw(sb.build().layerTree);
|
||||
|
||||
expect(
|
||||
domRenderer.sceneElement!.querySelectorAll('#view-0'),
|
||||
hasLength(0),
|
||||
);
|
||||
});
|
||||
// TODO: https://github.com/flutter/flutter/issues/60040
|
||||
}, skip: isIosSafari);
|
||||
@ -311,3 +381,13 @@ Future<void> _createPlatformView(int id, String viewType) {
|
||||
);
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
Future<void> _disposePlatformView(int id) {
|
||||
final completer = Completer<void>();
|
||||
window.sendPlatformMessage(
|
||||
'flutter/platform_views',
|
||||
codec.encodeMethodCall(MethodCall('dispose', id)),
|
||||
(dynamic _) => completer.complete(),
|
||||
);
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user