Skip to content

Commit

Permalink
Fix concurrent overlay handling and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
amantoux committed Dec 26, 2023
1 parent 2b3a010 commit c4e60ec
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 31 deletions.
44 changes: 22 additions & 22 deletions packages/fleather/lib/src/widgets/text_selection.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1078,16 +1078,17 @@ class SelectionOverlay {
/// Builds the handles by inserting them into the [context]'s overlay.
/// {@endtemplate}
void showHandles() {
if (_handles != null) {
return;
}

_handles = <OverlayEntry>[
OverlayEntry(builder: _buildStartHandle),
OverlayEntry(builder: _buildEndHandle),
];
Overlay.of(context, rootOverlay: true, debugRequiredFor: debugRequiredFor)
.insertAll(_handles!);
SchedulerBinding.instance.addPostFrameCallback((_) {
if (_handles != null) {
return;
}
_handles = <OverlayEntry>[
OverlayEntry(builder: _buildStartHandle),
OverlayEntry(builder: _buildEndHandle),
];
Overlay.of(context, rootOverlay: true, debugRequiredFor: debugRequiredFor)
.insertAll(_handles!);
});
}

/// {@template flutter.widgets.SelectionOverlay.hideHandles}
Expand All @@ -1111,13 +1112,15 @@ class SelectionOverlay {
WidgetBuilder? contextMenuBuilder,
}) {
if (contextMenuBuilder == null) {
if (_toolbar != null) {
return;
}
_toolbar = OverlayEntry(builder: _buildToolbar);
Overlay.of(this.context,
rootOverlay: true, debugRequiredFor: debugRequiredFor)
.insert(_toolbar!);
SchedulerBinding.instance.addPostFrameCallback((_) {
if (_toolbar != null) {
return;
}
_toolbar = OverlayEntry(builder: _buildToolbar);
Overlay.of(this.context,
rootOverlay: true, debugRequiredFor: debugRequiredFor)
.insert(_toolbar!);
});
return;
}

Expand Down Expand Up @@ -1336,8 +1339,6 @@ class SelectionOverlay {
selectionEndpoints.first.point.dy - lineHeightAtStart,
);

// print('midpoint: $midpoint');

return _SelectionToolbarWrapper(
visibility: toolbarVisible,
layerLink: toolbarLayerLink,
Expand Down Expand Up @@ -1468,6 +1469,7 @@ class _SelectionToolbarWrapperState extends State<_SelectionToolbarWrapper>
@visibleForTesting
class SelectionHandleOverlay extends StatefulWidget {
const SelectionHandleOverlay({
super.key,
required this.type,
required this.handleLayerLink,
this.onSelectionHandleTapped,
Expand Down Expand Up @@ -2135,9 +2137,7 @@ class EditorTextSelectionGestureDetectorBuilder {
renderEditor.selectWord(cause: SelectionChangedCause.longPress);
}

//TODO: show magnifier

_dragStartViewportOffset = renderEditor.offset!.pixels;
_dragStartViewportOffset = renderEditor.offset?.pixels ?? 0;
_dragStartScrollOffset = _scrollPosition;
}
}
Expand Down
28 changes: 19 additions & 9 deletions packages/fleather/test/widgets/editor_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ void main() {

expect(find.text('Paste'), findsNothing);
await tester.longPress(find.byType(FleatherEditor));
tester.binding.scheduleWarmUpFrame();
await tester.pump();
// Given current toolbar implementation in Flutter no other choice
// than to search for "Paste" text
Expand All @@ -85,6 +86,7 @@ void main() {
expect(find.text('Paste'), findsNothing);
await tester.tap(find.byType(FleatherEditor));
await tester.tap(find.byType(FleatherEditor));
tester.binding.scheduleWarmUpFrame();
await tester.pump();
final finder = find.text('Paste');
expect(finder, findsOneWidget);
Expand Down Expand Up @@ -115,14 +117,15 @@ void main() {
final editor = EditorSandBox(tester: tester);
await editor.pump();
await tester.longPressAt(const Offset(20, 20));
tester.binding.scheduleWarmUpFrame();
await tester.pump();
expect(editor.findSelectionHandles(), findsNWidgets(2));
expect(find.byType(AdaptiveTextSelectionToolbar), findsOneWidget);
expect(find.byType(TextSelectionToolbar), findsOneWidget);
final state = tester.state(find.byType(RawEditor)) as RawEditorState;
state.updateEditingValueWithDeltas([delta]);
await tester.pump(throttleDuration);
expect(editor.findSelectionHandles(), findsNothing);
expect(find.byType(AdaptiveTextSelectionToolbar), findsNothing);
expect(find.byType(TextSelectionToolbar), findsNothing);
});

testWidgetsWithPlatform(
Expand All @@ -136,26 +139,28 @@ void main() {
await tester.tapAt(
tester.getTopLeft(find.byType(FleatherEditor)) + const Offset(1, 1),
buttons: kSecondaryMouseButton);
tester.binding.scheduleWarmUpFrame();
await tester.pump();
expect(
editor.selection,
const TextSelection(
baseOffset: 0,
extentOffset: 4,
affinity: TextAffinity.upstream));
expect(find.byType(AdaptiveTextSelectionToolbar), findsOneWidget);
expect(find.byType(CupertinoTextSelectionToolbar), findsOneWidget);
await tester.tapAt(
tester.getTopLeft(find.byType(FleatherEditor)) +
const Offset(10, 1),
buttons: kSecondaryMouseButton);
tester.binding.scheduleWarmUpFrame();
await tester.pump();
expect(
editor.selection,
const TextSelection(
baseOffset: 0,
extentOffset: 4,
affinity: TextAffinity.upstream));
expect(find.byType(AdaptiveTextSelectionToolbar), findsOneWidget);
expect(find.byType(CupertinoTextSelectionToolbar), findsOneWidget);
}, [TargetPlatform.iOS]);

testWidgetsWithPlatform(
Expand All @@ -170,20 +175,23 @@ void main() {
tester.getTopLeft(find.byType(FleatherEditor)) + const Offset(1, 1),
buttons: kSecondaryMouseButton);
await tester.pump();
tester.binding.scheduleWarmUpFrame();
expect(
editor.selection,
const TextSelection(
baseOffset: 0,
extentOffset: 4,
affinity: TextAffinity.upstream));
expect(find.byType(AdaptiveTextSelectionToolbar), findsOneWidget);
expect(find.byType(CupertinoTextSelectionToolbar), findsOneWidget);
await tester.tapAt(tester.getTopLeft(find.byType(FleatherEditor)) +
const Offset(1, 1));
await editor.pump();
tester.binding.scheduleWarmUpFrame();
await tester.pump();
await tester.tapAt(
tester.getTopLeft(find.byType(FleatherEditor)) + const Offset(1, 1),
buttons: kSecondaryMouseButton);
await editor.pump();
tester.binding.scheduleWarmUpFrame();
await tester.pump();
expect(
editor.selection,
const TextSelection.collapsed(
Expand All @@ -202,17 +210,19 @@ void main() {
tester.getTopLeft(find.byType(FleatherEditor)) +
const Offset(10, 1),
buttons: kSecondaryMouseButton);
tester.binding.scheduleWarmUpFrame();
await tester.pump();
expect(
editor.selection,
const TextSelection.collapsed(
offset: 1, affinity: TextAffinity.upstream));
expect(find.byType(AdaptiveTextSelectionToolbar), findsOneWidget);
expect(find.byType(DesktopTextSelectionToolbar), findsOneWidget);
await tester.tapAt(
tester.getTopLeft(find.byType(FleatherEditor)) + const Offset(5, 1),
buttons: kSecondaryMouseButton);
tester.binding.scheduleWarmUpFrame();
await tester.pump();
expect(find.byType(AdaptiveTextSelectionToolbar), findsNothing);
expect(find.byType(DesktopTextSelectionToolbar), findsNothing);
}, [TargetPlatform.windows]);

testWidgetsWithPlatform(
Expand Down

0 comments on commit c4e60ec

Please sign in to comment.