diff --git a/lib/web_ui/lib/src/engine/browser_location.dart b/lib/web_ui/lib/src/engine/browser_location.dart index e2f0cfc4d58abcce8abc21972f4f35dbf4324990..30bcfcdf64c37390e5368dd9b6063e6ae51ce0be 100644 --- a/lib/web_ui/lib/src/engine/browser_location.dart +++ b/lib/web_ui/lib/src/engine/browser_location.dart @@ -9,27 +9,6 @@ part of engine; // Some parts of this file were inspired/copied from the AngularDart router. -/// Ensures that `str` is prefixed with `leading`. -/// -/// If `str` is already prefixed, it'll be returned unchanged. If it's not, -/// this function will prefix it. -/// -/// The `applyWhenEmpty` flag controls whether this function should prefix `str` -/// or not when it's an empty string. -/// -/// ```dart -/// ensureLeading('/path', '/'); // "/path" -/// ensureLeading('path', '/'); // "/path" -/// ensureLeading('', '/'); // "/" -/// ensureLeading('', '/', applyWhenEmpty: false); // "" -/// ``` -String ensureLeading(String str, String leading, {bool applyWhenEmpty = true}) { - if (str.isEmpty && !applyWhenEmpty) { - return str; - } - return str.startsWith(leading) ? str : '$leading$str'; -} - /// [LocationStrategy] is responsible for representing and reading route state /// from the browser's URL. /// @@ -93,12 +72,11 @@ class HashLocationStrategy extends LocationStrategy { // the hash value is always prefixed with a `#` // and if it is empty then it will stay empty String path = _platformLocation.hash ?? ''; + assert(path.isEmpty || path.startsWith('#')); // Dart will complain if a call to substring is // executed with a position value that exceeds the // length of string. - path = path.isEmpty ? path : path.substring(1); - // The path, by convention, should always contain a leading '/'. - return ensureLeading(path, '/'); + return path.isEmpty ? path : path.substring(1); } @override diff --git a/lib/web_ui/lib/src/engine/test_embedding.dart b/lib/web_ui/lib/src/engine/test_embedding.dart index 713fddf712ca6b44decbf5c3804eeed9792e688b..c1295a2ff0921af7a2d78e7111305835d5e3d132 100644 --- a/lib/web_ui/lib/src/engine/test_embedding.dart +++ b/lib/web_ui/lib/src/engine/test_embedding.dart @@ -37,7 +37,7 @@ class TestLocationStrategy extends LocationStrategy { history = [initialEntry]; @override - String get path => ensureLeading(currentEntry.url, '/'); + String get path => currentEntry.url; int _currentEntryIndex; int get currentEntryIndex => _currentEntryIndex; diff --git a/lib/web_ui/lib/src/engine/window.dart b/lib/web_ui/lib/src/engine/window.dart index bfe950428e8b749ab2f3c305f5bf5a551ed413ed..298f79ec0c83145a8d55b011c0f313afa5406e2b 100644 --- a/lib/web_ui/lib/src/engine/window.dart +++ b/lib/web_ui/lib/src/engine/window.dart @@ -441,6 +441,10 @@ class EngineWindow extends ui.Window { _replyToPlatformMessage(callback, codec.encodeSuccessEnvelope(true)); break; } + // As soon as Flutter starts taking control of the app navigation, we + // should reset [_defaultRouteName] to "/" so it doesn't have any + // further effect after this point. + _defaultRouteName = '/'; return; } diff --git a/lib/web_ui/test/engine/history_test.dart b/lib/web_ui/test/engine/history_test.dart index c7c31b2cbd124ccd7fe981f248bdbbc78d3793b8..494b565ddd4c47c25f2e0915fb6b6bba77660ffa 100644 --- a/lib/web_ui/test/engine/history_test.dart +++ b/lib/web_ui/test/engine/history_test.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. // @dart = 2.6 -@TestOn('vm && linux') +@TestOn('!safari') // TODO(nurhan): https://github.com/flutter/flutter/issues/51169 import 'dart:async'; diff --git a/lib/web_ui/test/window_test.dart b/lib/web_ui/test/window_test.dart index a20bffe3877df273e9d226106831f79f273f8364..4062be970c3f186547df524d9ec7d08476e922e8 100644 --- a/lib/web_ui/test/window_test.dart +++ b/lib/web_ui/test/window_test.dart @@ -3,9 +3,15 @@ // found in the LICENSE file. // @dart = 2.6 +import 'dart:typed_data'; + import 'package:test/test.dart'; import 'package:ui/src/engine.dart'; +const MethodCodec codec = JSONMethodCodec(); + +void emptyCallback(ByteData date) {} + TestLocationStrategy _strategy; TestLocationStrategy get strategy => _strategy; set strategy(TestLocationStrategy newStrategy) { @@ -17,7 +23,27 @@ void main() { strategy = TestLocationStrategy.fromEntry(TestHistoryEntry('initial state', null, '/initial')); expect(window.defaultRouteName, '/initial'); + // Changing the URL in the address bar later shouldn't affect [window.defaultRouteName]. strategy.replaceState(null, null, '/newpath'); expect(window.defaultRouteName, '/initial'); }); + + test('window.defaultRouteName should reset after navigation platform message', () { + strategy = TestLocationStrategy.fromEntry(TestHistoryEntry('initial state', null, '/initial')); + // Reading it multiple times should return the same value. + expect(window.defaultRouteName, '/initial'); + expect(window.defaultRouteName, '/initial'); + + window.sendPlatformMessage( + 'flutter/navigation', + JSONMethodCodec().encodeMethodCall(MethodCall( + 'routePushed', + {'previousRouteName': '/foo', 'routeName': '/bar'}, + )), + emptyCallback, + ); + // After a navigation platform message, [window.defaultRouteName] should + // reset to "/". + expect(window.defaultRouteName, '/'); + }); }