diff --git a/dev/bots/allowlist.dart b/dev/bots/allowlist.dart index cd011c38be..966c3d89d5 100644 --- a/dev/bots/allowlist.dart +++ b/dev/bots/allowlist.dart @@ -48,5 +48,6 @@ const Set kCorePackageAllowList = { 'test_api', 'vector_math', 'vm_service', + 'web', 'webdriver', }; diff --git a/packages/flutter/lib/src/foundation/_capabilities_web.dart b/packages/flutter/lib/src/foundation/_capabilities_web.dart index 86deb78d0d..a71c517d8e 100644 --- a/packages/flutter/lib/src/foundation/_capabilities_web.dart +++ b/packages/flutter/lib/src/foundation/_capabilities_web.dart @@ -2,11 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// For now, we're hiding dart:js_interop's `@JS` to avoid a conflict with -// package:js' `@JS`. In the future, we should be able to remove package:js -// altogether and just import dart:js_interop. -import 'dart:js_interop' hide JS; -import 'package:js/js.dart'; +import 'dart:js_interop'; // This value is set by the engine. It is used to determine if the application is // using canvaskit. diff --git a/packages/flutter/lib/src/services/dom.dart b/packages/flutter/lib/src/services/dom.dart index c9181beede..00d3770949 100644 --- a/packages/flutter/lib/src/services/dom.dart +++ b/packages/flutter/lib/src/services/dom.dart @@ -2,11 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// For now, we're hiding dart:js_interop's `@JS` to avoid a conflict with -// package:js' `@JS`. In the future, we should be able to remove package:js -// altogether and just import dart:js_interop. -import 'dart:js_interop' hide JS; -import 'package:js/js.dart'; +import 'dart:js_interop'; /// This file includes static interop helpers for Flutter Web. // TODO(joshualitt): This file will eventually be removed, diff --git a/packages/flutter/pubspec.yaml b/packages/flutter/pubspec.yaml index a07d3a2a96..c10bb9087b 100644 --- a/packages/flutter/pubspec.yaml +++ b/packages/flutter/pubspec.yaml @@ -9,10 +9,10 @@ dependencies: # To update these, use "flutter update-packages --force-upgrade". characters: 1.3.0 collection: 1.17.2 - js: 0.6.7 material_color_utilities: 0.5.0 meta: 1.9.1 vector_math: 2.1.4 + web: 0.1.3-beta sky_engine: sdk: flutter @@ -72,4 +72,4 @@ dev_dependencies: webkit_inspection_protocol: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" yaml: 3.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" -# PUBSPEC CHECKSUM: dd07 +# PUBSPEC CHECKSUM: d32a diff --git a/packages/flutter/test/painting/_test_http_request.dart b/packages/flutter/test/painting/_test_http_request.dart index 9bb9be7ffe..8324d9b5e2 100644 --- a/packages/flutter/test/painting/_test_http_request.dart +++ b/packages/flutter/test/painting/_test_http_request.dart @@ -2,14 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// For now, we're hiding dart:js_interop's `@JS` to avoid a conflict with -// package:js' `@JS`. In the future, we should be able to remove package:js -// altogether and just import dart:js_interop. -import 'dart:js_interop' hide JS; +import 'dart:js_interop'; import 'package:flutter/src/services/dom.dart'; -import 'package:js/js.dart'; -import 'package:js/js_util.dart' as js_util; /// Defines a new property on an Object. @JS('Object.defineProperty') @@ -17,13 +12,12 @@ external JSVoid objectDefineProperty(JSAny o, JSString symbol, JSAny desc); void createGetter(JSAny mock, String key, JSAny? Function() get) { objectDefineProperty( - mock, - key.toJS, - js_util.jsify( - { - 'get': () { return get(); }.toJS - } - ) as JSAny); + mock, + key.toJS, + { + 'get': (() => get()).toJS, + }.jsify()!, + ); } @JS() @@ -51,13 +45,12 @@ class TestHttpRequest { ); // TODO(srujzs): This is needed for when we reify JS types. Right now, JSAny // is a typedef for Object?, but when we reify, it'll be its own type. - // ignore: unnecessary_cast final JSAny mock = _mock as JSAny; - createGetter(mock, 'headers', () => js_util.jsify(headers) as JSAny); + createGetter(mock, 'headers', () => headers.jsify()); createGetter(mock, - 'responseHeaders', () => js_util.jsify(responseHeaders) as JSAny); + 'responseHeaders', () => responseHeaders.jsify()); createGetter(mock, 'status', () => status.toJS); - createGetter(mock, 'response', () => js_util.jsify(response) as JSAny); + createGetter(mock, 'response', () => response.jsify()); } late DomXMLHttpRequestMock _mock; diff --git a/packages/flutter/test/widgets/selectable_region_context_menu_test.dart b/packages/flutter/test/widgets/selectable_region_context_menu_test.dart index 5ba4616402..e49aa01edd 100644 --- a/packages/flutter/test/widgets/selectable_region_context_menu_test.dart +++ b/packages/flutter/test/widgets/selectable_region_context_menu_test.dart @@ -5,20 +5,36 @@ @TestOn('browser') // This file contains web-only library. library; -import 'dart:html' as html; +import 'dart:js_interop'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:web/web.dart' as web; + +extension on JSString { + external JSBoolean includes(JSString searchString); +} +extension on web.HTMLCollection { + Iterable get iterable => _genIterable(length, (JSNumber i) => item(i)); +} +extension on web.CSSRuleList { + Iterable get iterable => _genIterable(length, (JSNumber i) => item(i)); +} + +typedef ItemGetter = T? Function(JSNumber index); +Iterable _genIterable(JSNumber length, ItemGetter getItem) { + return Iterable.generate(length.toDart.toInt(), (int index) => getItem(index.toJS)!); +} void main() { - html.Element? element; + web.HTMLElement? element; PlatformSelectableRegionContextMenu.debugOverrideRegisterViewFactory = (String viewType, Object Function(int viewId) fn, {bool isVisible = true}) { - element = fn(0) as html.Element; + element = fn(0) as web.HTMLElement; // The element needs to be attached to the document body to receive mouse // events. - html.document.body!.append(element!); + web.document.body!.append(element); }; // This force register the dom element. PlatformSelectableRegionContextMenu(child: const Placeholder()); @@ -26,19 +42,24 @@ void main() { test('DOM element is set up correctly', () async { expect(element, isNotNull); - expect(element!.style.width, '100%'); - expect(element!.style.height, '100%'); - expect(element!.classes.length, 1); - final String className = element!.classes.first; + expect(element!.style.width, '100%'.toJS); + expect(element!.style.height, '100%'.toJS); + expect(element!.classList.length, 1.toJS); + final JSString className = element!.className; - expect(html.document.head!.children, isNotEmpty); + expect(web.document.head!.children.iterable, isNotEmpty); bool foundStyle = false; - for (final html.Element element in html.document.head!.children) { - if (element is! html.StyleElement) { + for (final web.Element element in web.document.head!.children.iterable) { + if (element.tagName != 'STYLE'.toJS) { continue; } - final html.CssStyleSheet sheet = element.sheet! as html.CssStyleSheet; - foundStyle = sheet.rules!.any((html.CssRule rule) => rule.cssText!.contains(className)); + final web.CSSRuleList? rules = (element as web.HTMLStyleElement).sheet?.rules; + if (rules != null) { + foundStyle = rules.iterable.any((web.CSSRule rule) => rule.cssText.includes(className).toDart); + } + if (foundStyle) { + break; + } } expect(foundStyle, isTrue); }); @@ -62,11 +83,13 @@ void main() { // Dispatch right click. element!.dispatchEvent( - html.MouseEvent( - 'mousedown', - button: 2, - clientX: 200, - clientY: 300, + web.MouseEvent( + 'mousedown'.toJS, + web.MouseEventInit( + button: 2.toJS, + clientX: 200.toJS, + clientY: 300.toJS, + ), ), ); final RenderSelectionSpy renderSelectionSpy = tester.renderObject(find.byKey(spy));