[web] Migrate framework away from dart:html and package:js (#128580)
Use `package:web` and `dart:js_interop` instead. Part of https://github.com/flutter/flutter/issues/127030
This commit is contained in:
parent
52c4db8d33
commit
95be76ab7e
@ -48,5 +48,6 @@ const Set<String> kCorePackageAllowList = <String>{
|
||||
'test_api',
|
||||
'vector_math',
|
||||
'vm_service',
|
||||
'web',
|
||||
'webdriver',
|
||||
};
|
||||
|
@ -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.
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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(
|
||||
<String, Object>{
|
||||
'get': () { return get(); }.toJS
|
||||
}
|
||||
) as JSAny);
|
||||
mock,
|
||||
key.toJS,
|
||||
<String, JSFunction>{
|
||||
'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;
|
||||
|
@ -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<web.Element> get iterable => _genIterable(length, (JSNumber i) => item(i));
|
||||
}
|
||||
extension on web.CSSRuleList {
|
||||
Iterable<web.CSSRule> get iterable => _genIterable(length, (JSNumber i) => item(i));
|
||||
}
|
||||
|
||||
typedef ItemGetter<T> = T? Function(JSNumber index);
|
||||
Iterable<T> _genIterable<T>(JSNumber length, ItemGetter<T> getItem) {
|
||||
return Iterable<T>.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<RenderSelectionSpy>(find.byKey(spy));
|
||||
|
Loading…
x
Reference in New Issue
Block a user