LibWeb: Ignore DOM state when hiding removed popovers

Using https://github.com/whatwg/html/pull/9457
(with some changes made to catch up with the current spec)
to fix a spec bug and a crash when removing a visible popover.
This commit is contained in:
Gingeh 2025-01-14 11:06:06 +11:00 committed by Andrew Kaster
commit e670caeb0c
Notes: github-actions[bot] 2025-01-30 22:49:36 +00:00
5 changed files with 51 additions and 32 deletions

View file

@ -34,6 +34,7 @@ void PopoverInvokerElement::visit_edges(JS::Cell::Visitor& visitor)
}
// https://html.spec.whatwg.org/multipage/popover.html#popover-target-attribute-activation-behavior
// https://whatpr.org/html/9457/popover.html#popover-target-attribute-activation-behavior
void PopoverInvokerElement::popover_target_activation_behaviour(GC::Ref<DOM::Node> node, GC::Ref<DOM::Node> event_target)
{
// To run the popover target attribute activation behavior given a Node node and a Node eventTarget:
@ -60,14 +61,14 @@ void PopoverInvokerElement::popover_target_activation_behaviour(GC::Ref<DOM::Nod
&& popover->popover_visibility_state() == HTMLElement::PopoverVisibilityState::Hidden)
return;
// 6. If popover's popover visibility state is showing, then run the hide popover algorithm given popover, true, true, and false.
// 6. If popover's popover visibility state is showing, then run the hide popover algorithm given popover, true, true, false, and false.
if (popover->popover_visibility_state() == HTMLElement::PopoverVisibilityState::Showing) {
MUST(popover->hide_popover(FocusPreviousElement::Yes, FireEvents::Yes, ThrowExceptions::No));
MUST(popover->hide_popover(FocusPreviousElement::Yes, FireEvents::Yes, ThrowExceptions::No, IgnoreDomState::No));
}
// 7. Otherwise, if popover's popover visibility state is hidden and the result of running check popover validity given popover, false, false, and null is true, then run show popover given popover, false, and node.
// 7. Otherwise, if popover's popover visibility state is hidden and the result of running check popover validity given popover, false, false, null, and false is true, then run show popover given popover, false, and node.
else if (popover->popover_visibility_state() == HTMLElement::PopoverVisibilityState::Hidden
&& MUST(popover->check_popover_validity(ExpectedToBeShowing::No, ThrowExceptions::No, nullptr))) {
&& MUST(popover->check_popover_validity(ExpectedToBeShowing::No, ThrowExceptions::No, nullptr, IgnoreDomState::No))) {
MUST(popover->show_popover(ThrowExceptions::No, as<HTMLElement>(*node)));
}
}