diff --git a/lib/web_ui/lib/src/engine/platform_views/content_manager.dart b/lib/web_ui/lib/src/engine/platform_views/content_manager.dart index 288ab4374a32e..b5579bc4def25 100644 --- a/lib/web_ui/lib/src/engine/platform_views/content_manager.dart +++ b/lib/web_ui/lib/src/engine/platform_views/content_manager.dart @@ -25,6 +25,19 @@ import 'slots.dart'; /// This class keeps a registry of `factories`, `contents` so the framework can /// CRUD Platform Views as needed, regardless of the rendering backend. class PlatformViewManager { + PlatformViewManager() { + // Register some default factories. + registerFactory( + ui_web.PlatformViewRegistry.defaultVisibleViewType, + _defaultFactory, + ); + registerFactory( + ui_web.PlatformViewRegistry.defaultInvisibleViewType, + _defaultFactory, + isVisible: false, + ); + } + // The factory functions, indexed by the viewType final Map _factories = {}; @@ -223,3 +236,12 @@ class PlatformViewManager { return result; } } + +DomElement _defaultFactory( + int viewId, { + Object? params, +}) { + params!; + params as Map; + return domDocument.createElement(params.readString('tagName')); +} diff --git a/lib/web_ui/lib/ui_web/src/ui_web/platform_view_registry.dart b/lib/web_ui/lib/ui_web/src/ui_web/platform_view_registry.dart index ff9312f11da09..e33e8ebc53199 100644 --- a/lib/web_ui/lib/ui_web/src/ui_web/platform_view_registry.dart +++ b/lib/web_ui/lib/ui_web/src/ui_web/platform_view_registry.dart @@ -19,6 +19,20 @@ final PlatformViewRegistry platformViewRegistry = PlatformViewRegistry(); /// A registry for factories that create platform views. class PlatformViewRegistry { + /// The view type of the built-in factory that creates visible platform view + /// DOM elements. + /// + /// There's no need to register this view type with [PlatformViewRegistry] + /// because it is registered by default. + static const String defaultVisibleViewType = '_default_document_create_element_visible'; + + /// The view type of the built-in factory that creates invisible platform view + /// DOM elements. + /// + /// There's no need to register this view type with [PlatformViewRegistry] + /// because it is registered by default. + static const String defaultInvisibleViewType = '_default_document_create_element_invisible'; + /// Register [viewType] as being created by the given [viewFactory]. /// /// [viewFactory] can be any function that takes an integer and optional diff --git a/lib/web_ui/test/engine/platform_views/content_manager_test.dart b/lib/web_ui/test/engine/platform_views/content_manager_test.dart index 0502984a61b3f..214d46d079dc0 100644 --- a/lib/web_ui/test/engine/platform_views/content_manager_test.dart +++ b/lib/web_ui/test/engine/platform_views/content_manager_test.dart @@ -5,8 +5,7 @@ import 'package:test/bootstrap/browser.dart'; import 'package:test/test.dart'; import 'package:ui/src/engine.dart'; - -import '../../common/matchers.dart'; +import 'package:ui/ui_web/src/ui_web.dart' as ui_web; void main() { internalBootstrapBrowserTest(() => testMain); @@ -97,13 +96,14 @@ void testMain() { }); test('refuse to render views for unregistered factories', () async { - try { - contentManager.renderContent(unregisteredViewType, viewId, null); - fail('renderContent should have thrown an Assertion error!'); - } catch (e) { - expect(e, isAssertionError); - expect((e as AssertionError).message, contains(unregisteredViewType)); - } + expect( + () => contentManager.renderContent(unregisteredViewType, viewId, null), + throwsA(const TypeMatcher().having( + (AssertionError error) => error.message, + 'assertion message', + contains(unregisteredViewType), + )), + ); }); test('rendered markup contains required attributes', () async { @@ -203,5 +203,43 @@ void testMain() { }, throwsA(isA())); }); }); + + test('default factories', () { + final DomElement content0 = contentManager.renderContent( + ui_web.PlatformViewRegistry.defaultVisibleViewType, + viewId, + {'tagName': 'table'}, + ); + expect( + contentManager.getViewById(viewId), + content0.querySelector('table'), + ); + expect(contentManager.isVisible(viewId), isTrue); + expect(contentManager.isInvisible(viewId), isFalse); + + final DomElement content1 = contentManager.renderContent( + ui_web.PlatformViewRegistry.defaultInvisibleViewType, + viewId + 1, + {'tagName': 'script'}, + ); + expect( + contentManager.getViewById(viewId + 1), + content1.querySelector('script'), + ); + expect(contentManager.isVisible(viewId + 1), isFalse); + expect(contentManager.isInvisible(viewId + 1), isTrue); + + final DomElement content2 = contentManager.renderContent( + ui_web.PlatformViewRegistry.defaultVisibleViewType, + viewId + 2, + {'tagName': 'p'}, + ); + expect( + contentManager.getViewById(viewId + 2), + content2.querySelector('p'), + ); + expect(contentManager.isVisible(viewId + 2), isTrue); + expect(contentManager.isInvisible(viewId + 2), isFalse); + }); }); }