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

[webview_flutter_web] Copies web implementation of webview_flutter from v4_webview #6854

Merged
merged 4 commits into from
Dec 16, 2022
Merged
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
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.2.0

* **BREAKING CHANGE** Updates platform implementation to `2.0.0` release of
`webview_flutter_platform_interface`. See README for updated usage.
* Updates minimum Flutter version to 2.10.

## 0.1.0+4
Expand Down
12 changes: 5 additions & 7 deletions packages/webview_flutter/webview_flutter_web/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@ This is an implementation of the [`webview_flutter`](https://pub.dev/packages/we
It is currently severely limited and doesn't implement most of the available functionality.
The following functionality is currently available:

- `loadUrl` (Without headers)
- `requestUrl`
- `loadHTMLString` (Without `baseUrl`)
- Setting the `initialUrl` through `CreationParams`.
- `loadRequest`
- `loadHtmlString` (Without `baseUrl`)

Nothing else is currently supported.

Expand All @@ -20,7 +18,7 @@ yet, so it currently requires extra setup to use:
* [Add this package](https://pub.dev/packages/webview_flutter_web/install)
as an explicit dependency of your project, in addition to depending on
`webview_flutter`.
* Register `WebWebViewPlatform` as the `WebView.platform` before creating a
* Register `WebWebViewPlatform` as the `WebViewPlatform.instance` before creating a
`WebView`. See below for examples.

Once those steps below are complete, the APIs from `webview_flutter` listed
Expand All @@ -39,7 +37,7 @@ import 'package:webview_flutter/webview_flutter.dart';
import 'package:webview_flutter_web/webview_flutter_web.dart';
main() {
WebView.platform = WebWebViewPlatform();
WebViewPlatform.instance = WebWebViewPlatform();
...
```

Expand All @@ -55,7 +53,7 @@ import 'package:webview_flutter/webview_flutter.dart';
import 'package:webview_flutter_web/webview_flutter_web.dart';
void registerWebViewWebImplementation() {
WebView.platform = WebWebViewPlatform();
WebViewPlatform.instance = WebWebViewPlatform();
}
```

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// 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:html' as html;

import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:webview_flutter_web_example/legacy/web_view.dart';

void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

// URLs to navigate to in tests. These need to be URLs that we are confident will
// always be accessible, and won't do redirection. (E.g., just
// 'https://www.google.com/' will sometimes redirect traffic that looks
// like it's coming from a bot, which is true of these tests).
const String primaryUrl = 'https://flutter.dev/';
const String secondaryUrl = 'https://www.google.com/robots.txt';

testWidgets('initialUrl', (WidgetTester tester) async {
final Completer<WebViewController> controllerCompleter =
Completer<WebViewController>();
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: WebView(
key: GlobalKey(),
initialUrl: primaryUrl,
onWebViewCreated: (WebViewController controller) {
controllerCompleter.complete(controller);
},
),
),
);
await controllerCompleter.future;

// Assert an iframe has been rendered to the DOM with the correct src attribute.
final html.IFrameElement? element =
html.document.querySelector('iframe') as html.IFrameElement?;
expect(element, isNotNull);
expect(element!.src, primaryUrl);
});

testWidgets('loadUrl', (WidgetTester tester) async {
final Completer<WebViewController> controllerCompleter =
Completer<WebViewController>();
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: WebView(
key: GlobalKey(),
initialUrl: primaryUrl,
onWebViewCreated: (WebViewController controller) {
controllerCompleter.complete(controller);
},
),
),
);
final WebViewController controller = await controllerCompleter.future;
await controller.loadUrl(secondaryUrl);

// Assert an iframe has been rendered to the DOM with the correct src attribute.
final html.IFrameElement? element =
html.document.querySelector('iframe') as html.IFrameElement?;
expect(element, isNotNull);
expect(element!.src, secondaryUrl);
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,48 @@
// 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:html' as html;
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:webview_flutter_web_example/web_view.dart';
import 'package:webview_flutter_platform_interface/webview_flutter_platform_interface.dart';
import 'package:webview_flutter_web/webview_flutter_web.dart';

void main() {
Future<void> main() async {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

// URLs to navigate to in tests. These need to be URLs that we are confident will
// always be accessible, and won't do redirection. (E.g., just
// 'https://www.google.com/' will sometimes redirect traffic that looks
// like it's coming from a bot, which is true of these tests).
const String primaryUrl = 'https://flutter.dev/';
const String secondaryUrl = 'https://www.google.com/robots.txt';
final HttpServer server = await HttpServer.bind(InternetAddress.anyIPv4, 0);
server.forEach((HttpRequest request) {
if (request.uri.path == '/hello.txt') {
request.response.writeln('Hello, world.');
} else {
fail('unexpected request: ${request.method} ${request.uri}');
}
request.response.close();
});
final String prefixUrl = 'http://${server.address.address}:${server.port}';
final String primaryUrl = '$prefixUrl/hello.txt';

testWidgets('loadRequest', (WidgetTester tester) async {
final WebWebViewController controller =
WebWebViewController(const PlatformWebViewControllerCreationParams())
..loadRequest(
LoadRequestParams(uri: Uri.parse(primaryUrl)),
);

testWidgets('initialUrl', (WidgetTester tester) async {
final Completer<WebViewController> controllerCompleter =
Completer<WebViewController>();
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: WebView(
key: GlobalKey(),
initialUrl: primaryUrl,
onWebViewCreated: (WebViewController controller) {
controllerCompleter.complete(controller);
},
),
child: Builder(builder: (BuildContext context) {
return WebWebViewWidget(
PlatformWebViewWidgetCreationParams(controller: controller),
).build(context);
}),
),
);
await controllerCompleter.future;

// Assert an iframe has been rendered to the DOM with the correct src attribute.
final html.IFrameElement? element =
Expand All @@ -45,28 +52,31 @@ void main() {
expect(element!.src, primaryUrl);
});

testWidgets('loadUrl', (WidgetTester tester) async {
final Completer<WebViewController> controllerCompleter =
Completer<WebViewController>();
testWidgets('loadHtmlString', (WidgetTester tester) async {
final WebWebViewController controller =
WebWebViewController(const PlatformWebViewControllerCreationParams())
..loadHtmlString(
'data:text/html;charset=utf-8,${Uri.encodeFull('test html')}',
);

await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: WebView(
key: GlobalKey(),
initialUrl: primaryUrl,
onWebViewCreated: (WebViewController controller) {
controllerCompleter.complete(controller);
},
),
child: Builder(builder: (BuildContext context) {
return WebWebViewWidget(
PlatformWebViewWidgetCreationParams(controller: controller),
).build(context);
}),
),
);
final WebViewController controller = await controllerCompleter.future;
await controller.loadUrl(secondaryUrl);

// Assert an iframe has been rendered to the DOM with the correct src attribute.
final html.IFrameElement? element =
html.document.querySelector('iframe') as html.IFrameElement?;
expect(element, isNotNull);
expect(element!.src, secondaryUrl);
expect(
element!.src,
'data:text/html;charset=utf-8,data:text/html;charset=utf-8,test%2520html',
);
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
import 'dart:async';

import 'package:flutter/material.dart';
import 'package:webview_flutter_platform_interface/webview_flutter_platform_interface.dart';
import 'package:webview_flutter_web/webview_flutter_web.dart';
// ignore: implementation_imports
import 'package:webview_flutter_platform_interface/src/webview_flutter_platform_interface_legacy.dart';
// ignore: implementation_imports
import 'package:webview_flutter_web/src/webview_flutter_web_legacy.dart';

/// Optional callback invoked when a web view is first created. [controller] is
/// the [WebViewController] for the created web view.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import 'dart:async';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:webview_flutter_platform_interface/webview_flutter_platform_interface.dart';

import 'web_view.dart';
import 'package:webview_flutter_web/webview_flutter_web.dart';

void main() {
WebViewPlatform.instance = WebWebViewPlatform();
runApp(const MaterialApp(home: _WebViewExample()));
}

Expand All @@ -23,24 +23,26 @@ class _WebViewExample extends StatefulWidget {
}

class _WebViewExampleState extends State<_WebViewExample> {
final Completer<WebViewController> _controller =
Completer<WebViewController>();
final PlatformWebViewController _controller = PlatformWebViewController(
const PlatformWebViewControllerCreationParams(),
)..loadRequest(
LoadRequestParams(
uri: Uri.parse('https://flutter.dev'),
),
);

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter WebView example'),
actions: <Widget>[
_SampleMenu(_controller.future),
_SampleMenu(_controller),
],
),
body: WebView(
initialUrl: 'https://flutter.dev',
onWebViewCreated: (WebViewController controller) {
_controller.complete(controller);
},
),
body: PlatformWebViewWidget(
PlatformWebViewWidgetCreationParams(controller: _controller),
).build(context),
);
}
}
Expand All @@ -52,41 +54,37 @@ enum _MenuOptions {
class _SampleMenu extends StatelessWidget {
const _SampleMenu(this.controller);

final Future<WebViewController> controller;
final PlatformWebViewController controller;

@override
Widget build(BuildContext context) {
return FutureBuilder<WebViewController>(
future: controller,
builder:
(BuildContext context, AsyncSnapshot<WebViewController> controller) {
return PopupMenuButton<_MenuOptions>(
onSelected: (_MenuOptions value) {
switch (value) {
case _MenuOptions.doPostRequest:
_onDoPostRequest(controller.data!, context);
break;
}
},
itemBuilder: (BuildContext context) => <PopupMenuItem<_MenuOptions>>[
const PopupMenuItem<_MenuOptions>(
value: _MenuOptions.doPostRequest,
child: Text('Post Request'),
),
],
);
return PopupMenuButton<_MenuOptions>(
onSelected: (_MenuOptions value) {
switch (value) {
case _MenuOptions.doPostRequest:
_onDoPostRequest(controller);
break;
}
},
itemBuilder: (BuildContext context) => <PopupMenuItem<_MenuOptions>>[
const PopupMenuItem<_MenuOptions>(
value: _MenuOptions.doPostRequest,
child: Text('Post Request'),
),
],
);
}

Future<void> _onDoPostRequest(
WebViewController controller, BuildContext context) async {
final WebViewRequest request = WebViewRequest(
Future<void> _onDoPostRequest(PlatformWebViewController controller) async {
final LoadRequestParams params = LoadRequestParams(
uri: Uri.parse('https://httpbin.org/post'),
method: WebViewRequestMethod.post,
headers: <String, String>{'foo': 'bar', 'Content-Type': 'text/plain'},
method: LoadRequestMethod.post,
headers: const <String, String>{
'foo': 'bar',
'Content-Type': 'text/plain'
},
body: Uint8List.fromList('Test Body'.codeUnits),
);
await controller.loadRequest(request);
await controller.loadRequest(params);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ dependencies:
sdk: flutter
flutter_web_plugins:
sdk: flutter
webview_flutter_platform_interface: ^1.8.0
webview_flutter_platform_interface: ^2.0.0
webview_flutter_web:
# When depending on this package from a real application you should use:
# webview_flutter_web: ^x.y.z
Expand Down
Loading