Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
7f876d1
copy code from v4_webview
bparrishMines Dec 15, 2022
56fceb9
version bump and readme update
bparrishMines Dec 15, 2022
2a4b7d3
work towards better readme
bparrishMines Dec 15, 2022
e90e7df
Merge branch 'main' of github.com:flutter/plugins into webview_flutte…
bparrishMines Dec 15, 2022
b2480f8
improvements
bparrishMines Dec 15, 2022
0d4e703
more readme progress
bparrishMines Dec 16, 2022
9968f38
Merge branch 'main' of github.com:flutter/plugins into webview_flutte…
bparrishMines Dec 16, 2022
301fafa
improvements
bparrishMines Dec 16, 2022
e56c091
fix main and update more readme
bparrishMines Dec 16, 2022
65d28ed
excerpt changes and more 3.0 diffs
bparrishMines Dec 16, 2022
c41fa5b
cookie manager update
bparrishMines Dec 16, 2022
f5e7243
remove packages from exclude list
bparrishMines Dec 16, 2022
720082e
lint
bparrishMines Dec 16, 2022
de00284
better range
bparrishMines Dec 16, 2022
fc2d6cb
isForMainFrame
bparrishMines Dec 16, 2022
f1c7a65
load page after waiting for widget
bparrishMines Dec 16, 2022
b206a23
fix integration tests
bparrishMines Dec 16, 2022
998d8ae
Merge branch 'main' of github.com:flutter/plugins into webview_flutte…
bparrishMines Dec 16, 2022
a496fef
improve readme a bit
bparrishMines Dec 16, 2022
feb0b2e
collapse changelong. update platform-specific wording. include in exc…
bparrishMines Dec 16, 2022
fcf987d
use platform implementation packages
bparrishMines Dec 16, 2022
4ff354b
include missing exports
bparrishMines Dec 16, 2022
72f1db8
PR comments
bparrishMines Dec 16, 2022
45d1a34
correct spelling
bparrishMines Dec 16, 2022
cc30a02
Merge branch 'main' of github.com:flutter/plugins into webview_flutte…
bparrishMines Dec 16, 2022
cc24cbb
interface dev dependency
bparrishMines Dec 16, 2022
52069b3
move other usage above migration
bparrishMines Dec 17, 2022
dbc20fa
remove interface classes
bparrishMines Dec 17, 2022
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
7 changes: 5 additions & 2 deletions packages/webview_flutter/webview_flutter/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
## NEXT
## 4.0.0

* **BREAKING CHANGE** Updates implementation to use the `2.0.0` release of
`webview_flutter_platform_interface`. See `Usage` section in the README for updated usage. See
`Migrating from 3.0 to 4.0` section in the README for details on migrating to this version.
* Updates code for `no_leading_underscores_for_local_identifiers` lint.
* Updates minimum Flutter version to 2.10.
* Updates minimum Flutter version to 3.0.0.
* Fixes avoid_redundant_argument_values lint warnings and minor typos.
* Ignores unnecessary import warnings in preparation for [upcoming Flutter changes](https://github.com/flutter/flutter/pull/104231).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's collapse these two and the underscores one above to a catch-all "Updates code for new analysis options." so there's less minor stuff listed in with the big change.

* Updates references to the obsolete master branch.
Expand Down
233 changes: 176 additions & 57 deletions packages/webview_flutter/webview_flutter/README.md
Original file line number Diff line number Diff line change
@@ -1,41 +1,73 @@
# WebView for Flutter

<?code-excerpt path-base="excerpts/packages/webview_flutter_example"?>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! You can remove this package from script/configs/temp_exclude_excerpt.yaml in this PR as well.


[![pub package](https://img.shields.io/pub/v/webview_flutter.svg)](https://pub.dev/packages/webview_flutter)

A Flutter plugin that provides a WebView widget.

On iOS the WebView widget is backed by a [WKWebView](https://developer.apple.com/documentation/webkit/wkwebview);
On iOS the WebView widget is backed by a [WKWebView](https://developer.apple.com/documentation/webkit/wkwebview).
On Android the WebView widget is backed by a [WebView](https://developer.android.com/reference/android/webkit/WebView).

| | Android | iOS |
|-------------|----------------|------|
| **Support** | SDK 19+ or 20+ | 9.0+ |

## Usage
Add `webview_flutter` as a [dependency in your pubspec.yaml file](https://flutter.dev/docs/development/platform-integration/platform-channels). If you are targeting Android, make sure to read the *Android Platform Views* section below to choose the platform view mode that best suits your needs.

You can now include a WebView widget in your widget tree. See the
[WebView](https://pub.dev/documentation/webview_flutter/latest/webview_flutter/WebView-class.html)
widget's Dartdoc for more details on how to use the widget.
Add `webview_flutter` as a [dependency in your pubspec.yaml file](https://pub.dev/packages/webview_flutter/install).

You can now display a WebView by:

1. Instantiating a [WebViewController](https://pub.dev/documentation/webview_flutter/latest/webview_flutter/WebViewController-class.html).

<?code-excerpt "simple_example.dart (webview_controller)"?>
```dart
controller = WebViewController()
..setJavaScriptMode(JavaScriptMode.unrestricted)
..setBackgroundColor(const Color(0x00000000))
..setNavigationDelegate(
NavigationDelegate(
onProgress: (int progress) {
// Update loading bar.
},
onPageStarted: (String url) {},
onPageFinished: (String url) {},
onWebResourceError: (WebResourceError error) {},
onNavigationRequest: (NavigationRequest request) {
if (request.url.startsWith('https://www.youtube.com/')) {
return NavigationDecision.prevent;
}
return NavigationDecision.navigate;
},
),
)
..loadRequest(Uri.parse('https://flutter.dev'));
```

## Android Platform Views
This plugin uses
[Platform Views](https://flutter.dev/docs/development/platform-integration/platform-views) to embed
the Android’s webview within the Flutter app. It supports two modes:
*hybrid composition* (the current default) and *virtual display*.
2. Passing the controller to a [WebViewWidget](https://pub.dev/documentation/webview_flutter/latest/webview_flutter/WebViewWidget-class.html).

Here are some points to consider when choosing between the two:
<?code-excerpt "simple_example.dart (webview_widget)"?>
```dart
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Flutter Simple Example')),
body: WebViewWidget(controller: controller),
);
}
```

* *Hybrid composition* has built-in keyboard support while *virtual display* has multiple
[keyboard issues](https://github.com/flutter/flutter/issues?q=is%3Aopen+label%3Avd-only+label%3A%22p%3A+webview-keyboard%22).
* *Hybrid composition* requires Android SDK 19+ while *virtual display* requires Android SDK 20+.
* *Hybrid composition* and *virtual display* have different
[performance tradeoffs](https://flutter.dev/docs/development/platform-integration/platform-views#performance).
See the Dartdocs for [WebViewController](https://pub.dev/documentation/webview_flutter/latest/webview_flutter/WebViewController-class.html)
and [WebViewWidget](https://pub.dev/documentation/webview_flutter/latest/webview_flutter/WebViewWidget-class.html)
for more details.

### Android Platform Views

### Using Hybrid Composition
This plugin uses
[Platform Views](https://flutter.dev/docs/development/platform-integration/platform-views) to embed
the Android’s WebView within the Flutter app.

The mode is currently enabled by default. You should however make sure to set the correct `minSdkVersion` in `android/app/build.gradle` if it was previously lower than 19:
You should however make sure to set the correct `minSdkVersion` in `android/app/build.gradle` if it was previously lower than 19:

```groovy
android {
Expand All @@ -45,54 +77,141 @@ android {
}
```

### Using Virtual displays
### Platform Specific Features
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Platform-Specific Features


1. Set the correct `minSdkVersion` in `android/app/build.gradle` (if it was previously lower than 20):
Many classes have a subclass or an underlying implementation that provides access to platform
specific features.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here: platform-specific features


```groovy
android {
defaultConfig {
minSdkVersion 20
}
}
```

2. Set `WebView.platform = AndroidWebView();` in `initState()`.
For example:
To access platform specific features, start by including the import for the desired platform:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should mention adding a direct dependency on the implementation package in pubspec.yaml (see next comment).


```dart
import 'dart:io';

import 'package:webview_flutter/webview_flutter.dart';
<?code-excerpt "main.dart (platform_imports)"?>
```dart
// Import for Android features.
import 'package:webview_flutter/android.dart';
// ···
// Import for iOS features.
import 'package:webview_flutter/wkwebview.dart';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should remove these files entirely, and show importing from the packages instead, because if we re-export platform-specific packages, then any breaking change to those packages' platform-specific APIs will require a breaking change to the app-facing package as well, which we don't want.

Using the implementation packages directly for platform features is the pattern we're using in other plugins (local_auth, IAP, etc.)

Copy link
Contributor Author

@bparrishMines bparrishMines Dec 16, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with this approach. I like the app-facing package to remain mostly unaware of its implementations.

But to do this, I also had to add LoadRequestParams and JavaScriptChannelParams to the webview_flutter.dart export. I'm considering some other options,

  1. We could export LoadRequestParams and JavaScriptChannelParams in the platform implementations instead.
  2. Create a import 'package:webview_flutter/platform_interface.dart' export file.
  3. Require apps to import the platform interface when importing the platform implementations.
  4. Leave it as is.

My preference is to export these classes in the platform implementation classes. This would allow us import the minimum needed in the app-facing package and not require any additional work for a user to use the platform implementation classes.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, 1 seems like the best option. It also seems like the most consistent with the general policy that an interface should export all the types used in its public API (comparable to the lint about not using private classes in public APIs).

```

class WebViewExample extends StatefulWidget {
@override
WebViewExampleState createState() => WebViewExampleState();
}
Now, additional features can be accessed through the platform implementations. Classes
`WebViewController`, `WebViewWidget`, `NavigationDelegate`, and `WebViewCookieManager` pass their
functionality to a class provided by the current platform. Below are a couple of ways to access
additional functionality provided by the platform and is followed by an example.

1. Pass a creation params class provided by a platform implementation to a `fromPlatformCreationParams`
constructor (e.g. `WebViewController.fromPlatformCreationParams`,
`WebViewWidget.fromPlatformCreationParams`, etc...).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: just "etc." rather than "etc..."

2. Call methods on a platform implementation of a class by using the `platform` field (e.g.
`WebViewController.platform`, `WebViewWidget.platform`, etc...).

Below is an example of setting additional iOS and Android parameters to the `WebViewController`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: s/to the/on the/


<?code-excerpt "main.dart (platform_features)"?>
```dart
late final PlatformWebViewControllerCreationParams params;
if (WebViewPlatform.instance is WebKitWebViewPlatform) {
params = WebKitWebViewControllerCreationParams(
allowsInlineMediaPlayback: true,
mediaTypesRequiringUserAction: const <PlaybackMediaTypes>{},
);
} else {
params = const PlatformWebViewControllerCreationParams();
}

class WebViewExampleState extends State<WebViewExample> {
@override
void initState() {
super.initState();
// Enable virtual display.
if (Platform.isAndroid) WebView.platform = AndroidWebView();
}

@override
Widget build(BuildContext context) {
return WebView(
initialUrl: 'https://flutter.dev',
);
}
}
```
final WebViewController controller =
WebViewController.fromPlatformCreationParams(params);
// ···
if (controller.platform is AndroidWebViewController) {
AndroidWebViewController.enableDebugging(true);
(controller.platform as AndroidWebViewController)
.setMediaPlaybackRequiresUserGesture(false);
}
```

### Enable Material Components for Android
See https://pub.dev/documentation/webview_flutter/latest/android/android-library.html
for more details on Android features.

See https://pub.dev/documentation/webview_flutter/latest/wkwebview/wkwebview-library.html
for more details on iOS features.

## Migrating from 3.0 to 4.0

### Instantiating WebViewController

In version 3.0 and below, `WebViewController` could only be retrieved in a callback after the
`WebView` was added to the widget tree. Now, `WebViewController` must be instantiated and can be
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: there's an extra space in "was added"

used before it is added to the widget tree. See `Usage` section above for an example.

### Replacing WebView Functionality

The `WebView` class has been removed and it's functionality has been split into `WebViewController`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: its

and `WebViewWidget`.

`WebViewController` handles all functionality that is associated with the underlying WebView
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: "underlying web view" since it's referring to the concept rather than a class.

provided by each platform. (e.g. loading a url, setting the background color of the underlying
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: "e.g.,"

platform view, or clearing the cache).

`WebViewWidget` takes a `WebViewController` and handles all Flutter widget related functionality
(e.g. layout direction, gesture recognizers).

See the Dartdocs for [WebViewController](https://pub.dev/documentation/webview_flutter/latest/webview_flutter/WebViewController-class.html)
and [WebViewWidget](https://pub.dev/documentation/webview_flutter/latest/webview_flutter/WebViewWidget-class.html)
for more details.

### PlatformView Implementation on Android

The PlatformView implementation for Android is currently no longer configurable. It uses Texture
Layer Hybrid Composition on versions 23+ and automatically fallbacks to Hybrid Composition for
version 19-23. See https://github.com/flutter/flutter/issues/108106 for progress on manually
switching to Hybrid Composition on versions 23+.

### API Changes

Below is a non-exhaustive list of changes to the API:

* `WebViewController.clearCache` no longer clears local storage. Please use
`WebViewController.clearLocalStorage`.
* `WebViewController.clearCache` no longer reloads the page.
* `WebViewController.loadUrl` has been removed. Please use `WebViewController.loadRequest`.
* `WebViewController.evaluateJavascript` has been removed. Please use
`WebViewController.runJavaScript` or `WebViewController.runJavaScriptReturningResult`.
* `WebViewController.getScrollX` and `WebViewController.getScrollY` have been removed and have
been replaced by `WebViewController.getScrollPosition`.
* `WebViewController.runJavaScriptReturningResult` now returns an `Object` and not a `String`. This
will attempt to return a `bool` or `num` if the return value can be parsed.
* `CookieManager` is replaced by `WebViewCookieManager`.
* `NavigationDelegate.onWebResourceError` callback includes errors that are not from the main frame.
Use the `WebResourceError.isForMainFrame` field to filter errors.
* The following fields from `WebView` have been moved to `NavigationDelegate`. They can be added to
a WebView with `WebViewController.setNavigationDelegate`.
* `WebView.navigationDelegate` -> `NavigationDelegate.onNavigationRequest`
* `WebView.onPageStarted` -> `NavigationDelegate.onPageStarted`
* `WebView.onPageFinished` -> `NavigationDelegate.onPageFinished`
* `WebView.onProgress` -> `NavigationDelegate.onProgress`
* `WebView.onWebResourceError` -> `NavigationDelegate.onWebResourceError`
* The following fields from `WebView` have been moved to `WebViewController`:
* `WebView.javascriptMode` -> `WebViewController.setJavaScriptMode`
* `WebView.javascriptChannels` ->
`WebViewController.addJavaScriptChannel`/`WebViewController.removeJavaScriptChannel`
* `WebView.zoomEnabled` -> `WebViewController.enableZoom`
* `WebView.userAgent` -> `WebViewController.setUserAgent`
* `WebView.backgroundColor` -> `WebViewController.setBackgroundColor`
* The following features have been moved to an Android implementation class. See section
`Platform Specific Features` for details on accessing Android platform specific features.
* `WebView.debuggingEnabled` -> `static AndroidWebViewController.enableDebugging`
* `WebView.initialMediaPlaybackPolicy` -> `AndroidWebViewController.setMediaPlaybackRequiresUserGesture`
* The following features have been moved to an iOS implementation class. See section
`Platform Specific Features` for details on accessing iOS platform specific features.
* `WebView.gestureNavigationEnabled` -> `WebKitWebViewController.setAllowsBackForwardNavigationGestures`
* `WebView.initialMediaPlaybackPolicy` -> `WebKitWebViewControllerCreationParams.mediaTypesRequiringUserAction`
* `WebView.allowsInlineMediaPlayback` -> `WebKitWebViewControllerCreationParams.allowsInlineMediaPlayback`

## Enable Material Components for Android
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this and the next section still be ### headings under ## Usage?


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
## 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.
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
targets:
$default:
sources:
include:
- lib/**
# Some default includes that aren't really used here but will prevent
# false-negative warnings:
- $package$
- lib/$lib$
exclude:
- '**/.*/**'
- '**/build/**'
builders:
code_excerpter|code_excerpter:
enabled: true
Loading