mirror of
https://github.com/servo/servo.git
synced 2025-07-28 09:40:33 +01:00
* script: Move num module to script_bindings. Signed-off-by: Josh Matthews <josh@joshmatthews.net> * script: Make JS reflector creation generic over DOM trait. Signed-off-by: Josh Matthews <josh@joshmatthews.net> * script: Move bindings-specific lock to script_bindings. Signed-off-by: Josh Matthews <josh@joshmatthews.net> * script: Move DOM proto array code to script_bindings. Signed-off-by: Josh Matthews <josh@joshmatthews.net> * script: Move finalizer implementations to script_bindings. Signed-off-by: Josh Matthews <josh@joshmatthews.net> * script: Move some error routines to script_bindings. Signed-off-by: Josh Matthews <josh@joshmatthews.net> * script: Move some DOM interface conversion routines to script_bindings. Signed-off-by: Josh Matthews <josh@joshmatthews.net> * script: Make is_array_like generic over DOM trait. Signed-off-by: Josh Matthews <josh@joshmatthews.net> * script: Use generic interfaces for conditional exposure functions. Signed-off-by: Josh Matthews <josh@joshmatthews.net> * script: Move a bunch of routines used by codegen to script_bindings. Signed-off-by: Josh Matthews <josh@joshmatthews.net> * Formatting. Signed-off-by: Josh Matthews <josh@joshmatthews.net> * Fix clippy warnings. Signed-off-by: Josh Matthews <josh@joshmatthews.net> --------- Signed-off-by: Josh Matthews <josh@joshmatthews.net>
96 lines
3.1 KiB
Rust
96 lines
3.1 KiB
Rust
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
|
|
//! Machinery to conditionally expose things.
|
|
|
|
use js::rust::HandleObject;
|
|
use script_bindings::codegen::Globals::Globals;
|
|
use servo_config::prefs::get;
|
|
|
|
use crate::DomTypes;
|
|
use crate::dom::bindings::interface::is_exposed_in;
|
|
use crate::dom::globalscope::GlobalScopeHelpers;
|
|
use crate::realms::{AlreadyInRealm, InRealm};
|
|
use crate::script_runtime::JSContext;
|
|
|
|
/// A container with a list of conditions.
|
|
pub(crate) struct Guard<T: Clone + Copy> {
|
|
conditions: &'static [Condition],
|
|
value: T,
|
|
}
|
|
|
|
impl<T: Clone + Copy> Guard<T> {
|
|
/// Construct a new guarded value.
|
|
pub(crate) const fn new(conditions: &'static [Condition], value: T) -> Self {
|
|
Guard { conditions, value }
|
|
}
|
|
|
|
/// Expose the value if the conditions are satisfied.
|
|
///
|
|
/// The passed handle is the object on which the value may be exposed.
|
|
pub(crate) fn expose<D: DomTypes>(
|
|
&self,
|
|
cx: JSContext,
|
|
obj: HandleObject,
|
|
global: HandleObject,
|
|
) -> Option<T> {
|
|
let mut exposed_on_global = false;
|
|
let conditions_satisfied = self.conditions.iter().all(|c| match c {
|
|
Condition::Satisfied => {
|
|
exposed_on_global = true;
|
|
true
|
|
},
|
|
// If there are multiple Exposed conditions, we just need one of them to be true
|
|
Condition::Exposed(globals) => {
|
|
exposed_on_global |= is_exposed_in(global, *globals);
|
|
true
|
|
},
|
|
_ => c.is_satisfied::<D>(cx, obj, global),
|
|
});
|
|
|
|
if conditions_satisfied && exposed_on_global {
|
|
Some(self.value)
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
}
|
|
|
|
/// A condition to expose things.
|
|
#[derive(Clone, Copy)]
|
|
pub(crate) enum Condition {
|
|
/// The condition is satisfied if the function returns true.
|
|
Func(fn(JSContext, HandleObject) -> bool),
|
|
/// The condition is satisfied if the preference is set.
|
|
Pref(&'static str),
|
|
// The condition is satisfied if the interface is exposed in the global.
|
|
Exposed(Globals),
|
|
SecureContext(),
|
|
/// The condition is always satisfied.
|
|
Satisfied,
|
|
}
|
|
|
|
fn is_secure_context<D: DomTypes>(cx: JSContext) -> bool {
|
|
unsafe {
|
|
let in_realm_proof = AlreadyInRealm::assert_for_cx(JSContext::from_ptr(*cx));
|
|
D::GlobalScope::from_context(*cx, InRealm::Already(&in_realm_proof)).is_secure_context()
|
|
}
|
|
}
|
|
|
|
impl Condition {
|
|
pub(crate) fn is_satisfied<D: DomTypes>(
|
|
&self,
|
|
cx: JSContext,
|
|
obj: HandleObject,
|
|
global: HandleObject,
|
|
) -> bool {
|
|
match *self {
|
|
Condition::Pref(name) => get().get_value(name).try_into().unwrap_or(false),
|
|
Condition::Func(f) => f(cx, obj),
|
|
Condition::Exposed(globals) => is_exposed_in(global, globals),
|
|
Condition::SecureContext() => is_secure_context::<D>(cx),
|
|
Condition::Satisfied => true,
|
|
}
|
|
}
|
|
}
|