Revert "[web] Migrate Flutter Web DOM usage to JS static interop - 44. (#33380)" (#34375)
This reverts commit 17c22c36dc0d0b00ddac06b7eea83886b9a31ffc.
diff --git a/lib/web_ui/lib/src/engine/dom.dart b/lib/web_ui/lib/src/engine/dom.dart
index 78dffb9..d409f61 100644
--- a/lib/web_ui/lib/src/engine/dom.dart
+++ b/lib/web_ui/lib/src/engine/dom.dart
@@ -49,13 +49,6 @@
]) as DomCSSStyleDeclaration;
external DomScreen? get screen;
external int requestAnimationFrame(DomRequestAnimationFrameCallback callback);
- void postMessage(Object message, String targetOrigin,
- [List<DomMessagePort>? messagePorts]) =>
- js_util.callMethod(this, 'postMessage', <Object>[
- message,
- targetOrigin,
- if (messagePorts != null) js_util.jsify(messagePorts)
- ]);
}
typedef DomRequestAnimationFrameCallback = void Function(num highResTime);
@@ -943,8 +936,6 @@
external String? get search;
// We have to change the name here because 'hash' is inherited from [Object].
String get locationHash => js_util.getProperty(this, 'hash');
- external String get origin;
- external String get href;
}
@JS()
@@ -1141,8 +1132,8 @@
external String? get data;
}
-DomCompositionEvent createDomCompositionEvent(String type,
- [Map<dynamic, dynamic>? options]) =>
+DomCompositionEvent createDomCompositionEvent(String type, [Map<dynamic,
+ dynamic>? options]) =>
js_util.callConstructor(domGetConstructor('CompositionEvent')!,
<Object>[type, if (options != null) js_util.jsify(options)]);
@@ -1183,7 +1174,6 @@
extension DomTokenListExtension on DomTokenList {
external void add(String value);
- external void remove(String value);
external bool contains(String token);
}
@@ -1327,64 +1317,6 @@
DomPoint(this.x, this.y);
}
-@JS()
-@staticInterop
-class DomWebSocket extends DomEventTarget {}
-
-extension DomWebSocketExtension on DomWebSocket {
- external void send(Object? data);
-}
-
-DomWebSocket createDomWebSocket(String url) =>
- domCallConstructorString('WebSocket', <Object>[url])! as DomWebSocket;
-
-@JS()
-@staticInterop
-class DomMessageEvent extends DomEvent {}
-
-extension DomMessageEventExtension on DomMessageEvent {
- dynamic get data => js_util.dartify(js_util.getProperty(this, 'data'));
- external String get origin;
-}
-
-@JS()
-@staticInterop
-class DomHTMLIFrameElement extends DomHTMLElement {}
-
-extension DomHTMLIFrameElementExtension on DomHTMLIFrameElement {
- external set src(String? value);
- external String? get src;
- external set height(String? value);
- external set width(String? value);
- external DomWindow get contentWindow;
-}
-
-DomHTMLIFrameElement createDomHTMLIFrameElement() =>
- domDocument.createElement('iframe') as DomHTMLIFrameElement;
-
-@JS()
-@staticInterop
-class DomMessagePort extends DomEventTarget {}
-
-extension DomMessagePortExtension on DomMessagePort {
- void postMessage(Object? message) => js_util.callMethod(this, 'postMessage',
- <Object>[if (message != null) js_util.jsify(message)]);
- external void start();
-}
-
-@JS()
-@staticInterop
-class DomMessageChannel {}
-
-extension DomMessageChannelExtension on DomMessageChannel {
- external DomMessagePort get port1;
- external DomMessagePort get port2;
-}
-
-DomMessageChannel createDomMessageChannel() =>
- domCallConstructorString('MessageChannel', <Object>[])!
- as DomMessageChannel;
-
Object? domGetConstructor(String constructorName) =>
js_util.getProperty(domWindow, constructorName);
diff --git a/sky/packages/sky_engine/BUILD.gn b/sky/packages/sky_engine/BUILD.gn
index 28d7ea3..c587ad8 100644
--- a/sky/packages/sky_engine/BUILD.gn
+++ b/sky/packages/sky_engine/BUILD.gn
@@ -200,6 +200,7 @@
" \"dart:core\": \"core/core.dart\"",
" \"dart:developer\": \"developer/developer.dart\"",
" \"dart:ffi\": \"ffi/ffi.dart\"",
+ " \"dart:html\": \"html/html_dart2js.dart\"",
" \"dart:io\": \"io/io.dart\"",
" \"dart:isolate\": \"isolate/isolate.dart\"",
" \"dart:js\": \"js/js.dart\"",
diff --git a/sky/packages/sky_engine/lib/_embedder.yaml b/sky/packages/sky_engine/lib/_embedder.yaml
index 0901274..c59d362 100644
--- a/sky/packages/sky_engine/lib/_embedder.yaml
+++ b/sky/packages/sky_engine/lib/_embedder.yaml
@@ -8,6 +8,7 @@
"dart:core": "../../../../../third_party/dart/sdk/lib/core/core.dart"
"dart:developer": "../../../../../third_party/dart/sdk/lib/developer/developer.dart"
"dart:ffi": "../../../../../third_party/dart/sdk/lib/ffi/ffi.dart"
+ "dart:html": "../../../../../third_party/dart/sdk/lib/html/html_dart2js.dart"
"dart:io": "../../../../../third_party/dart/sdk/lib/io/io.dart"
"dart:isolate": "../../../../../third_party/dart/sdk/lib/isolate/isolate.dart"
"dart:js": "../../../../../third_party/dart/sdk/lib/js/js.dart"
diff --git a/web_sdk/sdk_rewriter.dart b/web_sdk/sdk_rewriter.dart
index 3ab50d5..f7dfbf8 100644
--- a/web_sdk/sdk_rewriter.dart
+++ b/web_sdk/sdk_rewriter.dart
@@ -42,6 +42,7 @@
import 'dart:collection';
import 'dart:convert' hide Codec;
import 'dart:developer' as developer;
+import 'dart:html' as html;
import 'dart:js' as js;
import 'dart:js_util' as js_util;
import 'dart:_js_annotations';
diff --git a/web_sdk/test/js_access_test.dart b/web_sdk/test/js_access_test.dart
index dc45714..81ab8c5 100644
--- a/web_sdk/test/js_access_test.dart
+++ b/web_sdk/test/js_access_test.dart
@@ -64,6 +64,8 @@
final _CheckResult result = _checkFile(
File('lib/web_ui/lib/src/engine/alarm_clock.dart'),
'''
+import 'dart:html'
+ show HtmlElement;
import 'dart:async';
import 'package:ui/ui.dart'
as ui;
@@ -71,7 +73,8 @@
);
expect(result.failed, isTrue);
expect(result.violations, <String>[
- "on line 2: import is broken up into multiple lines: import 'package:ui/ui.dart'",
+ "on line 1: import is broken up into multiple lines: import 'dart:html'",
+ "on line 4: import is broken up into multiple lines: import 'package:ui/ui.dart'",
]);
}
diff --git a/web_sdk/test/sdk_rewriter_test.dart b/web_sdk/test/sdk_rewriter_test.dart
index 383db27..69c707f 100644
--- a/web_sdk/test/sdk_rewriter_test.dart
+++ b/web_sdk/test/sdk_rewriter_test.dart
@@ -30,6 +30,7 @@
import 'dart:collection';
import 'dart:convert' hide Codec;
import 'dart:developer' as developer;
+import 'dart:html' as html;
import 'dart:js' as js;
import 'dart:js_util' as js_util;
import 'dart:_js_annotations';
diff --git a/web_sdk/web_engine_tester/lib/golden_tester.dart b/web_sdk/web_engine_tester/lib/golden_tester.dart
index e5c2f04..db7b0dc 100644
--- a/web_sdk/web_engine_tester/lib/golden_tester.dart
+++ b/web_sdk/web_engine_tester/lib/golden_tester.dart
@@ -4,16 +4,14 @@
import 'dart:async';
import 'dart:convert';
+import 'dart:html' as html;
import 'package:test/test.dart';
-// ignore: implementation_imports
import 'package:ui/src/engine.dart' show operatingSystem, OperatingSystem, useCanvasKit;
-// ignore: implementation_imports
-import 'package:ui/src/engine/dom.dart';
import 'package:ui/ui.dart';
Future<dynamic> _callScreenshotServer(dynamic requestData) async {
- final DomXMLHttpRequest request = await domHttpRequest(
+ final html.HttpRequest request = await html.HttpRequest.request(
'screenshot',
method: 'POST',
sendData: json.encode(requestData),
diff --git a/web_sdk/web_engine_tester/lib/static/host.dart b/web_sdk/web_engine_tester/lib/static/host.dart
index e98cc23..2af3419 100644
--- a/web_sdk/web_engine_tester/lib/static/host.dart
+++ b/web_sdk/web_engine_tester/lib/static/host.dart
@@ -7,12 +7,11 @@
import 'dart:async';
import 'dart:convert';
+import 'dart:html';
import 'package:js/js.dart';
import 'package:stack_trace/stack_trace.dart';
import 'package:stream_channel/stream_channel.dart';
-// ignore: implementation_imports
-import 'package:ui/src/engine/dom.dart';
/// A class defined in content shell, used to control its behavior.
@JS()
@@ -47,14 +46,13 @@
external set _jsApi(_JSApi api);
/// The iframes created for each loaded test suite, indexed by the suite id.
-final Map<int, DomHTMLIFrameElement> _iframes = <int, DomHTMLIFrameElement>{};
+final Map<int, IFrameElement> _iframes = <int, IFrameElement>{};
/// Subscriptions created for each loaded test suite, indexed by the suite id.
-final Map<int, List<DomSubscription>> _domSubscriptions = <int, List<DomSubscription>>{};
-final Map<int, List<StreamSubscription<dynamic>>> _streamSubscriptions =<int, List<StreamSubscription<dynamic>>>{};
+final Map<int, List<StreamSubscription<dynamic>>> _subscriptions = <int, List<StreamSubscription<dynamic>>>{};
/// The URL for the current page.
-final Uri _currentUrl = Uri.parse(domWindow.location.href);
+final Uri _currentUrl = Uri.parse(window.location.href);
/// Code that runs in the browser and loads test suites at the server's behest.
///
@@ -113,7 +111,7 @@
testRunner?.waitUntilDone();
if (_currentUrl.queryParameters['debug'] == 'true') {
- domDocument.body!.classList.add('debug');
+ document.body!.classes.add('debug');
}
runZonedGuarded(
@@ -128,17 +126,14 @@
final StreamChannel<dynamic> iframeChannel = _connectToIframe(url, messageId);
suiteChannel.pipe(iframeChannel);
} else if (message['command'] == 'displayPause') {
- domDocument.body!.classList.add('paused');
+ document.body!.classes.add('paused');
} else if (message['command'] == 'resume') {
- domDocument.body!.classList.remove('paused');
+ document.body!.classes.remove('paused');
} else {
assert(message['command'] == 'closeSuite');
_iframes.remove(message['id'])!.remove();
- for (final DomSubscription subscription in _domSubscriptions.remove(message['id'])!) {
- subscription.cancel();
- }
- for (final StreamSubscription<dynamic> subscription in _streamSubscriptions.remove(message['id'])!) {
+ for (final StreamSubscription<dynamic> subscription in _subscriptions.remove(message['id'])!) {
subscription.cancel();
}
}
@@ -150,10 +145,9 @@
(_) => serverChannel.sink.add(<String, String>{'command': 'ping'}));
_jsApi = _JSApi(resume: allowInterop(() {
- if (!domDocument.body!.classList.contains('paused')) {
+ if (!document.body!.classes.remove('paused')) {
return;
}
- domDocument.body!.classList.remove('paused');
serverChannel.sink.add(<String, String>{'command': 'resume'});
}), restartCurrent: allowInterop(() {
serverChannel.sink.add(<String, String>{'command': 'restart'});
@@ -170,13 +164,13 @@
MultiChannel<dynamic> _connectToServer() {
// The `managerUrl` query parameter contains the WebSocket URL of the remote
// [BrowserManager] with which this communicates.
- final DomWebSocket webSocket = createDomWebSocket(_currentUrl.queryParameters['managerUrl']!);
+ final WebSocket webSocket = WebSocket(_currentUrl.queryParameters['managerUrl']!);
final StreamChannelController<dynamic> controller = StreamChannelController<dynamic>(sync: true);
- webSocket.addEventListener('message', allowInterop((DomEvent message) {
- final String data = (message as DomMessageEvent).data as String;
+ webSocket.onMessage.listen((MessageEvent message) {
+ final String data = message.data as String;
controller.local.sink.add(jsonDecode(data));
- }));
+ });
controller.local.stream
.listen((dynamic message) => webSocket.send(jsonEncode(message)));
@@ -189,34 +183,31 @@
///
/// [id] identifies the suite loaded in this iframe.
StreamChannel<dynamic> _connectToIframe(String url, int id) {
- final DomHTMLIFrameElement iframe = createDomHTMLIFrameElement();
+ final IFrameElement iframe = IFrameElement();
_iframes[id] = iframe;
iframe
..src = url
..width = '1000'
..height = '1000';
- domDocument.body!.appendChild(iframe);
+ document.body!.children.add(iframe);
// Use this to communicate securely with the iframe.
- final DomMessageChannel channel = createDomMessageChannel();
+ final MessageChannel channel = MessageChannel();
final StreamChannelController<dynamic> controller = StreamChannelController<dynamic>(sync: true);
// Use this to avoid sending a message to the iframe before it's sent a
// message to us. This ensures that no messages get dropped on the floor.
final Completer<dynamic> readyCompleter = Completer<dynamic>();
- final List<DomSubscription> domSubscriptions = <DomSubscription>[];
- final List<StreamSubscription<dynamic>> streamSubscriptions = <StreamSubscription<dynamic>>[];
- _domSubscriptions[id] = domSubscriptions;
- _streamSubscriptions[id] = streamSubscriptions;
- domSubscriptions.add(DomSubscription(domWindow, 'message',
- allowInterop((DomEvent event) {
- final DomMessageEvent message = event as DomMessageEvent;
+ final List<StreamSubscription<dynamic>> subscriptions = <StreamSubscription<dynamic>>[];
+ _subscriptions[id] = subscriptions;
+
+ subscriptions.add(window.onMessage.listen((dynamic message) {
// A message on the Window can theoretically come from any website. It's
// very unlikely that a malicious site would care about hacking someone's
// unit tests, let alone be able to find the test server while it's
// running, but it's good practice to check the origin anyway.
- if (message.origin != domWindow.location.origin) {
+ if (message.origin != window.location.origin) {
return;
}
@@ -229,24 +220,20 @@
if (message.data['ready'] == true) {
// This message indicates that the iframe is actively listening for
// events, so the message channel's second port can now be transferred.
- channel.port2.start();
- iframe.contentWindow.postMessage('port', domWindow.location.origin,
- <DomMessagePort>[channel.port2]);
+ iframe.contentWindow!.postMessage('port', window.location.origin, <MessagePort>[channel.port2]);
readyCompleter.complete();
} else if (message.data['exception'] == true) {
// This message from `dart.js` indicates that an exception occurred
// loading the test.
controller.local.sink.add(message.data['data']);
}
- })));
+ }));
- channel.port1.start();
- domSubscriptions.add(DomSubscription(channel.port1, 'message',
- allowInterop((DomEvent message) {
- controller.local.sink.add((message as DomMessageEvent).data['data']);
- })));
+ subscriptions.add(channel.port1.onMessage.listen((dynamic message) {
+ controller.local.sink.add(message.data['data']);
+ }));
- streamSubscriptions.add(controller.local.stream.listen((dynamic message) async {
+ subscriptions.add(controller.local.stream.listen((dynamic message) async {
await readyCompleter.future;
channel.port1.postMessage(message);
}));