diff --git a/Libraries/LibWeb/Bindings/MainThreadVM.cpp b/Libraries/LibWeb/Bindings/MainThreadVM.cpp index e6538a9f7fb..38ef537bdd7 100644 --- a/Libraries/LibWeb/Bindings/MainThreadVM.cpp +++ b/Libraries/LibWeb/Bindings/MainThreadVM.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -677,9 +678,9 @@ void queue_mutation_observer_microtask(DOM::Document const& document) for (auto& observer : surrounding_agent.mutation_observers) notify_set.append(&observer); - // FIXME: 3. Let signalSet be a clone of the surrounding agent’s signal slots. - - // FIXME: 4. Empty the surrounding agent’s signal slots. + // 3. Let signalSet be a clone of the surrounding agent’s signal slots. + // 4. Empty the surrounding agent’s signal slots. + auto signal_set = move(surrounding_agent.signal_slots); // 5. For each mo of notifySet: for (auto& mutation_observer : notify_set) { @@ -716,7 +717,12 @@ void queue_mutation_observer_microtask(DOM::Document const& document) } } - // FIXME: 6. For each slot of signalSet, fire an event named slotchange, with its bubbles attribute set to true, at slot. + // 6. For each slot of signalSet, fire an event named slotchange, with its bubbles attribute set to true, at slot. + for (auto& slot : signal_set) { + DOM::EventInit event_init; + event_init.bubbles = true; + slot->dispatch_event(DOM::Event::create(slot->realm(), HTML::EventNames::slotchange, event_init)); + } })); } diff --git a/Libraries/LibWeb/DOM/Slottable.cpp b/Libraries/LibWeb/DOM/Slottable.cpp index 41d70c78b01..3095cc99ec1 100644 --- a/Libraries/LibWeb/DOM/Slottable.cpp +++ b/Libraries/LibWeb/DOM/Slottable.cpp @@ -206,7 +206,8 @@ void assign_a_slot(Slottable const& slottable) // https://dom.spec.whatwg.org/#signal-a-slot-change void signal_a_slot_change(GC::Ref slottable) { - // FIXME: 1. Append slot to slot’s relevant agent’s signal slots. + // 1. Append slot to slot’s relevant agent’s signal slots. + HTML::relevant_agent(slottable).signal_slots.append(slottable); // 2. Queue a mutation observer microtask. Bindings::queue_mutation_observer_microtask(slottable->document()); diff --git a/Libraries/LibWeb/HTML/Scripting/Agent.h b/Libraries/LibWeb/HTML/Scripting/Agent.h index 7953231fb10..e15f757b6bb 100644 --- a/Libraries/LibWeb/HTML/Scripting/Agent.h +++ b/Libraries/LibWeb/HTML/Scripting/Agent.h @@ -32,6 +32,10 @@ struct Agent { // Each similar-origin window agent has a custom element reactions stack, which is initially empty. CustomElementReactionsStack custom_element_reactions_stack {}; + // https://dom.spec.whatwg.org/#signal-slot-list + // Each similar-origin window agent has signal slots (a set of slots), which is initially empty. [HTML] + Vector> signal_slots; + // https://html.spec.whatwg.org/multipage/custom-elements.html#current-element-queue // A similar-origin window agent's current element queue is the element queue at the top of its custom element reactions stack. Vector>& current_element_queue() { return custom_element_reactions_stack.element_queue_stack.last(); } diff --git a/Tests/LibWeb/Text/expected/wpt-import/shadow-dom/slotchange-customelements.txt b/Tests/LibWeb/Text/expected/wpt-import/shadow-dom/slotchange-customelements.txt new file mode 100644 index 00000000000..22b5c0e3cfb --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/shadow-dom/slotchange-customelements.txt @@ -0,0 +1,6 @@ +Harness status: OK + +Found 1 tests + +1 Pass +Pass slotchange must fire on initialization of custom elements with slotted children \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/shadow-dom/slotchange-event.txt b/Tests/LibWeb/Text/expected/wpt-import/shadow-dom/slotchange-event.txt new file mode 100644 index 00000000000..327572d8f14 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/shadow-dom/slotchange-event.txt @@ -0,0 +1,38 @@ +Harness status: OK + +Found 32 tests + +12 Pass +20 Fail +Fail slotchange event must fire on a default slot element inside an open shadow root in a document +Fail slotchange event must fire on a default slot element inside a closed shadow root in a document +Fail slotchange event must fire on a default slot element inside an open shadow root not in a document +Fail slotchange event must fire on a default slot element inside a closed shadow root not in a document +Fail slotchange event must fire on a named slot element insidean open shadow root in a document +Fail slotchange event must fire on a named slot element insidea closed shadow root in a document +Fail slotchange event must fire on a named slot element insidean open shadow root not in a document +Fail slotchange event must fire on a named slot element insidea closed shadow root not in a document +Pass slotchange event must not fire on a slot element inside an open shadow root in a document when another slot's assigned nodes change +Pass slotchange event must not fire on a slot element inside a closed shadow root in a document when another slot's assigned nodes change +Pass slotchange event must not fire on a slot element inside an open shadow root not in a document when another slot's assigned nodes change +Pass slotchange event must not fire on a slot element inside a closed shadow root not in a document when another slot's assigned nodes change +Pass slotchange event must fire on a slot element when a shadow host has a slottable and the slot was inserted and must not fire when the shadow host was mutated after the slot was removed inside an open shadow root in a document +Pass slotchange event must fire on a slot element when a shadow host has a slottable and the slot was inserted and must not fire when the shadow host was mutated after the slot was removed inside a closed shadow root in a document +Pass slotchange event must fire on a slot element when a shadow host has a slottable and the slot was inserted and must not fire when the shadow host was mutated after the slot was removed inside an open shadow root not in a document +Pass slotchange event must fire on a slot element when a shadow host has a slottable and the slot was inserted and must not fire when the shadow host was mutated after the slot was removed inside a closed shadow root not in a document +Fail slotchange event must fire on a slot element inside an open shadow root in a document even if the slot was removed immediately after the assigned nodes were mutated +Fail slotchange event must fire on a slot element inside a closed shadow root in a document even if the slot was removed immediately after the assigned nodes were mutated +Fail slotchange event must fire on a slot element inside an open shadow root not in a document even if the slot was removed immediately after the assigned nodes were mutated +Fail slotchange event must fire on a slot element inside a closed shadow root not in a document even if the slot was removed immediately after the assigned nodes were mutated +Fail slotchange event must fire on a slot element inside an open shadow root in a document when innerHTML modifies the children of the shadow host +Fail slotchange event must fire on a slot element inside a closed shadow root in a document when innerHTML modifies the children of the shadow host +Fail slotchange event must fire on a slot element inside an open shadow root not in a document when innerHTML modifies the children of the shadow host +Fail slotchange event must fire on a slot element inside a closed shadow root not in a document when innerHTML modifies the children of the shadow host +Pass slotchange event must fire on a slot element inside an open shadow root in a document when nested slots's contents change +Pass slotchange event must fire on a slot element inside a closed shadow root in a document when nested slots's contents change +Pass slotchange event must fire on a slot element inside an open shadow root not in a document when nested slots's contents change +Pass slotchange event must fire on a slot element inside a closed shadow root not in a document when nested slots's contents change +Fail slotchange event must fire at the end of current microtask after mutation observers are invoked inside an open shadow root in a document when slots's contents change +Fail slotchange event must fire at the end of current microtask after mutation observers are invoked inside a closed shadow root in a document when slots's contents change +Fail slotchange event must fire at the end of current microtask after mutation observers are invoked inside an open shadow root not in a document when slots's contents change +Fail slotchange event must fire at the end of current microtask after mutation observers are invoked inside a closed shadow root not in a document when slots's contents change \ No newline at end of file diff --git a/Tests/LibWeb/Text/input/wpt-import/shadow-dom/slotchange-customelements.html b/Tests/LibWeb/Text/input/wpt-import/shadow-dom/slotchange-customelements.html new file mode 100644 index 00000000000..e37b3c3aa25 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/shadow-dom/slotchange-customelements.html @@ -0,0 +1,55 @@ + + + +Shadow DOM: slotchange customelements + + + + + + +
+
+ +
+
+ + + diff --git a/Tests/LibWeb/Text/input/wpt-import/shadow-dom/slotchange-event.html b/Tests/LibWeb/Text/input/wpt-import/shadow-dom/slotchange-event.html new file mode 100644 index 00000000000..ada71392e59 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/shadow-dom/slotchange-event.html @@ -0,0 +1,602 @@ + + + +Shadow DOM: slotchange event + + + + + + + +
+ + +