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

Commit d6ca8a3

Browse files
authored
[webview_flutter] Deprecate evaluateJavascript in favour of runJavaScript and runJavaScriptForResult. (#4403)
1 parent e39a584 commit d6ca8a3

File tree

6 files changed

+213
-57
lines changed

6 files changed

+213
-57
lines changed

packages/webview_flutter/webview_flutter/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## 2.2.0
2+
3+
* Added `runJavascript` and `runJavascriptForResult` to supersede `evaluateJavascript`.
4+
* Deprecated `evaluateJavascript`.
5+
16
## 2.1.2
27

38
* Fix typos in the README.

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

Lines changed: 60 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,28 @@ void main() {
7070
expect(currentUrl, secondaryUrl);
7171
}, skip: _skipDueToIssue86757);
7272

73+
testWidgets('evaluateJavascript', (WidgetTester tester) async {
74+
final Completer<WebViewController> controllerCompleter =
75+
Completer<WebViewController>();
76+
await tester.pumpWidget(
77+
Directionality(
78+
textDirection: TextDirection.ltr,
79+
child: WebView(
80+
key: GlobalKey(),
81+
initialUrl: primaryUrl,
82+
onWebViewCreated: (WebViewController controller) {
83+
controllerCompleter.complete(controller);
84+
},
85+
javascriptMode: JavascriptMode.unrestricted,
86+
),
87+
),
88+
);
89+
final WebViewController controller = await controllerCompleter.future;
90+
// ignore: deprecated_member_use
91+
final String result = await controller.evaluateJavascript('1 + 1');
92+
expect(result, equals('2'));
93+
});
94+
7395
// TODO(bparrishMines): skipped due to https://github.com/flutter/flutter/issues/86757.
7496
testWidgets('loadUrl with headers', (WidgetTester tester) async {
7597
final Completer<WebViewController> controllerCompleter =
@@ -108,12 +130,12 @@ void main() {
108130
await pageLoads.stream.firstWhere((String url) => url == currentUrl);
109131

110132
final String content = await controller
111-
.evaluateJavascript('document.documentElement.innerText');
133+
.runJavascriptReturningResult('document.documentElement.innerText');
112134
expect(content.contains('flutter_test_header'), isTrue);
113135
}, skip: Platform.isAndroid && _skipDueToIssue86757);
114136

115137
// TODO(bparrishMines): skipped due to https://github.com/flutter/flutter/issues/86757.
116-
testWidgets('JavaScriptChannel', (WidgetTester tester) async {
138+
testWidgets('JavascriptChannel', (WidgetTester tester) async {
117139
final Completer<WebViewController> controllerCompleter =
118140
Completer<WebViewController>();
119141
final Completer<void> pageStarted = Completer<void>();
@@ -153,11 +175,7 @@ void main() {
153175
await pageLoaded.future;
154176

155177
expect(messagesReceived, isEmpty);
156-
// Append a return value "1" in the end will prevent an iOS platform exception.
157-
// See: https://github.com/flutter/flutter/issues/66318#issuecomment-701105380
158-
// TODO(cyanglaz): remove the workaround "1" in the end when the below issue is fixed.
159-
// https://github.com/flutter/flutter/issues/66318
160-
await controller.evaluateJavascript('Echo.postMessage("hello");1;');
178+
await controller.runJavascript('Echo.postMessage("hello");');
161179
expect(messagesReceived, equals(<String>['hello']));
162180
}, skip: Platform.isAndroid && _skipDueToIssue86757);
163181

@@ -404,7 +422,8 @@ void main() {
404422
WebViewController controller = await controllerCompleter.future;
405423
await pageLoaded.future;
406424

407-
String isPaused = await controller.evaluateJavascript('isPaused();');
425+
String isPaused =
426+
await controller.runJavascriptReturningResult('isPaused();');
408427
expect(isPaused, _webviewBool(false));
409428

410429
controllerCompleter = Completer<WebViewController>();
@@ -433,7 +452,7 @@ void main() {
433452
controller = await controllerCompleter.future;
434453
await pageLoaded.future;
435454

436-
isPaused = await controller.evaluateJavascript('isPaused();');
455+
isPaused = await controller.runJavascriptReturningResult('isPaused();');
437456
expect(isPaused, _webviewBool(true));
438457
});
439458

@@ -464,7 +483,8 @@ void main() {
464483
final WebViewController controller = await controllerCompleter.future;
465484
await pageLoaded.future;
466485

467-
String isPaused = await controller.evaluateJavascript('isPaused();');
486+
String isPaused =
487+
await controller.runJavascriptReturningResult('isPaused();');
468488
expect(isPaused, _webviewBool(false));
469489

470490
pageLoaded = Completer<void>();
@@ -492,7 +512,7 @@ void main() {
492512

493513
await pageLoaded.future;
494514

495-
isPaused = await controller.evaluateJavascript('isPaused();');
515+
isPaused = await controller.runJavascriptReturningResult('isPaused();');
496516
expect(isPaused, _webviewBool(false));
497517
});
498518

@@ -542,7 +562,7 @@ void main() {
542562
await videoPlaying.future;
543563

544564
String fullScreen =
545-
await controller.evaluateJavascript('isFullScreen();');
565+
await controller.runJavascriptReturningResult('isFullScreen();');
546566
expect(fullScreen, _webviewBool(false));
547567
});
548568

@@ -594,7 +614,7 @@ void main() {
594614
await videoPlaying.future;
595615

596616
String fullScreen =
597-
await controller.evaluateJavascript('isFullScreen();');
617+
await controller.runJavascriptReturningResult('isFullScreen();');
598618
expect(fullScreen, _webviewBool(true));
599619
}, skip: Platform.isAndroid);
600620
});
@@ -660,7 +680,8 @@ void main() {
660680
await pageStarted.future;
661681
await pageLoaded.future;
662682

663-
String isPaused = await controller.evaluateJavascript('isPaused();');
683+
String isPaused =
684+
await controller.runJavascriptReturningResult('isPaused();');
664685
expect(isPaused, _webviewBool(false));
665686

666687
controllerCompleter = Completer<WebViewController>();
@@ -694,7 +715,7 @@ void main() {
694715
await pageStarted.future;
695716
await pageLoaded.future;
696717

697-
isPaused = await controller.evaluateJavascript('isPaused();');
718+
isPaused = await controller.runJavascriptReturningResult('isPaused();');
698719
expect(isPaused, _webviewBool(true));
699720
});
700721

@@ -730,7 +751,8 @@ void main() {
730751
await pageStarted.future;
731752
await pageLoaded.future;
732753

733-
String isPaused = await controller.evaluateJavascript('isPaused();');
754+
String isPaused =
755+
await controller.runJavascriptReturningResult('isPaused();');
734756
expect(isPaused, _webviewBool(false));
735757

736758
pageStarted = Completer<void>();
@@ -763,7 +785,7 @@ void main() {
763785
await pageStarted.future;
764786
await pageLoaded.future;
765787

766-
isPaused = await controller.evaluateJavascript('isPaused();');
788+
isPaused = await controller.runJavascriptReturningResult('isPaused();');
767789
expect(isPaused, _webviewBool(false));
768790
});
769791
});
@@ -1028,15 +1050,16 @@ void main() {
10281050

10291051
final WebViewController controller = await controllerCompleter.future;
10301052
await pageLoaded.future;
1031-
final String viewportRectJSON = await _evaluateJavascript(
1053+
final String viewportRectJSON = await _runJavascriptReturningResult(
10321054
controller, 'JSON.stringify(viewport.getBoundingClientRect())');
10331055
final Map<String, dynamic> viewportRectRelativeToViewport =
10341056
jsonDecode(viewportRectJSON);
10351057

10361058
// Check that the input is originally outside of the viewport.
10371059

1038-
final String initialInputClientRectJSON = await _evaluateJavascript(
1039-
controller, 'JSON.stringify(inputEl.getBoundingClientRect())');
1060+
final String initialInputClientRectJSON =
1061+
await _runJavascriptReturningResult(
1062+
controller, 'JSON.stringify(inputEl.getBoundingClientRect())');
10401063
final Map<String, dynamic> initialInputClientRectRelativeToViewport =
10411064
jsonDecode(initialInputClientRectJSON);
10421065

@@ -1045,12 +1068,13 @@ void main() {
10451068
viewportRectRelativeToViewport['bottom'],
10461069
isFalse);
10471070

1048-
await controller.evaluateJavascript('inputEl.focus()');
1071+
await controller.runJavascript('inputEl.focus()');
10491072

10501073
// Check that focusing the input brought it into view.
10511074

1052-
final String lastInputClientRectJSON = await _evaluateJavascript(
1053-
controller, 'JSON.stringify(inputEl.getBoundingClientRect())');
1075+
final String lastInputClientRectJSON =
1076+
await _runJavascriptReturningResult(
1077+
controller, 'JSON.stringify(inputEl.getBoundingClientRect())');
10541078
final Map<String, dynamic> lastInputClientRectRelativeToViewport =
10551079
jsonDecode(lastInputClientRectJSON);
10561080

@@ -1106,7 +1130,7 @@ void main() {
11061130

11071131
await pageLoads.stream.first; // Wait for initial page load.
11081132
final WebViewController controller = await controllerCompleter.future;
1109-
await controller.evaluateJavascript('location.href = "$secondaryUrl"');
1133+
await controller.runJavascript('location.href = "$secondaryUrl"');
11101134

11111135
await pageLoads.stream.first; // Wait for the next page load.
11121136
final String? currentUrl = await controller.currentUrl();
@@ -1237,7 +1261,7 @@ void main() {
12371261
await pageLoads.stream.first; // Wait for initial page load.
12381262
final WebViewController controller = await controllerCompleter.future;
12391263
await controller
1240-
.evaluateJavascript('location.href = "https://www.youtube.com/"');
1264+
.runJavascript('location.href = "https://www.youtube.com/"');
12411265

12421266
// There should never be any second page load, since our new URL is
12431267
// blocked. Still wait for a potential page change for some time in order
@@ -1277,7 +1301,7 @@ void main() {
12771301

12781302
await pageLoads.stream.first; // Wait for initial page load.
12791303
final WebViewController controller = await controllerCompleter.future;
1280-
await controller.evaluateJavascript('location.href = "$secondaryUrl"');
1304+
await controller.runJavascript('location.href = "$secondaryUrl"');
12811305

12821306
await pageLoads.stream.first; // Wait for second page to load.
12831307
final String? currentUrl = await controller.currentUrl();
@@ -1332,7 +1356,7 @@ void main() {
13321356
),
13331357
);
13341358
final WebViewController controller = await controllerCompleter.future;
1335-
await controller.evaluateJavascript('window.open("$primaryUrl", "_blank")');
1359+
await controller.runJavascript('window.open("$primaryUrl", "_blank")');
13361360
await pageLoaded.future;
13371361
final String? currentUrl = await controller.currentUrl();
13381362
expect(currentUrl, primaryUrl);
@@ -1368,7 +1392,7 @@ void main() {
13681392
await pageLoaded.future;
13691393
pageLoaded = Completer<void>();
13701394

1371-
await controller.evaluateJavascript('window.open("$secondaryUrl")');
1395+
await controller.runJavascript('window.open("$secondaryUrl")');
13721396
await pageLoaded.future;
13731397
pageLoaded = Completer<void>();
13741398
expect(controller.currentUrl(), completion(secondaryUrl));
@@ -1382,7 +1406,7 @@ void main() {
13821406
);
13831407

13841408
testWidgets(
1385-
'javascript does not run in parent window',
1409+
'JavaScript does not run in parent window',
13861410
(WidgetTester tester) async {
13871411
final String iframe = '''
13881412
<!DOCTYPE html>
@@ -1439,9 +1463,10 @@ void main() {
14391463
final WebViewController controller = await controllerCompleter.future;
14401464
await pageLoadCompleter.future;
14411465

1442-
expect(controller.evaluateJavascript('iframeLoaded'), completion('true'));
1466+
expect(controller.runJavascriptReturningResult('iframeLoaded'),
1467+
completion('true'));
14431468
expect(
1444-
controller.evaluateJavascript(
1469+
controller.runJavascriptReturningResult(
14451470
'document.querySelector("p") && document.querySelector("p").textContent'),
14461471
completion('null'),
14471472
);
@@ -1461,13 +1486,13 @@ String _webviewBool(bool value) {
14611486

14621487
/// Returns the value used for the HTTP User-Agent: request header in subsequent HTTP requests.
14631488
Future<String> _getUserAgent(WebViewController controller) async {
1464-
return _evaluateJavascript(controller, 'navigator.userAgent;');
1489+
return _runJavascriptReturningResult(controller, 'navigator.userAgent;');
14651490
}
14661491

1467-
Future<String> _evaluateJavascript(
1492+
Future<String> _runJavascriptReturningResult(
14681493
WebViewController controller, String js) async {
14691494
if (defaultTargetPlatform == TargetPlatform.iOS) {
1470-
return await controller.evaluateJavascript(js);
1495+
return await controller.runJavascriptReturningResult(js);
14711496
}
1472-
return jsonDecode(await controller.evaluateJavascript(js));
1497+
return jsonDecode(await controller.runJavascriptReturningResult(js));
14731498
}

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -210,14 +210,14 @@ class SampleMenu extends StatelessWidget {
210210
WebViewController controller, BuildContext context) async {
211211
// Send a message with the user agent string to the Toaster JavaScript channel we registered
212212
// with the WebView.
213-
await controller.evaluateJavascript(
213+
await controller.runJavascript(
214214
'Toaster.postMessage("User Agent: " + navigator.userAgent);');
215215
}
216216

217217
void _onListCookies(
218218
WebViewController controller, BuildContext context) async {
219219
final String cookies =
220-
await controller.evaluateJavascript('document.cookie');
220+
await controller.runJavascriptReturningResult('document.cookie');
221221
// ignore: deprecated_member_use
222222
Scaffold.of(context).showSnackBar(SnackBar(
223223
content: Column(
@@ -232,7 +232,7 @@ class SampleMenu extends StatelessWidget {
232232
}
233233

234234
void _onAddToCache(WebViewController controller, BuildContext context) async {
235-
await controller.evaluateJavascript(
235+
await controller.runJavascript(
236236
'caches.open("test_caches_entry"); localStorage["test_localStorage"] = "dummy_entry";');
237237
// ignore: deprecated_member_use
238238
Scaffold.of(context).showSnackBar(const SnackBar(
@@ -241,7 +241,7 @@ class SampleMenu extends StatelessWidget {
241241
}
242242

243243
void _onListCache(WebViewController controller, BuildContext context) async {
244-
await controller.evaluateJavascript('caches.keys()'
244+
await controller.runJavascript('caches.keys()'
245245
'.then((cacheKeys) => JSON.stringify({"cacheKeys" : cacheKeys, "localStorage" : localStorage}))'
246246
'.then((caches) => Toaster.postMessage(caches))');
247247
}

0 commit comments

Comments
 (0)