2020-03-01 10:34:07 +11:00
|
|
|
//! WebViewController is a combination of various delegates and helpers for an underlying
|
|
|
|
//! `WKWebView`. It allows you to do things such as handle opening a file (for uploads or
|
|
|
|
//! in-browser-processing), handling navigation actions or JS message callbacks, and so on.
|
2020-02-28 13:34:34 +11:00
|
|
|
|
2020-03-20 14:07:44 +11:00
|
|
|
use crate::webview::config::WebViewConfig;
|
|
|
|
use crate::webview::enums::{
|
2020-03-01 10:34:07 +11:00
|
|
|
NavigationAction, NavigationPolicy,
|
|
|
|
NavigationResponse, NavigationResponsePolicy,
|
|
|
|
OpenPanelParameters
|
|
|
|
};
|
2020-03-20 14:07:44 +11:00
|
|
|
use crate::webview::handle::WebViewHandle;
|
2020-02-28 13:34:34 +11:00
|
|
|
|
2020-03-01 10:34:07 +11:00
|
|
|
/// You can implement this on structs to handle callbacks from the underlying `WKWebView`.
|
2020-02-28 13:34:34 +11:00
|
|
|
pub trait WebViewController {
|
2020-03-20 14:07:44 +11:00
|
|
|
/// Due to a quirk in how the underlying `WKWebView` works, the configuration object must be
|
|
|
|
/// set up before initializing anything. To enable this, you can implement this method and
|
|
|
|
/// return whatever `WebViewConfig` object you want.
|
|
|
|
///
|
|
|
|
/// By default, this returns `WebViewConfig::default()`.
|
|
|
|
fn configure(&mut self) -> WebViewConfig { WebViewConfig::default() }
|
|
|
|
|
|
|
|
/// Called when the View is ready to work with. You're passed a `ViewHandle` - this is safe to
|
|
|
|
/// store and use repeatedly, but it's not thread safe - any UI calls must be made from the
|
|
|
|
/// main thread!
|
|
|
|
fn did_load(&mut self, _view: WebViewHandle) {}
|
|
|
|
|
|
|
|
/// Called when this is about to be added to the view heirarchy.
|
|
|
|
fn will_appear(&self) {}
|
|
|
|
|
|
|
|
/// Called after this has been added to the view heirarchy.
|
|
|
|
fn did_appear(&self) {}
|
|
|
|
|
|
|
|
/// Called when this is about to be removed from the view heirarchy.
|
|
|
|
fn will_disappear(&self) {}
|
|
|
|
|
|
|
|
/// Called when this has been removed from the view heirarchy.
|
|
|
|
fn did_disappear(&self) {}
|
|
|
|
|
2020-03-01 10:34:07 +11:00
|
|
|
/// Called when a JS message is passed by the browser process. For instance, if you added
|
|
|
|
/// `notify` as a callback, and in the browser you called
|
|
|
|
/// `webkit.messageHandlers.notify.postMessage({...})` it would wind up here, with `name` being
|
|
|
|
/// `notify` and `body` being your arguments.
|
|
|
|
///
|
|
|
|
/// Note that at the moment, you really should handle bridging JSON/stringification yourself.
|
|
|
|
fn on_message(&self, _name: &str, _body: &str) {}
|
2020-02-28 13:34:34 +11:00
|
|
|
|
2020-03-01 10:34:07 +11:00
|
|
|
/// Given a callback handler, you can decide what policy should be taken for a given browser
|
|
|
|
/// action. By default, this is `NavigationPolicy::Allow`.
|
|
|
|
fn policy_for_navigation_action<F: Fn(NavigationPolicy)>(&self, _action: NavigationAction, handler: F) {
|
2020-02-28 13:34:34 +11:00
|
|
|
handler(NavigationPolicy::Allow);
|
|
|
|
}
|
|
|
|
|
2020-03-01 10:34:07 +11:00
|
|
|
/// Given a callback handler, you can decide what policy should be taken for a given browser
|
|
|
|
/// response. By default, this is `NavigationResponsePolicy::Allow`.
|
|
|
|
fn policy_for_navigation_response<F: Fn(NavigationResponsePolicy)>(&self, _response: NavigationResponse, handler: F) {
|
2020-02-28 13:34:34 +11:00
|
|
|
handler(NavigationResponsePolicy::Allow);
|
|
|
|
}
|
|
|
|
|
2020-03-01 10:34:07 +11:00
|
|
|
/// Given a callback handler and some open panel parameters (e.g, if the user is clicking an
|
|
|
|
/// upload field that pre-specifies supported options), you should create a `FileSelectPanel`
|
|
|
|
/// and thread the callbacks accordingly.
|
|
|
|
fn run_open_panel<F: Fn(Option<Vec<String>>) + 'static>(&self, _parameters: OpenPanelParameters, handler: F) {
|
2020-02-28 13:34:34 +11:00
|
|
|
handler(None);
|
|
|
|
}
|
|
|
|
|
2020-03-01 10:34:07 +11:00
|
|
|
/// Given a callback handler and a suggested filename, you should create a `FileSavePanel`
|
|
|
|
/// and thread the callbacks accordingly.
|
|
|
|
///
|
|
|
|
/// Note that this specific callback is only
|
2020-03-20 14:07:44 +11:00
|
|
|
/// automatically fired if you're linking in to the `webview_downloading` feature, which
|
2020-03-01 10:34:07 +11:00
|
|
|
/// is not guaranteed to be App Store compatible. If you want a version that can go in the App
|
|
|
|
/// Store, you'll likely need to write some JS in the webview to handle triggering
|
|
|
|
/// downloading/saving. This is due to Apple not allowing the private methods on `WKWebView` to
|
|
|
|
/// be open, which... well, complain to them, not me. :)
|
|
|
|
fn run_save_panel<F: Fn(bool, Option<String>) + 'static>(&self, _suggested_filename: &str, handler: F) {
|
2020-02-28 13:34:34 +11:00
|
|
|
handler(false, None);
|
|
|
|
}
|
|
|
|
}
|