Skip to content
This repository has been archived by the owner on Feb 22, 2023. It is now read-only.

[url_launcher] Switch to new launchUrl interface #5985

Merged
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion packages/url_launcher/url_launcher/CHANGELOG.md
@@ -1,5 +1,6 @@
## NEXT
## 6.1.4

* Adopts new platform interface method for launching URLs.
* Ignores unnecessary import warnings in preparation for [upcoming Flutter changes](https://github.com/flutter/flutter/pull/105648).

## 6.1.3
Expand Down
32 changes: 32 additions & 0 deletions packages/url_launcher/url_launcher/lib/src/type_conversion.dart
@@ -0,0 +1,32 @@
// Copyright 2013 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.

import 'package:url_launcher_platform_interface/url_launcher_platform_interface.dart';

import 'types.dart';

/// Converts an (app-facing) [WebViewConfiguration] to a (platform interface)
/// [InAppWebViewConfiguration].
InAppWebViewConfiguration convertConfiguration(WebViewConfiguration config) {
return InAppWebViewConfiguration(
enableJavaScript: config.enableJavaScript,
enableDomStorage: config.enableDomStorage,
headers: config.headers,
);
}

/// Converts an (app-facing) [LaunchMode] to a (platform interface)
/// [PreferredLaunchMode].
PreferredLaunchMode convertLaunchMode(LaunchMode mode) {
switch (mode) {
case LaunchMode.platformDefault:
return PreferredLaunchMode.platformDefault;
case LaunchMode.inAppWebView:
return PreferredLaunchMode.inAppWebView;
case LaunchMode.externalApplication:
return PreferredLaunchMode.externalApplication;
case LaunchMode.externalNonBrowserApplication:
return PreferredLaunchMode.externalNonBrowserApplication;
}
}
Expand Up @@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:url_launcher/src/type_conversion.dart';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: relative url

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, I noticed and fixed the other file's copy, but missed this one. I wish VS Code weren't so eager to add package-based imports.

import 'package:url_launcher_platform_interface/url_launcher_platform_interface.dart';

import 'types.dart';
Expand All @@ -24,27 +25,18 @@ Future<bool> launchUrlString(
WebViewConfiguration webViewConfiguration = const WebViewConfiguration(),
String? webOnlyWindowName,
}) async {
final bool isWebURL =
urlString.startsWith('http:') || urlString.startsWith('https:');
if (mode == LaunchMode.inAppWebView && !isWebURL) {
if (mode == LaunchMode.inAppWebView &&
!(urlString.startsWith('https:') || urlString.startsWith('http:'))) {
throw ArgumentError.value(urlString, 'urlString',
'To use an in-app web view, you must provide an http(s) URL.');
}
final bool useWebView = mode == LaunchMode.inAppWebView ||
(isWebURL && mode == LaunchMode.platformDefault);

// TODO(stuartmorgan): Create a replacement platform interface method that
// uses something more like the new argument structure, and switch to using
// that, to support launch mode on more platforms.
return await UrlLauncherPlatform.instance.launch(
return await UrlLauncherPlatform.instance.launchUrl(
urlString,
useSafariVC: useWebView,
useWebView: useWebView,
enableJavaScript: webViewConfiguration.enableJavaScript,
enableDomStorage: webViewConfiguration.enableDomStorage,
universalLinksOnly: mode == LaunchMode.externalNonBrowserApplication,
headers: webViewConfiguration.headers,
webOnlyWindowName: webOnlyWindowName,
LaunchOptions(
mode: convertLaunchMode(mode),
webViewConfiguration: convertConfiguration(webViewConfiguration),
webOnlyWindowName: webOnlyWindowName,
),
);
}

Expand Down
20 changes: 10 additions & 10 deletions packages/url_launcher/url_launcher/lib/src/url_launcher_uri.dart
Expand Up @@ -7,6 +7,8 @@ import 'dart:async';
import 'package:url_launcher/url_launcher_string.dart';
import 'package:url_launcher_platform_interface/url_launcher_platform_interface.dart';

import 'type_conversion.dart';

/// Passes [url] to the underlying platform for handling.
///
/// [mode] support varies significantly by platform:
Expand Down Expand Up @@ -43,20 +45,18 @@ Future<bool> launchUrl(
WebViewConfiguration webViewConfiguration = const WebViewConfiguration(),
String? webOnlyWindowName,
}) async {
final bool isWebURL = url.scheme == 'http' || url.scheme == 'https';
if (mode == LaunchMode.inAppWebView && !isWebURL) {
if (mode == LaunchMode.inAppWebView &&
!(url.scheme == 'https' || url.scheme == 'http')) {
throw ArgumentError.value(url, 'url',
'To use an in-app web view, you must provide an http(s) URL.');
}
// TODO(stuartmorgan): Use UrlLauncherPlatform directly once a new API
// that better matches these parameters has been added. For now, delegate to
// launchUrlString so that there's only one copy of the parameter translation
// logic.
return await launchUrlString(
return await UrlLauncherPlatform.instance.launchUrl(
url.toString(),
mode: mode,
webViewConfiguration: webViewConfiguration,
webOnlyWindowName: webOnlyWindowName,
LaunchOptions(
mode: convertLaunchMode(mode),
webViewConfiguration: convertConfiguration(webViewConfiguration),
webOnlyWindowName: webOnlyWindowName,
),
);
}

Expand Down
4 changes: 2 additions & 2 deletions packages/url_launcher/url_launcher/pubspec.yaml
Expand Up @@ -3,7 +3,7 @@ description: Flutter plugin for launching a URL. Supports
web, phone, SMS, and email schemes.
repository: https://github.com/flutter/plugins/tree/main/packages/url_launcher/url_launcher
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+url_launcher%22
version: 6.1.3
version: 6.1.4

environment:
sdk: ">=2.14.0 <3.0.0"
Expand Down Expand Up @@ -34,7 +34,7 @@ dependencies:
# implementations, as both are compatible.
url_launcher_linux: ">=2.0.0 <4.0.0"
url_launcher_macos: ">=2.0.0 <4.0.0"
url_launcher_platform_interface: ^2.0.3
url_launcher_platform_interface: ^2.1.0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

url_launcher_web: ^2.0.0
url_launcher_windows: ">=2.0.0 <4.0.0"

Expand Down
8 changes: 3 additions & 5 deletions packages/url_launcher/url_launcher/test/link_test.dart
Expand Up @@ -19,7 +19,7 @@ void main() {
UrlLauncherPlatform.instance = mock;
});

group('$Link', () {
group('Link', () {
testWidgets('handles null uri correctly', (WidgetTester tester) async {
bool isBuilt = false;
FollowLink? followLink;
Expand Down Expand Up @@ -55,8 +55,7 @@ void main() {
mock
..setLaunchExpectations(
url: 'http://example.com/foobar',
useSafariVC: false,
useWebView: false,
launchMode: PreferredLaunchMode.externalApplication,
universalLinksOnly: false,
enableJavaScript: true,
enableDomStorage: true,
Expand Down Expand Up @@ -85,8 +84,7 @@ void main() {
mock
..setLaunchExpectations(
url: 'http://example.com/foobar',
useSafariVC: true,
useWebView: true,
launchMode: PreferredLaunchMode.inAppWebView,
universalLinksOnly: false,
enableJavaScript: true,
enableDomStorage: true,
Expand Down
Expand Up @@ -11,6 +11,7 @@ class MockUrlLauncher extends Fake
with MockPlatformInterfaceMixin
implements UrlLauncherPlatform {
String? url;
PreferredLaunchMode? launchMode;
bool? useSafariVC;
bool? useWebView;
bool? enableJavaScript;
Expand All @@ -32,15 +33,17 @@ class MockUrlLauncher extends Fake

void setLaunchExpectations({
required String url,
required bool? useSafariVC,
required bool useWebView,
PreferredLaunchMode? launchMode,
bool? useSafariVC,
bool? useWebView,
required bool enableJavaScript,
required bool enableDomStorage,
required bool universalLinksOnly,
required Map<String, String> headers,
required String? webOnlyWindowName,
}) {
this.url = url;
this.launchMode = launchMode;
this.useSafariVC = useSafariVC;
this.useWebView = useWebView;
this.enableJavaScript = enableJavaScript;
Expand Down Expand Up @@ -88,6 +91,18 @@ class MockUrlLauncher extends Fake
return response!;
}

@override
Future<bool> launchUrl(String url, LaunchOptions options) async {
expect(url, this.url);
expect(options.mode, launchMode);
expect(options.webViewConfiguration.enableJavaScript, enableJavaScript);
expect(options.webViewConfiguration.enableDomStorage, enableDomStorage);
expect(options.webViewConfiguration.headers, headers);
expect(options.webOnlyWindowName, webOnlyWindowName);
launchCalled = true;
return response!;
}

@override
Future<void> closeWebView() async {
closeWebViewCalled = true;
Expand Down
Expand Up @@ -43,8 +43,7 @@ void main() {
mock
..setLaunchExpectations(
url: urlString,
useSafariVC: true,
useWebView: true,
launchMode: PreferredLaunchMode.platformDefault,
enableJavaScript: true,
enableDomStorage: true,
universalLinksOnly: false,
Expand All @@ -60,8 +59,7 @@ void main() {
mock
..setLaunchExpectations(
url: urlString,
useSafariVC: false,
useWebView: false,
launchMode: PreferredLaunchMode.platformDefault,
enableJavaScript: true,
enableDomStorage: true,
universalLinksOnly: false,
Expand All @@ -77,8 +75,7 @@ void main() {
mock
..setLaunchExpectations(
url: urlString,
useSafariVC: true,
useWebView: true,
launchMode: PreferredLaunchMode.platformDefault,
enableJavaScript: true,
enableDomStorage: true,
universalLinksOnly: false,
Expand All @@ -95,8 +92,7 @@ void main() {
mock
..setLaunchExpectations(
url: urlString,
useSafariVC: false,
useWebView: false,
launchMode: PreferredLaunchMode.platformDefault,
enableJavaScript: true,
enableDomStorage: true,
universalLinksOnly: false,
Expand All @@ -113,8 +109,7 @@ void main() {
mock
..setLaunchExpectations(
url: urlString,
useSafariVC: true,
useWebView: true,
launchMode: PreferredLaunchMode.inAppWebView,
enableJavaScript: true,
enableDomStorage: true,
universalLinksOnly: false,
Expand All @@ -131,8 +126,7 @@ void main() {
mock
..setLaunchExpectations(
url: urlString,
useSafariVC: false,
useWebView: false,
launchMode: PreferredLaunchMode.externalApplication,
enableJavaScript: true,
enableDomStorage: true,
universalLinksOnly: false,
Expand All @@ -151,8 +145,7 @@ void main() {
mock
..setLaunchExpectations(
url: urlString,
useSafariVC: false,
useWebView: false,
launchMode: PreferredLaunchMode.externalNonBrowserApplication,
enableJavaScript: true,
enableDomStorage: true,
universalLinksOnly: true,
Expand All @@ -171,8 +164,7 @@ void main() {
mock
..setLaunchExpectations(
url: urlString,
useSafariVC: true,
useWebView: true,
launchMode: PreferredLaunchMode.inAppWebView,
enableJavaScript: false,
enableDomStorage: true,
universalLinksOnly: false,
Expand All @@ -193,8 +185,7 @@ void main() {
mock
..setLaunchExpectations(
url: urlString,
useSafariVC: true,
useWebView: true,
launchMode: PreferredLaunchMode.inAppWebView,
enableJavaScript: true,
enableDomStorage: false,
universalLinksOnly: false,
Expand All @@ -215,8 +206,7 @@ void main() {
mock
..setLaunchExpectations(
url: urlString,
useSafariVC: true,
useWebView: true,
launchMode: PreferredLaunchMode.inAppWebView,
enableJavaScript: true,
enableDomStorage: true,
universalLinksOnly: false,
Expand Down Expand Up @@ -245,8 +235,7 @@ void main() {
mock
..setLaunchExpectations(
url: emailLaunchUrlString,
useSafariVC: false,
useWebView: false,
launchMode: PreferredLaunchMode.platformDefault,
enableJavaScript: true,
enableDomStorage: true,
universalLinksOnly: false,
Expand All @@ -264,8 +253,7 @@ void main() {
mock
..setLaunchExpectations(
url: urlString,
useSafariVC: false,
useWebView: false,
launchMode: PreferredLaunchMode.platformDefault,
enableJavaScript: true,
enableDomStorage: true,
universalLinksOnly: false,
Expand Down