Commit 5252a300 authored by Ian Hickson's avatar Ian Hickson

Merge pull request #709 from Hixie/canPop

Navigator.canPop(context)
parents 93b1f100 cf7a3b04
...@@ -37,6 +37,9 @@ abstract class Route<T> { ...@@ -37,6 +37,9 @@ abstract class Route<T> {
/// responsibility of the Route to later call dispose(). /// responsibility of the Route to later call dispose().
bool didPop(T result) => true; bool didPop(T result) => true;
/// Whether calling didPop() would return false.
bool get willHandlePopInternally => false;
/// The given route has been pushed onto the navigator after this route. /// The given route has been pushed onto the navigator after this route.
void didPushNext(Route nextRoute) { } void didPushNext(Route nextRoute) { }
...@@ -129,6 +132,11 @@ class Navigator extends StatefulComponent { ...@@ -129,6 +132,11 @@ class Navigator extends StatefulComponent {
return returnValue; return returnValue;
} }
static bool canPop(BuildContext context) {
NavigatorState navigator = context.ancestorStateOfType(NavigatorState);
return navigator.canPop();
}
static void popAndPushNamed(BuildContext context, String routeName, { Set<Key> mostValuableKeys }) { static void popAndPushNamed(BuildContext context, String routeName, { Set<Key> mostValuableKeys }) {
openTransaction(context, (NavigatorTransaction transaction) { openTransaction(context, (NavigatorTransaction transaction) {
transaction.pop(); transaction.pop();
...@@ -280,7 +288,10 @@ class NavigatorState extends State<Navigator> { ...@@ -280,7 +288,10 @@ class NavigatorState extends State<Navigator> {
assert(() { _debugLocked = true; return true; }); assert(() { _debugLocked = true; return true; });
Route route = _history.last; Route route = _history.last;
assert(route._navigator == this); assert(route._navigator == this);
bool debugPredictedWouldPop;
assert(() { debugPredictedWouldPop = !route.willHandlePopInternally; return true; });
if (route.didPop(result)) { if (route.didPop(result)) {
assert(debugPredictedWouldPop);
if (_history.length > 1) { if (_history.length > 1) {
setState(() { setState(() {
// We use setState to guarantee that we'll rebuild, since the routes // We use setState to guarantee that we'll rebuild, since the routes
...@@ -295,6 +306,8 @@ class NavigatorState extends State<Navigator> { ...@@ -295,6 +306,8 @@ class NavigatorState extends State<Navigator> {
assert(() { _debugLocked = false; return true; }); assert(() { _debugLocked = false; return true; });
return false; return false;
} }
} else {
assert(!debugPredictedWouldPop);
} }
assert(() { _debugLocked = false; return true; }); assert(() { _debugLocked = false; return true; });
return true; return true;
...@@ -306,6 +319,11 @@ class NavigatorState extends State<Navigator> { ...@@ -306,6 +319,11 @@ class NavigatorState extends State<Navigator> {
_pop(); _pop();
} }
bool canPop() {
assert(_history.length > 0);
return _history.length > 1 || _history[0].willHandlePopInternally;
}
bool _hadTransaction = true; bool _hadTransaction = true;
bool openTransaction(NavigatorTransactionCallback callback) { bool openTransaction(NavigatorTransactionCallback callback) {
......
...@@ -236,6 +236,9 @@ abstract class LocalHistoryRoute<T> extends Route<T> { ...@@ -236,6 +236,9 @@ abstract class LocalHistoryRoute<T> extends Route<T> {
} }
return super.didPop(result); return super.didPop(result);
} }
bool get willHandlePopInternally {
return _localHistory != null && _localHistory.length > 0;
}
} }
class _ModalScopeStatus extends InheritedWidget { class _ModalScopeStatus extends InheritedWidget {
......
...@@ -29,7 +29,9 @@ void main() { ...@@ -29,7 +29,9 @@ void main() {
expect(tester.findText('Settings'), isNull); expect(tester.findText('Settings'), isNull);
expect(tester.findText('Overlay'), isNull); expect(tester.findText('Overlay'), isNull);
expect(Navigator.canPop(containerKey1.currentContext), isFalse);
Navigator.pushNamed(containerKey1.currentContext, '/settings'); Navigator.pushNamed(containerKey1.currentContext, '/settings');
expect(Navigator.canPop(containerKey1.currentContext), isTrue);
tester.pump(); tester.pump();
...@@ -63,6 +65,7 @@ void main() { ...@@ -63,6 +65,7 @@ void main() {
expect(tester.findText('Settings'), isOnStage); expect(tester.findText('Settings'), isOnStage);
expect(tester.findText('Overlay'), isOnStage); expect(tester.findText('Overlay'), isOnStage);
expect(Navigator.canPop(containerKey2.currentContext), isTrue);
Navigator.pop(containerKey2.currentContext); Navigator.pop(containerKey2.currentContext);
tester.pump(); tester.pump();
...@@ -76,6 +79,7 @@ void main() { ...@@ -76,6 +79,7 @@ void main() {
expect(tester.findText('Settings'), isOnStage); expect(tester.findText('Settings'), isOnStage);
expect(tester.findText('Overlay'), isNull); expect(tester.findText('Overlay'), isNull);
expect(Navigator.canPop(containerKey2.currentContext), isTrue);
Navigator.pop(containerKey2.currentContext); Navigator.pop(containerKey2.currentContext);
tester.pump(); tester.pump();
...@@ -89,6 +93,8 @@ void main() { ...@@ -89,6 +93,8 @@ void main() {
expect(tester.findText('Settings'), isNull); expect(tester.findText('Settings'), isNull);
expect(tester.findText('Overlay'), isNull); expect(tester.findText('Overlay'), isNull);
expect(Navigator.canPop(containerKey1.currentContext), isFalse);
}); });
}); });
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment