LibWeb: Implement legacyOutputDidListenersThrowFlag

This commit is contained in:
stelar7 2024-11-07 22:59:03 +01:00 committed by Jelle Raaijmakers
parent 932fb2024e
commit 4357c3229c
Notes: github-actions[bot] 2024-11-26 13:51:37 +00:00
3 changed files with 19 additions and 10 deletions

View file

@ -31,7 +31,7 @@
namespace Web::DOM {
// https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke
bool EventDispatcher::inner_invoke(Event& event, Vector<GC::Root<DOM::DOMEventListener>>& listeners, Event::Phase phase, bool invocation_target_in_shadow_tree)
bool EventDispatcher::inner_invoke(Event& event, Vector<GC::Root<DOM::DOMEventListener>>& listeners, Event::Phase phase, bool invocation_target_in_shadow_tree, bool& legacy_output_did_listeners_throw)
{
// 1. Let found be false.
bool found = false;
@ -99,7 +99,8 @@ bool EventDispatcher::inner_invoke(Event& event, Vector<GC::Root<DOM::DOMEventLi
VERIFY(window_or_worker);
window_or_worker->report_an_exception(*result.release_error().value());
// FIXME: 2. Set legacyOutputDidListenersThrowFlag if given. (Only used by IndexedDB currently)
// 2. Set legacyOutputDidListenersThrowFlag if given. (Only used by IndexedDB currently)
legacy_output_did_listeners_throw = true;
}
// 12. Unset events in passive listener flag.
@ -121,7 +122,7 @@ bool EventDispatcher::inner_invoke(Event& event, Vector<GC::Root<DOM::DOMEventLi
}
// https://dom.spec.whatwg.org/#concept-event-listener-invoke
void EventDispatcher::invoke(Event::PathEntry& struct_, Event& event, Event::Phase phase)
void EventDispatcher::invoke(Event::PathEntry& struct_, Event& event, Event::Phase phase, bool& legacy_output_did_listeners_throw)
{
auto last_valid_shadow_adjusted_target = event.path().last_matching([&struct_](auto& entry) {
return entry.index <= struct_.index && entry.shadow_adjusted_target;
@ -154,7 +155,7 @@ void EventDispatcher::invoke(Event::PathEntry& struct_, Event& event, Event::Pha
bool invocation_target_in_shadow_tree = struct_.invocation_target_in_shadow_tree;
// 8. Let found be the result of running inner invoke with event, listeners, phase, invocationTargetInShadowTree, and legacyOutputDidListenersThrowFlag if given.
bool found = inner_invoke(event, listeners, phase, invocation_target_in_shadow_tree);
bool found = inner_invoke(event, listeners, phase, invocation_target_in_shadow_tree, legacy_output_did_listeners_throw);
// 9. If found is false and events isTrusted attribute is true, then:
if (!found && event.is_trusted()) {
@ -175,7 +176,7 @@ void EventDispatcher::invoke(Event::PathEntry& struct_, Event& event, Event::Pha
return;
// 3. Inner invoke with event, listeners, phase, invocationTargetInShadowTree, and legacyOutputDidListenersThrowFlag if given.
inner_invoke(event, listeners, phase, invocation_target_in_shadow_tree);
inner_invoke(event, listeners, phase, invocation_target_in_shadow_tree, legacy_output_did_listeners_throw);
// 4. Set events type attribute value to originalEventType.
event.set_type(original_event_type);
@ -184,6 +185,13 @@ void EventDispatcher::invoke(Event::PathEntry& struct_, Event& event, Event::Pha
// https://dom.spec.whatwg.org/#concept-event-dispatch
bool EventDispatcher::dispatch(GC::Ref<EventTarget> target, Event& event, bool legacy_target_override)
{
bool legacy_output_did_listeners_throw = false;
return dispatch(target, event, legacy_target_override, legacy_output_did_listeners_throw);
}
// https://dom.spec.whatwg.org/#concept-event-dispatch
bool EventDispatcher::dispatch(GC::Ref<EventTarget> target, Event& event, bool legacy_target_override, bool& legacy_output_did_listeners_throw)
{
// 1. Set events dispatch flag.
event.set_dispatched(true);
@ -351,7 +359,7 @@ bool EventDispatcher::dispatch(GC::Ref<EventTarget> target, Event& event, bool l
event.set_phase(Event::Phase::CapturingPhase);
// 3. Invoke with struct, event, "capturing", and legacyOutputDidListenersThrowFlag if given.
invoke(entry, event, Event::Phase::CapturingPhase);
invoke(entry, event, Event::Phase::CapturingPhase, legacy_output_did_listeners_throw);
}
// 14. For each struct in events path:
@ -371,7 +379,7 @@ bool EventDispatcher::dispatch(GC::Ref<EventTarget> target, Event& event, bool l
}
// 3. Invoke with struct, event, "bubbling", and legacyOutputDidListenersThrowFlag if given.
invoke(entry, event, Event::Phase::BubblingPhase);
invoke(entry, event, Event::Phase::BubblingPhase, legacy_output_did_listeners_throw);
}
}

View file

@ -15,10 +15,11 @@ namespace Web::DOM {
class EventDispatcher {
public:
static bool dispatch(GC::Ref<EventTarget>, Event&, bool legacy_target_override = false);
static bool dispatch(GC::Ref<EventTarget>, Event&, bool legacy_target_override, bool& legacy_output_did_listeners_throw);
private:
static void invoke(Event::PathEntry&, Event&, Event::Phase);
static bool inner_invoke(Event&, Vector<GC::Root<DOM::DOMEventListener>>&, Event::Phase, bool);
static void invoke(Event::PathEntry&, Event&, Event::Phase, bool& legacy_output_did_listeners_throw);
static bool inner_invoke(Event&, Vector<GC::Root<DOM::DOMEventListener>>&, Event::Phase, bool, bool&);
};
}

View file

@ -146,7 +146,7 @@ bool fire_a_version_change_event(JS::Realm& realm, FlyString const& event_name,
auto legacy_output_did_listeners_throw_flag = false;
// 7. Dispatch event at target with legacyOutputDidListenersThrowFlag.
DOM::EventDispatcher::dispatch(target, *event, legacy_output_did_listeners_throw_flag);
DOM::EventDispatcher::dispatch(target, *event, false, legacy_output_did_listeners_throw_flag);
// 8. Return legacyOutputDidListenersThrowFlag.
return legacy_output_did_listeners_throw_flag;