void
nsAnimationReceiver::RecordAnimationMutation(Animation* aAnimation,
                                             AnimationMutation aMutationType)
{
  KeyframeEffectReadonly* effect = aAnimation->GetEffect();
  if (!effect) {
    return;
  }

  Element* animationTarget = effect->GetTarget();
  if (!animationTarget) {
    return;
  }

  if (!Animations() || !(Subtree() || animationTarget == Target()) ||
      animationTarget->ChromeOnlyAccess()) {
    return;
  }

  if (nsAutoAnimationMutationBatch::IsBatching()) {
    if (nsAutoAnimationMutationBatch::GetBatchTarget() != animationTarget) {
      return;
    }

    switch (aMutationType) {
      case eAnimationMutation_Added:
        nsAutoAnimationMutationBatch::AnimationAdded(aAnimation);
        break;
      case eAnimationMutation_Changed:
        nsAutoAnimationMutationBatch::AnimationChanged(aAnimation);
        break;
      case eAnimationMutation_Removed:
        nsAutoAnimationMutationBatch::AnimationRemoved(aAnimation);
        break;
    }

    nsAutoAnimationMutationBatch::AddObserver(Observer());
    return;
  }

  nsDOMMutationRecord* m =
    Observer()->CurrentRecord(nsGkAtoms::animations);

  NS_ASSERTION(!m->mTarget, "Wrong target!");

  m->mTarget = animationTarget;

  switch (aMutationType) {
    case eAnimationMutation_Added:
      m->mAddedAnimations.AppendElement(aAnimation);
      break;
    case eAnimationMutation_Changed:
      m->mChangedAnimations.AppendElement(aAnimation);
      break;
    case eAnimationMutation_Removed:
      m->mRemovedAnimations.AppendElement(aAnimation);
      break;
  }
}
static inline Element*
GetTarget(AnimationPlayer* aPlayer)
{
  KeyframeEffectReadonly* effect = aPlayer->GetEffect();
  if (!effect) {
    return nullptr;
  }

  Element* target;
  nsCSSPseudoElements::Type pseudoType;
  effect->GetTarget(target, pseudoType);

  // If the animation targets a pseudo-element, we don't dispatch
  // notifications for it.  (In the future we will have PseudoElement
  // objects we can use as the target of the notifications.)
  if (pseudoType != nsCSSPseudoElements::ePseudo_NotPseudoElement) {
    return nullptr;
  }

  return effect->GetTarget();
}