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

* Add methods to load HTML and Flutter assets.

Adds methods to the webview_flutter_platform_interface to support
loading content from Flutter asset defined in the pubspec.yaml of
directly from HTML string.

* Renamed loadHtml to loadHtmlString

* Support loading arbitrary files instead of only Flutter assets

* Update changelog description

* Fix formatting

* Fix formatting
diff --git a/packages/webview_flutter/webview_flutter_platform_interface/CHANGELOG.md b/packages/webview_flutter/webview_flutter_platform_interface/CHANGELOG.md
index 0579121..4c7434a 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.4.0
+
+* Added `loadFile` and `loadHtml` interface methods.
+
 ## 1.3.0
 
 * Added `loadRequest` method to platform interface.
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 a88479e..8df9f4c 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
@@ -80,6 +80,24 @@
   }
 
   @override
+  Future<void> loadFile(String absoluteFilePath) async {
+    assert(absoluteFilePath != null);
+    return _channel.invokeMethod<void>('loadFile', absoluteFilePath);
+  }
+
+  @override
+  Future<void> loadHtmlString(
+    String html, {
+    String? baseUrl,
+  }) async {
+    assert(html != null);
+    return _channel.invokeMethod<void>('loadHtmlString', <String, dynamic>{
+      'html': html,
+      'baseUrl': baseUrl,
+    });
+  }
+
+  @override
   Future<void> loadUrl(
     String url,
     Map<String, String>? headers,
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 806f950..cfc8174 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
@@ -23,6 +23,32 @@
   /// The `handler` parameter must not be null.
   WebViewPlatformController(WebViewPlatformCallbacksHandler handler);
 
+  /// 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,
+  ) {
+    throw UnimplementedError(
+        "WebView loadFlutterAsset is not implemented on the current platform");
+  }
+
+  /// 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,
+  }) {
+    throw UnimplementedError(
+        "WebView loadHtmlString 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
diff --git a/packages/webview_flutter/webview_flutter_platform_interface/pubspec.yaml b/packages/webview_flutter/webview_flutter_platform_interface/pubspec.yaml
index 508af0e..4a4746d 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 @@
 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.3.0
+version: 1.4.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 b85b7b3..3960135 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
@@ -57,6 +57,61 @@
       log.clear();
     });
 
+    test('loadFile', () async {
+      await webViewPlatform.loadFile(
+        '/folder/asset.html',
+      );
+
+      expect(
+        log,
+        <Matcher>[
+          isMethodCall(
+            'loadFile',
+            arguments: '/folder/asset.html',
+          ),
+        ],
+      );
+    });
+
+    test('loadHtmlString without base URL', () async {
+      await webViewPlatform.loadHtmlString(
+        'Test HTML string',
+      );
+
+      expect(
+        log,
+        <Matcher>[
+          isMethodCall(
+            'loadHtmlString',
+            arguments: <String, String?>{
+              'html': 'Test HTML string',
+              'baseUrl': null,
+            },
+          ),
+        ],
+      );
+    });
+
+    test('loadHtmlString without base URL', () async {
+      await webViewPlatform.loadHtmlString(
+        'Test HTML string',
+        baseUrl: 'https://flutter.dev',
+      );
+
+      expect(
+        log,
+        <Matcher>[
+          isMethodCall(
+            'loadHtmlString',
+            arguments: <String, String?>{
+              'html': 'Test HTML string',
+              'baseUrl': 'https://flutter.dev',
+            },
+          ),
+        ],
+      );
+    });
+
     test('loadUrl with headers', () async {
       await webViewPlatform.loadUrl(
         'https://test.url',