Files
QIDISlicer/src/slic3r/GUI/WebViewPlatformUtilsMac.mm
2025-03-22 08:46:31 +08:00

189 lines
8.6 KiB
Plaintext

#include "WebViewPlatformUtils.hpp"
#import <WebKit/WKWebView.h>
#import <WebKit/WKNavigationDelegate.h>
#import <WebKit/WKWebViewConfiguration.h>
#import <WebKit/WKWebsiteDataStore.h>
#import <Foundation/Foundation.h>
#import <Foundation/NSURLSession.h>
@interface MyNavigationDelegate: NSObject<WKNavigationDelegate> {
id<WKNavigationDelegate> _delegate;
NSString* _username;
NSString* _passwd;
}
- (id) initWithOriginalDelegate: (id<WKNavigationDelegate>) delegate userName: (const char*) username password: (const char*) password;
- (id<WKNavigationDelegate>) wrapped_delegate;
@end
@implementation MyNavigationDelegate
- (id) initWithOriginalDelegate: (id<WKNavigationDelegate>) delegate userName: (const char*) username password: (const char*) password {
if (self = [super init]) {
_delegate = delegate;
_username = [[NSString alloc] initWithFormat:@"%s", username];
_passwd = [[NSString alloc] initWithFormat:@"%s", password];
}
return self;
}
- (id<WKNavigationDelegate>) wrapped_delegate {
return _delegate;
}
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
if ([_delegate respondsToSelector:@selector(webView:decidePolicyForNavigationAction:decisionHandler:)]) {
[_delegate webView:webView decidePolicyForNavigationAction:navigationAction decisionHandler:decisionHandler];
} else {
decisionHandler(WKNavigationActionPolicyAllow);
}
}
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction preferences:(WKWebpagePreferences *)preferences decisionHandler:(void (^)(WKNavigationActionPolicy, WKWebpagePreferences *))decisionHandler API_AVAILABLE(macos(10.15), ios(13.0)) {
if ([_delegate respondsToSelector:@selector(webView:decidePolicyForNavigationAction:preferences:decisionHandler:)]) {
[_delegate webView:webView decidePolicyForNavigationAction:navigationAction preferences:preferences decisionHandler:decisionHandler];
} else {
decisionHandler(WKNavigationActionPolicyAllow, preferences);
}
}
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler {
if ([_delegate respondsToSelector:@selector(webView:decidePolicyForNavigationResponse:decisionHandler:)]) {
[_delegate webView:webView decidePolicyForNavigationResponse: navigationResponse decisionHandler: decisionHandler];
} else {
decisionHandler(WKNavigationResponsePolicyAllow);
}
}
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(null_unspecified WKNavigation *)navigation {
if ([_delegate respondsToSelector:@selector(webView:didStartProvisionalNavigation:)]) {
[_delegate webView:webView didStartProvisionalNavigation:navigation];
}
}
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(null_unspecified WKNavigation *)navigation {
if ([_delegate respondsToSelector:@selector(webView:didReceiveServerRedirectForProvisionalNavigation:)]) {
[_delegate webView:webView didReceiveServerRedirectForProvisionalNavigation:navigation];
}
}
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error {
if ([_delegate respondsToSelector:@selector(webView:didFailProvisionalNavigation:withError:)]) {
[_delegate webView:webView didFailProvisionalNavigation:navigation withError:error];
}
}
- (void)webView:(WKWebView *)webView didCommitNavigation:(null_unspecified WKNavigation *)navigation {
if ([_delegate respondsToSelector:@selector(webView:didCommitNavigation:)]) {
[_delegate webView:webView didCommitNavigation:navigation];
}
}
- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation {
if ([_delegate respondsToSelector:@selector(webView:didFinishNavigation:)]) {
[_delegate webView:webView didFinishNavigation:navigation];
}
}
- (void)webView:(WKWebView *)webView didFailNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error {
if ([_delegate respondsToSelector:@selector(webView:didFailNavigation:withError:)]) {
[_delegate webView:webView didFailNavigation:navigation withError:error];
}
}
- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler {
//challenge.protectionSpace.realm
completionHandler(
NSURLSessionAuthChallengeUseCredential,
[NSURLCredential credentialWithUser: _username password: _passwd persistence: NSURLCredentialPersistenceForSession]
);
}
- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView API_AVAILABLE(macos(10.11), ios(9.0)) {
if ([_delegate respondsToSelector:@selector(webViewWebContentProcessDidTerminate:)]) {
[_delegate webViewWebContentProcessDidTerminate:webView];
}
}
- (void)webView:(WKWebView *)webView authenticationChallenge:(NSURLAuthenticationChallenge *)challenge shouldAllowDeprecatedTLS:(void (^)(BOOL))decisionHandler API_AVAILABLE(macos(11.0), ios(14.0)) {
if ([_delegate respondsToSelector:@selector(webView:authenticationChallenge:shouldAllowDeprecatedTLS:)]) {
[_delegate webView:webView authenticationChallenge:challenge shouldAllowDeprecatedTLS:decisionHandler];
} else {
decisionHandler(YES);
}
}
@end
namespace Slic3r::GUI {
void setup_webview_with_credentials(wxWebView* web_view, const std::string& username, const std::string& password)
{
remove_webview_credentials(web_view);
WKWebView* backend = static_cast<WKWebView*>(web_view->GetNativeBackend());
if (![backend.navigationDelegate isKindOfClass:MyNavigationDelegate.class]) {
backend.navigationDelegate = [[MyNavigationDelegate alloc]
initWithOriginalDelegate:backend.navigationDelegate
userName:username.c_str()
password:password.c_str()];
}
}
void remove_webview_credentials(wxWebView* web_view)
{
WKWebView* backend = static_cast<WKWebView*>(web_view->GetNativeBackend());
if ([backend.navigationDelegate isKindOfClass:MyNavigationDelegate.class]) {
MyNavigationDelegate* my_delegate = backend.navigationDelegate;
backend.navigationDelegate = my_delegate.wrapped_delegate;
}
}
void delete_cookies(wxWebView* web_view, const std::string& url)
{
WKWebView* backend = static_cast<WKWebView*>(web_view->GetNativeBackend());
NSString *url_string = [NSString stringWithCString:url.c_str() encoding:[NSString defaultCStringEncoding]];
WKWebsiteDataStore *data_store = backend.configuration.websiteDataStore;
NSSet *website_data_types = [NSSet setWithObject:WKWebsiteDataTypeCookies];
[data_store fetchDataRecordsOfTypes:website_data_types completionHandler:^(NSArray<WKWebsiteDataRecord *> *records) {
for (WKWebsiteDataRecord *record in records) {
if ([url_string containsString:record.displayName]) {
[data_store removeDataOfTypes:website_data_types
forDataRecords:@[record]
completionHandler:^{
//NSLog(@"Deleted cookies for domain: %@", record.displayName);
}];
}
}
}];
}
void delete_cookies_with_counter(wxWebView* web_view, const std::string& url, std::atomic<size_t>& counter)
{
delete_cookies(web_view, url);
counter++;
}
void add_request_authorization(wxWebView* web_view, const wxString& address, const std::string& token)
{
// unused on MacOS
assert(true);
}
void remove_request_authorization(wxWebView* web_view)
{
// unused on MacOS
assert(true);
}
void load_request(wxWebView* web_view, const std::string& address, const std::string& token)
{
WKWebView* backend = static_cast<WKWebView*>(web_view->GetNativeBackend());
NSString *url_string = [NSString stringWithCString:address.c_str() encoding:[NSString defaultCStringEncoding]];
NSString *token_string = [NSString stringWithCString:token.c_str() encoding:[NSString defaultCStringEncoding]];
NSURL *url = [NSURL URLWithString:url_string];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSString *auth_value = [NSString stringWithFormat:@"External %@", token_string];
[request setValue:auth_value forHTTPHeaderField:@"Authorization"];
[backend loadRequest:request];
}
}