diff options
Diffstat (limited to 'Source/WebCore/svg/animation/SVGSMILElement.cpp')
-rw-r--r-- | Source/WebCore/svg/animation/SVGSMILElement.cpp | 266 |
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 +} |