-
Notifications
You must be signed in to change notification settings - Fork 3.6k
[webview_flutter_wkwebview] Add javascript panel interface for wkwebview #5795
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
1923b69
aebf948
d062b10
f7ea3a1
4222646
c480a66
714a0eb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -108,6 +108,38 @@ const String kLogExamplePage = ''' | |
| </html> | ||
| '''; | ||
|
|
||
| const String kAlertTestPage = ''' | ||
| <!DOCTYPE html> | ||
| <html> | ||
| <head> | ||
| <script type = "text/javascript"> | ||
| function showAlert(text) { | ||
| alert(text); | ||
| } | ||
|
|
||
| function showConfirm(text) { | ||
| var result = confirm(text); | ||
| alert(result); | ||
| } | ||
|
|
||
| function showPrompt(text, defaultText) { | ||
| var inputString = prompt('Enter input', 'Default text'); | ||
| alert(inputString); | ||
| } | ||
| </script> | ||
| </head> | ||
|
|
||
| <body> | ||
| <p> Click the following button to see the effect </p> | ||
| <form> | ||
| <input type = "button" value = "Alert" onclick = "showAlert('Test Alert');" /> | ||
| <input type = "button" value = "Confirm" onclick = "showConfirm('Test Confirm');" /> | ||
| <input type = "button" value = "Prompt" onclick = "showPrompt('Test Prompt', 'Default Value');" /> | ||
| </form> | ||
| </body> | ||
| </html> | ||
| '''; | ||
|
|
||
| class WebViewExample extends StatefulWidget { | ||
| const WebViewExample({super.key, this.cookieManager}); | ||
|
|
||
|
|
@@ -297,6 +329,7 @@ enum MenuOptions { | |
| setCookie, | ||
| logExample, | ||
| basicAuthentication, | ||
| javaScriptAlert, | ||
| } | ||
|
|
||
| class SampleMenu extends StatelessWidget { | ||
|
|
@@ -348,6 +381,8 @@ class SampleMenu extends StatelessWidget { | |
| _onLogExample(); | ||
| case MenuOptions.basicAuthentication: | ||
| _promptForUrl(context); | ||
| case MenuOptions.javaScriptAlert: | ||
| _onJavaScriptAlertExample(context); | ||
| } | ||
| }, | ||
| itemBuilder: (BuildContext context) => <PopupMenuItem<MenuOptions>>[ | ||
|
|
@@ -412,6 +447,10 @@ class SampleMenu extends StatelessWidget { | |
| value: MenuOptions.basicAuthentication, | ||
| child: Text('Basic Authentication Example'), | ||
| ), | ||
| const PopupMenuItem<MenuOptions>( | ||
| value: MenuOptions.javaScriptAlert, | ||
| child: Text('JavaScript Alert Example'), | ||
| ), | ||
| ], | ||
| ); | ||
| } | ||
|
|
@@ -536,6 +575,28 @@ class SampleMenu extends StatelessWidget { | |
| return webViewController.loadHtmlString(kTransparentBackgroundPage); | ||
| } | ||
|
|
||
| Future<void> _onJavaScriptAlertExample(BuildContext context) { | ||
| webViewController.setOnJavaScriptAlertDialog( | ||
| (JavaScriptAlertDialogRequest request) async { | ||
| await _showAlert(context, request.message); | ||
| }); | ||
|
|
||
| webViewController.setOnJavaScriptConfirmDialog( | ||
| (JavaScriptConfirmDialogRequest request) async { | ||
| final bool result = await _showConfirm(context, request.message); | ||
| return result; | ||
| }); | ||
|
|
||
| webViewController.setOnJavaScriptTextInputDialog( | ||
| (JavaScriptTextInputDialogRequest request) async { | ||
| final String result = | ||
| await _showTextInput(context, request.message, request.defaultText); | ||
| return result; | ||
| }); | ||
|
|
||
| return webViewController.loadHtmlString(kAlertTestPage); | ||
| } | ||
|
|
||
| Widget _getCookieList(String cookies) { | ||
| if (cookies == '""') { | ||
| return Container(); | ||
|
|
@@ -605,6 +666,67 @@ class SampleMenu extends StatelessWidget { | |
| }, | ||
| ); | ||
| } | ||
|
|
||
| Future<void> _showAlert(BuildContext context, String message) async { | ||
| return showDialog<void>( | ||
| context: context, | ||
| builder: (BuildContext ctx) { | ||
| return AlertDialog( | ||
| content: Text(message), | ||
| actions: <Widget>[ | ||
| TextButton( | ||
| onPressed: () { | ||
| Navigator.of(ctx).pop(); | ||
| }, | ||
| child: const Text('OK')) | ||
| ], | ||
| ); | ||
| }); | ||
| } | ||
|
|
||
| Future<bool> _showConfirm(BuildContext context, String message) async { | ||
| final dynamic result = await showDialog<bool>( | ||
| context: context, | ||
| builder: (BuildContext ctx) { | ||
| return AlertDialog( | ||
| content: Text(message), | ||
| actions: <Widget>[ | ||
| TextButton( | ||
| onPressed: () { | ||
| Navigator.of(ctx).pop(false); | ||
| }, | ||
| child: const Text('Cancel')), | ||
| TextButton( | ||
| onPressed: () { | ||
| Navigator.of(ctx).pop(true); | ||
| }, | ||
| child: const Text('OK')), | ||
| ], | ||
| ); | ||
| }); | ||
|
|
||
| return result.runtimeType == bool && result as bool; | ||
| } | ||
|
|
||
| Future<String> _showTextInput( | ||
| BuildContext context, String message, String? defaultText) async { | ||
| final dynamic result = await showDialog<String>( | ||
| context: context, | ||
| builder: (BuildContext ctx) { | ||
| return AlertDialog( | ||
| content: Text(message), | ||
| actions: <Widget>[ | ||
| TextButton( | ||
| onPressed: () { | ||
| Navigator.of(ctx).pop('Text test'); | ||
| }, | ||
| child: const Text('Enter')), | ||
| ], | ||
| ); | ||
| }); | ||
|
|
||
| return result.runtimeType == String ? result as String : ''; | ||
|
||
| } | ||
| } | ||
|
|
||
| class NavigationControls extends StatelessWidget { | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -167,7 +167,7 @@ WKAudiovisualMediaTypes FWFNativeWKAudiovisualMediaTypeFromEnumData( | |||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| FWFNSUrlRequestData *FWFNSUrlRequestDataFromNativeNSURLRequest(NSURLRequest *request) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return [FWFNSUrlRequestData | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| makeWithUrl:request.URL.absoluteString | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| makeWithUrl:request.URL.absoluteString.length > 0 ? request.URL.absoluteString : @"" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| testWidgets('target _blank opens in same window', | |
| (WidgetTester tester) async { | |
| final Completer<WebViewController> controllerCompleter = | |
| Completer<WebViewController>(); | |
| final Completer<void> pageLoaded = Completer<void>(); | |
| await tester.pumpWidget( | |
| Directionality( | |
| textDirection: TextDirection.ltr, | |
| child: WebView( | |
| key: GlobalKey(), | |
| onWebViewCreated: (WebViewController controller) { | |
| controllerCompleter.complete(controller); | |
| }, | |
| javascriptMode: JavascriptMode.unrestricted, | |
| onPageFinished: (String url) { | |
| pageLoaded.complete(null); | |
| }, | |
| ), | |
| ), | |
| ); | |
| final WebViewController controller = await controllerCompleter.future; | |
| await controller.runJavascript('window.open("$primaryUrl", "_blank")'); | |
| await pageLoaded.future; | |
| final String? currentUrl = await controller.currentUrl(); | |
| expect(currentUrl, primaryUrl); | |
| }); |
@hellohuanlin
It can be nil with this test case.
I updated code to nil check.
Thanks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this would be easier to read as
result is bool ? result : false.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bparrishMines I just remove the result of dynamic type on aebf948