mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-12-07 21:59:54 +00:00
LibWeb: Move mutation observers from IntrusiveList to GC::RootVector
We need to prevent these mutation observers from being garbage collected, and since they are only part of SimilarOriginWindowAgent and themselves as part of the intrusive list, nobody is visiting them. Make the list of pending mutation observers a GC::RootVector so we keep them alive until they have been processed in the microtask. Restores 1400+ WPT subtest passes in `dom/nodes/Element-classlist.html`.
This commit is contained in:
parent
150828af98
commit
e281e3a274
Notes:
github-actions[bot]
2025-11-24 12:46:48 +00:00
Author: https://github.com/gmta
Commit: e281e3a274
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/6917
Reviewed-by: https://github.com/AtkinsSJ ✅
4 changed files with 6 additions and 19 deletions
|
|
@ -731,15 +731,8 @@ void queue_mutation_observer_microtask(DOM::Document const& document)
|
|||
surrounding_agent.mutation_observer_microtask_queued = false;
|
||||
|
||||
// 2. Let notifySet be a clone of the surrounding agent’s pending mutation observers.
|
||||
GC::RootVector<DOM::MutationObserver*> notify_set(heap);
|
||||
for (auto& observer : surrounding_agent.pending_mutation_observers)
|
||||
notify_set.append(&observer);
|
||||
|
||||
// 3. Empty the surrounding agent’s pending mutation observers.
|
||||
// NB: We instead do this at the end of the microtask. Steps 2 and 3 are equivalent to moving
|
||||
// surrounding_agent.pending_mutation_observers, but it's unmovable. Actually copying the MutationObservers
|
||||
// causes issues, so for now, keep notify_set as pointers and defer this step until after we've finished
|
||||
// using the notify_set.
|
||||
auto notify_set = move(surrounding_agent.pending_mutation_observers);
|
||||
|
||||
// 4. Let signalSet be a clone of the surrounding agent’s signal slots.
|
||||
// 5. Empty the surrounding agent’s signal slots.
|
||||
|
|
@ -788,9 +781,6 @@ void queue_mutation_observer_microtask(DOM::Document const& document)
|
|||
event_init.bubbles = true;
|
||||
slot->dispatch_event(DOM::Event::create(slot->realm(), HTML::EventNames::slotchange, event_init));
|
||||
}
|
||||
|
||||
// NB: Step 3, done later.
|
||||
surrounding_agent.pending_mutation_observers.clear();
|
||||
}));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -64,11 +64,6 @@ private:
|
|||
|
||||
// https://dom.spec.whatwg.org/#concept-mo-queue
|
||||
Vector<GC::Ref<MutationRecord>> m_record_queue;
|
||||
|
||||
IntrusiveListNode<MutationObserver> m_list_node;
|
||||
|
||||
public:
|
||||
using List = IntrusiveList<&MutationObserver::m_list_node>;
|
||||
};
|
||||
|
||||
// https://dom.spec.whatwg.org/#registered-observer
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ namespace Web::HTML {
|
|||
NonnullOwnPtr<SimilarOriginWindowAgent> SimilarOriginWindowAgent::create(GC::Heap& heap)
|
||||
{
|
||||
// See 'creating an agent' step in: https://html.spec.whatwg.org/multipage/webappapis.html#obtain-similar-origin-window-agent
|
||||
auto agent = adopt_own(*new SimilarOriginWindowAgent(CanBlock::No));
|
||||
auto agent = adopt_own(*new SimilarOriginWindowAgent(heap, CanBlock::No));
|
||||
agent->event_loop = heap.allocate<HTML::EventLoop>(HTML::EventLoop::Type::Window);
|
||||
return agent;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Shannon Booth <shannon@serenityos.org>
|
||||
* Copyright (c) 2025, Jelle Raaijmakers <jelle@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
|
@ -29,7 +30,7 @@ struct SimilarOriginWindowAgent : public Agent {
|
|||
|
||||
// https://dom.spec.whatwg.org/#mutation-observer-list
|
||||
// Each similar-origin window agent also has pending mutation observers (a set of zero or more MutationObserver objects), which is initially empty.
|
||||
DOM::MutationObserver::List pending_mutation_observers;
|
||||
GC::RootVector<GC::Ref<DOM::MutationObserver>> pending_mutation_observers;
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/custom-elements.html#custom-element-reactions-stack
|
||||
// Each similar-origin window agent has a custom element reactions stack, which is initially empty.
|
||||
|
|
@ -45,8 +46,9 @@ struct SimilarOriginWindowAgent : public Agent {
|
|||
Vector<GC::Root<DOM::Element>> const& current_element_queue() const { return custom_element_reactions_stack.element_queue_stack.last(); }
|
||||
|
||||
private:
|
||||
explicit SimilarOriginWindowAgent(CanBlock can_block)
|
||||
SimilarOriginWindowAgent(GC::Heap& heap, CanBlock can_block)
|
||||
: Agent(can_block)
|
||||
, pending_mutation_observers(heap)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue