Move signals_slots to ScriptMutationObservers (#39275)

Both places where we access signals_slots already have a reference to
ScriptMutationObserver. This saves us another access to
with_script_thread.


Testing: This does not change functionality.
Fixes: Part of addressing: https://github.com/servo/servo/issues/37969

Signed-off-by: Narfinger <Narfinger@users.noreply.github.com>
This commit is contained in:
Narfinger 2025-09-12 20:43:59 +02:00 committed by GitHub
parent 250c4cda00
commit 033da09800
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 21 additions and 32 deletions

View file

@ -352,11 +352,11 @@ impl HTMLSlotElement {
} }
self.is_in_agents_signal_slots.set(true); self.is_in_agents_signal_slots.set(true);
let mutation_observers = ScriptThread::mutation_observers();
// Step 1. Append slot to slots relevant agents signal slots. // Step 1. Append slot to slots relevant agents signal slots.
ScriptThread::add_signal_slot(self); mutation_observers.add_signal_slot(self);
// Step 2. Queue a mutation observer microtask. // Step 2. Queue a mutation observer microtask.
let mutation_observers = ScriptThread::mutation_observers();
mutation_observers.queue_mutation_observer_microtask(ScriptThread::microtask_queue()); mutation_observers.queue_mutation_observer_microtask(ScriptThread::microtask_queue());
} }

View file

@ -10,7 +10,6 @@ use script_bindings::inheritance::Castable;
use script_bindings::root::{Dom, DomRoot}; use script_bindings::root::{Dom, DomRoot};
use script_bindings::script_runtime::CanGc; use script_bindings::script_runtime::CanGc;
use crate::ScriptThread;
use crate::dom::bindings::cell::DomRefCell; use crate::dom::bindings::cell::DomRefCell;
use crate::dom::types::{EventTarget, HTMLSlotElement, MutationObserver, MutationRecord}; use crate::dom::types::{EventTarget, HTMLSlotElement, MutationObserver, MutationRecord};
use crate::microtask::{Microtask, MicrotaskQueue}; use crate::microtask::{Microtask, MicrotaskQueue};
@ -26,6 +25,9 @@ pub(crate) struct ScriptMutationObservers {
/// The unit of related similar-origin browsing contexts' list of MutationObserver objects /// The unit of related similar-origin browsing contexts' list of MutationObserver objects
mutation_observers: DomRefCell<Vec<Dom<MutationObserver>>>, mutation_observers: DomRefCell<Vec<Dom<MutationObserver>>>,
/// <https://dom.spec.whatwg.org/#signal-slot-list>
signal_slots: DomRefCell<Vec<Dom<HTMLSlotElement>>>,
} }
impl ScriptMutationObservers { impl ScriptMutationObservers {
@ -46,7 +48,7 @@ impl ScriptMutationObservers {
// Step 4. Let signalSet be a clone of the surrounding agents signal slots. // Step 4. Let signalSet be a clone of the surrounding agents signal slots.
// Step 5. Empty the surrounding agents signal slots. // Step 5. Empty the surrounding agents signal slots.
let signal_set: Vec<DomRoot<HTMLSlotElement>> = ScriptThread::take_signal_slots(); let signal_set: Vec<DomRoot<HTMLSlotElement>> = self.take_signal_slots();
// Step 6. For each mo of notifySet: // Step 6. For each mo of notifySet:
for mo in notify_list.iter() { for mo in notify_list.iter() {
@ -93,4 +95,19 @@ impl ScriptMutationObservers {
microtask_queue.enqueue(Microtask::NotifyMutationObservers, script_thread.get_cx()); microtask_queue.enqueue(Microtask::NotifyMutationObservers, script_thread.get_cx());
}); });
} }
pub(crate) fn add_signal_slot(&self, observer: &HTMLSlotElement) {
self.signal_slots.borrow_mut().push(Dom::from_ref(observer));
}
pub(crate) fn take_signal_slots(&self) -> Vec<DomRoot<HTMLSlotElement>> {
self.signal_slots
.take()
.into_iter()
.inspect(|slot| {
slot.remove_from_signal_slots();
})
.map(|slot| slot.as_rooted())
.collect()
}
} }

View file

@ -126,7 +126,6 @@ use crate::dom::document::{
use crate::dom::element::Element; use crate::dom::element::Element;
use crate::dom::globalscope::GlobalScope; use crate::dom::globalscope::GlobalScope;
use crate::dom::html::htmliframeelement::HTMLIFrameElement; use crate::dom::html::htmliframeelement::HTMLIFrameElement;
use crate::dom::html::htmlslotelement::HTMLSlotElement;
use crate::dom::node::NodeTraits; use crate::dom::node::NodeTraits;
use crate::dom::servoparser::{ParserContext, ServoParser}; use crate::dom::servoparser::{ParserContext, ServoParser};
use crate::dom::types::DebuggerGlobalScope; use crate::dom::types::DebuggerGlobalScope;
@ -281,9 +280,6 @@ pub struct ScriptThread {
mutation_observers: Rc<ScriptMutationObservers>, mutation_observers: Rc<ScriptMutationObservers>,
/// <https://dom.spec.whatwg.org/#signal-slot-list>
signal_slots: DomRefCell<Vec<Dom<HTMLSlotElement>>>,
/// A handle to the WebGL thread /// A handle to the WebGL thread
#[no_trace] #[no_trace]
webgl_chan: Option<WebGLPipeline>, webgl_chan: Option<WebGLPipeline>,
@ -507,29 +503,6 @@ impl ScriptThread {
with_script_thread(|script_thread| script_thread.microtask_queue.clone()) with_script_thread(|script_thread| script_thread.microtask_queue.clone())
} }
pub(crate) fn add_signal_slot(observer: &HTMLSlotElement) {
with_script_thread(|script_thread| {
script_thread
.signal_slots
.borrow_mut()
.push(Dom::from_ref(observer));
})
}
pub(crate) fn take_signal_slots() -> Vec<DomRoot<HTMLSlotElement>> {
with_script_thread(|script_thread| {
script_thread
.signal_slots
.take()
.into_iter()
.inspect(|slot| {
slot.remove_from_signal_slots();
})
.map(|slot| slot.as_rooted())
.collect()
})
}
pub(crate) fn mark_document_with_no_blocked_loads(doc: &Document) { pub(crate) fn mark_document_with_no_blocked_loads(doc: &Document) {
with_script_thread(|script_thread| { with_script_thread(|script_thread| {
script_thread script_thread
@ -1001,7 +974,6 @@ impl ScriptThread {
js_runtime, js_runtime,
closed_pipelines: DomRefCell::new(FxHashSet::default()), closed_pipelines: DomRefCell::new(FxHashSet::default()),
mutation_observers: Default::default(), mutation_observers: Default::default(),
signal_slots: Default::default(),
system_font_service, system_font_service,
webgl_chan: state.webgl_chan, webgl_chan: state.webgl_chan,
#[cfg(feature = "webxr")] #[cfg(feature = "webxr")]