Bug 1322939 - Implement inert subtrees. r=smaug
MozReview-Commit-ID: 8qREtIZSGC9
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -190,21 +190,38 @@ Element::QueryInterface(REFNSIID aIID, v
return NS_OK;
}
// Give the binding manager a chance to get an interface for this element.
return OwnerDoc()->BindingManager()->GetBindingImplementation(this, aIID,
aInstancePtr);
}
+bool
+Element::IsInert() const
+{
+ nsDocument* doc = static_cast<nsDocument*>(GetUncomposedDoc());
+ if (doc->GetPendingDialogStack().IsEmpty()) {
+ return false;
+ }
+ Element* topMostElement = doc->PendingDialogStackTop();
+ return this != topMostElement &&
+ !nsContentUtils::ContentIsDescendantOf(this, topMostElement);
+}
+
EventStates
Element::IntrinsicState() const
{
- return IsEditable() ? NS_EVENT_STATE_MOZ_READWRITE :
- NS_EVENT_STATE_MOZ_READONLY;
+ EventStates state = IsEditable() && !IsInert()
+ ? NS_EVENT_STATE_MOZ_READWRITE
+ : NS_EVENT_STATE_MOZ_READONLY;
+ if (IsInert()) {
+ state |= NS_EVENT_STATE_INERT;
+ }
+ return state;
}
void
Element::NotifyStateChange(EventStates aStates)
{
nsIDocument* doc = GetComposedDoc();
if (doc) {
nsAutoScriptBlocker scriptBlocker;
--- a/dom/base/Element.h
+++ b/dom/base/Element.h
@@ -174,16 +174,21 @@ public:
}
#endif // MOZILLA_INTERNAL_API
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ELEMENT_IID)
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) override;
+ /*
+ * Check if element is inert
+ */
+ bool IsInert() const;
+
/**
* Method to get the full state of this element. See mozilla/EventStates.h
* for the possible bits that could be set here.
*/
EventStates State() const
{
// mState is maintained by having whoever might have changed it
// call UpdateState() or one of the other mState mutators.
--- a/dom/events/EventStates.h
+++ b/dom/events/EventStates.h
@@ -269,18 +269,18 @@ private:
// Content has focus and should show a ring.
#define NS_EVENT_STATE_FOCUSRING NS_DEFINE_EVENT_STATE_MACRO(30)
// Content is a submit control and the form isn't valid.
#define NS_EVENT_STATE_MOZ_SUBMITINVALID NS_DEFINE_EVENT_STATE_MACRO(31)
// UI friendly version of :invalid pseudo-class.
#define NS_EVENT_STATE_MOZ_UI_INVALID NS_DEFINE_EVENT_STATE_MACRO(32)
// UI friendly version of :valid pseudo-class.
#define NS_EVENT_STATE_MOZ_UI_VALID NS_DEFINE_EVENT_STATE_MACRO(33)
-// This bit is currently free.
-// #define NS_EVENT_STATE_?????????? NS_DEFINE_EVENT_STATE_MACRO(34)
+// Inert subtrees
+#define NS_EVENT_STATE_INERT NS_DEFINE_EVENT_STATE_MACRO(34)
// Handler for click to play plugin
#define NS_EVENT_STATE_TYPE_CLICK_TO_PLAY NS_DEFINE_EVENT_STATE_MACRO(35)
// Content is in the optimum region.
#define NS_EVENT_STATE_OPTIMUM NS_DEFINE_EVENT_STATE_MACRO(36)
// Content is in the suboptimal region.
#define NS_EVENT_STATE_SUB_OPTIMUM NS_DEFINE_EVENT_STATE_MACRO(37)
// Content is in the sub-suboptimal region.
#define NS_EVENT_STATE_SUB_SUB_OPTIMUM NS_DEFINE_EVENT_STATE_MACRO(38)
--- a/layout/style/nsCSSPseudoClassList.h
+++ b/layout/style/nsCSSPseudoClassList.h
@@ -160,16 +160,20 @@ CSS_STATE_PSEUDO_CLASS(enabled, ":enable
CSS_STATE_PSEUDO_CLASS(focus, ":focus", 0, "", NS_EVENT_STATE_FOCUS)
CSS_STATE_PSEUDO_CLASS(focusWithin, ":focus-within", 0, "", NS_EVENT_STATE_FOCUS_WITHIN)
CSS_STATE_PSEUDO_CLASS(hover, ":hover", 0, "", NS_EVENT_STATE_HOVER)
CSS_STATE_PSEUDO_CLASS(mozDragOver, ":-moz-drag-over", 0, "", NS_EVENT_STATE_DRAGOVER)
CSS_STATE_PSEUDO_CLASS(target, ":target", 0, "", NS_EVENT_STATE_URLTARGET)
CSS_STATE_PSEUDO_CLASS(indeterminate, ":indeterminate", 0, "",
NS_EVENT_STATE_INDETERMINATE)
+CSS_STATE_PSEUDO_CLASS(mozInert, ":-moz-inert",
+ CSS_PSEUDO_CLASS_ENABLED_IN_UA_SHEETS_AND_CHROME, "",
+ NS_EVENT_STATE_INERT)
+
CSS_STATE_PSEUDO_CLASS(mozDevtoolsHighlighted, ":-moz-devtools-highlighted", 0, "",
NS_EVENT_STATE_DEVTOOLS_HIGHLIGHTED)
CSS_STATE_PSEUDO_CLASS(mozStyleeditorTransitioning, ":-moz-styleeditor-transitioning", 0, "",
NS_EVENT_STATE_STYLEEDITOR_TRANSITIONING)
// Matches the element which is being displayed full-screen, and
// any containing frames.
CSS_STATE_PSEUDO_CLASS(fullscreen, ":fullscreen",
--- a/layout/style/res/ua.css
+++ b/layout/style/res/ua.css
@@ -125,16 +125,25 @@
cursor: pointer;
}
*|*:any-link:-moz-focusring {
/* Don't specify the outline-color, we should always use initial value. */
outline: 1px dotted;
}
+/* Inert subtrees */
+*|*:-moz-inert {
+ pointer-events: none;
+ -moz-user-focus: none;
+ -moz-user-input: disabled;
+ -moz-user-modify: read-only;
+ -moz-user-select: none;
+}
+
/* Miscellaneous */
*|*::-moz-anonymous-block, *|*::-moz-cell-content {
display: block !important;
position: static !important;
unicode-bidi: inherit;
text-overflow: inherit;
overflow-clip-box: inherit;