aboutsummaryrefslogtreecommitdiffstats
path: root/components/servo/webview_delegate.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/servo/webview_delegate.rs')
-rw-r--r--components/servo/webview_delegate.rs124
1 files changed, 78 insertions, 46 deletions
diff --git a/components/servo/webview_delegate.rs b/components/servo/webview_delegate.rs
index ef8cb93cb66..27b8f0ae852 100644
--- a/components/servo/webview_delegate.rs
+++ b/components/servo/webview_delegate.rs
@@ -14,6 +14,7 @@ use embedder_traits::{
};
use ipc_channel::ipc::IpcSender;
use keyboard_types::KeyboardEvent;
+use serde::Serialize;
use url::Url;
use webrender_api::units::{DeviceIntPoint, DeviceIntRect, DeviceIntSize};
@@ -60,6 +61,46 @@ impl Drop for NavigationRequest {
}
}
+/// Sends a response over an IPC channel, or a default response on [`Drop`] if no response was sent.
+pub(crate) struct IpcResponder<T: Serialize> {
+ response_sender: IpcSender<T>,
+ response_sent: bool,
+ /// Always present, except when taken by [`Drop`].
+ default_response: Option<T>,
+}
+
+impl<T: Serialize> IpcResponder<T> {
+ pub(crate) fn new(response_sender: IpcSender<T>, default_response: T) -> Self {
+ Self {
+ response_sender,
+ response_sent: false,
+ default_response: Some(default_response),
+ }
+ }
+
+ pub(crate) fn send(&mut self, response: T) -> bincode::Result<()> {
+ let result = self.response_sender.send(response);
+ self.response_sent = true;
+ result
+ }
+
+ pub(crate) fn into_inner(self) -> IpcSender<T> {
+ self.response_sender.clone()
+ }
+}
+
+impl<T: Serialize> Drop for IpcResponder<T> {
+ fn drop(&mut self) {
+ if !self.response_sent {
+ let response = self
+ .default_response
+ .take()
+ .expect("Guaranteed by inherent impl");
+ let _ = self.response_sender.send(response);
+ }
+ }
+}
+
/// A permissions request for a [`WebView`] The embedder should allow or deny the request,
/// either by reading a cached value or querying the user for permission via the user
/// interface.
@@ -82,29 +123,22 @@ impl PermissionRequest {
}
}
-pub struct AllowOrDenyRequest {
- pub(crate) response_sender: IpcSender<AllowOrDeny>,
- pub(crate) response_sent: bool,
- pub(crate) default_response: AllowOrDeny,
-}
+pub struct AllowOrDenyRequest(IpcResponder<AllowOrDeny>);
impl AllowOrDenyRequest {
- pub fn allow(mut self) {
- let _ = self.response_sender.send(AllowOrDeny::Allow);
- self.response_sent = true;
+ pub(crate) fn new(
+ response_sender: IpcSender<AllowOrDeny>,
+ default_response: AllowOrDeny,
+ ) -> Self {
+ Self(IpcResponder::new(response_sender, default_response))
}
- pub fn deny(mut self) {
- let _ = self.response_sender.send(AllowOrDeny::Deny);
- self.response_sent = true;
+ pub fn allow(mut self) {
+ let _ = self.0.send(AllowOrDeny::Allow);
}
-}
-impl Drop for AllowOrDenyRequest {
- fn drop(&mut self) {
- if !self.response_sent {
- let _ = self.response_sender.send(self.default_response);
- }
+ pub fn deny(mut self) {
+ let _ = self.0.send(AllowOrDeny::Deny);
}
}
@@ -114,11 +148,22 @@ impl Drop for AllowOrDenyRequest {
pub struct AuthenticationRequest {
pub(crate) url: Url,
pub(crate) for_proxy: bool,
- pub(crate) response_sender: IpcSender<Option<AuthenticationResponse>>,
- pub(crate) response_sent: bool,
+ pub(crate) responder: IpcResponder<Option<AuthenticationResponse>>,
}
impl AuthenticationRequest {
+ pub(crate) fn new(
+ url: Url,
+ for_proxy: bool,
+ response_sender: IpcSender<Option<AuthenticationResponse>>,
+ ) -> Self {
+ Self {
+ url,
+ for_proxy,
+ responder: IpcResponder::new(response_sender, None),
+ }
+ }
+
/// The URL of the request that triggered this authentication.
pub fn url(&self) -> &Url {
&self.url
@@ -130,17 +175,8 @@ impl AuthenticationRequest {
/// Respond to the [`AuthenticationRequest`] with the given username and password.
pub fn authenticate(mut self, username: String, password: String) {
let _ = self
- .response_sender
+ .responder
.send(Some(AuthenticationResponse { username, password }));
- self.response_sent = true;
- }
-}
-
-impl Drop for AuthenticationRequest {
- fn drop(&mut self) {
- if !self.response_sent {
- let _ = self.response_sender.send(None);
- }
}
}
@@ -149,11 +185,20 @@ impl Drop for AuthenticationRequest {
/// by calling [`WebResourceLoad::intercept`].
pub struct WebResourceLoad {
pub request: WebResourceRequest,
- pub(crate) response_sender: IpcSender<WebResourceResponseMsg>,
- pub(crate) intercepted: bool,
+ pub(crate) responder: IpcResponder<WebResourceResponseMsg>,
}
impl WebResourceLoad {
+ pub(crate) fn new(
+ web_resource_request: WebResourceRequest,
+ response_sender: IpcSender<WebResourceResponseMsg>,
+ ) -> Self {
+ Self {
+ request: web_resource_request,
+ responder: IpcResponder::new(response_sender, WebResourceResponseMsg::DoNotIntercept),
+ }
+ }
+
/// The [`WebResourceRequest`] associated with this [`WebResourceLoad`].
pub fn request(&self) -> &WebResourceRequest {
&self.request
@@ -161,28 +206,15 @@ impl WebResourceLoad {
/// Intercept this [`WebResourceLoad`] and control the response via the returned
/// [`InterceptedWebResourceLoad`].
pub fn intercept(mut self, response: WebResourceResponse) -> InterceptedWebResourceLoad {
- let _ = self
- .response_sender
- .send(WebResourceResponseMsg::Start(response));
- self.intercepted = true;
+ let _ = self.responder.send(WebResourceResponseMsg::Start(response));
InterceptedWebResourceLoad {
request: self.request.clone(),
- response_sender: self.response_sender.clone(),
+ response_sender: self.responder.into_inner(),
finished: false,
}
}
}
-impl Drop for WebResourceLoad {
- fn drop(&mut self) {
- if !self.intercepted {
- let _ = self
- .response_sender
- .send(WebResourceResponseMsg::DoNotIntercept);
- }
- }
-}
-
/// An intercepted web resource load. This struct allows the client to send an alternative response
/// after calling [`WebResourceLoad::intercept`]. In order to send chunks of body data, the client
/// must call [`InterceptedWebResourceLoad::send_body_data`]. When the interception is complete, the client