LibWeb/HTML: Add source field to ToggleEventInit

Corresponds to:
95131eec8f

As we now have a field in that dictionary, I removed the separate
`source` parameter from ToggleEvent::create(). Also updated the
relevant test.
This commit is contained in:
Sam Atkins 2025-11-27 16:55:34 +00:00 committed by Tim Ledbetter
parent 99bef81d09
commit e5ea4f9bdf
Notes: github-actions[bot] 2025-12-01 14:59:29 +00:00
7 changed files with 47 additions and 22 deletions

View file

@ -88,8 +88,9 @@ void HTMLDialogElement::queue_a_dialog_toggle_event_task(AK::String old_state, A
ToggleEventInit event_init {};
event_init.old_state = move(old_state);
event_init.new_state = move(new_state);
event_init.source = source;
dispatch_event(ToggleEvent::create(realm(), HTML::EventNames::toggle, move(event_init), source));
dispatch_event(ToggleEvent::create(realm(), HTML::EventNames::toggle, move(event_init)));
// 2. Set element's dialog toggle task tracker to null.
m_dialog_toggle_task_tracker = {};
@ -177,6 +178,7 @@ WebIDL::ExceptionOr<void> HTMLDialogElement::show_modal()
return show_a_modal_dialog(*this, nullptr);
}
// https://html.spec.whatwg.org/multipage/interactive-elements.html#show-a-modal-dialog
WebIDL::ExceptionOr<void> HTMLDialogElement::show_a_modal_dialog(HTMLDialogElement& subject, GC::Ptr<DOM::Element> source)
{
// To show a modal dialog given a dialog element subject:
@ -203,14 +205,16 @@ WebIDL::ExceptionOr<void> HTMLDialogElement::show_a_modal_dialog(HTMLDialogEleme
return WebIDL::InvalidStateError::create(realm, "Dialog already open as popover"_utf16);
// 6. If the result of firing an event named beforetoggle, using ToggleEvent,
// with the cancelable attribute initialized to true, the oldState attribute initialized to "closed",
// the newState attribute initialized to "open", and the source attribute initialized to source at subject is false, then return.
// with the cancelable attribute initialized to true, the oldState attribute initialized to "closed",
// the newState attribute initialized to "open", and the source attribute initialized to source at subject is
// false, then return.
ToggleEventInit event_init {};
event_init.cancelable = true;
event_init.old_state = "closed"_string;
event_init.new_state = "open"_string;
event_init.source = source;
auto beforetoggle_result = subject.dispatch_event(ToggleEvent::create(realm, EventNames::beforetoggle, move(event_init), source));
auto beforetoggle_result = subject.dispatch_event(ToggleEvent::create(realm, EventNames::beforetoggle, move(event_init)));
if (!beforetoggle_result)
return {};
@ -344,8 +348,9 @@ void HTMLDialogElement::close_the_dialog(Optional<String> result, GC::Ptr<DOM::E
ToggleEventInit event_init {};
event_init.old_state = "open"_string;
event_init.new_state = "closed"_string;
event_init.source = source;
dispatch_event(ToggleEvent::create(realm(), HTML::EventNames::beforetoggle, move(event_init), source));
dispatch_event(ToggleEvent::create(realm(), HTML::EventNames::beforetoggle, move(event_init)));
// 3. If subject does not have an open attribute, then return.
if (!has_attribute(AttributeNames::open))

View file

@ -1263,12 +1263,16 @@ WebIDL::ExceptionOr<void> HTMLElement::show_popover(ThrowExceptions throw_except
m_popover_showing_or_hiding = false;
};
// 9. If the result of firing an event named beforetoggle, using ToggleEvent, with the cancelable attribute initialized to true, the oldState attribute initialized to "closed", the newState attribute initialized to "open" at element, and the source attribute initialized to source at element is false, then run cleanupShowingFlag and return.
// 9. If the result of firing an event named beforetoggle, using ToggleEvent, with the cancelable attribute
// initialized to true, the oldState attribute initialized to "closed", the newState attribute initialized to
// "open" at element, and the source attribute initialized to source at element is false,
// then run cleanupShowingFlag and return.
ToggleEventInit event_init {};
event_init.old_state = "closed"_string;
event_init.new_state = "open"_string;
event_init.cancelable = true;
if (!dispatch_event(ToggleEvent::create(realm(), HTML::EventNames::beforetoggle, move(event_init), source))) {
event_init.source = source;
if (!dispatch_event(ToggleEvent::create(realm(), HTML::EventNames::beforetoggle, move(event_init)))) {
cleanup_showing_flag();
return {};
}
@ -1500,25 +1504,30 @@ WebIDL::ExceptionOr<void> HTMLElement::hide_popover(FocusPreviousElement focus_p
// 9. If fireEvents is true:
if (fire_events == FireEvents::Yes) {
// 9.1. Fire an event named beforetoggle, using ToggleEvent, with the oldState attribute initialized to "open", the newState attribute initialized to "closed", and the source attribute set to source at element.
// 1. Fire an event named beforetoggle, using ToggleEvent, with the oldState attribute initialized to "open",
// the newState attribute initialized to "closed", and the source attribute set to source at element.
ToggleEventInit event_init {};
event_init.old_state = "open"_string;
event_init.new_state = "closed"_string;
dispatch_event(ToggleEvent::create(realm(), HTML::EventNames::beforetoggle, move(event_init), source));
event_init.source = source;
dispatch_event(ToggleEvent::create(realm(), HTML::EventNames::beforetoggle, move(event_init)));
// 9.2. If autoPopoverListContainsElement is true and document's showing auto popover list's last item is not element, then run hide all popovers until given element, focusPreviousElement, and false.
// 2. If autoPopoverListContainsElement is true and document's showing auto popover list's last item is not
// element, then run hide all popovers until given element, focusPreviousElement, and false.
if (auto_popover_list_contains_element && (showing_popovers.is_empty() || showing_popovers.last() != this))
hide_all_popovers_until(GC::Ptr(this), focus_previous_element, FireEvents::No);
// 9.3. If the result of running check popover validity given element, true, throwExceptions, null, and ignoreDomState is false, then run cleanupSteps and return.
// 3. If the result of running check popover validity given element, true, throwExceptions, null, and
// ignoreDomState is false, then run cleanupSteps and return.
if (!TRY(check_popover_validity(ExpectedToBeShowing::Yes, throw_exceptions, nullptr, ignore_dom_state))) {
cleanup_steps();
return {};
}
// 9.4. Request an element to be removed from the top layer given element.
document.request_an_element_to_be_remove_from_the_top_layer(*this);
} else {
// 10. Otherwise, remove an element from the top layer immediately given element.
}
// 10. Otherwise, remove an element from the top layer immediately given element.
else {
document.remove_an_element_from_the_top_layer_immediately(*this);
}
@ -1901,8 +1910,9 @@ void HTMLElement::queue_a_popover_toggle_event_task(String old_state, String new
ToggleEventInit event_init {};
event_init.old_state = move(old_state);
event_init.new_state = move(new_state);
event_init.source = source;
dispatch_event(ToggleEvent::create(realm(), HTML::EventNames::toggle, move(event_init), source));
dispatch_event(ToggleEvent::create(realm(), HTML::EventNames::toggle, move(event_init)));
// 2. Set element's popover toggle task tracker to null.
m_popover_toggle_task_tracker = {};

View file

@ -12,9 +12,9 @@ namespace Web::HTML {
GC_DEFINE_ALLOCATOR(ToggleEvent);
GC::Ref<ToggleEvent> ToggleEvent::create(JS::Realm& realm, FlyString const& event_name, ToggleEventInit event_init, GC::Ptr<DOM::Element> source)
GC::Ref<ToggleEvent> ToggleEvent::create(JS::Realm& realm, FlyString const& event_name, ToggleEventInit event_init)
{
return realm.create<ToggleEvent>(realm, event_name, move(event_init), source);
return realm.create<ToggleEvent>(realm, event_name, move(event_init));
}
WebIDL::ExceptionOr<GC::Ref<ToggleEvent>> ToggleEvent::construct_impl(JS::Realm& realm, FlyString const& event_name, ToggleEventInit event_init)
@ -22,11 +22,11 @@ WebIDL::ExceptionOr<GC::Ref<ToggleEvent>> ToggleEvent::construct_impl(JS::Realm&
return create(realm, event_name, move(event_init));
}
ToggleEvent::ToggleEvent(JS::Realm& realm, FlyString const& event_name, ToggleEventInit event_init, GC::Ptr<DOM::Element> source)
ToggleEvent::ToggleEvent(JS::Realm& realm, FlyString const& event_name, ToggleEventInit event_init)
: DOM::Event(realm, event_name, event_init)
, m_old_state(move(event_init.old_state))
, m_new_state(move(event_init.new_state))
, m_source(source)
, m_source(event_init.source)
{
}

View file

@ -17,6 +17,7 @@ namespace Web::HTML {
struct ToggleEventInit : public DOM::EventInit {
String old_state;
String new_state;
GC::Ptr<DOM::Element> source;
};
class ToggleEvent : public DOM::Event {
@ -24,7 +25,7 @@ class ToggleEvent : public DOM::Event {
GC_DECLARE_ALLOCATOR(ToggleEvent);
public:
[[nodiscard]] static GC::Ref<ToggleEvent> create(JS::Realm&, FlyString const& event_name, ToggleEventInit = {}, GC::Ptr<DOM::Element> source = {});
[[nodiscard]] static GC::Ref<ToggleEvent> create(JS::Realm&, FlyString const& event_name, ToggleEventInit = {});
static WebIDL::ExceptionOr<GC::Ref<ToggleEvent>> construct_impl(JS::Realm&, FlyString const& event_name, ToggleEventInit);
// https://html.spec.whatwg.org/multipage/interaction.html#dom-toggleevent-oldstate
@ -43,7 +44,7 @@ public:
virtual void visit_edges(Cell::Visitor&) override;
private:
ToggleEvent(JS::Realm&, FlyString const& event_name, ToggleEventInit event_init, GC::Ptr<DOM::Element> source);
ToggleEvent(JS::Realm&, FlyString const& event_name, ToggleEventInit event_init);
virtual void initialize(JS::Realm&) override;

View file

@ -12,4 +12,5 @@ interface ToggleEvent : Event {
dictionary ToggleEventInit : EventInit {
DOMString oldState = "";
DOMString newState = "";
Element? source = null;
};