mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
libservo: Clean up interfaces for alert()/confirm()/prompt() (#35579)
Signed-off-by: Delan Azabani <dazabani@igalia.com>
This commit is contained in:
parent
03e953e22c
commit
276f6a3ba7
16 changed files with 278 additions and 222 deletions
|
@ -201,7 +201,7 @@ mod from_script {
|
|||
Self::ChangePageTitle(..) => target_variant!("ChangePageTitle"),
|
||||
Self::MoveTo(..) => target_variant!("MoveTo"),
|
||||
Self::ResizeTo(..) => target_variant!("ResizeTo"),
|
||||
Self::Prompt(..) => target_variant!("Prompt"),
|
||||
Self::ShowSimpleDialog(..) => target_variant!("ShowSimpleDialog"),
|
||||
Self::RequestAuthentication(..) => target_variant!("RequestAuthentication"),
|
||||
Self::ShowContextMenu(..) => target_variant!("ShowContextMenu"),
|
||||
Self::AllowNavigationRequest(..) => target_variant!("AllowNavigationRequest"),
|
||||
|
|
|
@ -26,8 +26,8 @@ use cssparser::{Parser, ParserInput, SourceLocation};
|
|||
use devtools_traits::{ScriptToDevtoolsControlMsg, TimelineMarker, TimelineMarkerType};
|
||||
use dom_struct::dom_struct;
|
||||
use embedder_traits::{
|
||||
EmbedderMsg, PromptDefinition, PromptOrigin, PromptResult, Theme, WebDriverJSError,
|
||||
WebDriverJSResult,
|
||||
AlertResponse, ConfirmResponse, EmbedderMsg, PromptResponse, SimpleDialog, Theme,
|
||||
WebDriverJSError, WebDriverJSResult,
|
||||
};
|
||||
use euclid::default::{Point2D as UntypedPoint2D, Rect as UntypedRect};
|
||||
use euclid::{Point2D, Rect, Scale, Size2D, Vector2D};
|
||||
|
@ -736,30 +736,43 @@ impl WindowMethods<crate::DomTypeHolder> for Window {
|
|||
}
|
||||
let (sender, receiver) =
|
||||
ProfiledIpc::channel(self.global().time_profiler_chan().clone()).unwrap();
|
||||
let prompt = PromptDefinition::Alert(s.to_string(), sender);
|
||||
let msg = EmbedderMsg::Prompt(self.webview_id(), prompt, PromptOrigin::Untrusted);
|
||||
let dialog = SimpleDialog::Alert {
|
||||
message: s.to_string(),
|
||||
response_sender: sender,
|
||||
};
|
||||
let msg = EmbedderMsg::ShowSimpleDialog(self.webview_id(), dialog);
|
||||
self.send_to_embedder(msg);
|
||||
receiver.recv().unwrap();
|
||||
let AlertResponse::Ok = receiver.recv().unwrap();
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#dom-confirm
|
||||
fn Confirm(&self, s: DOMString) -> bool {
|
||||
let (sender, receiver) =
|
||||
ProfiledIpc::channel(self.global().time_profiler_chan().clone()).unwrap();
|
||||
let prompt = PromptDefinition::OkCancel(s.to_string(), sender);
|
||||
let msg = EmbedderMsg::Prompt(self.webview_id(), prompt, PromptOrigin::Untrusted);
|
||||
let dialog = SimpleDialog::Confirm {
|
||||
message: s.to_string(),
|
||||
response_sender: sender,
|
||||
};
|
||||
let msg = EmbedderMsg::ShowSimpleDialog(self.webview_id(), dialog);
|
||||
self.send_to_embedder(msg);
|
||||
receiver.recv().unwrap() == PromptResult::Primary
|
||||
receiver.recv().unwrap() == ConfirmResponse::Ok
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#dom-prompt
|
||||
fn Prompt(&self, message: DOMString, default: DOMString) -> Option<DOMString> {
|
||||
let (sender, receiver) =
|
||||
ProfiledIpc::channel(self.global().time_profiler_chan().clone()).unwrap();
|
||||
let prompt = PromptDefinition::Input(message.to_string(), default.to_string(), sender);
|
||||
let msg = EmbedderMsg::Prompt(self.webview_id(), prompt, PromptOrigin::Untrusted);
|
||||
let dialog = SimpleDialog::Prompt {
|
||||
message: message.to_string(),
|
||||
default: default.to_string(),
|
||||
response_sender: sender,
|
||||
};
|
||||
let msg = EmbedderMsg::ShowSimpleDialog(self.webview_id(), dialog);
|
||||
self.send_to_embedder(msg);
|
||||
receiver.recv().unwrap().map(|s| s.into())
|
||||
match receiver.recv().unwrap() {
|
||||
PromptResponse::Ok(input) => Some(input.into()),
|
||||
PromptResponse::Cancel => None,
|
||||
}
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#dom-window-stop
|
||||
|
|
|
@ -708,11 +708,11 @@ impl Servo {
|
|||
webview.delegate().request_resize_to(webview, size);
|
||||
}
|
||||
},
|
||||
EmbedderMsg::Prompt(webview_id, prompt_definition, prompt_origin) => {
|
||||
EmbedderMsg::ShowSimpleDialog(webview_id, prompt_definition) => {
|
||||
if let Some(webview) = self.get_webview_handle(webview_id) {
|
||||
webview
|
||||
.delegate()
|
||||
.show_prompt(webview, prompt_definition, prompt_origin);
|
||||
.show_simple_dialog(webview, prompt_definition);
|
||||
}
|
||||
},
|
||||
EmbedderMsg::ShowContextMenu(webview_id, ipc_sender, title, items) => {
|
||||
|
|
|
@ -9,8 +9,7 @@ use compositing_traits::ConstellationMsg;
|
|||
use embedder_traits::{
|
||||
AllowOrDeny, AuthenticationResponse, ContextMenuResult, Cursor, FilterPattern,
|
||||
GamepadHapticEffectType, InputMethodType, LoadStatus, MediaSessionEvent, PermissionFeature,
|
||||
PromptDefinition, PromptOrigin, WebResourceRequest, WebResourceResponse,
|
||||
WebResourceResponseMsg,
|
||||
SimpleDialog, WebResourceRequest, WebResourceResponse, WebResourceResponseMsg,
|
||||
};
|
||||
use ipc_channel::ipc::IpcSender;
|
||||
use keyboard_types::KeyboardEvent;
|
||||
|
@ -338,17 +337,25 @@ pub trait WebViewDelegate {
|
|||
) {
|
||||
}
|
||||
|
||||
/// Show dialog to user
|
||||
/// Show the user a [simple dialog](https://html.spec.whatwg.org/multipage/#simple-dialogs) (`alert()`, `confirm()`,
|
||||
/// or `prompt()`). Since their messages are controlled by web content, they should be presented to the user in a
|
||||
/// way that makes them impossible to mistake for browser UI.
|
||||
/// TODO: This API needs to be reworked to match the new model of how responses are sent.
|
||||
fn show_prompt(&self, _webview: WebView, prompt: PromptDefinition, _: PromptOrigin) {
|
||||
let _ = match prompt {
|
||||
PromptDefinition::Alert(_, response_sender) => response_sender.send(()),
|
||||
PromptDefinition::OkCancel(_, response_sender) => {
|
||||
response_sender.send(embedder_traits::PromptResult::Dismissed)
|
||||
},
|
||||
PromptDefinition::Input(_, _, response_sender) => response_sender.send(None),
|
||||
fn show_simple_dialog(&self, _webview: WebView, dialog: SimpleDialog) {
|
||||
// Return the DOM-specified default value for when we **cannot show simple dialogs**.
|
||||
let _ = match dialog {
|
||||
SimpleDialog::Alert {
|
||||
response_sender, ..
|
||||
} => response_sender.send(Default::default()),
|
||||
SimpleDialog::Confirm {
|
||||
response_sender, ..
|
||||
} => response_sender.send(Default::default()),
|
||||
SimpleDialog::Prompt {
|
||||
response_sender, ..
|
||||
} => response_sender.send(Default::default()),
|
||||
};
|
||||
}
|
||||
|
||||
/// Show a context menu to the user
|
||||
fn show_context_menu(
|
||||
&self,
|
||||
|
|
|
@ -123,14 +123,30 @@ pub enum ContextMenuResult {
|
|||
Selected(usize),
|
||||
}
|
||||
|
||||
/// [Simple dialogs](https://html.spec.whatwg.org/multipage/#simple-dialogs) are synchronous dialogs
|
||||
/// that can be opened by web content. Since their messages are controlled by web content, they
|
||||
/// should be presented to the user in a way that makes them impossible to mistake for browser UI.
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub enum PromptDefinition {
|
||||
/// Show a message.
|
||||
Alert(String, IpcSender<()>),
|
||||
/// Ask a Ok/Cancel question.
|
||||
OkCancel(String, IpcSender<PromptResult>),
|
||||
/// Ask the user to enter text.
|
||||
Input(String, String, IpcSender<Option<String>>),
|
||||
pub enum SimpleDialog {
|
||||
/// [`alert()`](https://html.spec.whatwg.org/multipage/#dom-alert).
|
||||
/// TODO: Include details about the document origin.
|
||||
Alert {
|
||||
message: String,
|
||||
response_sender: IpcSender<AlertResponse>,
|
||||
},
|
||||
/// [`confirm()`](https://html.spec.whatwg.org/multipage/#dom-confirm).
|
||||
/// TODO: Include details about the document origin.
|
||||
Confirm {
|
||||
message: String,
|
||||
response_sender: IpcSender<ConfirmResponse>,
|
||||
},
|
||||
/// [`prompt()`](https://html.spec.whatwg.org/multipage/#dom-prompt).
|
||||
/// TODO: Include details about the document origin.
|
||||
Prompt {
|
||||
message: String,
|
||||
default: String,
|
||||
response_sender: IpcSender<PromptResponse>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||
|
@ -142,22 +158,52 @@ pub struct AuthenticationResponse {
|
|||
}
|
||||
|
||||
#[derive(Deserialize, PartialEq, Serialize)]
|
||||
pub enum PromptOrigin {
|
||||
/// Prompt is triggered from content (window.prompt/alert/confirm/…).
|
||||
/// Prompt message is unknown.
|
||||
Untrusted,
|
||||
/// Prompt is triggered from Servo (ask for permission, show error,…).
|
||||
Trusted,
|
||||
pub enum AlertResponse {
|
||||
/// The user chose Ok, or the dialog was otherwise dismissed or ignored.
|
||||
Ok,
|
||||
}
|
||||
|
||||
impl Default for AlertResponse {
|
||||
fn default() -> Self {
|
||||
// Per <https://html.spec.whatwg.org/multipage/#dom-alert>,
|
||||
// if we **cannot show simple dialogs**, including cases where the user or user agent decides to ignore
|
||||
// all modal dialogs, we need to return (which represents Ok).
|
||||
Self::Ok
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, PartialEq, Serialize)]
|
||||
pub enum PromptResult {
|
||||
/// Prompt was closed by clicking on the primary button (ok/yes)
|
||||
Primary,
|
||||
/// Prompt was closed by clicking on the secondary button (cancel/no)
|
||||
Secondary,
|
||||
/// Prompt was dismissed
|
||||
Dismissed,
|
||||
pub enum ConfirmResponse {
|
||||
/// The user chose Ok.
|
||||
Ok,
|
||||
/// The user chose Cancel, or the dialog was otherwise dismissed or ignored.
|
||||
Cancel,
|
||||
}
|
||||
|
||||
impl Default for ConfirmResponse {
|
||||
fn default() -> Self {
|
||||
// Per <https://html.spec.whatwg.org/multipage/#dom-confirm>,
|
||||
// if we **cannot show simple dialogs**, including cases where the user or user agent decides to ignore
|
||||
// all modal dialogs, we need to return false (which represents Cancel), not true (Ok).
|
||||
Self::Cancel
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, PartialEq, Serialize)]
|
||||
pub enum PromptResponse {
|
||||
/// The user chose Ok, with the given input.
|
||||
Ok(String),
|
||||
/// The user chose Cancel, or the dialog was otherwise dismissed or ignored.
|
||||
Cancel,
|
||||
}
|
||||
|
||||
impl Default for PromptResponse {
|
||||
fn default() -> Self {
|
||||
// Per <https://html.spec.whatwg.org/multipage/#dom-prompt>,
|
||||
// if we **cannot show simple dialogs**, including cases where the user or user agent decides to ignore
|
||||
// all modal dialogs, we need to return null (which represents Cancel), not the default input.
|
||||
Self::Cancel
|
||||
}
|
||||
}
|
||||
|
||||
/// A response to a request to allow or deny an action.
|
||||
|
@ -177,8 +223,10 @@ pub enum EmbedderMsg {
|
|||
MoveTo(WebViewId, DeviceIntPoint),
|
||||
/// Resize the window to size
|
||||
ResizeTo(WebViewId, DeviceIntSize),
|
||||
/// Show dialog to user
|
||||
Prompt(WebViewId, PromptDefinition, PromptOrigin),
|
||||
/// Show the user a [simple dialog](https://html.spec.whatwg.org/multipage/#simple-dialogs) (`alert()`, `confirm()`,
|
||||
/// or `prompt()`). Since their messages are controlled by web content, they should be presented to the user in a
|
||||
/// way that makes them impossible to mistake for browser UI.
|
||||
ShowSimpleDialog(WebViewId, SimpleDialog),
|
||||
/// Request authentication for a load or navigation from the embedder.
|
||||
RequestAuthentication(
|
||||
WebViewId,
|
||||
|
@ -280,7 +328,7 @@ impl Debug for EmbedderMsg {
|
|||
EmbedderMsg::ChangePageTitle(..) => write!(f, "ChangePageTitle"),
|
||||
EmbedderMsg::MoveTo(..) => write!(f, "MoveTo"),
|
||||
EmbedderMsg::ResizeTo(..) => write!(f, "ResizeTo"),
|
||||
EmbedderMsg::Prompt(..) => write!(f, "Prompt"),
|
||||
EmbedderMsg::ShowSimpleDialog(..) => write!(f, "ShowSimpleDialog"),
|
||||
EmbedderMsg::RequestAuthentication(..) => write!(f, "RequestAuthentication"),
|
||||
EmbedderMsg::AllowUnload(..) => write!(f, "AllowUnload"),
|
||||
EmbedderMsg::AllowNavigationRequest(..) => write!(f, "AllowNavigationRequest"),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue