Skip to content

Commit

Permalink
[webview_flutter] Add setCookie to CookieManager and support initial …
Browse files Browse the repository at this point in the history
…cookies in creation params. (flutter#4561)

This PR adds a function for setting cookies to the CookieManager, as well support for setting initial cookies through the `CreationParams` object.

Fixes flutter#27597
  • Loading branch information
BeMacized committed Dec 7, 2021
1 parent 131036d commit 4fdf85c
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 10 deletions.
5 changes: 5 additions & 0 deletions packages/webview_flutter/webview_flutter/CHANGELOG.md
@@ -1,3 +1,8 @@
## 2.7.0

* Adds `setCookie` to CookieManager.
* CreationParams now supports setting `initialCookies`.

## 2.6.0

* Adds support for the `loadRequest` method.
Expand Down
17 changes: 17 additions & 0 deletions packages/webview_flutter/webview_flutter/example/lib/main.dart
Expand Up @@ -181,6 +181,7 @@ enum MenuOptions {
loadLocalFile,
loadHtmlString,
transparentBackground,
setCookie,
}

class SampleMenu extends StatelessWidget {
Expand Down Expand Up @@ -232,6 +233,9 @@ class SampleMenu extends StatelessWidget {
case MenuOptions.transparentBackground:
_onTransparentBackground(controller.data!, context);
break;
case MenuOptions.setCookie:
_onSetCookie(controller.data!, context);
break;
}
},
itemBuilder: (BuildContext context) => <PopupMenuItem<MenuOptions>>[
Expand Down Expand Up @@ -281,6 +285,10 @@ class SampleMenu extends StatelessWidget {
value: MenuOptions.transparentBackground,
child: Text('Transparent background example'),
),
const PopupMenuItem<MenuOptions>(
value: MenuOptions.setCookie,
child: Text('Set cookie'),
),
],
);
},
Expand Down Expand Up @@ -357,6 +365,15 @@ class SampleMenu extends StatelessWidget {
await controller.loadUrl('data:text/html;base64,$contentBase64');
}

Future<void> _onSetCookie(
WebViewController controller, BuildContext context) async {
await CookieManager().setCookie(
const WebViewCookie(
name: 'foo', value: 'bar', domain: 'httpbin.org', path: '/anything'),
);
await controller.loadUrl('https://httpbin.org/anything');
}

Future<void> _onDoPostRequest(
WebViewController controller, BuildContext context) async {
final WebViewRequest request = WebViewRequest(
Expand Down
Expand Up @@ -22,5 +22,6 @@ export 'package:webview_flutter_platform_interface/webview_flutter_platform_inte
WebSettings,
WebResourceError,
WebResourceErrorType,
WebViewCookie,
WebViewRequest,
WebViewRequestMethod;
32 changes: 28 additions & 4 deletions packages/webview_flutter/webview_flutter/lib/src/webview.dart
Expand Up @@ -3,12 +3,15 @@
// found in the LICENSE file.

import 'dart:async';
import 'dart:io';

import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'package:webview_flutter_android/webview_android.dart';
import 'package:webview_flutter_android/webview_android_cookie_manager.dart';
import 'package:webview_flutter_platform_interface/webview_flutter_platform_interface.dart';
import 'package:webview_flutter_wkwebview/webview_flutter_wkwebview.dart';

import '../platform_interface.dart';
Expand Down Expand Up @@ -79,6 +82,7 @@ class WebView extends StatefulWidget {
Key? key,
this.onWebViewCreated,
this.initialUrl,
this.initialCookies = const <WebViewCookie>[],
this.javascriptMode = JavascriptMode.disabled,
this.javascriptChannels,
this.navigationDelegate,
Expand Down Expand Up @@ -150,6 +154,9 @@ class WebView extends StatefulWidget {
/// The initial URL to load.
final String? initialUrl;

/// The initial cookies to set.
final List<WebViewCookie> initialCookies;

/// Whether JavaScript execution is enabled.
final JavascriptMode javascriptMode;

Expand Down Expand Up @@ -365,6 +372,7 @@ CreationParams _creationParamsfromWidget(WebView widget) {
userAgent: widget.userAgent,
autoMediaPlaybackPolicy: widget.initialMediaPlaybackPolicy,
backgroundColor: widget.backgroundColor,
cookies: widget.initialCookies,
);
}

Expand Down Expand Up @@ -779,16 +787,32 @@ class CookieManager {
return _instance ??= CookieManager._();
}

CookieManager._();
CookieManager._() {
if (WebViewCookieManagerPlatform.instance == null) {
if (Platform.isAndroid) {
WebViewCookieManagerPlatform.instance = WebViewAndroidCookieManager();
} else if (Platform.isIOS) {
WebViewCookieManagerPlatform.instance = WKWebViewCookieManager();
} else {
throw AssertionError(
'This platform is currently unsupported by webview_flutter.');
}
}
}

static CookieManager? _instance;

/// Clears all cookies for all [WebView] instances.
///
/// This is a no op on iOS version smaller than 9.
///
/// Returns true if cookies were present before clearing, else false.
Future<bool> clearCookies() => WebView.platform.clearCookies();
Future<bool> clearCookies() =>
WebViewCookieManagerPlatform.instance!.clearCookies();

/// Sets a cookie for all [WebView] instances.
///
/// This is a no op on iOS versions below 11.
Future<void> setCookie(WebViewCookie cookie) =>
WebViewCookieManagerPlatform.instance!.setCookie(cookie);
}

// Throws an ArgumentError if `url` is not a valid URL string.
Expand Down
6 changes: 3 additions & 3 deletions packages/webview_flutter/webview_flutter/pubspec.yaml
Expand Up @@ -2,7 +2,7 @@ name: webview_flutter
description: A Flutter plugin that provides a WebView widget on Android and iOS.
repository: https://github.com/flutter/plugins/tree/master/packages/webview_flutter/webview_flutter
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+webview%22
version: 2.6.0
version: 2.7.0

environment:
sdk: ">=2.14.0 <3.0.0"
Expand All @@ -19,9 +19,9 @@ flutter:
dependencies:
flutter:
sdk: flutter
webview_flutter_android: ^2.7.0
webview_flutter_android: ^2.8.0
webview_flutter_platform_interface: ^1.8.0
webview_flutter_wkwebview: ^2.5.0
webview_flutter_wkwebview: ^2.6.0

dev_dependencies:
build_runner: ^2.1.5
Expand Down
Expand Up @@ -23,10 +23,12 @@ void main() {

late MockWebViewPlatform mockWebViewPlatform;
late MockWebViewPlatformController mockWebViewPlatformController;
late MockWebViewCookieManagerPlatform mockWebViewCookieManagerPlatform;

setUp(() {
mockWebViewPlatformController = MockWebViewPlatformController();
mockWebViewPlatform = MockWebViewPlatform();
mockWebViewCookieManagerPlatform = MockWebViewCookieManagerPlatform();
when(mockWebViewPlatform.build(
context: anyNamed('context'),
creationParams: anyNamed('creationParams'),
Expand All @@ -46,6 +48,11 @@ void main() {
});

WebView.platform = mockWebViewPlatform;
WebViewCookieManagerPlatform.instance = mockWebViewCookieManagerPlatform;
});

tearDown(() {
mockWebViewCookieManagerPlatform.reset();
});

testWidgets('Create WebView', (WidgetTester tester) async {
Expand Down Expand Up @@ -499,9 +506,6 @@ void main() {
});

testWidgets('Cookies can be cleared once', (WidgetTester tester) async {
when(mockWebViewPlatform.clearCookies())
.thenAnswer((_) => Future<bool>.value(true));

await tester.pumpWidget(
const WebView(
initialUrl: 'https://flutter.io',
Expand All @@ -512,6 +516,21 @@ void main() {
expect(hasCookies, true);
});

testWidgets('Cookies can be set', (WidgetTester tester) async {
const WebViewCookie cookie =
WebViewCookie(name: 'foo', value: 'bar', domain: 'flutter.dev');

await tester.pumpWidget(
const WebView(
initialUrl: 'https://flutter.io',
),
);
final CookieManager cookieManager = CookieManager();
await cookieManager.setCookie(cookie);
expect(mockWebViewCookieManagerPlatform.setCookieCalls,
<WebViewCookie>[cookie]);
});

testWidgets('Initial JavaScript channels', (WidgetTester tester) async {
await tester.pumpWidget(
WebView(
Expand Down Expand Up @@ -1308,3 +1327,19 @@ class MatchesCreationParams extends Matcher {
.matches(creationParams.javascriptChannelNames, matchState);
}
}

class MockWebViewCookieManagerPlatform extends WebViewCookieManagerPlatform {
List<WebViewCookie> setCookieCalls = <WebViewCookie>[];

@override
Future<bool> clearCookies() async => true;

@override
Future<void> setCookie(WebViewCookie cookie) async {
setCookieCalls.add(cookie);
}

void reset() {
setCookieCalls = <WebViewCookie>[];
}
}

0 comments on commit 4fdf85c

Please sign in to comment.