mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
previous invocation results
This commit is contained in:
parent
2de91c7788
commit
462a825bd1
3 changed files with 106 additions and 30 deletions
|
@ -3,6 +3,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use dom::bindings::codegen::Bindings::PermissionStatusBinding::{PermissionDescriptor, PermissionName, PermissionState};
|
use dom::bindings::codegen::Bindings::PermissionStatusBinding::{PermissionDescriptor, PermissionName, PermissionState};
|
||||||
|
use dom::bindings::codegen::Bindings::PermissionStatusBinding::PermissionStatusMethods;
|
||||||
use dom::bindings::codegen::Bindings::PermissionsBinding::{self, PermissionsMethods};
|
use dom::bindings::codegen::Bindings::PermissionsBinding::{self, PermissionsMethods};
|
||||||
use dom::bindings::error::Error;
|
use dom::bindings::error::Error;
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::Root;
|
||||||
|
@ -22,9 +23,9 @@ use tinyfiledialogs::{self, MessageBoxIcon, YesNo};
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
const DIALOG_TITLE: &'static str = "Permission request dialog";
|
const DIALOG_TITLE: &'static str = "Permission request dialog";
|
||||||
#[cfg(target_os = "linux")]
|
const NONSECURE_DIALOG_MESSAGE: &'static str = "feature is only safe to use in secure context,\
|
||||||
const QUERY_DIALOG_MESSAGE: &'static str = "Can't guarantee, that the current context is secure.
|
but servo can't guarantee\n that the current context is secure. Do you want to proceed and grant permission?";
|
||||||
\t\tStill grant permission for";
|
const REQUEST_DIALOG_MESSAGE: &'static str = "Do you want to grant permission for";
|
||||||
const ROOT_DESC_CONVERSION_ERROR: &'static str = "Can't convert to an IDL value of type PermissionDescriptor";
|
const ROOT_DESC_CONVERSION_ERROR: &'static str = "Can't convert to an IDL value of type PermissionDescriptor";
|
||||||
|
|
||||||
pub trait PermissionAlgorithm {
|
pub trait PermissionAlgorithm {
|
||||||
|
@ -114,8 +115,17 @@ impl Permissions {
|
||||||
// (Query) Step 6 - 7.
|
// (Query) Step 6 - 7.
|
||||||
&Operation::Query => Bluetooth::permission_query(cx, &p, &bluetooth_desc, &result),
|
&Operation::Query => Bluetooth::permission_query(cx, &p, &bluetooth_desc, &result),
|
||||||
|
|
||||||
// (Revoke) Step 3 - 4.
|
&Operation::Revoke => {
|
||||||
&Operation::Revoke => Bluetooth::permission_revoke(&bluetooth_desc, &result),
|
// (Revoke) Step 3.
|
||||||
|
let globalscope = self.global();
|
||||||
|
globalscope.as_window()
|
||||||
|
.permission_state_invocation_results()
|
||||||
|
.borrow_mut()
|
||||||
|
.remove(&root_desc.name.to_string());
|
||||||
|
|
||||||
|
// (Revoke) Step 4.
|
||||||
|
Bluetooth::permission_revoke(&bluetooth_desc, &result)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -136,8 +146,18 @@ impl Permissions {
|
||||||
// (Query) Step 7.
|
// (Query) Step 7.
|
||||||
p.resolve_native(cx, &status);
|
p.resolve_native(cx, &status);
|
||||||
},
|
},
|
||||||
// (Revoke) Step 3 - 4.
|
|
||||||
&Operation::Revoke => Permissions::permission_revoke(&root_desc, &status),
|
&Operation::Revoke => {
|
||||||
|
// (Revoke) Step 3.
|
||||||
|
let globalscope = self.global();
|
||||||
|
globalscope.as_window()
|
||||||
|
.permission_state_invocation_results()
|
||||||
|
.borrow_mut()
|
||||||
|
.remove(&root_desc.name.to_string());
|
||||||
|
|
||||||
|
// (Revoke) Step 4.
|
||||||
|
Permissions::permission_revoke(&root_desc, &status);
|
||||||
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -210,46 +230,85 @@ impl PermissionAlgorithm for Permissions {
|
||||||
// Step 1.
|
// Step 1.
|
||||||
Permissions::permission_query(cx, promise, descriptor, status);
|
Permissions::permission_query(cx, promise, descriptor, status);
|
||||||
|
|
||||||
// TODO: Step 2 - 4: `environment settings object` is not implemented in Servo yet.
|
match status.State() {
|
||||||
// For this reason in the `get_descriptor_permission_state` function we can't decide
|
// Step 3.
|
||||||
// if we have a secure context or not, or store the previous invocation results.
|
PermissionState::Prompt => {
|
||||||
// Without these the remaining steps can't be implemented properly.
|
let perm_name = status.get_query();
|
||||||
|
// https://w3c.github.io/permissions/#request-permission-to-use (Step 3 - 4)
|
||||||
|
let state =
|
||||||
|
prompt_user(&format!("{} {} ?", REQUEST_DIALOG_MESSAGE, perm_name.clone()));
|
||||||
|
|
||||||
|
let globalscope = GlobalScope::current();
|
||||||
|
globalscope.as_window()
|
||||||
|
.permission_state_invocation_results()
|
||||||
|
.borrow_mut()
|
||||||
|
.insert(perm_name.to_string(), state);
|
||||||
|
},
|
||||||
|
|
||||||
|
// Step 2.
|
||||||
|
_ => return,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 4.
|
||||||
|
Permissions::permission_query(cx, promise, descriptor, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn permission_revoke(_descriptor: &PermissionDescriptor, _status: &PermissionStatus) {}
|
fn permission_revoke(_descriptor: &PermissionDescriptor, _status: &PermissionStatus) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://w3c.github.io/permissions/#permission-state
|
// https://w3c.github.io/permissions/#permission-state
|
||||||
pub fn get_descriptor_permission_state(permission_name: PermissionName ,
|
pub fn get_descriptor_permission_state(permission_name: PermissionName,
|
||||||
_env_settings_obj: Option<*mut JSObject>)
|
env_settings_obj: Option<&GlobalScope>)
|
||||||
-> PermissionState {
|
-> PermissionState {
|
||||||
// TODO: Step 1: If settings wasn’t passed, set it to the current settings object.
|
// Step 1.
|
||||||
// TODO: `environment settings object` is not implemented in Servo yet.
|
let settings = match env_settings_obj {
|
||||||
|
Some(env_settings_obj) => Root::from_ref(env_settings_obj),
|
||||||
|
None => GlobalScope::current(),
|
||||||
|
};
|
||||||
|
|
||||||
// Step 2.
|
// Step 2.
|
||||||
// TODO: The `is the environment settings object a non-secure context` check is missing.
|
// TODO: The `is the environment settings object a non-secure context` check is missing.
|
||||||
// The current solution is a workaround with a message box to warn about this,
|
// The current solution is a workaround with a message box to warn about this,
|
||||||
// if the feature is not allowed in non-secure contexcts,
|
// if the feature is not allowed in non-secure contexcts,
|
||||||
// and let the user decide to grant the permission or not.
|
// and let the user decide to grant the permission or not.
|
||||||
if !allowed_in_nonsecure_contexts(&permission_name) {
|
let state = match allowed_in_nonsecure_contexts(&permission_name) {
|
||||||
if PREFS.get("dom.permissions.testing.allowed_in_nonsecure_contexts").as_boolean().unwrap_or(false) {
|
true => PermissionState::Prompt,
|
||||||
return PermissionState::Granted;
|
false => {
|
||||||
} else {
|
match PREFS.get("dom.permissions.testing.allowed_in_nonsecure_contexts").as_boolean().unwrap_or(false) {
|
||||||
return prompt_user(permission_name);
|
true => PermissionState::Granted,
|
||||||
}
|
false => {
|
||||||
|
settings.as_window()
|
||||||
|
.permission_state_invocation_results()
|
||||||
|
.borrow_mut()
|
||||||
|
.remove(&permission_name.to_string());
|
||||||
|
prompt_user(&format!("The {} {}", permission_name, NONSECURE_DIALOG_MESSAGE))
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Step 3.
|
||||||
|
if let Some(prev_result) = settings.as_window()
|
||||||
|
.permission_state_invocation_results()
|
||||||
|
.borrow()
|
||||||
|
.get(&permission_name.to_string()) {
|
||||||
|
return prev_result.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Step 3: Store the invocation results
|
// Store the invocation result
|
||||||
// TODO: `environment settings object` is not implemented in Servo yet.
|
settings.as_window()
|
||||||
|
.permission_state_invocation_results()
|
||||||
|
.borrow_mut()
|
||||||
|
.insert(permission_name.to_string(), state);
|
||||||
|
|
||||||
// Step 4.
|
// Step 4.
|
||||||
PermissionState::Granted
|
state
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
fn prompt_user(permission_name: PermissionName) -> PermissionState {
|
fn prompt_user(message: &str) -> PermissionState {
|
||||||
match tinyfiledialogs::message_box_yes_no(DIALOG_TITLE,
|
match tinyfiledialogs::message_box_yes_no(DIALOG_TITLE,
|
||||||
&format!("{} {:?} ?", QUERY_DIALOG_MESSAGE, permission_name),
|
message,
|
||||||
MessageBoxIcon::Question,
|
MessageBoxIcon::Question,
|
||||||
YesNo::No) {
|
YesNo::No) {
|
||||||
YesNo::Yes => PermissionState::Granted,
|
YesNo::Yes => PermissionState::Granted,
|
||||||
|
@ -258,7 +317,7 @@ fn prompt_user(permission_name: PermissionName) -> PermissionState {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_os = "linux"))]
|
#[cfg(not(target_os = "linux"))]
|
||||||
fn prompt_user(_permission_name: PermissionName) -> PermissionState {
|
fn prompt_user(_message: &str) -> PermissionState {
|
||||||
// TODO popup only supported on linux
|
// TODO popup only supported on linux
|
||||||
PermissionState::Denied
|
PermissionState::Denied
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,12 +4,14 @@
|
||||||
|
|
||||||
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
|
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
|
||||||
use dom::bindings::codegen::Bindings::PermissionStatusBinding::{self, PermissionDescriptor, PermissionName};
|
use dom::bindings::codegen::Bindings::PermissionStatusBinding::{self, PermissionDescriptor, PermissionName};
|
||||||
use dom::bindings::codegen::Bindings::PermissionStatusBinding::{PermissionState, PermissionStatusMethods};
|
use dom::bindings::codegen::Bindings::PermissionStatusBinding::{PermissionNameValues, PermissionState};
|
||||||
|
use dom::bindings::codegen::Bindings::PermissionStatusBinding::PermissionStatusMethods;
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::reflector::reflect_dom_object;
|
use dom::bindings::reflector::reflect_dom_object;
|
||||||
use dom::eventtarget::EventTarget;
|
use dom::eventtarget::EventTarget;
|
||||||
use dom::globalscope::GlobalScope;
|
use dom::globalscope::GlobalScope;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
use std::fmt::{self, Display, Formatter};
|
||||||
|
|
||||||
// https://w3c.github.io/permissions/#permissionstatus
|
// https://w3c.github.io/permissions/#permissionstatus
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
|
@ -52,3 +54,9 @@ impl PermissionStatusMethods for PermissionStatus {
|
||||||
// https://w3c.github.io/permissions/#dom-permissionstatus-onchange
|
// https://w3c.github.io/permissions/#dom-permissionstatus-onchange
|
||||||
event_handler!(onchange, GetOnchange, SetOnchange);
|
event_handler!(onchange, GetOnchange, SetOnchange);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for PermissionName {
|
||||||
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||||
|
write!(f, "{}", PermissionNameValues::strings[*self as usize].to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ use dom::bindings::codegen::Bindings::EventHandlerBinding::OnBeforeUnloadEventHa
|
||||||
use dom::bindings::codegen::Bindings::EventHandlerBinding::OnErrorEventHandlerNonNull;
|
use dom::bindings::codegen::Bindings::EventHandlerBinding::OnErrorEventHandlerNonNull;
|
||||||
use dom::bindings::codegen::Bindings::FunctionBinding::Function;
|
use dom::bindings::codegen::Bindings::FunctionBinding::Function;
|
||||||
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
|
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
|
||||||
|
use dom::bindings::codegen::Bindings::PermissionStatusBinding::PermissionState;
|
||||||
use dom::bindings::codegen::Bindings::RequestBinding::RequestInit;
|
use dom::bindings::codegen::Bindings::RequestBinding::RequestInit;
|
||||||
use dom::bindings::codegen::Bindings::WindowBinding::{self, FrameRequestCallback, WindowMethods};
|
use dom::bindings::codegen::Bindings::WindowBinding::{self, FrameRequestCallback, WindowMethods};
|
||||||
use dom::bindings::codegen::Bindings::WindowBinding::{ScrollBehavior, ScrollToOptions};
|
use dom::bindings::codegen::Bindings::WindowBinding::{ScrollBehavior, ScrollToOptions};
|
||||||
|
@ -249,7 +250,10 @@ pub struct Window {
|
||||||
|
|
||||||
/// A handle for communicating messages to the webvr thread, if available.
|
/// A handle for communicating messages to the webvr thread, if available.
|
||||||
#[ignore_heap_size_of = "channels are hard"]
|
#[ignore_heap_size_of = "channels are hard"]
|
||||||
webvr_thread: Option<IpcSender<WebVRMsg>>
|
webvr_thread: Option<IpcSender<WebVRMsg>>,
|
||||||
|
|
||||||
|
/// A map for storing the previous permission state read results.
|
||||||
|
permission_state_invocation_results: DOMRefCell<HashMap<String, PermissionState>>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Window {
|
impl Window {
|
||||||
|
@ -338,6 +342,10 @@ impl Window {
|
||||||
pub fn webvr_thread(&self) -> Option<IpcSender<WebVRMsg>> {
|
pub fn webvr_thread(&self) -> Option<IpcSender<WebVRMsg>> {
|
||||||
self.webvr_thread.clone()
|
self.webvr_thread.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn permission_state_invocation_results(&self) -> &DOMRefCell<HashMap<String, PermissionState>> {
|
||||||
|
&self.permission_state_invocation_results
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))]
|
#[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))]
|
||||||
|
@ -1704,7 +1712,8 @@ impl Window {
|
||||||
scroll_offsets: DOMRefCell::new(HashMap::new()),
|
scroll_offsets: DOMRefCell::new(HashMap::new()),
|
||||||
media_query_lists: WeakMediaQueryListVec::new(),
|
media_query_lists: WeakMediaQueryListVec::new(),
|
||||||
test_runner: Default::default(),
|
test_runner: Default::default(),
|
||||||
webvr_thread: webvr_thread
|
webvr_thread: webvr_thread,
|
||||||
|
permission_state_invocation_results: DOMRefCell::new(HashMap::new()),
|
||||||
};
|
};
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue