diff --git a/packages/url_launcher/url_launcher_web/CHANGELOG.md b/packages/url_launcher/url_launcher_web/CHANGELOG.md index 0702685893ae..df1b2c97b744 100644 --- a/packages/url_launcher/url_launcher_web/CHANGELOG.md +++ b/packages/url_launcher/url_launcher_web/CHANGELOG.md @@ -1,10 +1,15 @@ +# 0.1.1+6 + +- Open "mailto" urls with target set as "\_top" on Safari browsers. +- Update lower bound of dart dependency to 2.2.0. + # 0.1.1+5 -* Update lower bound of dart dependency to 2.1.0. +- Update lower bound of dart dependency to 2.1.0. # 0.1.1+4 -* Declare API stability and compatibility with `1.0.0` (more details at: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0). +- Declare API stability and compatibility with `1.0.0` (more details at: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0). # 0.1.1+3 @@ -12,7 +17,7 @@ # 0.1.1+2 -- Open urls with target "_top" on iOS PWAs. +- Open urls with target "\_top" on iOS PWAs. # 0.1.1+1 diff --git a/packages/url_launcher/url_launcher_web/lib/src/navigator.dart b/packages/url_launcher/url_launcher_web/lib/src/navigator.dart deleted file mode 100644 index 4c7a99d4c486..000000000000 --- a/packages/url_launcher/url_launcher_web/lib/src/navigator.dart +++ /dev/null @@ -1,15 +0,0 @@ -@JS() -library navigator; - -import 'package:js/js.dart'; -import 'package:meta/meta.dart'; - -@JS('window.navigator.standalone') -external bool get _standalone; - -/// The window.navigator.standalone DOM property. -bool get standalone => _standalone ?? false; - -@visibleForTesting -@JS('window.navigator.standalone') -external set standalone(bool enabled); diff --git a/packages/url_launcher/url_launcher_web/lib/url_launcher_web.dart b/packages/url_launcher/url_launcher_web/lib/url_launcher_web.dart index cce2bbf635ee..e55ceb2269bc 100644 --- a/packages/url_launcher/url_launcher_web/lib/url_launcher_web.dart +++ b/packages/url_launcher/url_launcher_web/lib/url_launcher_web.dart @@ -4,7 +4,10 @@ import 'dart:html' as html; import 'package:flutter_web_plugins/flutter_web_plugins.dart'; import 'package:meta/meta.dart'; import 'package:url_launcher_platform_interface/url_launcher_platform_interface.dart'; -import 'src/navigator.dart' as navigator; + +import 'package:platform_detect/platform_detect.dart' show browser; + +const _mailtoScheme = 'mailto'; /// The web implementation of [UrlLauncherPlatform]. /// @@ -12,6 +15,9 @@ import 'src/navigator.dart' as navigator; class UrlLauncherPlugin extends UrlLauncherPlatform { html.Window _window; + // The set of schemes that can be handled by the plugin + static final _supportedSchemes = {'http', 'https', _mailtoScheme}; + /// A constructor that allows tests to override the window object used by the plugin. UrlLauncherPlugin({@visibleForTesting html.Window window}) : _window = window ?? html.window; @@ -21,25 +27,24 @@ class UrlLauncherPlugin extends UrlLauncherPlatform { UrlLauncherPlatform.instance = UrlLauncherPlugin(); } + String _getUrlScheme(String url) => Uri.tryParse(url)?.scheme; + + bool _isMailtoScheme(String url) => _getUrlScheme(url) == _mailtoScheme; + /// Opens the given [url] in a new window. /// /// Returns the newly created window. @visibleForTesting html.WindowBase openNewWindow(String url) { - // We need to open on _top in ios browsers in standalone mode. + // We need to open mailto urls on the _top window context on safari browsers. // See https://github.com/flutter/flutter/issues/51461 for reference. - final target = navigator.standalone ? '_top' : ''; + final target = browser.isSafari && _isMailtoScheme(url) ? '_top' : ''; return _window.open(url, target); } @override Future canLaunch(String url) { - final Uri parsedUrl = Uri.tryParse(url); - if (parsedUrl == null) return Future.value(false); - - return Future.value(parsedUrl.isScheme('http') || - parsedUrl.isScheme('https') || - parsedUrl.isScheme('mailto')); + return Future.value(_supportedSchemes.contains(_getUrlScheme(url))); } @override diff --git a/packages/url_launcher/url_launcher_web/pubspec.yaml b/packages/url_launcher/url_launcher_web/pubspec.yaml index 16bc4a5e8693..207f2dc15424 100644 --- a/packages/url_launcher/url_launcher_web/pubspec.yaml +++ b/packages/url_launcher/url_launcher_web/pubspec.yaml @@ -4,7 +4,7 @@ homepage: https://github.com/flutter/plugins/tree/master/packages/url_launcher/u # 0.1.y+z is compatible with 1.0.0, if you land a breaking change bump # the version to 2.0.0. # See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 -version: 0.1.1+5 +version: 0.1.1+6 flutter: plugin: @@ -15,12 +15,12 @@ flutter: dependencies: url_launcher_platform_interface: ^1.0.1 + platform_detect: ^1.4.0 flutter: sdk: flutter flutter_web_plugins: sdk: flutter meta: ^1.1.7 - js: ^0.6.0 dev_dependencies: flutter_test: @@ -30,5 +30,5 @@ dev_dependencies: mockito: ^4.1.1 environment: - sdk: ">=2.1.0 <3.0.0" + sdk: ">=2.2.0 <3.0.0" flutter: ">=1.10.0 <2.0.0" diff --git a/packages/url_launcher/url_launcher_web/test/url_launcher_web_test.dart b/packages/url_launcher/url_launcher_web/test/url_launcher_web_test.dart index b6cf8b70460e..4cf92062e10f 100644 --- a/packages/url_launcher/url_launcher_web/test/url_launcher_web_test.dart +++ b/packages/url_launcher/url_launcher_web/test/url_launcher_web_test.dart @@ -7,9 +7,10 @@ import 'dart:html' as html; import 'package:flutter_test/flutter_test.dart'; import 'package:url_launcher_web/url_launcher_web.dart'; -import 'package:url_launcher_web/src/navigator.dart' as navigator; import 'package:mockito/mockito.dart'; +import 'package:platform_detect/test_utils.dart' as platform; + class MockWindow extends Mock implements html.Window {} void main() { @@ -17,6 +18,10 @@ void main() { MockWindow mockWindow = MockWindow(); UrlLauncherPlugin plugin = UrlLauncherPlugin(window: mockWindow); + setUp(() { + platform.configurePlatformForTesting(browser: platform.chrome); + }); + group('canLaunch', () { test('"http" URLs -> true', () { expect(plugin.canLaunch('http://google.com'), completion(isTrue)); @@ -75,28 +80,46 @@ void main() { }); group('openNewWindow', () { - bool _standalone; + test('http urls should be launched in a new window', () { + plugin.openNewWindow('http://www.google.com'); - setUp(() { - _standalone = navigator.standalone; + verify(mockWindow.open('http://www.google.com', '')); }); - tearDown(() { - navigator.standalone = _standalone; - }); - - test('the window that is launched is a new window', () { + test('https urls should be launched in a new window', () { plugin.openNewWindow('https://www.google.com'); verify(mockWindow.open('https://www.google.com', '')); }); - test('the window that is launched is in the same window', () { - navigator.standalone = true; + test('mailto urls should be launched on a new window', () { + plugin.openNewWindow('mailto:name@mydomain.com'); - plugin.openNewWindow('https://www.google.com'); + verify(mockWindow.open('mailto:name@mydomain.com', '')); + }); + + group('Safari', () { + setUp(() { + platform.configurePlatformForTesting(browser: platform.safari); + }); + + test('http urls should be launched in a new window', () { + plugin.openNewWindow('http://www.google.com'); + + verify(mockWindow.open('http://www.google.com', '')); + }); + + test('https urls should be launched in a new window', () { + plugin.openNewWindow('https://www.google.com'); + + verify(mockWindow.open('https://www.google.com', '')); + }); + + test('mailto urls should be launched on the same window', () { + plugin.openNewWindow('mailto:name@mydomain.com'); - verify(mockWindow.open('https://www.google.com', '_top')); + verify(mockWindow.open('mailto:name@mydomain.com', '_top')); + }); }); }); });