From 68f8848f4212f4e384df7e6a51e4778ff3685efd Mon Sep 17 00:00:00 2001 From: Maurice Parrish Date: Wed, 2 Sep 2020 07:39:13 -0700 Subject: [PATCH 01/19] webview portion --- .../webviewflutter/FlutterWebView.java | 71 +++++++++++++++++++ .../webviewflutter/FlutterWebViewClient.java | 4 +- 2 files changed, 73 insertions(+), 2 deletions(-) diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java index f9659d9873f4..9b85cb9db375 100644 --- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java +++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java @@ -4,15 +4,27 @@ package io.flutter.plugins.webviewflutter; +import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.content.Context; +import android.graphics.Bitmap; import android.hardware.display.DisplayManager; import android.os.Build; import android.os.Handler; +import android.os.Message; +import android.view.KeyEvent; import android.view.View; +import android.webkit.WebChromeClient; +import android.webkit.WebResourceRequest; import android.webkit.WebStorage; +import android.webkit.WebView; import android.webkit.WebViewClient; + +import io.flutter.Log; import io.flutter.plugin.common.BinaryMessenger; + +import androidx.annotation.NonNull; +import androidx.webkit.WebViewClientCompat; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; import io.flutter.plugin.common.MethodChannel.MethodCallHandler; @@ -49,6 +61,9 @@ public class FlutterWebView implements PlatformView, MethodCallHandler { // Allow local storage. webView.getSettings().setDomStorageEnabled(true); webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true); + webView.getSettings().setSupportMultipleWindows(true); + // Internal Bug: b/159892679 + webView.setWebChromeClient(createWebChromeClient()); methodChannel = new MethodChannel(messenger, "plugins.flutter.io/webview_" + id); methodChannel.setMethodCallHandler(this); @@ -354,6 +369,62 @@ private void updateUserAgent(String userAgent) { webView.getSettings().setUserAgentString(userAgent); } + // Verifies that a url opened by `Window.open` has a secure url. + private boolean validNewWindowUrl(String url) { + return url.startsWith("https://") || url.startsWith("http://"); + } + + // Internal Bug: b/159892679 + private WebChromeClient createWebChromeClient() { + return new WebChromeClient() { + @Override + public boolean onCreateWindow(final WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) { + WebViewClient webViewClient; + if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + webViewClient = new WebViewClient() { + @Override + public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { + final String url = request.getUrl().toString(); + if (validNewWindowUrl(url)) { + flutterWebViewClient.shouldOverrideUrlLoading(FlutterWebView.this.webView, request); + } + return true; + } + }; + } else { + webViewClient = new WebViewClientCompat() { + @TargetApi(Build.VERSION_CODES.N) + @Override + public boolean shouldOverrideUrlLoading(@NonNull WebView view, @NonNull WebResourceRequest request) { + final String url = request.getUrl().toString(); + if (validNewWindowUrl(url)) { + flutterWebViewClient.shouldOverrideUrlLoading(FlutterWebView.this.webView, request); + } + return true; + } + + @Override + public boolean shouldOverrideUrlLoading(WebView view, String url) { + if (validNewWindowUrl(url)) { + flutterWebViewClient.shouldOverrideUrlLoading(FlutterWebView.this.webView, url); + } + return true; + } + }; + } + + final WebView newWebView = new WebView(view.getContext()); + newWebView.setWebViewClient(webViewClient); + + final WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj; + transport.setWebView(newWebView); + resultMsg.sendToTarget(); + + return true; + } + }; + } + @Override public void dispose() { methodChannel.setMethodCallHandler(null); diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebViewClient.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebViewClient.java index 474435ca3dfe..24926bfc4117 100644 --- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebViewClient.java +++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebViewClient.java @@ -77,7 +77,7 @@ private static String errorCodeToString(int errorCode) { } @TargetApi(Build.VERSION_CODES.LOLLIPOP) - private boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { + boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { if (!hasNavigationDelegate) { return false; } @@ -97,7 +97,7 @@ private boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest reques return request.isForMainFrame(); } - private boolean shouldOverrideUrlLoading(WebView view, String url) { + boolean shouldOverrideUrlLoading(WebView view, String url) { if (!hasNavigationDelegate) { return false; } From 733700293ea64317b7d02dfe5063edb64c72356d Mon Sep 17 00:00:00 2001 From: Maurice Parrish Date: Wed, 2 Sep 2020 09:48:42 -0700 Subject: [PATCH 02/19] url_launcher --- .../url_launcher/android/build.gradle | 1 + .../plugins/urllauncher/WebViewActivity.java | 69 +++++++++++++++++++ .../webviewflutter/FlutterWebView.java | 5 +- 3 files changed, 74 insertions(+), 1 deletion(-) diff --git a/packages/url_launcher/url_launcher/android/build.gradle b/packages/url_launcher/url_launcher/android/build.gradle index c02b29a5814f..f21da840dc93 100644 --- a/packages/url_launcher/url_launcher/android/build.gradle +++ b/packages/url_launcher/url_launcher/android/build.gradle @@ -38,6 +38,7 @@ android { dependencies { compileOnly 'androidx.annotation:annotation:1.0.0' + implementation 'androidx.webkit:webkit:1.0.0' testImplementation 'junit:junit:4.12' testImplementation 'org.mockito:mockito-core:1.10.19' testImplementation 'androidx.test:core:1.0.0' diff --git a/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java b/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java index 52714790a25c..d6b3c492c102 100644 --- a/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java +++ b/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java @@ -1,5 +1,6 @@ package io.flutter.plugins.urllauncher; +import android.annotation.TargetApi; import android.app.Activity; import android.content.BroadcastReceiver; import android.content.Context; @@ -7,11 +8,17 @@ import android.content.IntentFilter; import android.os.Build; import android.os.Bundle; +import android.os.Message; import android.provider.Browser; import android.view.KeyEvent; +import android.webkit.WebChromeClient; import android.webkit.WebResourceRequest; import android.webkit.WebView; import android.webkit.WebViewClient; + +import androidx.annotation.NonNull; +import androidx.webkit.WebViewClientCompat; + import java.util.HashMap; import java.util.Map; @@ -77,9 +84,12 @@ public void onCreate(Bundle savedInstanceState) { webview.getSettings().setJavaScriptEnabled(enableJavaScript); webview.getSettings().setDomStorageEnabled(enableDomStorage); + webview.getSettings().setSupportMultipleWindows(true); // Open new urls inside the webview itself. webview.setWebViewClient(webViewClient); + // Internal Bug: b/159892679 + webview.setWebChromeClient(createWebChromeClient()); // Register receiver that may finish this Activity. registerReceiver(broadcastReceiver, closeIntentFilter); @@ -126,4 +136,63 @@ public static Intent createIntent( .putExtra(ENABLE_DOM_EXTRA, enableDomStorage) .putExtra(Browser.EXTRA_HEADERS, headersBundle); } + + // Verifies that a url opened by `Window.open` has a secure url. + private boolean validNewWindowUrl(String url) { + return url.startsWith("https://") || url.startsWith("http://"); + } + + // Internal Bug: b/159892679 + private WebChromeClient createWebChromeClient() { + return new WebChromeClient() { + @Override + public boolean onCreateWindow(final WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) { + final WebViewClient webViewClient; + // This attempts to avoid using WebViewClientCompat due to bug + // https://bugs.chromium.org/p/chromium/issues/detail?id=925887. Also, see + // https://github.com/flutter/flutter/issues/29446. + if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + webViewClient = new WebViewClient() { + @Override + public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { + final String url = request.getUrl().toString(); + if (validNewWindowUrl(url)) { + webview.loadUrl(url); + } + return true; + } + }; + } else { + webViewClient = new WebViewClientCompat() { + @TargetApi(Build.VERSION_CODES.N) + @Override + public boolean shouldOverrideUrlLoading(@NonNull WebView view, @NonNull WebResourceRequest request) { + final String url = request.getUrl().toString(); + if (validNewWindowUrl(url)) { + webview.loadUrl(url); + } + return true; + } + + @Override + public boolean shouldOverrideUrlLoading(WebView view, String url) { + if (validNewWindowUrl(url)) { + webview.loadUrl(url); + } + return true; + } + }; + } + + final WebView newWebView = new WebView(view.getContext()); + newWebView.setWebViewClient(webViewClient); + + final WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj; + transport.setWebView(newWebView); + resultMsg.sendToTarget(); + + return true; + } + }; + } } diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java index 9b85cb9db375..444a768536fb 100644 --- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java +++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java @@ -379,7 +379,10 @@ private WebChromeClient createWebChromeClient() { return new WebChromeClient() { @Override public boolean onCreateWindow(final WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) { - WebViewClient webViewClient; + final WebViewClient webViewClient; + // This attempts to avoid using WebViewClientCompat due to bug + // https://bugs.chromium.org/p/chromium/issues/detail?id=925887. Also, see + // https://github.com/flutter/flutter/issues/29446. if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { webViewClient = new WebViewClient() { @Override From 3fa09aa46cf7b42d8c5cacce8f492a4d326dc03b Mon Sep 17 00:00:00 2001 From: Maurice Parrish Date: Wed, 2 Sep 2020 09:55:10 -0700 Subject: [PATCH 03/19] formatting --- .../plugins/urllauncher/WebViewActivity.java | 68 +++++++++-------- .../webviewflutter/FlutterWebView.java | 76 +++++++++---------- 2 files changed, 73 insertions(+), 71 deletions(-) diff --git a/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java b/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java index d6b3c492c102..92347e773354 100644 --- a/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java +++ b/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java @@ -15,10 +15,8 @@ import android.webkit.WebResourceRequest; import android.webkit.WebView; import android.webkit.WebViewClient; - import androidx.annotation.NonNull; import androidx.webkit.WebViewClientCompat; - import java.util.HashMap; import java.util.Map; @@ -146,42 +144,46 @@ private boolean validNewWindowUrl(String url) { private WebChromeClient createWebChromeClient() { return new WebChromeClient() { @Override - public boolean onCreateWindow(final WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) { + public boolean onCreateWindow( + final WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) { final WebViewClient webViewClient; // This attempts to avoid using WebViewClientCompat due to bug // https://bugs.chromium.org/p/chromium/issues/detail?id=925887. Also, see // https://github.com/flutter/flutter/issues/29446. - if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - webViewClient = new WebViewClient() { - @Override - public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { - final String url = request.getUrl().toString(); - if (validNewWindowUrl(url)) { - webview.loadUrl(url); - } - return true; - } - }; + if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + webViewClient = + new WebViewClient() { + @Override + public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { + final String url = request.getUrl().toString(); + if (validNewWindowUrl(url)) { + webview.loadUrl(url); + } + return true; + } + }; } else { - webViewClient = new WebViewClientCompat() { - @TargetApi(Build.VERSION_CODES.N) - @Override - public boolean shouldOverrideUrlLoading(@NonNull WebView view, @NonNull WebResourceRequest request) { - final String url = request.getUrl().toString(); - if (validNewWindowUrl(url)) { - webview.loadUrl(url); - } - return true; - } - - @Override - public boolean shouldOverrideUrlLoading(WebView view, String url) { - if (validNewWindowUrl(url)) { - webview.loadUrl(url); - } - return true; - } - }; + webViewClient = + new WebViewClientCompat() { + @TargetApi(Build.VERSION_CODES.N) + @Override + public boolean shouldOverrideUrlLoading( + @NonNull WebView view, @NonNull WebResourceRequest request) { + final String url = request.getUrl().toString(); + if (validNewWindowUrl(url)) { + webview.loadUrl(url); + } + return true; + } + + @Override + public boolean shouldOverrideUrlLoading(WebView view, String url) { + if (validNewWindowUrl(url)) { + webview.loadUrl(url); + } + return true; + } + }; } final WebView newWebView = new WebView(view.getContext()); diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java index 444a768536fb..706f1518440b 100644 --- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java +++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java @@ -4,27 +4,21 @@ package io.flutter.plugins.webviewflutter; -import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.content.Context; -import android.graphics.Bitmap; import android.hardware.display.DisplayManager; import android.os.Build; import android.os.Handler; import android.os.Message; -import android.view.KeyEvent; import android.view.View; import android.webkit.WebChromeClient; import android.webkit.WebResourceRequest; import android.webkit.WebStorage; import android.webkit.WebView; import android.webkit.WebViewClient; - -import io.flutter.Log; -import io.flutter.plugin.common.BinaryMessenger; - import androidx.annotation.NonNull; import androidx.webkit.WebViewClientCompat; +import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; import io.flutter.plugin.common.MethodChannel.MethodCallHandler; @@ -378,42 +372,48 @@ private boolean validNewWindowUrl(String url) { private WebChromeClient createWebChromeClient() { return new WebChromeClient() { @Override - public boolean onCreateWindow(final WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) { + public boolean onCreateWindow( + final WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) { final WebViewClient webViewClient; // This attempts to avoid using WebViewClientCompat due to bug // https://bugs.chromium.org/p/chromium/issues/detail?id=925887. Also, see // https://github.com/flutter/flutter/issues/29446. - if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - webViewClient = new WebViewClient() { - @Override - public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { - final String url = request.getUrl().toString(); - if (validNewWindowUrl(url)) { - flutterWebViewClient.shouldOverrideUrlLoading(FlutterWebView.this.webView, request); - } - return true; - } - }; + if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + webViewClient = + new WebViewClient() { + @Override + public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { + final String url = request.getUrl().toString(); + if (validNewWindowUrl(url)) { + flutterWebViewClient.shouldOverrideUrlLoading( + FlutterWebView.this.webView, request); + } + return true; + } + }; } else { - webViewClient = new WebViewClientCompat() { - @TargetApi(Build.VERSION_CODES.N) - @Override - public boolean shouldOverrideUrlLoading(@NonNull WebView view, @NonNull WebResourceRequest request) { - final String url = request.getUrl().toString(); - if (validNewWindowUrl(url)) { - flutterWebViewClient.shouldOverrideUrlLoading(FlutterWebView.this.webView, request); - } - return true; - } - - @Override - public boolean shouldOverrideUrlLoading(WebView view, String url) { - if (validNewWindowUrl(url)) { - flutterWebViewClient.shouldOverrideUrlLoading(FlutterWebView.this.webView, url); - } - return true; - } - }; + webViewClient = + new WebViewClientCompat() { + @TargetApi(Build.VERSION_CODES.N) + @Override + public boolean shouldOverrideUrlLoading( + @NonNull WebView view, @NonNull WebResourceRequest request) { + final String url = request.getUrl().toString(); + if (validNewWindowUrl(url)) { + flutterWebViewClient.shouldOverrideUrlLoading( + FlutterWebView.this.webView, request); + } + return true; + } + + @Override + public boolean shouldOverrideUrlLoading(WebView view, String url) { + if (validNewWindowUrl(url)) { + flutterWebViewClient.shouldOverrideUrlLoading(FlutterWebView.this.webView, url); + } + return true; + } + }; } final WebView newWebView = new WebView(view.getContext()); From 39b030bb2bd23ba7d60cee31cc42466bb1db0170 Mon Sep 17 00:00:00 2001 From: Maurice Parrish Date: Wed, 2 Sep 2020 12:18:09 -0700 Subject: [PATCH 04/19] Seperate to a class --- .../url_launcher/android/build.gradle | 1 - .../plugins/urllauncher/WebViewActivity.java | 107 +++++++---------- .../webviewflutter/FlutterWebView.java | 109 +++++++----------- 3 files changed, 84 insertions(+), 133 deletions(-) diff --git a/packages/url_launcher/url_launcher/android/build.gradle b/packages/url_launcher/url_launcher/android/build.gradle index f21da840dc93..c02b29a5814f 100644 --- a/packages/url_launcher/url_launcher/android/build.gradle +++ b/packages/url_launcher/url_launcher/android/build.gradle @@ -38,7 +38,6 @@ android { dependencies { compileOnly 'androidx.annotation:annotation:1.0.0' - implementation 'androidx.webkit:webkit:1.0.0' testImplementation 'junit:junit:4.12' testImplementation 'org.mockito:mockito-core:1.10.19' testImplementation 'androidx.test:core:1.0.0' diff --git a/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java b/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java index 92347e773354..b989c5235e63 100644 --- a/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java +++ b/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java @@ -16,7 +16,6 @@ import android.webkit.WebView; import android.webkit.WebViewClient; import androidx.annotation.NonNull; -import androidx.webkit.WebViewClientCompat; import java.util.HashMap; import java.util.Map; @@ -65,6 +64,47 @@ public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request private IntentFilter closeIntentFilter = new IntentFilter(ACTION_CLOSE); + private class FlutterWebChromeClient extends WebChromeClient { + @Override + public boolean onCreateWindow( + final WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) { + final WebViewClient webViewClient = + new WebViewClient() { + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + @Override + public boolean shouldOverrideUrlLoading( + @NonNull WebView view, @NonNull WebResourceRequest request) { + final String url = request.getUrl().toString(); + if (isSecure(url)) { + webview.loadUrl(url); + } + return true; + } + + @Override + public boolean shouldOverrideUrlLoading(WebView view, String url) { + if (isSecure(url)) { + webview.loadUrl(url); + } + return true; + } + }; + + final WebView newWebView = new WebView(webview.getContext()); + newWebView.setWebViewClient(webViewClient); + + final WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj; + transport.setWebView(newWebView); + resultMsg.sendToTarget(); + + return true; + } + // Verifies that a url opened by `Window.open` has a secure url. + private boolean isSecure(String url) { + return url.startsWith("https://") || url.startsWith("http://"); + } + } + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -87,7 +127,7 @@ public void onCreate(Bundle savedInstanceState) { // Open new urls inside the webview itself. webview.setWebViewClient(webViewClient); // Internal Bug: b/159892679 - webview.setWebChromeClient(createWebChromeClient()); + webview.setWebChromeClient(new FlutterWebChromeClient()); // Register receiver that may finish this Activity. registerReceiver(broadcastReceiver, closeIntentFilter); @@ -134,67 +174,4 @@ public static Intent createIntent( .putExtra(ENABLE_DOM_EXTRA, enableDomStorage) .putExtra(Browser.EXTRA_HEADERS, headersBundle); } - - // Verifies that a url opened by `Window.open` has a secure url. - private boolean validNewWindowUrl(String url) { - return url.startsWith("https://") || url.startsWith("http://"); - } - - // Internal Bug: b/159892679 - private WebChromeClient createWebChromeClient() { - return new WebChromeClient() { - @Override - public boolean onCreateWindow( - final WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) { - final WebViewClient webViewClient; - // This attempts to avoid using WebViewClientCompat due to bug - // https://bugs.chromium.org/p/chromium/issues/detail?id=925887. Also, see - // https://github.com/flutter/flutter/issues/29446. - if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - webViewClient = - new WebViewClient() { - @Override - public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { - final String url = request.getUrl().toString(); - if (validNewWindowUrl(url)) { - webview.loadUrl(url); - } - return true; - } - }; - } else { - webViewClient = - new WebViewClientCompat() { - @TargetApi(Build.VERSION_CODES.N) - @Override - public boolean shouldOverrideUrlLoading( - @NonNull WebView view, @NonNull WebResourceRequest request) { - final String url = request.getUrl().toString(); - if (validNewWindowUrl(url)) { - webview.loadUrl(url); - } - return true; - } - - @Override - public boolean shouldOverrideUrlLoading(WebView view, String url) { - if (validNewWindowUrl(url)) { - webview.loadUrl(url); - } - return true; - } - }; - } - - final WebView newWebView = new WebView(view.getContext()); - newWebView.setWebViewClient(webViewClient); - - final WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj; - transport.setWebView(newWebView); - resultMsg.sendToTarget(); - - return true; - } - }; - } } diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java index 706f1518440b..c0c8afe2f58f 100644 --- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java +++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java @@ -17,7 +17,6 @@ import android.webkit.WebView; import android.webkit.WebViewClient; import androidx.annotation.NonNull; -import androidx.webkit.WebViewClientCompat; import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; @@ -35,6 +34,47 @@ public class FlutterWebView implements PlatformView, MethodCallHandler { private final FlutterWebViewClient flutterWebViewClient; private final Handler platformThreadHandler; + private class FlutterWebChromeClient extends WebChromeClient { + @Override + public boolean onCreateWindow( + final WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) { + final WebViewClient webViewClient = + new WebViewClient() { + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + @Override + public boolean shouldOverrideUrlLoading( + @NonNull WebView view, @NonNull WebResourceRequest request) { + final String url = request.getUrl().toString(); + if (isSecure(url)) { + flutterWebViewClient.shouldOverrideUrlLoading(FlutterWebView.this.webView, request); + } + return true; + } + + @Override + public boolean shouldOverrideUrlLoading(WebView view, String url) { + if (isSecure(url)) { + flutterWebViewClient.shouldOverrideUrlLoading(FlutterWebView.this.webView, url); + } + return true; + } + }; + + final WebView newWebView = new WebView(view.getContext()); + newWebView.setWebViewClient(webViewClient); + + final WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj; + transport.setWebView(newWebView); + resultMsg.sendToTarget(); + + return true; + } + // Verifies that a url opened by `Window.open` has a secure url. + private boolean isSecure(String url) { + return url.startsWith("https://") || url.startsWith("http://"); + } + } + @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) @SuppressWarnings("unchecked") FlutterWebView( @@ -57,7 +97,7 @@ public class FlutterWebView implements PlatformView, MethodCallHandler { webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true); webView.getSettings().setSupportMultipleWindows(true); // Internal Bug: b/159892679 - webView.setWebChromeClient(createWebChromeClient()); + webView.setWebChromeClient(new FlutterWebChromeClient()); methodChannel = new MethodChannel(messenger, "plugins.flutter.io/webview_" + id); methodChannel.setMethodCallHandler(this); @@ -363,71 +403,6 @@ private void updateUserAgent(String userAgent) { webView.getSettings().setUserAgentString(userAgent); } - // Verifies that a url opened by `Window.open` has a secure url. - private boolean validNewWindowUrl(String url) { - return url.startsWith("https://") || url.startsWith("http://"); - } - - // Internal Bug: b/159892679 - private WebChromeClient createWebChromeClient() { - return new WebChromeClient() { - @Override - public boolean onCreateWindow( - final WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) { - final WebViewClient webViewClient; - // This attempts to avoid using WebViewClientCompat due to bug - // https://bugs.chromium.org/p/chromium/issues/detail?id=925887. Also, see - // https://github.com/flutter/flutter/issues/29446. - if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - webViewClient = - new WebViewClient() { - @Override - public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { - final String url = request.getUrl().toString(); - if (validNewWindowUrl(url)) { - flutterWebViewClient.shouldOverrideUrlLoading( - FlutterWebView.this.webView, request); - } - return true; - } - }; - } else { - webViewClient = - new WebViewClientCompat() { - @TargetApi(Build.VERSION_CODES.N) - @Override - public boolean shouldOverrideUrlLoading( - @NonNull WebView view, @NonNull WebResourceRequest request) { - final String url = request.getUrl().toString(); - if (validNewWindowUrl(url)) { - flutterWebViewClient.shouldOverrideUrlLoading( - FlutterWebView.this.webView, request); - } - return true; - } - - @Override - public boolean shouldOverrideUrlLoading(WebView view, String url) { - if (validNewWindowUrl(url)) { - flutterWebViewClient.shouldOverrideUrlLoading(FlutterWebView.this.webView, url); - } - return true; - } - }; - } - - final WebView newWebView = new WebView(view.getContext()); - newWebView.setWebViewClient(webViewClient); - - final WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj; - transport.setWebView(newWebView); - resultMsg.sendToTarget(); - - return true; - } - }; - } - @Override public void dispose() { methodChannel.setMethodCallHandler(null); From bb8154ba328ef05ca79f4fcf9cd2ab0d50c41305 Mon Sep 17 00:00:00 2001 From: Maurice Parrish Date: Wed, 2 Sep 2020 12:20:12 -0700 Subject: [PATCH 05/19] Add documentation --- .../java/io/flutter/plugins/urllauncher/WebViewActivity.java | 5 +++-- .../io/flutter/plugins/webviewflutter/FlutterWebView.java | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java b/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java index b989c5235e63..7af1ffb15d93 100644 --- a/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java +++ b/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java @@ -122,11 +122,12 @@ public void onCreate(Bundle savedInstanceState) { webview.getSettings().setJavaScriptEnabled(enableJavaScript); webview.getSettings().setDomStorageEnabled(enableDomStorage); - webview.getSettings().setSupportMultipleWindows(true); // Open new urls inside the webview itself. webview.setWebViewClient(webViewClient); - // Internal Bug: b/159892679 + + // Multi windows is set with FlutterWebChromeClient by default to handle internal bug: b/159892679. + webview.getSettings().setSupportMultipleWindows(true); webview.setWebChromeClient(new FlutterWebChromeClient()); // Register receiver that may finish this Activity. diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java index c0c8afe2f58f..11dd7cd06a52 100644 --- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java +++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java @@ -95,8 +95,9 @@ private boolean isSecure(String url) { // Allow local storage. webView.getSettings().setDomStorageEnabled(true); webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true); + + // Multi windows is set with FlutterWebChromeClient by default to handle internal bug: b/159892679. webView.getSettings().setSupportMultipleWindows(true); - // Internal Bug: b/159892679 webView.setWebChromeClient(new FlutterWebChromeClient()); methodChannel = new MethodChannel(messenger, "plugins.flutter.io/webview_" + id); From 625f673ce76800a0e5684ea95a33b05209c3394f Mon Sep 17 00:00:00 2001 From: Maurice Parrish Date: Wed, 2 Sep 2020 12:21:16 -0700 Subject: [PATCH 06/19] Change doc location --- .../java/io/flutter/plugins/urllauncher/WebViewActivity.java | 3 ++- .../java/io/flutter/plugins/webviewflutter/FlutterWebView.java | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java b/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java index 7af1ffb15d93..321f7bfa325f 100644 --- a/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java +++ b/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java @@ -64,6 +64,7 @@ public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request private IntentFilter closeIntentFilter = new IntentFilter(ACTION_CLOSE); + // Verifies that a url opened by `Window.open` has a secure url. private class FlutterWebChromeClient extends WebChromeClient { @Override public boolean onCreateWindow( @@ -99,7 +100,7 @@ public boolean shouldOverrideUrlLoading(WebView view, String url) { return true; } - // Verifies that a url opened by `Window.open` has a secure url. + private boolean isSecure(String url) { return url.startsWith("https://") || url.startsWith("http://"); } diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java index 11dd7cd06a52..bc6db05ebc83 100644 --- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java +++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java @@ -34,6 +34,7 @@ public class FlutterWebView implements PlatformView, MethodCallHandler { private final FlutterWebViewClient flutterWebViewClient; private final Handler platformThreadHandler; + // Verifies that a url opened by `Window.open` has a secure url. private class FlutterWebChromeClient extends WebChromeClient { @Override public boolean onCreateWindow( @@ -69,7 +70,7 @@ public boolean shouldOverrideUrlLoading(WebView view, String url) { return true; } - // Verifies that a url opened by `Window.open` has a secure url. + private boolean isSecure(String url) { return url.startsWith("https://") || url.startsWith("http://"); } From 9f8014ff7ff9be83a9d3a114d617b23ff8d344a6 Mon Sep 17 00:00:00 2001 From: Maurice Parrish Date: Fri, 4 Sep 2020 09:25:03 -0700 Subject: [PATCH 07/19] load with no navigation delegate --- .../plugins/webviewflutter/FlutterWebView.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java index bc6db05ebc83..233b98c2c624 100644 --- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java +++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java @@ -43,19 +43,18 @@ public boolean onCreateWindow( new WebViewClient() { @TargetApi(Build.VERSION_CODES.LOLLIPOP) @Override - public boolean shouldOverrideUrlLoading( - @NonNull WebView view, @NonNull WebResourceRequest request) { + public boolean shouldOverrideUrlLoading(@NonNull WebView view, @NonNull WebResourceRequest request) { final String url = request.getUrl().toString(); - if (isSecure(url)) { - flutterWebViewClient.shouldOverrideUrlLoading(FlutterWebView.this.webView, request); + if (isSecure(url) && !flutterWebViewClient.shouldOverrideUrlLoading(FlutterWebView.this.webView, request)) { + webView.loadUrl(url); } return true; } @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { - if (isSecure(url)) { - flutterWebViewClient.shouldOverrideUrlLoading(FlutterWebView.this.webView, url); + if (isSecure(url) && !flutterWebViewClient.shouldOverrideUrlLoading(FlutterWebView.this.webView, url)) { + webView.loadUrl(url); } return true; } From ef55f0849ffcc8b963d3c302837c8ce843f4a8b6 Mon Sep 17 00:00:00 2001 From: Maurice Parrish Date: Fri, 4 Sep 2020 09:30:42 -0700 Subject: [PATCH 08/19] formatting --- .../plugins/webviewflutter/FlutterWebView.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java index 233b98c2c624..c021ec025131 100644 --- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java +++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java @@ -43,9 +43,12 @@ public boolean onCreateWindow( new WebViewClient() { @TargetApi(Build.VERSION_CODES.LOLLIPOP) @Override - public boolean shouldOverrideUrlLoading(@NonNull WebView view, @NonNull WebResourceRequest request) { + public boolean shouldOverrideUrlLoading( + @NonNull WebView view, @NonNull WebResourceRequest request) { final String url = request.getUrl().toString(); - if (isSecure(url) && !flutterWebViewClient.shouldOverrideUrlLoading(FlutterWebView.this.webView, request)) { + if (isSecure(url) + && !flutterWebViewClient.shouldOverrideUrlLoading( + FlutterWebView.this.webView, request)) { webView.loadUrl(url); } return true; @@ -53,7 +56,9 @@ public boolean shouldOverrideUrlLoading(@NonNull WebView view, @NonNull WebResou @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { - if (isSecure(url) && !flutterWebViewClient.shouldOverrideUrlLoading(FlutterWebView.this.webView, url)) { + if (isSecure(url) + && !flutterWebViewClient.shouldOverrideUrlLoading( + FlutterWebView.this.webView, url)) { webView.loadUrl(url); } return true; From 9bd470a5d841129e9aaf95fd94a62dc2041faba5 Mon Sep 17 00:00:00 2001 From: Maurice Parrish Date: Fri, 4 Sep 2020 21:11:29 -0700 Subject: [PATCH 09/19] test for window open --- .../test_driver/webview_flutter_e2e.dart | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart b/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart index 162ca2cdcd9a..79b709e1e4a6 100644 --- a/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart +++ b/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart @@ -828,6 +828,36 @@ void main() { final String currentUrl = await controller.currentUrl(); expect(currentUrl, 'about:blank'); }); + + testWidgets('can open new window and go back', (WidgetTester tester) async { + final Completer controllerCompleter = + Completer(); + final Completer pageLoaded = Completer(); + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: WebView( + key: GlobalKey(), + onWebViewCreated: (WebViewController controller) { + controllerCompleter.complete(controller); + }, + javascriptMode: JavascriptMode.unrestricted, + onPageFinished: (String url) { + pageLoaded.complete(); + }, + initialUrl: 'https://flutter.dev', + ), + ), + ); + final WebViewController controller = await controllerCompleter.future; + await controller + .evaluateJavascript('window.open("https://www.google.com")'); + await pageLoaded.future; + expect(controller.currentUrl(), completion('https://www.google.com/')); + + await controller.goBack(); + expect(controller.currentUrl(), completion('https://www.flutter.dev')); + }); } // JavaScript booleans evaluate to different string values on Android and iOS. From 833bb0afd96a44a3a075e273ca1295201c1448e3 Mon Sep 17 00:00:00 2001 From: Maurice Parrish Date: Tue, 8 Sep 2020 11:46:22 -0700 Subject: [PATCH 10/19] Add test to check for http/https --- .../test_driver/webview_flutter_e2e.dart | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart b/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart index 79b709e1e4a6..b4fb1f47bc43 100644 --- a/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart +++ b/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart @@ -858,6 +858,27 @@ void main() { await controller.goBack(); expect(controller.currentUrl(), completion('https://www.flutter.dev')); }); + + testWidgets('only open window for http/https', (WidgetTester tester) async { + final Completer controllerCompleter = + Completer(); + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: WebView( + key: GlobalKey(), + onWebViewCreated: (WebViewController controller) { + controllerCompleter.complete(controller); + }, + javascriptMode: JavascriptMode.unrestricted, + initialUrl: 'https://flutter.dev', + ), + ), + ); + final WebViewController controller = await controllerCompleter.future; + await controller.evaluateJavascript('window.open("go.com")'); + expect(controller.currentUrl(), completion('https://www.flutter.dev/')); + }, skip: !Platform.isAndroid); } // JavaScript booleans evaluate to different string values on Android and iOS. From dde8c7f7fe5c0189220427d5c967df455547b7ed Mon Sep 17 00:00:00 2001 From: Maurice Parrish Date: Wed, 9 Sep 2020 14:12:07 -0700 Subject: [PATCH 11/19] dont filter url and set test to only run on android --- .../plugins/urllauncher/WebViewActivity.java | 13 +-- .../webviewflutter/FlutterWebView.java | 14 +--- .../test_driver/webview_flutter_e2e.dart | 79 ++++++++----------- 3 files changed, 37 insertions(+), 69 deletions(-) diff --git a/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java b/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java index 321f7bfa325f..9fdc2caedff2 100644 --- a/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java +++ b/packages/url_launcher/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java @@ -75,18 +75,13 @@ public boolean onCreateWindow( @Override public boolean shouldOverrideUrlLoading( @NonNull WebView view, @NonNull WebResourceRequest request) { - final String url = request.getUrl().toString(); - if (isSecure(url)) { - webview.loadUrl(url); - } + webview.loadUrl(request.getUrl().toString()); return true; } @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { - if (isSecure(url)) { - webview.loadUrl(url); - } + webview.loadUrl(url); return true; } }; @@ -100,10 +95,6 @@ public boolean shouldOverrideUrlLoading(WebView view, String url) { return true; } - - private boolean isSecure(String url) { - return url.startsWith("https://") || url.startsWith("http://"); - } } @Override diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java index c021ec025131..9bec8fa0ef13 100644 --- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java +++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java @@ -46,9 +46,8 @@ public boolean onCreateWindow( public boolean shouldOverrideUrlLoading( @NonNull WebView view, @NonNull WebResourceRequest request) { final String url = request.getUrl().toString(); - if (isSecure(url) - && !flutterWebViewClient.shouldOverrideUrlLoading( - FlutterWebView.this.webView, request)) { + if (!flutterWebViewClient.shouldOverrideUrlLoading( + FlutterWebView.this.webView, request)) { webView.loadUrl(url); } return true; @@ -56,9 +55,8 @@ public boolean shouldOverrideUrlLoading( @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { - if (isSecure(url) - && !flutterWebViewClient.shouldOverrideUrlLoading( - FlutterWebView.this.webView, url)) { + if (!flutterWebViewClient.shouldOverrideUrlLoading( + FlutterWebView.this.webView, url)) { webView.loadUrl(url); } return true; @@ -74,10 +72,6 @@ public boolean shouldOverrideUrlLoading(WebView view, String url) { return true; } - - private boolean isSecure(String url) { - return url.startsWith("https://") || url.startsWith("http://"); - } } @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) diff --git a/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart b/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart index b4fb1f47bc43..f110aaa91f7d 100644 --- a/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart +++ b/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart @@ -829,56 +829,39 @@ void main() { expect(currentUrl, 'about:blank'); }); - testWidgets('can open new window and go back', (WidgetTester tester) async { - final Completer controllerCompleter = - Completer(); - final Completer pageLoaded = Completer(); - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: WebView( - key: GlobalKey(), - onWebViewCreated: (WebViewController controller) { - controllerCompleter.complete(controller); - }, - javascriptMode: JavascriptMode.unrestricted, - onPageFinished: (String url) { - pageLoaded.complete(); - }, - initialUrl: 'https://flutter.dev', + testWidgets( + 'can open new window and go back', + (WidgetTester tester) async { + final Completer controllerCompleter = + Completer(); + final Completer pageLoaded = Completer(); + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: WebView( + key: GlobalKey(), + onWebViewCreated: (WebViewController controller) { + controllerCompleter.complete(controller); + }, + javascriptMode: JavascriptMode.unrestricted, + onPageFinished: (String url) { + pageLoaded.complete(); + }, + initialUrl: 'https://flutter.dev', + ), ), - ), - ); - final WebViewController controller = await controllerCompleter.future; - await controller - .evaluateJavascript('window.open("https://www.google.com")'); - await pageLoaded.future; - expect(controller.currentUrl(), completion('https://www.google.com/')); - - await controller.goBack(); - expect(controller.currentUrl(), completion('https://www.flutter.dev')); - }); + ); + final WebViewController controller = await controllerCompleter.future; + await controller + .evaluateJavascript('window.open("https://www.google.com")'); + await pageLoaded.future; + expect(controller.currentUrl(), completion('https://www.google.com/')); - testWidgets('only open window for http/https', (WidgetTester tester) async { - final Completer controllerCompleter = - Completer(); - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: WebView( - key: GlobalKey(), - onWebViewCreated: (WebViewController controller) { - controllerCompleter.complete(controller); - }, - javascriptMode: JavascriptMode.unrestricted, - initialUrl: 'https://flutter.dev', - ), - ), - ); - final WebViewController controller = await controllerCompleter.future; - await controller.evaluateJavascript('window.open("go.com")'); - expect(controller.currentUrl(), completion('https://www.flutter.dev/')); - }, skip: !Platform.isAndroid); + await controller.goBack(); + expect(controller.currentUrl(), completion('https://www.flutter.dev')); + }, + skip: !Platform.isAndroid, + ); } // JavaScript booleans evaluate to different string values on Android and iOS. From c5bf9d1ce3fb067cde883d05f01f3fac1e48fa15 Mon Sep 17 00:00:00 2001 From: Maurice Parrish Date: Wed, 9 Sep 2020 17:34:35 -0700 Subject: [PATCH 12/19] version bump --- packages/url_launcher/url_launcher/CHANGELOG.md | 4 ++++ packages/url_launcher/url_launcher/pubspec.yaml | 2 +- packages/webview_flutter/CHANGELOG.md | 4 ++++ packages/webview_flutter/pubspec.yaml | 2 +- 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/url_launcher/url_launcher/CHANGELOG.md b/packages/url_launcher/url_launcher/CHANGELOG.md index e7e31acfd968..861321c16f3d 100644 --- a/packages/url_launcher/url_launcher/CHANGELOG.md +++ b/packages/url_launcher/url_launcher/CHANGELOG.md @@ -1,3 +1,7 @@ +## 5.5.4 + +* Handle WebView multi-window support. + ## 5.5.3 * Suppress deprecation warning on the `shouldOverrideUrlLoading` method on Android. diff --git a/packages/url_launcher/url_launcher/pubspec.yaml b/packages/url_launcher/url_launcher/pubspec.yaml index 57048a2b3f98..be3185237fd9 100644 --- a/packages/url_launcher/url_launcher/pubspec.yaml +++ b/packages/url_launcher/url_launcher/pubspec.yaml @@ -2,7 +2,7 @@ name: url_launcher description: Flutter plugin for launching a URL on Android and iOS. Supports web, phone, SMS, and email schemes. homepage: https://github.com/flutter/plugins/tree/master/packages/url_launcher/url_launcher -version: 5.5.3 +version: 5.5.4 flutter: plugin: diff --git a/packages/webview_flutter/CHANGELOG.md b/packages/webview_flutter/CHANGELOG.md index baa485ba5b17..e1f4c3c2d1c8 100644 --- a/packages/webview_flutter/CHANGELOG.md +++ b/packages/webview_flutter/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.23 + +* Handle WebView multi-window support. + ## 0.3.22+2 * Update package:e2e reference to use the local version in the flutter/plugins diff --git a/packages/webview_flutter/pubspec.yaml b/packages/webview_flutter/pubspec.yaml index ec811833c9b8..8a4a62ea76a6 100644 --- a/packages/webview_flutter/pubspec.yaml +++ b/packages/webview_flutter/pubspec.yaml @@ -1,6 +1,6 @@ name: webview_flutter description: A Flutter plugin that provides a WebView widget on Android and iOS. -version: 0.3.22+2 +version: 0.3.23 homepage: https://github.com/flutter/plugins/tree/master/packages/webview_flutter environment: From 380c7dd907cac8a2e95a15997793ee72f138a4ec Mon Sep 17 00:00:00 2001 From: Maurice Parrish Date: Fri, 11 Sep 2020 13:03:47 -0700 Subject: [PATCH 13/19] javascript test --- .../test_driver/webview_flutter_e2e.dart | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart b/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart index f110aaa91f7d..0b8dc699a46b 100644 --- a/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart +++ b/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart @@ -862,6 +862,50 @@ void main() { }, skip: !Platform.isAndroid, ); + + testWidgets( + 'javascript does not run in parent window', + (WidgetTester tester) async { + final String openWindowTest = ''' + + Resize test + + + + + + '''; + final String openWindowTestBase64 = + base64Encode(const Utf8Encoder().convert(openWindowTest)); + final Completer controllerCompleter = + Completer(); + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: WebView( + key: GlobalKey(), + onWebViewCreated: (WebViewController controller) { + controllerCompleter.complete(controller); + }, + javascriptMode: JavascriptMode.unrestricted, + initialUrl: + 'data:text/html;charset=utf-8;base64,$openWindowTestBase64', + ), + ), + ); + + final WebViewController controller = await controllerCompleter.future; + final String result = await controller.evaluateJavascript( + 'document.querySelector("p") && document.querySelector("p").textContent'); + print(result); + }, + skip: !Platform.isAndroid, + ); } // JavaScript booleans evaluate to different string values on Android and iOS. From 9bfc1d227d6bd23c32ef9a30c623634b0d6d4e38 Mon Sep 17 00:00:00 2001 From: Maurice Parrish Date: Fri, 11 Sep 2020 18:55:48 -0700 Subject: [PATCH 14/19] Add iframe --- .../example/test_driver/webview_flutter_e2e.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart b/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart index 0b8dc699a46b..e55a77918c5e 100644 --- a/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart +++ b/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart @@ -894,7 +894,7 @@ void main() { }, javascriptMode: JavascriptMode.unrestricted, initialUrl: - 'data:text/html;charset=utf-8;base64,$openWindowTestBase64', + '', + ' '''; @@ -888,6 +889,7 @@ void main() { base64Encode(const Utf8Encoder().convert(openWindowTest)); final Completer controllerCompleter = Completer(); + final Completer pageLoadCompleter = Completer(); await tester.pumpWidget( Directionality( @@ -899,16 +901,23 @@ void main() { }, javascriptMode: JavascriptMode.unrestricted, initialUrl: - ' + + ''';