mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[web] Migrate Flutter Web DOM usage to JS static interop - 38. (flutter/engine#33374)
This commit is contained in:
parent
de593702de
commit
df7a821479
@ -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
|
||||
|
||||
@ -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')) {
|
||||
|
||||
@ -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 {}
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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,
|
||||
(_) {},
|
||||
);
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -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();
|
||||
}
|
||||
});
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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';
|
||||
|
||||
|
||||
@ -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');
|
||||
|
||||
@ -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');
|
||||
|
||||
|
||||
@ -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%',
|
||||
|
||||
@ -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>>[
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user