WebKit Bugzilla
Attachment 356879 Details for
Bug 191237
: Remove SVG properties tear-off objects
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
19-SVGAnimateElement
19-SVGAnimateElement.patch (text/plain), 57.92 KB, created by
Said Abou-Hallawa
on 2018-12-08 11:33:05 PST
(
hide
)
Description:
19-SVGAnimateElement
Filename:
MIME Type:
Creator:
Said Abou-Hallawa
Created:
2018-12-08 11:33:05 PST
Size:
57.92 KB
patch
obsolete
>diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 9f86b3e33ff..a8353320b3a 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,110 @@ >+2018-12-07 Said Abou-Hallawa <sabouhallawa@apple.com> >+ >+ Remove SVG properties tear-off objects >+ https://bugs.webkit.org/show_bug.cgi?id=191237 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ This patch changes the SMIL animation classes to adopt the new way of >+ creating and managing the animation. Here are the details: >+ >+ -- SVGAnimateColorElement does not need to count for "currentColor". This >+ logic was moved to SVGAnimationColorFunction. >+ >+ -- SVGAnimateElementBase does not need to determine the type of the >+ animation from the attributeName. This is now decided by >+ SVGElement::createAnimator(). >+ >+ -- SVGAnimateElementBase does not need to apply the animation to the target >+ SVGElement. This is now done by the SVGAnimator::apply(). >+ >+ -- SVGAnimateElementBase does not have to worry about multiple <animate> >+ elements are animating the same property. This is now achieved storing >+ the SVGAnimatedProperty in SVGElement as a RefCounted object. So >+ calculateAnimatedValue() does not use resultElement. >+ >+ * svg/SVGAnimateColorElement.cpp: >+ (WebCore::attributeValueIsCurrentColor): Deleted. >+ (WebCore::SVGAnimateColorElement::determinePropertyValueTypes): Deleted. >+ * svg/SVGAnimateColorElement.h: >+ * svg/SVGAnimateElementBase.cpp: >+ (WebCore::SVGAnimateElementBase::SVGAnimateElementBase): >+ (WebCore::SVGAnimateElementBase::setTargetElement): >+ (WebCore::SVGAnimateElementBase::setAttributeName): >+ (WebCore::SVGAnimateElementBase::createAnimator const): >+ (WebCore::SVGAnimateElementBase::resetAnimation): >+ (WebCore::SVGAnimateElementBase::hasValidAttributeType const): >+ (WebCore::SVGAnimateElementBase::isDiscreteAnimator const): >+ (WebCore::SVGAnimateElementBase::calculateFromAndToValues): >+ (WebCore::SVGAnimateElementBase::calculateFromAndByValues): >+ (WebCore::SVGAnimateElementBase::calculateToAtEndOfDurationValue): >+ (WebCore::SVGAnimateElementBase::resetAnimatedType): >+ (WebCore::SVGAnimateElementBase::calculateAnimatedValue): >+ (WebCore::SVGAnimateElementBase::applyResultsToTarget): >+ (WebCore::SVGAnimateElementBase::clearAnimatedType): >+ (WebCore::SVGAnimateElementBase::isTargetAttributeCSSProperty): >+ (WebCore::SVGAnimateElementBase::hasInvalidCSSAttributeType const): >+ (WebCore::SVGAnimateElementBase::calculateDistance): >+ (WebCore::SVGAnimateElementBase::hasValidAttributeType): Deleted. >+ (WebCore::SVGAnimateElementBase::determineAnimatedPropertyType const): Deleted. >+ (WebCore::propertyTypesAreConsistent): Deleted. >+ (WebCore::applyCSSPropertyToTarget): Deleted. >+ (WebCore::removeCSSPropertyFromTarget): Deleted. >+ (WebCore::applyCSSPropertyToTargetAndInstances): Deleted. >+ (WebCore::removeCSSPropertyFromTargetAndInstances): Deleted. >+ (WebCore::notifyTargetAboutAnimValChange): Deleted. >+ (WebCore::notifyTargetAndInstancesAboutAnimValChange): Deleted. >+ (WebCore::SVGAnimateElementBase::animatedPropertyTypeSupportsAddition const): Deleted. >+ (WebCore::SVGAnimateElementBase::isAdditive const): Deleted. >+ (WebCore::SVGAnimateElementBase::resetAnimatedPropertyType): Deleted. >+ (WebCore::SVGAnimateElementBase::ensureAnimator): Deleted. >+ * svg/SVGAnimateElementBase.h: >+ (WebCore::SVGAnimateElementBase::animateRangeString const): >+ * svg/SVGAnimateMotionElement.cpp: >+ (WebCore::SVGAnimateMotionElement::hasValidAttributeType const): >+ (WebCore::SVGAnimateMotionElement::hasValidAttributeName const): >+ (WebCore::SVGAnimateMotionElement::calculateFromAndByValues): >+ (WebCore::SVGAnimateMotionElement::calculateAnimatedValue): >+ (WebCore::SVGAnimateMotionElement::updateAnimationMode): >+ (WebCore::SVGAnimateMotionElement::hasValidAttributeType): Deleted. >+ (WebCore::SVGAnimateMotionElement::hasValidAttributeName): Deleted. >+ * svg/SVGAnimateMotionElement.h: >+ * svg/SVGAnimateTransformElement.cpp: >+ (WebCore::SVGAnimateTransformElement::hasValidAttributeType const): >+ (WebCore::SVGAnimateTransformElement::animateRangeString const): >+ (WebCore::SVGAnimateTransformElement::hasValidAttributeType): Deleted. >+ * svg/SVGAnimateTransformElement.h: >+ * svg/SVGAnimationElement.cpp: >+ (WebCore::SVGAnimationElement::updateAnimationMode): >+ (WebCore::SVGAnimationElement::setAttributeType): >+ (WebCore::SVGAnimationElement::isAdditive const): >+ (WebCore::SVGAnimationElement::isAccumulated const): >+ (WebCore::SVGAnimationElement::calculateKeyTimesForCalcModePaced): >+ (WebCore::SVGAnimationElement::currentValuesForValuesAnimation): >+ (WebCore::SVGAnimationElement::startedActiveInterval): >+ (WebCore::SVGAnimationElement::updateAnimation): >+ (WebCore::inheritsFromProperty): >+ (WebCore::SVGAnimationElement::resetAnimation): >+ (WebCore::SVGAnimationElement::isTargetAttributeCSSProperty): Deleted. >+ (WebCore::SVGAnimationElement::shouldApplyAnimation): Deleted. >+ (WebCore::SVGAnimationElement::computeCSSPropertyValue): Deleted. >+ (WebCore::SVGAnimationElement::adjustForInheritance): Deleted. >+ (WebCore::SVGAnimationElement::resetAnimatedPropertyType): Deleted. >+ (WebCore::SVGAnimationElement::setTargetElement): Deleted. >+ (WebCore::SVGAnimationElement::checkInvalidCSSAttributeType): Deleted. >+ * svg/SVGAnimationElement.h: >+ (WebCore::SVGAnimationElement::animateAdditiveNumber): >+ (WebCore::SVGAnimationElement::adjustForInheritance): Deleted. >+ (WebCore::SVGAnimationElement::adjustFromToListValues): Deleted. >+ (WebCore::SVGAnimationElement::animateDiscreteType): Deleted. >+ (WebCore::SVGAnimationElement::attributeRegistry): Deleted. >+ (WebCore::SVGAnimationElement::hasInvalidCSSAttributeType const): Deleted. >+ * svg/SVGMPathElement.cpp: >+ (WebCore::SVGMPathElement::buildPendingResource): >+ (WebCore::SVGMPathElement::pathElement const): >+ (WebCore::SVGMPathElement::pathElement): Deleted. >+ * svg/SVGMPathElement.h: >+ > 2018-12-07 Said Abou-Hallawa <sabouhallawa@apple.com> > > Remove SVG properties tear-off objects >diff --git a/Source/WebCore/svg/SVGAnimateColorElement.cpp b/Source/WebCore/svg/SVGAnimateColorElement.cpp >index 0b82c1ab9c0..4bbb140eac5 100644 >--- a/Source/WebCore/svg/SVGAnimateColorElement.cpp >+++ b/Source/WebCore/svg/SVGAnimateColorElement.cpp >@@ -2,6 +2,7 @@ > * Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org> > * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org> > * Copyright (C) 2007 Eric Seidel <eric@webkit.org> >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * This library is free software; you can redistribute it and/or > * modify it under the terms of the GNU Library General Public >@@ -40,19 +41,4 @@ Ref<SVGAnimateColorElement> SVGAnimateColorElement::create(const QualifiedName& > return adoptRef(*new SVGAnimateColorElement(tagName, document)); > } > >-static bool attributeValueIsCurrentColor(const String& value) >-{ >- static NeverDestroyed<const AtomicString> currentColor("currentColor", AtomicString::ConstructFromLiteral); >- return value == currentColor; >-} >- >-void SVGAnimateColorElement::determinePropertyValueTypes(const String& from, const String& to) >-{ >- SVGAnimateElementBase::determinePropertyValueTypes(from, to); >- if (attributeValueIsCurrentColor(from)) >- m_fromPropertyValueType = CurrentColorValue; >- if (attributeValueIsCurrentColor(to)) >- m_toPropertyValueType = CurrentColorValue; >-} >- > } >diff --git a/Source/WebCore/svg/SVGAnimateColorElement.h b/Source/WebCore/svg/SVGAnimateColorElement.h >index 87ba96c84b3..e38aa743f2d 100644 >--- a/Source/WebCore/svg/SVGAnimateColorElement.h >+++ b/Source/WebCore/svg/SVGAnimateColorElement.h >@@ -32,7 +32,6 @@ public: > > private: > SVGAnimateColorElement(const QualifiedName&, Document&); >- void determinePropertyValueTypes(const String& from, const String& to) override; > }; > > } // namespace WebCore >diff --git a/Source/WebCore/svg/SVGAnimateElementBase.cpp b/Source/WebCore/svg/SVGAnimateElementBase.cpp >index 2a7e079755f..820d70a3544 100644 >--- a/Source/WebCore/svg/SVGAnimateElementBase.cpp >+++ b/Source/WebCore/svg/SVGAnimateElementBase.cpp >@@ -1,9 +1,9 @@ > /* > * Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org> > * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org> >- * Copyright (C) 2008 Apple Inc. All rights reserved. > * Copyright (C) Research In Motion Limited 2011. All rights reserved. > * Copyright (C) 2014 Adobe Systems Incorporated. All rights reserved. >+ * Copyright (C) 2008-2018 Apple Inc. All rights reserved. > * > * This library is free software; you can redistribute it and/or > * modify it under the terms of the GNU Library General Public >@@ -24,13 +24,10 @@ > #include "config.h" > #include "SVGAnimateElementBase.h" > >-#include "CSSPropertyNames.h" >-#include "CSSPropertyParser.h" > #include "QualifiedName.h" >-#include "RenderObject.h" >-#include "SVGAnimatorFactory.h" >+#include "SVGAnimator.h" > #include "SVGElement.h" >-#include "SVGNames.h" >+#include "SVGPropertyAnimatorCreator.h" > #include "StyleProperties.h" > #include <wtf/IsoMallocInlines.h> > >@@ -40,413 +37,154 @@ WTF_MAKE_ISO_ALLOCATED_IMPL(SVGAnimateElementBase); > > SVGAnimateElementBase::SVGAnimateElementBase(const QualifiedName& tagName, Document& document) > : SVGAnimationElement(tagName, document) >- , m_animatedPropertyType(AnimatedString) > { > ASSERT(hasTagName(SVGNames::animateTag) || hasTagName(SVGNames::setTag) || hasTagName(SVGNames::animateColorTag) || hasTagName(SVGNames::animateTransformTag)); > } > >-SVGAnimateElementBase::~SVGAnimateElementBase() = default; >- >-bool SVGAnimateElementBase::hasValidAttributeType() >+void SVGAnimateElementBase::setTargetElement(SVGElement* target) > { >- if (!this->targetElement()) >- return false; >- >- return m_animatedPropertyType != AnimatedUnknown && !hasInvalidCSSAttributeType(); >+ SVGAnimationElement::setTargetElement(target); >+ resetAnimation(); > } > >-AnimatedPropertyType SVGAnimateElementBase::determineAnimatedPropertyType(SVGElement& targetElement) const >+void SVGAnimateElementBase::setAttributeName(const QualifiedName& attributeName) > { >- auto propertyTypes = targetElement.animatedPropertyTypesForAttribute(attributeName()); >- if (propertyTypes.isEmpty()) >- return AnimatedUnknown; >- >- ASSERT(propertyTypes.size() <= 2); >- AnimatedPropertyType type = propertyTypes[0]; >- if (hasTagName(SVGNames::animateColorTag) && type != AnimatedColor) >- return AnimatedUnknown; >- >- // Animations of transform lists are not allowed for <animate> or <set> >- // http://www.w3.org/TR/SVG/animate.html#AnimationAttributesAndProperties >- if (type == AnimatedTransformList && !hasTagName(SVGNames::animateTransformTag)) >- return AnimatedUnknown; >- >- // Fortunately there's just one special case needed here: SVGMarkerElements orientAttr, which >- // corresponds to SVGAnimatedAngle orientAngle and SVGAnimatedEnumeration orientType. We have to >- // figure out whose value to change here. >- if (targetElement.hasTagName(SVGNames::markerTag) && type == AnimatedAngle) { >- ASSERT(propertyTypes.size() == 2); >- ASSERT(propertyTypes[0] == AnimatedAngle); >- ASSERT(propertyTypes[1] == AnimatedEnumeration); >- } else if (propertyTypes.size() == 2) >- ASSERT(propertyTypes[0] == propertyTypes[1]); >- >- return type; >+ SVGSMILElement::setAttributeName(attributeName); >+ resetAnimation(); > } > >-void SVGAnimateElementBase::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGSMILElement* resultElement) >+RefPtr<SVGAnimator> SVGAnimateElementBase::createAnimator() const > { >- ASSERT(resultElement); >- auto targetElement = makeRefPtr(this->targetElement()); >- if (!targetElement) >- return; >- >- ASSERT(m_animatedPropertyType == determineAnimatedPropertyType(*targetElement)); >- >- ASSERT(percentage >= 0 && percentage <= 1); >- ASSERT(m_animatedPropertyType != AnimatedTransformList || hasTagName(SVGNames::animateTransformTag)); >- ASSERT(m_animatedPropertyType != AnimatedUnknown); >- ASSERT(m_animator); >- ASSERT(m_animator->type() == m_animatedPropertyType); >- ASSERT(m_fromType); >- ASSERT(m_fromType->type() == m_animatedPropertyType); >- ASSERT(m_toType); >- >- SVGAnimateElementBase& resultAnimationElement = downcast<SVGAnimateElementBase>(*resultElement); >- ASSERT(resultAnimationElement.m_animatedType); >- ASSERT(resultAnimationElement.m_animatedPropertyType == m_animatedPropertyType); >- >- if (hasTagName(SVGNames::setTag)) >- percentage = 1; >+ ASSERT(targetElement()); >+ ASSERT(!hasInvalidCSSAttributeType()); > >- if (calcMode() == CalcMode::Discrete) >- percentage = percentage < 0.5 ? 0 : 1; >- >- // Target element might have changed. >- m_animator->setContextElement(targetElement.get()); >+ if (!m_animator) >+ m_animator = targetElement()->createAnimator(attributeName(), animationMode(), calcMode(), isAccumulated(), isAdditive()); > >- // Be sure to detach list wrappers before we modfiy their underlying value. If we'd do >- // if after calculateAnimatedValue() ran the cached pointers in the list propery tear >- // offs would point nowhere, and we couldn't create copies of those values anymore, >- // while detaching. This is covered by assertions, moving this down would fire them. >- if (!m_animatedProperties.isEmpty()) >- m_animator->animValWillChange(m_animatedProperties); >+ return m_animator; >+} > >- // Values-animation accumulates using the last values entry corresponding to the end of duration time. >- SVGAnimatedType* toAtEndOfDurationType = m_toAtEndOfDurationType ? m_toAtEndOfDurationType.get() : m_toType.get(); >- m_animator->calculateAnimatedValue(percentage, repeatCount, m_fromType.get(), m_toType.get(), toAtEndOfDurationType, resultAnimationElement.m_animatedType.get()); >+void SVGAnimateElementBase::resetAnimation() >+{ >+ SVGAnimationElement::resetAnimation(); >+ m_animator = nullptr; > } > >-bool SVGAnimateElementBase::calculateToAtEndOfDurationValue(const String& toAtEndOfDurationString) >+bool SVGAnimateElementBase::hasValidAttributeType() const > { >- if (toAtEndOfDurationString.isEmpty()) >+ if (hasInvalidCSSAttributeType()) > return false; >- m_toAtEndOfDurationType = ensureAnimator()->constructFromString(toAtEndOfDurationString); >- return true; >+ return targetElement() && targetElement()->isAnimatedAttribute(attributeName()); >+} >+ >+bool SVGAnimateElementBase::isDiscreteAnimator() const >+{ >+ return hasValidAttributeType() && m_animator->isDiscrete(); > } > >-bool SVGAnimateElementBase::calculateFromAndToValues(const String& fromString, const String& toString) >+bool SVGAnimateElementBase::calculateFromAndToValues(const String& from, const String& to) > { >- if (!this->targetElement()) >+ if (!targetElement() || !createAnimator()) > return false; > >- determinePropertyValueTypes(fromString, toString); >- ensureAnimator()->calculateFromAndToValues(m_fromType, m_toType, fromString, toString); >- ASSERT(m_animatedPropertyType == m_animator->type()); >+ m_animator->setFromAndToValues(targetElement(), animateRangeString(from), animateRangeString(to)); > return true; > } > >-bool SVGAnimateElementBase::calculateFromAndByValues(const String& fromString, const String& byString) >+bool SVGAnimateElementBase::calculateFromAndByValues(const String& from, const String& by) > { >- if (!this->targetElement()) >+ if (!targetElement() || !createAnimator()) > return false; > >- if (animationMode() == ByAnimation && !isAdditive()) >+ if (animationMode() == AnimationMode::By && (!isAdditive() || isDiscreteAnimator())) > return false; > >- // from-by animation may only be used with attributes that support addition (e.g. most numeric attributes). >- if (animationMode() == FromByAnimation && !animatedPropertyTypeSupportsAddition()) >+ if (animationMode() == AnimationMode::FromBy && isDiscreteAnimator()) > return false; > > ASSERT(!hasTagName(SVGNames::setTag)); >- >- determinePropertyValueTypes(fromString, byString); >- ensureAnimator()->calculateFromAndByValues(m_fromType, m_toType, fromString, byString); >- ASSERT(m_animatedPropertyType == m_animator->type()); >+ m_animator->setFromAndByValues(targetElement(), animateRangeString(from), animateRangeString(by)); > return true; > } > >-#ifndef NDEBUG >-static inline bool propertyTypesAreConsistent(AnimatedPropertyType expectedPropertyType, const SVGElementAnimatedPropertyList& animatedTypes) >-{ >- for (auto& type : animatedTypes) { >- for (auto& property : type.properties) { >- if (expectedPropertyType != property->animatedPropertyType()) { >- // This is the only allowed inconsistency. SVGAnimatedAngleAnimator handles both SVGAnimatedAngle & SVGAnimatedEnumeration for markers orient attribute. >- if (expectedPropertyType == AnimatedAngle && property->animatedPropertyType() == AnimatedEnumeration) >- return true; >- return false; >- } >- } >- } >- >- return true; >-} >-#endif >- >-void SVGAnimateElementBase::resetAnimatedType() >-{ >- SVGAnimatedTypeAnimator* animator = ensureAnimator(); >- ASSERT(m_animatedPropertyType == animator->type()); >- >- auto targetElement = makeRefPtr(this->targetElement()); >- if (!targetElement) >- return; >- >- const QualifiedName& attributeName = this->attributeName(); >- ShouldApplyAnimation shouldApply = shouldApplyAnimation(targetElement.get(), attributeName); >- >- if (shouldApply == DontApplyAnimation) >- return; >- >- if (shouldApply == ApplyXMLAnimation || shouldApply == ApplyXMLandCSSAnimation) { >- // SVG DOM animVal animation code-path. >- m_animatedProperties = animator->findAnimatedPropertiesForAttributeName(*targetElement, attributeName); >- if (m_animatedProperties.isEmpty()) >- return; >- >- ASSERT(propertyTypesAreConsistent(m_animatedPropertyType, m_animatedProperties)); >- if (!m_animatedType) >- m_animatedType = animator->startAnimValAnimation(m_animatedProperties); >- else { >- animator->resetAnimValToBaseVal(m_animatedProperties, *m_animatedType); >- animator->animValDidChange(m_animatedProperties); >- } >- return; >- } >- >- // CSS properties animation code-path. >- ASSERT(m_animatedProperties.isEmpty()); >- String baseValue; >- >- if (shouldApply == ApplyCSSAnimation) { >- ASSERT(SVGAnimationElement::isTargetAttributeCSSProperty(targetElement.get(), attributeName)); >- computeCSSPropertyValue(targetElement.get(), cssPropertyID(attributeName.localName()), baseValue); >- } >- >- if (!m_animatedType) >- m_animatedType = animator->constructFromString(baseValue); >- else >- m_animatedType->setValueAsString(attributeName, baseValue); >-} >- >-static inline void applyCSSPropertyToTarget(SVGElement& targetElement, CSSPropertyID id, const String& value) >+bool SVGAnimateElementBase::calculateToAtEndOfDurationValue(const String& toAtEndOfDurationString) > { >- ASSERT(!targetElement.m_deletionHasBegun); >+ if (!targetElement() || !createAnimator()) >+ return false; > >- if (!targetElement.ensureAnimatedSMILStyleProperties().setProperty(id, value, false)) >- return; >+ if (toAtEndOfDurationString.isEmpty()) >+ return false; > >- targetElement.invalidateStyleAndLayerComposition(); >-} >+ if (isDiscreteAnimator()) >+ return true; > >-static inline void removeCSSPropertyFromTarget(SVGElement& targetElement, CSSPropertyID id) >-{ >- ASSERT(!targetElement.m_deletionHasBegun); >- targetElement.ensureAnimatedSMILStyleProperties().removeProperty(id); >- targetElement.invalidateStyleAndLayerComposition(); >+ m_animator->setToAtEndOfDurationValue(animateRangeString(toAtEndOfDurationString)); >+ return true; > } > >-static inline void applyCSSPropertyToTargetAndInstances(SVGElement& targetElement, const QualifiedName& attributeName, const String& valueAsString) >+void SVGAnimateElementBase::resetAnimatedType() > { >- // FIXME: Do we really need to check both isConnected and !parentNode? >- if (attributeName == anyQName() || !targetElement.isConnected() || !targetElement.parentNode()) >+ if (!targetElement() || !createAnimator()) > return; > >- CSSPropertyID id = cssPropertyID(attributeName.localName()); >- >- SVGElement::InstanceUpdateBlocker blocker(targetElement); >- applyCSSPropertyToTarget(targetElement, id, valueAsString); >- >- // If the target element has instances, update them as well, w/o requiring the <use> tree to be rebuilt. >- for (auto* instance : targetElement.instances()) >- applyCSSPropertyToTarget(*instance, id, valueAsString); >+ m_animator->start(targetElement()); > } > >-static inline void removeCSSPropertyFromTargetAndInstances(SVGElement& targetElement, const QualifiedName& attributeName) >+void SVGAnimateElementBase::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGSMILElement*) > { >- // FIXME: Do we really need to check both isConnected and !parentNode? >- if (attributeName == anyQName() || !targetElement.isConnected() || !targetElement.parentNode()) >+ if (!targetElement() || !createAnimator()) > return; > >- CSSPropertyID id = cssPropertyID(attributeName.localName()); >+ ASSERT(percentage >= 0 && percentage <= 1); > >- SVGElement::InstanceUpdateBlocker blocker(targetElement); >- removeCSSPropertyFromTarget(targetElement, id); >+ if (hasTagName(SVGNames::setTag)) >+ percentage = 1; > >- // If the target element has instances, update them as well, w/o requiring the <use> tree to be rebuilt. >- for (auto* instance : targetElement.instances()) >- removeCSSPropertyFromTarget(*instance, id); >-} >+ if (calcMode() == CalcMode::Discrete) >+ percentage = percentage < 0.5 ? 0 : 1; > >-static inline void notifyTargetAboutAnimValChange(SVGElement& targetElement, const QualifiedName& attributeName) >-{ >- ASSERT(!targetElement.m_deletionHasBegun); >- targetElement.svgAttributeChanged(attributeName); >+ m_animator->progress(targetElement(), percentage, repeatCount); > } > >-static inline void notifyTargetAndInstancesAboutAnimValChange(SVGElement& targetElement, const QualifiedName& attributeName) >+void SVGAnimateElementBase::applyResultsToTarget() > { >- if (attributeName == anyQName() || !targetElement.isConnected() || !targetElement.parentNode()) >+ if (!targetElement() || !createAnimator()) > return; > >- SVGElement::InstanceUpdateBlocker blocker(targetElement); >- notifyTargetAboutAnimValChange(targetElement, attributeName); >- >- // If the target element has instances, update them as well, w/o requiring the <use> tree to be rebuilt. >- for (auto* instance : targetElement.instances()) >- notifyTargetAboutAnimValChange(*instance, attributeName); >+ m_animator->apply(targetElement()); > } > > void SVGAnimateElementBase::clearAnimatedType(SVGElement* targetElement) > { >- if (!m_animatedType) >- return; >- >- // If the SVGAnimatedType is a list type, e.g. SVGLengthListValues, the wrappers of the >- // animated properties have to be detached from the items in the list before it's deleted. >- if (!m_animatedProperties.isEmpty()) >- m_animator->animValWillChange(m_animatedProperties); >- >- if (!targetElement) { >- m_animatedType = nullptr; >- return; >- } >- >- if (m_animatedProperties.isEmpty()) { >- // CSS properties animation code-path. >- removeCSSPropertyFromTargetAndInstances(*targetElement, attributeName()); >- m_animatedType = nullptr; >+ if (!targetElement || !m_animator) > return; >- } > >- ShouldApplyAnimation shouldApply = shouldApplyAnimation(targetElement, attributeName()); >- if (shouldApply == ApplyXMLandCSSAnimation) >- removeCSSPropertyFromTargetAndInstances(*targetElement, attributeName()); >- >- // SVG DOM animVal animation code-path. >- if (m_animator) { >- m_animator->stopAnimValAnimation(m_animatedProperties); >- notifyTargetAndInstancesAboutAnimValChange(*targetElement, attributeName()); >- } >- >- m_animatedProperties.clear(); >- m_animatedType = nullptr; >+ m_animator->stop(targetElement); > } > >-void SVGAnimateElementBase::applyResultsToTarget() >+bool SVGAnimateElementBase::isTargetAttributeCSSProperty(SVGElement* targetElement, const QualifiedName& attributeName) > { >- ASSERT(m_animatedPropertyType != AnimatedTransformList || hasTagName(SVGNames::animateTransformTag)); >- ASSERT(m_animatedPropertyType != AnimatedUnknown); >- ASSERT(m_animator); >- >- // Early exit if our animated type got destroyed by a previous endedActiveInterval(). >- if (!m_animatedType) >- return; >- >- auto targetElement = makeRefPtr(this->targetElement()); >- const QualifiedName& attributeName = this->attributeName(); >- >- ASSERT(targetElement); >- >- if (m_animatedProperties.isEmpty()) { >- // CSS properties animation code-path. >- // Convert the result of the animation to a String and apply it as CSS property on the target & all instances. >- applyCSSPropertyToTargetAndInstances(*targetElement, attributeName, m_animatedType->valueAsString()); >- return; >- } >- >- // We do update the style and the animation property independent of each other. >- ShouldApplyAnimation shouldApply = shouldApplyAnimation(targetElement.get(), attributeName); >- if (shouldApply == ApplyXMLandCSSAnimation) >- applyCSSPropertyToTargetAndInstances(*targetElement, attributeName, m_animatedType->valueAsString()); >- >- // SVG DOM animVal animation code-path. >- // At this point the SVG DOM values are already changed, unlike for CSS. >- // We only have to trigger update notifications here. >- m_animator->animValDidChange(m_animatedProperties); >- notifyTargetAndInstancesAboutAnimValChange(*targetElement, attributeName); >+ return targetElement->isAnimatedStyleAttribute(attributeName); > } > >-bool SVGAnimateElementBase::animatedPropertyTypeSupportsAddition() const >+bool SVGAnimateElementBase::hasInvalidCSSAttributeType() const > { >- // Spec: http://www.w3.org/TR/SVG/animate.html#AnimationAttributesAndProperties. >- switch (m_animatedPropertyType) { >- case AnimatedBoolean: >- case AnimatedEnumeration: >- case AnimatedPreserveAspectRatio: >- case AnimatedString: >- case AnimatedUnknown: >+ if (!targetElement()) > return false; >- case AnimatedAngle: >- case AnimatedColor: >- case AnimatedInteger: >- case AnimatedIntegerOptionalInteger: >- case AnimatedLength: >- case AnimatedLengthList: >- case AnimatedNumber: >- case AnimatedNumberList: >- case AnimatedNumberOptionalNumber: >- case AnimatedPath: >- case AnimatedPoints: >- case AnimatedRect: >- case AnimatedTransformList: >- return true; >- default: >- RELEASE_ASSERT_NOT_REACHED(); >- return true; >- } >-} >+ >+ if (!m_hasInvalidCSSAttributeType) >+ m_hasInvalidCSSAttributeType = hasValidAttributeName() && attributeType() == AttributeType::CSS && !isTargetAttributeCSSProperty(targetElement(), attributeName()); > >-bool SVGAnimateElementBase::isAdditive() const >-{ >- if (animationMode() == ByAnimation || animationMode() == FromByAnimation) { >- if (!animatedPropertyTypeSupportsAddition()) >- return false; >- } >- >- return SVGAnimationElement::isAdditive(); >+ return *m_hasInvalidCSSAttributeType; > } > >-float SVGAnimateElementBase::calculateDistance(const String& fromString, const String& toString) >+float SVGAnimateElementBase::calculateDistance(const String& from, const String& to) > { > // FIXME: A return value of float is not enough to support paced animations on lists. >- if (!this->targetElement()) >+ if (!targetElement() || !createAnimator()) > return -1; > >- return ensureAnimator()->calculateDistance(fromString, toString); >-} >- >-void SVGAnimateElementBase::setTargetElement(SVGElement* target) >-{ >- SVGAnimationElement::setTargetElement(target); >- resetAnimatedPropertyType(); >-} >- >-void SVGAnimateElementBase::setAttributeName(const QualifiedName& attributeName) >-{ >- SVGSMILElement::setAttributeName(attributeName); >- checkInvalidCSSAttributeType(targetElement()); >- resetAnimatedPropertyType(); >-} >- >-void SVGAnimateElementBase::resetAnimatedPropertyType() >-{ >- SVGAnimationElement::resetAnimatedPropertyType(); >- ASSERT(!m_animatedType); >- m_fromType = nullptr; >- m_toType = nullptr; >- m_toAtEndOfDurationType = nullptr; >- m_animator = nullptr; >- m_animatedPropertyType = targetElement() ? determineAnimatedPropertyType(*targetElement()) : AnimatedString; >-} >- >-SVGAnimatedTypeAnimator* SVGAnimateElementBase::ensureAnimator() >-{ >- if (!m_animator) >- m_animator = SVGAnimatorFactory::create(this, targetElement(), m_animatedPropertyType); >- ASSERT(m_animatedPropertyType == m_animator->type()); >- return m_animator.get(); >+ return m_animator->calculateDistance(targetElement(), from, to); > } > > } // namespace WebCore >diff --git a/Source/WebCore/svg/SVGAnimateElementBase.h b/Source/WebCore/svg/SVGAnimateElementBase.h >index aa5341d5eca..1a7afbb8c1a 100644 >--- a/Source/WebCore/svg/SVGAnimateElementBase.h >+++ b/Source/WebCore/svg/SVGAnimateElementBase.h >@@ -23,19 +23,17 @@ > > #pragma once > >-#include "SVGAnimatedType.h" >-#include "SVGAnimatedTypeAnimator.h" > #include "SVGAnimationElement.h" > #include "SVGNames.h" > > namespace WebCore { > >+class SVGAnimator; >+ > class SVGAnimateElementBase : public SVGAnimationElement { > WTF_MAKE_ISO_ALLOCATED(SVGAnimateElementBase); > public: >- virtual ~SVGAnimateElementBase(); >- >- AnimatedPropertyType determineAnimatedPropertyType(SVGElement&) const; >+ bool isDiscreteAnimator() const; > > protected: > SVGAnimateElementBase(const QualifiedName&, Document&); >@@ -43,33 +41,30 @@ protected: > void resetAnimatedType() override; > void clearAnimatedType(SVGElement* targetElement) override; > >- bool calculateToAtEndOfDurationValue(const String& toAtEndOfDurationString) override; > bool calculateFromAndToValues(const String& fromString, const String& toString) override; > bool calculateFromAndByValues(const String& fromString, const String& byString) override; >+ bool calculateToAtEndOfDurationValue(const String& toAtEndOfDurationString) override; >+ > void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGSMILElement* resultElement) override; >+ > void applyResultsToTarget() override; > float calculateDistance(const String& fromString, const String& toString) override; >- bool isAdditive() const override; > > void setTargetElement(SVGElement*) override; > void setAttributeName(const QualifiedName&) override; >- void resetAnimatedPropertyType() override; >+ void resetAnimation() override; > >- AnimatedPropertyType m_animatedPropertyType; >+ virtual String animateRangeString(const String& string) const { return string; } > > private: >- SVGAnimatedTypeAnimator* ensureAnimator(); >- bool animatedPropertyTypeSupportsAddition() const; >- >- bool hasValidAttributeType() override; >+ RefPtr<SVGAnimator> createAnimator() const; > >- std::unique_ptr<SVGAnimatedType> m_fromType; >- std::unique_ptr<SVGAnimatedType> m_toType; >- std::unique_ptr<SVGAnimatedType> m_toAtEndOfDurationType; >- std::unique_ptr<SVGAnimatedType> m_animatedType; >+ bool hasValidAttributeType() const override; >+ static bool isTargetAttributeCSSProperty(SVGElement*, const QualifiedName&); >+ bool hasInvalidCSSAttributeType() const; > >- SVGElementAnimatedPropertyList m_animatedProperties; >- std::unique_ptr<SVGAnimatedTypeAnimator> m_animator; >+ mutable RefPtr<SVGAnimator> m_animator; >+ mutable std::optional<bool> m_hasInvalidCSSAttributeType; > }; > > } // namespace WebCore >diff --git a/Source/WebCore/svg/SVGAnimateMotionElement.cpp b/Source/WebCore/svg/SVGAnimateMotionElement.cpp >index 7a8c63e6703..1cb9af610db 100644 >--- a/Source/WebCore/svg/SVGAnimateMotionElement.cpp >+++ b/Source/WebCore/svg/SVGAnimateMotionElement.cpp >@@ -57,7 +57,7 @@ Ref<SVGAnimateMotionElement> SVGAnimateMotionElement::create(const QualifiedName > return adoptRef(*new SVGAnimateMotionElement(tagName, document)); > } > >-bool SVGAnimateMotionElement::hasValidAttributeType() >+bool SVGAnimateMotionElement::hasValidAttributeType() const > { > auto targetElement = makeRefPtr(this->targetElement()); > if (!targetElement) >@@ -90,7 +90,7 @@ bool SVGAnimateMotionElement::hasValidAttributeType() > return false; > } > >-bool SVGAnimateMotionElement::hasValidAttributeName() >+bool SVGAnimateMotionElement::hasValidAttributeName() const > { > // AnimateMotion does not use attributeName so it is always valid. > return true; >@@ -176,7 +176,7 @@ bool SVGAnimateMotionElement::calculateFromAndToValues(const String& fromString, > bool SVGAnimateMotionElement::calculateFromAndByValues(const String& fromString, const String& byString) > { > m_hasToPointAtEndOfDuration = false; >- if (animationMode() == ByAnimation && !isAdditive()) >+ if (animationMode() == AnimationMode::By && !isAdditive()) > return false; > parsePoint(fromString, m_fromPoint); > FloatPoint byPoint; >@@ -222,7 +222,7 @@ void SVGAnimateMotionElement::calculateAnimatedValue(float percentage, unsigned > if (!isAdditive()) > transform->makeIdentity(); > >- if (animationMode() != PathAnimation) { >+ if (animationMode() != AnimationMode::Path) { > FloatPoint toPointAtEndOfDuration = m_toPoint; > if (isAccumulated() && repeatCount && m_hasToPointAtEndOfDuration) > toPointAtEndOfDuration = m_toPointAtEndOfDuration; >@@ -288,7 +288,7 @@ float SVGAnimateMotionElement::calculateDistance(const String& fromString, const > void SVGAnimateMotionElement::updateAnimationMode() > { > if (!m_animationPath.isEmpty()) >- setAnimationMode(PathAnimation); >+ setAnimationMode(AnimationMode::Path); > else > SVGAnimationElement::updateAnimationMode(); > } >diff --git a/Source/WebCore/svg/SVGAnimateMotionElement.h b/Source/WebCore/svg/SVGAnimateMotionElement.h >index 24dececdd6b..f93e643f3d8 100644 >--- a/Source/WebCore/svg/SVGAnimateMotionElement.h >+++ b/Source/WebCore/svg/SVGAnimateMotionElement.h >@@ -36,8 +36,8 @@ public: > private: > SVGAnimateMotionElement(const QualifiedName&, Document&); > >- bool hasValidAttributeType() override; >- bool hasValidAttributeName() override; >+ bool hasValidAttributeType() const override; >+ bool hasValidAttributeName() const override; > > void parseAttribute(const QualifiedName&, const AtomicString&) override; > >diff --git a/Source/WebCore/svg/SVGAnimateTransformElement.cpp b/Source/WebCore/svg/SVGAnimateTransformElement.cpp >index 0149cc899e9..4738f81402f 100644 >--- a/Source/WebCore/svg/SVGAnimateTransformElement.cpp >+++ b/Source/WebCore/svg/SVGAnimateTransformElement.cpp >@@ -43,7 +43,7 @@ Ref<SVGAnimateTransformElement> SVGAnimateTransformElement::create(const Qualifi > return adoptRef(*new SVGAnimateTransformElement(tagName, document)); > } > >-bool SVGAnimateTransformElement::hasValidAttributeType() >+bool SVGAnimateTransformElement::hasValidAttributeType() const > { > if (!this->targetElement()) > return false; >@@ -51,7 +51,7 @@ bool SVGAnimateTransformElement::hasValidAttributeType() > if (attributeType() == AttributeType::CSS) > return false; > >- return m_animatedPropertyType == AnimatedTransformList; >+ return true; > } > > void SVGAnimateTransformElement::parseAttribute(const QualifiedName& name, const AtomicString& value) >@@ -66,4 +66,9 @@ void SVGAnimateTransformElement::parseAttribute(const QualifiedName& name, const > SVGAnimateElementBase::parseAttribute(name, value); > } > >+String SVGAnimateTransformElement::animateRangeString(const String& string) const >+{ >+ return SVGTransformValue::prefixForTransfromType(m_type) + string + ')'; >+} >+ > } >diff --git a/Source/WebCore/svg/SVGAnimateTransformElement.h b/Source/WebCore/svg/SVGAnimateTransformElement.h >index 62973082d0d..301ea88ab46 100644 >--- a/Source/WebCore/svg/SVGAnimateTransformElement.h >+++ b/Source/WebCore/svg/SVGAnimateTransformElement.h >@@ -39,8 +39,9 @@ public: > private: > SVGAnimateTransformElement(const QualifiedName&, Document&); > >- bool hasValidAttributeType() final; >+ bool hasValidAttributeType() const final; > void parseAttribute(const QualifiedName&, const AtomicString&) final; >+ String animateRangeString(const String&) const final; > > SVGTransformValue::SVGTransformType m_type; > }; >diff --git a/Source/WebCore/svg/SVGAnimationElement.cpp b/Source/WebCore/svg/SVGAnimationElement.cpp >index 3f25808f8c4..65851d0caf6 100644 >--- a/Source/WebCore/svg/SVGAnimationElement.cpp >+++ b/Source/WebCore/svg/SVGAnimationElement.cpp >@@ -26,7 +26,6 @@ > #include "config.h" > #include "SVGAnimationElement.h" > >-#include "CSSComputedStyleDeclaration.h" > #include "CSSPropertyNames.h" > #include "CSSPropertyParser.h" > #include "Document.h" >@@ -268,13 +267,13 @@ void SVGAnimationElement::updateAnimationMode() > { > // http://www.w3.org/TR/2001/REC-smil-animation-20010904/#AnimFuncValues > if (hasAttribute(SVGNames::valuesAttr)) >- setAnimationMode(ValuesAnimation); >+ setAnimationMode(AnimationMode::Values); > else if (!toValue().isEmpty()) >- setAnimationMode(fromValue().isEmpty() ? ToAnimation : FromToAnimation); >+ setAnimationMode(fromValue().isEmpty() ? AnimationMode::To : AnimationMode::FromTo); > else if (!byValue().isEmpty()) >- setAnimationMode(fromValue().isEmpty() ? ByAnimation : FromByAnimation); >+ setAnimationMode(fromValue().isEmpty() ? AnimationMode::By : AnimationMode::FromBy); > else >- setAnimationMode(NoAnimation); >+ setAnimationMode(AnimationMode::None); > } > > void SVGAnimationElement::setCalcMode(const AtomicString& calcMode) >@@ -305,7 +304,6 @@ void SVGAnimationElement::setAttributeType(const AtomicString& attributeType) > m_attributeType = AttributeType::XML; > else > m_attributeType = AttributeType::Auto; >- checkInvalidCSSAttributeType(targetElement()); > } > > String SVGAnimationElement::toValue() const >@@ -327,49 +325,20 @@ bool SVGAnimationElement::isAdditive() const > { > static NeverDestroyed<const AtomicString> sum("sum", AtomicString::ConstructFromLiteral); > const AtomicString& value = attributeWithoutSynchronization(SVGNames::additiveAttr); >- return value == sum || animationMode() == ByAnimation; >+ return value == sum || animationMode() == AnimationMode::By; > } > > bool SVGAnimationElement::isAccumulated() const > { > static NeverDestroyed<const AtomicString> sum("sum", AtomicString::ConstructFromLiteral); > const AtomicString& value = attributeWithoutSynchronization(SVGNames::accumulateAttr); >- return value == sum && animationMode() != ToAnimation; >-} >- >-bool SVGAnimationElement::isTargetAttributeCSSProperty(SVGElement* element, const QualifiedName& attributeName) >-{ >- if (element->isTextContent() >- && (attributeName == SVGNames::xAttr || attributeName == SVGNames::yAttr)) >- return false; >- >- return SVGElement::isAnimatableCSSProperty(attributeName); >-} >- >-SVGAnimationElement::ShouldApplyAnimation SVGAnimationElement::shouldApplyAnimation(SVGElement* targetElement, const QualifiedName& attributeName) >-{ >- if (!hasValidAttributeType() || !targetElement || attributeName == anyQName()) >- return DontApplyAnimation; >- >- // Always animate CSS properties, using the ApplyCSSAnimation code path, regardless of the attributeType value. >- if (isTargetAttributeCSSProperty(targetElement, attributeName)) { >- if (targetElement->isPresentationAttributeWithSVGDOM(attributeName)) >- return ApplyXMLandCSSAnimation; >- return ApplyCSSAnimation; >- } >- >- >- // If attributeType="CSS" and attributeName doesn't point to a CSS property, ignore the animation. >- if (attributeType() == AttributeType::CSS) >- return DontApplyAnimation; >- >- return ApplyXMLAnimation; >+ return value == sum && animationMode() != AnimationMode::To; > } > > void SVGAnimationElement::calculateKeyTimesForCalcModePaced() > { > ASSERT(calcMode() == CalcMode::Paced); >- ASSERT(animationMode() == ValuesAnimation); >+ ASSERT(animationMode() == AnimationMode::Values); > > unsigned valuesCount = m_values.size(); > ASSERT(valuesCount >= 1); >@@ -492,8 +461,7 @@ void SVGAnimationElement::currentValuesForValuesAnimation(float percent, float& > CalcMode calcMode = this->calcMode(); > if (is<SVGAnimateElement>(*this) || is<SVGAnimateColorElement>(*this)) { > ASSERT(targetElement()); >- AnimatedPropertyType type = downcast<SVGAnimateElementBase>(*this).determineAnimatedPropertyType(*targetElement()); >- if (type == AnimatedBoolean || type == AnimatedEnumeration || type == AnimatedPreserveAspectRatio || type == AnimatedString) >+ if (downcast<SVGAnimateElementBase>(*this).isDiscreteAnimator()) > calcMode = CalcMode::Discrete; > } > if (!m_keyPoints.isEmpty() && calcMode != CalcMode::Paced) >@@ -554,7 +522,7 @@ void SVGAnimationElement::startedActiveInterval() > unsigned splinesCount = m_keySplines.size(); > if (!splinesCount > || (hasAttributeWithoutSynchronization(SVGNames::keyPointsAttr) && m_keyPoints.size() - 1 != splinesCount) >- || (animationMode == ValuesAnimation && m_values.size() - 1 != splinesCount) >+ || (animationMode == AnimationMode::Values && m_values.size() - 1 != splinesCount) > || (hasAttributeWithoutSynchronization(SVGNames::keyTimesAttr) && m_keyTimes.size() - 1 != splinesCount)) > return; > } >@@ -562,22 +530,22 @@ void SVGAnimationElement::startedActiveInterval() > String from = fromValue(); > String to = toValue(); > String by = byValue(); >- if (animationMode == NoAnimation) >+ if (animationMode == AnimationMode::None) > return; >- if ((animationMode == FromToAnimation || animationMode == FromByAnimation || animationMode == ToAnimation || animationMode == ByAnimation) >+ if ((animationMode == AnimationMode::FromTo || animationMode == AnimationMode::FromBy || animationMode == AnimationMode::To || animationMode == AnimationMode::By) > && (hasAttributeWithoutSynchronization(SVGNames::keyPointsAttr) && hasAttributeWithoutSynchronization(SVGNames::keyTimesAttr) && (m_keyTimes.size() < 2 || m_keyTimes.size() != m_keyPoints.size()))) > return; >- if (animationMode == FromToAnimation) >+ if (animationMode == AnimationMode::FromTo) > m_animationValid = calculateFromAndToValues(from, to); >- else if (animationMode == ToAnimation) { >+ else if (animationMode == AnimationMode::To) { > // For to-animations the from value is the current accumulated value from lower priority animations. > // The value is not static and is determined during the animation. > m_animationValid = calculateFromAndToValues(emptyString(), to); >- } else if (animationMode == FromByAnimation) >+ } else if (animationMode == AnimationMode::FromBy) > m_animationValid = calculateFromAndByValues(from, by); >- else if (animationMode == ByAnimation) >+ else if (animationMode == AnimationMode::By) > m_animationValid = calculateFromAndByValues(emptyString(), by); >- else if (animationMode == ValuesAnimation) { >+ else if (animationMode == AnimationMode::Values) { > m_animationValid = m_values.size() >= 1 > && (calcMode == CalcMode::Paced || !hasAttributeWithoutSynchronization(SVGNames::keyTimesAttr) || hasAttributeWithoutSynchronization(SVGNames::keyPointsAttr) || (m_values.size() == m_keyTimes.size())) > && (calcMode == CalcMode::Discrete || !m_keyTimes.size() || m_keyTimes.last() == 1) >@@ -587,7 +555,7 @@ void SVGAnimationElement::startedActiveInterval() > m_animationValid = calculateToAtEndOfDurationValue(m_values.last()); > if (calcMode == CalcMode::Paced && m_animationValid) > calculateKeyTimesForCalcModePaced(); >- } else if (animationMode == PathAnimation) >+ } else if (animationMode == AnimationMode::Path) > m_animationValid = calcMode == CalcMode::Paced || !hasAttributeWithoutSynchronization(SVGNames::keyPointsAttr) || (m_keyTimes.size() > 1 && m_keyTimes.size() == m_keyPoints.size()); > } > >@@ -599,7 +567,7 @@ void SVGAnimationElement::updateAnimation(float percent, unsigned repeatCount, S > float effectivePercent; > CalcMode calcMode = this->calcMode(); > AnimationMode animationMode = this->animationMode(); >- if (animationMode == ValuesAnimation) { >+ if (animationMode == AnimationMode::Values) { > String from; > String to; > currentValuesForValuesAnimation(percent, effectivePercent, from, to); >@@ -614,7 +582,7 @@ void SVGAnimationElement::updateAnimation(float percent, unsigned repeatCount, S > effectivePercent = calculatePercentFromKeyPoints(percent); > else if (m_keyPoints.isEmpty() && calcMode == CalcMode::Spline && m_keyTimes.size() > 1) > effectivePercent = calculatePercentForSpline(percent, calculateKeyTimesIndex(percent)); >- else if (animationMode == FromToAnimation || animationMode == ToAnimation) >+ else if (animationMode == AnimationMode::FromTo || animationMode == AnimationMode::To) > effectivePercent = calculatePercentForFromTo(percent); > else > effectivePercent = percent; >@@ -622,38 +590,13 @@ void SVGAnimationElement::updateAnimation(float percent, unsigned repeatCount, S > calculateAnimatedValue(effectivePercent, repeatCount, resultElement); > } > >-void SVGAnimationElement::computeCSSPropertyValue(SVGElement* element, CSSPropertyID id, String& valueString) >-{ >- ASSERT(element); >- >- // Don't include any properties resulting from CSS Transitions/Animations or SMIL animations, as we want to retrieve the "base value". >- element->setUseOverrideComputedStyle(true); >- RefPtr<CSSValue> value = ComputedStyleExtractor(element).propertyValue(id); >- valueString = value ? value->cssText() : String(); >- element->setUseOverrideComputedStyle(false); >-} >- >-void SVGAnimationElement::adjustForInheritance(SVGElement* targetElement, const QualifiedName& attributeName, String& value) >-{ >- // FIXME: At the moment the computed style gets returned as a String and needs to get parsed again. >- // In the future we might want to work with the value type directly to avoid the String parsing. >- ASSERT(targetElement); >- >- auto parent = makeRefPtr(targetElement->parentElement()); >- if (!parent || !parent->isSVGElement()) >- return; >- >- SVGElement& svgParent = downcast<SVGElement>(*parent); >- computeCSSPropertyValue(&svgParent, cssPropertyID(attributeName.localName()), value); >-} >- >-static bool inheritsFromProperty(SVGElement*, const QualifiedName& attributeName, const String& value) >+static bool inheritsFromProperty(SVGElement* targetElement, const QualifiedName& attributeName, const String& value) > { > static NeverDestroyed<const AtomicString> inherit("inherit", AtomicString::ConstructFromLiteral); > > if (value.isEmpty() || value != inherit) > return false; >- return SVGElement::isAnimatableCSSProperty(attributeName); >+ return targetElement->isAnimatedStyleAttribute(attributeName); > } > > void SVGAnimationElement::determinePropertyValueTypes(const String& from, const String& to) >@@ -667,21 +610,10 @@ void SVGAnimationElement::determinePropertyValueTypes(const String& from, const > if (inheritsFromProperty(targetElement.get(), attributeName, to)) > m_toPropertyValueType = InheritValue; > } >-void SVGAnimationElement::resetAnimatedPropertyType() >+void SVGAnimationElement::resetAnimation() > { > m_lastValuesAnimationFrom = String(); > m_lastValuesAnimationTo = String(); > } > >-void SVGAnimationElement::setTargetElement(SVGElement* target) >-{ >- SVGSMILElement::setTargetElement(target); >- checkInvalidCSSAttributeType(target); >-} >- >-void SVGAnimationElement::checkInvalidCSSAttributeType(SVGElement* target) >-{ >- m_hasInvalidCSSAttributeType = target && hasValidAttributeName() && attributeType() == AttributeType::CSS && !isTargetAttributeCSSProperty(target, attributeName()); >-} >- > } >diff --git a/Source/WebCore/svg/SVGAnimationElement.h b/Source/WebCore/svg/SVGAnimationElement.h >index bfe230c5df6..769060089dd 100644 >--- a/Source/WebCore/svg/SVGAnimationElement.h >+++ b/Source/WebCore/svg/SVGAnimationElement.h >@@ -24,7 +24,6 @@ > > #pragma once > >-#include "SVGAnimatedBoolean.h" > #include "SVGExternalResourcesRequired.h" > #include "SVGSMILElement.h" > #include "SVGTests.h" >@@ -36,22 +35,10 @@ class ConditionEventListener; > class SVGAnimatedType; > class TimeContainer; > >-enum AnimationMode { >- NoAnimation, >- FromToAnimation, >- FromByAnimation, >- ToAnimation, >- ByAnimation, >- ValuesAnimation, >- PathAnimation // Used by AnimateMotion. >-}; >- > // If we have 'currentColor' or 'inherit' as animation value, we need to grab > // the value during the animation since the value can be animated itself. > enum AnimatedPropertyValueType { RegularPropertyValue, CurrentColorValue, InheritValue }; > >-enum class CalcMode { Discrete, Linear, Paced, Spline }; >- > class SVGAnimationElement : public SVGSMILElement, public SVGExternalResourcesRequired, public SVGTests { > WTF_MAKE_ISO_ALLOCATED(SVGAnimationElement); > public: >@@ -64,71 +51,14 @@ public: > void endElement(); > void endElementAt(float offset); > >- static bool isTargetAttributeCSSProperty(SVGElement*, const QualifiedName&); >- > bool isAdditive() const override; > bool isAccumulated() const; > AnimationMode animationMode() const { return m_animationMode; } > CalcMode calcMode() const { return m_calcMode; } > >- enum ShouldApplyAnimation { >- DontApplyAnimation, >- ApplyCSSAnimation, >- ApplyXMLAnimation, >- ApplyXMLandCSSAnimation // For presentation attributes with SVG DOM properties. >- }; >- >- ShouldApplyAnimation shouldApplyAnimation(SVGElement* targetElement, const QualifiedName& attributeName); >- > AnimatedPropertyValueType fromPropertyValueType() const { return m_fromPropertyValueType; } > AnimatedPropertyValueType toPropertyValueType() const { return m_toPropertyValueType; } > >- template<typename AnimatedType> void adjustForInheritance(AnimatedType (*parseTypeFromString)(SVGAnimationElement*, const String&), AnimatedPropertyValueType valueType, AnimatedType& animatedType, SVGElement* contextElement) >- { >- if (valueType != InheritValue) >- return; >- // Replace 'inherit' by its computed property value. >- ASSERT(parseTypeFromString); >- String typeString; >- adjustForInheritance(contextElement, attributeName(), typeString); >- animatedType = (*parseTypeFromString)(this, typeString); >- } >- >- template<typename AnimatedType> bool adjustFromToListValues(const AnimatedType& fromList, const AnimatedType& toList, AnimatedType& animatedList, float percentage, bool resizeAnimatedListIfNeeded = true) >- { >- // If no 'to' value is given, nothing to animate. >- unsigned toListSize = toList.size(); >- if (!toListSize) >- return false; >- >- // If the 'from' value is given and it's length doesn't match the 'to' value list length, fallback to a discrete animation. >- unsigned fromListSize = fromList.size(); >- if (fromListSize != toListSize && fromListSize) { >- if (percentage < 0.5) { >- if (animationMode() != ToAnimation) >- animatedList = AnimatedType(fromList); >- } else >- animatedList = AnimatedType(toList); >- >- return false; >- } >- >- ASSERT(!fromListSize || fromListSize == toListSize); >- if (resizeAnimatedListIfNeeded && animatedList.size() < toListSize) >- animatedList.resize(toListSize); >- >- return true; >- } >- >- template<typename AnimatedType> void animateDiscreteType(float percentage, const AnimatedType& fromType, const AnimatedType& toType, AnimatedType& animatedType) >- { >- if ((animationMode() == FromToAnimation && percentage > 0.5) || animationMode() == ToAnimation || percentage == 1) { >- animatedType = AnimatedType(toType); >- return; >- } >- animatedType = AnimatedType(fromType); >- } >- > void animateAdditiveNumber(float percentage, unsigned repeatCount, float fromNumber, float toNumber, float toAtEndOfDurationNumber, float& animatedNumber) > { > float number; >@@ -140,7 +70,7 @@ public: > if (isAccumulated() && repeatCount) > number += toAtEndOfDurationNumber * repeatCount; > >- if (isAdditive() && animationMode() != ToAnimation) >+ if (isAdditive() && animationMode() != AnimationMode::To) > animatedNumber += number; > else > animatedNumber = number; >@@ -149,13 +79,11 @@ public: > protected: > SVGAnimationElement(const QualifiedName&, Document&); > >- using AttributeOwnerProxy = SVGAttributeOwnerProxyImpl<SVGAnimationElement, SVGElement, SVGExternalResourcesRequired, SVGTests>; >- static AttributeOwnerProxy::AttributeRegistry& attributeRegistry() { return AttributeOwnerProxy::attributeRegistry(); } >- const SVGAttributeOwnerProxy& attributeOwnerProxy() const override { return m_attributeOwnerProxy; } >+ using PropertyRegistry = SVGPropertyOwnerRegistry<SVGAnimationElement, SVGElement, SVGExternalResourcesRequired, SVGTests>; >+ const SVGPropertyRegistry& propertyRegistry() const override { return m_propertyRegistry; } > >- void computeCSSPropertyValue(SVGElement*, CSSPropertyID, String& value); > virtual void determinePropertyValueTypes(const String& from, const String& to); >- virtual void resetAnimatedPropertyType(); >+ virtual void resetAnimation(); > > static bool isSupportedAttribute(const QualifiedName&); > void parseAttribute(const QualifiedName&, const AtomicString&) override; >@@ -177,10 +105,7 @@ protected: > AnimatedPropertyValueType m_fromPropertyValueType { RegularPropertyValue }; > AnimatedPropertyValueType m_toPropertyValueType { RegularPropertyValue }; > >- void setTargetElement(SVGElement*) override; > void setAttributeName(const QualifiedName&) override { } >- bool hasInvalidCSSAttributeType() const { return m_hasInvalidCSSAttributeType; } >- void checkInvalidCSSAttributeType(SVGElement*); > > virtual void updateAnimationMode(); > void setAnimationMode(AnimationMode animationMode) { m_animationMode = animationMode; } >@@ -204,9 +129,6 @@ private: > float calculatePercentForFromTo(float percent) const; > unsigned calculateKeyTimesIndex(float percent) const; > >- void applyAnimatedValue(ShouldApplyAnimation, SVGElement* targetElement, const QualifiedName& attributeName, SVGAnimatedType*); >- void adjustForInheritance(SVGElement* targetElement, const QualifiedName& attributeName, String&); >- > void setCalcMode(const AtomicString&); > > bool m_animationValid { false }; >@@ -218,10 +140,9 @@ private: > Vector<UnitBezier> m_keySplines; > String m_lastValuesAnimationFrom; > String m_lastValuesAnimationTo; >- bool m_hasInvalidCSSAttributeType { false }; > CalcMode m_calcMode { CalcMode::Linear }; >- AnimationMode m_animationMode { NoAnimation }; >- AttributeOwnerProxy m_attributeOwnerProxy { *this }; >+ AnimationMode m_animationMode { AnimationMode::None }; >+ PropertyRegistry m_propertyRegistry { *this }; > }; > > } // namespace WebCore >diff --git a/Source/WebCore/svg/SVGMPathElement.cpp b/Source/WebCore/svg/SVGMPathElement.cpp >index 18e9dd516f3..af729f20dc7 100644 >--- a/Source/WebCore/svg/SVGMPathElement.cpp >+++ b/Source/WebCore/svg/SVGMPathElement.cpp >@@ -26,6 +26,7 @@ > #include "SVGDocumentExtensions.h" > #include "SVGNames.h" > #include "SVGPathElement.h" >+#include <wtf/IsoMallocInlines.h> > > namespace WebCore { > >@@ -55,7 +56,8 @@ void SVGMPathElement::buildPendingResource() > if (!isConnected()) > return; > >- auto target = SVGURIReference::targetElementFromIRIString(href(), treeScope()); >+ String href = this->href()->currentValue(); >+ auto target = SVGURIReference::targetElementFromIRIString(href, treeScope()); > if (!target.element) { > // Do not register as pending if we are already pending this resource. > if (document().accessSVGExtensions().isPendingResource(this, target.identifier)) >@@ -119,7 +121,7 @@ void SVGMPathElement::svgAttributeChanged(const QualifiedName& attrName) > SVGExternalResourcesRequired::svgAttributeChanged(attrName); > } > >-RefPtr<SVGPathElement> SVGMPathElement::pathElement() >+RefPtr<SVGPathElement> SVGMPathElement::pathElement() const > { > auto target = targetElementFromIRIString(href(), treeScope()); > if (is<SVGPathElement>(target.element)) >diff --git a/Source/WebCore/svg/SVGMPathElement.h b/Source/WebCore/svg/SVGMPathElement.h >index 39c9ea04518..f4a729d9952 100644 >--- a/Source/WebCore/svg/SVGMPathElement.h >+++ b/Source/WebCore/svg/SVGMPathElement.h >@@ -20,8 +20,6 @@ > > #pragma once > >-#include "SVGAnimatedBoolean.h" >-#include "SVGAnimatedString.h" > #include "SVGElement.h" > #include "SVGExternalResourcesRequired.h" > #include "SVGNames.h" >@@ -38,16 +36,16 @@ public: > > virtual ~SVGMPathElement(); > >- RefPtr<SVGPathElement> pathElement(); >+ RefPtr<SVGPathElement> pathElement() const; > > void targetPathChanged(); > > private: > SVGMPathElement(const QualifiedName&, Document&); > >- using AttributeOwnerProxy = SVGAttributeOwnerProxyImpl<SVGMPathElement, SVGElement, SVGExternalResourcesRequired, SVGURIReference>; >+ using PropertyRegistry = SVGPropertyOwnerRegistry<SVGMPathElement, SVGElement, SVGExternalResourcesRequired, SVGURIReference>; >+ const SVGPropertyRegistry& propertyRegistry() const final { return m_propertyRegistry; } > >- const SVGAttributeOwnerProxy& attributeOwnerProxy() const final { return m_attributeOwnerProxy; } > void parseAttribute(const QualifiedName&, const AtomicString&) final; > void svgAttributeChanged(const QualifiedName&) final; > >@@ -61,7 +59,7 @@ private: > > void notifyParentOfPathChange(ContainerNode*); > >- AttributeOwnerProxy m_attributeOwnerProxy { *this }; >+ PropertyRegistry m_propertyRegistry { *this }; > }; > > } // namespace WebCore
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 191237
:
353808
|
353812
|
353815
|
353817
|
353818
|
353820
|
353824
|
353825
|
355382
|
355386
|
355388
|
355393
|
355568
|
355574
|
355575
|
355577
|
355580
|
355582
|
355585
|
355666
|
355672
|
355693
|
355699
|
355711
|
355752
|
355777
|
355820
|
356333
|
356334
|
356338
|
356340
|
356342
|
356344
|
356346
|
356351
|
356352
|
356358
|
356360
|
356380
|
356497
|
356500
|
356507
|
356579
|
356607
|
356728
|
356729
|
356730
|
356731
|
356732
|
356733
|
356752
|
356810
|
356811
|
356879
|
356880
|
356881
|
356882
|
356883
|
356884
|
356885
|
356887
|
356888
|
356889
|
356892
|
356895
|
356896
|
359721
|
359735
|
359747
|
363581
|
363595
|
363613
|
363690
|
364172
|
364180
|
366512
|
366557
|
366636