#[cfg(target_os = "macos")]
use std::ptr::null_mut;
use block2::Block;
use objc2::{define_class, msg_send, rc::Retained, runtime::NSObject, MainThreadOnly};
#[cfg(target_os = "macos")]
use objc2_app_kit::{NSModalResponse, NSModalResponseOK, NSOpenPanel};
use objc2_foundation::{MainThreadMarker, NSObjectProtocol};
#[cfg(target_os = "macos")]
use objc2_foundation::{NSArray, NSURL};
#[cfg(target_os = "macos")]
use objc2_web_kit::WKOpenPanelParameters;
use objc2_web_kit::{
WKFrameInfo, WKMediaCaptureType, WKPermissionDecision, WKSecurityOrigin, WKUIDelegate,
};
use crate::WryWebView;
pub struct WryWebViewUIDelegateIvars {}
define_class!(
#[unsafe(super(NSObject))]
#[name = "WryWebViewUIDelegate"]
#[thread_kind = MainThreadOnly]
#[ivars = WryWebViewUIDelegateIvars]
pub struct WryWebViewUIDelegate;
unsafe impl NSObjectProtocol for WryWebViewUIDelegate {}
unsafe impl WKUIDelegate for WryWebViewUIDelegate {
#[cfg(target_os = "macos")]
#[unsafe(method(webView:runOpenPanelWithParameters:initiatedByFrame:completionHandler:))]
fn run_file_upload_panel(
&self,
_webview: &WryWebView,
open_panel_params: &WKOpenPanelParameters,
_frame: &WKFrameInfo,
handler: &block2::Block<dyn Fn(*const NSArray<NSURL>)>,
) {
unsafe {
if let Some(mtm) = MainThreadMarker::new() {
let open_panel = NSOpenPanel::openPanel(mtm);
open_panel.setCanChooseFiles(true);
let allow_multi = open_panel_params.allowsMultipleSelection();
open_panel.setAllowsMultipleSelection(allow_multi);
let allow_dir = open_panel_params.allowsDirectories();
open_panel.setCanChooseDirectories(allow_dir);
let ok: NSModalResponse = open_panel.runModal();
if ok == NSModalResponseOK {
let url = open_panel.URLs();
(*handler).call((Retained::as_ptr(&url),));
} else {
(*handler).call((null_mut(),));
}
}
}
}
#[unsafe(method(webView:requestMediaCapturePermissionForOrigin:initiatedByFrame:type:decisionHandler:))]
fn request_media_capture_permission(
&self,
_webview: &WryWebView,
_origin: &WKSecurityOrigin,
_frame: &WKFrameInfo,
_capture_type: WKMediaCaptureType,
decision_handler: &Block<dyn Fn(WKPermissionDecision)>,
) {
(*decision_handler).call((WKPermissionDecision::Grant,));
}
}
);
impl WryWebViewUIDelegate {
pub fn new(mtm: MainThreadMarker) -> Retained<Self> {
let delegate = mtm
.alloc::<WryWebViewUIDelegate>()
.set_ivars(WryWebViewUIDelegateIvars {});
unsafe { msg_send![super(delegate), init] }
}
}