diff --git a/LayoutTests/imported/w3c/web-platform-tests/html/semantics/popovers/popover-nested-in-button-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/html/semantics/popovers/popover-nested-in-button-expected.txt index 54b765c0cbeaf..e5c2ab7e35e3d 100644 --- a/LayoutTests/imported/w3c/web-platform-tests/html/semantics/popovers/popover-nested-in-button-expected.txt +++ b/LayoutTests/imported/w3c/web-platform-tests/html/semantics/popovers/popover-nested-in-button-expected.txt @@ -1,6 +1,6 @@ Button Button -FAIL clicking a popover nested inside a button should not re-invoke the popover assert_true: Should still be open expected true got false +PASS clicking a popover nested inside a button should not re-invoke the popover PASS corner case: invoker that is also a popover -FAIL invoker inside popover still works, even with weird nesting assert_true: descendant doesn't close popover expected true got false +PASS invoker inside popover still works, even with weird nesting diff --git a/Source/WebCore/html/HTMLButtonElement.cpp b/Source/WebCore/html/HTMLButtonElement.cpp index 7c364074c2bb2..ac9678394fca5 100644 --- a/Source/WebCore/html/HTMLButtonElement.cpp +++ b/Source/WebCore/html/HTMLButtonElement.cpp @@ -172,7 +172,7 @@ void HTMLButtonElement::defaultEventHandler(Event& event) } if (!(protectedForm && m_type == SUBMIT)) - handlePopoverTargetAction(); + handlePopoverTargetAction(event.target()); } diff --git a/Source/WebCore/html/HTMLFormControlElement.cpp b/Source/WebCore/html/HTMLFormControlElement.cpp index 452f2278da9e9..6b6845b1a8f4b 100644 --- a/Source/WebCore/html/HTMLFormControlElement.cpp +++ b/Source/WebCore/html/HTMLFormControlElement.cpp @@ -395,7 +395,7 @@ void HTMLFormControlElement::setPopoverTargetAction(const AtomString& value) } // https://html.spec.whatwg.org/#popover-target-attribute-activation-behavior -void HTMLFormControlElement::handlePopoverTargetAction() const +void HTMLFormControlElement::handlePopoverTargetAction(const EventTarget* eventTarget) const { RefPtr target = popoverTargetElement(); if (!target) @@ -403,6 +403,11 @@ void HTMLFormControlElement::handlePopoverTargetAction() const ASSERT(target->popoverData()); + if (RefPtr eventTargetElement = dynamicDowncast(eventTarget)) { + if (target->containsIncludingShadowDOM(eventTargetElement.get()) && target.get()->isDescendantOrShadowDescendantOf(this)) + return; + } + auto action = popoverTargetAction(); bool canHide = action == hideAtom() || action == toggleAtom(); bool shouldHide = canHide && target->popoverData()->visibilityState() == PopoverVisibilityState::Showing; diff --git a/Source/WebCore/html/HTMLFormControlElement.h b/Source/WebCore/html/HTMLFormControlElement.h index 5d5fed4eb89be..084b1b14e734e 100644 --- a/Source/WebCore/html/HTMLFormControlElement.h +++ b/Source/WebCore/html/HTMLFormControlElement.h @@ -130,7 +130,7 @@ class HTMLFormControlElement : public HTMLElement, public ValidatedFormListedEle void dispatchBlurEvent(RefPtr&& newFocusedElement) override; - void handlePopoverTargetAction() const; + void handlePopoverTargetAction(const EventTarget*) const; CommandType commandType() const; void handleCommand(); diff --git a/Source/WebCore/html/HTMLInputElement.cpp b/Source/WebCore/html/HTMLInputElement.cpp index 47527d3de5602..faa38c3cc888a 100644 --- a/Source/WebCore/html/HTMLInputElement.cpp +++ b/Source/WebCore/html/HTMLInputElement.cpp @@ -1362,7 +1362,7 @@ void HTMLInputElement::defaultEventHandler(Event& event) if (commandForElement()) handleCommand(); else - handlePopoverTargetAction(); + handlePopoverTargetAction(event.target()); if (event.defaultHandled()) return; }