[url_launcher_web] Launch mailto urls in same window in Safari (#2740)
This uses package:platform_detect to determine whether the app is running in Safari or not.
https://pub.dev/packages/platform_detect
Co-authored-by: David Iglesias Teixeira <ditman@gmail.com>
diff --git a/packages/url_launcher/url_launcher_web/CHANGELOG.md b/packages/url_launcher/url_launcher_web/CHANGELOG.md
index 0702685..df1b2c9 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 4c7a99d..0000000
--- 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 cce2bbf..e55ceb2 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 '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 @@
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 @@
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<bool> canLaunch(String url) {
- final Uri parsedUrl = Uri.tryParse(url);
- if (parsedUrl == null) return Future<bool>.value(false);
-
- return Future<bool>.value(parsedUrl.isScheme('http') ||
- parsedUrl.isScheme('https') ||
- parsedUrl.isScheme('mailto'));
+ return Future<bool>.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 16bc4a5..207f2dc 100644
--- a/packages/url_launcher/url_launcher_web/pubspec.yaml
+++ b/packages/url_launcher/url_launcher_web/pubspec.yaml
@@ -4,7 +4,7 @@
# 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 @@
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 @@
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 b6cf8b7..4cf9206 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 @@
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 @@
});
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', ''));
+ });
- verify(mockWindow.open('https://www.google.com', '_top'));
+ 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('mailto:name@mydomain.com', '_top'));
+ });
});
});
});