-
Notifications
You must be signed in to change notification settings - Fork 9.8k
[webview_flutter] Implementations of loadFile
and loadHtmlString
for WKWebView
#4486
Changes from 5 commits
8e05ac2
c1dc83a
f1343c2
0351601
b945839
5218c0a
d5cf9f9
98eb236
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,8 +6,11 @@ | |
|
||
import 'dart:async'; | ||
import 'dart:convert'; | ||
import 'dart:io'; | ||
|
||
import 'package:flutter/foundation.dart'; | ||
import 'package:flutter/material.dart'; | ||
import 'package:path_provider/path_provider.dart'; | ||
import 'package:webview_flutter_platform_interface/webview_flutter_platform_interface.dart'; | ||
|
||
import 'navigation_decision.dart'; | ||
|
@@ -33,6 +36,21 @@ The navigation delegate is set to block navigation to the youtube website. | |
</html> | ||
'''; | ||
|
||
const String kLocalFileExamplePage = ''' | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<title>Load file or HTML string example</title> | ||
</head> | ||
<body> | ||
|
||
<h1>Local demo page</h1> | ||
<p>This is an example page used to demonstrate how to load a local file or HTML string using the <a href="https://pub.dev/packages/webview_flutter">Flutter webview</a> plugin.</p> | ||
|
||
</body> | ||
</html> | ||
'''; | ||
|
||
class _WebViewExample extends StatefulWidget { | ||
const _WebViewExample({Key? key}) : super(key: key); | ||
|
||
|
@@ -120,6 +138,8 @@ enum _MenuOptions { | |
listCache, | ||
clearCache, | ||
navigationDelegate, | ||
loadLocalFile, | ||
loadHtmlString, | ||
} | ||
|
||
class _SampleMenu extends StatelessWidget { | ||
|
@@ -157,6 +177,12 @@ class _SampleMenu extends StatelessWidget { | |
case _MenuOptions.navigationDelegate: | ||
_onNavigationDelegateExample(controller.data!, context); | ||
break; | ||
case _MenuOptions.loadLocalFile: | ||
_onLoadLocalFileExample(controller.data!, context); | ||
break; | ||
case _MenuOptions.loadHtmlString: | ||
_onLoadHtmlStringExample(controller.data!, context); | ||
break; | ||
} | ||
}, | ||
itemBuilder: (BuildContext context) => <PopupMenuItem<_MenuOptions>>[ | ||
|
@@ -189,6 +215,14 @@ class _SampleMenu extends StatelessWidget { | |
value: _MenuOptions.navigationDelegate, | ||
child: Text('Navigation Delegate example'), | ||
), | ||
const PopupMenuItem<_MenuOptions>( | ||
value: _MenuOptions.loadHtmlString, | ||
child: Text('Load HTML string'), | ||
), | ||
const PopupMenuItem<_MenuOptions>( | ||
value: _MenuOptions.loadLocalFile, | ||
child: Text('Load local file'), | ||
), | ||
BeMacized marked this conversation as resolved.
Show resolved
Hide resolved
|
||
], | ||
); | ||
}, | ||
|
@@ -259,6 +293,18 @@ class _SampleMenu extends StatelessWidget { | |
await controller.loadUrl('data:text/html;base64,$contentBase64'); | ||
} | ||
|
||
void _onLoadLocalFileExample( | ||
WebViewController controller, BuildContext context) async { | ||
String pathToIndex = await _prepareLocalFile(); | ||
|
||
await controller.loadFile(pathToIndex); | ||
} | ||
|
||
void _onLoadHtmlStringExample( | ||
WebViewController controller, BuildContext context) async { | ||
await controller.loadHtmlString(kLocalFileExamplePage); | ||
} | ||
|
||
Widget _getCookieList(String cookies) { | ||
if (cookies == null || cookies == '""') { | ||
return Container(); | ||
|
@@ -272,6 +318,20 @@ class _SampleMenu extends StatelessWidget { | |
children: cookieWidgets.toList(), | ||
); | ||
} | ||
|
||
static Future<String> _prepareLocalFile() async { | ||
final String tmpDir = (await getTemporaryDirectory()).path; | ||
File indexFile = File('$tmpDir/www/index.html'); | ||
|
||
if (await indexFile.exists()) { | ||
return indexFile.path; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This early return seems odd; why would we want not changes someone made locally to the example HTML (e.g., to try to reproduce an issue in the context of the example) after having already run once to take effect? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You are right. I added this check with the idea that if the file exists we don't have to write it again (in case the user presses the button twice in the same session). However I didn't think about the fact that the file will be persisted over multiple sessions and developers might want to change the HTML contents. |
||
} | ||
|
||
await Directory('$tmpDir/www').create(recursive: true); | ||
await indexFile.writeAsString(kLocalFileExamplePage); | ||
|
||
return indexFile.path; | ||
} | ||
BeMacized marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
class _NavigationControls extends StatelessWidget { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -305,6 +305,35 @@ class WebViewController { | |
|
||
WebView _widget; | ||
|
||
/// Loads the file located on the specified [absoluteFilePath]. | ||
/// | ||
/// The [absoluteFilePath] parameter should contain the absolute path to the | ||
/// file as it is stored on the device. For example: | ||
/// `/Users/username/Documents/www/index.html`. | ||
/// | ||
/// Throws an ArgumentError if the [absoluteFilePath] does not exist. | ||
Future<void> loadFile( | ||
String absoluteFilePath, | ||
) { | ||
assert(absoluteFilePath != null || absoluteFilePath.isNotEmpty); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We don't need null assertions in example code that's null-safe; no non-null-safe code can call it since it's not a library. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removed the redundant assert. |
||
return _webViewPlatformController.loadFile(absoluteFilePath); | ||
} | ||
|
||
/// Loads the supplied HTML string. | ||
/// | ||
/// The [baseUrl] parameter is used when resolving relative URLs within the | ||
/// HTML string. | ||
Future<void> loadHtmlString( | ||
String html, { | ||
String? baseUrl, | ||
}) { | ||
assert(html != null || html.isNotEmpty); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removed the redundant assert. |
||
return _webViewPlatformController.loadHtmlString( | ||
html, | ||
baseUrl: baseUrl, | ||
); | ||
} | ||
|
||
/// Loads the specified URL. | ||
/// | ||
/// If `headers` is not null and the URL is an HTTP URL, the key value paris in `headers` will | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: There's no reason not to break this line to wrap to 80 characters, since HTML doesn't care about whitespace.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.