Skip to content
This repository has been archived by the owner on Feb 22, 2023. It is now read-only.

[webview_flutter] Add loadRequest functionality to app facing package. #4573

Merged
merged 23 commits into from Dec 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
6bc4fa8
Add android implementations for loadRequest.
BeMacized Dec 1, 2021
2557862
Update changelog and pubspec.
BeMacized Dec 1, 2021
986217b
Fix comment.
BeMacized Dec 1, 2021
493ad5d
Fix comment.
BeMacized Dec 1, 2021
ab49b54
Add tests
BeMacized Dec 2, 2021
8ca591a
Add back removed license headers
BeMacized Dec 2, 2021
78f9968
Fix analysis error
BeMacized Dec 2, 2021
425251e
Merge branch 'webview_flutter/request_url_native_android' into webvie…
BeMacized Dec 3, 2021
be39a75
Add support for loadRequest to app facing package
BeMacized Dec 3, 2021
706df11
Add test
BeMacized Dec 3, 2021
f024a18
Comment pending dependency in pubspec
BeMacized Dec 3, 2021
7e0a385
Remove workaround for supporting custom headers when making post requ…
BeMacized Dec 6, 2021
ecd7027
Merge branch 'webview_flutter/request_url_native_android' into webvie…
BeMacized Dec 6, 2021
bd65812
Document android workaround in dart doc
BeMacized Dec 6, 2021
6110116
Enforce uri scheme
BeMacized Dec 6, 2021
b5cb337
Merge branch 'webview_flutter/request_url_native_android' into webvie…
BeMacized Dec 6, 2021
885abad
Merge remote-tracking branch 'upstream/master' into webview_flutter/r…
BeMacized Dec 6, 2021
b3f50e7
Update loadRequest dartdoc
BeMacized Dec 6, 2021
712e5ae
Document android workaround in readme
BeMacized Dec 6, 2021
f02ea2a
Processed PR feedback.
BeMacized Dec 6, 2021
a4d2340
Merge branch 'webview_flutter/request_url_native_android' into webvie…
BeMacized Dec 6, 2021
37ce0f8
Merge remote-tracking branch 'upstream/master' into webview_flutter/r…
BeMacized Dec 7, 2021
3434a01
Updated dependency, version and changelog.
BeMacized Dec 7, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/webview_flutter/webview_flutter/CHANGELOG.md
@@ -1,3 +1,7 @@
## 2.6.0

* Adds support for the `loadRequest` method.

## 2.5.0

* Adds an option to set the background color of the webview.
Expand Down
5 changes: 5 additions & 0 deletions packages/webview_flutter/webview_flutter/README.md
Expand Up @@ -92,3 +92,8 @@ android {

To use Material Components when the user interacts with input elements in the WebView,
follow the steps described in the [Enabling Material Components instructions](https://flutter.dev/docs/deployment/android#enabling-material-components).

### Setting custom headers on POST requests

Currently, setting custom headers when making a post request with the WebViewController's `loadRequest` method is not supported on Android.
If you require this functionality, a workaround is to make the request manually, and then load the response data using `loadHTMLString` instead.
20 changes: 20 additions & 0 deletions packages/webview_flutter/webview_flutter/example/lib/main.dart
Expand Up @@ -7,6 +7,7 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';

import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
Expand Down Expand Up @@ -176,6 +177,7 @@ enum MenuOptions {
listCache,
clearCache,
navigationDelegate,
doPostRequest,
loadLocalFile,
loadHtmlString,
transparentBackground,
Expand Down Expand Up @@ -218,6 +220,9 @@ class SampleMenu extends StatelessWidget {
case MenuOptions.navigationDelegate:
_onNavigationDelegateExample(controller.data!, context);
break;
case MenuOptions.doPostRequest:
_onDoPostRequest(controller.data!, context);
break;
case MenuOptions.loadLocalFile:
_onLoadLocalFileExample(controller.data!, context);
break;
Expand Down Expand Up @@ -259,6 +264,10 @@ class SampleMenu extends StatelessWidget {
value: MenuOptions.navigationDelegate,
child: Text('Navigation Delegate example'),
),
const PopupMenuItem<MenuOptions>(
value: MenuOptions.doPostRequest,
child: Text('Post Request'),
),
const PopupMenuItem<MenuOptions>(
value: MenuOptions.loadHtmlString,
child: Text('Load HTML string'),
Expand Down Expand Up @@ -348,6 +357,17 @@ class SampleMenu extends StatelessWidget {
await controller.loadUrl('data:text/html;base64,$contentBase64');
}

Future<void> _onDoPostRequest(
WebViewController controller, BuildContext context) async {
final WebViewRequest request = WebViewRequest(
uri: Uri.parse('https://httpbin.org/post'),
method: WebViewRequestMethod.post,
headers: <String, String>{'foo': 'bar', 'Content-Type': 'text/plain'},
body: Uint8List.fromList('Test Body'.codeUnits),
);
await controller.loadRequest(request);
}

Future<void> _onLoadLocalFileExample(
WebViewController controller, BuildContext context) async {
final String pathToIndex = await _prepareLocalFile();
Expand Down
Expand Up @@ -21,4 +21,6 @@ export 'package:webview_flutter_platform_interface/webview_flutter_platform_inte
WebSetting,
WebSettings,
WebResourceError,
WebResourceErrorType;
WebResourceErrorType,
WebViewRequest,
WebViewRequestMethod;
20 changes: 20 additions & 0 deletions packages/webview_flutter/webview_flutter/lib/src/webview.dart
Expand Up @@ -550,6 +550,26 @@ class WebViewController {
return _webViewPlatformController.loadUrl(url, headers);
}

/// Makes a specific HTTP request and loads the response in the webview.
///
/// [WebViewRequest.method] must be one of the supported HTTP methods
/// in [WebViewRequestMethod].
///
/// If [WebViewRequest.headers] is not empty, its key-value pairs will be
/// added as the headers for the request.
///
/// If [WebViewRequest.body] is not null, it will be added as the body
/// for the request.
///
/// Throws an ArgumentError if [WebViewRequest.uri] has empty scheme.
///
/// Android only:
/// When making a POST request, headers are ignored. As a workaround, make
/// the request manually and load the response data using [loadHTMLString].
Future<void> loadRequest(WebViewRequest request) async {
return _webViewPlatformController.loadRequest(request);
}

/// Accessor to the current URL that the WebView is displaying.
///
/// If [WebView.initialUrl] was never specified, returns `null`.
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.5.0
version: 2.6.0

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

dev_dependencies:
Expand Down
Expand Up @@ -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:typed_data';

import 'package:flutter/src/foundation/basic_types.dart';
import 'package:flutter/src/gestures/recognizer.dart';
import 'package:flutter/widgets.dart';
Expand Down Expand Up @@ -246,6 +248,29 @@ void main() {
));
});

testWidgets('loadRequest', (WidgetTester tester) async {
WebViewController? controller;
await tester.pumpWidget(
WebView(
onWebViewCreated: (WebViewController webViewController) {
controller = webViewController;
},
),
);
expect(controller, isNotNull);

final WebViewRequest req = WebViewRequest(
uri: Uri.parse('https://flutter.dev'),
method: WebViewRequestMethod.post,
headers: <String, String>{'foo': 'bar'},
body: Uint8List.fromList('Test Body'.codeUnits),
);

await controller!.loadRequest(req);

verify(mockWebViewPlatformController.loadRequest(req));
});

testWidgets('Clear Cache', (WidgetTester tester) async {
WebViewController? controller;
await tester.pumpWidget(
Expand Down
@@ -1,22 +1,26 @@
// 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.

// Mocks generated by Mockito 5.0.16 from annotations
// in webview_flutter/test/webview_flutter_test.dart.
// Do not manually edit this file.

import 'dart:async' as _i9;

import 'package:flutter/foundation.dart' as _i7;
import 'package:flutter/foundation.dart' as _i3;
import 'package:flutter/gestures.dart' as _i8;
import 'package:flutter/widgets.dart' as _i2;
import 'package:mockito/mockito.dart' as _i1;
import 'package:webview_flutter_platform_interface/src/platform_interface/javascript_channel_registry.dart'
as _i6;
as _i7;
import 'package:webview_flutter_platform_interface/src/platform_interface/webview_platform.dart'
as _i3;
as _i4;
import 'package:webview_flutter_platform_interface/src/platform_interface/webview_platform_callbacks_handler.dart'
as _i5;
as _i6;
import 'package:webview_flutter_platform_interface/src/platform_interface/webview_platform_controller.dart'
as _i10;
import 'package:webview_flutter_platform_interface/src/types/types.dart' as _i4;
import 'package:webview_flutter_platform_interface/src/types/types.dart' as _i5;

// ignore_for_file: avoid_redundant_argument_values
// ignore_for_file: avoid_setters_without_getters
Expand All @@ -29,26 +33,26 @@ import 'package:webview_flutter_platform_interface/src/types/types.dart' as _i4;

class _FakeWidget_0 extends _i1.Fake implements _i2.Widget {
@override
String toString({_i2.DiagnosticLevel? minLevel = _i2.DiagnosticLevel.info}) =>
String toString({_i3.DiagnosticLevel? minLevel = _i3.DiagnosticLevel.info}) =>
super.toString();
}

/// A class which mocks [WebViewPlatform].
///
/// See the documentation for Mockito's code generation for more information.
class MockWebViewPlatform extends _i1.Mock implements _i3.WebViewPlatform {
class MockWebViewPlatform extends _i1.Mock implements _i4.WebViewPlatform {
MockWebViewPlatform() {
_i1.throwOnMissingStub(this);
}

@override
_i2.Widget build(
{_i2.BuildContext? context,
_i4.CreationParams? creationParams,
_i5.WebViewPlatformCallbacksHandler? webViewPlatformCallbacksHandler,
_i6.JavascriptChannelRegistry? javascriptChannelRegistry,
_i3.WebViewPlatformCreatedCallback? onWebViewPlatformCreated,
Set<_i7.Factory<_i8.OneSequenceGestureRecognizer>>?
_i5.CreationParams? creationParams,
_i6.WebViewPlatformCallbacksHandler? webViewPlatformCallbacksHandler,
_i7.JavascriptChannelRegistry? javascriptChannelRegistry,
_i4.WebViewPlatformCreatedCallback? onWebViewPlatformCreated,
Set<_i3.Factory<_i8.OneSequenceGestureRecognizer>>?
gestureRecognizers}) =>
(super.noSuchMethod(
Invocation.method(#build, [], {
Expand Down Expand Up @@ -83,6 +87,11 @@ class MockWebViewPlatformController extends _i1.Mock
returnValue: Future<void>.value(),
returnValueForMissingStub: Future<void>.value()) as _i9.Future<void>);
@override
_i9.Future<void> loadFlutterAsset(String? key) =>
(super.noSuchMethod(Invocation.method(#loadFlutterAsset, [key]),
returnValue: Future<void>.value(),
returnValueForMissingStub: Future<void>.value()) as _i9.Future<void>);
@override
_i9.Future<void> loadHtmlString(String? html, {String? baseUrl}) =>
(super.noSuchMethod(
Invocation.method(#loadHtmlString, [html], {#baseUrl: baseUrl}),
Expand All @@ -94,12 +103,12 @@ class MockWebViewPlatformController extends _i1.Mock
returnValue: Future<void>.value(),
returnValueForMissingStub: Future<void>.value()) as _i9.Future<void>);
@override
_i9.Future<void> loadRequest(_i4.WebViewRequest? request) =>
_i9.Future<void> loadRequest(_i5.WebViewRequest? request) =>
(super.noSuchMethod(Invocation.method(#loadRequest, [request]),
returnValue: Future<void>.value(),
returnValueForMissingStub: Future<void>.value()) as _i9.Future<void>);
@override
_i9.Future<void> updateSettings(_i4.WebSettings? setting) =>
_i9.Future<void> updateSettings(_i5.WebSettings? setting) =>
(super.noSuchMethod(Invocation.method(#updateSettings, [setting]),
returnValue: Future<void>.value(),
returnValueForMissingStub: Future<void>.value()) as _i9.Future<void>);
Expand Down