Navigation Menu

Skip to content

Commit

Permalink
previous invocation results
Browse files Browse the repository at this point in the history
  • Loading branch information
Zakor Gyula committed Feb 14, 2017
1 parent 2de91c7 commit 462a825
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 30 deletions.
113 changes: 86 additions & 27 deletions components/script/dom/permissions.rs
Expand Up @@ -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;
Expand All @@ -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 {
Expand Down Expand Up @@ -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)
},
} }
}, },
_ => { _ => {
Expand All @@ -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);
},
} }
}, },
}; };
Expand Down Expand Up @@ -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,
Expand All @@ -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
} }
Expand Down
10 changes: 9 additions & 1 deletion components/script/dom/permissionstatus.rs
Expand Up @@ -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]
Expand Down Expand Up @@ -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 changes: 11 additions & 2 deletions components/script/dom/window.rs
Expand Up @@ -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};
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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"))]
Expand Down Expand Up @@ -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 {
Expand Down

0 comments on commit 462a825

Please sign in to comment.