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

[webview_flutter] Add interface methods to load local files and HTML strings. #4446

Merged
merged 8 commits into from
Nov 4, 2021
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,3 +1,7 @@
## 1.3.0

* Added `loadFlutterAsset` and `loadHtml` interface methods.
mvanbeusekom marked this conversation as resolved.
Show resolved Hide resolved

## 1.2.0

* Added `runJavascript` and `runJavascriptReturningResult` interface methods to supersede `evaluateJavascript`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,24 @@ class MethodChannelWebViewPlatform implements WebViewPlatformController {
);
}

@override
Future<void> loadFlutterAsset(String assetName) async {
assert(assetName != null);
return _channel.invokeMethod<void>('loadFlutterAsset', assetName);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

You've listed issues for both assets and arbitrary local files in the PR description; why are we restricting to assets here?

It's not clear to me that we should actually support assets on a per-plugin basis, in fact, since there are other cases where someone may want asset paths (e.g., FFI). It might make more sense to just support file paths, and then have a dedicated plugin (or maybe a function in path_provider) to get asset paths.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As far as I know, it is not possible to load files in the WKWebView control that live outside the application bundle (due to security reasons). By only allowing loading of Flutter assets you force developers to add their HTML files as part of the iOS bundle ensuring that the file is always available and can be loaded.

This might be a bit restrictive to other platforms however I think it will cover most use cases where people wish to load local files. At least that was my reasoning.

Copy link
Contributor

Choose a reason for hiding this comment

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

As far as I know, it is not possible to load files in the WKWebView control that live outside the application bundle (due to security reasons).

Do you have a source for that? It's not a documented restriction of the file-loading API.

This might be a bit restrictive to other platforms however I think it will cover most use cases where people wish to load local files. At least that was my reasoning.

One of the issues you linked is explicitly about a use case where assets wouldn't work; I don't think we have any data on how common one or the other use case is.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No I don't have any documentation to back that up. And there are indeed samples that allow you to load information from for example the Documents directory. My bad.

I will update the interface to accept an absolute file path instead.

Copy link
Contributor Author

@mvanbeusekom mvanbeusekom Oct 27, 2021

Choose a reason for hiding this comment

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

Done. I those to accept only the absolute file path as that seems to be the easiest way to work cross platform.

On Android the WebView.loadUrl method requires the path to be prefixed with file:// (which we can take care of internally).

The [WKWebView loadFileURL:] only accepts an instance of the NSURL class which can easily be created from the absolute path using the [NSURL fileURLWithPath:] method.


@override
Future<void> loadHtml(
Copy link
Contributor

Choose a reason for hiding this comment

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

How about loadHtmlString; we expect all of the mechanism for loading to provide HTML so this seems confusingly vague.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Renamed.

String html, {
String? baseUrl,
}) async {
assert(html != null);
return _channel.invokeMethod<void>('loadHtml', <String, dynamic>{
'html': html,
'baseUrl': baseUrl,
});
}

@override
Future<void> loadUrl(
String url,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,29 @@ abstract class WebViewPlatformController {
/// The `handler` parameter must not be null.
WebViewPlatformController(WebViewPlatformCallbacksHandler handler);

/// Loads the Flutter asset specified in the pubspec.yaml file.
///
/// Throws an ArgumentError if [assetName] is not part of the specified assets
/// in the pubspec.yaml file.
Future<void> loadFlutterAsset(
String assetName,
) {
throw UnimplementedError(
"WebView loadFlutterAsset is not implemented on the current platform");
}

/// Loads the supplied HTML.
///
/// The [baseUrl] parameter is used when resolving relative URLs within the
/// HTML string.
Future<void> loadHtml(
String html, {
String? baseUrl,
}) {
throw UnimplementedError(
"WebView loadHtml is not implemented on the current platform");
}

/// Loads the specified URL.
///
/// If `headers` is not null and the URL is an HTTP URL, the key value paris in `headers` will
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ repository: https://github.com/flutter/plugins/tree/master/packages/webview_flut
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+webview_flutter%22
# NOTE: We strongly prefer non-breaking changes, even at the expense of a
# less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes
version: 1.2.0
version: 1.3.0

environment:
sdk: ">=2.12.0 <3.0.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,61 @@ void main() {
log.clear();
});

test('loadFlutterAsset', () async {
await webViewPlatform.loadFlutterAsset(
'folder/asset.html',
);

expect(
log,
<Matcher>[
isMethodCall(
'loadFlutterAsset',
arguments: 'folder/asset.html',
),
],
);
});

test('loadHtml without base URL', () async {
await webViewPlatform.loadHtml(
'Test HTML string',
);

expect(
log,
<Matcher>[
isMethodCall(
'loadHtml',
arguments: <String, String?>{
'html': 'Test HTML string',
'baseUrl': null,
},
),
],
);
});

test('loadHtml without base URL', () async {
await webViewPlatform.loadHtml(
'Test HTML string',
baseUrl: 'https://flutter.dev',
);

expect(
log,
<Matcher>[
isMethodCall(
'loadHtml',
arguments: <String, String?>{
'html': 'Test HTML string',
'baseUrl': 'https://flutter.dev',
},
),
],
);
});

test('loadUrl with headers', () async {
await webViewPlatform.loadUrl(
'https://test.url',
Expand Down