Unverified Commit 632681da authored by Mouad Debbar's avatar Mouad Debbar Committed by GitHub

Reland "[web] Migrate framework to fully use package:web (#128901)" (#132092)

Relanding https://github.com/flutter/flutter/pull/128901

Part of https://github.com/flutter/flutter/issues/113402
Part of https://github.com/flutter/flutter/issues/127030
parent d631b262
......@@ -4,7 +4,7 @@
import 'dart:ui_web' as ui_web;
import '../services/dom.dart';
import 'package:web/web.dart' as web;
import 'platform.dart' as platform;
......@@ -38,7 +38,7 @@ final platform.TargetPlatform? _testPlatform = () {
// 0.20ms. As `defaultTargetPlatform` is routinely called dozens of times per
// frame this value should be cached.
final platform.TargetPlatform _browserPlatform = () {
final String navigatorPlatform = domWindow.navigator.platform?.toLowerCase() ?? '';
final String navigatorPlatform = web.window.navigator.platform.toLowerCase();
if (navigatorPlatform.startsWith('mac')) {
return platform.TargetPlatform.macOS;
}
......@@ -58,7 +58,7 @@ final platform.TargetPlatform _browserPlatform = () {
// 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 (domWindow.matchMedia('only screen and (pointer: fine)').matches) {
if (web.window.matchMedia('only screen and (pointer: fine)').matches) {
return platform.TargetPlatform.linux;
}
return platform.TargetPlatform.android;
......
......@@ -7,17 +7,17 @@ import 'dart:js_interop';
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 = DomXMLHttpRequest Function();
typedef HttpRequestFactory = web.XMLHttpRequest Function();
/// Default HTTP client.
DomXMLHttpRequest _httpClient() {
return DomXMLHttpRequest();
web.XMLHttpRequest _httpClient() {
return web.XMLHttpRequest();
}
/// Creates an overridable factory function.
......@@ -135,9 +135,9 @@ class NetworkImage
// 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<DomXMLHttpRequest> completer =
Completer<DomXMLHttpRequest>();
final DomXMLHttpRequest request = httpRequestFactory();
final Completer<web.XMLHttpRequest> completer =
Completer<web.XMLHttpRequest>();
final web.XMLHttpRequest request = httpRequestFactory();
request.open('GET', key.url, true);
request.responseType = 'arraybuffer';
......@@ -147,9 +147,9 @@ class NetworkImage
});
}
request.addEventListener('load', createDomEventListener((DomEvent e) {
final int? status = request.status;
final bool accepted = status! >= 200 && status < 300;
request.addEventListener('load', (web.Event 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,12 +161,11 @@ class NetworkImage
} else {
completer.completeError(e);
throw image_provider.NetworkImageLoadException(
statusCode: request.status ?? 400, uri: resolved);
statusCode: status, uri: resolved);
}
}));
}.toJS);
request.addEventListener('error',
createDomEventListener(completer.completeError));
request.addEventListener('error', completer.completeError.toJS);
request.send();
......@@ -176,7 +175,7 @@ class NetworkImage
if (bytes.lengthInBytes == 0) {
throw image_provider.NetworkImageLoadException(
statusCode: request.status!, uri: resolved);
statusCode: request.status, uri: resolved);
}
if (decode != null) {
......
This diff is collapsed.
......@@ -2,11 +2,12 @@
// 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';
......@@ -27,7 +28,7 @@ const String _kClassRule = '''
''';
const int _kRightClickButton = 2;
typedef _WebSelectionCallBack = void Function(DomHTMLElement, DomMouseEvent);
typedef _WebSelectionCallBack = void Function(web.HTMLElement, web.MouseEvent);
/// Function signature for `ui_web.platformViewRegistry.registerViewFactory`.
@visibleForTesting
......@@ -80,11 +81,11 @@ class PlatformSelectableRegionContextMenu extends StatelessWidget {
// Registers the view factories for the interceptor widgets.
static void _register() {
assert(_registeredViewType == null);
_registeredViewType = _registerWebSelectionCallback((DomHTMLElement element, DomMouseEvent event) {
_registeredViewType = _registerWebSelectionCallback((web.HTMLElement element, web.MouseEvent event) {
final SelectionContainerDelegate? client = _activeClient;
if (client != null) {
// Converts the html right click event to flutter coordinate.
final Offset localOffset = Offset(event.offsetX.toDouble(), event.offsetY.toDouble());
final Offset localOffset = Offset(event.offsetX, event.offsetY);
final Matrix4 transform = client.getTransformTo(null);
final Offset globalOffset = MatrixUtils.transformPoint(transform, localOffset);
client.dispatchSelectionEvent(SelectWordSelectionEvent(globalPosition: globalOffset));
......@@ -93,9 +94,9 @@ class PlatformSelectableRegionContextMenu extends StatelessWidget {
element.innerText = client.getSelectedContent()?.plainText ?? '';
// Programmatically select the dom element in browser.
final DomRange range = domDocument.createRange();
final web.Range range = web.document.createRange();
range.selectNode(element);
final DomSelection? selection = domWindow.getSelection();
final web.Selection? selection = web.window.getSelection();
if (selection != null) {
selection.removeAllRanges();
selection.addRange(range);
......@@ -106,26 +107,26 @@ class PlatformSelectableRegionContextMenu extends StatelessWidget {
static String _registerWebSelectionCallback(_WebSelectionCallBack callback) {
_registerViewFactory(_viewType, (int viewId) {
final DomHTMLElement htmlElement = createDomHTMLDivElement();
final web.HTMLElement htmlElement = web.document.createElement('div') as web.HTMLElement;
htmlElement
..style.width = '100%'
..style.height = '100%'
..classList.add(_kClassName);
// Create css style for _kClassName.
final DomHTMLStyleElement styleElement = createDomHTMLStyleElement();
domDocument.head!.append(styleElement);
final DomCSSStyleSheet sheet = styleElement.sheet! as DomCSSStyleSheet;
final web.HTMLStyleElement styleElement = web.document.createElement('style') as web.HTMLStyleElement;
web.document.head!.append(styleElement);
final web.CSSStyleSheet sheet = styleElement.sheet!;
sheet.insertRule(_kClassRule, 0);
sheet.insertRule(_kClassSelectionRule, 1);
htmlElement.addEventListener('mousedown', createDomEventListener((DomEvent event) {
final DomMouseEvent mouseEvent = event as DomMouseEvent;
htmlElement.addEventListener('mousedown', (web.Event event) {
final web.MouseEvent mouseEvent = event as web.MouseEvent;
if (mouseEvent.button != _kRightClickButton) {
return;
}
callback(htmlElement, mouseEvent);
}));
}.toJS);
return htmlElement;
}, isVisible: false);
return _viewType;
......
......@@ -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 @@ void runTests() {
(WidgetTester tester) async {
final TestHttpRequest testHttpRequest = TestHttpRequest()
..status = 200
..mockEvent = MockEvent('load', createDomEvent('Event', 'test error'))
..mockEvent = MockEvent('load', web.Event('test error'))
..response = (Uint8List.fromList(kTransparentImage)).buffer;
httpRequestFactory = () {
......@@ -46,7 +46,7 @@ void runTests() {
(WidgetTester tester) async {
final TestHttpRequest testHttpRequest = TestHttpRequest()
..status = 404
..mockEvent = MockEvent('error', createDomEvent('Event', 'test error'));
..mockEvent = MockEvent('error', web.Event('test error'));
httpRequestFactory = () {
......@@ -64,14 +64,14 @@ void runTests() {
);
await tester.pumpWidget(image);
expect((tester.takeException() as DomProgressEvent).type, 'test error');
expect((tester.takeException() as web.ProgressEvent).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', createDomEvent('Event', 'test error'))
..mockEvent = MockEvent('load', web.Event('test error'))
..response = (Uint8List.fromList(<int>[])).buffer;
httpRequestFactory = () {
......
......@@ -4,16 +4,16 @@
import 'dart:js_interop';
import 'package:flutter/src/services/dom.dart';
import 'package:web/web.dart' as web;
/// Defines a new property on an Object.
@JS('Object.defineProperty')
external JSVoid objectDefineProperty(JSAny o, JSString symbol, JSAny desc);
external void objectDefineProperty(JSAny o, String symbol, JSAny desc);
void createGetter(JSAny mock, String key, JSAny? Function() get) {
objectDefineProperty(
mock,
key.toJS,
key,
<String, JSFunction>{
'get': (() => get()).toJS,
}.jsify()!,
......@@ -35,6 +35,8 @@ class DomXMLHttpRequestMock {
});
}
typedef _DartDomEventListener = JSVoid Function(web.Event event);
class TestHttpRequest {
TestHttpRequest() {
_mock = DomXMLHttpRequestMock(
......@@ -58,26 +60,26 @@ class TestHttpRequest {
Object? response;
Map<String, String> get responseHeaders => headers;
JSVoid open(JSString method, JSString url, JSBoolean async) {}
JSVoid open(String method, String url, bool async) {}
JSVoid send() {}
JSVoid setRequestHeader(JSString name, JSString value) {
headers[name.toDart] = value.toDart;
JSVoid setRequestHeader(String name, String value) {
headers[name] = value;
}
JSVoid addEventListener(JSString type, DomEventListener listener) {
if (type.toDart == mockEvent?.type) {
final DartDomEventListener dartListener =
(listener as JSExportedDartFunction).toDart as DartDomEventListener;
JSVoid addEventListener(String type, web.EventListener listener) {
if (type == mockEvent?.type) {
final _DartDomEventListener dartListener =
(listener as JSExportedDartFunction).toDart as _DartDomEventListener;
dartListener(mockEvent!.event);
}
}
DomXMLHttpRequest getMock() => _mock as DomXMLHttpRequest;
web.XMLHttpRequest getMock() => _mock as web.XMLHttpRequest;
}
class MockEvent {
MockEvent(this.type, this.event);
final String type;
final DomEvent event;
final web.Event event;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment