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

Commit ca974ab

Browse files
[webview_flutter_web] Copies web implementation of webview_flutter from v4_webview (#6854)
* v4 web impl * add breaking change * fix lints * exclude web plugin
1 parent 5f62d21 commit ca974ab

22 files changed

+1136
-381
lines changed

packages/webview_flutter/webview_flutter_web/CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
## NEXT
1+
## 0.2.0
22

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

57
## 0.1.0+4

packages/webview_flutter/webview_flutter_web/README.md

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,8 @@ This is an implementation of the [`webview_flutter`](https://pub.dev/packages/we
55
It is currently severely limited and doesn't implement most of the available functionality.
66
The following functionality is currently available:
77

8-
- `loadUrl` (Without headers)
9-
- `requestUrl`
10-
- `loadHTMLString` (Without `baseUrl`)
11-
- Setting the `initialUrl` through `CreationParams`.
8+
- `loadRequest`
9+
- `loadHtmlString` (Without `baseUrl`)
1210

1311
Nothing else is currently supported.
1412

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

2624
Once those steps below are complete, the APIs from `webview_flutter` listed
@@ -39,7 +37,7 @@ import 'package:webview_flutter/webview_flutter.dart';
3937
import 'package:webview_flutter_web/webview_flutter_web.dart';
4038
4139
main() {
42-
WebView.platform = WebWebViewPlatform();
40+
WebViewPlatform.instance = WebWebViewPlatform();
4341
...
4442
```
4543

@@ -55,7 +53,7 @@ import 'package:webview_flutter/webview_flutter.dart';
5553
import 'package:webview_flutter_web/webview_flutter_web.dart';
5654
5755
void registerWebViewWebImplementation() {
58-
WebView.platform = WebWebViewPlatform();
56+
WebViewPlatform.instance = WebWebViewPlatform();
5957
}
6058
```
6159

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'dart:async';
6+
import 'dart:html' as html;
7+
8+
import 'package:flutter/material.dart';
9+
import 'package:flutter/widgets.dart';
10+
import 'package:flutter_test/flutter_test.dart';
11+
import 'package:integration_test/integration_test.dart';
12+
import 'package:webview_flutter_web_example/legacy/web_view.dart';
13+
14+
void main() {
15+
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
16+
17+
// URLs to navigate to in tests. These need to be URLs that we are confident will
18+
// always be accessible, and won't do redirection. (E.g., just
19+
// 'https://www.google.com/' will sometimes redirect traffic that looks
20+
// like it's coming from a bot, which is true of these tests).
21+
const String primaryUrl = 'https://flutter.dev/';
22+
const String secondaryUrl = 'https://www.google.com/robots.txt';
23+
24+
testWidgets('initialUrl', (WidgetTester tester) async {
25+
final Completer<WebViewController> controllerCompleter =
26+
Completer<WebViewController>();
27+
await tester.pumpWidget(
28+
Directionality(
29+
textDirection: TextDirection.ltr,
30+
child: WebView(
31+
key: GlobalKey(),
32+
initialUrl: primaryUrl,
33+
onWebViewCreated: (WebViewController controller) {
34+
controllerCompleter.complete(controller);
35+
},
36+
),
37+
),
38+
);
39+
await controllerCompleter.future;
40+
41+
// Assert an iframe has been rendered to the DOM with the correct src attribute.
42+
final html.IFrameElement? element =
43+
html.document.querySelector('iframe') as html.IFrameElement?;
44+
expect(element, isNotNull);
45+
expect(element!.src, primaryUrl);
46+
});
47+
48+
testWidgets('loadUrl', (WidgetTester tester) async {
49+
final Completer<WebViewController> controllerCompleter =
50+
Completer<WebViewController>();
51+
await tester.pumpWidget(
52+
Directionality(
53+
textDirection: TextDirection.ltr,
54+
child: WebView(
55+
key: GlobalKey(),
56+
initialUrl: primaryUrl,
57+
onWebViewCreated: (WebViewController controller) {
58+
controllerCompleter.complete(controller);
59+
},
60+
),
61+
),
62+
);
63+
final WebViewController controller = await controllerCompleter.future;
64+
await controller.loadUrl(secondaryUrl);
65+
66+
// Assert an iframe has been rendered to the DOM with the correct src attribute.
67+
final html.IFrameElement? element =
68+
html.document.querySelector('iframe') as html.IFrameElement?;
69+
expect(element, isNotNull);
70+
expect(element!.src, secondaryUrl);
71+
});
72+
}

packages/webview_flutter/webview_flutter_web/example/integration_test/webview_flutter_test.dart

Lines changed: 43 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,41 +2,48 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
import 'dart:async';
65
import 'dart:html' as html;
6+
import 'dart:io';
77

88
import 'package:flutter/material.dart';
99
import 'package:flutter/widgets.dart';
1010
import 'package:flutter_test/flutter_test.dart';
1111
import 'package:integration_test/integration_test.dart';
12-
import 'package:webview_flutter_web_example/web_view.dart';
12+
import 'package:webview_flutter_platform_interface/webview_flutter_platform_interface.dart';
13+
import 'package:webview_flutter_web/webview_flutter_web.dart';
1314

14-
void main() {
15+
Future<void> main() async {
1516
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
1617

17-
// URLs to navigate to in tests. These need to be URLs that we are confident will
18-
// always be accessible, and won't do redirection. (E.g., just
19-
// 'https://www.google.com/' will sometimes redirect traffic that looks
20-
// like it's coming from a bot, which is true of these tests).
21-
const String primaryUrl = 'https://flutter.dev/';
22-
const String secondaryUrl = 'https://www.google.com/robots.txt';
18+
final HttpServer server = await HttpServer.bind(InternetAddress.anyIPv4, 0);
19+
server.forEach((HttpRequest request) {
20+
if (request.uri.path == '/hello.txt') {
21+
request.response.writeln('Hello, world.');
22+
} else {
23+
fail('unexpected request: ${request.method} ${request.uri}');
24+
}
25+
request.response.close();
26+
});
27+
final String prefixUrl = 'http://${server.address.address}:${server.port}';
28+
final String primaryUrl = '$prefixUrl/hello.txt';
29+
30+
testWidgets('loadRequest', (WidgetTester tester) async {
31+
final WebWebViewController controller =
32+
WebWebViewController(const PlatformWebViewControllerCreationParams())
33+
..loadRequest(
34+
LoadRequestParams(uri: Uri.parse(primaryUrl)),
35+
);
2336

24-
testWidgets('initialUrl', (WidgetTester tester) async {
25-
final Completer<WebViewController> controllerCompleter =
26-
Completer<WebViewController>();
2737
await tester.pumpWidget(
2838
Directionality(
2939
textDirection: TextDirection.ltr,
30-
child: WebView(
31-
key: GlobalKey(),
32-
initialUrl: primaryUrl,
33-
onWebViewCreated: (WebViewController controller) {
34-
controllerCompleter.complete(controller);
35-
},
36-
),
40+
child: Builder(builder: (BuildContext context) {
41+
return WebWebViewWidget(
42+
PlatformWebViewWidgetCreationParams(controller: controller),
43+
).build(context);
44+
}),
3745
),
3846
);
39-
await controllerCompleter.future;
4047

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

48-
testWidgets('loadUrl', (WidgetTester tester) async {
49-
final Completer<WebViewController> controllerCompleter =
50-
Completer<WebViewController>();
55+
testWidgets('loadHtmlString', (WidgetTester tester) async {
56+
final WebWebViewController controller =
57+
WebWebViewController(const PlatformWebViewControllerCreationParams())
58+
..loadHtmlString(
59+
'data:text/html;charset=utf-8,${Uri.encodeFull('test html')}',
60+
);
61+
5162
await tester.pumpWidget(
5263
Directionality(
5364
textDirection: TextDirection.ltr,
54-
child: WebView(
55-
key: GlobalKey(),
56-
initialUrl: primaryUrl,
57-
onWebViewCreated: (WebViewController controller) {
58-
controllerCompleter.complete(controller);
59-
},
60-
),
65+
child: Builder(builder: (BuildContext context) {
66+
return WebWebViewWidget(
67+
PlatformWebViewWidgetCreationParams(controller: controller),
68+
).build(context);
69+
}),
6170
),
6271
);
63-
final WebViewController controller = await controllerCompleter.future;
64-
await controller.loadUrl(secondaryUrl);
6572

6673
// Assert an iframe has been rendered to the DOM with the correct src attribute.
6774
final html.IFrameElement? element =
6875
html.document.querySelector('iframe') as html.IFrameElement?;
6976
expect(element, isNotNull);
70-
expect(element!.src, secondaryUrl);
77+
expect(
78+
element!.src,
79+
'data:text/html;charset=utf-8,data:text/html;charset=utf-8,test%2520html',
80+
);
7181
});
7282
}

packages/webview_flutter/webview_flutter_web/example/lib/web_view.dart renamed to packages/webview_flutter/webview_flutter_web/example/lib/legacy/web_view.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
import 'dart:async';
66

77
import 'package:flutter/material.dart';
8-
import 'package:webview_flutter_platform_interface/webview_flutter_platform_interface.dart';
9-
import 'package:webview_flutter_web/webview_flutter_web.dart';
8+
// ignore: implementation_imports
9+
import 'package:webview_flutter_platform_interface/src/webview_flutter_platform_interface_legacy.dart';
10+
// ignore: implementation_imports
11+
import 'package:webview_flutter_web/src/webview_flutter_web_legacy.dart';
1012

1113
/// Optional callback invoked when a web view is first created. [controller] is
1214
/// the [WebViewController] for the created web view.

packages/webview_flutter/webview_flutter_web/example/lib/main.dart

Lines changed: 35 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ import 'dart:async';
88
import 'dart:typed_data';
99
import 'package:flutter/material.dart';
1010
import 'package:webview_flutter_platform_interface/webview_flutter_platform_interface.dart';
11-
12-
import 'web_view.dart';
11+
import 'package:webview_flutter_web/webview_flutter_web.dart';
1312

1413
void main() {
14+
WebViewPlatform.instance = WebWebViewPlatform();
1515
runApp(const MaterialApp(home: _WebViewExample()));
1616
}
1717

@@ -23,24 +23,26 @@ class _WebViewExample extends StatefulWidget {
2323
}
2424

2525
class _WebViewExampleState extends State<_WebViewExample> {
26-
final Completer<WebViewController> _controller =
27-
Completer<WebViewController>();
26+
final PlatformWebViewController _controller = PlatformWebViewController(
27+
const PlatformWebViewControllerCreationParams(),
28+
)..loadRequest(
29+
LoadRequestParams(
30+
uri: Uri.parse('https://flutter.dev'),
31+
),
32+
);
2833

2934
@override
3035
Widget build(BuildContext context) {
3136
return Scaffold(
3237
appBar: AppBar(
3338
title: const Text('Flutter WebView example'),
3439
actions: <Widget>[
35-
_SampleMenu(_controller.future),
40+
_SampleMenu(_controller),
3641
],
3742
),
38-
body: WebView(
39-
initialUrl: 'https://flutter.dev',
40-
onWebViewCreated: (WebViewController controller) {
41-
_controller.complete(controller);
42-
},
43-
),
43+
body: PlatformWebViewWidget(
44+
PlatformWebViewWidgetCreationParams(controller: _controller),
45+
).build(context),
4446
);
4547
}
4648
}
@@ -52,41 +54,37 @@ enum _MenuOptions {
5254
class _SampleMenu extends StatelessWidget {
5355
const _SampleMenu(this.controller);
5456

55-
final Future<WebViewController> controller;
57+
final PlatformWebViewController controller;
5658

5759
@override
5860
Widget build(BuildContext context) {
59-
return FutureBuilder<WebViewController>(
60-
future: controller,
61-
builder:
62-
(BuildContext context, AsyncSnapshot<WebViewController> controller) {
63-
return PopupMenuButton<_MenuOptions>(
64-
onSelected: (_MenuOptions value) {
65-
switch (value) {
66-
case _MenuOptions.doPostRequest:
67-
_onDoPostRequest(controller.data!, context);
68-
break;
69-
}
70-
},
71-
itemBuilder: (BuildContext context) => <PopupMenuItem<_MenuOptions>>[
72-
const PopupMenuItem<_MenuOptions>(
73-
value: _MenuOptions.doPostRequest,
74-
child: Text('Post Request'),
75-
),
76-
],
77-
);
61+
return PopupMenuButton<_MenuOptions>(
62+
onSelected: (_MenuOptions value) {
63+
switch (value) {
64+
case _MenuOptions.doPostRequest:
65+
_onDoPostRequest(controller);
66+
break;
67+
}
7868
},
69+
itemBuilder: (BuildContext context) => <PopupMenuItem<_MenuOptions>>[
70+
const PopupMenuItem<_MenuOptions>(
71+
value: _MenuOptions.doPostRequest,
72+
child: Text('Post Request'),
73+
),
74+
],
7975
);
8076
}
8177

82-
Future<void> _onDoPostRequest(
83-
WebViewController controller, BuildContext context) async {
84-
final WebViewRequest request = WebViewRequest(
78+
Future<void> _onDoPostRequest(PlatformWebViewController controller) async {
79+
final LoadRequestParams params = LoadRequestParams(
8580
uri: Uri.parse('https://httpbin.org/post'),
86-
method: WebViewRequestMethod.post,
87-
headers: <String, String>{'foo': 'bar', 'Content-Type': 'text/plain'},
81+
method: LoadRequestMethod.post,
82+
headers: const <String, String>{
83+
'foo': 'bar',
84+
'Content-Type': 'text/plain'
85+
},
8886
body: Uint8List.fromList('Test Body'.codeUnits),
8987
);
90-
await controller.loadRequest(request);
88+
await controller.loadRequest(params);
9189
}
9290
}

packages/webview_flutter/webview_flutter_web/example/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ dependencies:
1010
sdk: flutter
1111
flutter_web_plugins:
1212
sdk: flutter
13-
webview_flutter_platform_interface: ^1.8.0
13+
webview_flutter_platform_interface: ^2.0.0
1414
webview_flutter_web:
1515
# When depending on this package from a real application you should use:
1616
# webview_flutter_web: ^x.y.z

0 commit comments

Comments
 (0)