summaryrefslogtreecommitdiff
path: root/Source/WebCore/svg/animation/SVGSMILElement.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/svg/animation/SVGSMILElement.cpp')
-rw-r--r--Source/WebCore/svg/animation/SVGSMILElement.cpp266
1 files changed, 149 insertions, 117 deletions
diff --git a/Source/WebCore/svg/animation/SVGSMILElement.cpp b/Source/WebCore/svg/animation/SVGSMILElement.cpp
index a1df1f81e..2551af600 100644
--- a/Source/WebCore/svg/animation/SVGSMILElement.cpp
+++ b/Source/WebCore/svg/animation/SVGSMILElement.cpp
@@ -24,18 +24,16 @@
*/
#include "config.h"
-
-#if ENABLE(SVG)
#include "SVGSMILElement.h"
-#include "Attribute.h"
#include "CSSPropertyNames.h"
#include "Document.h"
#include "Event.h"
#include "EventListener.h"
+#include "EventNames.h"
+#include "EventSender.h"
#include "FloatConversion.h"
#include "FrameView.h"
-#include "HTMLNames.h"
#include "SMILTimeContainer.h"
#include "SVGDocumentExtensions.h"
#include "SVGNames.h"
@@ -48,29 +46,41 @@
#include <wtf/Vector.h>
namespace WebCore {
-
+
+static SMILEventSender& smilBeginEventSender()
+{
+ static NeverDestroyed<SMILEventSender> sender(eventNames().beginEventEvent);
+ return sender;
+}
+
+static SMILEventSender& smilEndEventSender()
+{
+ static NeverDestroyed<SMILEventSender> sender(eventNames().endEventEvent);
+ return sender;
+}
+
// This is used for duration type time values that can't be negative.
static const double invalidCachedTime = -1.;
-class ConditionEventListener : public EventListener {
+class ConditionEventListener final : public EventListener {
public:
- static PassRefPtr<ConditionEventListener> create(SVGSMILElement* animation, SVGSMILElement::Condition* condition)
+ static Ref<ConditionEventListener> create(SVGSMILElement* animation, SVGSMILElement::Condition* condition)
{
- return adoptRef(new ConditionEventListener(animation, condition));
+ return adoptRef(*new ConditionEventListener(animation, condition));
}
static const ConditionEventListener* cast(const EventListener* listener)
{
return listener->type() == ConditionEventListenerType
? static_cast<const ConditionEventListener*>(listener)
- : 0;
+ : nullptr;
}
- virtual bool operator==(const EventListener& other) override;
+ bool operator==(const EventListener& other) const final;
void disconnectAnimation()
{
- m_animation = 0;
+ m_animation = nullptr;
}
private:
@@ -81,13 +91,13 @@ private:
{
}
- virtual void handleEvent(ScriptExecutionContext*, Event*) override;
+ void handleEvent(ScriptExecutionContext*, Event*) final;
SVGSMILElement* m_animation;
SVGSMILElement::Condition* m_condition;
};
-bool ConditionEventListener::operator==(const EventListener& listener)
+bool ConditionEventListener::operator==(const EventListener& listener) const
{
if (const ConditionEventListener* conditionEventListener = ConditionEventListener::cast(&listener))
return m_animation == conditionEventListener->m_animation && m_condition == conditionEventListener->m_condition;
@@ -114,7 +124,7 @@ SVGSMILElement::Condition::Condition(Type type, BeginOrEnd beginOrEnd, const Str
SVGSMILElement::SVGSMILElement(const QualifiedName& tagName, Document& doc)
: SVGElement(tagName, doc)
, m_attributeName(anyQName())
- , m_targetElement(0)
+ , m_targetElement(nullptr)
, m_conditionsConnected(false)
, m_hasEndEventConditions(false)
, m_isWaitingForFirstInterval(true)
@@ -138,6 +148,8 @@ SVGSMILElement::SVGSMILElement(const QualifiedName& tagName, Document& doc)
SVGSMILElement::~SVGSMILElement()
{
clearResourceReferences();
+ smilBeginEventSender().cancelEvent(*this);
+ smilEndEventSender().cancelEvent(*this);
disconnectConditions();
if (m_timeContainer && m_targetElement && hasValidAttributeName())
m_timeContainer->unschedule(this, m_targetElement, m_attributeName);
@@ -145,16 +157,21 @@ SVGSMILElement::~SVGSMILElement()
void SVGSMILElement::clearResourceReferences()
{
- document().accessSVGExtensions()->removeAllTargetReferencesForElement(this);
+ document().accessSVGExtensions().removeAllTargetReferencesForElement(this);
+}
+
+void SVGSMILElement::clearTarget()
+{
+ setTargetElement(nullptr);
}
void SVGSMILElement::buildPendingResource()
{
clearResourceReferences();
- if (!inDocument()) {
+ if (!isConnected()) {
// Reset the target element if we are no longer in the document.
- setTargetElement(0);
+ setTargetElement(nullptr);
return;
}
@@ -162,59 +179,62 @@ void SVGSMILElement::buildPendingResource()
String href = getAttribute(XLinkNames::hrefAttr);
Element* target;
if (href.isEmpty())
- target = parentNode() && parentNode()->isElementNode() ? toElement(parentNode()) : 0;
+ target = is<Element>(parentNode()) ? downcast<Element>(parentNode()) : nullptr;
else
target = SVGURIReference::targetElementFromIRIString(href, document(), &id);
- SVGElement* svgTarget = target && target->isSVGElement() ? toSVGElement(target) : 0;
+ SVGElement* svgTarget = is<SVGElement>(target) ? downcast<SVGElement>(target) : nullptr;
- if (svgTarget && !svgTarget->inDocument())
- svgTarget = 0;
+ if (svgTarget && !svgTarget->isConnected())
+ svgTarget = nullptr;
if (svgTarget != targetElement())
setTargetElement(svgTarget);
if (!svgTarget) {
// Do not register as pending if we are already pending this resource.
- if (document().accessSVGExtensions()->isPendingResource(this, id))
+ if (document().accessSVGExtensions().isPendingResource(this, id))
return;
if (!id.isEmpty()) {
- document().accessSVGExtensions()->addPendingResource(id, this);
+ document().accessSVGExtensions().addPendingResource(id, this);
ASSERT(hasPendingResources());
}
} else {
// 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.
- document().accessSVGExtensions()->addElementReferencingTarget(this, svgTarget);
+ document().accessSVGExtensions().addElementReferencingTarget(this, svgTarget);
}
}
-static inline QualifiedName constructQualifiedName(const SVGElement* svgElement, const String& attributeName)
+inline QualifiedName SVGSMILElement::constructAttributeName() const
{
- ASSERT(svgElement);
- if (attributeName.isEmpty())
+ auto parseResult = Document::parseQualifiedName(attributeWithoutSynchronization(SVGNames::attributeNameAttr));
+ if (parseResult.hasException())
return anyQName();
- if (!attributeName.contains(':'))
- return QualifiedName(nullAtom, attributeName, nullAtom);
-
- String prefix;
- String localName;
- if (!Document::parseQualifiedName(attributeName, prefix, localName, ASSERT_NO_EXCEPTION))
- return anyQName();
-
- String namespaceURI = svgElement->lookupNamespaceURI(prefix);
+
+ AtomicString prefix, localName;
+ std::tie(prefix, localName) = parseResult.releaseReturnValue();
+
+ if (prefix.isNull())
+ return { nullAtom, localName, nullAtom };
+
+ auto namespaceURI = lookupNamespaceURI(prefix);
if (namespaceURI.isEmpty())
return anyQName();
-
- return QualifiedName(nullAtom, localName, namespaceURI);
+
+ return { nullAtom, localName, namespaceURI };
+}
+
+inline void SVGSMILElement::updateAttributeName()
+{
+ setAttributeName(constructAttributeName());
}
static inline void clearTimesWithDynamicOrigins(Vector<SMILTimeWithOrigin>& timeList)
{
- for (int i = timeList.size() - 1; i >= 0; --i) {
- if (timeList[i].originIsScript())
- timeList.remove(i);
- }
+ timeList.removeAllMatching([] (const SMILTimeWithOrigin& time) {
+ return time.originIsScript();
+ });
}
void SVGSMILElement::reset()
@@ -235,23 +255,23 @@ void SVGSMILElement::reset()
Node::InsertionNotificationRequest SVGSMILElement::insertedInto(ContainerNode& rootParent)
{
SVGElement::insertedInto(rootParent);
- if (!rootParent.inDocument())
+ if (!rootParent.isConnected())
return InsertionDone;
// Verify we are not in <use> instance tree.
ASSERT(!isInShadowTree());
- setAttributeName(constructQualifiedName(this, fastGetAttribute(SVGNames::attributeNameAttr)));
+ updateAttributeName();
+
SVGSVGElement* owner = ownerSVGElement();
if (!owner)
return InsertionDone;
- m_timeContainer = owner->timeContainer();
- ASSERT(m_timeContainer);
+ m_timeContainer = &owner->timeContainer();
m_timeContainer->setDocumentOrderIndexesDirty();
// "If no attribute is present, the default begin value (an offset-value of 0) must be evaluated."
- if (!fastHasAttribute(SVGNames::beginAttr))
+ if (!hasAttributeWithoutSynchronization(SVGNames::beginAttr))
m_beginTimes.append(SMILTimeWithOrigin());
if (m_isWaitingForFirstInterval)
@@ -260,20 +280,23 @@ Node::InsertionNotificationRequest SVGSMILElement::insertedInto(ContainerNode& r
if (m_timeContainer)
m_timeContainer->notifyIntervalsChanged();
- buildPendingResource();
+ return InsertionShouldCallFinishedInsertingSubtree;
+}
- return InsertionDone;
+void SVGSMILElement::finishedInsertingSubtree()
+{
+ buildPendingResource();
}
void SVGSMILElement::removedFrom(ContainerNode& rootParent)
{
- if (rootParent.inDocument()) {
+ if (rootParent.isConnected()) {
clearResourceReferences();
disconnectConditions();
- setTargetElement(0);
+ setTargetElement(nullptr);
setAttributeName(anyQName());
animationAttributeChanged();
- m_timeContainer = 0;
+ m_timeContainer = nullptr;
}
SVGElement::removedFrom(rootParent);
@@ -299,7 +322,7 @@ SMILTime SVGSMILElement::parseOffsetValue(const String& data)
result = parse.left(parse.length() - 1).toDouble(&ok);
else
result = parse.toDouble(&ok);
- if (!ok)
+ if (!ok || !SMILTime(result).isFinite())
return SMILTime::unresolved();
return result;
}
@@ -311,7 +334,7 @@ SMILTime SVGSMILElement::parseClockValue(const String& data)
String parse = data.stripWhiteSpace();
- DEFINE_STATIC_LOCAL(const AtomicString, indefiniteValue, ("indefinite", AtomicString::ConstructFromLiteral));
+ static NeverDestroyed<const AtomicString> indefiniteValue("indefinite", AtomicString::ConstructFromLiteral);
if (parse == indefiniteValue)
return SMILTime::indefinite();
@@ -335,7 +358,7 @@ SMILTime SVGSMILElement::parseClockValue(const String& data)
} else
return parseOffsetValue(parse);
- if (!ok)
+ if (!ok || !SMILTime(result).isFinite())
return SMILTime::unresolved();
return result;
}
@@ -418,14 +441,14 @@ void SVGSMILElement::parseBeginOrEnd(const String& parseString, BeginOrEnd begin
if (beginOrEnd == End)
m_hasEndEventConditions = false;
HashSet<double> existing;
- for (unsigned n = 0; n < timeList.size(); ++n)
- existing.add(timeList[n].time().value());
+ for (auto& time : timeList)
+ existing.add(time.time().value());
Vector<String> splitString;
parseString.split(';', splitString);
- for (unsigned n = 0; n < splitString.size(); ++n) {
- SMILTime value = parseClockValue(splitString[n]);
+ for (auto& string : splitString) {
+ SMILTime value = parseClockValue(string);
if (value.isUnresolved())
- parseCondition(splitString[n], beginOrEnd);
+ parseCondition(string, beginOrEnd);
else if (!existing.contains(value.value()))
timeList.append(SMILTimeWithOrigin(value, SMILTimeWithOrigin::ParserOrigin));
}
@@ -434,19 +457,19 @@ void SVGSMILElement::parseBeginOrEnd(const String& parseString, BeginOrEnd begin
bool SVGSMILElement::isSupportedAttribute(const QualifiedName& attrName)
{
- DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
- if (supportedAttributes.isEmpty()) {
- supportedAttributes.add(SVGNames::beginAttr);
- supportedAttributes.add(SVGNames::endAttr);
- supportedAttributes.add(SVGNames::durAttr);
- supportedAttributes.add(SVGNames::repeatDurAttr);
- supportedAttributes.add(SVGNames::repeatCountAttr);
- supportedAttributes.add(SVGNames::minAttr);
- supportedAttributes.add(SVGNames::maxAttr);
- supportedAttributes.add(SVGNames::attributeNameAttr);
- supportedAttributes.add(XLinkNames::hrefAttr);
+ static NeverDestroyed<HashSet<QualifiedName>> supportedAttributes;
+ if (supportedAttributes.get().isEmpty()) {
+ supportedAttributes.get().add(SVGNames::beginAttr);
+ supportedAttributes.get().add(SVGNames::endAttr);
+ supportedAttributes.get().add(SVGNames::durAttr);
+ supportedAttributes.get().add(SVGNames::repeatDurAttr);
+ supportedAttributes.get().add(SVGNames::repeatCountAttr);
+ supportedAttributes.get().add(SVGNames::minAttr);
+ supportedAttributes.get().add(SVGNames::maxAttr);
+ supportedAttributes.get().add(SVGNames::attributeNameAttr);
+ supportedAttributes.get().add(XLinkNames::hrefAttr);
}
- return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName);
+ return supportedAttributes.get().contains<SVGAttributeHashTranslator>(attrName);
}
void SVGSMILElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
@@ -455,21 +478,25 @@ void SVGSMILElement::parseAttribute(const QualifiedName& name, const AtomicStrin
if (!m_conditions.isEmpty()) {
disconnectConditions();
m_conditions.clear();
- parseBeginOrEnd(fastGetAttribute(SVGNames::endAttr), End);
+ parseBeginOrEnd(attributeWithoutSynchronization(SVGNames::endAttr), End);
}
parseBeginOrEnd(value.string(), Begin);
- if (inDocument())
+ if (isConnected())
connectConditions();
} else if (name == SVGNames::endAttr) {
if (!m_conditions.isEmpty()) {
disconnectConditions();
m_conditions.clear();
- parseBeginOrEnd(fastGetAttribute(SVGNames::beginAttr), Begin);
+ parseBeginOrEnd(attributeWithoutSynchronization(SVGNames::beginAttr), Begin);
}
parseBeginOrEnd(value.string(), End);
- if (inDocument())
+ if (isConnected())
connectConditions();
- } else
+ } else if (name == SVGNames::onendAttr)
+ setAttributeEventListener(eventNames().endEventEvent, name, value);
+ else if (name == SVGNames::onbeginAttr)
+ setAttributeEventListener(eventNames().beginEventEvent, name, value);
+ else
SVGElement::parseAttribute(name, value);
}
@@ -491,11 +518,11 @@ void SVGSMILElement::svgAttributeChanged(const QualifiedName& attrName)
else if (attrName == SVGNames::maxAttr)
m_cachedMax = invalidCachedTime;
else if (attrName == SVGNames::attributeNameAttr)
- setAttributeName(constructQualifiedName(this, fastGetAttribute(SVGNames::attributeNameAttr)));
+ updateAttributeName();
else if (attrName.matches(XLinkNames::hrefAttr)) {
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
buildPendingResource();
- } else if (inDocument()) {
+ } else if (isConnected()) {
if (attrName == SVGNames::beginAttr)
beginListChanged(elapsed());
else if (attrName == SVGNames::endAttr)
@@ -515,8 +542,7 @@ void SVGSMILElement::connectConditions()
if (m_conditionsConnected)
disconnectConditions();
m_conditionsConnected = true;
- for (unsigned n = 0; n < m_conditions.size(); ++n) {
- Condition& condition = m_conditions[n];
+ for (auto& condition : m_conditions) {
if (condition.m_type == Condition::EventBase) {
ASSERT(!condition.m_syncbase);
Element* eventBase = eventBaseFor(condition);
@@ -524,17 +550,17 @@ void SVGSMILElement::connectConditions()
continue;
ASSERT(!condition.m_eventListener);
condition.m_eventListener = ConditionEventListener::create(this, &condition);
- eventBase->addEventListener(condition.m_name, condition.m_eventListener, false);
+ eventBase->addEventListener(condition.m_name, *condition.m_eventListener, false);
} else if (condition.m_type == Condition::Syncbase) {
ASSERT(!condition.m_baseID.isEmpty());
condition.m_syncbase = treeScope().getElementById(condition.m_baseID);
if (!condition.m_syncbase)
continue;
- if (!isSVGSMILElement(*condition.m_syncbase)) {
+ if (!is<SVGSMILElement>(*condition.m_syncbase)) {
condition.m_syncbase = nullptr;
continue;
}
- toSVGSMILElement(*condition.m_syncbase).addTimeDependent(this);
+ downcast<SVGSMILElement>(*condition.m_syncbase).addTimeDependent(this);
}
}
}
@@ -544,8 +570,7 @@ void SVGSMILElement::disconnectConditions()
if (!m_conditionsConnected)
return;
m_conditionsConnected = false;
- for (unsigned n = 0; n < m_conditions.size(); ++n) {
- Condition& condition = m_conditions[n];
+ for (auto& condition : m_conditions) {
if (condition.m_type == Condition::EventBase) {
ASSERT(!condition.m_syncbase);
if (!condition.m_eventListener)
@@ -557,14 +582,14 @@ void SVGSMILElement::disconnectConditions()
// our condition event listener, in case it later fires.
Element* eventBase = eventBaseFor(condition);
if (eventBase)
- eventBase->removeEventListener(condition.m_name, condition.m_eventListener.get(), false);
+ eventBase->removeEventListener(condition.m_name, *condition.m_eventListener, false);
condition.m_eventListener->disconnectAnimation();
- condition.m_eventListener = 0;
+ condition.m_eventListener = nullptr;
} else if (condition.m_type == Condition::Syncbase) {
if (condition.m_syncbase)
- toSVGSMILElement(condition.m_syncbase.get())->removeTimeDependent(this);
+ downcast<SVGSMILElement>(condition.m_syncbase.get())->removeTimeDependent(this);
}
- condition.m_syncbase = 0;
+ condition.m_syncbase = nullptr;
}
}
@@ -623,9 +648,9 @@ bool SVGSMILElement::isFrozen() const
SVGSMILElement::Restart SVGSMILElement::restart() const
{
- DEFINE_STATIC_LOCAL(const AtomicString, never, ("never", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(const AtomicString, whenNotActive, ("whenNotActive", AtomicString::ConstructFromLiteral));
- const AtomicString& value = fastGetAttribute(SVGNames::restartAttr);
+ static NeverDestroyed<const AtomicString> never("never", AtomicString::ConstructFromLiteral);
+ static NeverDestroyed<const AtomicString> whenNotActive("whenNotActive", AtomicString::ConstructFromLiteral);
+ const AtomicString& value = attributeWithoutSynchronization(SVGNames::restartAttr);
if (value == never)
return RestartNever;
if (value == whenNotActive)
@@ -635,8 +660,8 @@ SVGSMILElement::Restart SVGSMILElement::restart() const
SVGSMILElement::FillMode SVGSMILElement::fill() const
{
- DEFINE_STATIC_LOCAL(const AtomicString, freeze, ("freeze", AtomicString::ConstructFromLiteral));
- const AtomicString& value = fastGetAttribute(SVGNames::fillAttr);
+ static NeverDestroyed<const AtomicString> freeze("freeze", AtomicString::ConstructFromLiteral);
+ const AtomicString& value = attributeWithoutSynchronization(SVGNames::fillAttr);
return value == freeze ? FillFreeze : FillRemove;
}
@@ -644,7 +669,7 @@ SMILTime SVGSMILElement::dur() const
{
if (m_cachedDur != invalidCachedTime)
return m_cachedDur;
- const AtomicString& value = fastGetAttribute(SVGNames::durAttr);
+ const AtomicString& value = attributeWithoutSynchronization(SVGNames::durAttr);
SMILTime clockValue = parseClockValue(value);
return m_cachedDur = clockValue <= 0 ? SMILTime::unresolved() : clockValue;
}
@@ -653,7 +678,7 @@ SMILTime SVGSMILElement::repeatDur() const
{
if (m_cachedRepeatDur != invalidCachedTime)
return m_cachedRepeatDur;
- const AtomicString& value = fastGetAttribute(SVGNames::repeatDurAttr);
+ const AtomicString& value = attributeWithoutSynchronization(SVGNames::repeatDurAttr);
SMILTime clockValue = parseClockValue(value);
m_cachedRepeatDur = clockValue <= 0 ? SMILTime::unresolved() : clockValue;
return m_cachedRepeatDur;
@@ -664,11 +689,11 @@ SMILTime SVGSMILElement::repeatCount() const
{
if (m_cachedRepeatCount != invalidCachedTime)
return m_cachedRepeatCount;
- const AtomicString& value = fastGetAttribute(SVGNames::repeatCountAttr);
+ const AtomicString& value = attributeWithoutSynchronization(SVGNames::repeatCountAttr);
if (value.isNull())
return SMILTime::unresolved();
- DEFINE_STATIC_LOCAL(const AtomicString, indefiniteValue, ("indefinite", AtomicString::ConstructFromLiteral));
+ static NeverDestroyed<const AtomicString> indefiniteValue("indefinite", AtomicString::ConstructFromLiteral);
if (value == indefiniteValue)
return SMILTime::indefinite();
bool ok;
@@ -680,16 +705,16 @@ SMILTime SVGSMILElement::maxValue() const
{
if (m_cachedMax != invalidCachedTime)
return m_cachedMax;
- const AtomicString& value = fastGetAttribute(SVGNames::maxAttr);
+ const AtomicString& value = attributeWithoutSynchronization(SVGNames::maxAttr);
SMILTime result = parseClockValue(value);
- return m_cachedMax = (result.isUnresolved() || result < 0) ? SMILTime::indefinite() : result;
+ return m_cachedMax = (result.isUnresolved() || result <= 0) ? SMILTime::indefinite() : result;
}
SMILTime SVGSMILElement::minValue() const
{
if (m_cachedMin != invalidCachedTime)
return m_cachedMin;
- const AtomicString& value = fastGetAttribute(SVGNames::minAttr);
+ const AtomicString& value = attributeWithoutSynchronization(SVGNames::minAttr);
SMILTime result = parseClockValue(value);
return m_cachedMin = (result.isUnresolved() || result < 0) ? 0 : result;
}
@@ -1022,7 +1047,7 @@ SMILTime SVGSMILElement::calculateNextProgressTime(SMILTime elapsed) const
return repeatingDurationEnd;
return m_intervalEnd;
}
- return elapsed + 0.025;
+ return elapsed + SMILAnimationFrameDelay;
}
return m_intervalBegin >= elapsed ? m_intervalBegin : SMILTime::unresolved();
}
@@ -1047,9 +1072,6 @@ bool SVGSMILElement::progress(SMILTime elapsed, SVGSMILElement* resultElement, b
ASSERT(m_timeContainer);
ASSERT(m_isWaitingForFirstInterval || m_intervalBegin.isFinite());
- if (!m_conditionsConnected)
- connectConditions();
-
if (!m_intervalBegin.isFinite()) {
ASSERT(m_activeState == Inactive);
m_nextProgressTime = SMILTime::unresolved();
@@ -1106,9 +1128,17 @@ bool SVGSMILElement::progress(SMILTime elapsed, SVGSMILElement* resultElement, b
}
if (oldActiveState == Active && m_activeState != Active) {
+ smilEndEventSender().dispatchEventSoon(*this);
endedActiveInterval();
if (m_activeState != Frozen)
clearAnimatedType(m_targetElement);
+ } else if (oldActiveState != Active && m_activeState == Active)
+ smilBeginEventSender().dispatchEventSoon(*this);
+
+ // Triggering all the pending events if the animation timeline is changed.
+ if (seekToTime) {
+ if (m_activeState == Inactive || m_activeState == Frozen)
+ smilEndEventSender().dispatchEventSoon(*this);
}
m_nextProgressTime = calculateNextProgressTime(elapsed);
@@ -1118,26 +1148,23 @@ bool SVGSMILElement::progress(SMILTime elapsed, SVGSMILElement* resultElement, b
void SVGSMILElement::notifyDependentsIntervalChanged(NewOrExistingInterval newOrExisting)
{
ASSERT(m_intervalBegin.isFinite());
- DEFINE_STATIC_LOCAL(HashSet<SVGSMILElement*>, loopBreaker, ());
- if (loopBreaker.contains(this))
+ static NeverDestroyed<HashSet<SVGSMILElement*>> loopBreaker;
+ if (loopBreaker.get().contains(this))
return;
- loopBreaker.add(this);
+ loopBreaker.get().add(this);
- TimeDependentSet::iterator end = m_timeDependents.end();
- for (TimeDependentSet::iterator it = m_timeDependents.begin(); it != end; ++it) {
- SVGSMILElement* dependent = *it;
+ for (auto& dependent : m_timeDependents) {
dependent->createInstanceTimesFromSyncbase(this, newOrExisting);
}
- loopBreaker.remove(this);
+ loopBreaker.get().remove(this);
}
void SVGSMILElement::createInstanceTimesFromSyncbase(SVGSMILElement* syncbase, NewOrExistingInterval)
{
// FIXME: To be really correct, this should handle updating exising interval by changing
// the associated times instead of creating new ones.
- for (unsigned n = 0; n < m_conditions.size(); ++n) {
- Condition& condition = m_conditions[n];
+ for (auto& condition : m_conditions) {
if (condition.m_type == Condition::Syncbase && condition.m_syncbase == syncbase) {
ASSERT(condition.m_name == "begin" || condition.m_name == "end");
// No nested time containers in SVG, no need for crazy time space conversions. Phew!
@@ -1189,6 +1216,11 @@ void SVGSMILElement::endedActiveInterval()
clearTimesWithDynamicOrigins(m_endTimes);
}
+void SVGSMILElement::dispatchPendingEvent(SMILEventSender* eventSender)
+{
+ ASSERT(eventSender == &smilBeginEventSender() || eventSender == &smilEndEventSender());
+ const AtomicString& eventType = eventSender->eventType();
+ dispatchEvent(Event::create(eventType, false, false));
}
-#endif
+}