@@ -652,45 +652,47 @@ constexpr PopoverAttributeState ToPopoverAttributeState(
652
652
} // namespace
653
653
654
654
void nsGenericHTMLElement::AfterSetPopoverAttr () {
655
- const nsAttrValue* newValue = GetParsedAttr (nsGkAtoms::popover);
656
-
657
- const PopoverAttributeState newState = [&newValue]() {
658
- if (newValue) {
659
- MOZ_ASSERT (newValue->Type () == nsAttrValue::eEnum);
655
+ auto mapPopoverState = [](const nsAttrValue* value) -> PopoverAttributeState {
656
+ if (value) {
657
+ MOZ_ASSERT (value->Type () == nsAttrValue::eEnum);
660
658
const auto popoverAttributeKeyword =
661
- static_cast <PopoverAttributeKeyword>(newValue ->GetEnumValue ());
659
+ static_cast <PopoverAttributeKeyword>(value ->GetEnumValue ());
662
660
return ToPopoverAttributeState (popoverAttributeKeyword);
663
661
}
664
662
665
663
// The missing value default is the no popover state, see
666
664
// <https://html.spec.whatwg.org/multipage/popover.html#attr-popover>.
667
665
return PopoverAttributeState::None;
668
- }();
666
+ };
667
+
668
+ PopoverAttributeState newState =
669
+ mapPopoverState (GetParsedAttr (nsGkAtoms::popover));
669
670
670
671
const PopoverAttributeState oldState = GetPopoverAttributeState ();
671
672
672
673
if (newState != oldState) {
673
- EnsurePopoverData ().SetPopoverAttributeState (newState);
674
-
675
- HidePopoverInternal (/* aFocusPreviousElement = */ true ,
676
- /* aFireEvents = */ true , IgnoreErrors ());
677
-
678
- // In case `HidePopoverInternal` changed the state, keep the corresponding
679
- // changes and don't overwrite anything here.
680
- if (newState == GetPopoverAttributeState ()) {
681
- if (newState == PopoverAttributeState::None) {
682
- // `HidePopoverInternal` above didn't remove the element from the top
683
- // layer, because in that call, the element's popover attribute state
684
- // was already `None`. Revisit this, when the spec is corrected
685
- // (bug 1835811).
686
- OwnerDoc ()->RemovePopoverFromTopLayer (*this );
674
+ PopoverPseudoStateUpdate (false , true );
687
675
688
- ClearPopoverData ();
689
- RemoveStates (ElementState::POPOVER_OPEN);
690
- } else {
691
- // TODO: what if `HidePopoverInternal` called `ShowPopup()`?
692
- PopoverPseudoStateUpdate (false , true );
676
+ if (IsPopoverOpen ()) {
677
+ HidePopoverInternal (/* aFocusPreviousElement = */ true ,
678
+ /* aFireEvents = */ true , IgnoreErrors ());
679
+ // Event handlers could have removed the popover attribute, or changed
680
+ // its value.
681
+ // https://github.com/whatwg/html/issues/9034
682
+ newState = mapPopoverState (GetParsedAttr (nsGkAtoms::popover));
683
+ }
684
+
685
+ if (newState == PopoverAttributeState::None) {
686
+ // HidePopoverInternal above could have removed the popover from the top
687
+ // layer.
688
+ if (GetPopoverData ()) {
689
+ OwnerDoc ()->RemovePopoverFromTopLayer (*this );
693
690
}
691
+ ClearPopoverData ();
692
+ RemoveStates (ElementState::POPOVER_OPEN);
693
+ } else {
694
+ // TODO: what if `HidePopoverInternal` called `ShowPopup()`?
695
+ EnsurePopoverData ().SetPopoverAttributeState (newState);
694
696
}
695
697
}
696
698
}
@@ -3165,17 +3167,12 @@ bool nsGenericHTMLElement::PopoverOpen() const {
3165
3167
bool nsGenericHTMLElement::CheckPopoverValidity (
3166
3168
PopoverVisibilityState aExpectedState, Document* aExpectedDocument,
3167
3169
ErrorResult& aRv) {
3168
- const PopoverData* data = GetPopoverData ();
3169
- if (!data ||
3170
- data->GetPopoverAttributeState () == PopoverAttributeState::None) {
3171
- MOZ_ASSERT (!HasAttr (nsGkAtoms::popover));
3170
+ if (GetPopoverAttributeState () == PopoverAttributeState::None) {
3172
3171
aRv.ThrowNotSupportedError (" Element is in the no popover state" );
3173
3172
return false ;
3174
3173
}
3175
3174
3176
- MOZ_ASSERT (HasAttr (nsGkAtoms::popover));
3177
-
3178
- if (data->GetPopoverVisibilityState () != aExpectedState) {
3175
+ if (GetPopoverData ()->GetPopoverVisibilityState () != aExpectedState) {
3179
3176
return false ;
3180
3177
}
3181
3178
0 commit comments