mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Delegate permission prompt dialog formatting to embedders
This commit is contained in:
parent
675b36dde5
commit
f75d547c61
3 changed files with 76 additions and 25 deletions
|
@ -185,9 +185,8 @@ pub enum EmbedderMsg {
|
||||||
GetSelectedBluetoothDevice(Vec<String>, IpcSender<Option<String>>),
|
GetSelectedBluetoothDevice(Vec<String>, IpcSender<Option<String>>),
|
||||||
/// Open file dialog to select files. Set boolean flag to true allows to select multiple files.
|
/// Open file dialog to select files. Set boolean flag to true allows to select multiple files.
|
||||||
SelectFiles(Vec<FilterPattern>, bool, IpcSender<Option<Vec<String>>>),
|
SelectFiles(Vec<FilterPattern>, bool, IpcSender<Option<Vec<String>>>),
|
||||||
/// Open yes/no message for user to allow permission specified by first String.
|
/// Open interface to request permission specified by prompt.
|
||||||
/// With dialog title specified by second String.
|
PromptPermission(PermissionPrompt, IpcSender<PermissionRequest>),
|
||||||
PromptPermission(String, String, IpcSender<PermissionRequest>),
|
|
||||||
/// Request to present an IME to the user when an editable element is focused.
|
/// Request to present an IME to the user when an editable element is focused.
|
||||||
ShowIME(InputMethodType),
|
ShowIME(InputMethodType),
|
||||||
/// Request to hide the IME when the editable element is blurred.
|
/// Request to hide the IME when the editable element is blurred.
|
||||||
|
@ -304,7 +303,30 @@ pub enum MediaSessionEvent {
|
||||||
SetPositionState(MediaPositionState),
|
SetPositionState(MediaPositionState),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Status for prompting user for permission.
|
/// Enum with variants that match the DOM PermissionName enum
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
|
pub enum PermissionName {
|
||||||
|
Geolocation,
|
||||||
|
Notifications,
|
||||||
|
Push,
|
||||||
|
Midi,
|
||||||
|
Camera,
|
||||||
|
Microphone,
|
||||||
|
Speaker,
|
||||||
|
DeviceInfo,
|
||||||
|
BackgroundSync,
|
||||||
|
Bluetooth,
|
||||||
|
PersistentStorage,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Information required to display a permission prompt
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
|
pub enum PermissionPrompt {
|
||||||
|
Insecure(PermissionName),
|
||||||
|
Request(PermissionName),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Status for prompting user for permission.
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
pub enum PermissionRequest {
|
pub enum PermissionRequest {
|
||||||
Granted,
|
Granted,
|
||||||
|
|
|
@ -19,7 +19,7 @@ use crate::dom::promise::Promise;
|
||||||
use crate::realms::{AlreadyInRealm, InRealm};
|
use crate::realms::{AlreadyInRealm, InRealm};
|
||||||
use crate::script_runtime::JSContext;
|
use crate::script_runtime::JSContext;
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
use embedder_traits::{EmbedderMsg, PermissionRequest};
|
use embedder_traits::{self, EmbedderMsg, PermissionPrompt, PermissionRequest};
|
||||||
use ipc_channel::ipc;
|
use ipc_channel::ipc;
|
||||||
use js::conversions::ConversionResult;
|
use js::conversions::ConversionResult;
|
||||||
use js::jsapi::JSObject;
|
use js::jsapi::JSObject;
|
||||||
|
@ -27,11 +27,6 @@ use js::jsval::{ObjectValue, UndefinedValue};
|
||||||
use servo_config::pref;
|
use servo_config::pref;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
const DIALOG_TITLE: &'static str = "Permission request dialog";
|
|
||||||
const NONSECURE_DIALOG_MESSAGE: &'static str = "feature is only safe to use in secure context,\
|
|
||||||
but servo can't guarantee\n that the current context is secure. Do you want to proceed and grant permission?";
|
|
||||||
const REQUEST_DIALOG_MESSAGE: &'static str = "Do you want to grant permission for";
|
|
||||||
|
|
||||||
pub trait PermissionAlgorithm {
|
pub trait PermissionAlgorithm {
|
||||||
type Descriptor;
|
type Descriptor;
|
||||||
type Status;
|
type Status;
|
||||||
|
@ -256,10 +251,11 @@ impl PermissionAlgorithm for Permissions {
|
||||||
// Step 3.
|
// Step 3.
|
||||||
PermissionState::Prompt => {
|
PermissionState::Prompt => {
|
||||||
let perm_name = status.get_query();
|
let perm_name = status.get_query();
|
||||||
|
let prompt =
|
||||||
|
PermissionPrompt::Request(embedder_traits::PermissionName::from(perm_name));
|
||||||
|
|
||||||
// https://w3c.github.io/permissions/#request-permission-to-use (Step 3 - 4)
|
// https://w3c.github.io/permissions/#request-permission-to-use (Step 3 - 4)
|
||||||
let globalscope = GlobalScope::current().expect("No current global object");
|
let globalscope = GlobalScope::current().expect("No current global object");
|
||||||
let prompt = format!("{} {} ?", REQUEST_DIALOG_MESSAGE, perm_name.clone());
|
|
||||||
let state = prompt_user_from_embedder(prompt, &globalscope);
|
let state = prompt_user_from_embedder(prompt, &globalscope);
|
||||||
globalscope
|
globalscope
|
||||||
.permission_state_invocation_results()
|
.permission_state_invocation_results()
|
||||||
|
@ -305,8 +301,10 @@ pub fn get_descriptor_permission_state(
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.remove(&permission_name.to_string());
|
.remove(&permission_name.to_string());
|
||||||
|
|
||||||
let prompt = format!("The {} {}", permission_name, NONSECURE_DIALOG_MESSAGE);
|
prompt_user_from_embedder(
|
||||||
prompt_user_from_embedder(prompt, &globalscope)
|
PermissionPrompt::Insecure(embedder_traits::PermissionName::from(permission_name)),
|
||||||
|
&globalscope,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -357,13 +355,9 @@ fn allowed_in_nonsecure_contexts(permission_name: &PermissionName) -> bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prompt_user_from_embedder(prompt: String, gs: &GlobalScope) -> PermissionState {
|
fn prompt_user_from_embedder(prompt: PermissionPrompt, gs: &GlobalScope) -> PermissionState {
|
||||||
let (sender, receiver) = ipc::channel().expect("Failed to create IPC channel!");
|
let (sender, receiver) = ipc::channel().expect("Failed to create IPC channel!");
|
||||||
gs.send_to_embedder(EmbedderMsg::PromptPermission(
|
gs.send_to_embedder(EmbedderMsg::PromptPermission(prompt, sender));
|
||||||
prompt,
|
|
||||||
DIALOG_TITLE.to_string(),
|
|
||||||
sender,
|
|
||||||
));
|
|
||||||
|
|
||||||
match receiver.recv() {
|
match receiver.recv() {
|
||||||
Ok(PermissionRequest::Granted) => PermissionState::Granted,
|
Ok(PermissionRequest::Granted) => PermissionState::Granted,
|
||||||
|
@ -377,3 +371,23 @@ fn prompt_user_from_embedder(prompt: String, gs: &GlobalScope) -> PermissionStat
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<PermissionName> for embedder_traits::PermissionName {
|
||||||
|
fn from(permission_name: PermissionName) -> Self {
|
||||||
|
match permission_name {
|
||||||
|
PermissionName::Geolocation => embedder_traits::PermissionName::Geolocation,
|
||||||
|
PermissionName::Notifications => embedder_traits::PermissionName::Notifications,
|
||||||
|
PermissionName::Push => embedder_traits::PermissionName::Push,
|
||||||
|
PermissionName::Midi => embedder_traits::PermissionName::Midi,
|
||||||
|
PermissionName::Camera => embedder_traits::PermissionName::Camera,
|
||||||
|
PermissionName::Microphone => embedder_traits::PermissionName::Microphone,
|
||||||
|
PermissionName::Speaker => embedder_traits::PermissionName::Speaker,
|
||||||
|
PermissionName::Device_info => embedder_traits::PermissionName::DeviceInfo,
|
||||||
|
PermissionName::Background_sync => embedder_traits::PermissionName::BackgroundSync,
|
||||||
|
PermissionName::Bluetooth => embedder_traits::PermissionName::Bluetooth,
|
||||||
|
PermissionName::Persistent_storage => {
|
||||||
|
embedder_traits::PermissionName::PersistentStorage
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ use keyboard_types::{Key, KeyboardEvent, Modifiers, ShortcutMatcher};
|
||||||
use servo::compositing::windowing::{WebRenderDebugOption, WindowEvent};
|
use servo::compositing::windowing::{WebRenderDebugOption, WindowEvent};
|
||||||
use servo::embedder_traits::{
|
use servo::embedder_traits::{
|
||||||
EmbedderMsg, FilterPattern, PermissionRequest, PromptDefinition, PromptOrigin, PromptResult,
|
EmbedderMsg, FilterPattern, PermissionRequest, PromptDefinition, PromptOrigin, PromptResult,
|
||||||
|
PermissionPrompt,
|
||||||
};
|
};
|
||||||
use servo::msg::constellation_msg::TopLevelBrowsingContextId as BrowserId;
|
use servo::msg::constellation_msg::TopLevelBrowsingContextId as BrowserId;
|
||||||
use servo::msg::constellation_msg::TraversalDirection;
|
use servo::msg::constellation_msg::TraversalDirection;
|
||||||
|
@ -493,8 +494,8 @@ where
|
||||||
self.event_queue.push(WindowEvent::SendError(None, reason));
|
self.event_queue.push(WindowEvent::SendError(None, reason));
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
EmbedderMsg::PromptPermission(message, dialog_title, sender) => {
|
EmbedderMsg::PromptPermission(prompt, sender) => {
|
||||||
let permission_state = prompt_user(&message, &dialog_title);
|
let permission_state = prompt_user(prompt);
|
||||||
let _ = sender.send(permission_state);
|
let _ = sender.send(permission_state);
|
||||||
}
|
}
|
||||||
EmbedderMsg::ShowIME(_kind) => {
|
EmbedderMsg::ShowIME(_kind) => {
|
||||||
|
@ -520,13 +521,27 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
fn prompt_user(prompt: &str, dialog_title: &str) -> PermissionRequest {
|
fn prompt_user(prompt: PermissionPrompt) -> PermissionRequest {
|
||||||
if opts::get().headless {
|
if opts::get().headless {
|
||||||
return PermissionRequest::Denied;
|
return PermissionRequest::Denied;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let message = match prompt {
|
||||||
|
PermissionPrompt::Request(permission_name) => {
|
||||||
|
format!("Do you want to grant permission for {:?}?", permission_name)
|
||||||
|
},
|
||||||
|
PermissionPrompt::Insecure(permission_name) => {
|
||||||
|
format!(
|
||||||
|
"The {:?} feature is only safe to use in secure context, but servo can't guarantee\n\
|
||||||
|
that the current context is secure. Do you want to proceed and grant permission?",
|
||||||
|
permission_name
|
||||||
|
)
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
match tinyfiledialogs::message_box_yes_no(
|
match tinyfiledialogs::message_box_yes_no(
|
||||||
dialog_title,
|
"Permission request dialog",
|
||||||
prompt,
|
&message,
|
||||||
MessageBoxIcon::Question,
|
MessageBoxIcon::Question,
|
||||||
YesNo::No,
|
YesNo::No,
|
||||||
) {
|
) {
|
||||||
|
@ -536,7 +551,7 @@ fn prompt_user(prompt: &str, dialog_title: &str) -> PermissionRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_os = "linux"))]
|
#[cfg(not(target_os = "linux"))]
|
||||||
fn prompt_user(_prompt: &str, _dialog_title: &str) -> PermissionRequest {
|
fn prompt_user(_prompt: PermissionPrompt) -> PermissionRequest {
|
||||||
// TODO popup only supported on linux
|
// TODO popup only supported on linux
|
||||||
PermissionRequest::Denied
|
PermissionRequest::Denied
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue