Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
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
2 changes: 1 addition & 1 deletion packages/webview_flutter/webview_flutter_web/AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@

Google Inc.
Bodhi Mulders <[email protected]>

Sophie Bremer
4 changes: 3 additions & 1 deletion packages/webview_flutter/webview_flutter_web/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
## NEXT
## 0.3.0

* Adds support for `baseUrl` parameter in `loadHtmlString`.
* Adds `runJavaScript`.
* Updates minimum supported SDK version to Flutter 3.27/Dart 3.6.

## 0.2.3+4
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:async';
import 'dart:convert';
import 'dart:js_interop';
import 'dart:ui_web' as ui_web;

import 'package:flutter/widgets.dart';
import 'package:web/helpers.dart';
import 'package:web/web.dart' as web;
import 'package:webview_flutter_platform_interface/webview_flutter_platform_interface.dart';

Expand All @@ -18,7 +20,7 @@ import 'http_request_factory.dart';
@immutable
class WebWebViewControllerCreationParams
extends PlatformWebViewControllerCreationParams {
/// Creates a new [AndroidWebViewControllerCreationParams] instance.
/// Creates a new [WebWebViewControllerCreationParams] instance.
WebWebViewControllerCreationParams({
@visibleForTesting this.httpRequestFactory = const HttpRequestFactory(),
}) : super();
Expand All @@ -44,6 +46,8 @@ class WebWebViewControllerCreationParams
..style.width = '100%'
..style.height = '100%'
..style.border = 'none';

final Duration _iFrameWaitDelay = const Duration(milliseconds: 100);
}

/// An implementation of [PlatformWebViewController] using Flutter for Web API.
Expand All @@ -58,13 +62,53 @@ class WebWebViewController extends PlatformWebViewController {
WebWebViewControllerCreationParams get _webWebViewParams =>
params as WebWebViewControllerCreationParams;

// Retrieves the iFrame's content body after attachment to DOM.
Future<web.HTMLBodyElement> _getIFrameBody() async {
final web.Document document = await _getIFrameDocument();

while (document.body == null) {
await Future<void>.delayed(_webWebViewParams._iFrameWaitDelay);
}

return document.body! as HTMLBodyElement;
}

// Retrieves the iFrame's content document after attachment to DOM.
Future<web.Document> _getIFrameDocument() async {
// If the document is not yet available, wait for the 'load' event.
if (_webWebViewParams.iFrame.contentDocument == null) {
final Completer<void> completer = Completer<void>();
_webWebViewParams.iFrame.addEventListener(
'load',
(web.Event _) {
completer.complete();
}.toJS,
AddEventListenerOptions(once: true),
);
// If src is not set, the iframe will never load.
if (_webWebViewParams.iFrame.src.isEmpty) {
_webWebViewParams.iFrame.src = 'about:blank';
}
await completer.future;
}
return _webWebViewParams.iFrame.contentDocument!;
}

@override
Future<void> loadHtmlString(String html, {String? baseUrl}) async {
_webWebViewParams.iFrame.src = Uri.dataFromString(
html,
mimeType: 'text/html',
encoding: utf8,
).toString();
Future<void> loadHtmlString(String html, {String? baseUrl}) {
final Completer<void> loading = Completer<void>();

_webWebViewParams.iFrame.addEventListener(
'load',
() {
_webWebViewParams.iFrame.contentDocument?.write(html.toJS);
loading.complete();
}.toJS,
AddEventListenerOptions(once: true),
);
_webWebViewParams.iFrame.src = baseUrl ?? 'about:blank';

return loading.future;
}

@override
Expand All @@ -83,6 +127,34 @@ class WebWebViewController extends PlatformWebViewController {
}
}

@override
Future<void> runJavaScript(String javaScript) async {
final Completer<void> run = Completer<void>();
final web.Document document = await _getIFrameDocument();
final web.HTMLBodyElement body = await _getIFrameBody();
final web.HTMLScriptElement script =
document.createElement('script') as web.HTMLScriptElement;

script.addEventListener(
'load',
() {
body.removeChild(script);
run.complete();
}.toJS,
AddEventListenerOptions(once: true),
);

script.src = Uri.dataFromString(
javaScript,
mimeType: 'text/javascript',
encoding: utf8,
).toString();

body.appendChild(script);

await run.future;
}

/// Performs an AJAX request defined by [params].
Future<void> _updateIFrameFromXhr(LoadRequestParams params) async {
final web.Response response =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: webview_flutter_web
description: A Flutter plugin that provides a WebView widget on web.
repository: https://github.com/flutter/packages/tree/main/packages/webview_flutter/webview_flutter_web
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+webview%22
version: 0.2.3+4
version: 0.3.0

environment:
sdk: ^3.6.0
Expand Down