Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
ffcf4191
Unverified
Commit
ffcf4191
authored
Oct 09, 2020
by
Mouad Debbar
Committed by
GitHub
Oct 09, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[web] Support custom url strategies (#59797)
parent
4f2fcca6
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
737 additions
and
3 deletions
+737
-3
pubspec.yaml
dev/benchmarks/macrobenchmarks/pubspec.yaml
+1
-1
pubspec.yaml
dev/integration_tests/flutter_gallery/pubspec.yaml
+1
-1
flutter_web_plugins.dart
packages/flutter_web_plugins/lib/flutter_web_plugins.dart
+1
-0
js_url_strategy.dart
...utter_web_plugins/lib/src/navigation/js_url_strategy.dart
+118
-0
url_strategy.dart
.../flutter_web_plugins/lib/src/navigation/url_strategy.dart
+320
-0
utils.dart
packages/flutter_web_plugins/lib/src/navigation/utils.dart
+67
-0
pubspec.yaml
packages/flutter_web_plugins/pubspec.yaml
+3
-1
url_strategy_test.dart
...lutter_web_plugins/test/navigation/url_strategy_test.dart
+188
-0
utils_test.dart
packages/flutter_web_plugins/test/navigation/utils_test.dart
+38
-0
No files found.
dev/benchmarks/macrobenchmarks/pubspec.yaml
View file @
ffcf4191
...
...
@@ -43,6 +43,7 @@ dependencies:
http
:
0.12.2
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http_parser
:
3.1.4
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
intl
:
0.16.1
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
js
:
0.6.3-nullsafety.1
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
json_rpc_2
:
2.2.2
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
matcher
:
0.12.10-nullsafety.1
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta
:
1.3.0-nullsafety.3
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
...
...
@@ -105,7 +106,6 @@ dev_dependencies:
html
:
0.14.0+3
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http_multi_server
:
2.2.0
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
io
:
0.3.4
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
js
:
0.6.3-nullsafety.1
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
logging
:
0.11.4
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
mime
:
0.9.7
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
node_interop
:
1.1.1
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
...
...
dev/integration_tests/flutter_gallery/pubspec.yaml
View file @
ffcf4191
...
...
@@ -28,6 +28,7 @@ dependencies:
connectivity_macos
:
0.1.0+5
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
connectivity_platform_interface
:
1.0.6
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
device_info_platform_interface
:
1.0.1
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
js
:
0.6.3-nullsafety.1
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta
:
1.3.0-nullsafety.3
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
path
:
1.8.0-nullsafety.1
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
plugin_platform_interface
:
1.0.3
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
...
...
@@ -73,7 +74,6 @@ dev_dependencies:
http_multi_server
:
2.2.0
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http_parser
:
3.1.4
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
io
:
0.3.4
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
js
:
0.6.3-nullsafety.1
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
json_rpc_2
:
2.2.2
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
logging
:
0.11.4
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
matcher
:
0.12.10-nullsafety.1
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
...
...
packages/flutter_web_plugins/lib/flutter_web_plugins.dart
View file @
ffcf4191
...
...
@@ -17,5 +17,6 @@
/// describing how the `url_launcher` package was created using [flutter_web_plugins].
library
flutter_web_plugins
;
export
'src/navigation/url_strategy.dart'
;
export
'src/plugin_event_channel.dart'
;
export
'src/plugin_registry.dart'
;
packages/flutter_web_plugins/lib/src/navigation/js_url_strategy.dart
0 → 100644
View file @
ffcf4191
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
@JS
()
library
js_location_strategy
;
import
'dart:async'
;
import
'dart:html'
as
html
;
import
'dart:ui'
as
ui
;
import
'package:js/js.dart'
;
import
'package:meta/meta.dart'
;
import
'url_strategy.dart'
;
typedef
_JsSetUrlStrategy
=
void
Function
(
JsUrlStrategy
);
/// A JavaScript hook to customize the URL strategy of a Flutter app.
//
// Keep this in sync with the JS name in the web engine. Find it at:
// https://github.com/flutter/engine/blob/custom_location_strategy/lib/web_ui/lib/src/engine/navigation/js_url_strategy.dart
//
// TODO(mdebbar): Add integration test https://github.com/flutter/flutter/issues/66852
@JS
(
'_flutter_web_set_location_strategy'
)
external
_JsSetUrlStrategy
get
jsSetUrlStrategy
;
typedef
_PathGetter
=
String
Function
();
typedef
_StateGetter
=
Object
Function
();
typedef
_AddPopStateListener
=
ui
.
VoidCallback
Function
(
html
.
EventListener
);
typedef
_StringToString
=
String
Function
(
String
);
typedef
_StateOperation
=
void
Function
(
Object
state
,
String
title
,
String
url
);
typedef
_HistoryMove
=
Future
<
void
>
Function
(
int
count
);
/// Given a Dart implementation of URL strategy, converts it to a JavaScript
/// URL strategy to be passed through JS interop.
JsUrlStrategy
convertToJsUrlStrategy
(
UrlStrategy
strategy
)
{
if
(
strategy
==
null
)
{
return
null
;
}
return
JsUrlStrategy
(
getPath:
allowInterop
(
strategy
.
getPath
),
getState:
allowInterop
(
strategy
.
getState
),
addPopStateListener:
allowInterop
(
strategy
.
addPopStateListener
),
prepareExternalUrl:
allowInterop
(
strategy
.
prepareExternalUrl
),
pushState:
allowInterop
(
strategy
.
pushState
),
replaceState:
allowInterop
(
strategy
.
replaceState
),
go:
allowInterop
(
strategy
.
go
),
);
}
/// The JavaScript representation of a URL strategy.
///
/// This is used to pass URL strategy implementations across a JS-interop
/// bridge from the app to the engine.
@JS
()
@anonymous
abstract
class
JsUrlStrategy
{
/// Creates an instance of [JsUrlStrategy] from a bag of URL strategy
/// functions.
external
factory
JsUrlStrategy
({
@required
_PathGetter
getPath
,
@required
_StateGetter
getState
,
@required
_AddPopStateListener
addPopStateListener
,
@required
_StringToString
prepareExternalUrl
,
@required
_StateOperation
pushState
,
@required
_StateOperation
replaceState
,
@required
_HistoryMove
go
,
});
/// Adds a listener to the `popstate` event and returns a function that
/// removes the listener.
external
ui
.
VoidCallback
addPopStateListener
(
html
.
EventListener
fn
);
/// Returns the active path in the browser.
external
String
getPath
();
/// Returns the history state in the browser.
///
/// See: https://developer.mozilla.org/en-US/docs/Web/API/History/state
external
Object
getState
();
/// Given a path that's internal to the app, create the external url that
/// will be used in the browser.
external
String
prepareExternalUrl
(
String
internalUrl
);
/// Push a new history entry.
///
/// See: https://developer.mozilla.org/en-US/docs/Web/API/History/pushState
external
void
pushState
(
Object
state
,
String
title
,
String
url
);
/// Replace the currently active history entry.
///
/// See: https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState
external
void
replaceState
(
Object
state
,
String
title
,
String
url
);
/// Moves forwards or backwards through the history stack.
///
/// A negative [count] value causes a backward move in the history stack. And
/// a positive [count] value causs a forward move.
///
/// Examples:
///
/// * `go(-2)` moves back 2 steps in history.
/// * `go(3)` moves forward 3 steps in hisotry.
///
/// See: https://developer.mozilla.org/en-US/docs/Web/API/History/go
external
Future
<
void
>
go
(
int
count
);
}
packages/flutter_web_plugins/lib/src/navigation/url_strategy.dart
0 → 100644
View file @
ffcf4191
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import
'dart:async'
;
import
'dart:html'
as
html
;
import
'dart:ui'
as
ui
;
import
'js_url_strategy.dart'
;
import
'utils.dart'
;
/// Change the strategy to use for handling browser URL.
///
/// Setting this to null disables all integration with the browser history.
void
setUrlStrategy
(
UrlStrategy
strategy
)
{
jsSetUrlStrategy
(
convertToJsUrlStrategy
(
strategy
));
}
/// Represents and reads route state from the browser's URL.
///
/// By default, the [HashUrlStrategy] subclass is used if the app doesn't
/// specify one.
abstract
class
UrlStrategy
{
/// Abstract const constructor. This constructor enables subclasses to provide
/// const constructors so that they can be used in const expressions.
const
UrlStrategy
();
/// Adds a listener to the `popstate` event and returns a function that, when
/// invoked, removes the listener.
ui
.
VoidCallback
addPopStateListener
(
html
.
EventListener
fn
);
/// Returns the active path in the browser.
String
getPath
();
/// The state of the current browser history entry.
///
/// See: https://developer.mozilla.org/en-US/docs/Web/API/History/state
Object
getState
();
/// Given a path that's internal to the app, create the external url that
/// will be used in the browser.
String
prepareExternalUrl
(
String
internalUrl
);
/// Push a new history entry.
///
/// See: https://developer.mozilla.org/en-US/docs/Web/API/History/pushState
void
pushState
(
Object
state
,
String
title
,
String
url
);
/// Replace the currently active history entry.
///
/// See: https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState
void
replaceState
(
Object
state
,
String
title
,
String
url
);
/// Moves forwards or backwards through the history stack.
///
/// A negative [count] value causes a backward move in the history stack. And
/// a positive [count] value causs a forward move.
///
/// Examples:
///
/// * `go(-2)` moves back 2 steps in history.
/// * `go(3)` moves forward 3 steps in hisotry.
///
/// See: https://developer.mozilla.org/en-US/docs/Web/API/History/go
Future
<
void
>
go
(
int
count
);
}
/// Uses the browser URL's [hash fragments](https://en.wikipedia.org/wiki/Uniform_Resource_Locator#Syntax)
/// to represent its state.
///
/// By default, this class is used as the URL strategy for the app. However,
/// this class is still useful for apps that want to extend it.
///
/// In order to use [HashUrlStrategy] for an app, it needs to be set like this:
///
/// ```dart
/// import 'package:flutter_web_plugins/flutter_web_plugins.dart';
///
/// // Somewhere before calling `runApp()` do:
/// setUrlStrategy(const HashUrlStrategy());
/// ```
class
HashUrlStrategy
extends
UrlStrategy
{
/// Creates an instance of [HashUrlStrategy].
///
/// The [PlatformLocation] parameter is useful for testing to mock out browser
/// interations.
const
HashUrlStrategy
(
[
this
.
_platformLocation
=
const
BrowserPlatformLocation
()]);
final
PlatformLocation
_platformLocation
;
@override
ui
.
VoidCallback
addPopStateListener
(
html
.
EventListener
fn
)
{
_platformLocation
.
addPopStateListener
(
fn
);
return
()
=>
_platformLocation
.
removePopStateListener
(
fn
);
}
@override
String
getPath
()
{
// the hash value is always prefixed with a `#`
// and if it is empty then it will stay empty
final
String
path
=
_platformLocation
.
hash
??
''
;
assert
(
path
.
isEmpty
||
path
.
startsWith
(
'#'
));
// We don't want to return an empty string as a path. Instead we default to "/".
if
(
path
.
isEmpty
||
path
==
'#'
)
{
return
'/'
;
}
// At this point, we know [path] starts with "#" and isn't empty.
return
path
.
substring
(
1
);
}
@override
Object
getState
()
=>
_platformLocation
.
state
;
@override
String
prepareExternalUrl
(
String
internalUrl
)
{
// It's convention that if the hash path is empty, we omit the `#`; however,
// if the empty URL is pushed it won't replace any existing fragment. So
// when the hash path is empty, we instead return the location's path and
// query.
return
internalUrl
.
isEmpty
?
'
${_platformLocation.pathname}${_platformLocation.search}
'
:
'#
$internalUrl
'
;
}
@override
void
pushState
(
Object
state
,
String
title
,
String
url
)
{
_platformLocation
.
pushState
(
state
,
title
,
prepareExternalUrl
(
url
));
}
@override
void
replaceState
(
Object
state
,
String
title
,
String
url
)
{
_platformLocation
.
replaceState
(
state
,
title
,
prepareExternalUrl
(
url
));
}
@override
Future
<
void
>
go
(
int
count
)
{
_platformLocation
.
go
(
count
);
return
_waitForPopState
();
}
/// Waits until the next popstate event is fired.
///
/// This is useful, for example, to wait until the browser has handled the
/// `history.back` transition.
Future
<
void
>
_waitForPopState
()
{
final
Completer
<
void
>
completer
=
Completer
<
void
>();
ui
.
VoidCallback
unsubscribe
;
unsubscribe
=
addPopStateListener
((
_
)
{
unsubscribe
();
completer
.
complete
();
});
return
completer
.
future
;
}
}
/// Uses the browser URL's pathname to represent Flutter's route name.
///
/// In order to use [PathUrlStrategy] for an app, it needs to be set like this:
///
/// ```dart
/// import 'package:flutter_web_plugins/flutter_web_plugins.dart';
///
/// // Somewhere before calling `runApp()` do:
/// setUrlStrategy(PathUrlStrategy());
/// ```
class
PathUrlStrategy
extends
HashUrlStrategy
{
/// Creates an instance of [PathUrlStrategy].
///
/// The [PlatformLocation] parameter is useful for testing to mock out browser
/// interations.
PathUrlStrategy
([
PlatformLocation
_platformLocation
=
const
BrowserPlatformLocation
(),
])
:
_basePath
=
stripTrailingSlash
(
extractPathname
(
checkBaseHref
(
_platformLocation
.
getBaseHref
(),
))),
super
(
_platformLocation
);
final
String
_basePath
;
@override
String
getPath
()
{
final
String
path
=
_platformLocation
.
pathname
+
_platformLocation
.
search
;
if
(
_basePath
.
isNotEmpty
&&
path
.
startsWith
(
_basePath
))
{
return
ensureLeadingSlash
(
path
.
substring
(
_basePath
.
length
));
}
return
ensureLeadingSlash
(
path
);
}
@override
String
prepareExternalUrl
(
String
internalUrl
)
{
if
(
internalUrl
.
isNotEmpty
&&
!
internalUrl
.
startsWith
(
'/'
))
{
internalUrl
=
'/
$internalUrl
'
;
}
return
'
$_basePath$internalUrl
'
;
}
}
/// Encapsulates all calls to DOM apis, which allows the [UrlStrategy] classes
/// to be platform agnostic and testable.
///
/// For convenience, the [PlatformLocation] class can be used by implementations
/// of [UrlStrategy] to interact with DOM apis like pushState, popState, etc.
abstract
class
PlatformLocation
{
/// Abstract const constructor. This constructor enables subclasses to provide
/// const constructors so that they can be used in const expressions.
const
PlatformLocation
();
/// Registers an event listener for the `popstate` event.
///
/// See: https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onpopstate
void
addPopStateListener
(
html
.
EventListener
fn
);
/// Unregisters the given listener (added by [addPopStateListener]) from the
/// `popstate` event.
///
/// See: https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onpopstate
void
removePopStateListener
(
html
.
EventListener
fn
);
/// The `pathname` part of the URL in the browser address bar.
///
/// See: https://developer.mozilla.org/en-US/docs/Web/API/Location/pathname
String
get
pathname
;
/// The `query` part of the URL in the browser address bar.
///
/// See: https://developer.mozilla.org/en-US/docs/Web/API/Location/search
String
get
search
;
/// The `hash` part of the URL in the browser address bar.
///
/// See: https://developer.mozilla.org/en-US/docs/Web/API/Location/hash
String
get
hash
;
/// The `state` in the current history entry.
///
/// See: https://developer.mozilla.org/en-US/docs/Web/API/History/state
Object
get
state
;
/// Adds a new entry to the browser history stack.
///
/// See: https://developer.mozilla.org/en-US/docs/Web/API/History/pushState
void
pushState
(
Object
state
,
String
title
,
String
url
);
/// Replaces the current entry in the browser history stack.
///
/// See: https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState
void
replaceState
(
Object
state
,
String
title
,
String
url
);
/// Moves forwards or backwards through the history stack.
///
/// A negative [count] value causes a backward move in the history stack. And
/// a positive [count] value causs a forward move.
///
/// Examples:
///
/// * `go(-2)` moves back 2 steps in history.
/// * `go(3)` moves forward 3 steps in hisotry.
///
/// See: https://developer.mozilla.org/en-US/docs/Web/API/History/go
void
go
(
int
count
);
/// The base href where the Flutter app is being served.
///
/// See: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
String
getBaseHref
();
}
/// Delegates to real browser APIs to provide platform location functionality.
class
BrowserPlatformLocation
extends
PlatformLocation
{
/// Default constructor for [BrowserPlatformLocation].
const
BrowserPlatformLocation
();
html
.
Location
get
_location
=>
html
.
window
.
location
;
html
.
History
get
_history
=>
html
.
window
.
history
;
@override
void
addPopStateListener
(
html
.
EventListener
fn
)
{
html
.
window
.
addEventListener
(
'popstate'
,
fn
);
}
@override
void
removePopStateListener
(
html
.
EventListener
fn
)
{
html
.
window
.
removeEventListener
(
'popstate'
,
fn
);
}
@override
String
get
pathname
=>
_location
.
pathname
;
@override
String
get
search
=>
_location
.
search
;
@override
String
get
hash
=>
_location
.
hash
;
@override
Object
get
state
=>
_history
.
state
;
@override
void
pushState
(
Object
state
,
String
title
,
String
url
)
{
_history
.
pushState
(
state
,
title
,
url
);
}
@override
void
replaceState
(
Object
state
,
String
title
,
String
url
)
{
_history
.
replaceState
(
state
,
title
,
url
);
}
@override
void
go
(
int
count
)
{
_history
.
go
(
count
);
}
@override
String
getBaseHref
()
=>
getBaseElementHrefFromDom
();
// String getBaseHref() => html.document.baseUri;
}
packages/flutter_web_plugins/lib/src/navigation/utils.dart
0 → 100644
View file @
ffcf4191
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import
'dart:html'
;
AnchorElement
_urlParsingNode
;
/// Extracts the pathname part of a full [url].
///
/// Example: for the url `http://example.com/foo`, the extracted pathname will
/// be `/foo`.
String
extractPathname
(
String
url
)
{
// TODO(mdebbar): Use the `URI` class instead?
_urlParsingNode
??=
AnchorElement
();
_urlParsingNode
.
href
=
url
;
final
String
pathname
=
_urlParsingNode
.
pathname
;
return
(
pathname
.
isEmpty
||
pathname
[
0
]
==
'/'
)
?
pathname
:
'/
$pathname
'
;
}
Element
_baseElement
;
/// Finds the <base> element in the document and returns its `href` attribute.
///
/// Returns null if the element isn't found.
String
getBaseElementHrefFromDom
(
)
{
if
(
_baseElement
==
null
)
{
_baseElement
=
document
.
querySelector
(
'base'
);
if
(
_baseElement
==
null
)
{
return
null
;
}
}
return
_baseElement
.
getAttribute
(
'href'
);
}
/// Checks that [baseHref] is set.
///
/// Throws an exception otherwise.
String
checkBaseHref
(
String
baseHref
)
{
if
(
baseHref
==
null
)
{
throw
Exception
(
'Please add a <base> element to your index.html'
);
}
if
(!
baseHref
.
endsWith
(
'/'
))
{
throw
Exception
(
'The base href has to end with a "/" to work correctly'
);
}
return
baseHref
;
}
/// Prepends a forward slash to [path] if it doesn't start with one already.
///
/// Returns [path] unchanged if it already starts with a forward slash.
String
ensureLeadingSlash
(
String
path
)
{
if
(!
path
.
startsWith
(
'/'
))
{
return
'/
$path
'
;
}
return
path
;
}
/// Removes the trailing forward slash from [path] if any.
String
stripTrailingSlash
(
String
path
)
{
if
(
path
.
endsWith
(
'/'
))
{
return
path
.
substring
(
0
,
path
.
length
-
1
);
}
return
path
;
}
packages/flutter_web_plugins/pubspec.yaml
View file @
ffcf4191
...
...
@@ -10,6 +10,8 @@ dependencies:
flutter
:
sdk
:
flutter
js
:
0.6.3-nullsafety.1
characters
:
1.1.0-nullsafety.3
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
collection
:
1.15.0-nullsafety.3
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
meta
:
1.3.0-nullsafety.3
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
...
...
@@ -34,4 +36,4 @@ dev_dependencies:
term_glyph
:
1.2.0-nullsafety.1
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
test_api
:
0.2.19-nullsafety.2
# THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
# PUBSPEC CHECKSUM:
417a
# PUBSPEC CHECKSUM:
2180
packages/flutter_web_plugins/test/navigation/url_strategy_test.dart
0 → 100644
View file @
ffcf4191
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import
'dart:html'
;
@TestOn
(
'chrome'
)
// Uses web-only Flutter SDK
import
'package:flutter_test/flutter_test.dart'
;
import
'package:flutter_web_plugins/flutter_web_plugins.dart'
;
void
main
(
)
{
group
(
'
$HashUrlStrategy
'
,
()
{
TestPlatformLocation
location
;
setUp
(()
{
location
=
TestPlatformLocation
();
});
tearDown
(()
{
location
=
null
;
});
test
(
'leading slash is optional'
,
()
{
final
HashUrlStrategy
strategy
=
HashUrlStrategy
(
location
);
location
.
hash
=
'#/'
;
expect
(
strategy
.
getPath
(),
'/'
);
location
.
hash
=
'#/foo'
;
expect
(
strategy
.
getPath
(),
'/foo'
);
location
.
hash
=
'#foo'
;
expect
(
strategy
.
getPath
(),
'foo'
);
});
test
(
'path should not be empty'
,
()
{
final
HashUrlStrategy
strategy
=
HashUrlStrategy
(
location
);
location
.
hash
=
''
;
expect
(
strategy
.
getPath
(),
'/'
);
location
.
hash
=
'#'
;
expect
(
strategy
.
getPath
(),
'/'
);
});
});
group
(
'
$PathUrlStrategy
'
,
()
{
TestPlatformLocation
location
;
setUp
(()
{
location
=
TestPlatformLocation
();
});
tearDown
(()
{
location
=
null
;
});
test
(
'validates base href'
,
()
{
location
.
baseHref
=
'/'
;
expect
(
()
=>
PathUrlStrategy
(
location
),
returnsNormally
,
);
location
.
baseHref
=
'/foo/'
;
expect
(
()
=>
PathUrlStrategy
(
location
),
returnsNormally
,
);
location
.
baseHref
=
''
;
expect
(
()
=>
PathUrlStrategy
(
location
),
throwsException
,
);
location
.
baseHref
=
'foo'
;
expect
(
()
=>
PathUrlStrategy
(
location
),
throwsException
,
);
location
.
baseHref
=
'/foo'
;
expect
(
()
=>
PathUrlStrategy
(
location
),
throwsException
,
);
});
test
(
'leading slash is always prepended'
,
()
{
location
.
baseHref
=
'/'
;
final
PathUrlStrategy
strategy
=
PathUrlStrategy
(
location
);
location
.
pathname
=
''
;
expect
(
strategy
.
getPath
(),
'/'
);
location
.
pathname
=
'foo'
;
expect
(
strategy
.
getPath
(),
'/foo'
);
});
test
(
'gets path correctly in the presence of basePath'
,
()
{
location
.
baseHref
=
'https://example.com/foo/'
;
final
PathUrlStrategy
strategy
=
PathUrlStrategy
(
location
);
location
.
pathname
=
'/foo/'
;
expect
(
strategy
.
getPath
(),
'/'
);
location
.
pathname
=
'/foo'
;
expect
(
strategy
.
getPath
(),
'/'
);
location
.
pathname
=
'/foo/bar'
;
expect
(
strategy
.
getPath
(),
'/bar'
);
});
test
(
'gets path correctly in the presence of query params'
,
()
{
location
.
baseHref
=
'https://example.com/foo/'
;
location
.
pathname
=
'/foo/bar'
;
final
PathUrlStrategy
strategy
=
PathUrlStrategy
(
location
);
location
.
search
=
'?q=1'
;
expect
(
strategy
.
getPath
(),
'/bar?q=1'
);
location
.
search
=
'?q=1&t=r'
;
expect
(
strategy
.
getPath
(),
'/bar?q=1&t=r'
);
});
test
(
'generates external path correctly in the presence of basePath'
,
()
{
location
.
baseHref
=
'https://example.com/foo/'
;
final
PathUrlStrategy
strategy
=
PathUrlStrategy
(
location
);
expect
(
strategy
.
prepareExternalUrl
(
''
),
'/foo'
);
expect
(
strategy
.
prepareExternalUrl
(
'/'
),
'/foo/'
);
expect
(
strategy
.
prepareExternalUrl
(
'bar'
),
'/foo/bar'
);
expect
(
strategy
.
prepareExternalUrl
(
'/bar'
),
'/foo/bar'
);
expect
(
strategy
.
prepareExternalUrl
(
'/bar/'
),
'/foo/bar/'
);
});
});
}
/// A mock implementation of [PlatformLocation] that doesn't access the browser.
class
TestPlatformLocation
extends
PlatformLocation
{
@override
String
pathname
=
''
;
@override
String
search
=
''
;
@override
String
hash
=
''
;
@override
dynamic
state
;
/// Mocks the base href of the document.
String
baseHref
=
''
;
@override
void
addPopStateListener
(
EventListener
fn
)
{
throw
UnimplementedError
();
}
@override
void
removePopStateListener
(
EventListener
fn
)
{
throw
UnimplementedError
();
}
@override
void
pushState
(
dynamic
state
,
String
title
,
String
url
)
{
throw
UnimplementedError
();
}
@override
void
replaceState
(
dynamic
state
,
String
title
,
String
url
)
{
throw
UnimplementedError
();
}
@override
void
go
(
int
count
)
{
throw
UnimplementedError
();
}
@override
String
getBaseHref
()
=>
baseHref
;
}
packages/flutter_web_plugins/test/navigation/utils_test.dart
0 → 100644
View file @
ffcf4191
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
@TestOn
(
'browser'
)
// Uses web-only Flutter SDK
import
'package:flutter_test/flutter_test.dart'
;
import
'package:flutter_web_plugins/src/navigation/utils.dart'
;
void
main
(
)
{
test
(
'checks base href'
,
()
{
expect
(()
=>
checkBaseHref
(
null
),
throwsException
);
expect
(()
=>
checkBaseHref
(
'foo'
),
throwsException
);
expect
(()
=>
checkBaseHref
(
'/foo'
),
throwsException
);
expect
(()
=>
checkBaseHref
(
'foo/bar'
),
throwsException
);
expect
(()
=>
checkBaseHref
(
'/foo/bar'
),
throwsException
);
expect
(()
=>
checkBaseHref
(
'/'
),
returnsNormally
);
expect
(()
=>
checkBaseHref
(
'/foo/'
),
returnsNormally
);
expect
(()
=>
checkBaseHref
(
'/foo/bar/'
),
returnsNormally
);
});
test
(
'extracts pathname from URL'
,
()
{
expect
(
extractPathname
(
'/'
),
'/'
);
expect
(
extractPathname
(
'/foo'
),
'/foo'
);
expect
(
extractPathname
(
'/foo/'
),
'/foo/'
);
expect
(
extractPathname
(
'/foo/bar'
),
'/foo/bar'
);
expect
(
extractPathname
(
'/foo/bar/'
),
'/foo/bar/'
);
expect
(
extractPathname
(
'https://example.com'
),
'/'
);
expect
(
extractPathname
(
'https://example.com/'
),
'/'
);
expect
(
extractPathname
(
'https://example.com/foo'
),
'/foo'
);
expect
(
extractPathname
(
'https://example.com/foo#bar'
),
'/foo'
);
expect
(
extractPathname
(
'https://example.com/foo/#bar'
),
'/foo/'
);
});
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment