diff --git a/packages/url_launcher/url_launcher_web/CHANGELOG.md b/packages/url_launcher/url_launcher_web/CHANGELOG.md index ed8f68129c3..b891293c005 100644 --- a/packages/url_launcher/url_launcher_web/CHANGELOG.md +++ b/packages/url_launcher/url_launcher_web/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.3.3 + +* Changes `launchUrl` so it always returns `true`, except for disallowed URL schemes. + ## 2.3.2 * Adds support for `web: ^1.0.0`. diff --git a/packages/url_launcher/url_launcher_web/README.md b/packages/url_launcher/url_launcher_web/README.md index 91d7fb623b0..6853a6ccc53 100644 --- a/packages/url_launcher/url_launcher_web/README.md +++ b/packages/url_launcher/url_launcher_web/README.md @@ -30,4 +30,14 @@ In such cases, you can use the `webOnlyWindowName` parameter, setting it to `_self`, to open the URL within the current tab. Another approach is to ensure that the `uri` is synchronously ready. -Read more: MDN > [Transient activation](https://developer.mozilla.org/en-US/docs/Glossary/Transient_activation). \ No newline at end of file +Read more: MDN > [Transient activation](https://developer.mozilla.org/en-US/docs/Glossary/Transient_activation). + +### Method `launchUrl` always returns `true` for allowed schemes + +The `launchUrl` method always returns `true` on the web platform for allowed +schemes. This is because URLs are opened in a new window using the `noopener` +window feature. When the `noopener` feature is used, the browser does not +return any information that can be used to determine if the link was +successfully opened. + +Read more: MDN > [window.open](https://developer.mozilla.org/en-US/docs/Web/API/Window/open#noopener). \ No newline at end of file diff --git a/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.dart b/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.dart index b7590387346..00b74cd6f59 100644 --- a/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.dart +++ b/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.dart @@ -120,6 +120,15 @@ void main() { (WidgetTester _) async { expect(plugin.launch('javascript:alert("1")'), completion(isFalse)); }); + + testWidgets('launching a unknown sceheme returns true', + (WidgetTester _) async { + expect( + plugin.launch( + 'foo:bar', + ), + completion(isTrue)); + }); }); group('openNewWindow', () { 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 070852db4c3..1a33f3aea7c 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 @@ -66,9 +66,12 @@ class UrlLauncherPlugin extends UrlLauncherPlatform { /// Opens the given [url] in the specified [webOnlyWindowName]. /// - /// Returns the newly created window. + /// Always returns `true`, except for disallowed schemes. Because `noopener` + /// is used as a window feature, it can not be detected if the window was + /// opened successfully. + /// See https://html.spec.whatwg.org/multipage/nav-history-apis.html#window-open-steps. @visibleForTesting - html.Window? openNewWindow(String url, {String? webOnlyWindowName}) { + bool openNewWindow(String url, {String? webOnlyWindowName}) { final String? scheme = _getUrlScheme(url); // Actively disallow opening some schemes, like javascript. // See https://github.com/flutter/flutter/issues/136657 @@ -76,7 +79,7 @@ class UrlLauncherPlugin extends UrlLauncherPlatform { if (kDebugMode) { print('Disallowed URL with scheme: $scheme'); } - return null; + return false; } // Some schemes need to be opened on the _top window context on Safari. // See https://github.com/flutter/flutter/issues/51461 @@ -84,7 +87,9 @@ class UrlLauncherPlugin extends UrlLauncherPlatform { ((_isSafari && _isSafariTargetTopScheme(scheme)) ? '_top' : ''); // ignore: unsafe_html - return _window.open(url, target, 'noopener,noreferrer'); + _window.open(url, target, 'noopener,noreferrer'); + + return true; } @override @@ -109,7 +114,7 @@ class UrlLauncherPlugin extends UrlLauncherPlatform { @override Future launchUrl(String url, LaunchOptions options) async { final String? windowName = options.webOnlyWindowName; - return openNewWindow(url, webOnlyWindowName: windowName) != null; + return openNewWindow(url, webOnlyWindowName: windowName); } @override diff --git a/packages/url_launcher/url_launcher_web/pubspec.yaml b/packages/url_launcher/url_launcher_web/pubspec.yaml index 9149edfcbe3..3730a4dd90e 100644 --- a/packages/url_launcher/url_launcher_web/pubspec.yaml +++ b/packages/url_launcher/url_launcher_web/pubspec.yaml @@ -2,7 +2,7 @@ name: url_launcher_web description: Web platform implementation of url_launcher repository: https://github.com/flutter/packages/tree/main/packages/url_launcher/url_launcher_web issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+url_launcher%22 -version: 2.3.2 +version: 2.3.3 environment: sdk: ^3.3.0