[url_launcher_web] Open url in same window when browser is in standalone mode. (#2656)
Fixes https://github.com/flutter/flutter/issues/51461
diff --git a/packages/url_launcher/url_launcher_web/CHANGELOG.md b/packages/url_launcher/url_launcher_web/CHANGELOG.md
index 0cb57ef..f8416af 100644
--- a/packages/url_launcher/url_launcher_web/CHANGELOG.md
+++ b/packages/url_launcher/url_launcher_web/CHANGELOG.md
@@ -1,3 +1,7 @@
+# 0.1.1+2
+
+- Open urls with target "_top" on iOS PWAs.
+
# 0.1.1+1
- Make the pedantic dev_dependency explicit.
diff --git a/packages/url_launcher/url_launcher_web/lib/src/navigator.dart b/packages/url_launcher/url_launcher_web/lib/src/navigator.dart
new file mode 100644
index 0000000..4c7a99d
--- /dev/null
+++ b/packages/url_launcher/url_launcher_web/lib/src/navigator.dart
@@ -0,0 +1,15 @@
+@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 c37d872..688df43 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,6 +4,7 @@
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;
/// The web implementation of [UrlLauncherPlatform].
///
@@ -19,7 +20,10 @@
/// Returns the newly created window.
@visibleForTesting
html.WindowBase openNewWindow(String url) {
- return html.window.open(url, '');
+ // We need to open on _top in ios browsers in standalone mode.
+ // See https://github.com/flutter/flutter/issues/51461 for reference.
+ final target = navigator.standalone ? '_top' : '';
+ return html.window.open(url, target);
}
@override
diff --git a/packages/url_launcher/url_launcher_web/pubspec.yaml b/packages/url_launcher/url_launcher_web/pubspec.yaml
index 8e74677..a43a828 100644
--- a/packages/url_launcher/url_launcher_web/pubspec.yaml
+++ b/packages/url_launcher/url_launcher_web/pubspec.yaml
@@ -1,7 +1,7 @@
name: url_launcher_web
description: Web platform implementation of url_launcher
homepage: https://github.com/flutter/plugins/tree/master/packages/url_launcher/url_launcher_web
-version: 0.1.1+1
+version: 0.1.1+2
flutter:
plugin:
@@ -17,6 +17,7 @@
flutter_web_plugins:
sdk: flutter
meta: ^1.1.7
+ js: ^0.6.0
dev_dependencies:
flutter_test:
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 3fb9b78..8711013 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
@@ -5,10 +5,10 @@
@TestOn('chrome') // Uses web-only Flutter SDK
import 'dart:html' as html;
-
import 'package:flutter_test/flutter_test.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:url_launcher_web/url_launcher_web.dart';
+import 'package:url_launcher_web/src/navigator.dart' as navigator;
import 'package:url_launcher_platform_interface/url_launcher_platform_interface.dart';
void main() {
@@ -54,6 +54,19 @@
expect(newWindow.opener, equals(html.window));
});
+ test('the window that is launched is in the same window', () {
+ final originalStandalone = navigator.standalone;
+ // Simulate the navigator is in standalone mode on iOS devices.
+ // https://developer.mozilla.org/en-US/docs/Web/API/Navigator
+ navigator.standalone = true;
+ final UrlLauncherPlugin urlLauncherPlugin = UrlLauncherPlugin();
+ final html.WindowBase window =
+ urlLauncherPlugin.openNewWindow('https://www.google.com');
+ expect(window, isNotNull);
+ expect(window.opener, isNot(equals(html.window)));
+ navigator.standalone = originalStandalone;
+ });
+
test('does not implement closeWebView()', () {
expect(closeWebView(), throwsUnimplementedError);
});