Skip to content

Commit

Permalink
Bug 1833570 - Change popover invoker type from boolean to Element. r=…
Browse files Browse the repository at this point in the history
…emilio

The invoker type is currently implemented as boolean as suggested at
whatwg/html#9168. This issue is now closed and
has been fixed at whatwg/html#9171.

This patch is to be follow above discussions and implement popover invoker
type as element.

Differential Revision: https://phabricator.services.mozilla.com/D178287
  • Loading branch information
ziransun committed May 29, 2023
1 parent e7727c0 commit c517718
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 26 deletions.
4 changes: 3 additions & 1 deletion dom/base/Document.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15046,7 +15046,9 @@ void Document::HidePopover(Element& aPopover, bool aFocusPreviousElement,
}
}

aPopover.SetHasPopoverInvoker(false);
auto* data = popoverHTMLEl->GetPopoverData();
MOZ_ASSERT(data, "Should have popover data");
data->SetInvoker(nullptr);

// Fire beforetoggle event and re-check popover validity.
if (aFireEvents && !wasHiding) {
Expand Down
16 changes: 2 additions & 14 deletions dom/base/Element.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4248,19 +4248,6 @@ void Element::ClearServoData(Document* aDoc) {
}
}

bool Element::HasPopoverInvoker() const {
auto* popoverData = GetPopoverData();
return popoverData && popoverData->HasPopoverInvoker();
}

void Element::SetHasPopoverInvoker(bool aHasInvoker) {
if (aHasInvoker) {
EnsurePopoverData().SetHasPopoverInvoker(true);
} else if (auto* popoverData = GetPopoverData()) {
popoverData->SetHasPopoverInvoker(false);
}
}

bool Element::IsAutoPopover() const {
const auto* htmlElement = nsGenericHTMLElement::FromNode(this);
return htmlElement &&
Expand Down Expand Up @@ -4305,8 +4292,9 @@ Element* Element::GetTopmostPopoverAncestor() const {

checkAncestor(newPopover->GetFlattenedTreeParentElement());

// TODO: To handle the button invokers
// https://github.com/whatwg/html/issues/9160
RefPtr<Element> invoker = newPopover->GetPopoverData()->GetInvoker();
checkAncestor(invoker);

return topmostPopoverAncestor;
}
Expand Down
4 changes: 0 additions & 4 deletions dom/base/Element.h
Original file line number Diff line number Diff line change
Expand Up @@ -581,10 +581,6 @@ class Element : public FragmentOrElement {
return CreatePopoverData();
}

// https://html.spec.whatwg.org/multipage/popover.html#popover-invoker
bool HasPopoverInvoker() const;
void SetHasPopoverInvoker(bool);

bool IsAutoPopover() const;
bool IsPopoverOpen() const;

Expand Down
23 changes: 17 additions & 6 deletions dom/base/PopoverData.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,12 @@
#include "nsThreadUtils.h"
#include "nsIWeakReferenceUtils.h"

class nsINode;

namespace mozilla::dom {

class Element;

// https://html.spec.whatwg.org/#attr-popover
enum class PopoverAttributeState : uint8_t {
None,
Expand Down Expand Up @@ -66,10 +70,14 @@ class PopoverData {
mPreviouslyFocusedElement = aPreviouslyFocusedElement;
}

bool HasPopoverInvoker() const { return mHasPopoverInvoker; }
void SetHasPopoverInvoker(bool aHasPopoverInvoker) {
mHasPopoverInvoker = aHasPopoverInvoker;
RefPtr<Element> GetInvoker() const {
return do_QueryReferent(mInvokerElement);
}
void SetInvoker(Element* aInvokerElement) {
mInvokerElement =
do_GetWeakReference(static_cast<nsINode*>(aInvokerElement));
}

PopoverToggleEventTask* GetToggleEventTask() const { return mTask; }
void SetToggleEventTask(PopoverToggleEventTask* aTask) { mTask = aTask; }
void ClearToggleEventTask() { mTask = nullptr; }
Expand All @@ -85,9 +93,12 @@ class PopoverData {
// See, https://github.com/whatwg/html/issues/9063
nsWeakPtr mPreviouslyFocusedElement = nullptr;

// https://html.spec.whatwg.org/multipage/popover.html#popover-invoker, also
// see https://github.com/whatwg/html/issues/9168.
bool mHasPopoverInvoker = false;
// https://html.spec.whatwg.org/#popover-invoker
// Since having a popover invoker only makes a difference if the invoker
// is in the document (in another open popover to be precise) we can make
// this a weak reference, as if the element goes away it's necessarily not
// connected to our document.
nsWeakPtr mInvokerElement;
bool mIsHiding = false;
RefPtr<PopoverToggleEventTask> mTask;
};
Expand Down
2 changes: 1 addition & 1 deletion dom/html/nsGenericHTMLElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2892,7 +2892,7 @@ void nsGenericHTMLFormControlElementWithState::HandlePopoverTargetAction() {
if (canHide && target->IsPopoverOpen()) {
target->HidePopover(IgnoreErrors());
} else if (canShow && !target->IsPopoverOpen()) {
target->SetHasPopoverInvoker(true);
target->GetPopoverData()->SetInvoker(this);
target->ShowPopover(IgnoreErrors());
}
}
Expand Down

0 comments on commit c517718

Please sign in to comment.