Move clearCookies behind the platform abstraction (#1663)
This is a followup for #1618, #1624, and #1645, and moves the plugins.flutter.io/cookie_manager method channel behind the platform interface which allows a third party package to provide a new platform implementation the cooke manager.
See the description for #1618 for more details.
Following this PR all platform specific code can be replaced by an external package.
diff --git a/packages/webview_flutter/CHANGELOG.md b/packages/webview_flutter/CHANGELOG.md
index 306181c..4ba6202 100644
--- a/packages/webview_flutter/CHANGELOG.md
+++ b/packages/webview_flutter/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.3.9
+
+* Allow external packages to provide webview implementations for new platforms.
+
## 0.3.8+1
* Suppress deprecation warning for BinaryMessages. See: https://github.com/flutter/flutter/issues/33446
diff --git a/packages/webview_flutter/lib/platform_interface.dart b/packages/webview_flutter/lib/platform_interface.dart
index 5d8899a..bfb5b62 100644
--- a/packages/webview_flutter/lib/platform_interface.dart
+++ b/packages/webview_flutter/lib/platform_interface.dart
@@ -10,20 +10,20 @@
import 'webview_flutter.dart';
-/// Interface for callbacks made by [WebViewPlatform].
+/// Interface for callbacks made by [WebViewPlatformController].
///
-/// The webview plugin implements this class, and passes an instance to the [WebViewPlatform].
-/// [WebViewPlatform] is notifying this handler on events that happened on the platform's webview.
+/// The webview plugin implements this class, and passes an instance to the [WebViewPlatformController].
+/// [WebViewPlatformController] is notifying this handler on events that happened on the platform's webview.
abstract class WebViewPlatformCallbacksHandler {
- /// Invoked by [WebViewPlatform] when a JavaScript channel message is received.
+ /// Invoked by [WebViewPlatformController] when a JavaScript channel message is received.
void onJavaScriptChannelMessage(String channel, String message);
- /// Invoked by [WebViewPlatform] when a navigation request is pending.
+ /// Invoked by [WebViewPlatformController] when a navigation request is pending.
///
/// If true is returned the navigation is allowed, otherwise it is blocked.
bool onNavigationRequest({String url, bool isForMainFrame});
- /// Invoked by [WebViewPlatform] when a page has finished loading.
+ /// Invoked by [WebViewPlatformController] when a page has finished loading.
void onPageFinished(String url);
}
@@ -31,13 +31,13 @@
///
/// An instance implementing this interface is passed to the `onWebViewPlatformCreated` callback that is
/// passed to [WebViewPlatformBuilder#onWebViewPlatformCreated].
-abstract class WebViewPlatform {
+abstract class WebViewPlatformController {
/// Creates a new WebViewPlatform.
///
/// Callbacks made by the WebView will be delegated to `handler`.
///
/// The `handler` parameter must not be null.
- WebViewPlatform(WebViewPlatformCallbacksHandler handler);
+ WebViewPlatformController(WebViewPlatformCallbacksHandler handler);
/// Loads the specified URL.
///
@@ -182,7 +182,7 @@
}
}
-/// Configuration to use when creating a new [WebViewPlatform].
+/// Configuration to use when creating a new [WebViewPlatformController].
class CreationParams {
CreationParams(
{this.initialUrl, this.webSettings, this.javascriptChannelNames});
@@ -194,7 +194,7 @@
/// The initial [WebSettings] for the new webview.
///
- /// This can later be updated with [WebViewPlatform.updateSettings].
+ /// This can later be updated with [WebViewPlatformController.updateSettings].
final WebSettings webSettings;
/// The initial set of JavaScript channels that are configured for this webview.
@@ -217,14 +217,14 @@
}
typedef WebViewPlatformCreatedCallback = void Function(
- WebViewPlatform webViewPlatform);
+ WebViewPlatformController webViewPlatformController);
-/// Interface building a platform WebView implementation.
+/// Interface for a platform implementation of a WebView.
///
-/// [WebView#platformBuilder] controls the builder that is used by [WebView].
+/// [WebView.platform] controls the builder that is used by [WebView].
/// [AndroidWebViewPlatform] and [CupertinoWebViewPlatform] are the default implementations
/// for Android and iOS respectively.
-abstract class WebViewBuilder {
+abstract class WebViewPlatform {
/// Builds a new WebView.
///
/// Returns a Widget tree that embeds the created webview.
@@ -232,10 +232,10 @@
/// `creationParams` are the initial parameters used to setup the webview.
///
/// `webViewPlatformHandler` will be used for handling callbacks that are made by the created
- /// [WebViewPlatform].
+ /// [WebViewPlatformController].
///
- /// `onWebViewPlatformCreated` will be invoked after the platform specific [WebViewPlatform]
- /// implementation is created with the [WebViewPlatform] instance as a parameter.
+ /// `onWebViewPlatformCreated` will be invoked after the platform specific [WebViewPlatformController]
+ /// implementation is created with the [WebViewPlatformController] instance as a parameter.
///
/// `gestureRecognizers` specifies which gestures should be consumed by the web view.
/// It is possible for other gesture recognizers to be competing with the web view on pointer
@@ -256,4 +256,12 @@
WebViewPlatformCreatedCallback onWebViewPlatformCreated,
Set<Factory<OneSequenceGestureRecognizer>> gestureRecognizers,
});
+
+ /// Clears all cookies for all [WebView] instances.
+ ///
+ /// Returns true if cookies were present before clearing, else false.
+ Future<bool> clearCookies() {
+ throw UnimplementedError(
+ "WebView clearCookies is not implemented on the current platform");
+ }
}
diff --git a/packages/webview_flutter/lib/src/webview_android.dart b/packages/webview_flutter/lib/src/webview_android.dart
index 8d5f98a..f7afcc0 100644
--- a/packages/webview_flutter/lib/src/webview_android.dart
+++ b/packages/webview_flutter/lib/src/webview_android.dart
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+import 'dart:async';
+
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/services.dart';
@@ -12,10 +14,10 @@
/// Builds an Android webview.
///
-/// This is used as the default implementation for [WebView.platformBuilder] on Android. It uses
+/// This is used as the default implementation for [WebView.platform] on Android. It uses
/// an [AndroidView] to embed the webview in the widget hierarchy, and uses a method channel to
/// communicate with the platform code.
-class AndroidWebViewBuilder implements WebViewBuilder {
+class AndroidWebView implements WebViewPlatform {
@override
Widget build({
BuildContext context,
@@ -55,4 +57,7 @@
),
);
}
+
+ @override
+ Future<bool> clearCookies() => MethodChannelWebViewPlatform.clearCookies();
}
diff --git a/packages/webview_flutter/lib/src/webview_cupertino.dart b/packages/webview_flutter/lib/src/webview_cupertino.dart
index 04ca9d7..0e84908 100644
--- a/packages/webview_flutter/lib/src/webview_cupertino.dart
+++ b/packages/webview_flutter/lib/src/webview_cupertino.dart
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+import 'dart:async';
+
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/services.dart';
@@ -12,10 +14,10 @@
/// Builds an iOS webview.
///
-/// This is used as the default implementation for [WebView.platformBuilder] on iOS. It uses
+/// This is used as the default implementation for [WebView.platform] on iOS. It uses
/// a [UiKitView] to embed the webview in the widget hierarchy, and uses a method channel to
/// communicate with the platform code.
-class CupertinoWebViewBuilder implements WebViewBuilder {
+class CupertinoWebView implements WebViewPlatform {
@override
Widget build({
BuildContext context,
@@ -39,4 +41,7 @@
creationParamsCodec: const StandardMessageCodec(),
);
}
+
+ @override
+ Future<bool> clearCookies() => MethodChannelWebViewPlatform.clearCookies();
}
diff --git a/packages/webview_flutter/lib/src/webview_method_channel.dart b/packages/webview_flutter/lib/src/webview_method_channel.dart
index d86a8b4..91cb3b6 100644
--- a/packages/webview_flutter/lib/src/webview_method_channel.dart
+++ b/packages/webview_flutter/lib/src/webview_method_channel.dart
@@ -8,8 +8,8 @@
import '../platform_interface.dart';
-/// A [WebViewPlatform] that uses a method channel to control the webview.
-class MethodChannelWebViewPlatform implements WebViewPlatform {
+/// A [WebViewPlatformController] that uses a method channel to control the webview.
+class MethodChannelWebViewPlatform implements WebViewPlatformController {
MethodChannelWebViewPlatform(int id, this._platformCallbacksHandler)
: assert(_platformCallbacksHandler != null),
_channel = MethodChannel('plugins.flutter.io/webview_$id') {
@@ -20,6 +20,9 @@
final MethodChannel _channel;
+ static const MethodChannel _cookieManagerChannel =
+ MethodChannel('plugins.flutter.io/cookie_manager');
+
Future<bool> _onMethodCall(MethodCall call) async {
switch (call.method) {
case 'javascriptChannelMessage':
@@ -105,6 +108,16 @@
'removeJavascriptChannels', javascriptChannelNames.toList());
}
+ /// Method channel mplementation for [WebViewPlatform.clearCookies].
+ static Future<bool> clearCookies() {
+ return _cookieManagerChannel
+ // TODO(amirh): remove this when the invokeMethod update makes it to stable Flutter.
+ // https://github.com/flutter/flutter/issues/26431
+ // ignore: strong_mode_implicit_dynamic_method
+ .invokeMethod('clearCookies')
+ .then<bool>((dynamic result) => result);
+ }
+
static Map<String, dynamic> _webSettingsToMap(WebSettings settings) {
final Map<String, dynamic> map = <String, dynamic>{};
void _addIfNonNull(String key, dynamic value) {
diff --git a/packages/webview_flutter/lib/webview_flutter.dart b/packages/webview_flutter/lib/webview_flutter.dart
index dd7e920..3c0175e 100644
--- a/packages/webview_flutter/lib/webview_flutter.dart
+++ b/packages/webview_flutter/lib/webview_flutter.dart
@@ -6,7 +6,6 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
-import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'platform_interface.dart';
@@ -125,37 +124,37 @@
}) : assert(javascriptMode != null),
super(key: key);
- static WebViewBuilder _platformBuilder;
+ static WebViewPlatform _platform;
- /// Sets a custom [WebViewBuilder].
+ /// Sets a custom [WebViewPlatform].
///
/// This property can be set to use a custom platform implementation for WebViews.
///
- /// Setting `platformBuilder` doesn't affect [WebView]s that were already created.
+ /// Setting `platform` doesn't affect [WebView]s that were already created.
///
- /// The default value is [AndroidWebViewBuilder] on Android and [CupertinoWebViewBuilder] on iOs.
- static set platformBuilder(WebViewBuilder platformBuilder) {
- _platformBuilder = platformBuilder;
+ /// The default value is [AndroidWebView] on Android and [CupertinoWebView] on iOS.
+ static set platform(WebViewPlatform platform) {
+ _platform = platform;
}
- /// The [WebViewBuilder] that's used to create new [WebView]s.
+ /// The WebView platform that's used by this WebView.
///
- /// The default value is [AndroidWebViewBuilder] on Android and [CupertinoWebViewBuilder] on iOs.
- static WebViewBuilder get platformBuilder {
- if (_platformBuilder == null) {
+ /// The default value is [AndroidWebView] on Android and [CupertinoWebView] on iOS.
+ static WebViewPlatform get platform {
+ if (_platform == null) {
switch (defaultTargetPlatform) {
case TargetPlatform.android:
- _platformBuilder = AndroidWebViewBuilder();
+ _platform = AndroidWebView();
break;
case TargetPlatform.iOS:
- _platformBuilder = CupertinoWebViewBuilder();
+ _platform = CupertinoWebView();
break;
default:
throw UnsupportedError(
"Trying to use the default webview implementation for $defaultTargetPlatform but there isn't a default one");
}
}
- return _platformBuilder;
+ return _platform;
}
/// If not null invoked once the web view is created.
@@ -268,7 +267,7 @@
@override
Widget build(BuildContext context) {
- return WebView.platformBuilder.build(
+ return WebView.platform.build(
context: context,
onWebViewPlatformCreated: _onWebViewPlatformCreated,
webViewPlatformCallbacksHandler: _platformCallbacksHandler,
@@ -294,7 +293,7 @@
});
}
- void _onWebViewPlatformCreated(WebViewPlatform webViewPlatform) {
+ void _onWebViewPlatformCreated(WebViewPlatformController webViewPlatform) {
final WebViewController controller =
WebViewController._(widget, webViewPlatform, _platformCallbacksHandler);
_controller.complete(controller);
@@ -416,13 +415,13 @@
class WebViewController {
WebViewController._(
this._widget,
- this._webViewPlatform,
+ this._webViewPlatformController,
this._platformCallbacksHandler,
- ) : assert(_webViewPlatform != null) {
+ ) : assert(_webViewPlatformController != null) {
_settings = _webSettingsFromWidget(_widget);
}
- final WebViewPlatform _webViewPlatform;
+ final WebViewPlatformController _webViewPlatformController;
final _PlatformCallbacksHandler _platformCallbacksHandler;
@@ -444,7 +443,7 @@
}) async {
assert(url != null);
_validateUrlString(url);
- return _webViewPlatform.loadUrl(url, headers);
+ return _webViewPlatformController.loadUrl(url, headers);
}
/// Accessor to the current URL that the WebView is displaying.
@@ -455,7 +454,7 @@
/// words, by the time this future completes, the WebView may be displaying a
/// different URL).
Future<String> currentUrl() {
- return _webViewPlatform.currentUrl();
+ return _webViewPlatformController.currentUrl();
}
/// Checks whether there's a back history item.
@@ -463,7 +462,7 @@
/// Note that this operation is asynchronous, and it is possible that the "canGoBack" state has
/// changed by the time the future completed.
Future<bool> canGoBack() {
- return _webViewPlatform.canGoBack();
+ return _webViewPlatformController.canGoBack();
}
/// Checks whether there's a forward history item.
@@ -471,26 +470,26 @@
/// Note that this operation is asynchronous, and it is possible that the "canGoForward" state has
/// changed by the time the future completed.
Future<bool> canGoForward() {
- return _webViewPlatform.canGoForward();
+ return _webViewPlatformController.canGoForward();
}
/// Goes back in the history of this WebView.
///
/// If there is no back history item this is a no-op.
Future<void> goBack() {
- return _webViewPlatform.goBack();
+ return _webViewPlatformController.goBack();
}
/// Goes forward in the history of this WebView.
///
/// If there is no forward history item this is a no-op.
Future<void> goForward() {
- return _webViewPlatform.goForward();
+ return _webViewPlatformController.goForward();
}
/// Reloads the current URL.
Future<void> reload() {
- return _webViewPlatform.reload();
+ return _webViewPlatformController.reload();
}
/// Clears all caches used by the [WebView].
@@ -504,7 +503,7 @@
///
/// Note: Calling this method also triggers a reload.
Future<void> clearCache() async {
- await _webViewPlatform.clearCache();
+ await _webViewPlatformController.clearCache();
return reload();
}
@@ -518,7 +517,7 @@
final WebSettings update =
_clearUnchangedWebSettings(_settings, newSettings);
_settings = newSettings;
- return _webViewPlatform.updateSettings(update);
+ return _webViewPlatformController.updateSettings(update);
}
Future<void> _updateJavascriptChannels(
@@ -531,10 +530,10 @@
final Set<String> channelsToRemove =
currentChannels.difference(newChannelNames);
if (channelsToRemove.isNotEmpty) {
- _webViewPlatform.removeJavascriptChannels(channelsToRemove);
+ _webViewPlatformController.removeJavascriptChannels(channelsToRemove);
}
if (channelsToAdd.isNotEmpty) {
- _webViewPlatform.addJavascriptChannels(channelsToAdd);
+ _webViewPlatformController.addJavascriptChannels(channelsToAdd);
}
_platformCallbacksHandler._updateJavascriptChannelsFromSet(newChannels);
}
@@ -567,7 +566,7 @@
// TODO(amirh): remove this on when the invokeMethod update makes it to stable Flutter.
// https://github.com/flutter/flutter/issues/26431
// ignore: strong_mode_implicit_dynamic_method
- return _webViewPlatform.evaluateJavascript(javascriptString);
+ return _webViewPlatformController.evaluateJavascript(javascriptString);
}
}
@@ -580,21 +579,14 @@
CookieManager._();
- static const MethodChannel _channel =
- MethodChannel('plugins.flutter.io/cookie_manager');
static CookieManager _instance;
- /// Clears all cookies.
+ /// Clears all cookies for all [WebView] instances.
///
- /// This is supported for >= IOS 9.
+ /// This is a no op on iOS version smaller than 9.
///
/// Returns true if cookies were present before clearing, else false.
- Future<bool> clearCookies() => _channel
- // TODO(amirh): remove this when the invokeMethod update makes it to stable Flutter.
- // https://github.com/flutter/flutter/issues/26431
- // ignore: strong_mode_implicit_dynamic_method
- .invokeMethod('clearCookies')
- .then<bool>((dynamic result) => result);
+ Future<bool> clearCookies() => WebView.platform.clearCookies();
}
// Throws an ArgumentError if `url` is not a valid URL string.
diff --git a/packages/webview_flutter/pubspec.yaml b/packages/webview_flutter/pubspec.yaml
index da24d39..2dbabc8 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.8+1
+version: 0.3.9
author: Flutter Team <flutter-dev@googlegroups.com>
homepage: https://github.com/flutter/plugins/tree/master/packages/webview_flutter
diff --git a/packages/webview_flutter/test/webview_flutter_test.dart b/packages/webview_flutter/test/webview_flutter_test.dart
index 2a458ad..d451a86 100644
--- a/packages/webview_flutter/test/webview_flutter_test.dart
+++ b/packages/webview_flutter/test/webview_flutter_test.dart
@@ -752,10 +752,10 @@
group('Custom platform implementation', () {
setUpAll(() {
- WebView.platformBuilder = MyWebViewBuilder();
+ WebView.platform = MyWebViewPlatform();
});
tearDownAll(() {
- WebView.platformBuilder = null;
+ WebView.platform = null;
});
testWidgets('creation', (WidgetTester tester) async {
@@ -765,8 +765,8 @@
),
);
- final MyWebViewBuilder builder = WebView.platformBuilder;
- final MyWebViewPlatform platform = builder.lastPlatformBuilt;
+ final MyWebViewPlatform builder = WebView.platform;
+ final MyWebViewPlatformController platform = builder.lastPlatformBuilt;
expect(
platform.creationParams,
@@ -794,8 +794,8 @@
),
);
- final MyWebViewBuilder builder = WebView.platformBuilder;
- final MyWebViewPlatform platform = builder.lastPlatformBuilt;
+ final MyWebViewPlatform builder = WebView.platform;
+ final MyWebViewPlatformController platform = builder.lastPlatformBuilt;
final Map<String, String> headers = <String, String>{
'header': 'value',
@@ -1033,8 +1033,8 @@
}
}
-class MyWebViewBuilder implements WebViewBuilder {
- MyWebViewPlatform lastPlatformBuilt;
+class MyWebViewPlatform implements WebViewPlatform {
+ MyWebViewPlatformController lastPlatformBuilt;
@override
Widget build({
@@ -1045,15 +1045,20 @@
Set<Factory<OneSequenceGestureRecognizer>> gestureRecognizers,
}) {
assert(onWebViewPlatformCreated != null);
- lastPlatformBuilt = MyWebViewPlatform(
+ lastPlatformBuilt = MyWebViewPlatformController(
creationParams, gestureRecognizers, webViewPlatformCallbacksHandler);
onWebViewPlatformCreated(lastPlatformBuilt);
return Container();
}
+
+ @override
+ Future<bool> clearCookies() {
+ return Future<bool>.sync(() => null);
+ }
}
-class MyWebViewPlatform extends WebViewPlatform {
- MyWebViewPlatform(this.creationParams, this.gestureRecognizers,
+class MyWebViewPlatformController extends WebViewPlatformController {
+ MyWebViewPlatformController(this.creationParams, this.gestureRecognizers,
WebViewPlatformCallbacksHandler platformHandler)
: super(platformHandler);