[web] Migrate Flutter Web DOM usage to JS static interop - 38. (flutter/engine#33374)

This commit is contained in:
joshualitt 2022-06-27 11:33:45 -07:00 committed by GitHub
parent de593702de
commit df7a821479
12 changed files with 44 additions and 40 deletions

View File

@ -4,6 +4,8 @@
// TODO(yjbanov): rename this file to web_only_api.dart.
// https://github.com/flutter/flutter/issues/100394
// Rather than extending this file with new APIs, we
// should instead use js interop.
// This file contains extra web-only API that non-web engines do not have.
//
@ -129,13 +131,13 @@ void webOnlySetPluginHandler(Future<void> Function(String, ByteData?, PlatformMe
engine.pluginMessageCallHandler = handler;
}
/// A function which takes a unique `id` and creates an HTML element.
typedef PlatformViewFactory = html.Element Function(int viewId);
/// A registry for factories that create platform views.
class PlatformViewRegistry {
/// Register [viewTypeId] as being creating by the given [factory].
bool registerViewFactory(String viewTypeId, PlatformViewFactory viewFactory,
/// Register [viewTypeId] as being creating by the given [viewFactory].
/// [viewFactory] can be any function that takes an integer and returns an
/// `HTMLElement` DOM object.
bool registerViewFactory(String viewTypeId,
Object Function(int viewId) viewFactory,
{bool isVisible = true}) {
// TODO(web): Deprecate this once there's another way of calling `registerFactory` (js interop?)
return engine.platformViewManager

View File

@ -185,7 +185,7 @@ OperatingSystem detectOperatingSystem({
return OperatingSystem.iOs;
} else if (userAgent.contains('Android')) {
// The Android OS reports itself as "Linux armv8l" in
// [html.window.navigator.platform]. So we have to check the user-agent to
// [domWindow.navigator.platform]. So we have to check the user-agent to
// determine if the OS is Android or not.
return OperatingSystem.android;
} else if (platform.startsWith('Linux')) {

View File

@ -47,8 +47,11 @@ extension DomWindowExtension on DomWindow {
if (pseudoElt != null) pseudoElt
]) as DomCSSStyleDeclaration;
external DomScreen? get screen;
external int requestAnimationFrame(DomRequestAnimationFrameCallback callback);
}
typedef DomRequestAnimationFrameCallback = void Function(num highResTime);
@JS()
@staticInterop
class DomConsole {}

View File

@ -345,7 +345,7 @@ class FlutterViewEmbedder {
//
// VisualViewport API is not enabled in Firefox as well. On the other hand
// Firefox returns correct values for innerHeight, innerWidth.
// Firefox also triggers html.window.onResize therefore this timer does
// Firefox also triggers domWindow.onResize therefore this timer does
// not need to be set up for Firefox.
final int initialInnerWidth = domWindow.innerWidth!;
// Counts how many times screen size was checked. It is checked up to 5
@ -539,7 +539,7 @@ class FlutterViewEmbedder {
String get currentHtml => _rootApplicationElement?.outerHTML ?? '';
}
// Applies the required global CSS to an incoming [html.CssStyleSheet] `sheet`.
// Applies the required global CSS to an incoming [DomCSSStyleSheet] `sheet`.
void applyGlobalCssRulesToSheet(
DomCSSStyleSheet sheet, {
required BrowserEngine browserEngine,

View File

@ -3,10 +3,11 @@
// found in the LICENSE file.
import 'dart:async';
import 'dart:html' as html;
import 'dart:typed_data';
import 'dom.dart';
import 'platform_dispatcher.dart';
import 'safe_browser_api.dart';
import 'services.dart';
final ByteData? _fontChangeMessage =
@ -22,13 +23,13 @@ FutureOr<void> sendFontChangeMessage() async {
if (!_fontChangeScheduled) {
_fontChangeScheduled = true;
// Batch updates into next animationframe.
html.window.requestAnimationFrame((num _) {
domWindow.requestAnimationFrame(allowInterop((num _) {
_fontChangeScheduled = false;
EnginePlatformDispatcher.instance.invokeOnPlatformMessage(
'flutter/system',
_fontChangeMessage,
(_) {},
);
});
}));
}
}

View File

@ -4,7 +4,6 @@
import 'dart:async';
import 'dart:developer' as developer;
import 'dart:html' as html;
import 'package:ui/src/engine/assets.dart';
import 'package:ui/src/engine/browser_detection.dart';
@ -22,6 +21,8 @@ import 'package:ui/src/engine/text/line_break_properties.dart';
import 'package:ui/src/engine/window.dart';
import 'package:ui/ui.dart' as ui;
import 'dom.dart';
/// The mode the app is running in.
/// Keep these in sync with the same constants on the framework-side under foundation/constants.dart.
const bool kReleaseMode =
@ -178,7 +179,7 @@ Future<void> initializeEngineServices({
// fires.
if (!waitingForAnimation) {
waitingForAnimation = true;
html.window.requestAnimationFrame((num highResTime) {
domWindow.requestAnimationFrame(allowInterop((num highResTime) {
frameTimingsOnVsync();
// Reset immediately, because `frameHandler` can schedule more frames.
@ -210,7 +211,7 @@ Future<void> initializeEngineServices({
// implement it properly.
EnginePlatformDispatcher.instance.invokeOnDrawFrame();
}
});
}));
}
};

View File

@ -64,7 +64,7 @@ T setJsProperty<T>(Object object, String name, T value) {
'Attempted to set property "$name" on a JavaScript object. This property '
'has not been checked for safety. Possible solutions to this problem:\n'
' - Do not set this property.\n'
' - Use a `dart:html` API that does the same thing.\n'
' - Use a `js_util` API that does the same thing.\n'
' - Ensure that the property is safe then add it to _safeJsProperties set.',
);
return js_util.setProperty<T>(object, name, value);

View File

@ -10,7 +10,6 @@ library ui;
import 'dart:async';
import 'dart:collection' as collection;
import 'dart:convert';
import 'dart:html' as html;
import 'dart:math' as math;
import 'dart:typed_data';

View File

@ -27,7 +27,7 @@ void testMain() {
test('embeds interactive platform views', () async {
ui.platformViewRegistry.registerViewFactory(
'test-platform-view',
(int viewId) => html.DivElement()..id = 'view-0',
(int viewId) => createDomHTMLDivElement()..id = 'view-0',
);
await createPlatformView(0, 'test-platform-view');
@ -63,7 +63,7 @@ void testMain() {
test('clips platform views with RRects', () async {
ui.platformViewRegistry.registerViewFactory(
'test-platform-view',
(int viewId) => html.DivElement()..id = 'view-0',
(int viewId) => createDomHTMLDivElement()..id = 'view-0',
);
await createPlatformView(0, 'test-platform-view');
@ -103,7 +103,7 @@ void testMain() {
test('correctly transforms platform views', () async {
ui.platformViewRegistry.registerViewFactory(
'test-platform-view',
(int viewId) => html.DivElement()..id = 'view-0',
(int viewId) => createDomHTMLDivElement()..id = 'view-0',
);
await createPlatformView(0, 'test-platform-view');
@ -135,7 +135,7 @@ void testMain() {
test('correctly offsets platform views', () async {
ui.platformViewRegistry.registerViewFactory(
'test-platform-view',
(int viewId) => html.DivElement()..id = 'view-0',
(int viewId) => createDomHTMLDivElement()..id = 'view-0',
);
await createPlatformView(0, 'test-platform-view');
@ -175,7 +175,7 @@ void testMain() {
test('correctly offsets when clip chain length is changed', () async {
ui.platformViewRegistry.registerViewFactory(
'test-platform-view',
(int viewId) => html.DivElement()..id = 'view-0',
(int viewId) => createDomHTMLDivElement()..id = 'view-0',
);
await createPlatformView(0, 'test-platform-view');
@ -228,7 +228,7 @@ void testMain() {
window.debugOverrideDevicePixelRatio(4);
ui.platformViewRegistry.registerViewFactory(
'test-platform-view',
(int viewId) => html.DivElement()..id = 'view-0',
(int viewId) => createDomHTMLDivElement()..id = 'view-0',
);
await createPlatformView(0, 'test-platform-view');
@ -255,7 +255,7 @@ void testMain() {
window.debugOverrideDevicePixelRatio(4);
ui.platformViewRegistry.registerViewFactory(
'test-platform-view',
(int viewId) => html.DivElement()..id = 'view-0',
(int viewId) => createDomHTMLDivElement()..id = 'view-0',
);
await createPlatformView(0, 'test-platform-view');
@ -297,7 +297,7 @@ void testMain() {
for (int i = 0; i < 16; i++) {
ui.platformViewRegistry.registerViewFactory(
'test-platform-view',
(int viewId) => html.DivElement()..id = 'view-$i',
(int viewId) => createDomHTMLDivElement()..id = 'view-$i',
);
await createPlatformView(i, 'test-platform-view');
platformViewIds.add(i);
@ -453,7 +453,7 @@ void testMain() {
for (int i = 0; i < 20; i++) {
ui.platformViewRegistry.registerViewFactory(
'test-platform-view',
(int viewId) => html.DivElement()..id = 'view-$i',
(int viewId) => createDomHTMLDivElement()..id = 'view-$i',
);
await createPlatformView(i, 'test-platform-view');
platformViewIds.add(i);
@ -583,7 +583,7 @@ void testMain() {
test('embeds and disposes of a platform view', () async {
ui.platformViewRegistry.registerViewFactory(
'test-platform-view',
(int viewId) => html.DivElement()..id = 'view-0',
(int viewId) => createDomHTMLDivElement()..id = 'view-0',
);
await createPlatformView(0, 'test-platform-view');
@ -626,7 +626,7 @@ void testMain() {
test('removed the DOM node of an unrendered platform view', () async {
ui.platformViewRegistry.registerViewFactory(
'test-platform-view',
(int viewId) => html.DivElement()..id = 'view-0',
(int viewId) => createDomHTMLDivElement()..id = 'view-0',
);
await createPlatformView(0, 'test-platform-view');
@ -688,7 +688,7 @@ void testMain() {
() async {
ui.platformViewRegistry.registerViewFactory(
'test-platform-view',
(int viewId) => html.DivElement()..id = 'test-view',
(int viewId) => createDomHTMLDivElement()..id = 'test-view',
);
await createPlatformView(0, 'test-platform-view');
@ -725,7 +725,7 @@ void testMain() {
() async {
ui.platformViewRegistry.registerViewFactory(
'test-platform-view',
(int viewId) => html.DivElement()..id = 'view-0',
(int viewId) => createDomHTMLDivElement()..id = 'view-0',
);
await createPlatformView(0, 'test-platform-view');
@ -748,7 +748,7 @@ void testMain() {
HtmlViewEmbedder.debugDisableOverlays = true;
ui.platformViewRegistry.registerViewFactory(
'test-platform-view',
(int viewId) => html.DivElement()..id = 'view-0',
(int viewId) => createDomHTMLDivElement()..id = 'view-0',
);
await createPlatformView(0, 'test-platform-view');
@ -778,7 +778,7 @@ void testMain() {
ui.platformViewRegistry.registerViewFactory(
'test-platform-view',
(int viewId) => html.DivElement()..id = 'view-0',
(int viewId) => createDomHTMLDivElement()..id = 'view-0',
);
await createPlatformView(0, 'test-platform-view');
await createPlatformView(1, 'test-platform-view');
@ -824,7 +824,7 @@ void testMain() {
HtmlViewEmbedder.debugDisableOverlays = true;
ui.platformViewRegistry.registerViewFactory(
'test-platform-view',
(int viewId) => html.DivElement()..id = 'view-0',
(int viewId) => createDomHTMLDivElement()..id = 'view-0',
);
await createPlatformView(0, 'test-platform-view');
await createPlatformView(1, 'test-platform-view');
@ -863,11 +863,11 @@ void testMain() {
ui.platformViewRegistry.registerViewFactory(
'test-visible-view',
(int viewId) =>
html.DivElement()..className = 'visible-platform-view');
createDomHTMLDivElement()..className = 'visible-platform-view');
ui.platformViewRegistry.registerViewFactory(
'test-invisible-view',
(int viewId) =>
html.DivElement()..className = 'invisible-platform-view',
createDomHTMLDivElement()..className = 'invisible-platform-view',
isVisible: false,
);
await createPlatformView(0, 'test-visible-view');

View File

@ -3,7 +3,6 @@
// found in the LICENSE file.
import 'dart:async';
import 'dart:html' as html;
import 'dart:typed_data';
import 'package:js/js.dart';
@ -533,7 +532,7 @@ void _testForImageCodecs({required bool useBrowserImageDecoder}) {
test('the same image can be rendered on difference surfaces', () async {
ui.platformViewRegistry.registerViewFactory(
'test-platform-view',
(int viewId) => html.DivElement()..id = 'view-0',
(int viewId) => createDomHTMLDivElement()..id = 'view-0',
);
await createPlatformView(0, 'test-platform-view');

View File

@ -1806,7 +1806,7 @@ void _testPlatformView() {
ui.platformViewRegistry.registerViewFactory(
'test-platform-view',
(int viewId) => html.DivElement()
(int viewId) => createDomHTMLDivElement()
..id = 'view-0'
..style.width = '100%'
..style.height = '100%',

View File

@ -3,7 +3,6 @@
// found in the LICENSE file.
import 'dart:async';
import 'dart:html' as html;
import 'package:test/bootstrap/browser.dart';
import 'package:test/test.dart';
@ -28,11 +27,11 @@ Future<void> testMain() async {
setUp(() async {
platformViewRegistry.registerViewFactory(
'test-0',
(int viewId) => html.DivElement(),
(int viewId) => createDomHTMLDivElement(),
);
platformViewRegistry.registerViewFactory(
'test-1',
(int viewId) => html.DivElement(),
(int viewId) => createDomHTMLDivElement(),
);
// Ensure the views are created...
await Future.wait(<Future<void>>[