Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Fixes iframe navigation being handled in the main frame when `Navigat…
…ionDelegate.onNavigationRequest` is present.
  • Loading branch information
petermnt committed Mar 27, 2024
commit cf619d047f9a80b44b09867433df9eca7a32b9e3
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 3.16.1

* Fixes iframe navigation being handled in the main frame when `NavigationDelegate.onNavigationRequest` is present.

## 3.16.0

* Adds onReceivedHttpError WebViewClient callback to support
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,13 @@ public void onReceivedError(
public boolean shouldOverrideUrlLoading(
@NonNull WebView view, @NonNull WebResourceRequest request) {
flutterApi.requestLoading(this, view, request, reply -> {});
return returnValueForShouldOverrideUrlLoading;

// Since we cannot call loadUrl for a subframe, we currently only allow the delegate to stop
// navigations that target the main frame, if the request is not for the main frame
// we just return false to allow the navigation.
//
// For more details see: https://github.com/flutter/flutter/issues/25329#issuecomment-464863209
return request.isForMainFrame() && returnValueForShouldOverrideUrlLoading;
}

// Legacy codepath for < 24; newer versions use the variant above.
Expand Down Expand Up @@ -187,7 +193,13 @@ public void onReceivedError(
public boolean shouldOverrideUrlLoading(
@NonNull WebView view, @NonNull WebResourceRequest request) {
flutterApi.requestLoading(this, view, request, reply -> {});
return returnValueForShouldOverrideUrlLoading;

// Since we cannot call loadUrl for a subframe, we currently only allow the delegate to stop
// navigations that target the main frame, if the request is not for the main frame
// we just return false to allow the navigation.
//
// For more details see: https://github.com/flutter/flutter/issues/25329#issuecomment-464863209
return request.isForMainFrame() && returnValueForShouldOverrideUrlLoading;
}

// Legacy codepath for < Lollipop; newer versions use the variant above.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// 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.

package io.flutter.plugins.webviewflutter;

import android.webkit.WebViewClient;

public class WebViewClientCompatImplTest extends WebViewClientTest {

@Override
WebViewClient createInstance(WebViewClientFlutterApiImpl flutterApi) {
return new WebViewClientHostApiImpl.WebViewClientCompatImpl(flutterApi);
}

@Override
void setReturnValueForShouldOverrideUrlLoading(WebViewClient client, boolean value) {
((WebViewClientHostApiImpl.WebViewClientCompatImpl) client)
.setReturnValueForShouldOverrideUrlLoading(value);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// 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.

package io.flutter.plugins.webviewflutter;

import android.webkit.WebViewClient;

public class WebViewClientImplTest extends WebViewClientTest {

@Override
WebViewClient createInstance(WebViewClientFlutterApiImpl flutterApi) {
return new WebViewClientHostApiImpl.WebViewClientImpl(flutterApi);
}

@Override
void setReturnValueForShouldOverrideUrlLoading(WebViewClient client, boolean value) {
((WebViewClientHostApiImpl.WebViewClientImpl) client)
.setReturnValueForShouldOverrideUrlLoading(value);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
package io.flutter.plugins.webviewflutter;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
Expand All @@ -28,7 +30,7 @@
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;

public class WebViewClientTest {
public abstract class WebViewClientTest {
@Rule public MockitoRule mockitoRule = MockitoJUnit.rule();

@Mock public WebViewClientFlutterApiImpl mockFlutterApi;
Expand All @@ -39,7 +41,11 @@ public class WebViewClientTest {

InstanceManager instanceManager;
WebViewClientHostApiImpl hostApiImpl;
WebViewClientCompatImpl webViewClient;
WebViewClient webViewClient;

abstract WebViewClient createInstance(WebViewClientFlutterApiImpl flutterApi);

abstract void setReturnValueForShouldOverrideUrlLoading(WebViewClient client, boolean value);

@Before
public void setUp() {
Expand All @@ -51,7 +57,7 @@ public void setUp() {
@NonNull
public WebViewClient createWebViewClient(
@NonNull WebViewClientFlutterApiImpl flutterApi) {
webViewClient = (WebViewClientCompatImpl) super.createWebViewClient(flutterApi);
webViewClient = createInstance(flutterApi);
return webViewClient;
}
};
Expand All @@ -74,6 +80,7 @@ public void onPageStarted() {
}

@Test
@SuppressWarnings("deprecation")
public void onReceivedError() {
webViewClient.onReceivedError(mockWebView, 32, "description", "https://www.google.com");
verify(mockFlutterApi)
Expand All @@ -87,12 +94,61 @@ public void onReceivedError() {
}

@Test
@SuppressWarnings("deprecation")
public void urlLoading() {
webViewClient.shouldOverrideUrlLoading(mockWebView, "https://www.google.com");
verify(mockFlutterApi)
.urlLoading(eq(webViewClient), eq(mockWebView), eq("https://www.google.com"), any());
}

@Test
public void urlLoadingForMainFrame() {
setReturnValueForShouldOverrideUrlLoading(webViewClient, false);

final WebResourceRequest mockRequest = mock(WebResourceRequest.class);
when(mockRequest.isForMainFrame()).thenReturn(true);

assertFalse(webViewClient.shouldOverrideUrlLoading(mockWebView, mockRequest));
verify(mockFlutterApi)
.requestLoading(eq(webViewClient), eq(mockWebView), eq(mockRequest), any());
}

@Test
public void urlLoadingForMainFrameWithOverride() {
setReturnValueForShouldOverrideUrlLoading(webViewClient, true);

final WebResourceRequest mockRequest = mock(WebResourceRequest.class);
when(mockRequest.isForMainFrame()).thenReturn(true);

assertTrue(webViewClient.shouldOverrideUrlLoading(mockWebView, mockRequest));
verify(mockFlutterApi)
.requestLoading(eq(webViewClient), eq(mockWebView), eq(mockRequest), any());
}

@Test
public void urlLoadingNotForMainFrame() {
setReturnValueForShouldOverrideUrlLoading(webViewClient, false);

final WebResourceRequest mockRequest = mock(WebResourceRequest.class);
when(mockRequest.isForMainFrame()).thenReturn(false);

assertFalse(webViewClient.shouldOverrideUrlLoading(mockWebView, mockRequest));
verify(mockFlutterApi)
.requestLoading(eq(webViewClient), eq(mockWebView), eq(mockRequest), any());
}

@Test
public void urlLoadingNotForMainFrameWithOverride() {
setReturnValueForShouldOverrideUrlLoading(webViewClient, true);

final WebResourceRequest mockRequest = mock(WebResourceRequest.class);
when(mockRequest.isForMainFrame()).thenReturn(false);

assertFalse(webViewClient.shouldOverrideUrlLoading(mockWebView, mockRequest));
verify(mockFlutterApi)
.requestLoading(eq(webViewClient), eq(mockWebView), eq(mockRequest), any());
}

@Test
public void convertWebResourceRequestWithNullHeaders() {
final Uri mockUri = mock(Uri.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ const String kNavigationExamplePage = '''
<head><title>Navigation Delegate Example</title></head>
<body>
<p>
The navigation delegate is set to block navigation to the youtube website.
The navigation delegate is set to block navigation to the pub.dev website.
</p>
<ul>
<ul><a href="https://www.youtube.com/">https://www.youtube.com/</a></ul>
<ul><a href="https://pub.dev/">https://pub.dev/</a></ul>
<ul><a href="https://www.google.com/">https://www.google.com/</a></ul>
</ul>
</body>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: webview_flutter_android
description: A Flutter plugin that provides a WebView widget on Android.
repository: https://github.com/flutter/packages/tree/main/packages/webview_flutter/webview_flutter_android
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+webview%22
version: 3.16.0
version: 3.16.1

environment:
sdk: ^3.1.0
Expand Down