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 54b765c0cbea..e5c2ab7e35e3 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 7c364074c2bb..ac9678394fca 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 452f2278da9e..767cb0911cdc 100644 --- a/Source/WebCore/html/HTMLFormControlElement.cpp +++ b/Source/WebCore/html/HTMLFormControlElement.cpp @@ -395,24 +395,29 @@ 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) + RefPtr popover = popoverTargetElement(); + if (!popover) return; - ASSERT(target->popoverData()); + ASSERT(popover->popoverData()); + + if (RefPtr eventTargetNode = dynamicDowncast(eventTarget)) { + if (popover->containsIncludingShadowDOM(eventTargetNode.get()) && popover->isDescendantOrShadowDescendantOf(this)) + return; + } auto action = popoverTargetAction(); bool canHide = action == hideAtom() || action == toggleAtom(); - bool shouldHide = canHide && target->popoverData()->visibilityState() == PopoverVisibilityState::Showing; + bool shouldHide = canHide && popover->popoverData()->visibilityState() == PopoverVisibilityState::Showing; bool canShow = action == showAtom() || action == toggleAtom(); - bool shouldShow = canShow && target->popoverData()->visibilityState() == PopoverVisibilityState::Hidden; + bool shouldShow = canShow && popover->popoverData()->visibilityState() == PopoverVisibilityState::Hidden; if (shouldHide) - target->hidePopover(); + popover->hidePopover(); else if (shouldShow) - target->showPopover(this); + popover->showPopover(this); } RefPtr HTMLFormControlElement::commandForElement() const diff --git a/Source/WebCore/html/HTMLFormControlElement.h b/Source/WebCore/html/HTMLFormControlElement.h index 5d5fed4eb89b..084b1b14e734 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 47527d3de560..faa38c3cc888 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; }