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
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## NEXT
## 3.5.0

* Adds support for `PlatformNavigationDelegate.onUrlChange`.
* Bumps androidx.webkit:webkit from 1.6.0 to 1.6.1.

## 3.4.5
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,21 @@ public void urlLoading(
urlLoading(getIdentifierForClient(webViewClient), webViewIdentifier, urlArg, callback);
}

/** Passes arguments from {@link WebViewClient#doUpdateVisitedHistory} to Dart. */
public void doUpdateVisitedHistory(
WebViewClient webViewClient,
WebView webView,
String url,
boolean isReload,
Reply<Void> callback) {
webViewFlutterApi.create(webView, reply -> {});

final Long webViewIdentifier =
Objects.requireNonNull(instanceManager.getIdentifierForStrongReference(webView));
doUpdateVisitedHistory(
getIdentifierForClient(webViewClient), webViewIdentifier, url, isReload, callback);
}

private long getIdentifierForClient(WebViewClient webViewClient) {
final Long identifier = instanceManager.getIdentifierForStrongReference(webViewClient);
if (identifier == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ public boolean shouldOverrideUrlLoading(WebView view, String url) {
return returnValueForShouldOverrideUrlLoading;
}

@Override
public void doUpdateVisitedHistory(WebView view, String url, boolean isReload) {
flutterApi.doUpdateVisitedHistory(this, view, url, isReload, reply -> {});
}

@Override
public void onUnhandledKeyEvent(WebView view, KeyEvent event) {
// Deliberately empty. Occasionally the webview will mark events as having failed to be
Expand Down Expand Up @@ -154,6 +159,11 @@ public boolean shouldOverrideUrlLoading(WebView view, String url) {
return returnValueForShouldOverrideUrlLoading;
}

@Override
public void doUpdateVisitedHistory(WebView view, String url, boolean isReload) {
flutterApi.doUpdateVisitedHistory(this, view, url, isReload, reply -> {});
}

@Override
public void onUnhandledKeyEvent(WebView view, KeyEvent event) {
// Deliberately empty. Occasionally the webview will mark events as having failed to be
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,4 +123,12 @@ public WebViewClient createWebViewClient(WebViewClientFlutterApiImpl flutterApi)

verify(mockWebViewClient).setReturnValueForShouldOverrideUrlLoading(false);
}

@Test
public void doUpdateVisitedHistory() {
webViewClient.doUpdateVisitedHistory(mockWebView, "https://www.google.com", true);
verify(mockFlutterApi)
.doUpdateVisitedHistory(
eq(webViewClient), eq(mockWebView), eq("https://www.google.com"), eq(true), any());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -942,6 +942,81 @@ Future<void> main() async {
final String? currentUrl = await controller.currentUrl();
expect(currentUrl, secondaryUrl);
});

testWidgets('can receive url changes', (WidgetTester tester) async {
final Completer<void> pageLoaded = Completer<void>();

final PlatformNavigationDelegate navigationDelegate =
PlatformNavigationDelegate(
const PlatformNavigationDelegateCreationParams(),
)..setOnPageFinished((_) => pageLoaded.complete());

final PlatformWebViewController controller = PlatformWebViewController(
const PlatformWebViewControllerCreationParams(),
)
..setJavaScriptMode(JavaScriptMode.unrestricted)
..setPlatformNavigationDelegate(navigationDelegate)
..loadRequest(LoadRequestParams(uri: Uri.parse(blankPageEncoded)));

await tester.pumpWidget(Builder(
builder: (BuildContext context) {
return PlatformWebViewWidget(
PlatformWebViewWidgetCreationParams(controller: controller),
).build(context);
},
));

await pageLoaded.future;
await navigationDelegate.setOnPageFinished((_) {});

final Completer<String> urlChangeCompleter = Completer<String>();
await navigationDelegate.setOnUrlChange((UrlChange change) {
urlChangeCompleter.complete(change.url);
});

await controller.runJavaScript('location.href = "$primaryUrl"');

await expectLater(urlChangeCompleter.future, completion(primaryUrl));
});

testWidgets('can receive updates to history state',
(WidgetTester tester) async {
final Completer<void> pageLoaded = Completer<void>();

final PlatformNavigationDelegate navigationDelegate =
PlatformNavigationDelegate(
const PlatformNavigationDelegateCreationParams(),
)..setOnPageFinished((_) => pageLoaded.complete());

final PlatformWebViewController controller = PlatformWebViewController(
const PlatformWebViewControllerCreationParams(),
)
..setJavaScriptMode(JavaScriptMode.unrestricted)
..setPlatformNavigationDelegate(navigationDelegate)
..loadRequest(LoadRequestParams(uri: Uri.parse(primaryUrl)));

await tester.pumpWidget(Builder(
builder: (BuildContext context) {
return PlatformWebViewWidget(
PlatformWebViewWidgetCreationParams(controller: controller),
).build(context);
},
));

await pageLoaded.future;
await navigationDelegate.setOnPageFinished((_) {});

final Completer<String> urlChangeCompleter = Completer<String>();
await navigationDelegate.setOnUrlChange((UrlChange change) {
urlChangeCompleter.complete(change.url);
});

await controller.runJavaScript(
'window.history.pushState({}, "", "secondary.txt");',
);

await expectLater(urlChangeCompleter.future, completion(secondaryUrl));
});
});

testWidgets('target _blank opens in same window',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@ Page resource error:
}
debugPrint('allowing navigation to ${request.url}');
return NavigationDecision.navigate;
})
..setOnUrlChange((UrlChange change) {
debugPrint('url change to ${change.url}');
}),
)
..addJavaScriptChannel(JavaScriptChannelParams(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ dependencies:
# The example app is bundled with the plugin so we use a path dependency on
# the parent directory to use the current plugin's version.
path: ../
webview_flutter_platform_interface: ^2.0.0
webview_flutter_platform_interface: ^2.1.0

dev_dependencies:
espresso: ^0.2.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ class AndroidWebViewProxy {
android_webview.WebResourceRequest request,
)? requestLoading,
void Function(android_webview.WebView webView, String url)? urlLoading,
void Function(android_webview.WebView webView, String url, bool isReload)?
doUpdateVisitedHistory,
}) createAndroidWebViewClient;

/// Constructs a [android_webview.FlutterAssetManager].
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -677,6 +677,7 @@ class WebViewClient extends JavaObject {
@Deprecated('Only called on Android version < 23.') this.onReceivedError,
this.requestLoading,
this.urlLoading,
this.doUpdateVisitedHistory,
@visibleForTesting super.binaryMessenger,
@visibleForTesting super.instanceManager,
}) : super.detached() {
Expand All @@ -696,6 +697,7 @@ class WebViewClient extends JavaObject {
@Deprecated('Only called on Android version < 23.') this.onReceivedError,
this.requestLoading,
this.urlLoading,
this.doUpdateVisitedHistory,
super.binaryMessenger,
super.instanceManager,
}) : super.detached();
Expand Down Expand Up @@ -840,6 +842,10 @@ class WebViewClient extends JavaObject {
/// indicates whether the [WebView] loaded the URL.
final void Function(WebView webView, String url)? urlLoading;

/// Notify the host application to update its visited links database.
final void Function(WebView webView, String url, bool isReload)?
doUpdateVisitedHistory;

/// Sets the required synchronous return value for the Java method,
/// `WebViewClient.shouldOverrideUrlLoading(...)`.
///
Expand Down Expand Up @@ -867,6 +873,7 @@ class WebViewClient extends JavaObject {
onReceivedError: onReceivedError,
requestLoading: requestLoading,
urlLoading: urlLoading,
doUpdateVisitedHistory: doUpdateVisitedHistory,
binaryMessenger: _api.binaryMessenger,
instanceManager: _api.instanceManager,
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// 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.
// Autogenerated from Pigeon (v9.0.5), do not edit directly.
// Autogenerated from Pigeon (v9.2.3), do not edit directly.
// See also: https://pub.dev/packages/pigeon
// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import

Expand Down Expand Up @@ -1514,6 +1514,9 @@ abstract class WebViewClientFlutterApi {

void urlLoading(int instanceId, int webViewInstanceId, String url);

void doUpdateVisitedHistory(
int instanceId, int webViewInstanceId, String url, bool isReload);

static void setup(WebViewClientFlutterApi? api,
{BinaryMessenger? binaryMessenger}) {
{
Expand Down Expand Up @@ -1682,6 +1685,36 @@ abstract class WebViewClientFlutterApi {
});
}
}
{
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.WebViewClientFlutterApi.doUpdateVisitedHistory',
codec,
binaryMessenger: binaryMessenger);
if (api == null) {
channel.setMessageHandler(null);
} else {
channel.setMessageHandler((Object? message) async {
assert(message != null,
'Argument for dev.flutter.pigeon.WebViewClientFlutterApi.doUpdateVisitedHistory was null.');
final List<Object?> args = (message as List<Object?>?)!;
final int? arg_instanceId = (args[0] as int?);
assert(arg_instanceId != null,
'Argument for dev.flutter.pigeon.WebViewClientFlutterApi.doUpdateVisitedHistory was null, expected non-null int.');
final int? arg_webViewInstanceId = (args[1] as int?);
assert(arg_webViewInstanceId != null,
'Argument for dev.flutter.pigeon.WebViewClientFlutterApi.doUpdateVisitedHistory was null, expected non-null int.');
final String? arg_url = (args[2] as String?);
assert(arg_url != null,
'Argument for dev.flutter.pigeon.WebViewClientFlutterApi.doUpdateVisitedHistory was null, expected non-null String.');
final bool? arg_isReload = (args[3] as bool?);
assert(arg_isReload != null,
'Argument for dev.flutter.pigeon.WebViewClientFlutterApi.doUpdateVisitedHistory was null, expected non-null bool.');
api.doUpdateVisitedHistory(
arg_instanceId!, arg_webViewInstanceId!, arg_url!, arg_isReload!);
return;
});
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -754,6 +754,30 @@ class WebViewClientFlutterApiImpl extends WebViewClientFlutterApi {
instance.urlLoading!(webViewInstance!, url);
}
}

@override
void doUpdateVisitedHistory(
int instanceId,
int webViewInstanceId,
String url,
bool isReload,
) {
final WebViewClient? instance = instanceManager
.getInstanceWithWeakReference(instanceId) as WebViewClient?;
final WebView? webViewInstance = instanceManager
.getInstanceWithWeakReference(webViewInstanceId) as WebView?;
assert(
instance != null,
'InstanceManager does not contain an WebViewClient with instanceId: $instanceId',
);
assert(
webViewInstance != null,
'InstanceManager does not contain an WebView with instanceId: $webViewInstanceId',
);
if (instance!.doUpdateVisitedHistory != null) {
instance.doUpdateVisitedHistory!(webViewInstance!, url, isReload);
}
}
}

/// Host api implementation for [DownloadListener].
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -704,6 +704,15 @@ class AndroidNavigationDelegateCreationParams
final AndroidWebViewProxy androidWebViewProxy;
}

/// Android details of the change to a web view's url.
class AndroidUrlChange extends UrlChange {
/// Constructs an [AndroidUrlChange].
const AndroidUrlChange({required super.url, required this.isReload});

/// Whether the url is being reloaded.
final bool isReload;
}

/// A place to register callback methods responsible to handle navigation events
/// triggered by the [android_webview.WebView].
class AndroidNavigationDelegate extends PlatformNavigationDelegate {
Expand Down Expand Up @@ -778,6 +787,18 @@ class AndroidNavigationDelegate extends PlatformNavigationDelegate {
weakThis.target!._handleNavigation(url, isForMainFrame: true);
}
},
doUpdateVisitedHistory: (
android_webview.WebView webView,
String url,
bool isReload,
) {
if (weakThis.target?._onUrlChange != null) {
weakThis.target!._onUrlChange!(AndroidUrlChange(
Comment thread
bparrishMines marked this conversation as resolved.
Outdated
url: url,
isReload: isReload,
));
}
},
);

_downloadListener = (this.params as AndroidNavigationDelegateCreationParams)
Expand Down Expand Up @@ -833,6 +854,7 @@ class AndroidNavigationDelegate extends PlatformNavigationDelegate {
WebResourceErrorCallback? _onWebResourceError;
NavigationRequestCallback? _onNavigationRequest;
LoadRequestCallback? _onLoadRequest;
UrlChangeCallback? _onUrlChange;

void _handleNavigation(
String url, {
Expand Down Expand Up @@ -913,4 +935,9 @@ class AndroidNavigationDelegate extends PlatformNavigationDelegate {
) async {
_onWebResourceError = onWebResourceError;
}

@override
Future<void> setOnUrlChange(UrlChangeCallback onUrlChange) async {
_onUrlChange = onUrlChange;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,13 @@ abstract class WebViewClientFlutterApi {
);

void urlLoading(int instanceId, int webViewInstanceId, String url);

void doUpdateVisitedHistory(
int instanceId,
int webViewInstanceId,
String url,
bool isReload,
);
}

@HostApi(dartHostTestHandler: 'TestDownloadListenerHostApi')
Expand Down
4 changes: 2 additions & 2 deletions packages/webview_flutter/webview_flutter_android/pubspec.yaml
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.4.5
version: 3.5.0

environment:
sdk: ">=2.18.0 <4.0.0"
Expand All @@ -20,7 +20,7 @@ flutter:
dependencies:
flutter:
sdk: flutter
webview_flutter_platform_interface: ^2.0.0
webview_flutter_platform_interface: ^2.1.0

dev_dependencies:
build_runner: ^2.1.4
Expand Down
Loading