Skip to content

Commit dcc645b

Browse files
Merge pull request #398 from Workiva/null-safe-dataTransfer
FED-2812 Catch MouseEvent.dataTransfer null exception
2 parents 2a0b883 + 9836919 commit dcc645b

File tree

2 files changed

+36
-1
lines changed

2 files changed

+36
-1
lines changed

lib/src/react_client/event_helpers.dart

+27-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ library react_client.event_helpers;
44
import 'dart:html';
55

66
import 'package:js/js_util.dart';
7+
import 'package:meta/meta.dart';
78
import 'package:react/react_client/js_interop_helpers.dart';
89
import 'package:react/src/react_client/synthetic_data_transfer.dart';
910
import 'package:react/src/react_client/synthetic_event_wrappers.dart';
@@ -72,7 +73,7 @@ SyntheticMouseEvent wrapNativeMouseEvent(MouseEvent nativeEvent) {
7273
'clientX': nativeEvent.client.x,
7374
'clientY': nativeEvent.client.y,
7475
'ctrlKey': nativeEvent.ctrlKey,
75-
'dataTransfer': nativeEvent.dataTransfer,
76+
'dataTransfer': nativeEvent.safeDataTransfer,
7677
'metaKey': nativeEvent.metaKey,
7778
'pageX': nativeEvent.page.x,
7879
'pageY': nativeEvent.page.y,
@@ -823,3 +824,28 @@ extension DataTransferHelper on SyntheticMouseEvent {
823824
/// See <https://developer.mozilla.org/en-US/docs/Web/API/DragEvent/dataTransfer>
824825
SyntheticDataTransfer? get dataTransfer => syntheticDataTransferFactory(getProperty(this, 'dataTransfer'));
825826
}
827+
828+
extension SafeNativeDataTransfer on MouseEvent {
829+
/// In Dart SDK versions with null-safety enabled,
830+
/// [the interop](https://github.com/dart-lang/sdk/blob/master/sdk/lib/html/dart2js/html_dart2js.dart#L22421-L22422)
831+
/// for [MouseEvent.dataTransfer] is non-nullable despite the
832+
/// [JS spec for `dataTransfer`](https://developer.mozilla.org/en-US/docs/Web/API/DragEvent/dataTransfer)
833+
/// clearly indicating that it can be null.
834+
///
835+
/// This can cause the SDK to throw when a `MouseEvent` is manually constructed, and the `dataTransfer`
836+
/// getter is then accessed when running with `sound_null_safety` enabled:
837+
/// ```
838+
/// Unexpected null value encountered in Dart web platform libraries.
839+
/// ```
840+
///
841+
/// This extension is used to catch the error within our [wrapNativeMouseEvent] function so that
842+
/// `SyntheticMouseEvent`s do not throw the null exception.
843+
@internal
844+
DataTransfer? get safeDataTransfer {
845+
DataTransfer? dataTransfer;
846+
try {
847+
dataTransfer = this.dataTransfer;
848+
} catch (_) {}
849+
return dataTransfer;
850+
}
851+
}

test/react_client/event_helpers_test.dart

+9
Original file line numberDiff line numberDiff line change
@@ -2105,6 +2105,15 @@ main() {
21052105
});
21062106
});
21072107
});
2108+
2109+
// See: `SafeNativeDataTransfer` extension
2110+
group('SafeNativeDataTransfer MouseEvent extension', () {
2111+
test(
2112+
'prevents faulty Dart SDK web platform null exceptions when '
2113+
'accessing the `dataTransfer` getter on a manually constructed MouseEvent', () {
2114+
expect(() => wrapNativeMouseEvent(MouseEvent('click')).dataTransfer, returnsNormally);
2115+
});
2116+
});
21082117
}
21092118

21102119
class MockDataTransfer extends Mock implements DataTransfer {}

0 commit comments

Comments
 (0)