From 7feed65909aee911a40a43c6faa948a54f4a6ecb Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Wed, 1 Dec 2021 14:18:56 +0100 Subject: [PATCH 1/4] Adds the `loadFlutterAsset` method to the interface. Adds the `loadFlutterAsset` method to the platform interface. This method, when implemented, is responsible for correctly loading HTML content that is part of the Flutter asset bundle. --- .../CHANGELOG.md | 4 ++++ .../webview_method_channel.dart | 6 ++++++ .../webview_platform_controller.dart | 11 ++++++++++ .../pubspec.yaml | 2 +- .../webview_method_channel_test.dart | 20 +++++++++++++++++++ 5 files changed, 42 insertions(+), 1 deletion(-) diff --git a/packages/webview_flutter/webview_flutter_platform_interface/CHANGELOG.md b/packages/webview_flutter/webview_flutter_platform_interface/CHANGELOG.md index 4e506ded26db..d11223930fd0 100644 --- a/packages/webview_flutter/webview_flutter_platform_interface/CHANGELOG.md +++ b/packages/webview_flutter/webview_flutter_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.6.0 + +* Adds the `loadFlutterAsset` method to the platform interface. + ## 1.5.2 * Mirgrates from analysis_options_legacy.yaml to the more strict analysis_options.yaml. diff --git a/packages/webview_flutter/webview_flutter_platform_interface/lib/src/method_channel/webview_method_channel.dart b/packages/webview_flutter/webview_flutter_platform_interface/lib/src/method_channel/webview_method_channel.dart index 043b5888a69f..471daff57bcc 100644 --- a/packages/webview_flutter/webview_flutter_platform_interface/lib/src/method_channel/webview_method_channel.dart +++ b/packages/webview_flutter/webview_flutter_platform_interface/lib/src/method_channel/webview_method_channel.dart @@ -87,6 +87,12 @@ class MethodChannelWebViewPlatform implements WebViewPlatformController { return _channel.invokeMethod('loadFile', absoluteFilePath); } + @override + Future loadFlutterAsset(String key) async { + assert(key.isNotEmpty); + return _channel.invokeMethod('loadFlutterAsset', key); + } + @override Future loadHtmlString( String html, { diff --git a/packages/webview_flutter/webview_flutter_platform_interface/lib/src/platform_interface/webview_platform_controller.dart b/packages/webview_flutter/webview_flutter_platform_interface/lib/src/platform_interface/webview_platform_controller.dart index da73204e0099..3437fe1f2c09 100644 --- a/packages/webview_flutter/webview_flutter_platform_interface/lib/src/platform_interface/webview_platform_controller.dart +++ b/packages/webview_flutter/webview_flutter_platform_interface/lib/src/platform_interface/webview_platform_controller.dart @@ -35,6 +35,17 @@ abstract class WebViewPlatformController { /// Throws an ArgumentError if the [absoluteFilePath] does not exist. Future loadFile( String absoluteFilePath, + ) { + throw UnimplementedError( + 'WebView loadFile is not implemented on the current platform'); + } + + /// Loads the Flutter asset specified in the pubspec.yaml file. + /// + /// Throws an ArgumentError if [key] is not part of the specified assets + /// in the pubspec.yaml file. + Future loadFlutterAsset( + String key, ) { throw UnimplementedError( 'WebView loadFlutterAsset is not implemented on the current platform'); diff --git a/packages/webview_flutter/webview_flutter_platform_interface/pubspec.yaml b/packages/webview_flutter/webview_flutter_platform_interface/pubspec.yaml index 318fea614b4d..3c0b5fa34b63 100644 --- a/packages/webview_flutter/webview_flutter_platform_interface/pubspec.yaml +++ b/packages/webview_flutter/webview_flutter_platform_interface/pubspec.yaml @@ -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.5.2 +version: 1.6.0 environment: sdk: ">=2.12.0 <3.0.0" diff --git a/packages/webview_flutter/webview_flutter_platform_interface/test/src/method_channel/webview_method_channel_test.dart b/packages/webview_flutter/webview_flutter_platform_interface/test/src/method_channel/webview_method_channel_test.dart index 2db2dfad4f57..2c20441c9a65 100644 --- a/packages/webview_flutter/webview_flutter_platform_interface/test/src/method_channel/webview_method_channel_test.dart +++ b/packages/webview_flutter/webview_flutter_platform_interface/test/src/method_channel/webview_method_channel_test.dart @@ -73,6 +73,26 @@ void main() { ); }); + test('loadFlutterAsset', () async { + await webViewPlatform.loadFlutterAsset( + 'folder/asset.html', + ); + + expect( + log, + [ + isMethodCall( + 'loadFlutterAsset', + arguments: 'folder/asset.html', + ), + ], + ); + }); + + test('loadFlutterAsset with empty key', () async { + expect(() => webViewPlatform.loadFlutterAsset(''), throwsAssertionError); + }); + test('loadHtmlString without base URL', () async { await webViewPlatform.loadHtmlString( 'Test HTML string', From 9be0339d00b70eaf07940b98b04e5b00e2b29122 Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Thu, 2 Dec 2021 20:44:59 +0100 Subject: [PATCH 2/4] Handle PlatformException correctly. Converts the `PlatformException` into an `ArgumentException` when there is a failure loading the file or asset. --- .../webview_method_channel.dart | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/packages/webview_flutter/webview_flutter_platform_interface/lib/src/method_channel/webview_method_channel.dart b/packages/webview_flutter/webview_flutter_platform_interface/lib/src/method_channel/webview_method_channel.dart index 471daff57bcc..96376330105d 100644 --- a/packages/webview_flutter/webview_flutter_platform_interface/lib/src/method_channel/webview_method_channel.dart +++ b/packages/webview_flutter/webview_flutter_platform_interface/lib/src/method_channel/webview_method_channel.dart @@ -84,13 +84,31 @@ class MethodChannelWebViewPlatform implements WebViewPlatformController { @override Future loadFile(String absoluteFilePath) async { assert(absoluteFilePath != null); - return _channel.invokeMethod('loadFile', absoluteFilePath); + + try { + return await _channel.invokeMethod('loadFile', absoluteFilePath); + } on PlatformException catch (ex) { + if (ex.code == 'loadFile_failed') { + throw ArgumentError(ex.message); + } + + rethrow; + } } @override Future loadFlutterAsset(String key) async { assert(key.isNotEmpty); - return _channel.invokeMethod('loadFlutterAsset', key); + + try { + return await _channel.invokeMethod('loadFlutterAsset', key); + } on PlatformException catch (ex) { + if (ex.code == 'loadFlutterAsset_failed') { + throw ArgumentError(ex.message); + } + + rethrow; + } } @override From 388f41caf8fbf26d18d0c5cebbe16239a2fe2fa6 Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Thu, 2 Dec 2021 21:01:33 +0100 Subject: [PATCH 3/4] Adds tests for PlatformException handling. --- .../webview_method_channel_test.dart | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/packages/webview_flutter/webview_flutter_platform_interface/test/src/method_channel/webview_method_channel_test.dart b/packages/webview_flutter/webview_flutter_platform_interface/test/src/method_channel/webview_method_channel_test.dart index 5db6064ced11..7fd31cbec397 100644 --- a/packages/webview_flutter/webview_flutter_platform_interface/test/src/method_channel/webview_method_channel_test.dart +++ b/packages/webview_flutter/webview_flutter_platform_interface/test/src/method_channel/webview_method_channel_test.dart @@ -32,6 +32,23 @@ void main() { case 'canGoBack': case 'canGoForward': return true; + case 'loadFile': + if (methodCall.arguments == 'invalid file') { + throw PlatformException( + code: 'loadFile_failed', + message: 'Failed loading file.', + details: null); + } + return null; + case 'loadFlutterAsset': + if (methodCall.arguments == 'invalid key') { + throw PlatformException( + code: 'loadFlutterAsset_failed', + message: 'Failed loading asset.', + details: null, + ); + } + return null; case 'runJavascriptReturningResult': case 'evaluateJavascript': return methodCall.arguments as String; @@ -73,6 +90,19 @@ void main() { ); }); + test('loadFile with invalid file', () async { + expect( + () => webViewPlatform.loadFile('invalid file'), + throwsA( + isA().having( + (ArgumentError error) => error.message, + 'message', + 'Failed loading file.', + ), + ), + ); + }); + test('loadFlutterAsset', () async { await webViewPlatform.loadFlutterAsset( 'folder/asset.html', @@ -93,6 +123,19 @@ void main() { expect(() => webViewPlatform.loadFlutterAsset(''), throwsAssertionError); }); + test('loadFlutterAsset with invalid key', () async { + expect( + () => webViewPlatform.loadFlutterAsset('invalid key'), + throwsA( + isA().having( + (ArgumentError error) => error.message, + 'message', + 'Failed loading asset.', + ), + ), + ); + }); + test('loadHtmlString without base URL', () async { await webViewPlatform.loadHtmlString( 'Test HTML string', From bbc3d92e3615fc806b3a80513b138c9f15be529d Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Thu, 2 Dec 2021 21:20:47 +0100 Subject: [PATCH 4/4] Fix PR feedback --- .../webview_method_channel.dart | 2 +- .../webview_method_channel_test.dart | 40 ++++++++++++++++++- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/packages/webview_flutter/webview_flutter_platform_interface/lib/src/method_channel/webview_method_channel.dart b/packages/webview_flutter/webview_flutter_platform_interface/lib/src/method_channel/webview_method_channel.dart index 4eafec6fbd9a..5a0aaa891370 100644 --- a/packages/webview_flutter/webview_flutter_platform_interface/lib/src/method_channel/webview_method_channel.dart +++ b/packages/webview_flutter/webview_flutter_platform_interface/lib/src/method_channel/webview_method_channel.dart @@ -103,7 +103,7 @@ class MethodChannelWebViewPlatform implements WebViewPlatformController { try { return await _channel.invokeMethod('loadFlutterAsset', key); } on PlatformException catch (ex) { - if (ex.code == 'loadFlutterAsset_failed') { + if (ex.code == 'loadFlutterAsset_invalidKey') { throw ArgumentError(ex.message); } diff --git a/packages/webview_flutter/webview_flutter_platform_interface/test/src/method_channel/webview_method_channel_test.dart b/packages/webview_flutter/webview_flutter_platform_interface/test/src/method_channel/webview_method_channel_test.dart index 7fd31cbec397..94ad30988889 100644 --- a/packages/webview_flutter/webview_flutter_platform_interface/test/src/method_channel/webview_method_channel_test.dart +++ b/packages/webview_flutter/webview_flutter_platform_interface/test/src/method_channel/webview_method_channel_test.dart @@ -38,15 +38,27 @@ void main() { code: 'loadFile_failed', message: 'Failed loading file.', details: null); + } else if (methodCall.arguments == 'some error') { + throw PlatformException( + code: 'some_error', + message: 'Some error occurred.', + details: null, + ); } return null; case 'loadFlutterAsset': if (methodCall.arguments == 'invalid key') { throw PlatformException( - code: 'loadFlutterAsset_failed', + code: 'loadFlutterAsset_invalidKey', message: 'Failed loading asset.', details: null, ); + } else if (methodCall.arguments == 'some error') { + throw PlatformException( + code: 'some_error', + message: 'Some error occurred.', + details: null, + ); } return null; case 'runJavascriptReturningResult': @@ -103,6 +115,19 @@ void main() { ); }); + test('loadFile with some error.', () async { + expect( + () => webViewPlatform.loadFile('some error'), + throwsA( + isA().having( + (PlatformException error) => error.message, + 'message', + 'Some error occurred.', + ), + ), + ); + }); + test('loadFlutterAsset', () async { await webViewPlatform.loadFlutterAsset( 'folder/asset.html', @@ -136,6 +161,19 @@ void main() { ); }); + test('loadFlutterAsset with some error.', () async { + expect( + () => webViewPlatform.loadFlutterAsset('some error'), + throwsA( + isA().having( + (PlatformException error) => error.message, + 'message', + 'Some error occurred.', + ), + ), + ); + }); + test('loadHtmlString without base URL', () async { await webViewPlatform.loadHtmlString( 'Test HTML string',