Skip to content

Commit f314a1e

Browse files
tugorezditman
authored and
Egor
committed
[url_launcher_web] Launch mailto urls in same window in Safari (flutter#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 <[email protected]>
1 parent 49f304a commit f314a1e

File tree

5 files changed

+61
-43
lines changed

5 files changed

+61
-43
lines changed

packages/url_launcher/url_launcher_web/CHANGELOG.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,23 @@
1+
# 0.1.1+6
2+
3+
- Open "mailto" urls with target set as "\_top" on Safari browsers.
4+
- Update lower bound of dart dependency to 2.2.0.
5+
16
# 0.1.1+5
27

3-
* Update lower bound of dart dependency to 2.1.0.
8+
- Update lower bound of dart dependency to 2.1.0.
49

510
# 0.1.1+4
611

7-
* Declare API stability and compatibility with `1.0.0` (more details at: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0).
12+
- Declare API stability and compatibility with `1.0.0` (more details at: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0).
813

914
# 0.1.1+3
1015

1116
- Refactor tests to not rely on the underlying browser behavior.
1217

1318
# 0.1.1+2
1419

15-
- Open urls with target "_top" on iOS PWAs.
20+
- Open urls with target "\_top" on iOS PWAs.
1621

1722
# 0.1.1+1
1823

packages/url_launcher/url_launcher_web/lib/src/navigator.dart

Lines changed: 0 additions & 15 deletions
This file was deleted.

packages/url_launcher/url_launcher_web/lib/url_launcher_web.dart

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,20 @@ import 'dart:html' as html;
44
import 'package:flutter_web_plugins/flutter_web_plugins.dart';
55
import 'package:meta/meta.dart';
66
import 'package:url_launcher_platform_interface/url_launcher_platform_interface.dart';
7-
import 'src/navigator.dart' as navigator;
7+
8+
import 'package:platform_detect/platform_detect.dart' show browser;
9+
10+
const _mailtoScheme = 'mailto';
811

912
/// The web implementation of [UrlLauncherPlatform].
1013
///
1114
/// This class implements the `package:url_launcher` functionality for the web.
1215
class UrlLauncherPlugin extends UrlLauncherPlatform {
1316
html.Window _window;
1417

18+
// The set of schemes that can be handled by the plugin
19+
static final _supportedSchemes = {'http', 'https', _mailtoScheme};
20+
1521
/// A constructor that allows tests to override the window object used by the plugin.
1622
UrlLauncherPlugin({@visibleForTesting html.Window window})
1723
: _window = window ?? html.window;
@@ -21,25 +27,24 @@ class UrlLauncherPlugin extends UrlLauncherPlatform {
2127
UrlLauncherPlatform.instance = UrlLauncherPlugin();
2228
}
2329

30+
String _getUrlScheme(String url) => Uri.tryParse(url)?.scheme;
31+
32+
bool _isMailtoScheme(String url) => _getUrlScheme(url) == _mailtoScheme;
33+
2434
/// Opens the given [url] in a new window.
2535
///
2636
/// Returns the newly created window.
2737
@visibleForTesting
2838
html.WindowBase openNewWindow(String url) {
29-
// We need to open on _top in ios browsers in standalone mode.
39+
// We need to open mailto urls on the _top window context on safari browsers.
3040
// See https://github.com/flutter/flutter/issues/51461 for reference.
31-
final target = navigator.standalone ? '_top' : '';
41+
final target = browser.isSafari && _isMailtoScheme(url) ? '_top' : '';
3242
return _window.open(url, target);
3343
}
3444

3545
@override
3646
Future<bool> canLaunch(String url) {
37-
final Uri parsedUrl = Uri.tryParse(url);
38-
if (parsedUrl == null) return Future<bool>.value(false);
39-
40-
return Future<bool>.value(parsedUrl.isScheme('http') ||
41-
parsedUrl.isScheme('https') ||
42-
parsedUrl.isScheme('mailto'));
47+
return Future<bool>.value(_supportedSchemes.contains(_getUrlScheme(url)));
4348
}
4449

4550
@override

packages/url_launcher/url_launcher_web/pubspec.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ homepage: https://github.com/flutter/plugins/tree/master/packages/url_launcher/u
44
# 0.1.y+z is compatible with 1.0.0, if you land a breaking change bump
55
# the version to 2.0.0.
66
# See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0
7-
version: 0.1.1+5
7+
version: 0.1.1+6
88

99
flutter:
1010
plugin:
@@ -15,12 +15,12 @@ flutter:
1515

1616
dependencies:
1717
url_launcher_platform_interface: ^1.0.1
18+
platform_detect: ^1.4.0
1819
flutter:
1920
sdk: flutter
2021
flutter_web_plugins:
2122
sdk: flutter
2223
meta: ^1.1.7
23-
js: ^0.6.0
2424

2525
dev_dependencies:
2626
flutter_test:
@@ -30,5 +30,5 @@ dev_dependencies:
3030
mockito: ^4.1.1
3131

3232
environment:
33-
sdk: ">=2.1.0 <3.0.0"
33+
sdk: ">=2.2.0 <3.0.0"
3434
flutter: ">=1.10.0 <2.0.0"

packages/url_launcher/url_launcher_web/test/url_launcher_web_test.dart

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,21 @@
77
import 'dart:html' as html;
88
import 'package:flutter_test/flutter_test.dart';
99
import 'package:url_launcher_web/url_launcher_web.dart';
10-
import 'package:url_launcher_web/src/navigator.dart' as navigator;
1110
import 'package:mockito/mockito.dart';
1211

12+
import 'package:platform_detect/test_utils.dart' as platform;
13+
1314
class MockWindow extends Mock implements html.Window {}
1415

1516
void main() {
1617
group('$UrlLauncherPlugin', () {
1718
MockWindow mockWindow = MockWindow();
1819
UrlLauncherPlugin plugin = UrlLauncherPlugin(window: mockWindow);
1920

21+
setUp(() {
22+
platform.configurePlatformForTesting(browser: platform.chrome);
23+
});
24+
2025
group('canLaunch', () {
2126
test('"http" URLs -> true', () {
2227
expect(plugin.canLaunch('http://google.com'), completion(isTrue));
@@ -75,28 +80,46 @@ void main() {
7580
});
7681

7782
group('openNewWindow', () {
78-
bool _standalone;
83+
test('http urls should be launched in a new window', () {
84+
plugin.openNewWindow('http://www.google.com');
7985

80-
setUp(() {
81-
_standalone = navigator.standalone;
86+
verify(mockWindow.open('http://www.google.com', ''));
8287
});
8388

84-
tearDown(() {
85-
navigator.standalone = _standalone;
86-
});
87-
88-
test('the window that is launched is a new window', () {
89+
test('https urls should be launched in a new window', () {
8990
plugin.openNewWindow('https://www.google.com');
9091

9192
verify(mockWindow.open('https://www.google.com', ''));
9293
});
9394

94-
test('the window that is launched is in the same window', () {
95-
navigator.standalone = true;
95+
test('mailto urls should be launched on a new window', () {
96+
plugin.openNewWindow('mailto:[email protected]');
9697

97-
plugin.openNewWindow('https://www.google.com');
98+
verify(mockWindow.open('mailto:[email protected]', ''));
99+
});
100+
101+
group('Safari', () {
102+
setUp(() {
103+
platform.configurePlatformForTesting(browser: platform.safari);
104+
});
105+
106+
test('http urls should be launched in a new window', () {
107+
plugin.openNewWindow('http://www.google.com');
108+
109+
verify(mockWindow.open('http://www.google.com', ''));
110+
});
111+
112+
test('https urls should be launched in a new window', () {
113+
plugin.openNewWindow('https://www.google.com');
114+
115+
verify(mockWindow.open('https://www.google.com', ''));
116+
});
117+
118+
test('mailto urls should be launched on the same window', () {
119+
plugin.openNewWindow('mailto:[email protected]');
98120

99-
verify(mockWindow.open('https://www.google.com', '_top'));
121+
verify(mockWindow.open('mailto:[email protected]', '_top'));
122+
});
100123
});
101124
});
102125
});

0 commit comments

Comments
 (0)