mirror of
https://github.com/servo/servo.git
synced 2025-09-30 00:29:14 +01:00
servoshell: Support runtime preference manipulation (#38159)
These changes add a custom servo:preferences URL that allows modifying selected preferences at runtime. The goal of this work is to make it easy to test pages while toggling experimental web platform features, and support quickly changing the User-Agent header. Testing: Manually verified that spacex.com loads correctly after changing the user agent, and that https://polygon.io/ displays grid elements correctly and no console errors with the experimental prefs enabled. Fixes: #35862 <img width="1136" height="880" alt="Screenshot 2025-07-18 at 1 06 23 AM" src="https://github.com/user-attachments/assets/2d27c321-6ca0-43c3-a347-7bc4b55272df" /> --------- Signed-off-by: Josh Matthews <josh@joshmatthews.net>
This commit is contained in:
parent
c97ec1b2fb
commit
6565d982bd
13 changed files with 308 additions and 25 deletions
|
@ -8,11 +8,13 @@ use constellation_traits::ScriptToConstellationMessage;
|
|||
use dom_struct::dom_struct;
|
||||
use js::rust::HandleObject;
|
||||
use profile_traits::mem::MemoryReportResult;
|
||||
use script_bindings::error::{Error, Fallible};
|
||||
use script_bindings::interfaces::ServoInternalsHelpers;
|
||||
use script_bindings::script_runtime::JSContext;
|
||||
use script_bindings::str::USVString;
|
||||
use servo_config::prefs::{self, PrefValue};
|
||||
|
||||
use crate::dom::bindings::codegen::Bindings::ServoInternalsBinding::ServoInternalsMethods;
|
||||
use crate::dom::bindings::error::Error;
|
||||
use crate::dom::bindings::reflector::{DomGlobal, Reflector, reflect_dom_object};
|
||||
use crate::dom::bindings::root::DomRoot;
|
||||
use crate::dom::globalscope::GlobalScope;
|
||||
|
@ -20,6 +22,7 @@ use crate::dom::promise::Promise;
|
|||
use crate::realms::{AlreadyInRealm, InRealm};
|
||||
use crate::routed_promise::{RoutedPromiseListener, route_promise};
|
||||
use crate::script_runtime::CanGc;
|
||||
use crate::script_thread::ScriptThread;
|
||||
|
||||
#[dom_struct]
|
||||
pub(crate) struct ServoInternals {
|
||||
|
@ -55,6 +58,51 @@ impl ServoInternalsMethods<crate::DomTypeHolder> for ServoInternals {
|
|||
}
|
||||
promise
|
||||
}
|
||||
|
||||
/// <https://servo.org/internal-no-spec>
|
||||
fn GetBoolPreference(&self, name: USVString) -> Fallible<bool> {
|
||||
if let PrefValue::Bool(b) = prefs::get().get_value(&name) {
|
||||
return Ok(b);
|
||||
}
|
||||
Err(Error::TypeMismatch)
|
||||
}
|
||||
|
||||
/// <https://servo.org/internal-no-spec>
|
||||
fn GetIntPreference(&self, name: USVString) -> Fallible<i64> {
|
||||
if let PrefValue::Int(i) = prefs::get().get_value(&name) {
|
||||
return Ok(i);
|
||||
}
|
||||
Err(Error::TypeMismatch)
|
||||
}
|
||||
|
||||
/// <https://servo.org/internal-no-spec>
|
||||
fn GetStringPreference(&self, name: USVString) -> Fallible<USVString> {
|
||||
if let PrefValue::Str(s) = prefs::get().get_value(&name) {
|
||||
return Ok(s.into());
|
||||
}
|
||||
Err(Error::TypeMismatch)
|
||||
}
|
||||
|
||||
/// <https://servo.org/internal-no-spec>
|
||||
fn SetBoolPreference(&self, name: USVString, value: bool) {
|
||||
let mut current_prefs = prefs::get().clone();
|
||||
current_prefs.set_value(&name, value.into());
|
||||
prefs::set(current_prefs);
|
||||
}
|
||||
|
||||
/// <https://servo.org/internal-no-spec>
|
||||
fn SetIntPreference(&self, name: USVString, value: i64) {
|
||||
let mut current_prefs = prefs::get().clone();
|
||||
current_prefs.set_value(&name, value.into());
|
||||
prefs::set(current_prefs);
|
||||
}
|
||||
|
||||
/// <https://servo.org/internal-no-spec>
|
||||
fn SetStringPreference(&self, name: USVString, value: USVString) {
|
||||
let mut current_prefs = prefs::get().clone();
|
||||
current_prefs.set_value(&name, value.0.into());
|
||||
prefs::set(current_prefs);
|
||||
}
|
||||
}
|
||||
|
||||
impl RoutedPromiseListener<MemoryReportResult> for ServoInternals {
|
||||
|
@ -66,14 +114,16 @@ impl RoutedPromiseListener<MemoryReportResult> for ServoInternals {
|
|||
}
|
||||
|
||||
impl ServoInternalsHelpers for ServoInternals {
|
||||
/// The navigator.servo api is only exposed to about: pages except about:blank
|
||||
/// The navigator.servo api is exposed to about: pages except about:blank, as
|
||||
/// well as any URLs provided by embedders that register new protocol handlers.
|
||||
#[allow(unsafe_code)]
|
||||
fn is_servo_internal(cx: JSContext, _global: HandleObject) -> bool {
|
||||
unsafe {
|
||||
let in_realm_proof = AlreadyInRealm::assert_for_cx(cx);
|
||||
let global_scope = GlobalScope::from_context(*cx, InRealm::Already(&in_realm_proof));
|
||||
let url = global_scope.get_url();
|
||||
url.scheme() == "about" && url.as_str() != "about:blank"
|
||||
(url.scheme() == "about" && url.as_str() != "about:blank") ||
|
||||
ScriptThread::is_servo_privileged(url)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -346,6 +346,10 @@ pub struct ScriptThread {
|
|||
needs_rendering_update: Arc<AtomicBool>,
|
||||
|
||||
debugger_global: Dom<DebuggerGlobalScope>,
|
||||
|
||||
/// A list of URLs that can access privileged internal APIs.
|
||||
#[no_trace]
|
||||
privileged_urls: Vec<ServoUrl>,
|
||||
}
|
||||
|
||||
struct BHMExitSignal {
|
||||
|
@ -1016,6 +1020,7 @@ impl ScriptThread {
|
|||
scheduled_update_the_rendering: Default::default(),
|
||||
needs_rendering_update: Arc::new(AtomicBool::new(false)),
|
||||
debugger_global: debugger_global.as_traced(),
|
||||
privileged_urls: state.privileged_urls,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4030,6 +4035,10 @@ impl ScriptThread {
|
|||
};
|
||||
document.event_handler().handle_refresh_cursor();
|
||||
}
|
||||
|
||||
pub(crate) fn is_servo_privileged(url: ServoUrl) -> bool {
|
||||
with_script_thread(|script_thread| script_thread.privileged_urls.contains(&url))
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for ScriptThread {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue