void ServoRestyleManager::PostRestyleEvent(Element* aElement, nsRestyleHint aRestyleHint, nsChangeHint aMinChangeHint) { MOZ_ASSERT(!(aMinChangeHint & nsChangeHint_NeutralChange), "Didn't expect explicit change hints to be neutral!"); if (MOZ_UNLIKELY(IsDisconnected()) || MOZ_UNLIKELY(PresContext()->PresShell()->IsDestroying())) { return; } // We allow posting restyles from within change hint handling, but not from // within the restyle algorithm itself. MOZ_ASSERT(!ServoStyleSet::IsInServoTraversal()); if (aRestyleHint == 0 && !aMinChangeHint) { return; // Nothing to do. } // Processing change hints sometimes causes new change hints to be generated, // and very occasionally, additional restyle hints. We collect the change // hints manually to avoid re-traversing the DOM to find them. if (mReentrantChanges && !aRestyleHint) { mReentrantChanges->AppendElement(ReentrantChange { aElement, aMinChangeHint }); return; } if (aRestyleHint & ~eRestyle_AllHintsWithAnimations) { mHaveNonAnimationRestyles = true; } Servo_NoteExplicitHints(aElement, aRestyleHint, aMinChangeHint); }
void ServoRestyleManager::AttributeChanged(Element* aElement, int32_t aNameSpaceID, nsIAtom* aAttribute, int32_t aModType, const nsAttrValue* aOldValue) { MOZ_ASSERT(!mInStyleRefresh); MOZ_ASSERT_IF(mSnapshots.Get(aElement), mSnapshots.Get(aElement)->HasAttrs()); nsIFrame* primaryFrame = aElement->GetPrimaryFrame(); if (primaryFrame) { primaryFrame->AttributeChanged(aNameSpaceID, aAttribute, aModType); } nsChangeHint hint = aElement->GetAttributeChangeHint(aAttribute, aModType); if (hint) { PostRestyleEvent(aElement, nsRestyleHint(0), hint); } if (aAttribute == nsGkAtoms::style) { PostRestyleEvent(aElement, eRestyle_StyleAttribute, nsChangeHint(0)); } // <td> is affected by the cellpadding on its ancestor table, // so we should restyle the whole subtree if (aAttribute == nsGkAtoms::cellpadding && aElement->IsHTMLElement(nsGkAtoms::table)) { PostRestyleEvent(aElement, eRestyle_Subtree, nsChangeHint(0)); } if (aElement->IsAttributeMapped(aAttribute)) { Servo_NoteExplicitHints(aElement, eRestyle_Self, nsChangeHint(0)); } }
void ServoRestyleManager::PostRestyleEvent(Element* aElement, nsRestyleHint aRestyleHint, nsChangeHint aMinChangeHint) { if (MOZ_UNLIKELY(IsDisconnected()) || MOZ_UNLIKELY(PresContext()->PresShell()->IsDestroying())) { return; } if (aRestyleHint == 0 && !aMinChangeHint && !HasPendingRestyles()) { return; // Nothing to do. } // We allow posting change hints during restyling, but not restyle hints // themselves, since those would require us to re-traverse the tree. MOZ_ASSERT_IF(mInStyleRefresh, aRestyleHint == 0); // Processing change hints sometimes causes new change hints to be generated. // Doing this after the gecko post-traversal is problematic, so instead we just // queue them up for special handling. if (mReentrantChanges) { MOZ_ASSERT(aRestyleHint == 0); mReentrantChanges->AppendElement(ReentrantChange { aElement, aMinChangeHint }); return; } // XXX This is a temporary hack to make style attribute change works. // In the future, we should be able to use this hint directly. if (aRestyleHint & eRestyle_StyleAttribute) { aRestyleHint &= ~eRestyle_StyleAttribute; aRestyleHint |= eRestyle_Self | eRestyle_Subtree; } // XXX For now, convert eRestyle_Subtree into (eRestyle_Self | // eRestyle_SomeDescendants), which Servo will interpret as // RESTYLE_SELF | RESTYLE_DESCENDANTS, since this is a commonly // posted restyle hint that doesn't yet align with RestyleHint's // bits. if (aRestyleHint & eRestyle_Subtree) { aRestyleHint &= ~eRestyle_Subtree; aRestyleHint |= eRestyle_Self | eRestyle_SomeDescendants; } if (aRestyleHint || aMinChangeHint) { Servo_NoteExplicitHints(aElement, aRestyleHint, aMinChangeHint); } PostRestyleEventInternal(false); }
/* static */ void ServoRestyleManager::PostRestyleEventForAnimations(Element* aElement, nsRestyleHint aRestyleHint) { Servo_NoteExplicitHints(aElement, aRestyleHint, nsChangeHint(0)); }