aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock1
-rw-r--r--components/embedder_traits/lib.rs11
-rw-r--r--components/script/Cargo.toml3
-rw-r--r--components/script/dom/globalscope.rs9
-rw-r--r--components/script/dom/permissions.rs72
-rw-r--r--ports/glutin/browser.rs30
6 files changed, 81 insertions, 45 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 2c561e97ff5..8aca24486c2 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4762,7 +4762,6 @@ dependencies = [
"swapper",
"tendril",
"time",
- "tinyfiledialogs",
"unicode-bidi",
"unicode-segmentation",
"url",
diff --git a/components/embedder_traits/lib.rs b/components/embedder_traits/lib.rs
index c13ad617920..71eb7876eca 100644
--- a/components/embedder_traits/lib.rs
+++ b/components/embedder_traits/lib.rs
@@ -185,6 +185,9 @@ pub enum EmbedderMsg {
GetSelectedBluetoothDevice(Vec<String>, IpcSender<Option<String>>),
/// Open file dialog to select files. Set boolean flag to true allows to select multiple files.
SelectFiles(Vec<FilterPattern>, bool, IpcSender<Option<Vec<String>>>),
+ /// Open yes/no message for user to allow permission specified by first String.
+ /// With dialog title specified by second String.
+ PromptPermission(String, String, IpcSender<PermissionRequest>),
/// Request to present an IME to the user when an editable element is focused.
ShowIME(InputMethodType),
/// Request to hide the IME when the editable element is blurred.
@@ -222,6 +225,7 @@ impl Debug for EmbedderMsg {
EmbedderMsg::Panic(..) => write!(f, "Panic"),
EmbedderMsg::GetSelectedBluetoothDevice(..) => write!(f, "GetSelectedBluetoothDevice"),
EmbedderMsg::SelectFiles(..) => write!(f, "SelectFiles"),
+ EmbedderMsg::PromptPermission(..) => write!(f, "PromptPermission"),
EmbedderMsg::ShowIME(..) => write!(f, "ShowIME"),
EmbedderMsg::HideIME => write!(f, "HideIME"),
EmbedderMsg::Shutdown => write!(f, "Shutdown"),
@@ -299,3 +303,10 @@ pub enum MediaSessionEvent {
/// Indicates that the position state is set.
SetPositionState(MediaPositionState),
}
+
+// Status for prompting user for permission.
+#[derive(Clone, Debug, Deserialize, Serialize)]
+pub enum PermissionRequest {
+ Granted,
+ Denied,
+}
diff --git a/components/script/Cargo.toml b/components/script/Cargo.toml
index 03eac6cae65..9c5995c1c89 100644
--- a/components/script/Cargo.toml
+++ b/components/script/Cargo.toml
@@ -29,9 +29,6 @@ phf_codegen = "0.8"
phf_shared = "0.8"
serde_json = "1.0"
-[target.'cfg(target_os = "linux")'.dependencies]
-tinyfiledialogs = "3.0"
-
[dependencies]
accountable-refcell = {version = "0.2.0", optional = true}
app_units = "0.7"
diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs
index e631c9bfc9c..f46a07bbcb2 100644
--- a/components/script/dom/globalscope.rs
+++ b/components/script/dom/globalscope.rs
@@ -61,6 +61,7 @@ use crate::timers::{OneshotTimers, TimerCallback};
use content_security_policy::CspList;
use devtools_traits::{PageError, ScriptToDevtoolsControlMsg};
use dom_struct::dom_struct;
+use embedder_traits::EmbedderMsg;
use ipc_channel::ipc::{self, IpcSender};
use ipc_channel::router::ROUTER;
use js::glue::{IsWrapper, UnwrapObjectDynamic};
@@ -1917,6 +1918,14 @@ impl GlobalScope {
&self.script_to_constellation_chan
}
+ pub fn send_to_embedder(&self, msg: EmbedderMsg) {
+ self.send_to_constellation(ScriptMsg::ForwardToEmbedder(msg));
+ }
+
+ pub fn send_to_constellation(&self, msg: ScriptMsg) {
+ self.script_to_constellation_chan().send(msg).unwrap();
+ }
+
pub fn scheduler_chan(&self) -> &IpcSender<TimerSchedulerMsg> {
&self.scheduler_chan
}
diff --git a/components/script/dom/permissions.rs b/components/script/dom/permissions.rs
index e31ce563262..e456571cbc3 100644
--- a/components/script/dom/permissions.rs
+++ b/components/script/dom/permissions.rs
@@ -19,15 +19,14 @@ use crate::dom::promise::Promise;
use crate::realms::{AlreadyInRealm, InRealm};
use crate::script_runtime::JSContext;
use dom_struct::dom_struct;
+use embedder_traits::{EmbedderMsg, PermissionRequest};
+use ipc_channel::ipc;
use js::conversions::ConversionResult;
use js::jsapi::JSObject;
use js::jsval::{ObjectValue, UndefinedValue};
use servo_config::pref;
use std::rc::Rc;
-#[cfg(target_os = "linux")]
-use tinyfiledialogs::{self, MessageBoxIcon, YesNo};
-#[cfg(target_os = "linux")]
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?";
@@ -258,14 +257,10 @@ impl PermissionAlgorithm for Permissions {
PermissionState::Prompt => {
let perm_name = status.get_query();
- let globalscope = GlobalScope::current().expect("No current global object");
-
// https://w3c.github.io/permissions/#request-permission-to-use (Step 3 - 4)
- let state = prompt_user(
- &format!("{} {} ?", REQUEST_DIALOG_MESSAGE, perm_name.clone()),
- globalscope.is_headless(),
- );
-
+ 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);
globalscope
.permission_state_invocation_results()
.borrow_mut()
@@ -289,7 +284,7 @@ pub fn get_descriptor_permission_state(
env_settings_obj: Option<&GlobalScope>,
) -> PermissionState {
// Step 1.
- let settings = match env_settings_obj {
+ let globalscope = match env_settings_obj {
Some(env_settings_obj) => DomRoot::from_ref(env_settings_obj),
None => GlobalScope::current().expect("No current global object"),
};
@@ -305,20 +300,18 @@ pub fn get_descriptor_permission_state(
if pref!(dom.permissions.testing.allowed_in_nonsecure_contexts) {
PermissionState::Granted
} else {
- settings
+ globalscope
.permission_state_invocation_results()
.borrow_mut()
.remove(&permission_name.to_string());
- prompt_user(
- &format!("The {} {}", permission_name, NONSECURE_DIALOG_MESSAGE),
- settings.is_headless(),
- )
+ let prompt = format!("The {} {}", permission_name, NONSECURE_DIALOG_MESSAGE);
+ prompt_user_from_embedder(prompt, &globalscope)
}
};
// Step 3.
- if let Some(prev_result) = settings
+ if let Some(prev_result) = globalscope
.permission_state_invocation_results()
.borrow()
.get(&permission_name.to_string())
@@ -327,7 +320,7 @@ pub fn get_descriptor_permission_state(
}
// Store the invocation result
- settings
+ globalscope
.permission_state_invocation_results()
.borrow_mut()
.insert(permission_name.to_string(), state);
@@ -336,28 +329,6 @@ pub fn get_descriptor_permission_state(
state
}
-#[cfg(target_os = "linux")]
-fn prompt_user(message: &str, headless: bool) -> PermissionState {
- if headless {
- return PermissionState::Denied;
- }
- match tinyfiledialogs::message_box_yes_no(
- DIALOG_TITLE,
- message,
- MessageBoxIcon::Question,
- YesNo::No,
- ) {
- YesNo::Yes => PermissionState::Granted,
- YesNo::No => PermissionState::Denied,
- }
-}
-
-#[cfg(not(target_os = "linux"))]
-fn prompt_user(_message: &str, _headless: bool) -> PermissionState {
- // TODO popup only supported on linux
- PermissionState::Denied
-}
-
// https://w3c.github.io/permissions/#allowed-in-non-secure-contexts
fn allowed_in_nonsecure_contexts(permission_name: &PermissionName) -> bool {
match *permission_name {
@@ -385,3 +356,24 @@ fn allowed_in_nonsecure_contexts(permission_name: &PermissionName) -> bool {
PermissionName::Persistent_storage => false,
}
}
+
+fn prompt_user_from_embedder(prompt: String, gs: &GlobalScope) -> PermissionState {
+ let (sender, receiver) = ipc::channel().expect("Failed to create IPC channel!");
+ gs.send_to_embedder(EmbedderMsg::PromptPermission(
+ prompt,
+ DIALOG_TITLE.to_string(),
+ sender,
+ ));
+
+ match receiver.recv() {
+ Ok(PermissionRequest::Granted) => PermissionState::Granted,
+ Ok(PermissionRequest::Denied) => PermissionState::Denied,
+ Err(e) => {
+ warn!(
+ "Failed to receive permission state from embedder ({:?}).",
+ e
+ );
+ PermissionState::Denied
+ },
+ }
+}
diff --git a/ports/glutin/browser.rs b/ports/glutin/browser.rs
index 1b21bfebf5f..b250a38662a 100644
--- a/ports/glutin/browser.rs
+++ b/ports/glutin/browser.rs
@@ -7,7 +7,9 @@ use crate::window_trait::{WindowPortsMethods, LINE_HEIGHT};
use euclid::{Point2D, Vector2D};
use keyboard_types::{Key, KeyboardEvent, Modifiers, ShortcutMatcher};
use servo::compositing::windowing::{WebRenderDebugOption, WindowEvent};
-use servo::embedder_traits::{EmbedderMsg, FilterPattern, PromptDefinition, PromptOrigin, PromptResult};
+use servo::embedder_traits::{
+ EmbedderMsg, FilterPattern, PermissionRequest, PromptDefinition, PromptOrigin, PromptResult,
+};
use servo::msg::constellation_msg::TopLevelBrowsingContextId as BrowserId;
use servo::msg::constellation_msg::TraversalDirection;
use servo::net_traits::pub_domains::is_reg_domain;
@@ -491,6 +493,10 @@ where
self.event_queue.push(WindowEvent::SendError(None, reason));
};
},
+ EmbedderMsg::PromptPermission(message, dialog_title, sender) => {
+ let permission_state = prompt_user(&message, &dialog_title);
+ let _ = sender.send(permission_state);
+ }
EmbedderMsg::ShowIME(_kind) => {
debug!("ShowIME received");
},
@@ -514,6 +520,28 @@ where
}
#[cfg(target_os = "linux")]
+fn prompt_user(prompt: &str, dialog_title: &str) -> PermissionRequest {
+ if opts::get().headless {
+ return PermissionRequest::Denied;
+ }
+ match tinyfiledialogs::message_box_yes_no(
+ dialog_title,
+ prompt,
+ MessageBoxIcon::Question,
+ YesNo::No,
+ ) {
+ YesNo::Yes => PermissionRequest::Granted,
+ YesNo::No => PermissionRequest::Denied,
+ }
+}
+
+#[cfg(not(target_os = "linux"))]
+fn prompt_user(_prompt: &str, _dialog_title: &str) -> PermissionRequest {
+ // TODO popup only supported on linux
+ PermissionRequest::Denied
+}
+
+#[cfg(target_os = "linux")]
fn platform_get_selected_devices(devices: Vec<String>) -> Option<String> {
let picker_name = "Choose a device";