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

Commit 6f1c2df

Browse files
authored
[web] Provide convenient default factories for platform views (#43828)
Convenient default factories for creating DOM element from a given tag name. Required by flutter/flutter#130513 Part of flutter/flutter#127030
1 parent ba83c14 commit 6f1c2df

File tree

3 files changed

+83
-9
lines changed

3 files changed

+83
-9
lines changed

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,19 @@ import 'slots.dart';
2525
/// This class keeps a registry of `factories`, `contents` so the framework can
2626
/// CRUD Platform Views as needed, regardless of the rendering backend.
2727
class PlatformViewManager {
28+
PlatformViewManager() {
29+
// Register some default factories.
30+
registerFactory(
31+
ui_web.PlatformViewRegistry.defaultVisibleViewType,
32+
_defaultFactory,
33+
);
34+
registerFactory(
35+
ui_web.PlatformViewRegistry.defaultInvisibleViewType,
36+
_defaultFactory,
37+
isVisible: false,
38+
);
39+
}
40+
2841
// The factory functions, indexed by the viewType
2942
final Map<String, Function> _factories = <String, Function>{};
3043

@@ -223,3 +236,12 @@ class PlatformViewManager {
223236
return result;
224237
}
225238
}
239+
240+
DomElement _defaultFactory(
241+
int viewId, {
242+
Object? params,
243+
}) {
244+
params!;
245+
params as Map<Object?, Object?>;
246+
return domDocument.createElement(params.readString('tagName'));
247+
}

lib/web_ui/lib/ui_web/src/ui_web/platform_view_registry.dart

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,20 @@ final PlatformViewRegistry platformViewRegistry = PlatformViewRegistry();
1919

2020
/// A registry for factories that create platform views.
2121
class PlatformViewRegistry {
22+
/// The view type of the built-in factory that creates visible platform view
23+
/// DOM elements.
24+
///
25+
/// There's no need to register this view type with [PlatformViewRegistry]
26+
/// because it is registered by default.
27+
static const String defaultVisibleViewType = '_default_document_create_element_visible';
28+
29+
/// The view type of the built-in factory that creates invisible platform view
30+
/// DOM elements.
31+
///
32+
/// There's no need to register this view type with [PlatformViewRegistry]
33+
/// because it is registered by default.
34+
static const String defaultInvisibleViewType = '_default_document_create_element_invisible';
35+
2236
/// Register [viewType] as being created by the given [viewFactory].
2337
///
2438
/// [viewFactory] can be any function that takes an integer and optional

lib/web_ui/test/engine/platform_views/content_manager_test.dart

Lines changed: 47 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@
55
import 'package:test/bootstrap/browser.dart';
66
import 'package:test/test.dart';
77
import 'package:ui/src/engine.dart';
8-
9-
import '../../common/matchers.dart';
8+
import 'package:ui/ui_web/src/ui_web.dart' as ui_web;
109

1110
void main() {
1211
internalBootstrapBrowserTest(() => testMain);
@@ -97,13 +96,14 @@ void testMain() {
9796
});
9897

9998
test('refuse to render views for unregistered factories', () async {
100-
try {
101-
contentManager.renderContent(unregisteredViewType, viewId, null);
102-
fail('renderContent should have thrown an Assertion error!');
103-
} catch (e) {
104-
expect(e, isAssertionError);
105-
expect((e as AssertionError).message, contains(unregisteredViewType));
106-
}
99+
expect(
100+
() => contentManager.renderContent(unregisteredViewType, viewId, null),
101+
throwsA(const TypeMatcher<AssertionError>().having(
102+
(AssertionError error) => error.message,
103+
'assertion message',
104+
contains(unregisteredViewType),
105+
)),
106+
);
107107
});
108108

109109
test('rendered markup contains required attributes', () async {
@@ -203,5 +203,43 @@ void testMain() {
203203
}, throwsA(isA<AssertionError>()));
204204
});
205205
});
206+
207+
test('default factories', () {
208+
final DomElement content0 = contentManager.renderContent(
209+
ui_web.PlatformViewRegistry.defaultVisibleViewType,
210+
viewId,
211+
<dynamic, dynamic>{'tagName': 'table'},
212+
);
213+
expect(
214+
contentManager.getViewById(viewId),
215+
content0.querySelector('table'),
216+
);
217+
expect(contentManager.isVisible(viewId), isTrue);
218+
expect(contentManager.isInvisible(viewId), isFalse);
219+
220+
final DomElement content1 = contentManager.renderContent(
221+
ui_web.PlatformViewRegistry.defaultInvisibleViewType,
222+
viewId + 1,
223+
<dynamic, dynamic>{'tagName': 'script'},
224+
);
225+
expect(
226+
contentManager.getViewById(viewId + 1),
227+
content1.querySelector('script'),
228+
);
229+
expect(contentManager.isVisible(viewId + 1), isFalse);
230+
expect(contentManager.isInvisible(viewId + 1), isTrue);
231+
232+
final DomElement content2 = contentManager.renderContent(
233+
ui_web.PlatformViewRegistry.defaultVisibleViewType,
234+
viewId + 2,
235+
<dynamic, dynamic>{'tagName': 'p'},
236+
);
237+
expect(
238+
contentManager.getViewById(viewId + 2),
239+
content2.querySelector('p'),
240+
);
241+
expect(contentManager.isVisible(viewId + 2), isTrue);
242+
expect(contentManager.isInvisible(viewId + 2), isFalse);
243+
});
206244
});
207245
}

0 commit comments

Comments
 (0)