Bug 1322939 - Introduce :-moz-modal-dialog pseudo-selector. r=smaug, xidorn
MozReview-Commit-ID: 6xwc8oiBYa1
--- a/dom/events/EventStates.h
+++ b/dom/events/EventStates.h
@@ -295,18 +295,18 @@ private:
// This bit is currently free.
// #define NS_EVENT_STATE_?????????? NS_DEFINE_EVENT_STATE_MACRO(44)
// Element is highlighted (devtools inspector)
#define NS_EVENT_STATE_DEVTOOLS_HIGHLIGHTED NS_DEFINE_EVENT_STATE_MACRO(45)
// Element is an unresolved custom element candidate
#define NS_EVENT_STATE_UNRESOLVED NS_DEFINE_EVENT_STATE_MACRO(46)
// Element is transitioning for rules changed by style editor
#define NS_EVENT_STATE_STYLEEDITOR_TRANSITIONING NS_DEFINE_EVENT_STATE_MACRO(47)
-// This bit is currently free.
-// #define NS_EVENT_STATE_?????????? NS_DEFINE_EVENT_STATE_MACRO(48)
+// Modal <dialog> element
+#define NS_EVENT_STATE_MODAL_DIALOG NS_DEFINE_EVENT_STATE_MACRO(48)
// Element has focus-within.
#define NS_EVENT_STATE_FOCUS_WITHIN NS_DEFINE_EVENT_STATE_MACRO(49)
// Event state that is used for values that need to be parsed but do nothing.
#define NS_EVENT_STATE_IGNORE NS_DEFINE_EVENT_STATE_MACRO(63)
/**
* NOTE: do not go over 63 without updating EventStates::InternalType!
--- a/dom/html/HTMLDialogElement.cpp
+++ b/dom/html/HTMLDialogElement.cpp
@@ -94,16 +94,28 @@ HTMLDialogElement::ShowModal(ErrorResult
SetOpen(true, aError);
aError.SuppressException();
nsDocument* doc = static_cast<nsDocument*>(GetUncomposedDoc());
doc->PendingDialogStackPush(this);
}
+EventStates
+HTMLDialogElement::IntrinsicState() const
+{
+ EventStates state = nsGenericHTMLElement::IntrinsicState();
+
+ if (mIsModal) {
+ state |= NS_EVENT_STATE_MODAL_DIALOG;
+ }
+
+ return state;
+}
+
JSObject*
HTMLDialogElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
return HTMLDialogElementBinding::Wrap(aCx, this, aGivenProto);
}
} // namespace dom
} // namespace mozilla
--- a/dom/html/HTMLDialogElement.h
+++ b/dom/html/HTMLDialogElement.h
@@ -4,32 +4,34 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef HTMLDialogElement_h
#define HTMLDialogElement_h
#include "mozilla/AsyncEventDispatcher.h"
#include "mozilla/Attributes.h"
+#include "mozilla/EventStates.h"
#include "nsGenericHTMLElement.h"
#include "nsGkAtoms.h"
namespace mozilla {
namespace dom {
class HTMLDialogElement final : public nsGenericHTMLElement
{
public:
explicit HTMLDialogElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo) : nsGenericHTMLElement(aNodeInfo)
{
}
NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLDialogElement, dialog)
virtual nsresult Clone(mozilla::dom::NodeInfo* aNodeInfo, nsINode** aResult) const override;
+ virtual EventStates IntrinsicState() const override;
static bool IsDialogEnabled();
bool Open() const { return GetBoolAttr(nsGkAtoms::open); }
void SetOpen(bool aOpen, ErrorResult& aError)
{
SetHTMLBoolAttr(nsGkAtoms::open, aOpen, aError);
}
--- a/layout/style/nsCSSPseudoClassList.h
+++ b/layout/style/nsCSSPseudoClassList.h
@@ -129,16 +129,22 @@ CSS_PSEUDO_CLASS(mozBrowserFrame, ":-moz
// Matches whatever the contextual reference elements are for the
// matching operation.
CSS_PSEUDO_CLASS(scope, ":scope", 0, "layout.css.scope-pseudo.enabled")
// :not needs to come at the end of the non-bit pseudo-class list, since
// it doesn't actually get directly matched on in SelectorMatches.
CSS_PSEUDO_CLASS(negation, ":not", 0, "")
+
+// Modal <dialog> elements
+CSS_STATE_PSEUDO_CLASS(mozModalDialog, ":-moz-modal-dialog",
+ CSS_PSEUDO_CLASS_ENABLED_IN_UA_SHEETS_AND_CHROME, "",
+ NS_EVENT_STATE_MODAL_DIALOG)
+
// :dir(ltr) and :dir(rtl) match elements whose resolved
// directionality in the markup language is ltr or rtl respectively.
CSS_STATE_DEPENDENT_PSEUDO_CLASS(dir, ":dir", 0, "",
NS_EVENT_STATE_LTR | NS_EVENT_STATE_RTL)
CSS_STATE_PSEUDO_CLASS(link, ":link", 0, "", NS_EVENT_STATE_UNVISITED)
// what matches :link or :visited
CSS_STATE_PSEUDO_CLASS(mozAnyLink, ":-moz-any-link", 0, "",
--- a/layout/style/res/html.css
+++ b/layout/style/res/html.css
@@ -821,16 +821,24 @@ dialog {
background: white;
width: -moz-fit-content;
}
dialog:not([open]) {
display: none;
}
+dialog:-moz-modal-dialog {
+ -moz-top-layer: top !important;
+}
+
+dialog::backdrop {
+ background: rgba(0, 0, 0, 0.1);
+}
+
/* emulation of non-standard HTML <marquee> tag */
marquee {
inline-size: -moz-available;
display: inline-block;
vertical-align: text-bottom;
text-align: start;
-moz-binding: url('chrome://xbl-marquee/content/xbl-marquee.xml#marquee-horizontal');
}