Bug 1285474: stylo: Add nsINode method for knowing if the current document is using Servo's style back-end.
MozReview-Commit-ID: 3sRE7BZj1tu
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -1077,16 +1077,20 @@ public:
* Get this document's CSSLoader. This is guaranteed to not return null.
*/
mozilla::css::Loader* CSSLoader() const {
return mCSSLoader;
}
mozilla::StyleBackendType GetStyleBackendType() const;
+ bool IsStyledByServo() const {
+ return GetStyleBackendType() == mozilla::StyleBackendType::Servo;
+ }
+
/**
* Get this document's StyleImageLoader. This is guaranteed to not return null.
*/
mozilla::css::ImageLoader* StyleImageLoader() const {
return mStyleImageLoader;
}
/**
--- a/dom/base/nsINode.cpp
+++ b/dom/base/nsINode.cpp
@@ -3059,8 +3059,16 @@ nsINode::IsApzAware() const
return IsNodeApzAware();
}
bool
nsINode::IsNodeApzAwareInternal() const
{
return EventTarget::IsApzAware();
}
+
+#ifdef MOZ_STYLO
+bool
+nsINode::IsStyledByServo() const
+{
+ return OwnerDoc()->IsStyledByServo();
+}
+#endif
--- a/dom/base/nsINode.h
+++ b/dom/base/nsINode.h
@@ -962,16 +962,54 @@ public:
using nsIDOMEventTarget::AddSystemEventListener;
virtual bool IsApzAware() const override;
virtual nsPIDOMWindowOuter* GetOwnerGlobalForBindings() override;
virtual nsIGlobalObject* GetOwnerGlobal() const override;
/**
+ * Returns true if this is a node belonging to a document that uses the Servo
+ * style system.
+ */
+#ifdef MOZ_STYLO
+ bool IsStyledByServo() const;
+#else
+ bool IsStyledByServo() const { return false; }
+#endif
+
+ inline bool IsDirtyForServo() const
+ {
+ MOZ_ASSERT(IsStyledByServo());
+ return HasFlag(NODE_IS_DIRTY_FOR_SERVO);
+ }
+
+ inline bool HasDirtyDescendantsForServo() const
+ {
+ MOZ_ASSERT(IsStyledByServo());
+ return HasFlag(NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO);
+ }
+
+ inline void SetIsDirtyForServo() {
+ MOZ_ASSERT(IsStyledByServo());
+ SetFlags(NODE_IS_DIRTY_FOR_SERVO);
+ }
+
+ inline void SetHasDirtyDescendantsForServo() {
+ MOZ_ASSERT(IsStyledByServo());
+ SetFlags(NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO);
+ }
+
+ inline void SetIsDirtyAndHasDirtyDescendantsForServo() {
+ MOZ_ASSERT(IsStyledByServo());
+ SetFlags(NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO | NODE_IS_DIRTY_FOR_SERVO);
+ }
+
+
+ /**
* Adds a mutation observer to be notified when this node, or any of its
* descendants, are modified. The node will hold a weak reference to the
* observer, which means that it is the responsibility of the observer to
* remove itself in case it dies before the node. If an observer is added
* while observers are being notified, it may also be notified. In general,
* adding observers while inside a notification is not a good idea. An
* observer that is already observing the node must not be added without
* being removed first.
--- a/layout/base/RestyleManager.cpp
+++ b/layout/base/RestyleManager.cpp
@@ -644,17 +644,17 @@ RestyleManager::StyleChangeReflow(nsIFra
do {
mPresContext->PresShell()->FrameNeedsReflow(aFrame, dirtyType, dirtyBits,
rootHandling);
aFrame = nsLayoutUtils::GetNextContinuationOrIBSplitSibling(aFrame);
} while (aFrame);
}
void
-RestyleManager::AddSubtreeToOverflowTracker(nsIFrame* aFrame)
+RestyleManager::AddSubtreeToOverflowTracker(nsIFrame* aFrame)
{
if (aFrame->FrameMaintainsOverflow()) {
mOverflowChangedTracker.AddFrame(aFrame,
OverflowChangedTracker::CHILDREN_CHANGED);
}
nsIFrame::ChildListIterator lists(aFrame);
for (; !lists.IsDone(); lists.Next()) {
for (nsIFrame* child : lists.CurrentList()) {
@@ -2600,16 +2600,17 @@ ElementRestyler::ElementRestyler(nsPresC
, mKidsDesiredA11yNotifications(mDesiredA11yNotifications)
, mOurA11yNotification(eDontNotify)
, mVisibleKidsOfHiddenElement(aVisibleKidsOfHiddenElement)
#endif
#ifdef RESTYLE_LOGGING
, mLoggingDepth(aRestyleTracker.LoggingDepth() + 1)
#endif
{
+ MOZ_ASSERT_IF(mContent, !mContent->IsStyledByServo());
}
ElementRestyler::ElementRestyler(const ElementRestyler& aParentRestyler,
nsIFrame* aFrame,
uint32_t aConstructorFlags)
: mPresContext(aParentRestyler.mPresContext)
, mFrame(aFrame)
, mParentContent(aParentRestyler.mContent)
@@ -2634,16 +2635,17 @@ ElementRestyler::ElementRestyler(const E
, mKidsDesiredA11yNotifications(mDesiredA11yNotifications)
, mOurA11yNotification(eDontNotify)
, mVisibleKidsOfHiddenElement(aParentRestyler.mVisibleKidsOfHiddenElement)
#endif
#ifdef RESTYLE_LOGGING
, mLoggingDepth(aParentRestyler.mLoggingDepth + 1)
#endif
{
+ MOZ_ASSERT_IF(mContent, !mContent->IsStyledByServo());
if (aConstructorFlags & FOR_OUT_OF_FLOW_CHILD) {
// Note that the out-of-flow may not be a geometric descendant of
// the frame where we started the reresolve. Therefore, even if
// mHintsHandled already includes nsChangeHint_AllReflowHints we
// don't want to pass that on to the out-of-flow reresolve, since
// that can lead to the out-of-flow not getting reflowed when it
// should be (eg a reresolve starting at <body> that involves
// reflowing the <body> would miss reflowing fixed-pos nodes that
@@ -2682,16 +2684,17 @@ ElementRestyler::ElementRestyler(ParentC
, mKidsDesiredA11yNotifications(mDesiredA11yNotifications)
, mOurA11yNotification(eDontNotify)
, mVisibleKidsOfHiddenElement(aParentRestyler.mVisibleKidsOfHiddenElement)
#endif
#ifdef RESTYLE_LOGGING
, mLoggingDepth(aParentRestyler.mLoggingDepth + 1)
#endif
{
+ MOZ_ASSERT_IF(mContent, !mContent->IsStyledByServo());
}
ElementRestyler::ElementRestyler(nsPresContext* aPresContext,
nsIContent* aContent,
nsStyleChangeList* aChangeList,
nsChangeHint aHintsHandledByAncestors,
RestyleTracker& aRestyleTracker,
nsTArray<nsCSSSelector*>& aSelectorsForDescendants,
@@ -2881,29 +2884,31 @@ ElementRestyler::ConditionallyRestyleChi
}
void
ElementRestyler::ConditionallyRestyleChildren(nsIFrame* aFrame,
Element* aRestyleRoot)
{
MOZ_ASSERT(aFrame->GetContent());
MOZ_ASSERT(aFrame->GetContent()->IsElement());
+ MOZ_ASSERT(!aFrame->GetContent()->IsStyledByServo());
ConditionallyRestyleUndisplayedDescendants(aFrame, aRestyleRoot);
ConditionallyRestyleContentChildren(aFrame, aRestyleRoot);
}
// The structure of this method parallels RestyleContentChildren.
// If you update this method, you probably want to update that one too.
void
ElementRestyler::ConditionallyRestyleContentChildren(nsIFrame* aFrame,
Element* aRestyleRoot)
{
MOZ_ASSERT(aFrame->GetContent());
MOZ_ASSERT(aFrame->GetContent()->IsElement());
+ MOZ_ASSERT(!aFrame->GetContent()->IsStyledByServo());
if (aFrame->GetContent()->HasFlag(mRestyleTracker.RootBit())) {
aRestyleRoot = aFrame->GetContent()->AsElement();
}
for (nsIFrame* f = aFrame; f;
f = GetNextContinuationWithSameStyle(f, f->StyleContext())) {
nsIFrame::ChildListIterator lists(f);
@@ -2978,24 +2983,24 @@ void
ElementRestyler::ConditionallyRestyleUndisplayedNodes(
UndisplayedNode* aUndisplayed,
nsIContent* aUndisplayedParent,
const uint8_t aDisplay,
Element* aRestyleRoot)
{
MOZ_ASSERT(aDisplay == NS_STYLE_DISPLAY_NONE ||
aDisplay == NS_STYLE_DISPLAY_CONTENTS);
-
if (!aUndisplayed) {
return;
}
if (aUndisplayedParent &&
aUndisplayedParent->IsElement() &&
aUndisplayedParent->HasFlag(mRestyleTracker.RootBit())) {
+ MOZ_ASSERT(!aUndisplayedParent->IsStyledByServo());
aRestyleRoot = aUndisplayedParent->AsElement();
}
for (UndisplayedNode* undisplayed = aUndisplayed; undisplayed;
undisplayed = undisplayed->mNext) {
if (!undisplayed->mContent->IsElement()) {
continue;
@@ -3012,16 +3017,17 @@ ElementRestyler::ConditionallyRestyleUnd
}
}
}
void
ElementRestyler::ConditionallyRestyleContentDescendants(Element* aElement,
Element* aRestyleRoot)
{
+ MOZ_ASSERT(!aElement->IsStyledByServo());
if (aElement->HasFlag(mRestyleTracker.RootBit())) {
aRestyleRoot = aElement;
}
FlattenedChildIterator it(aElement);
for (nsIContent* n = it.GetNextChild(); n; n = it.GetNextChild()) {
if (n->IsElement()) {
Element* e = n->AsElement();
@@ -3042,16 +3048,17 @@ ElementRestyler::ConditionallyRestyle(ns
}
return ConditionallyRestyle(aFrame->GetContent()->AsElement(), aRestyleRoot);
}
bool
ElementRestyler::ConditionallyRestyle(Element* aElement, Element* aRestyleRoot)
{
+ MOZ_ASSERT(!aElement->IsStyledByServo());
LOG_RESTYLE("considering element %s for eRestyle_SomeDescendants",
ElementTagToString(aElement).get());
LOG_RESTYLE_INDENT();
if (aElement->HasFlag(mRestyleTracker.RootBit())) {
aRestyleRoot = aElement;
}
--- a/layout/base/RestyleTracker.cpp
+++ b/layout/base/RestyleTracker.cpp
@@ -163,28 +163,30 @@ RestyleTracker::DoProcessRestyles()
// loop so that we process any restyle events generated by processing
while (mPendingRestyles.Count()) {
if (mHaveLaterSiblingRestyles) {
// Convert them to individual restyles on all the later siblings
AutoTArray<RefPtr<Element>, RESTYLE_ARRAY_STACKSIZE> laterSiblingArr;
for (auto iter = mPendingRestyles.Iter(); !iter.Done(); iter.Next()) {
auto element = static_cast<dom::Element*>(iter.Key());
+ MOZ_ASSERT(!element->IsStyledByServo(), "Should not have Servo-styled elements here");
// Only collect the entries that actually need restyling by us (and
// haven't, for example, already been restyled).
// It's important to not mess with the flags on entries not in our
// document.
if (element->GetComposedDoc() == Document() &&
element->HasFlag(RestyleBit()) &&
(iter.Data()->mRestyleHint & eRestyle_LaterSiblings)) {
laterSiblingArr.AppendElement(element);
}
}
for (uint32_t i = 0; i < laterSiblingArr.Length(); ++i) {
Element* element = laterSiblingArr[i];
+ MOZ_ASSERT(!element->IsStyledByServo());
for (nsIContent* sibling = element->GetNextSibling();
sibling;
sibling = sibling->GetNextSibling()) {
if (sibling->IsElement()) {
LOG_RESTYLE("adding pending restyle for %s due to "
"eRestyle_LaterSiblings hint on %s",
FrameTagToString(sibling->AsElement()).get(),
FrameTagToString(element->AsElement()).get());