Revert "[web] Migrate framework to fully use package:web" (#129400)
Reverts flutter/flutter#128901
context: ([cl/542712088](https://critique.corp.google.com/542712088) , [b/288495136](https://b.corp.google.com/288495136))
diff --git a/packages/flutter/lib/src/foundation/_platform_web.dart b/packages/flutter/lib/src/foundation/_platform_web.dart
index 0974c37..788cbf4 100644
--- a/packages/flutter/lib/src/foundation/_platform_web.dart
+++ b/packages/flutter/lib/src/foundation/_platform_web.dart
@@ -4,7 +4,7 @@
import 'dart:ui' as ui;
-import 'package:web/web.dart' as web;
+import '../services/dom.dart';
import 'platform.dart' as platform;
@@ -40,7 +40,7 @@
// 0.20ms. As `defaultTargetPlatform` is routinely called dozens of times per
// frame this value should be cached.
final platform.TargetPlatform _browserPlatform = () {
- final String navigatorPlatform = web.window.navigator.platform.toLowerCase();
+ final String navigatorPlatform = domWindow.navigator.platform?.toLowerCase() ?? '';
if (navigatorPlatform.startsWith('mac')) {
return platform.TargetPlatform.macOS;
}
@@ -60,7 +60,7 @@
// indicates that a device has a "fine pointer" (mouse) as the primary
// pointing device, then we'll assume desktop linux, and otherwise we'll
// assume Android.
- if (web.window.matchMedia('only screen and (pointer: fine)').matches) {
+ if (domWindow.matchMedia('only screen and (pointer: fine)').matches) {
return platform.TargetPlatform.linux;
}
return platform.TargetPlatform.android;
diff --git a/packages/flutter/lib/src/painting/_network_image_web.dart b/packages/flutter/lib/src/painting/_network_image_web.dart
index e3e88bd..ceb012e 100644
--- a/packages/flutter/lib/src/painting/_network_image_web.dart
+++ b/packages/flutter/lib/src/painting/_network_image_web.dart
@@ -7,17 +7,17 @@
import 'dart:ui' as ui;
import 'package:flutter/foundation.dart';
-import 'package:web/web.dart' as web;
+import '../services/dom.dart';
import 'image_provider.dart' as image_provider;
import 'image_stream.dart';
/// Creates a type for an overridable factory function for testing purposes.
-typedef HttpRequestFactory = web.XMLHttpRequest Function();
+typedef HttpRequestFactory = DomXMLHttpRequest Function();
/// Default HTTP client.
-web.XMLHttpRequest _httpClient() {
- return web.XMLHttpRequest();
+DomXMLHttpRequest _httpClient() {
+ return DomXMLHttpRequest();
}
/// Creates an overridable factory function.
@@ -135,9 +135,9 @@
// We use a different method when headers are set because the
// `ui.webOnlyInstantiateImageCodecFromUrl` method is not capable of handling headers.
if (isCanvasKit || containsNetworkImageHeaders) {
- final Completer<web.XMLHttpRequest> completer =
- Completer<web.XMLHttpRequest>();
- final web.XMLHttpRequest request = httpRequestFactory();
+ final Completer<DomXMLHttpRequest> completer =
+ Completer<DomXMLHttpRequest>();
+ final DomXMLHttpRequest request = httpRequestFactory();
request.open('GET', key.url, true);
request.responseType = 'arraybuffer';
@@ -147,9 +147,9 @@
});
}
- request.addEventListener('load', (web.Event e) {
- final int status = request.status;
- final bool accepted = status >= 200 && status < 300;
+ request.addEventListener('load', createDomEventListener((DomEvent e) {
+ final int? status = request.status;
+ final bool accepted = status! >= 200 && status < 300;
final bool fileUri = status == 0; // file:// URIs have status of 0.
final bool notModified = status == 304;
final bool unknownRedirect = status > 307 && status < 400;
@@ -161,11 +161,12 @@
} else {
completer.completeError(e);
throw image_provider.NetworkImageLoadException(
- statusCode: status, uri: resolved);
+ statusCode: request.status ?? 400, uri: resolved);
}
- }.toJS);
+ }));
- request.addEventListener('error', completer.completeError.toJS);
+ request.addEventListener('error',
+ createDomEventListener(completer.completeError));
request.send();
@@ -175,7 +176,7 @@
if (bytes.lengthInBytes == 0) {
throw image_provider.NetworkImageLoadException(
- statusCode: request.status, uri: resolved);
+ statusCode: request.status!, uri: resolved);
}
if (decode != null) {
diff --git a/packages/flutter/lib/src/services/dom.dart b/packages/flutter/lib/src/services/dom.dart
new file mode 100644
index 0000000..00d3770
--- /dev/null
+++ b/packages/flutter/lib/src/services/dom.dart
@@ -0,0 +1,416 @@
+// Copyright 2014 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'dart:js_interop';
+
+/// This file includes static interop helpers for Flutter Web.
+// TODO(joshualitt): This file will eventually be removed,
+// https://github.com/flutter/flutter/issues/113402.
+
+/// [DomWindow] interop object.
+@JS()
+@staticInterop
+class DomWindow {}
+
+/// [DomWindow] required extension.
+extension DomWindowExtension on DomWindow {
+ @JS('matchMedia')
+ external DomMediaQueryList _matchMedia(JSString? query);
+
+ /// Returns a [DomMediaQueryList] of the media that matches [query].
+ DomMediaQueryList matchMedia(String? query) => _matchMedia(query?.toJS);
+
+ /// Returns the [DomNavigator] associated with this window.
+ external DomNavigator get navigator;
+
+ /// Gets the current selection.
+ external DomSelection? getSelection();
+}
+
+/// The underyling window.
+@JS('window')
+external DomWindow get domWindow;
+
+/// [DomMediaQueryList] interop object.
+@JS()
+@staticInterop
+class DomMediaQueryList {}
+
+/// [DomMediaQueryList] required extension.
+extension DomMediaQueryListExtension on DomMediaQueryList {
+ @JS('matches')
+ external JSBoolean get _matches;
+
+ /// Whether or not the query matched.
+ bool get matches => _matches.toDart;
+}
+
+/// [DomNavigator] interop object.
+@JS()
+@staticInterop
+class DomNavigator {}
+
+/// [DomNavigator] required extension.
+extension DomNavigatorExtension on DomNavigator {
+ @JS('platform')
+ external JSString? get _platform;
+
+ /// The underyling platform string.
+ String? get platform => _platform?.toDart;
+}
+
+/// A DOM event target.
+@JS()
+@staticInterop
+class DomEventTarget {}
+
+/// [DomEventTarget]'s required extension.
+extension DomEventTargetExtension on DomEventTarget {
+ @JS('addEventListener')
+ external JSVoid _addEventListener1(JSString type, DomEventListener? listener);
+
+ @JS('addEventListener')
+ external JSVoid _addEventListener2(
+ JSString type, DomEventListener? listener, JSBoolean useCapture);
+
+ /// Adds an event listener to this event target.
+ @JS('addEventListener')
+ void addEventListener(String type, DomEventListener? listener,
+ [bool? useCapture]) {
+ if (listener != null) {
+ if (useCapture == null) {
+ _addEventListener1(type.toJS, listener);
+ } else {
+ _addEventListener2(type.toJS, listener, useCapture.toJS);
+ }
+ }
+ }
+}
+
+/// [DomXMLHttpRequest] interop class.
+@JS('XMLHttpRequest')
+@staticInterop
+class DomXMLHttpRequest extends DomEventTarget {
+ /// Constructor for [DomXMLHttpRequest].
+ external factory DomXMLHttpRequest();
+}
+
+/// [DomXMLHttpRequest] extension.
+extension DomXMLHttpRequestExtension on DomXMLHttpRequest {
+ /// Gets the response.
+ external JSAny? get response;
+
+ @JS('responseText')
+ external JSString? get _responseText;
+
+ /// Gets the response text.
+ String? get responseText => _responseText?.toDart;
+
+ @JS('responseType')
+ external JSString get _responseType;
+
+ /// Gets the response type.
+ String get responseType => _responseType.toDart;
+
+ @JS('status')
+ external JSNumber? get _status;
+
+ /// Gets the status.
+ int? get status => _status?.toDart.toInt();
+
+ @JS('responseType')
+ external set _responseType(JSString value);
+
+ /// Set the response type.
+ set responseType(String value) => _responseType = value.toJS;
+
+ @JS('setRequestHeader')
+ external void _setRequestHeader(JSString header, JSString value);
+
+ /// Set the request header.
+ void setRequestHeader(String header, String value) =>
+ _setRequestHeader(header.toJS, value.toJS);
+
+ @JS('open')
+ external JSVoid _open(JSString method, JSString url, JSBoolean isAsync);
+
+ /// Open the request.
+ void open(String method, String url, bool isAsync) =>
+ _open(method.toJS, url.toJS, isAsync.toJS);
+
+ /// Send the request.
+ external JSVoid send();
+}
+
+/// Type for event listener.
+typedef DartDomEventListener = JSVoid Function(DomEvent event);
+
+/// The type of [JSFunction] expected as an `EventListener`.
+@JS()
+@staticInterop
+class DomEventListener {}
+
+/// Creates a [DomEventListener] from a [DartDomEventListener].
+DomEventListener createDomEventListener(DartDomEventListener listener) =>
+ listener.toJS as DomEventListener;
+
+/// [DomEvent] interop object.
+@JS()
+@staticInterop
+class DomEvent {}
+
+/// [DomEvent] required extension.
+extension DomEventExtension on DomEvent {
+ @JS('type')
+ external JSString get _type;
+
+ /// Get the event type.
+ String get type => _type.toDart;
+
+ /// Initialize an event.
+ external JSVoid initEvent(
+ JSString type, JSBoolean bubbles, JSBoolean cancelable);
+}
+
+/// [DomProgressEvent] interop object.
+@JS()
+@staticInterop
+class DomProgressEvent extends DomEvent {}
+
+/// [DomProgressEvent] required extension.
+extension DomProgressEventExtension on DomProgressEvent {
+ @JS('loaded')
+ external JSNumber? get _loaded;
+
+ /// Amount of work done.
+ int? get loaded => _loaded?.toDart.toInt();
+
+ @JS('total')
+ external JSNumber? get _total;
+
+ /// Total amount of work.
+ int? get total => _total?.toDart.toInt();
+}
+
+/// The underlying DOM document.
+@JS()
+@staticInterop
+class DomDocument {}
+
+/// [DomDocument]'s required extension.
+extension DomDocumentExtension on DomDocument {
+ @JS('createEvent')
+ external DomEvent _createEvent(JSString eventType);
+
+ /// Creates an event.
+ DomEvent createEvent(String eventType) => _createEvent(eventType.toJS);
+
+ /// Creates a range.
+ external DomRange createRange();
+
+ /// Gets the head element.
+ external DomHTMLHeadElement? get head;
+
+ /// Creates a [DomElement].
+ @JS('createElement')
+ external DomElement createElement(JSString name);
+}
+
+/// Returns the top level document.
+@JS('window.document')
+external DomDocument get domDocument;
+
+/// Creates a new DOM event.
+DomEvent createDomEvent(String type, String name) {
+ final DomEvent event = domDocument.createEvent(type);
+ event.initEvent(name.toJS, true.toJS, true.toJS);
+ return event;
+}
+
+/// A Range object.
+@JS()
+@staticInterop
+class DomRange {}
+
+/// [DomRange]'s required extension.
+extension DomRangeExtension on DomRange {
+ /// Selects the provided node.
+ external JSVoid selectNode(DomNode node);
+}
+
+/// A node in the DOM.
+@JS()
+@staticInterop
+class DomNode extends DomEventTarget {}
+
+/// [DomNode]'s required extension.
+extension DomNodeExtension on DomNode {
+ @JS('innerText')
+ external set _innerText(JSString text);
+
+ /// Sets the innerText of this node.
+ set innerText(String text) => _innerText = text.toJS;
+
+ /// Appends a node this node.
+ external JSVoid append(DomNode node);
+}
+
+/// An element in the DOM.
+@JS()
+@staticInterop
+class DomElement extends DomNode {}
+
+/// [DomElement]'s required extension.
+extension DomElementExtension on DomElement {
+ /// Returns the style of this element.
+ external DomCSSStyleDeclaration get style;
+
+ /// Returns the class list of this element.
+ external DomTokenList get classList;
+}
+
+/// An HTML element in the DOM.
+@JS()
+@staticInterop
+class DomHTMLElement extends DomElement {}
+
+/// A UI event.
+@JS()
+@staticInterop
+class DomUIEvent extends DomEvent {}
+
+/// A mouse event.
+@JS()
+@staticInterop
+class DomMouseEvent extends DomUIEvent {}
+
+/// [DomMouseEvent]'s required extension.
+extension DomMouseEventExtension on DomMouseEvent {
+ @JS('offsetX')
+ external JSNumber get _offsetX;
+
+ /// Returns the current x offset.
+ num get offsetX => _offsetX.toDart;
+
+ @JS('offsetY')
+ external JSNumber get _offsetY;
+
+ /// Returns the current y offset.
+ num get offsetY => _offsetY.toDart;
+
+ @JS('button')
+ external JSNumber get _button;
+
+ /// Returns the current button.
+ int get button => _button.toDart.toInt();
+}
+
+/// A DOM selection.
+@JS()
+@staticInterop
+class DomSelection {}
+
+/// [DomSelection]'s required extension.
+extension DomSelectionExtension on DomSelection {
+ /// Removes all ranges from this selection.
+ external JSVoid removeAllRanges();
+
+ /// Adds a range to this selection.
+ external JSVoid addRange(DomRange range);
+}
+
+/// A DOM html div element.
+@JS()
+@staticInterop
+class DomHTMLDivElement extends DomHTMLElement {}
+
+/// Factory constructor for [DomHTMLDivElement].
+DomHTMLDivElement createDomHTMLDivElement() =>
+ domDocument.createElement('div'.toJS) as DomHTMLDivElement;
+
+/// An html style element.
+@JS()
+@staticInterop
+class DomHTMLStyleElement extends DomHTMLElement {}
+
+/// [DomHTMLStyleElement]'s required extension.
+extension DomHTMLStyleElementExtension on DomHTMLStyleElement {
+ /// Get's the style sheet of this element.
+ external DomStyleSheet? get sheet;
+}
+
+/// Factory constructor for [DomHTMLStyleElement].
+DomHTMLStyleElement createDomHTMLStyleElement() =>
+ domDocument.createElement('style'.toJS) as DomHTMLStyleElement;
+
+/// CSS styles.
+@JS()
+@staticInterop
+class DomCSSStyleDeclaration {}
+
+/// [DomCSSStyleDeclaration]'s required extension.
+extension DomCSSStyleDeclarationExtension on DomCSSStyleDeclaration {
+ /// Sets the width.
+ set width(String value) => setProperty('width', value);
+
+ /// Sets the height.
+ set height(String value) => setProperty('height', value);
+
+ @JS('setProperty')
+ external JSVoid _setProperty(
+ JSString propertyName, JSString value, JSString priority);
+
+ /// Sets a CSS property by name.
+ void setProperty(String propertyName, String value, [String? priority]) {
+ priority ??= '';
+ _setProperty(propertyName.toJS, value.toJS, priority.toJS);
+ }
+}
+
+/// The HTML head element.
+@JS()
+@staticInterop
+class DomHTMLHeadElement extends DomHTMLElement {}
+
+/// A DOM style sheet.
+@JS()
+@staticInterop
+class DomStyleSheet {}
+
+/// A DOM CSS style sheet.
+@JS()
+@staticInterop
+class DomCSSStyleSheet extends DomStyleSheet {}
+
+/// [DomCSSStyleSheet]'s required extension.
+extension DomCSSStyleSheetExtension on DomCSSStyleSheet {
+ @JS('insertRule')
+ external JSNumber _insertRule1(JSString rule);
+
+ @JS('insertRule')
+ external JSNumber _insertRule2(JSString rule, JSNumber index);
+
+ /// Inserts a rule into this style sheet.
+ int insertRule(String rule, [int? index]) {
+ if (index == null) {
+ return _insertRule1(rule.toJS).toDart.toInt();
+ } else {
+ return _insertRule2(rule.toJS, index.toDouble().toJS).toDart.toInt();
+ }
+ }
+}
+
+/// A list of token.
+@JS()
+@staticInterop
+class DomTokenList {}
+
+/// [DomTokenList]'s required extension.
+extension DomTokenListExtension on DomTokenList {
+ @JS('add')
+ external JSVoid _add(JSString value);
+
+ /// Adds a token to this token list.
+ void add(String value) => _add(value.toJS);
+}
diff --git a/packages/flutter/lib/src/widgets/_platform_selectable_region_context_menu_web.dart b/packages/flutter/lib/src/widgets/_platform_selectable_region_context_menu_web.dart
index 9e29598..2a5fa32 100644
--- a/packages/flutter/lib/src/widgets/_platform_selectable_region_context_menu_web.dart
+++ b/packages/flutter/lib/src/widgets/_platform_selectable_region_context_menu_web.dart
@@ -2,12 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-import 'dart:js_interop';
import 'dart:ui_web' as ui_web;
import 'package:flutter/rendering.dart';
-import 'package:web/web.dart' as web;
+import '../services/dom.dart';
import 'basic.dart';
import 'framework.dart';
import 'platform_view.dart';
@@ -28,7 +27,7 @@
''';
const int _kRightClickButton = 2;
-typedef _WebSelectionCallBack = void Function(web.HTMLElement, web.MouseEvent);
+typedef _WebSelectionCallBack = void Function(DomHTMLElement, DomMouseEvent);
/// Function signature for `ui_web.platformViewRegistry.registerViewFactory`.
@visibleForTesting
@@ -81,11 +80,11 @@
// Registers the view factories for the interceptor widgets.
static void _register() {
assert(_registeredViewType == null);
- _registeredViewType = _registerWebSelectionCallback((web.HTMLElement element, web.MouseEvent event) {
+ _registeredViewType = _registerWebSelectionCallback((DomHTMLElement element, DomMouseEvent event) {
final SelectionContainerDelegate? client = _activeClient;
if (client != null) {
// Converts the html right click event to flutter coordinate.
- final Offset localOffset = Offset(event.offsetX, event.offsetY);
+ final Offset localOffset = Offset(event.offsetX.toDouble(), event.offsetY.toDouble());
final Matrix4 transform = client.getTransformTo(null);
final Offset globalOffset = MatrixUtils.transformPoint(transform, localOffset);
client.dispatchSelectionEvent(SelectWordSelectionEvent(globalPosition: globalOffset));
@@ -94,9 +93,9 @@
element.innerText = client.getSelectedContent()?.plainText ?? '';
// Programmatically select the dom element in browser.
- final web.Range range = web.document.createRange();
+ final DomRange range = domDocument.createRange();
range.selectNode(element);
- final web.Selection? selection = web.window.getSelection();
+ final DomSelection? selection = domWindow.getSelection();
if (selection != null) {
selection.removeAllRanges();
selection.addRange(range);
@@ -107,26 +106,26 @@
static String _registerWebSelectionCallback(_WebSelectionCallBack callback) {
_registerViewFactory(_viewType, (int viewId) {
- final web.HTMLElement htmlElement = web.document.createElement('div') as web.HTMLElement;
+ final DomHTMLElement htmlElement = createDomHTMLDivElement();
htmlElement
..style.width = '100%'
..style.height = '100%'
..classList.add(_kClassName);
// Create css style for _kClassName.
- final web.HTMLStyleElement styleElement = web.document.createElement('style') as web.HTMLStyleElement;
- web.document.head!.append(styleElement);
- final web.CSSStyleSheet sheet = styleElement.sheet!;
+ final DomHTMLStyleElement styleElement = createDomHTMLStyleElement();
+ domDocument.head!.append(styleElement);
+ final DomCSSStyleSheet sheet = styleElement.sheet! as DomCSSStyleSheet;
sheet.insertRule(_kClassRule, 0);
sheet.insertRule(_kClassSelectionRule, 1);
- htmlElement.addEventListener('mousedown', (web.Event event) {
- final web.MouseEvent mouseEvent = event as web.MouseEvent;
+ htmlElement.addEventListener('mousedown', createDomEventListener((DomEvent event) {
+ final DomMouseEvent mouseEvent = event as DomMouseEvent;
if (mouseEvent.button != _kRightClickButton) {
return;
}
callback(htmlElement, mouseEvent);
- }.toJS);
+ }));
return htmlElement;
}, isVisible: false);
return _viewType;
diff --git a/packages/flutter/test/painting/_network_image_test_web.dart b/packages/flutter/test/painting/_network_image_test_web.dart
index 307d6f9..f82a6e1 100644
--- a/packages/flutter/test/painting/_network_image_test_web.dart
+++ b/packages/flutter/test/painting/_network_image_test_web.dart
@@ -5,8 +5,8 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/src/painting/_network_image_web.dart';
+import 'package:flutter/src/services/dom.dart';
import 'package:flutter_test/flutter_test.dart';
-import 'package:web/web.dart' as web;
import '../image_data.dart';
import '_test_http_request.dart';
@@ -20,7 +20,7 @@
(WidgetTester tester) async {
final TestHttpRequest testHttpRequest = TestHttpRequest()
..status = 200
- ..mockEvent = MockEvent('load', web.Event('test error'))
+ ..mockEvent = MockEvent('load', createDomEvent('Event', 'test error'))
..response = (Uint8List.fromList(kTransparentImage)).buffer;
httpRequestFactory = () {
@@ -46,7 +46,7 @@
(WidgetTester tester) async {
final TestHttpRequest testHttpRequest = TestHttpRequest()
..status = 404
- ..mockEvent = MockEvent('error', web.Event('test error'));
+ ..mockEvent = MockEvent('error', createDomEvent('Event', 'test error'));
httpRequestFactory = () {
@@ -64,14 +64,14 @@
);
await tester.pumpWidget(image);
- expect((tester.takeException() as web.ProgressEvent).type, 'test error');
+ expect((tester.takeException() as DomProgressEvent).type, 'test error');
});
testWidgets('loads an image from the network with empty response',
(WidgetTester tester) async {
final TestHttpRequest testHttpRequest = TestHttpRequest()
..status = 200
- ..mockEvent = MockEvent('load', web.Event('test error'))
+ ..mockEvent = MockEvent('load', createDomEvent('Event', 'test error'))
..response = (Uint8List.fromList(<int>[])).buffer;
httpRequestFactory = () {
diff --git a/packages/flutter/test/painting/_test_http_request.dart b/packages/flutter/test/painting/_test_http_request.dart
index 5dea12e..8324d9b 100644
--- a/packages/flutter/test/painting/_test_http_request.dart
+++ b/packages/flutter/test/painting/_test_http_request.dart
@@ -4,16 +4,16 @@
import 'dart:js_interop';
-import 'package:web/web.dart' as web;
+import 'package:flutter/src/services/dom.dart';
/// Defines a new property on an Object.
@JS('Object.defineProperty')
-external void objectDefineProperty(JSAny o, String symbol, JSAny desc);
+external JSVoid objectDefineProperty(JSAny o, JSString symbol, JSAny desc);
void createGetter(JSAny mock, String key, JSAny? Function() get) {
objectDefineProperty(
mock,
- key,
+ key.toJS,
<String, JSFunction>{
'get': (() => get()).toJS,
}.jsify()!,
@@ -35,8 +35,6 @@
});
}
-typedef _DartDomEventListener = JSVoid Function(web.Event event);
-
class TestHttpRequest {
TestHttpRequest() {
_mock = DomXMLHttpRequestMock(
@@ -62,26 +60,26 @@
Object? response;
Map<String, String> get responseHeaders => headers;
- JSVoid open(String method, String url, bool async) {}
+ JSVoid open(JSString method, JSString url, JSBoolean async) {}
JSVoid send() {}
- JSVoid setRequestHeader(String name, String value) {
- headers[name] = value;
+ JSVoid setRequestHeader(JSString name, JSString value) {
+ headers[name.toDart] = value.toDart;
}
- JSVoid addEventListener(String type, web.EventListener listener) {
- if (type == mockEvent?.type) {
- final _DartDomEventListener dartListener =
- (listener as JSExportedDartFunction).toDart as _DartDomEventListener;
+ JSVoid addEventListener(JSString type, DomEventListener listener) {
+ if (type.toDart == mockEvent?.type) {
+ final DartDomEventListener dartListener =
+ (listener as JSExportedDartFunction).toDart as DartDomEventListener;
dartListener(mockEvent!.event);
}
}
- web.XMLHttpRequest getMock() => _mock as web.XMLHttpRequest;
+ DomXMLHttpRequest getMock() => _mock as DomXMLHttpRequest;
}
class MockEvent {
MockEvent(this.type, this.event);
final String type;
- final web.Event event;
+ final DomEvent event;
}