Rewild Your Web
web
browser
dweb
1--- original
2+++ modified
3@@ -9,14 +9,16 @@
4 use js::rust::HandleObject;
5 use profile_traits::mem::MemoryReportResult;
6 use script_bindings::error::{Error, Fallible};
7-use script_bindings::interfaces::ServoInternalsHelpers;
8+use script_bindings::interfaces::{EmbedderHelpers, ServoInternalsHelpers};
9 use script_bindings::script_runtime::JSContext;
10 use script_bindings::str::USVString;
11+use servo_config::embedder_prefs;
12 use servo_config::prefs::{self, PrefValue};
13
14 use crate::dom::bindings::codegen::Bindings::ServoInternalsBinding::ServoInternalsMethods;
15 use crate::dom::bindings::reflector::{DomGlobal, Reflector, reflect_dom_object};
16 use crate::dom::bindings::root::DomRoot;
17+use crate::dom::embedder::Embedder;
18 use crate::dom::globalscope::GlobalScope;
19 use crate::dom::promise::Promise;
20 use crate::realms::{AlreadyInRealm, InRealm};
21@@ -61,8 +63,17 @@
22
23 /// <https://servo.org/internal-no-spec>
24 fn GetBoolPreference(&self, name: USVString) -> Fallible<bool> {
25- if let PrefValue::Bool(b) = prefs::get().get_value(&name) {
26- return Ok(b);
27+ // Check if this is an embedder preference (contains a namespace separator)
28+ if name.contains('.') {
29+ // Look up in embedder preferences registry
30+ if let Some(PrefValue::Bool(b)) = prefs::get_embedder_pref(&name) {
31+ return Ok(b);
32+ }
33+ } else {
34+ // Core Servo preference
35+ if let PrefValue::Bool(b) = prefs::get().get_value(&name) {
36+ return Ok(b);
37+ }
38 }
39 Err(Error::TypeMismatch(None))
40 }
41@@ -69,8 +80,17 @@
42
43 /// <https://servo.org/internal-no-spec>
44 fn GetIntPreference(&self, name: USVString) -> Fallible<i64> {
45- if let PrefValue::Int(i) = prefs::get().get_value(&name) {
46- return Ok(i);
47+ // Check if this is an embedder preference (contains a namespace separator)
48+ if name.contains('.') {
49+ // Look up in embedder preferences registry
50+ if let Some(PrefValue::Int(i)) = prefs::get_embedder_pref(&name) {
51+ return Ok(i);
52+ }
53+ } else {
54+ // Core Servo preference
55+ if let PrefValue::Int(i) = prefs::get().get_value(&name) {
56+ return Ok(i);
57+ }
58 }
59 Err(Error::TypeMismatch(None))
60 }
61@@ -77,8 +97,17 @@
62
63 /// <https://servo.org/internal-no-spec>
64 fn GetStringPreference(&self, name: USVString) -> Fallible<USVString> {
65- if let PrefValue::Str(s) = prefs::get().get_value(&name) {
66- return Ok(s.into());
67+ // Check if this is an embedder preference (contains a namespace separator)
68+ if name.contains('.') {
69+ // Look up in embedder preferences registry
70+ if let Some(PrefValue::Str(s)) = prefs::get_embedder_pref(&name) {
71+ return Ok(s.into());
72+ }
73+ } else {
74+ // Core Servo preference
75+ if let PrefValue::Str(s) = prefs::get().get_value(&name) {
76+ return Ok(s.into());
77+ }
78 }
79 Err(Error::TypeMismatch(None))
80 }
81@@ -85,23 +114,59 @@
82
83 /// <https://servo.org/internal-no-spec>
84 fn SetBoolPreference(&self, name: USVString, value: bool) {
85- let mut current_prefs = prefs::get().clone();
86- current_prefs.set_value(&name, value.into());
87- prefs::set(current_prefs);
88+ let pref_value: PrefValue = value.into();
89+ // Check if this is an embedder preference (contains a namespace separator)
90+ if name.contains('.') {
91+ // Use the embedder prefs setter which invokes callbacks and notifies observers
92+ embedder_prefs::set_embedder_pref_from_script(&name, pref_value.clone());
93+ } else {
94+ // Core Servo preference
95+ let mut current_prefs = prefs::get().clone();
96+ current_prefs.set_value(&name, pref_value.clone());
97+ prefs::set(current_prefs);
98+ }
99+ // Broadcast preference change to all script threads via the Constellation
100+ let _ = self.global().script_to_constellation_chan().send(
101+ ScriptToConstellationMessage::BroadcastPreferenceChange(name.to_string(), pref_value),
102+ );
103 }
104
105 /// <https://servo.org/internal-no-spec>
106 fn SetIntPreference(&self, name: USVString, value: i64) {
107- let mut current_prefs = prefs::get().clone();
108- current_prefs.set_value(&name, value.into());
109- prefs::set(current_prefs);
110+ let pref_value: PrefValue = value.into();
111+ // Check if this is an embedder preference (contains a namespace separator)
112+ if name.contains('.') {
113+ // Use the embedder prefs setter which invokes callbacks and notifies observers
114+ embedder_prefs::set_embedder_pref_from_script(&name, pref_value.clone());
115+ } else {
116+ // Core Servo preference
117+ let mut current_prefs = prefs::get().clone();
118+ current_prefs.set_value(&name, pref_value.clone());
119+ prefs::set(current_prefs);
120+ }
121+ // Broadcast preference change to all script threads via the Constellation
122+ let _ = self.global().script_to_constellation_chan().send(
123+ ScriptToConstellationMessage::BroadcastPreferenceChange(name.to_string(), pref_value),
124+ );
125 }
126
127 /// <https://servo.org/internal-no-spec>
128 fn SetStringPreference(&self, name: USVString, value: USVString) {
129- let mut current_prefs = prefs::get().clone();
130- current_prefs.set_value(&name, value.0.into());
131- prefs::set(current_prefs);
132+ let pref_value: PrefValue = value.0.into();
133+ // Check if this is an embedder preference (contains a namespace separator)
134+ if name.contains('.') {
135+ // Use the embedder prefs setter which invokes callbacks and notifies observers
136+ embedder_prefs::set_embedder_pref_from_script(&name, pref_value.clone());
137+ } else {
138+ // Core Servo preference
139+ let mut current_prefs = prefs::get().clone();
140+ current_prefs.set_value(&name, pref_value.clone());
141+ prefs::set(current_prefs);
142+ }
143+ // Broadcast preference change to all script threads via the Constellation
144+ let _ = self.global().script_to_constellation_chan().send(
145+ ScriptToConstellationMessage::BroadcastPreferenceChange(name.to_string(), pref_value),
146+ );
147 }
148 }
149
150@@ -117,7 +182,10 @@
151 /// The navigator.servo api is exposed to about: pages except about:blank, as
152 /// well as any URLs provided by embedders that register new protocol handlers.
153 #[expect(unsafe_code)]
154- fn is_servo_internal(cx: JSContext, _global: HandleObject) -> bool {
155+ fn is_servo_internal(cx: JSContext, global: HandleObject) -> bool {
156+ if Embedder::is_allowed_to_embed(cx, global) {
157+ return true;
158+ }
159 unsafe {
160 let in_realm_proof = AlreadyInRealm::assert_for_cx(cx);
161 let global_scope = GlobalScope::from_context(*cx, InRealm::Already(&in_realm_proof));