-
Notifications
You must be signed in to change notification settings - Fork 3.3k
[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
[webview_flutter_wkwebview] Add javascript panel interface for wkwebview #5795
Conversation
9aea83f
to
961f82e
Compare
i remember that i have reviewed a similar PR before. Why are we opening a new PR? Also can you invite the same reviewers that you requested review before, so all previous reviewers have context and make sure their comments are addressed |
Previous PR is #4704 (comment) I don't have the permission to invite other reviewers. I will mention another reviewer to check Thank you. @stuartmorgan @bparrishMines Can you check this PR. Thanks |
961f82e
to
1923b69
Compare
); | ||
}); | ||
|
||
return result.runtimeType == bool && result as bool; |
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
); | ||
}); | ||
|
||
return result.runtimeType == String ? result as String : ''; |
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.
This one could be result is String ? result : ''
.
Although I just realized that the prompt()
dialog can technically return a null String and should provide support for this according to Android docs: https://developer.android.com/reference/android/webkit/WebChromeClient#onJsPrompt(android.webkit.WebView,%20java.lang.String,%20java.lang.String,%20java.lang.String,%20android.webkit.JsPromptResult). I'll actually go ahead and create a PR to update the interface method.
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 agree with your opinion. but one thing I worried that confirm() dialog also should be handle null case with this opinion.
I just thought that dismissing dialog without selection should be false in confirm and empty string in prompt.
But if we handle it as optional null, confirm dialog also return null when we just dismiss dialog.
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.
For confirm()
, I considered the same thing. However, I think canceling the operation is the same as returning false.
prompt()
is slightly different because there could be scenario where a user might want to return an empty string. And this could be considered different from a user that wants to cancel the operation.
completionHandler:^{ | ||
completionHandler(); | ||
}]; |
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 can be simplified to:
completionHandler:^{ | |
completionHandler(); | |
}]; | |
completionHandler:completionHandler]; |
completionHandler:^(BOOL isConfirmed) { | ||
completionHandler(isConfirmed); | ||
}]; |
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.
Same
completionHandler:^(BOOL isConfirmed) { | |
completionHandler(isConfirmed); | |
}]; | |
completionHandler:completionHandler]; |
completionHandler:^(NSString *_Nullable inputMessage) { | ||
completionHandler(inputMessage); | ||
}]; |
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.
Same
completionHandler:^(NSString *_Nullable inputMessage) { | |
completionHandler(inputMessage); | |
}]; | |
completionHandler:completionHandler]; |
packages/webview_flutter/webview_flutter_wkwebview/lib/src/web_kit/web_kit.dart
Show resolved
Hide resolved
b8bc0cf
to
aebf948
Compare
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.
@@ -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 : @"" |
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.
im a bit confused here - will absoluteString ever be nil
? if so, may be less confusing to do nil check rather than length check?
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.
Lines 1124 to 1149 in 83c2c4d
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
frame:FWFWKFrameInfoDataFromNativeWKFrameInfo( | ||
frame) | ||
completion:^(FlutterError *error) { | ||
NSAssert(!error, @"%@", error); |
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.
when will error happen? should we pipe the error to dark side rather than doing assert here?
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.
packages/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFUIDelegateHostApi.m
Lines 34 to 91 in 83c2c4d
- (void)onCreateWebViewForDelegate:(FWFUIDelegate *)instance | |
webView:(WKWebView *)webView | |
configuration:(WKWebViewConfiguration *)configuration | |
navigationAction:(WKNavigationAction *)navigationAction | |
completion:(void (^)(FlutterError *_Nullable))completion { | |
if (![self.instanceManager containsInstance:configuration]) { | |
[self.webViewConfigurationFlutterApi createWithConfiguration:configuration | |
completion:^(FlutterError *error) { | |
NSAssert(!error, @"%@", error); | |
}]; | |
} | |
NSInteger configurationIdentifier = | |
[self.instanceManager identifierWithStrongReferenceForInstance:configuration]; | |
FWFWKNavigationActionData *navigationActionData = | |
FWFWKNavigationActionDataFromNativeWKNavigationAction(navigationAction); | |
[self | |
onCreateWebViewForDelegateWithIdentifier:[self identifierForDelegate:instance] | |
webViewIdentifier:[self.instanceManager | |
identifierWithStrongReferenceForInstance:webView] | |
configurationIdentifier:configurationIdentifier | |
navigationAction:navigationActionData | |
completion:completion]; | |
} | |
- (void)requestMediaCapturePermissionForDelegateWithIdentifier:(FWFUIDelegate *)instance | |
webView:(WKWebView *)webView | |
origin:(WKSecurityOrigin *)origin | |
frame:(WKFrameInfo *)frame | |
type:(WKMediaCaptureType)type | |
completion: | |
(void (^)(WKPermissionDecision))completion | |
API_AVAILABLE(ios(15.0)) { | |
[self | |
requestMediaCapturePermissionForDelegateWithIdentifier:[self identifierForDelegate:instance] | |
webViewIdentifier: | |
[self.instanceManager | |
identifierWithStrongReferenceForInstance:webView] | |
origin: | |
FWFWKSecurityOriginDataFromNativeWKSecurityOrigin( | |
origin) | |
frame: | |
FWFWKFrameInfoDataFromNativeWKFrameInfo( | |
frame) | |
type: | |
FWFWKMediaCaptureTypeDataFromNativeWKMediaCaptureType( | |
type) | |
completion:^( | |
FWFWKPermissionDecisionData *decision, | |
FlutterError *error) { | |
NSAssert(!error, @"%@", error); | |
completion( | |
FWFNativeWKPermissionDecisionFromData( | |
decision)); | |
}]; | |
} | |
@end |
@hellohuanlin In this case, I just followed previous implementation. I also agree with that NSAssert can be dangerous sometime, but the error only came from pigeon generation part like follow code and I understood that it is serious situation if channel is not established.
packages/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFGeneratedWebKitApis.m
Lines 3094 to 3098 in 83c2c4d
completion(nil, | |
[FlutterError errorWithCode:@"channel-error" | |
message:@"Unable to establish connection on channel." | |
details:@""]); | |
} |
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.
We are still deciding on a better alternative for using NSAssert
in callback methods: flutter/flutter#140410
@jsharp83 is correct that we probably won't be able to send the error back to Dart, so we need a way to handle it on the platform side.
Definitely feel free to add feedback to this issue!
…t-panel-interface-wkwebview
flutter/packages@83c2c4d...129e08c 2024-01-19 [email protected] [pigeon] Run swift-format on ungenerated example app Swift files (flutter/packages#5934) 2024-01-19 [email protected] [path_provider_foundation] Run swift-format on Swift files (flutter/packages#5935) 2024-01-19 [email protected] [shared_preferences_foundation] Run swift-format on Swift files (flutter/packages#5933) 2024-01-19 [email protected] [various] Run swift-format on example app Swift files (flutter/packages#5931) 2024-01-19 [email protected] [camera_avfoundation] Remove development team from Xcode example app (flutter/packages#5930) 2024-01-18 [email protected] [webview_flutter_wkwebview] Add javascript panel interface for wkwebview (flutter/packages#5795) 2024-01-18 [email protected] [two_dimensional_scrollables] Fix must_call_super (flutter/packages#5921) 2024-01-18 [email protected] [pointer_interceptor] fix width and height unset warning on web platform (flutter/packages#5864) 2024-01-18 49699333+dependabot[bot]@users.noreply.github.com Bump github/codeql-action from 3.23.0 to 3.23.1 (flutter/packages#5922) 2024-01-18 [email protected] [google_maps_flutter] Clean up iOS example project (flutter/packages#5925) 2024-01-18 [email protected] [ci] Add flags to formatter command to decide which formatters to run (flutter/packages#5905) 2024-01-18 [email protected] Update tests to Xcode 15 and iOS 17 simulator (flutter/packages#5914) 2024-01-18 [email protected] Roll Flutter from def6af0 to f77f824 (25 revisions) (flutter/packages#5924) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages-flutter-autoroll Please CC [email protected],[email protected] on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
…iew (flutter#5795) * There are cases where Web calls System Popup with javascript on webview_flutter * At this time, the message comes in the WKUIDelegate part in iOS. * https://developer.apple.com/documentation/webkit/wkuidelegate/1537406-webview * https://developer.apple.com/documentation/webkit/wkuidelegate/1536489-webview * Related issue: flutter/flutter#30358 (comment) * Related Interface PR: flutter#5670 * The PR that contains all changes can be found at flutter#4704
Pre-launch Checklist
dart format
.)[shared_preferences]
pubspec.yaml
with an appropriate new version according to the pub versioning philosophy, or this PR is exempt from version changes.CHANGELOG.md
to add a description of the change, following repository CHANGELOG style.///
).If you need help, consider asking for advice on the #hackers-new channel on Discord.