Issue #2472 - Part 5: Make modal versions of <dialog> work, and tune styles.

This adds a pseudo-class `:-moz-modal-dialog` to be able to track whether the
dialog is in the top layer in CSS.
This implements default styling for modal dialogs following the HTML standard.
Slightly off-extreme color scheme chosen for unstyled <dialog> elements.
This commit is contained in:
Moonchild 2024-05-04 18:28:27 +02:00 committed by roytam1
commit 7d34b285e0
5 changed files with 57 additions and 4 deletions

View file

@ -56,6 +56,9 @@ HTMLDialogElement::Close(const mozilla::dom::Optional<nsAString>& aReturnValue)
ErrorResult ignored;
SetOpen(false, ignored);
ignored.SuppressException();
RemoveFromTopLayerIfNeeded();
RefPtr<AsyncEventDispatcher> eventDispatcher =
new AsyncEventDispatcher(this, NS_LITERAL_STRING("close"), false);
eventDispatcher->PostDOMEvent();
@ -72,6 +75,26 @@ HTMLDialogElement::Show()
ignored.SuppressException();
}
bool HTMLDialogElement::IsInTopLayer() const {
return State().HasState(NS_EVENT_STATE_MODAL_DIALOG);
}
void HTMLDialogElement::RemoveFromTopLayerIfNeeded() {
if (!IsInTopLayer()) {
return;
}
auto predictFunc = [&](Element* element) { return element == this; };
DebugOnly<Element*> removedElement = OwnerDoc()->TopLayerPop(predictFunc);
MOZ_ASSERT(removedElement == this);
RemoveStates(NS_EVENT_STATE_MODAL_DIALOG);
}
void HTMLDialogElement::UnbindFromTree(bool aNullParent) {
RemoveFromTopLayerIfNeeded();
nsGenericHTMLElement::UnbindFromTree(aNullParent);
}
void
HTMLDialogElement::ShowModal(ErrorResult& aError)
{
@ -79,6 +102,10 @@ HTMLDialogElement::ShowModal(ErrorResult& aError)
aError.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return;
}
if (!IsInTopLayer() && OwnerDoc()->TopLayerPush(this)) {
AddStates(NS_EVENT_STATE_MODAL_DIALOG);
}
SetOpen(true, aError);
aError.SuppressException();