Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit ef4ac03

Browse files
committed
bug fix
1 parent 212aa26 commit ef4ac03

File tree

5 files changed

+56
-50
lines changed

5 files changed

+56
-50
lines changed

lib/web_ui/lib/src/engine/dom.dart

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2260,13 +2260,10 @@ extension DomMediaQueryListExtension on DomMediaQueryList {
22602260
bool get matches => _matches.toDart;
22612261

22622262
@JS('addListener')
2263-
external JSVoid _addListener(JSFunction? listener);
2264-
void addListener(DomEventListener? listener) => _addListener(listener?.toJS);
2263+
external JSVoid addListener(JSFunction? listener);
22652264

22662265
@JS('removeListener')
2267-
external JSVoid _removeListener(JSFunction? listener);
2268-
void removeListener(DomEventListener? listener) =>
2269-
_removeListener(listener?.toJS);
2266+
external JSVoid removeListener(JSFunction? listener);
22702267
}
22712268

22722269
@JS()

lib/web_ui/lib/src/engine/platform_dispatcher.dart

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ class HighContrastSupport {
4343

4444
/// Reference to css media query that indicates whether high contrast is on.
4545
final DomMediaQueryList _highContrastMediaQuery = domWindow.matchMedia(_highContrastMediaQueryString);
46-
late final DomEventListener _onHighContrastChangeListener =
47-
allowInterop(_onHighContrastChange);
46+
late final JSFunction _onHighContrastChangeListener =
47+
_onHighContrastChange.toJS;
4848

4949
bool get isHighContrastEnabled => _highContrastMediaQuery.matches;
5050

@@ -64,7 +64,7 @@ class HighContrastSupport {
6464
}
6565
}
6666

67-
void _onHighContrastChange(DomEvent event) {
67+
JSVoid _onHighContrastChange(DomEvent event) {
6868
final DomMediaQueryListEvent mqEvent = event as DomMediaQueryListEvent;
6969
final bool isHighContrastEnabled = mqEvent.matches!;
7070
for (final HighContrastListener listener in _listeners) {
@@ -1031,20 +1031,20 @@ class EnginePlatformDispatcher extends ui.PlatformDispatcher {
10311031
/// A callback that is invoked whenever [_brightnessMediaQuery] changes value.
10321032
///
10331033
/// Updates the [_platformBrightness] with the new user preference.
1034-
DomEventListener? _brightnessMediaQueryListener;
1034+
JSFunction? _brightnessMediaQueryListener;
10351035

10361036
/// Set the callback function for listening changes in [_brightnessMediaQuery] value.
10371037
void _addBrightnessMediaQueryListener() {
10381038
_updatePlatformBrightness(_brightnessMediaQuery.matches
10391039
? ui.Brightness.dark
10401040
: ui.Brightness.light);
10411041

1042-
_brightnessMediaQueryListener = allowInterop((DomEvent event) {
1042+
_brightnessMediaQueryListener = (DomEvent event) {
10431043
final DomMediaQueryListEvent mqEvent =
10441044
event as DomMediaQueryListEvent;
10451045
_updatePlatformBrightness(
10461046
mqEvent.matches! ? ui.Brightness.dark : ui.Brightness.light);
1047-
});
1047+
}.toJS;
10481048
_brightnessMediaQuery.addListener(_brightnessMediaQueryListener);
10491049
}
10501050

lib/web_ui/lib/src/engine/view_embedder/hot_restart_cache_handler.dart

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,35 @@ import 'package:ui/src/engine.dart';
99

1010
import '../dom.dart';
1111

12+
// This exists as an example of moving JS types into engine code. In the longer
13+
// term, [JSArrayStore] will become a regular [JSArray] and the interface here
14+
// will live someplace more discoverable. However, we can't do that until we
15+
// reify JS types on JS backends.
16+
// TODO(joshualitt): Get rid of this after we reify types on JS backends.
17+
@JS()
18+
@staticInterop
19+
class JSArrayStore {}
20+
21+
extension JSArrayMethods on JSArrayStore {
22+
@JS('length')
23+
external JSNumber get _length;
24+
int get length => _length.toDart.toInt();
25+
26+
external JSVoid push(JSAny? o);
27+
external JSAny? at(JSNumber i);
28+
JSAny? operator[](int i) => at(i.toJS);
29+
}
30+
31+
JSArrayStore newArray() => <JSAny>[].toJSAnyShallow as JSArrayStore;
32+
1233
/// This is state persistent across hot restarts that indicates what
1334
/// to clear. Delay removal of old visible state to make the
1435
/// transition appear smooth.
1536
@JS('window.__flutterState')
16-
external JSArray? get _hotRestartStore;
17-
List<Object?>? get hotRestartStore =>
18-
_hotRestartStore?.toObjectShallow as List<Object>?;
37+
external JSArrayStore? get hotRestartStore;
1938

2039
@JS('window.__flutterState')
21-
external set _hotRestartStore(JSArray? nodes);
22-
set hotRestartStore(List<Object?>? nodes) =>
23-
_hotRestartStore = nodes?.toJSAnyShallow as JSArray?;
40+
external set hotRestartStore(JSArrayStore? nodes);
2441

2542
/// Handles [DomElement]s that need to be removed after a hot-restart.
2643
///
@@ -31,7 +48,7 @@ set hotRestartStore(List<Object?>? nodes) =>
3148
/// everything in [_elements] is removed from the DOM.
3249
class HotRestartCacheHandler {
3350
HotRestartCacheHandler() {
34-
if (_elements.isNotEmpty) {
51+
if (_elements.length > 0) {
3552
// We are in a post hot-restart world, clear the elements now.
3653
_clearAllElements();
3754
}
@@ -40,32 +57,35 @@ class HotRestartCacheHandler {
4057
/// The js-interop layer backing [_elements].
4158
///
4259
/// Elements are stored in a JS global array named [defaultCacheName].
43-
late List<Object?>? _jsElements;
60+
late JSArrayStore? _jsElements;
4461

4562
/// The elements that need to be cleaned up after hot-restart.
46-
List<Object?> get _elements {
63+
JSArrayStore get _elements {
4764
_jsElements = hotRestartStore;
4865
if (_jsElements == null) {
49-
_jsElements = <Object>[];
66+
_jsElements = newArray();
5067
hotRestartStore = _jsElements;
5168
}
5269
return _jsElements!;
5370
}
5471

5572
/// Removes every element from [_elements] and empties the list.
5673
void _clearAllElements() {
57-
for (final Object? element in _elements) {
58-
if (element is DomElement) {
59-
element.remove();
74+
final JSArrayStore elements = _elements;
75+
final int length = elements.length;
76+
for (int i = 0; i < length; i++) {
77+
final JSAny? element = _elements[i];
78+
if (domInstanceOfString(element, 'Element')) {
79+
(element! as DomElement).remove();
6080
}
6181
}
62-
hotRestartStore = <Object>[];
82+
hotRestartStore = newArray();
6383
}
6484

6585
/// Registers a [DomElement] to be removed after hot-restart.
6686
void registerElement(DomElement element) {
67-
final List<Object?> elements = _elements;
68-
elements.add(element);
69-
hotRestartStore = elements;
87+
// TODO(joshualitt): remove when we reify types on JS backends.
88+
// ignore: unnecessary_cast
89+
_elements.push(element as JSAny);
7090
}
7191
}

lib/web_ui/test/engine/view_embedder/embedding_strategy/embedding_strategy_test.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,11 @@ void doTests() {
4747
strategy.registerElementForCleanup(other);
4848
strategy.registerElementForCleanup(another);
4949

50-
final List<Object?> cache = hotRestartStore!;
50+
final JSArrayStore cache = hotRestartStore!;
5151

52-
expect(cache, hasLength(3));
53-
expect(cache.first, toBeCached);
54-
expect(cache.last, another);
52+
expect(cache.length == 3, isTrue);
53+
expect(cache[0], toBeCached);
54+
expect(cache[2], another);
5555
});
5656
});
5757
}

lib/web_ui/test/engine/view_embedder/hot_restart_cache_handler_test.dart

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ void doTests() {
2020

2121
expect(cache, isNotNull);
2222

23-
final List<Object?>? domCache = hotRestartStore;
23+
final JSArrayStore? domCache = hotRestartStore;
2424

2525
expect(domCache, isNotNull);
26-
expect(domCache, isEmpty);
26+
expect(domCache!.length == 0, isTrue);
2727
});
2828
});
2929

@@ -38,20 +38,9 @@ void doTests() {
3838
final DomElement element = createDomElement('for-test');
3939
cache!.registerElement(element);
4040

41-
final List<Object?>? domCache = hotRestartStore;
42-
expect(domCache, hasLength(1));
43-
expect(domCache!.last, element);
44-
});
45-
46-
test('Registers elements in the DOM cache', () async {
47-
final DomElement element = createDomElement('for-test');
48-
domDocument.body!.append(element);
49-
50-
cache!.registerElement(element);
51-
52-
final List<Object?>? domCache = hotRestartStore;
53-
expect(domCache, hasLength(1));
54-
expect(domCache!.last, element);
41+
final JSArrayStore? domCache = hotRestartStore;
42+
expect(domCache!.length == 1, isTrue);
43+
expect(domCache[0], element);
5544
});
5645

5746
test('Clears registered elements from the DOM and the cache upon restart',
@@ -69,8 +58,8 @@ void doTests() {
6958
// Simulate a hot restart...
7059
cache = HotRestartCacheHandler();
7160

72-
final List<Object?>? domCache = hotRestartStore;
73-
expect(domCache, hasLength(0));
61+
final JSArrayStore? domCache = hotRestartStore;
62+
expect(domCache!.length == 0, isTrue);
7463
expect(element.isConnected, isFalse); // Removed
7564
expect(element2.isConnected, isTrue);
7665
});

0 commit comments

Comments
 (0)