/
githubmirror
/
servo
Обзор
Документация
Войти
/
githubmirror
/
servo
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
components/script_bindings/guard.rs
94 строки
3 KB
Tim van der Lippe
script: Pass `&mut JSContext` to conversions (#46229)
04 июл 2026, 09:25
Не верифицирован
04 июл 2026, 09:25
f2e8e12
Код
Авторство
О чём код?
/* 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::context::JSContext; use js::realm::CurrentRealm; use js::rust::HandleObject; use servo_config::prefs::get; use crate::DomTypes; use crate::codegen::Globals::Globals; use crate::interface::is_exposed_in; use crate::interfaces::GlobalScopeHelpers; /// 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: &mut 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(&mut 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: &mut JSContext) -> bool { let mut realm = CurrentRealm::assert(cx); D::GlobalScope::from_current_realm(&mut realm).is_secure_context() } impl Condition { pub(crate) fn is_satisfied<D: DomTypes>( &self, cx: &mut 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, } } }