/*
 * Copyright (C) 2008 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "third_party/blink/renderer/core/svg/animation/svg_smil_element.h"

#include <algorithm>

#include "base/auto_reset.h"
#include "base/time/time.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/bindings/core/v8/js_event_handler_for_content_attribute.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/dom/events/native_event_listener.h"
#include "third_party/blink/renderer/core/dom/id_target_observer.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/core/svg/animation/smil_time_container.h"
#include "third_party/blink/renderer/core/svg/svg_svg_element.h"
#include "third_party/blink/renderer/core/svg/svg_uri_reference.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/blink/renderer/platform/wtf/math_extras.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"

namespace blink {

namespace {

// Compute the next time an interval with a certain (non-zero) simple duration
// will repeat, relative to a certain presentation time.
SMILTime ComputeNextRepeatTime(SMILTime interval_begin,
                               SMILTime simple_duration,
                               SMILTime presentation_time) {
  DCHECK(simple_duration);
  DCHECK_LE(interval_begin, presentation_time);
  SMILTime time_in_interval = presentation_time - interval_begin;
  SMILTime time_until_next_repeat =
      simple_duration - (time_in_interval % simple_duration);
  return presentation_time + time_until_next_repeat;
}

}  // namespace

void SMILInstanceTimeList::Append(SMILTime time, SMILTimeOrigin origin) {
  instance_times_.push_back(SMILTimeWithOrigin(time, origin));
  AddOrigin(origin);
}

void SMILInstanceTimeList::InsertSortedAndUnique(SMILTime time,
                                                 SMILTimeOrigin origin) {
  SMILTimeWithOrigin time_with_origin(time, origin);
  auto* position = std::lower_bound(instance_times_.begin(),
                                    instance_times_.end(), time_with_origin);
  // Don't add it if we already have one of those.
  for (auto* it = position; it != instance_times_.end(); ++it) {
    if (position->Time() != time)
      break;
    // If they share both time and origin, we don't need to add it,
    // we just need to react.
    if (position->Origin() == origin)
      return;
  }
  instance_times_.insert(position - instance_times_.begin(), time_with_origin);
  AddOrigin(origin);
}

void SMILInstanceTimeList::RemoveWithOrigin(SMILTimeOrigin origin) {
  if (!HasOrigin(origin))
    return;
  auto* tail =
      std::remove_if(instance_times_.begin(), instance_times_.end(),
                     [origin](const SMILTimeWithOrigin& instance_time) {
                       return instance_time.Origin() == origin;
                     });
  instance_times_.Shrink(tail - instance_times_.begin());
  ClearOrigin(origin);
}

void SMILInstanceTimeList::Sort() {
  std::sort(instance_times_.begin(), instance_times_.end());
}

SMILTime SMILInstanceTimeList::NextAfter(SMILTime time) const {
  // Find the value in |list| that is strictly greater than |time|.
  auto* next_item = std::lower_bound(
      instance_times_.begin(), instance_times_.end(), time,
      [](const SMILTimeWithOrigin& instance_time, const SMILTime& time) {
        return instance_time.Time() <= time;
      });
  if (next_item == instance_times_.end())
    return SMILTime::Unresolved();
  return next_item->Time();
}

// This is used for duration type time values that can't be negative.
static constexpr SMILTime kInvalidCachedTime = SMILTime::Earliest();

class ConditionEventListener final : public NativeEventListener {
 public:
  ConditionEventListener(SVGSMILElement* animation,
                         SVGSMILElement::Condition* condition)
      : animation_(animation), condition_(condition) {}

  void DisconnectAnimation() { animation_ = nullptr; }

  void Invoke(ExecutionContext*, Event*) override {
    if (!animation_)
      return;
    animation_->AddInstanceTimeAndUpdate(
        condition_->GetBeginOrEnd(),
        animation_->Elapsed() + condition_->Offset(), SMILTimeOrigin::kEvent);
  }

  void Trace(Visitor* visitor) const override {
    visitor->Trace(animation_);
    visitor->Trace(condition_);
    NativeEventListener::Trace(visitor);
  }

 private:
  Member<SVGSMILElement> animation_;
  Member<SVGSMILElement::Condition> condition_;
};

SVGSMILElement::Condition::Condition(Type type,
                                     BeginOrEnd begin_or_end,
                                     const AtomicString& base_id,
                                     const AtomicString& name,
                                     SMILTime offset,
                                     unsigned repeat)
    : type_(type),
      begin_or_end_(begin_or_end),
      base_id_(base_id),
      name_(name),
      offset_(offset),
      repeat_(repeat) {}

SVGSMILElement::Condition::~Condition() = default;

void SVGSMILElement::Condition::Trace(Visitor* visitor) const {
  visitor->Trace(base_element_);
  visitor->Trace(base_id_observer_);
  visitor->Trace(event_listener_);
}

void SVGSMILElement::Condition::ConnectSyncBase(SVGSMILElement& timed_element) {
  DCHECK(!base_id_.IsEmpty());
  DCHECK_EQ(type_, kSyncBase);
  DCHECK(!base_element_);
  auto* svg_smil_element =
      DynamicTo<SVGSMILElement>(SVGURIReference::ObserveTarget(
          base_id_observer_, timed_element.GetTreeScope(), base_id_,
          WTF::BindRepeating(&SVGSMILElement::BuildPendingResource,
                             WrapWeakPersistent(&timed_element))));
  if (!svg_smil_element)
    return;
  base_element_ = svg_smil_element;
  svg_smil_element->AddSyncBaseDependent(timed_element);
}

void SVGSMILElement::Condition::DisconnectSyncBase(
    SVGSMILElement& timed_element) {
  DCHECK_EQ(type_, kSyncBase);
  SVGURIReference::UnobserveTarget(base_id_observer_);
  if (!base_element_)
    return;
  To<SVGSMILElement>(*base_element_).RemoveSyncBaseDependent(timed_element);
  base_element_ = nullptr;
}

void SVGSMILElement::Condition::ConnectEventBase(
    SVGSMILElement& timed_element) {
  DCHECK_EQ(type_, kEventBase);
  DCHECK(!base_element_);
  DCHECK(!event_listener_);
  SVGElement* target;
  if (base_id_.IsEmpty()) {
    target = timed_element.targetElement();
  } else {
    target = DynamicTo<SVGElement>(SVGURIReference::ObserveTarget(
        base_id_observer_, timed_element.GetTreeScope(), base_id_,
        WTF::BindRepeating(&SVGSMILElement::BuildPendingResource,
                           WrapWeakPersistent(&timed_element))));
  }
  if (!target)
    return;
  event_listener_ =
      MakeGarbageCollected<ConditionEventListener>(&timed_element, this);
  base_element_ = target;
  base_element_->addEventListener(name_, event_listener_, false);
  timed_element.AddReferenceTo(base_element_);
}

void SVGSMILElement::Condition::DisconnectEventBase(
    SVGSMILElement& timed_element) {
  DCHECK_EQ(type_, kEventBase);
  SVGURIReference::UnobserveTarget(base_id_observer_);
  if (!event_listener_)
    return;
  base_element_->removeEventListener(name_, event_listener_, false);
  base_element_ = nullptr;
  event_listener_->DisconnectAnimation();
  event_listener_ = nullptr;
}

SVGSMILElement::SVGSMILElement(const QualifiedName& tag_name, Document& doc)
    : SVGElement(tag_name, doc),
      SVGTests(this),
      target_element_(nullptr),
      conditions_connected_(false),
      has_end_event_conditions_(false),
      is_waiting_for_first_interval_(true),
      is_scheduled_(false),
      interval_(SMILInterval::Unresolved()),
      previous_interval_(SMILInterval::Unresolved()),
      active_state_(kInactive),
      restart_(kRestartAlways),
      fill_(kFillRemove),
      last_progress_{0.0f, 0},
      document_order_index_(0),
      queue_handle_(kNotFound),
      cached_dur_(kInvalidCachedTime),
      cached_repeat_dur_(kInvalidCachedTime),
      cached_repeat_count_(SMILRepeatCount::Invalid()),
      cached_min_(kInvalidCachedTime),
      cached_max_(kInvalidCachedTime),
      interval_has_changed_(false),
      instance_lists_have_changed_(false),
      is_notifying_dependents_(false) {}

SVGSMILElement::~SVGSMILElement() = default;

void SVGSMILElement::ClearResourceAndEventBaseReferences() {
  SVGURIReference::UnobserveTarget(target_id_observer_);
  RemoveAllOutgoingReferences();
}

void SVGSMILElement::BuildPendingResource() {
  ClearResourceAndEventBaseReferences();
  DisconnectConditions();

  if (!isConnected()) {
    // Reset the target element if we are no longer in the document.
    SetTargetElement(nullptr);
    return;
  }

  const AtomicString& href = SVGURIReference::LegacyHrefString(*this);
  Element* target;
  if (href.IsEmpty()) {
    target = parentElement();
  } else {
    target = SVGURIReference::ObserveTarget(target_id_observer_, *this, href);
  }
  auto* svg_target = DynamicTo<SVGElement>(target);

  if (svg_target && !svg_target->isConnected())
    svg_target = nullptr;

  SetTargetElement(svg_target);

  if (svg_target) {
    // Register us with the target in the dependencies map. Any change of
    // hrefElement that leads to relayout/repainting now informs us, so we can
    // react to it.
    AddReferenceTo(svg_target);
  }
  ConnectConditions();
}

void SVGSMILElement::Reset() {
  active_state_ = kInactive;
  is_waiting_for_first_interval_ = true;
  interval_ = SMILInterval::Unresolved();
  previous_interval_ = SMILInterval::Unresolved();
  last_progress_ = {0.0f, 0};
}

Node::InsertionNotificationRequest SVGSMILElement::InsertedInto(
    ContainerNode& root_parent) {
  SVGElement::InsertedInto(root_parent);

  if (!root_parent.isConnected())
    return kInsertionDone;

  UseCounter::Count(GetDocument(), WebFeature::kSVGSMILElementInDocument);
  if (GetDocument().IsLoadCompleted()) {
    UseCounter::Count(&GetDocument(),
                      WebFeature::kSVGSMILElementInsertedAfterLoad);
  }

  SVGSVGElement* owner = ownerSVGElement();
  if (!owner)
    return kInsertionDone;

  time_container_ = owner->TimeContainer();
  DCHECK(time_container_);
  time_container_->SetDocumentOrderIndexesDirty();

  // "If no attribute is present, the default begin value (an offset-value of 0)
  // must be evaluated."
  if (!FastHasAttribute(svg_names::kBeginAttr) && begin_times_.IsEmpty())
    begin_times_.Append(SMILTime(), SMILTimeOrigin::kAttribute);

  BuildPendingResource();
  return kInsertionDone;
}

void SVGSMILElement::RemovedFrom(ContainerNode& root_parent) {
  if (root_parent.isConnected()) {
    ClearResourceAndEventBaseReferences();
    ClearConditions();
    SetTargetElement(nullptr);
    time_container_ = nullptr;
  }

  SVGElement::RemovedFrom(root_parent);
}

SMILTime SVGSMILElement::ParseOffsetValue(const String& data) {
  bool ok;
  double result = 0;
  const String parse = data.StripWhiteSpace();
  if (parse.EndsWith('h')) {
    result = parse.Left(parse.length() - 1).ToDouble(&ok) *
             base::Time::kSecondsPerHour;
  } else if (parse.EndsWith("min")) {
    result = parse.Left(parse.length() - 3).ToDouble(&ok) *
             base::Time::kSecondsPerMinute;
  } else if (parse.EndsWith("ms")) {
    result = parse.Left(parse.length() - 2).ToDouble(&ok) /
             base::Time::kMillisecondsPerSecond;
  } else if (parse.EndsWith('s')) {
    result = parse.Left(parse.length() - 1).ToDouble(&ok);
  } else {
    result = parse.ToDouble(&ok);
  }
  return ok ? SMILTime::FromSecondsD(result) : SMILTime::Unresolved();
}

SMILTime SVGSMILElement::ParseClockValue(const String& data) {
  if (data.IsNull())
    return SMILTime::Unresolved();

  String parse = data.StripWhiteSpace();

  DEFINE_STATIC_LOCAL(const AtomicString, indefinite_value, ("indefinite"));
  if (parse == indefinite_value)
    return SMILTime::Indefinite();

  double result = 0;
  bool ok;
  wtf_size_t double_point_one = parse.find(':');
  wtf_size_t double_point_two = parse.find(':', double_point_one + 1);
  if (double_point_one == 2 && double_point_two == 5 && parse.length() >= 8) {
    result += parse.Substring(0, 2).ToUIntStrict(&ok) * 60 * 60;
    if (!ok)
      return SMILTime::Unresolved();
    result += parse.Substring(3, 2).ToUIntStrict(&ok) * 60;
    if (!ok)
      return SMILTime::Unresolved();
    result += parse.Substring(6).ToDouble(&ok);
  } else if (double_point_one == 2 && double_point_two == kNotFound &&
             parse.length() >= 5) {
    result += parse.Substring(0, 2).ToUIntStrict(&ok) * 60;
    if (!ok)
      return SMILTime::Unresolved();
    result += parse.Substring(3).ToDouble(&ok);
  } else {
    return ParseOffsetValue(parse);
  }

  if (!ok)
    return SMILTime::Unresolved();
  return SMILTime::FromSecondsD(result);
}

bool SVGSMILElement::ParseCondition(const String& value,
                                    BeginOrEnd begin_or_end) {
  String parse_string = value.StripWhiteSpace();

  bool is_negated = false;
  bool ok;
  wtf_size_t pos = parse_string.find('+');
  if (pos == kNotFound) {
    pos = parse_string.find('-');
    is_negated = pos != kNotFound;
  }
  String condition_string;
  SMILTime offset;
  if (pos == kNotFound) {
    condition_string = parse_string;
  } else {
    condition_string = parse_string.Left(pos).StripWhiteSpace();
    String offset_string = parse_string.Substring(pos + 1).StripWhiteSpace();
    offset = ParseOffsetValue(offset_string);
    if (offset.IsUnresolved())
      return false;
    if (is_negated)
      offset = -offset;
  }
  if (condition_string.IsEmpty())
    return false;
  pos = condition_string.find('.');

  String base_id;
  String name_string;
  if (pos == kNotFound) {
    name_string = condition_string;
  } else {
    base_id = condition_string.Left(pos);
    name_string = condition_string.Substring(pos + 1);
  }
  if (name_string.IsEmpty())
    return false;

  Condition::Type type;
  int repeat = -1;
  if (name_string.StartsWith("repeat(") && name_string.EndsWith(')')) {
    repeat =
        name_string.Substring(7, name_string.length() - 8).ToUIntStrict(&ok);
    if (!ok)
      return false;
    name_string = "repeat";
    type = Condition::kSyncBase;
  } else if (name_string == "begin" || name_string == "end") {
    if (base_id.IsEmpty())
      return false;
    UseCounter::Count(&GetDocument(),
                      WebFeature::kSVGSMILBeginOrEndSyncbaseValue);
    type = Condition::kSyncBase;
  } else if (name_string.StartsWith("accesskey(")) {
    // FIXME: accesskey() support.
    type = Condition::kAccessKey;
  } else {
    UseCounter::Count(&GetDocument(), WebFeature::kSVGSMILBeginOrEndEventValue);
    type = Condition::kEventBase;
  }

  conditions_.push_back(MakeGarbageCollected<Condition>(
      type, begin_or_end, AtomicString(base_id), AtomicString(name_string),
      offset, repeat));

  if (type == Condition::kEventBase && begin_or_end == kEnd)
    has_end_event_conditions_ = true;

  return true;
}

void SVGSMILElement::ParseBeginOrEnd(const String& parse_string,
                                     BeginOrEnd begin_or_end) {
  auto& time_list = begin_or_end == kBegin ? begin_times_ : end_times_;
  if (begin_or_end == kEnd)
    has_end_event_conditions_ = false;

  // Remove any previously added offset-values.
  // TODO(fs): Ought to remove instance times originating from sync-bases,
  // events etc. as well if those conditions are no longer in the attribute.
  time_list.RemoveWithOrigin(SMILTimeOrigin::kAttribute);

  Vector<String> split_string;
  parse_string.Split(';', split_string);
  for (const auto& item : split_string) {
    SMILTime value = ParseClockValue(item);
    if (value.IsUnresolved())
      ParseCondition(item, begin_or_end);
    else
      time_list.Append(value, SMILTimeOrigin::kAttribute);
  }
  // "If no attribute is present, the default begin value (an offset-value of 0)
  // must be evaluated."
  if (begin_or_end == kBegin && parse_string.IsNull())
    begin_times_.Append(SMILTime(), SMILTimeOrigin::kAttribute);

  time_list.Sort();
}

void SVGSMILElement::ParseAttribute(const AttributeModificationParams& params) {
  const QualifiedName& name = params.name;
  const AtomicString& value = params.new_value;
  if (name == svg_names::kBeginAttr) {
    if (!conditions_.IsEmpty()) {
      ClearConditions();
      ParseBeginOrEnd(FastGetAttribute(svg_names::kEndAttr), kEnd);
    }
    ParseBeginOrEnd(value.GetString(), kBegin);
    if (isConnected()) {
      ConnectConditions();
      instance_lists_have_changed_ = true;
      InstanceListChanged();
    }
  } else if (name == svg_names::kEndAttr) {
    if (!conditions_.IsEmpty()) {
      ClearConditions();
      ParseBeginOrEnd(FastGetAttribute(svg_names::kBeginAttr), kBegin);
    }
    ParseBeginOrEnd(value.GetString(), kEnd);
    if (isConnected()) {
      ConnectConditions();
      instance_lists_have_changed_ = true;
      InstanceListChanged();
    }
  } else if (name == svg_names::kOnbeginAttr) {
    SetAttributeEventListener(event_type_names::kBeginEvent,
                              JSEventHandlerForContentAttribute::Create(
                                  GetExecutionContext(), name, value));
  } else if (name == svg_names::kOnendAttr) {
    SetAttributeEventListener(event_type_names::kEndEvent,
                              JSEventHandlerForContentAttribute::Create(
                                  GetExecutionContext(), name, value));
  } else if (name == svg_names::kOnrepeatAttr) {
    SetAttributeEventListener(event_type_names::kRepeatEvent,
                              JSEventHandlerForContentAttribute::Create(
                                  GetExecutionContext(), name, value));
  } else if (name == svg_names::kRestartAttr) {
    if (value == "never")
      restart_ = kRestartNever;
    else if (value == "whenNotActive")
      restart_ = kRestartWhenNotActive;
    else
      restart_ = kRestartAlways;
  } else if (name == svg_names::kFillAttr) {
    fill_ = value == "freeze" ? kFillFreeze : kFillRemove;
  } else if (name == svg_names::kDurAttr) {
    cached_dur_ = kInvalidCachedTime;
  } else if (name == svg_names::kRepeatDurAttr) {
    cached_repeat_dur_ = kInvalidCachedTime;
  } else if (name == svg_names::kRepeatCountAttr) {
    cached_repeat_count_ = SMILRepeatCount::Invalid();
  } else if (name == svg_names::kMinAttr) {
    cached_min_ = kInvalidCachedTime;
  } else if (name == svg_names::kMaxAttr) {
    cached_max_ = kInvalidCachedTime;
  } else {
    SVGElement::ParseAttribute(params);
  }
}

void SVGSMILElement::SvgAttributeChanged(
    const SvgAttributeChangedParams& params) {
  if (SVGURIReference::IsKnownAttribute(params.name)) {
    // TODO(fs): Could be smarter here when 'href' is specified and 'xlink:href'
    // is changed.
    SVGElement::InvalidationGuard invalidation_guard(this);
    BuildPendingResource();
    return;
  }
  SVGElement::SvgAttributeChanged(params);
}

bool SVGSMILElement::IsPresentationAttribute(
    const QualifiedName& attr_name) const {
  // Don't map 'fill' to the 'fill' property for animation elements.
  if (attr_name == svg_names::kFillAttr)
    return false;
  return SVGElement::IsPresentationAttribute(attr_name);
}

void SVGSMILElement::ConnectConditions() {
  if (conditions_connected_)
    DisconnectConditions();
  for (Condition* condition : conditions_) {
    if (condition->GetType() == Condition::kSyncBase)
      condition->ConnectSyncBase(*this);
    else if (condition->GetType() == Condition::kEventBase)
      condition->ConnectEventBase(*this);
  }
  conditions_connected_ = true;
}

void SVGSMILElement::DisconnectConditions() {
  if (!conditions_connected_)
    return;
  for (Condition* condition : conditions_) {
    if (condition->GetType() == Condition::kSyncBase)
      condition->DisconnectSyncBase(*this);
    else if (condition->GetType() == Condition::kEventBase)
      condition->DisconnectEventBase(*this);
  }
  conditions_connected_ = false;
}

void SVGSMILElement::ClearConditions() {
  DisconnectConditions();
  conditions_.clear();
}

void SVGSMILElement::SetTargetElement(SVGElement* target) {
  if (target == target_element_)
    return;
  WillChangeAnimationTarget();
  target_element_ = target;
  DidChangeAnimationTarget();
}

SMILTime SVGSMILElement::Elapsed() const {
  return time_container_ ? time_container_->Elapsed() : SMILTime();
}

SMILTime SVGSMILElement::BeginTimeForPrioritization(
    SMILTime presentation_time) const {
  if (GetActiveState() == kFrozen) {
    if (interval_.BeginsAfter(presentation_time))
      return previous_interval_.begin;
  }
  return interval_.begin;
}

bool SVGSMILElement::IsHigherPriorityThan(const SVGSMILElement* other,
                                          SMILTime presentation_time) const {
  // FIXME: This should also consider possible timing relations between the
  // elements.
  SMILTime this_begin = BeginTimeForPrioritization(presentation_time);
  SMILTime other_begin = other->BeginTimeForPrioritization(presentation_time);
  if (this_begin == other_begin)
    return DocumentOrderIndex() > other->DocumentOrderIndex();
  return this_begin > other_begin;
}

SMILTime SVGSMILElement::Dur() const {
  if (cached_dur_ != kInvalidCachedTime)
    return cached_dur_;
  const AtomicString& value = FastGetAttribute(svg_names::kDurAttr);
  SMILTime clock_value = ParseClockValue(value);
  return cached_dur_ =
             clock_value <= SMILTime() ? SMILTime::Unresolved() : clock_value;
}

SMILTime SVGSMILElement::RepeatDur() const {
  if (cached_repeat_dur_ != kInvalidCachedTime)
    return cached_repeat_dur_;
  const AtomicString& value = FastGetAttribute(svg_names::kRepeatDurAttr);
  SMILTime clock_value = ParseClockValue(value);
  cached_repeat_dur_ =
      clock_value <= SMILTime() ? SMILTime::Unresolved() : clock_value;
  return cached_repeat_dur_;
}

static SMILRepeatCount ParseRepeatCount(const AtomicString& value) {
  if (value.IsNull())
    return SMILRepeatCount::Unspecified();
  if (value == "indefinite")
    return SMILRepeatCount::Indefinite();
  bool ok;
  double result = value.ToDouble(&ok);
  if (ok && result > 0 && std::isfinite(result))
    return SMILRepeatCount::Numeric(result);
  return SMILRepeatCount::Unspecified();
}

SMILRepeatCount SVGSMILElement::RepeatCount() const {
  if (!cached_repeat_count_.IsValid()) {
    cached_repeat_count_ =
        ParseRepeatCount(FastGetAttribute(svg_names::kRepeatCountAttr));
  }
  DCHECK(cached_repeat_count_.IsValid());
  return cached_repeat_count_;
}

SMILTime SVGSMILElement::MaxValue() const {
  if (cached_max_ != kInvalidCachedTime)
    return cached_max_;
  const AtomicString& value = FastGetAttribute(svg_names::kMaxAttr);
  SMILTime result = ParseClockValue(value);
  return cached_max_ = (result.IsUnresolved() || result <= SMILTime())
                           ? SMILTime::Indefinite()
                           : result;
}

SMILTime SVGSMILElement::MinValue() const {
  if (cached_min_ != kInvalidCachedTime)
    return cached_min_;
  const AtomicString& value = FastGetAttribute(svg_names::kMinAttr);
  SMILTime result = ParseClockValue(value);
  return cached_min_ = (result.IsUnresolved() || result < SMILTime())
                           ? SMILTime()
                           : result;
}

SMILTime SVGSMILElement::SimpleDuration() const {
  return std::min(Dur(), SMILTime::Indefinite());
}

void SVGSMILElement::AddInstanceTime(BeginOrEnd begin_or_end,
                                     SMILTime time,
                                     SMILTimeOrigin origin) {
  auto& list = begin_or_end == kBegin ? begin_times_ : end_times_;
  list.InsertSortedAndUnique(time, origin);
  instance_lists_have_changed_ = true;
}

void SVGSMILElement::AddInstanceTimeAndUpdate(BeginOrEnd begin_or_end,
                                              SMILTime time,
                                              SMILTimeOrigin origin) {
  // Ignore new instance times for 'end' if the element is not active
  // and the origin is script.
  if (begin_or_end == kEnd && GetActiveState() == kInactive &&
      origin == SMILTimeOrigin::kScript)
    return;
  AddInstanceTime(begin_or_end, time, origin);
  InstanceListChanged();
}

SMILTime SVGSMILElement::RepeatingDuration() const {
  // Computing the active duration
  // http://www.w3.org/TR/SMIL2/smil-timing.html#Timing-ComputingActiveDur
  SMILRepeatCount repeat_count = RepeatCount();
  SMILTime repeat_dur = RepeatDur();
  SMILTime simple_duration = SimpleDuration();
  if (!simple_duration ||
      (repeat_dur.IsUnresolved() && repeat_count.IsUnspecified()))
    return simple_duration;
  repeat_dur = std::min(repeat_dur, SMILTime::Indefinite());
  SMILTime repeat_count_duration = simple_duration.Repeat(repeat_count);
  if (!repeat_count_duration.IsUnresolved())
    return std::min(repeat_dur, repeat_count_duration);
  return repeat_dur;
}

SMILTime SVGSMILElement::ResolveActiveEnd(SMILTime resolved_begin) const {
  SMILTime resolved_end = SMILTime::Indefinite();
  if (!end_times_.IsEmpty()) {
    SMILTime next_end = end_times_.NextAfter(resolved_begin);
    if (next_end.IsUnresolved()) {
      // If we have no pending end conditions, don't generate a new interval.
      if (!has_end_event_conditions_)
        return SMILTime::Unresolved();
    } else {
      resolved_end = next_end;
    }
  }
  // Computing the active duration
  // http://www.w3.org/TR/SMIL2/smil-timing.html#Timing-ComputingActiveDur
  SMILTime preliminary_active_duration;
  if (!resolved_end.IsUnresolved() && Dur().IsUnresolved() &&
      RepeatDur().IsUnresolved() && RepeatCount().IsUnspecified())
    preliminary_active_duration = resolved_end - resolved_begin;
  else if (!resolved_end.IsFinite())
    preliminary_active_duration = RepeatingDuration();
  else
    preliminary_active_duration =
        std::min(RepeatingDuration(), resolved_end - resolved_begin);

  SMILTime min_value = MinValue();
  SMILTime max_value = MaxValue();
  if (min_value > max_value) {
    // Ignore both.
    // http://www.w3.org/TR/2001/REC-smil-animation-20010904/#MinMax
    min_value = SMILTime();
    max_value = SMILTime::Indefinite();
  }
  return resolved_begin +
         std::min(max_value, std::max(min_value, preliminary_active_duration));
}

SMILInterval SVGSMILElement::ResolveInterval(SMILTime begin_after,
                                             SMILTime end_after) const {
  // Simplified version of the pseudocode in
  // http://www.w3.org/TR/SMIL3/smil-timing.html#q90.
  const size_t kMaxIterations = std::max(begin_times_.size() * 4, 1000000u);
  size_t current_iteration = 0;
  for (auto* search_start = begin_times_.begin();
       search_start != begin_times_.end(); ++search_start) {
    // Find the (next) instance time in the 'begin' list that is greater or
    // equal to |begin_after|.
    auto* begin_item = std::lower_bound(
        search_start, begin_times_.end(), begin_after,
        [](const SMILTimeWithOrigin& instance_time, const SMILTime& time) {
          return instance_time.Time() < time;
        });
    // If there are no more 'begin' instance times, or we encountered the
    // special value "indefinite" (which doesn't yield an instance time in the
    // 'begin' list), we're done.
    if (begin_item == begin_times_.end() || begin_item->Time().IsIndefinite())
      break;
    SMILTime temp_end = ResolveActiveEnd(begin_item->Time());
    if (temp_end.IsUnresolved())
      break;
    // Don't allow the interval to end in the past.
    if (temp_end > end_after)
      return SMILInterval(begin_item->Time(), temp_end);
    // Ensure forward progress by only considering the part of the 'begin' list
    // after |begin_item| for the next iteration.
    search_start = begin_item;
    begin_after = temp_end;
    // Debugging signal for crbug.com/1021630.
    CHECK_LT(current_iteration++, kMaxIterations);
  }
  return SMILInterval::Unresolved();
}

void SVGSMILElement::SetNewInterval(const SMILInterval& interval) {
  interval_ = interval;
  NotifyDependentsOnNewInterval(interval_);
}

void SVGSMILElement::SetNewIntervalEnd(SMILTime new_end) {
  interval_.end = new_end;
  NotifyDependentsOnNewInterval(interval_);
}

SMILTime SVGSMILElement::ComputeNextIntervalTime(
    SMILTime presentation_time,
    IncludeRepeats include_repeats) const {
  SMILTime next_interval_time = SMILTime::Unresolved();
  if (interval_.BeginsAfter(presentation_time)) {
    next_interval_time = interval_.begin;
  } else if (interval_.EndsAfter(presentation_time)) {
    SMILTime simple_duration = SimpleDuration();
    if (include_repeats == kIncludeRepeats && simple_duration) {
      SMILTime next_repeat_time = ComputeNextRepeatTime(
          interval_.begin, simple_duration, presentation_time);
      DCHECK(next_repeat_time.IsFinite());
      next_interval_time = std::min(next_repeat_time, interval_.end);
    } else {
      next_interval_time = interval_.end;
    }
  }
  SMILTime next_begin = begin_times_.NextAfter(presentation_time);
  // The special value "indefinite" does not yield an instance time in the
  // begin list, so only consider finite values here.
  if (next_begin.IsFinite())
    next_interval_time = std::min(next_interval_time, next_begin);
  return next_interval_time;
}

void SVGSMILElement::InstanceListChanged() {
  DCHECK(instance_lists_have_changed_);
  SMILTime current_presentation_time =
      time_container_ ? time_container_->LatestUpdatePresentationTime()
                      : SMILTime();
  DCHECK(!current_presentation_time.IsUnresolved());
  const bool was_active = GetActiveState() == kActive;
  UpdateInterval(current_presentation_time);
  // Check active state and reschedule using the time just before the current
  // presentation time. This means that the next animation update will take
  // care of updating the active state and send events as needed.
  SMILTime previous_presentation_time =
      current_presentation_time - SMILTime::Epsilon();
  if (was_active) {
    const SMILInterval& active_interval =
        GetActiveInterval(previous_presentation_time);
    active_state_ =
        DetermineActiveState(active_interval, previous_presentation_time);
    if (GetActiveState() != kActive)
      EndedActiveInterval();
  }
  if (time_container_) {
    SMILTime next_interval_time;
    // If we switched interval and the previous interval did not end yet, we
    // need to consider it when computing the next interval time.
    if (previous_interval_.IsResolved() &&
        previous_interval_.EndsAfter(previous_presentation_time)) {
      next_interval_time = previous_interval_.end;
    } else {
      next_interval_time =
          ComputeNextIntervalTime(previous_presentation_time, kIncludeRepeats);
    }
    time_container_->Reschedule(this, next_interval_time);
  }
}

void SVGSMILElement::DiscardOrRevalidateCurrentInterval(
    SMILTime presentation_time) {
  if (!interval_.IsResolved())
    return;
  // If the current interval has not yet started, discard it and re-resolve.
  if (interval_.BeginsAfter(presentation_time)) {
    interval_ = SMILInterval::Unresolved();
    return;
  }

  // If we have a current interval but it has not yet ended, re-resolve the
  // end time.
  if (interval_.EndsAfter(presentation_time)) {
    SMILTime new_end = ResolveActiveEnd(interval_.begin);
    if (new_end.IsUnresolved()) {
      // No active duration, discard the current interval.
      interval_ = SMILInterval::Unresolved();
      // If we discarded the first interval, revert to waiting for the first
      // interval.
      if (!previous_interval_.IsResolved())
        is_waiting_for_first_interval_ = true;
      return;
    }
    if (new_end != interval_.end)
      SetNewIntervalEnd(new_end);
  }
}

bool SVGSMILElement::HandleIntervalRestart(SMILTime presentation_time) {
  Restart restart = GetRestart();
  if (!is_waiting_for_first_interval_ && restart == kRestartNever)
    return false;
  if (!interval_.IsResolved() || interval_.EndsBefore(presentation_time))
    return true;
  if (restart == kRestartAlways) {
    SMILTime next_begin = begin_times_.NextAfter(interval_.begin);
    if (interval_.EndsAfter(next_begin)) {
      SetNewIntervalEnd(next_begin);
      return interval_.EndsBefore(presentation_time);
    }
  }
  return false;
}

SMILTime SVGSMILElement::LastIntervalEndTime() const {
  // If we're still waiting for the first interval we lack a time reference.
  if (!is_waiting_for_first_interval_) {
    // If we have a current interval (which likely just ended or restarted) use
    // the end of that.
    if (interval_.IsResolved())
      return interval_.end;
    // If we don't have a current interval (maybe because it got discarded for
    // not having started yet) but we have a previous interval, then use the
    // end of that.
    if (previous_interval_.IsResolved())
      return previous_interval_.end;
  }
  // We have to start from the beginning.
  return SMILTime::Earliest();
}

void SVGSMILElement::UpdateInterval(SMILTime presentation_time) {
  if (instance_lists_have_changed_) {
    instance_lists_have_changed_ = false;
    DiscardOrRevalidateCurrentInterval(presentation_time);
  }
  if (!HandleIntervalRestart(presentation_time))
    return;
  SMILTime begin_after = LastIntervalEndTime();
  SMILInterval next_interval = ResolveInterval(begin_after, presentation_time);
  // It's the same interval that we resolved before. Do nothing.
  if (next_interval == interval_)
    return;
  interval_has_changed_ = true;
  if (interval_.IsResolved())
    previous_interval_ = interval_;
  // If there are no more intervals to resolve, we have to wait for an event to
  // occur in order to get a new instance time.
  if (!next_interval.IsResolved()) {
    interval_ = next_interval;
    return;
  }
  SetNewInterval(next_interval);
}

void SVGSMILElement::AddedToTimeContainer() {
  DCHECK(time_container_);
  SMILTime current_presentation_time =
      time_container_->LatestUpdatePresentationTime();
  UpdateInterval(current_presentation_time);
  // Check active state and reschedule using the time just before the current
  // presentation time. This means that the next animation update will take
  // care of updating the active state and send events as needed.
  SMILTime previous_presentation_time =
      current_presentation_time - SMILTime::Epsilon();
  active_state_ = DetermineActiveState(interval_, previous_presentation_time);
  time_container_->Reschedule(
      this,
      ComputeNextIntervalTime(previous_presentation_time, kIncludeRepeats));

  // If there's an active interval, then revalidate the animation value.
  if (GetActiveState() != kInactive)
    StartedActiveInterval();
}

void SVGSMILElement::RemovedFromTimeContainer() {
  DCHECK(time_container_);
  // If the element is active reset to a clear state.
  if (GetActiveState() != kInactive)
    EndedActiveInterval();
}

const SMILInterval& SVGSMILElement::GetActiveInterval(SMILTime elapsed) const {
  // If there's no current interval, return the previous interval.
  if (!interval_.IsResolved())
    return previous_interval_;
  // If there's a previous interval and the current interval hasn't begun yet,
  // return the previous interval.
  if (previous_interval_.IsResolved() && interval_.BeginsAfter(elapsed))
    return previous_interval_;
  return interval_;
}

SVGSMILElement::ProgressState SVGSMILElement::CalculateProgressState(
    SMILTime presentation_time) const {
  const SMILTime simple_duration = SimpleDuration();
  if (simple_duration.IsIndefinite())
    return {0.0f, 0};
  if (!simple_duration)
    return {1.0f, 0};
  DCHECK(simple_duration.IsFinite());
  const SMILInterval& active_interval = GetActiveInterval(presentation_time);
  DCHECK(active_interval.IsResolved());
  const SMILTime active_time = presentation_time - active_interval.begin;
  const SMILTime repeating_duration = RepeatingDuration();
  int64_t repeat;
  SMILTime simple_time;
  if (presentation_time >= active_interval.end ||
      active_time > repeating_duration) {
    // Use the interval to compute the interval position if we've passed the
    // interval end, otherwise use the "repeating duration". This prevents a
    // stale interval (with for instance an 'indefinite' end) from yielding an
    // invalid interval position.
    SMILTime last_active_duration =
        presentation_time >= active_interval.end
            ? active_interval.end - active_interval.begin
            : repeating_duration;
    if (!last_active_duration.IsFinite())
      return {0.0f, 0};
    // If the repeat duration is a multiple of the simple duration, we should
    // use a progress value of 1.0, otherwise we should return a value that is
    // within the interval (< 1.0), so subtract the smallest representable time
    // delta in that case.
    repeat = last_active_duration.IntDiv(simple_duration);
    simple_time = last_active_duration % simple_duration;
    if (simple_time) {
      simple_time = simple_time - SMILTime::Epsilon();
    } else {
      simple_time = simple_duration;
      --repeat;
    }
  } else {
    repeat = active_time.IntDiv(simple_duration);
    simple_time = active_time % simple_duration;
  }
  return {clampTo<float>(simple_time.InternalValueAsDouble() /
                         simple_duration.InternalValueAsDouble()),
          clampTo<unsigned>(repeat)};
}

SMILTime SVGSMILElement::NextProgressTime(SMILTime presentation_time) const {
  if (GetActiveState() == kActive) {
    // If duration is indefinite the value does not actually change over time.
    // Same is true for <set>.
    SMILTime simple_duration = SimpleDuration();
    if (simple_duration.IsIndefinite() || IsA<SVGSetElement>(*this)) {
      SMILTime repeating_duration_end = interval_.begin + RepeatingDuration();
      // We are supposed to do freeze semantics when repeating ends, even if the
      // element is still active.
      // Take care that we get a timer callback at that point.
      if (presentation_time < repeating_duration_end &&
          interval_.EndsAfter(repeating_duration_end) &&
          repeating_duration_end.IsFinite())
        return repeating_duration_end;
      return interval_.end;
    }
    return presentation_time;
  }
  return interval_.begin >= presentation_time ? interval_.begin
                                              : SMILTime::Unresolved();
}

SVGSMILElement::ActiveState SVGSMILElement::DetermineActiveState(
    const SMILInterval& interval,
    SMILTime elapsed) const {
  if (interval.Contains(elapsed))
    return kActive;
  if (is_waiting_for_first_interval_)
    return kInactive;
  return Fill() == kFillFreeze ? kFrozen : kInactive;
}

bool SVGSMILElement::IsContributing(SMILTime elapsed) const {
  // Animation does not contribute during the active time if it is past its
  // repeating duration and has fill=remove.
  return (GetActiveState() == kActive &&
          (Fill() == kFillFreeze ||
           elapsed <= interval_.begin + RepeatingDuration())) ||
         GetActiveState() == kFrozen;
}

SVGSMILElement::EventDispatchMask SVGSMILElement::UpdateActiveState(
    SMILTime presentation_time,
    bool skip_repeat) {
  const bool was_active = GetActiveState() == kActive;
  active_state_ = DetermineActiveState(interval_, presentation_time);
  const bool is_active = GetActiveState() == kActive;
  const bool interval_restart =
      interval_has_changed_ && previous_interval_.end == interval_.begin;
  interval_has_changed_ = false;

  unsigned events_to_dispatch = kDispatchNoEvent;
  if ((was_active && !is_active) || interval_restart) {
    events_to_dispatch |= kDispatchEndEvent;
    EndedActiveInterval();
  }

  if (IsContributing(presentation_time)) {
    if ((!was_active && is_active) || interval_restart) {
      events_to_dispatch |= kDispatchBeginEvent;
      StartedActiveInterval();
    }

    if (!skip_repeat) {
      // TODO(fs): This is a bit fragile. Convert to be time-based (rather than
      // based on |last_progress_|) and thus (at least more) idempotent.
      ProgressState progress_state = CalculateProgressState(presentation_time);
      if (progress_state.repeat &&
          progress_state.repeat != last_progress_.repeat) {
        NotifyDependentsOnRepeat(progress_state.repeat, presentation_time);
        events_to_dispatch |= kDispatchRepeatEvent;
      }
      last_progress_ = progress_state;
    }
  }
  return static_cast<EventDispatchMask>(events_to_dispatch);
}

SVGSMILElement::EventDispatchMask SVGSMILElement::ComputeSeekEvents(
    const SMILInterval& starting_interval) const {
  // Is the element active at the seeked-to time?
  if (GetActiveState() != SVGSMILElement::kActive) {
    // Was the element active at the previous time?
    if (!starting_interval.IsResolved())
      return kDispatchNoEvent;
    // Dispatch an 'endEvent' for ending |starting_interval|.
    return kDispatchEndEvent;
  }
  // Was the element active at the previous time?
  if (starting_interval.IsResolved()) {
    // The same interval?
    if (interval_ == starting_interval)
      return kDispatchNoEvent;
    // Dispatch an 'endEvent' for ending |starting_interval| and a 'beginEvent'
    // for beginning the current interval.
    unsigned to_dispatch = kDispatchBeginEvent | kDispatchEndEvent;
    return static_cast<EventDispatchMask>(to_dispatch);
  }
  // Was not active at the previous time. Dispatch a 'beginEvent' for beginning
  // the current interval.
  return kDispatchBeginEvent;
}

void SVGSMILElement::DispatchEvents(EventDispatchMask events_to_dispatch) {
  // The ordering is based on the usual order in which these events should be
  // dispatched (and should match the order the flags are set in
  // UpdateActiveState().
  if (events_to_dispatch & kDispatchEndEvent) {
    EnqueueEvent(*Event::Create(event_type_names::kEndEvent),
                 TaskType::kDOMManipulation);
  }
  if (events_to_dispatch & kDispatchBeginEvent) {
    EnqueueEvent(*Event::Create(event_type_names::kBeginEvent),
                 TaskType::kDOMManipulation);
  }
  if (events_to_dispatch & kDispatchRepeatEvent) {
    EnqueueEvent(*Event::Create(event_type_names::kRepeatEvent),
                 TaskType::kDOMManipulation);
    EnqueueEvent(*Event::Create(AtomicString("repeatn")),
                 TaskType::kDOMManipulation);
  }
}

void SVGSMILElement::AddedEventListener(
    const AtomicString& event_type,
    RegisteredEventListener& registered_listener) {
  SVGElement::AddedEventListener(event_type, registered_listener);
  if (event_type == "repeatn") {
    UseCounter::Count(GetDocument(),
                      WebFeature::kSMILElementHasRepeatNEventListener);
  }
}

void SVGSMILElement::UpdateProgressState(SMILTime presentation_time) {
  last_progress_ = CalculateProgressState(presentation_time);
}

struct SVGSMILElement::NotifyDependentsInfo {
  explicit NotifyDependentsInfo(const SMILInterval& interval)
      : origin(SMILTimeOrigin::kSyncBase),
        repeat_nr(0),
        begin(interval.begin),
        end(interval.end) {}
  NotifyDependentsInfo(unsigned repeat_nr, SMILTime repeat_time)
      : origin(SMILTimeOrigin::kRepeat),
        repeat_nr(repeat_nr),
        begin(repeat_time),
        end(SMILTime::Unresolved()) {}

  SMILTimeOrigin origin;
  unsigned repeat_nr;
  SMILTime begin;  // repeat time if origin == kRepeat
  SMILTime end;
};

void SVGSMILElement::NotifyDependentsOnNewInterval(
    const SMILInterval& interval) {
  DCHECK(interval.IsResolved());
  NotifyDependents(NotifyDependentsInfo(interval));
}

void SVGSMILElement::NotifyDependentsOnRepeat(unsigned repeat_nr,
                                              SMILTime repeat_time) {
  DCHECK(repeat_nr);
  DCHECK(repeat_time.IsFinite());
  NotifyDependents(NotifyDependentsInfo(repeat_nr, repeat_time));
}

void SVGSMILElement::NotifyDependents(const NotifyDependentsInfo& info) {
  // Avoid infinite recursion which may be caused by:
  // |NotifyDependents| -> |CreateInstanceTimesFromSyncBase| ->
  // |AddInstanceTime| -> |InstanceListChanged| -> |NotifyDependents|
  if (is_notifying_dependents_)
    return;
  base::AutoReset<bool> reentrancy_guard(&is_notifying_dependents_, true);
  for (SVGSMILElement* element : sync_base_dependents_)
    element->CreateInstanceTimesFromSyncBase(this, info);
}

void SVGSMILElement::CreateInstanceTimesFromSyncBase(
    SVGSMILElement* timed_element,
    const NotifyDependentsInfo& info) {
  // FIXME: To be really correct, this should handle updating exising interval
  // by changing the associated times instead of creating new ones.
  for (Condition* condition : conditions_) {
    if (!condition->IsSyncBaseFor(timed_element))
      continue;
    // TODO(edvardt): This is a lot of string compares, which is slow, it
    // might be a good idea to change it for an enum and maybe make Condition
    // into a union?
    DCHECK(condition->GetName() == "begin" || condition->GetName() == "end" ||
           condition->GetName() == "repeat");

    // No nested time containers in SVG, no need for crazy time space
    // conversions. Phew!
    SMILTime time = SMILTime::Unresolved();
    if (info.origin == SMILTimeOrigin::kSyncBase) {
      if (condition->GetName() == "begin") {
        time = info.begin + condition->Offset();
      } else if (condition->GetName() == "end") {
        time = info.end + condition->Offset();
      }
    } else {
      DCHECK_EQ(info.origin, SMILTimeOrigin::kRepeat);
      if (info.repeat_nr != condition->Repeat())
        continue;
      time = info.begin + condition->Offset();
    }
    if (!time.IsFinite())
      continue;
    AddInstanceTime(condition->GetBeginOrEnd(), time, info.origin);
  }

  // No instance times were added.
  if (!instance_lists_have_changed_)
    return;

  // We're currently sending notifications for, and thus updating, this element
  // so let that update handle the new instance times.
  if (is_notifying_dependents_)
    return;

  InstanceListChanged();
}

void SVGSMILElement::AddSyncBaseDependent(SVGSMILElement& animation) {
  sync_base_dependents_.insert(&animation);
  if (!interval_.IsResolved())
    return;
  animation.CreateInstanceTimesFromSyncBase(this,
                                            NotifyDependentsInfo(interval_));
}

void SVGSMILElement::RemoveSyncBaseDependent(SVGSMILElement& animation) {
  sync_base_dependents_.erase(&animation);
}

void SVGSMILElement::BeginByLinkActivation() {
  AddInstanceTimeAndUpdate(kBegin, Elapsed(), SMILTimeOrigin::kLinkActivation);
}

void SVGSMILElement::StartedActiveInterval() {
  is_waiting_for_first_interval_ = false;
}

void SVGSMILElement::EndedActiveInterval() {
  begin_times_.RemoveWithOrigin(SMILTimeOrigin::kScript);
  end_times_.RemoveWithOrigin(SMILTimeOrigin::kScript);
}

bool SVGSMILElement::HasValidTarget() const {
  return targetElement() && targetElement()->InActiveDocument();
}

void SVGSMILElement::WillChangeAnimationTarget() {
  if (!is_scheduled_)
    return;
  DCHECK(time_container_);
  DCHECK(target_element_);
  time_container_->Unschedule(this);
  RemovedFromTimeContainer();
  is_scheduled_ = false;
}

void SVGSMILElement::DidChangeAnimationTarget() {
  DCHECK(!is_scheduled_);
  if (!time_container_ || !HasValidTarget())
    return;
  time_container_->Schedule(this);
  AddedToTimeContainer();
  is_scheduled_ = true;
}

void SVGSMILElement::Trace(Visitor* visitor) const {
  visitor->Trace(target_element_);
  visitor->Trace(target_id_observer_);
  visitor->Trace(time_container_);
  visitor->Trace(conditions_);
  visitor->Trace(sync_base_dependents_);
  SVGElement::Trace(visitor);
  SVGTests::Trace(visitor);
}

}  // namespace blink
