mirror of
https://github.com/flutter/flutter
synced 2024-10-06 00:09:53 +00:00
[SelectionOverlay]Move the debug statement to the scope of the assertion. (#108508)
This commit is contained in:
parent
611514886b
commit
c4df6b6d09
|
@ -132,7 +132,7 @@ class _OverlayExampleState extends State<OverlayExample> {
|
||||||
);
|
);
|
||||||
|
|
||||||
// Add the OverlayEntry to the Overlay.
|
// Add the OverlayEntry to the Overlay.
|
||||||
Overlay.of(context)!.insert(overlayEntry!);
|
Overlay.of(context, debugRequiredFor: widget)!.insert(overlayEntry!);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the OverlayEntry.
|
// Remove the OverlayEntry.
|
||||||
|
|
|
@ -363,7 +363,7 @@ class _CupertinoContextMenuState extends State<CupertinoContextMenu> with Ticker
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
Overlay.of(context, rootOverlay: true)!.insert(_lastOverlayEntry!);
|
Overlay.of(context, rootOverlay: true, debugRequiredFor: widget)!.insert(_lastOverlayEntry!);
|
||||||
_openController.forward();
|
_openController.forward();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1004,7 +1004,7 @@ class _BottomNavigationBarState extends State<BottomNavigationBar> with TickerPr
|
||||||
assert(debugCheckHasDirectionality(context));
|
assert(debugCheckHasDirectionality(context));
|
||||||
assert(debugCheckHasMaterialLocalizations(context));
|
assert(debugCheckHasMaterialLocalizations(context));
|
||||||
assert(debugCheckHasMediaQuery(context));
|
assert(debugCheckHasMediaQuery(context));
|
||||||
assert(Overlay.of(context, debugRequiredFor: widget) != null);
|
assert(debugCheckHasOverlay(context));
|
||||||
|
|
||||||
final BottomNavigationBarThemeData bottomTheme = BottomNavigationBarTheme.of(context);
|
final BottomNavigationBarThemeData bottomTheme = BottomNavigationBarTheme.of(context);
|
||||||
final BottomNavigationBarLandscapeLayout layout = widget.landscapeLayout
|
final BottomNavigationBarLandscapeLayout layout = widget.landscapeLayout
|
||||||
|
|
|
@ -655,7 +655,7 @@ class _RangeSliderState extends State<RangeSlider> with TickerProviderStateMixin
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
Overlay.of(context)!.insert(overlayEntry!);
|
Overlay.of(context, debugRequiredFor: widget)!.insert(overlayEntry!);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -842,7 +842,7 @@ class _SliderState extends State<Slider> with TickerProviderStateMixin {
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
Overlay.of(context)!.insert(overlayEntry!);
|
Overlay.of(context, debugRequiredFor: widget)!.insert(overlayEntry!);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -698,7 +698,7 @@ class TooltipState extends State<Tooltip> with SingleTickerProviderStateMixin {
|
||||||
if (_tooltipMessage.isEmpty) {
|
if (_tooltipMessage.isEmpty) {
|
||||||
return widget.child ?? const SizedBox();
|
return widget.child ?? const SizedBox();
|
||||||
}
|
}
|
||||||
assert(Overlay.of(context, debugRequiredFor: widget) != null);
|
assert(debugCheckHasOverlay(context));
|
||||||
final ThemeData theme = Theme.of(context);
|
final ThemeData theme = Theme.of(context);
|
||||||
final TooltipThemeData tooltipTheme = TooltipTheme.of(context);
|
final TooltipThemeData tooltipTheme = TooltipTheme.of(context);
|
||||||
final TextStyle defaultTextStyle;
|
final TextStyle defaultTextStyle;
|
||||||
|
|
|
@ -432,7 +432,7 @@ class _RawAutocompleteState<T extends Object> extends State<RawAutocomplete<T>>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
Overlay.of(context, rootOverlay: true)!.insert(newFloatingOptions);
|
Overlay.of(context, rootOverlay: true, debugRequiredFor: widget)!.insert(newFloatingOptions);
|
||||||
_floatingOptions = newFloatingOptions;
|
_floatingOptions = newFloatingOptions;
|
||||||
} else {
|
} else {
|
||||||
_floatingOptions = null;
|
_floatingOptions = null;
|
||||||
|
|
|
@ -9,6 +9,7 @@ import 'package:flutter/services.dart';
|
||||||
|
|
||||||
import 'basic.dart';
|
import 'basic.dart';
|
||||||
import 'binding.dart';
|
import 'binding.dart';
|
||||||
|
import 'debug.dart';
|
||||||
import 'framework.dart';
|
import 'framework.dart';
|
||||||
import 'media_query.dart';
|
import 'media_query.dart';
|
||||||
import 'overlay.dart';
|
import 'overlay.dart';
|
||||||
|
@ -598,7 +599,7 @@ class _DraggableState<T extends Object> extends State<Draggable<T>> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
assert(Overlay.of(context, debugRequiredFor: widget, rootOverlay: widget.rootOverlay) != null);
|
assert(debugCheckHasOverlay(context));
|
||||||
final bool canDrag = widget.maxSimultaneousDrags == null ||
|
final bool canDrag = widget.maxSimultaneousDrags == null ||
|
||||||
_activeCount < widget.maxSimultaneousDrags!;
|
_activeCount < widget.maxSimultaneousDrags!;
|
||||||
final bool showChild = _activeCount == 0 || widget.childWhenDragging == null;
|
final bool showChild = _activeCount == 0 || widget.childWhenDragging == null;
|
||||||
|
|
|
@ -702,7 +702,7 @@ class SliverReorderableListState extends State<SliverReorderableList> with Ticke
|
||||||
);
|
);
|
||||||
_dragInfo!.startDrag();
|
_dragInfo!.startDrag();
|
||||||
|
|
||||||
final OverlayState overlay = Overlay.of(context)!;
|
final OverlayState overlay = Overlay.of(context, debugRequiredFor: widget)!;
|
||||||
assert(_overlayEntry == null);
|
assert(_overlayEntry == null);
|
||||||
_overlayEntry = OverlayEntry(builder: _dragInfo!.createProxy);
|
_overlayEntry = OverlayEntry(builder: _dragInfo!.createProxy);
|
||||||
overlay.insert(_overlayEntry!);
|
overlay.insert(_overlayEntry!);
|
||||||
|
@ -897,7 +897,7 @@ class SliverReorderableListState extends State<SliverReorderableList> with Ticke
|
||||||
}
|
}
|
||||||
final Widget child = widget.itemBuilder(context, index);
|
final Widget child = widget.itemBuilder(context, index);
|
||||||
assert(child.key != null, 'All list items must have a key');
|
assert(child.key != null, 'All list items must have a key');
|
||||||
final OverlayState overlay = Overlay.of(context)!;
|
final OverlayState overlay = Overlay.of(context, debugRequiredFor: widget)!;
|
||||||
return _ReorderableItem(
|
return _ReorderableItem(
|
||||||
key: _ReorderableItemGlobalKey(child.key!, index, this),
|
key: _ReorderableItemGlobalKey(child.key!, index, this),
|
||||||
index: index,
|
index: index,
|
||||||
|
@ -1284,7 +1284,7 @@ class _DragInfo extends Drag {
|
||||||
}
|
}
|
||||||
|
|
||||||
Offset _overlayOrigin(BuildContext context) {
|
Offset _overlayOrigin(BuildContext context) {
|
||||||
final OverlayState overlay = Overlay.of(context)!;
|
final OverlayState overlay = Overlay.of(context, debugRequiredFor: context.widget)!;
|
||||||
final RenderBox overlayBox = overlay.context.findRenderObject()! as RenderBox;
|
final RenderBox overlayBox = overlay.context.findRenderObject()! as RenderBox;
|
||||||
return overlayBox.localToGlobal(Offset.zero);
|
return overlayBox.localToGlobal(Offset.zero);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import 'package:flutter/services.dart';
|
||||||
|
|
||||||
import 'actions.dart';
|
import 'actions.dart';
|
||||||
import 'basic.dart';
|
import 'basic.dart';
|
||||||
|
import 'debug.dart';
|
||||||
import 'focus_manager.dart';
|
import 'focus_manager.dart';
|
||||||
import 'focus_scope.dart';
|
import 'focus_scope.dart';
|
||||||
import 'framework.dart';
|
import 'framework.dart';
|
||||||
|
@ -804,7 +805,7 @@ class _SelectableRegionState extends State<SelectableRegion> with TextSelectionD
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
assert(Overlay.of(context, debugRequiredFor: widget) != null);
|
assert(debugCheckHasOverlay(context));
|
||||||
return CompositedTransformTarget(
|
return CompositedTransformTarget(
|
||||||
link: _toolbarLayerLink,
|
link: _toolbarLayerLink,
|
||||||
child: RawGestureDetector(
|
child: RawGestureDetector(
|
||||||
|
|
|
@ -16,6 +16,7 @@ import 'basic.dart';
|
||||||
import 'binding.dart';
|
import 'binding.dart';
|
||||||
import 'constants.dart';
|
import 'constants.dart';
|
||||||
import 'container.dart';
|
import 'container.dart';
|
||||||
|
import 'debug.dart';
|
||||||
import 'editable_text.dart';
|
import 'editable_text.dart';
|
||||||
import 'framework.dart';
|
import 'framework.dart';
|
||||||
import 'gesture_detector.dart';
|
import 'gesture_detector.dart';
|
||||||
|
@ -616,15 +617,8 @@ class SelectionOverlay {
|
||||||
_endHandleType = endHandleType,
|
_endHandleType = endHandleType,
|
||||||
_lineHeightAtEnd = lineHeightAtEnd,
|
_lineHeightAtEnd = lineHeightAtEnd,
|
||||||
_selectionEndpoints = selectionEndpoints,
|
_selectionEndpoints = selectionEndpoints,
|
||||||
_toolbarLocation = toolbarLocation {
|
_toolbarLocation = toolbarLocation,
|
||||||
final OverlayState? overlay = Overlay.of(context, rootOverlay: true);
|
assert(debugCheckHasOverlay(context));
|
||||||
assert(
|
|
||||||
overlay != null,
|
|
||||||
'No Overlay widget exists above $context.\n'
|
|
||||||
'Usually the Navigator created by WidgetsApp provides the overlay. Perhaps your '
|
|
||||||
'app content was created above the Navigator with the WidgetsApp builder parameter.',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The context in which the selection handles should appear.
|
/// The context in which the selection handles should appear.
|
||||||
///
|
///
|
||||||
|
|
|
@ -176,6 +176,37 @@ void main() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testWidgets('throw if no Overlay widget exists above', (WidgetTester tester) async {
|
||||||
|
await tester.pumpWidget(
|
||||||
|
const Directionality(
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
child: MediaQuery(
|
||||||
|
data: MediaQueryData(size: Size(800.0, 600.0)),
|
||||||
|
child: Center(
|
||||||
|
child: Material(
|
||||||
|
child: SelectableText('I love Flutter!'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
final Offset textFieldStart = tester.getTopLeft(find.byType(SelectableText));
|
||||||
|
final TestGesture gesture = await tester.startGesture(textFieldStart, kind: PointerDeviceKind.mouse);
|
||||||
|
await tester.pump(const Duration(seconds: 2));
|
||||||
|
await gesture.up();
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
final FlutterError error = tester.takeException() as FlutterError;
|
||||||
|
expect(
|
||||||
|
error.message,
|
||||||
|
contains('EditableText widgets require an Overlay widget ancestor'),
|
||||||
|
);
|
||||||
|
|
||||||
|
await tester.pumpWidget(const SizedBox.shrink());
|
||||||
|
expect(tester.takeException(), isNotNull); // side effect exception
|
||||||
|
});
|
||||||
|
|
||||||
testWidgets('Do not crash when remove SelectableText during handle drag', (WidgetTester tester) async {
|
testWidgets('Do not crash when remove SelectableText during handle drag', (WidgetTester tester) async {
|
||||||
// Regression test https://github.com/flutter/flutter/issues/108242
|
// Regression test https://github.com/flutter/flutter/issues/108242
|
||||||
bool isShow = true;
|
bool isShow = true;
|
||||||
|
|
Loading…
Reference in a new issue