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));
  }
}
Ejemplo n.º 3
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));
}