Diff
Modified: trunk/Source/WebCore/ChangeLog (179259 => 179260)
--- trunk/Source/WebCore/ChangeLog 2015-01-28 17:54:27 UTC (rev 179259)
+++ trunk/Source/WebCore/ChangeLog 2015-01-28 17:59:50 UTC (rev 179260)
@@ -1,5 +1,167 @@
2015-01-28 Darin Adler <[email protected]>
+ Make SVGElement::instancesForElement point to elements in the shadow tree, not SVGElementInstance objects
+ https://bugs.webkit.org/show_bug.cgi?id=140984
+
+ Reviewed by Anders Carlsson.
+
+ Refactoring of code that is pretty well covered by existing tests, so
+ not adding new tests.
+
+ Inspired by work Rob Buis did in Blink:
+
+ http://src.chromium.org/viewvc/blink?view=revision&revision=173275
+
+ * page/EventHandler.cpp:
+ (WebCore::EventHandler::clear): Removed code to zero m_lastInstanceUnderMouse.
+ (WebCore::instanceAssociatedWithShadowTreeElement): Deleted.
+ (WebCore::EventHandler::updateMouseEventTargetNode): Removed code that used
+ m_lastInstanceUnderMouse to track events on an object after recloning.
+ This behavior doesn't seem to be needed to pass any existing tests, and Rob
+ removed it from Blink, so I'll take it out and we can bring if back, based
+ on the original element rather than on the SVGElementInstance, if we find we
+ need to restore the behavior in the future.
+
+ * page/EventHandler.h: Removed m_lastInstanceUnderMouse.
+
+ * svg/SVGAnimateElementBase.cpp:
+ (WebCore::SVGAnimateElementBase::determineAnimatedPropertyType):
+ Changed this function to take a reference and to call the updated version
+ of the targetElement.animatedPropertyTypesForAttribute function.
+ (WebCore::SVGAnimateElementBase::calculateAnimatedValue): Updated to pass
+ a reference rather than a pointer.
+ (WebCore::SVGAnimateElementBase::resetAnimatedType): Updated to pass
+ references rather than pointers.
+ (WebCore::applyCSSPropertyToTarget): Updated to take a reference.
+ (WebCore::removeCSSPropertyFromTarget): Ditto.
+ (WebCore::applyCSSPropertyToTargetAndInstances): Ditto. Also use a modern
+ for loop, and iterate over shadow tree instances, not over SVGElementInstance.
+ (WebCore::removeCSSPropertyFromTargetAndInstances): Ditto.
+ (WebCore::notifyTargetAboutAnimValChange): Ditto.
+ (WebCore::notifyTargetAndInstancesAboutAnimValChange): Ditto.
+ (WebCore::SVGAnimateElementBase::clearAnimatedType): More of the same.
+ (WebCore::SVGAnimateElementBase::applyResultsToTarget): Ditto.
+ (WebCore::SVGAnimateElementBase::resetAnimatedPropertyType): Ditto.
+
+ * svg/SVGAnimateElementBase.h: Changed determineAnimatedPropertyType to take
+ a reference rahter than a pointer.
+
+ * svg/SVGAnimateMotionElement.cpp:
+ (WebCore::SVGAnimateMotionElement::applyResultsToTarget): Updated to use the
+ new instances instead of SVGElementInstance. Also added code to skip work if
+ the transform is not changing, and use the assignment operator instead of
+ breaking one matrix down and calling setMatrix on the other.
+
+ * svg/SVGAnimatedTypeAnimator.cpp:
+ (WebCore::SVGAnimatedTypeAnimator::findAnimatedPropertiesForAttributeName):
+ Changed to take a reference rather than a pointer, and rewrote to streamline,
+ using modern for loops and using the new instances set.
+
+ * svg/SVGAnimatedTypeAnimator.h: Removed the constructors from the
+ SVGElementAnimatedProperties struct since we can build them just fine without
+ them. Changed findAnimatedPropertiesForAttributeName to take a reference.
+
+ * svg/SVGAnimationElement.cpp:
+ (WebCore::SVGAnimationElement::currentValuesForValuesAnimation): Pass a
+ reference rather than a pointer. Also streamlined the code a bit and removed
+ a comment that tried to say exactly what the code was doing, but was outdated.
+
+ * svg/SVGElement.cpp:
+ (WebCore::SVGElement::~SVGElement): Disconnect all instances from this element
+ and also disconnect the corresponding element from this element if it itself
+ is an instance. This guarantees we have no dangling pointers.
+ (WebCore::SVGElement::mapInstanceToElement): Deleted.
+ (WebCore::SVGElement::removeInstanceMapping): Deleted.
+ (WebCore::SVGElement::instances): Renamed from instancesForElement and changed
+ to be a set of SVG element instances in the shadow tree, rather than
+ SVGElementInstance objects.
+ (WebCore::SVGElement::correspondingElement): Tweaked assertion a little and use
+ nullptr instead of 0.
+ (WebCore::SVGElement::correspondingUseElement): Added. Finds the use element
+ that owns the shadow tree this element is in by following the host element
+ pointer from the shadow root.
+ (WebCore::SVGElement::setCorrespondingElement): Added code to insert or remove
+ this element from the instances set of the corresponding element.
+ (WebCore::SVGElement::animatedPropertyTypesForAttribute): Renamed from
+ animatedPropertyTypeForAttribute and switched to use a return value instead of
+ an out argument.
+ (WebCore::SVGElement::addEventListener): Updated to use instances rather than
+ the old instancesForElement.
+ (WebCore::SVGElement::removeEventListener): Ditto.
+ (WebCore::SVGElement::synchronizeAllAnimatedSVGAttribute): Pass a reference.
+ (WebCore::SVGElement::synchronizeAnimatedSVGAttribute): Ditto.
+ (WebCore::SVGElement::isPresentationAttributeWithSVGDOM): Updated to use the
+ new function from AttributeToPropertyMap.
+
+ * svg/SVGElement.h: Changed animatedPropertyTypesForAttribute name to be plural
+ since it returns a vector of types, and made it use a return value instead of
+ an out argument. Added the correspondingUseElement function, and removed the
+ mapInstanceToElement and removeInstanceMapping functions.
+
+ * svg/SVGElementInstance.cpp:
+ (WebCore::SVGElementInstance::SVGElementInstance): Removed now-unneeded call to
+ mapInstanceToElement. This is now handled entirely by the SVGElement itself.
+ (WebCore::SVGElementInstance::detach): Removed now-unneeded call to
+ removeInstanceMapping. This is now handled entirely by the SVGElement itself.
+ (WebCore::SVGElementInstance::invalidateAllInstancesOfElement): Rewrote to be
+ based on the instances set; logic is different now because we remove each
+ element from that set as we go.
+
+ * svg/SVGElementRareData.h:
+ (WebCore::SVGElementRareData::SVGElementRareData): Removed initialization of
+ pointers since we can do that where they are defined instead.
+ (WebCore::SVGElementRareData::instances): Renamed from elementInstances and
+ changed the type.
+ (WebCore::SVGElementRareData::destroyAnimatedSMILStyleProperties): Deleted.
+ Unneeded since it was already called just before deleting the rare data.
+
+ * svg/SVGTests.cpp:
+ (WebCore::SVGTests::SVGTests): Took advantage of using namespace.
+ (WebCore::createSVGTestPropertyInfo): Added. Helper for function below.
+ (WebCore::createSVGTextAttributeToPropertyMap): Ditto.
+ (WebCore::SVGTests::attributeToPropertyMap): Changed to use the create function
+ above. No longer allocates objects on the heap.
+ (WebCore::SVGTests::hasExtension): Reworked #if code to make the MathML part
+ independent rather than repeating the return statement.
+ (WebCore::SVGTests::synchronizeAttribute): Added. Helper for functions below.
+ (WebCore::SVGTests::synchronizeRequiredFeatures): Call synchronizeAttribute.
+ (WebCore::SVGTests::synchronizeRequiredExtensions): Ditto.
+ (WebCore::SVGTests::synchronizeSystemLanguage): Ditto.
+
+ * svg/SVGTests.h: Removed unneeded forward declarations. Mark the many functions
+ that do not depend on object state as static so the call sites don't wastefully
+ pass a this pointer. Removed the unneeded requiredFeaturesPropertyInfo,
+ requiredExtensionsPropertyInfo, and systemLanguagePropertyInfo functions.
+ Added synchronizeAttribute helper function.
+
+ * svg/SVGUseElement.cpp:
+ (WebCore::SVGUseElement::invalidateDependentShadowTrees): Updated to use the
+ new instances set and a modern for loop.
+
+ * svg/properties/SVGAnimatedPropertyMacros.h: Pass reference to addProperty and
+ made a few other small refinements.
+
+ * svg/properties/SVGAttributeToPropertyMap.cpp:
+ (WebCore::SVGAttributeToPropertyMap::addProperties): Fixed problems mentioned
+ in FIXME where we did too much hashing and vector resizing.
+ (WebCore::SVGAttributeToPropertyMap::addProperty): Streamlined to use a single
+ hash table lookup.
+ (WebCore::SVGAttributeToPropertyMap::properties): Renamed from
+ animatedPropertiesForAttribute and changed to return a vector rather than using
+ an out argument. Also had to change some since the vectors are in the hash table
+ now rather than allocated on the heap.
+ (WebCore::SVGAttributeToPropertyMap::types): Renamed from
+ animatedPropertyTypeForAttribute and made changes just like the ones above.
+ (WebCore::SVGAttributeToPropertyMap::synchronizeProperties): Use modern for
+ loops, take a reference rather than a pointer, and use the function pointer
+ directly instead of calling through a helper with various assertions.
+ (WebCore::SVGAttributeToPropertyMap::synchronizeProperty): Ditto.
+
+ * svg/properties/SVGAttributeToPropertyMap.h: Updated to match the changes
+ above. Also changed the map to contain vectors instead of pointers to vectors.
+
+2015-01-28 Darin Adler <[email protected]>
+
REGRESSION (r173698): Leaks of selector lists in CSS parsing
https://bugs.webkit.org/show_bug.cgi?id=140993
Modified: trunk/Source/WebCore/page/EventHandler.cpp (179259 => 179260)
--- trunk/Source/WebCore/page/EventHandler.cpp 2015-01-28 17:54:27 UTC (rev 179259)
+++ trunk/Source/WebCore/page/EventHandler.cpp 2015-01-28 17:59:50 UTC (rev 179260)
@@ -459,7 +459,6 @@
m_resizeLayer = nullptr;
m_elementUnderMouse = nullptr;
m_lastElementUnderMouse = nullptr;
- m_lastInstanceUnderMouse = nullptr;
m_lastMouseMoveEventSubframe = nullptr;
m_lastScrollbarUnderMouse = nullptr;
m_clickCount = 0;
@@ -2352,22 +2351,6 @@
return m_frame.document()->prepareMouseEvent(request, documentPointForWindowPoint(m_frame, mouseEvent.position()), mouseEvent);
}
-static inline SVGElementInstance* instanceAssociatedWithShadowTreeElement(Node* referenceNode)
-{
- if (!referenceNode || !referenceNode->isSVGElement())
- return nullptr;
-
- ShadowRoot* shadowRoot = referenceNode->containingShadowRoot();
- if (!shadowRoot)
- return nullptr;
-
- Element* shadowTreeParentElement = shadowRoot->hostElement();
- if (!shadowTreeParentElement || !shadowTreeParentElement->hasTagName(useTag))
- return nullptr;
-
- return downcast<SVGUseElement>(*shadowTreeParentElement).instanceForShadowTreeElement(referenceNode);
-}
-
static RenderElement* nearestCommonHoverAncestor(RenderElement* obj1, RenderElement* obj2)
{
if (!obj1 || !obj2)
@@ -2409,37 +2392,6 @@
m_elementUnderMouse = targetElement;
- // <use> shadow tree elements may have been recloned, update node under mouse in any case
- if (m_lastInstanceUnderMouse) {
- SVGElement* lastCorrespondingElement = m_lastInstanceUnderMouse->correspondingElement();
- SVGElement* lastCorrespondingUseElement = m_lastInstanceUnderMouse->correspondingUseElement();
-
- if (lastCorrespondingElement && lastCorrespondingUseElement) {
- HashSet<SVGElementInstance*> instances = lastCorrespondingElement->instancesForElement();
-
- // Locate the recloned shadow tree element for our corresponding instance
- HashSet<SVGElementInstance*>::iterator end = instances.end();
- for (HashSet<SVGElementInstance*>::iterator it = instances.begin(); it != end; ++it) {
- SVGElementInstance* instance = (*it);
- ASSERT(instance->correspondingElement() == lastCorrespondingElement);
-
- if (instance == m_lastInstanceUnderMouse)
- continue;
-
- if (instance->correspondingUseElement() != lastCorrespondingUseElement)
- continue;
-
- SVGElement* shadowTreeElement = instance->shadowTreeElement();
- if (!shadowTreeElement->inDocument() || m_lastElementUnderMouse == shadowTreeElement)
- continue;
-
- m_lastElementUnderMouse = shadowTreeElement;
- m_lastInstanceUnderMouse = instance;
- break;
- }
- }
- }
-
// Fire mouseout/mouseover if the mouse has shifted to a different node.
if (fireMouseOverOut) {
RenderLayer* layerForLastNode = layerForNode(m_lastElementUnderMouse.get());
@@ -2481,7 +2433,6 @@
if (m_lastElementUnderMouse && &m_lastElementUnderMouse->document() != m_frame.document()) {
m_lastElementUnderMouse = nullptr;
m_lastScrollbarUnderMouse = nullptr;
- m_lastInstanceUnderMouse = nullptr;
}
if (m_lastElementUnderMouse != m_elementUnderMouse) {
@@ -2539,7 +2490,6 @@
}
}
m_lastElementUnderMouse = m_elementUnderMouse;
- m_lastInstanceUnderMouse = instanceAssociatedWithShadowTreeElement(m_elementUnderMouse.get());
}
}
Modified: trunk/Source/WebCore/page/EventHandler.h (179259 => 179260)
--- trunk/Source/WebCore/page/EventHandler.h 2015-01-28 17:54:27 UTC (rev 179259)
+++ trunk/Source/WebCore/page/EventHandler.h 2015-01-28 17:59:50 UTC (rev 179260)
@@ -92,7 +92,6 @@
class RenderLayer;
class RenderWidget;
class ScrollableArea;
-class SVGElementInstance;
class Scrollbar;
class TextEvent;
class Touch;
@@ -488,7 +487,6 @@
#endif
bool m_svgPan;
- RefPtr<SVGElementInstance> m_lastInstanceUnderMouse;
RenderLayer* m_resizeLayer;
Modified: trunk/Source/WebCore/svg/SVGAnimateElementBase.cpp (179259 => 179260)
--- trunk/Source/WebCore/svg/SVGAnimateElementBase.cpp 2015-01-28 17:54:27 UTC (rev 179259)
+++ trunk/Source/WebCore/svg/SVGAnimateElementBase.cpp 2015-01-28 17:59:50 UTC (rev 179260)
@@ -55,12 +55,9 @@
return m_animatedPropertyType != AnimatedUnknown && !hasInvalidCSSAttributeType();
}
-AnimatedPropertyType SVGAnimateElementBase::determineAnimatedPropertyType(SVGElement* targetElement) const
+AnimatedPropertyType SVGAnimateElementBase::determineAnimatedPropertyType(SVGElement& targetElement) const
{
- ASSERT(targetElement);
-
- Vector<AnimatedPropertyType> propertyTypes;
- targetElement->animatedPropertyTypeForAttribute(attributeName(), propertyTypes);
+ auto propertyTypes = targetElement.animatedPropertyTypesForAttribute(attributeName());
if (propertyTypes.isEmpty())
return AnimatedUnknown;
@@ -77,7 +74,7 @@
// 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) {
+ if (targetElement.hasTagName(SVGNames::markerTag) && type == AnimatedAngle) {
ASSERT(propertyTypes.size() == 2);
ASSERT(propertyTypes[0] == AnimatedAngle);
ASSERT(propertyTypes[1] == AnimatedEnumeration);
@@ -94,7 +91,7 @@
if (!targetElement)
return;
- ASSERT(m_animatedPropertyType == determineAnimatedPropertyType(targetElement));
+ ASSERT(m_animatedPropertyType == determineAnimatedPropertyType(*targetElement));
ASSERT(percentage >= 0 && percentage <= 1);
ASSERT(m_animatedPropertyType != AnimatedTransformList || hasTagName(SVGNames::animateTransformTag));
@@ -196,6 +193,9 @@
ASSERT(m_animatedPropertyType == animator->type());
SVGElement* targetElement = this->targetElement();
+ if (!targetElement)
+ return;
+
const QualifiedName& attributeName = this->attributeName();
ShouldApplyAnimation shouldApply = shouldApplyAnimation(targetElement, attributeName);
@@ -204,7 +204,7 @@
if (shouldApply == ApplyXMLAnimation || shouldApply == ApplyXMLandCSSAnimation) {
// SVG DOM animVal animation code-path.
- m_animatedProperties = animator->findAnimatedPropertiesForAttributeName(targetElement, attributeName);
+ m_animatedProperties = animator->findAnimatedPropertiesForAttributeName(*targetElement, attributeName);
if (m_animatedProperties.isEmpty())
return;
@@ -233,85 +233,72 @@
m_animatedType->setValueAsString(attributeName, baseValue);
}
-static inline void applyCSSPropertyToTarget(SVGElement* targetElement, CSSPropertyID id, const String& value)
+static inline void applyCSSPropertyToTarget(SVGElement& targetElement, CSSPropertyID id, const String& value)
{
- ASSERT(!targetElement->m_deletionHasBegun);
+ ASSERT(!targetElement.m_deletionHasBegun);
- if (!targetElement->ensureAnimatedSMILStyleProperties().setProperty(id, value, false, 0))
+ if (!targetElement.ensureAnimatedSMILStyleProperties().setProperty(id, value, false, 0))
return;
- targetElement->setNeedsStyleRecalc(SyntheticStyleChange);
+ targetElement.setNeedsStyleRecalc(SyntheticStyleChange);
}
-static inline void removeCSSPropertyFromTarget(SVGElement* targetElement, CSSPropertyID id)
+static inline void removeCSSPropertyFromTarget(SVGElement& targetElement, CSSPropertyID id)
{
- ASSERT(!targetElement->m_deletionHasBegun);
- targetElement->ensureAnimatedSMILStyleProperties().removeProperty(id);
- targetElement->setNeedsStyleRecalc(SyntheticStyleChange);
+ ASSERT(!targetElement.m_deletionHasBegun);
+ targetElement.ensureAnimatedSMILStyleProperties().removeProperty(id);
+ targetElement.setNeedsStyleRecalc(SyntheticStyleChange);
}
-static inline void applyCSSPropertyToTargetAndInstances(SVGElement* targetElement, const QualifiedName& attributeName, const String& valueAsString)
+static inline void applyCSSPropertyToTargetAndInstances(SVGElement& targetElement, const QualifiedName& attributeName, const String& valueAsString)
{
- ASSERT(targetElement);
- if (attributeName == anyQName() || !targetElement->inDocument() || !targetElement->parentNode())
+ // FIXME: Do we really need to check both inDocument and !parentNode?
+ if (attributeName == anyQName() || !targetElement.inDocument() || !targetElement.parentNode())
return;
CSSPropertyID id = cssPropertyID(attributeName.localName());
- SVGElementInstance::InstanceUpdateBlocker blocker(targetElement);
+ SVGElementInstance::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.
- const HashSet<SVGElementInstance*>& instances = targetElement->instancesForElement();
- const HashSet<SVGElementInstance*>::const_iterator end = instances.end();
- for (HashSet<SVGElementInstance*>::const_iterator it = instances.begin(); it != end; ++it) {
- if (SVGElement* shadowTreeElement = (*it)->shadowTreeElement())
- applyCSSPropertyToTarget(shadowTreeElement, id, valueAsString);
- }
+ for (auto* instance : targetElement.instances())
+ applyCSSPropertyToTarget(*instance, id, valueAsString);
}
-static inline void removeCSSPropertyFromTargetAndInstances(SVGElement* targetElement, const QualifiedName& attributeName)
+static inline void removeCSSPropertyFromTargetAndInstances(SVGElement& targetElement, const QualifiedName& attributeName)
{
- ASSERT(targetElement);
- if (attributeName == anyQName() || !targetElement->inDocument() || !targetElement->parentNode())
+ // FIXME: Do we really need to check both inDocument and !parentNode?
+ if (attributeName == anyQName() || !targetElement.inDocument() || !targetElement.parentNode())
return;
CSSPropertyID id = cssPropertyID(attributeName.localName());
- SVGElementInstance::InstanceUpdateBlocker blocker(targetElement);
+ SVGElementInstance::InstanceUpdateBlocker blocker(&targetElement);
removeCSSPropertyFromTarget(targetElement, id);
// If the target element has instances, update them as well, w/o requiring the <use> tree to be rebuilt.
- const HashSet<SVGElementInstance*>& instances = targetElement->instancesForElement();
- const HashSet<SVGElementInstance*>::const_iterator end = instances.end();
- for (HashSet<SVGElementInstance*>::const_iterator it = instances.begin(); it != end; ++it) {
- if (SVGElement* shadowTreeElement = (*it)->shadowTreeElement())
- removeCSSPropertyFromTarget(shadowTreeElement, id);
- }
+ for (auto* instance : targetElement.instances())
+ removeCSSPropertyFromTarget(*instance, id);
}
-static inline void notifyTargetAboutAnimValChange(SVGElement* targetElement, const QualifiedName& attributeName)
+static inline void notifyTargetAboutAnimValChange(SVGElement& targetElement, const QualifiedName& attributeName)
{
- ASSERT(!targetElement->m_deletionHasBegun);
- targetElement->svgAttributeChanged(attributeName);
+ ASSERT(!targetElement.m_deletionHasBegun);
+ targetElement.svgAttributeChanged(attributeName);
}
-static inline void notifyTargetAndInstancesAboutAnimValChange(SVGElement* targetElement, const QualifiedName& attributeName)
+static inline void notifyTargetAndInstancesAboutAnimValChange(SVGElement& targetElement, const QualifiedName& attributeName)
{
- ASSERT(targetElement);
- if (attributeName == anyQName() || !targetElement->inDocument() || !targetElement->parentNode())
+ if (attributeName == anyQName() || !targetElement.inDocument() || !targetElement.parentNode())
return;
- SVGElementInstance::InstanceUpdateBlocker blocker(targetElement);
+ SVGElementInstance::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.
- const HashSet<SVGElementInstance*>& instances = targetElement->instancesForElement();
- const HashSet<SVGElementInstance*>::const_iterator end = instances.end();
- for (HashSet<SVGElementInstance*>::const_iterator it = instances.begin(); it != end; ++it) {
- if (SVGElement* shadowTreeElement = (*it)->shadowTreeElement())
- notifyTargetAboutAnimValChange(shadowTreeElement, attributeName);
- }
+ for (auto* instance : targetElement.instances())
+ notifyTargetAboutAnimValChange(*instance, attributeName);
}
void SVGAnimateElementBase::clearAnimatedType(SVGElement* targetElement)
@@ -326,19 +313,19 @@
if (m_animatedProperties.isEmpty()) {
// CSS properties animation code-path.
- removeCSSPropertyFromTargetAndInstances(targetElement, attributeName());
+ removeCSSPropertyFromTargetAndInstances(*targetElement, attributeName());
m_animatedType = nullptr;
return;
}
ShouldApplyAnimation shouldApply = shouldApplyAnimation(targetElement, attributeName());
if (shouldApply == ApplyXMLandCSSAnimation)
- removeCSSPropertyFromTargetAndInstances(targetElement, attributeName());
+ removeCSSPropertyFromTargetAndInstances(*targetElement, attributeName());
// SVG DOM animVal animation code-path.
if (m_animator) {
m_animator->stopAnimValAnimation(m_animatedProperties);
- notifyTargetAndInstancesAboutAnimValChange(targetElement, attributeName());
+ notifyTargetAndInstancesAboutAnimValChange(*targetElement, attributeName());
}
m_animatedProperties.clear();
@@ -351,29 +338,32 @@
ASSERT(m_animatedPropertyType != AnimatedUnknown);
ASSERT(m_animator);
- // Early exit if our animated type got destructed by a previous endedActiveInterval().
+ // Early exit if our animated type got destroyed by a previous endedActiveInterval().
if (!m_animatedType)
return;
SVGElement* targetElement = 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());
+ applyCSSPropertyToTargetAndInstances(*targetElement, attributeName, m_animatedType->valueAsString());
return;
}
// We do update the style and the animation property independent of each other.
ShouldApplyAnimation shouldApply = shouldApplyAnimation(targetElement, attributeName);
if (shouldApply == ApplyXMLandCSSAnimation)
- applyCSSPropertyToTargetAndInstances(targetElement, attributeName, m_animatedType->valueAsString());
+ 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);
+ notifyTargetAndInstancesAboutAnimValChange(*targetElement, attributeName);
}
bool SVGAnimateElementBase::animatedPropertyTypeSupportsAddition() const
@@ -445,7 +435,7 @@
m_toType = nullptr;
m_toAtEndOfDurationType = nullptr;
m_animator = nullptr;
- m_animatedPropertyType = targetElement() ? determineAnimatedPropertyType(targetElement()) : AnimatedString;
+ m_animatedPropertyType = targetElement() ? determineAnimatedPropertyType(*targetElement()) : AnimatedString;
}
SVGAnimatedTypeAnimator* SVGAnimateElementBase::ensureAnimator()
Modified: trunk/Source/WebCore/svg/SVGAnimateElementBase.h (179259 => 179260)
--- trunk/Source/WebCore/svg/SVGAnimateElementBase.h 2015-01-28 17:54:27 UTC (rev 179259)
+++ trunk/Source/WebCore/svg/SVGAnimateElementBase.h 2015-01-28 17:59:50 UTC (rev 179260)
@@ -35,7 +35,7 @@
public:
virtual ~SVGAnimateElementBase();
- AnimatedPropertyType determineAnimatedPropertyType(SVGElement*) const;
+ AnimatedPropertyType determineAnimatedPropertyType(SVGElement&) const;
protected:
SVGAnimateElementBase(const QualifiedName&, Document&);
Modified: trunk/Source/WebCore/svg/SVGAnimateMotionElement.cpp (179259 => 179260)
--- trunk/Source/WebCore/svg/SVGAnimateMotionElement.cpp 2015-01-28 17:54:27 UTC (rev 179259)
+++ trunk/Source/WebCore/svg/SVGAnimateMotionElement.cpp 2015-01-28 17:59:50 UTC (rev 179260)
@@ -293,19 +293,17 @@
if (RenderElement* renderer = targetElement->renderer())
RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer);
- AffineTransform* t = targetElement->supplementalTransform();
- if (!t)
+ AffineTransform* targetSupplementalTransform = targetElement->supplementalTransform();
+ if (!targetSupplementalTransform)
return;
// ...except in case where we have additional instances in <use> trees.
- for (auto* instance : targetElement->instancesForElement()) {
- SVGElement* shadowTreeElement = instance->shadowTreeElement();
- ASSERT(shadowTreeElement);
- AffineTransform* transform = shadowTreeElement->supplementalTransform();
- if (!transform)
+ for (auto* instance : targetElement->instances()) {
+ AffineTransform* transform = instance->supplementalTransform();
+ if (!transform || *transform == *targetSupplementalTransform)
continue;
- transform->setMatrix(t->a(), t->b(), t->c(), t->d(), t->e(), t->f());
- if (RenderElement* renderer = shadowTreeElement->renderer()) {
+ *transform = *targetSupplementalTransform;
+ if (RenderElement* renderer = instance->renderer()) {
renderer->setNeedsTransformUpdate();
RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer);
}
Modified: trunk/Source/WebCore/svg/SVGAnimatedTypeAnimator.cpp (179259 => 179260)
--- trunk/Source/WebCore/svg/SVGAnimatedTypeAnimator.cpp 2015-01-28 17:54:27 UTC (rev 179259)
+++ trunk/Source/WebCore/svg/SVGAnimatedTypeAnimator.cpp 2015-01-28 17:59:50 UTC (rev 179260)
@@ -27,15 +27,6 @@
namespace WebCore {
-SVGElementAnimatedProperties::SVGElementAnimatedProperties()
- : element(0)
-{ }
-
-SVGElementAnimatedProperties::SVGElementAnimatedProperties(SVGElement* element, Vector<RefPtr<SVGAnimatedProperty>>& properties)
- : element(element)
- , properties(properties)
-{ }
-
SVGAnimatedTypeAnimator::SVGAnimatedTypeAnimator(AnimatedPropertyType type, SVGAnimationElement* animationElement, SVGElement* contextElement)
: m_type(type)
, m_animationElement(animationElement)
@@ -44,7 +35,8 @@
}
SVGAnimatedTypeAnimator::~SVGAnimatedTypeAnimator()
-{ }
+{
+}
void SVGAnimatedTypeAnimator::calculateFromAndToValues(std::unique_ptr<SVGAnimatedType>& from, std::unique_ptr<SVGAnimatedType>& to, const String& fromString, const String& toString)
{
@@ -59,41 +51,27 @@
addAnimatedTypes(from.get(), to.get());
}
-SVGElementAnimatedPropertyList SVGAnimatedTypeAnimator::findAnimatedPropertiesForAttributeName(SVGElement* targetElement, const QualifiedName& attributeName)
+SVGElementAnimatedPropertyList SVGAnimatedTypeAnimator::findAnimatedPropertiesForAttributeName(SVGElement& targetElement, const QualifiedName& attributeName)
{
- ASSERT(targetElement);
+ SVGElementAnimatedPropertyList result;
- SVGElementAnimatedPropertyList propertiesByInstance;
+ if (!SVGAnimatedType::supportsAnimVal(m_type))
+ return result;
- Vector<RefPtr<SVGAnimatedProperty>> targetProperties;
- targetElement->localAttributeToPropertyMap().animatedPropertiesForAttribute(targetElement, attributeName, targetProperties);
+ auto& propertyMap = targetElement.localAttributeToPropertyMap();
+ auto targetProperties = propertyMap.properties(targetElement, attributeName);
- if (!SVGAnimatedType::supportsAnimVal(m_type) || targetProperties.isEmpty())
- return SVGElementAnimatedPropertyList();
+ if (targetProperties.isEmpty())
+ return result;
- SVGElementAnimatedProperties propertiesPair(targetElement, targetProperties);
- propertiesByInstance.append(propertiesPair);
+ result.append(SVGElementAnimatedProperties { &targetElement, WTF::move(targetProperties) });
- const HashSet<SVGElementInstance*>& instances = targetElement->instancesForElement();
- const HashSet<SVGElementInstance*>::const_iterator end = instances.end();
- for (HashSet<SVGElementInstance*>::const_iterator it = instances.begin(); it != end; ++it) {
- SVGElement* shadowTreeElement = (*it)->shadowTreeElement();
- if (!shadowTreeElement)
- continue;
+ for (SVGElement* instance : targetElement.instances())
+ result.append(SVGElementAnimatedProperties { instance, propertyMap.properties(*instance, attributeName) });
- Vector<RefPtr<SVGAnimatedProperty>> instanceProperties;
- targetElement->localAttributeToPropertyMap().animatedPropertiesForAttribute(shadowTreeElement, attributeName, instanceProperties);
-
- SVGElementAnimatedProperties instancePropertiesPair(shadowTreeElement, instanceProperties);
- propertiesByInstance.append(instancePropertiesPair);
- }
-
#if !ASSERT_DISABLED
- SVGElementAnimatedPropertyList::const_iterator propertiesEnd = propertiesByInstance.end();
- for (SVGElementAnimatedPropertyList::const_iterator it = propertiesByInstance.begin(); it != propertiesEnd; ++it) {
- size_t propertiesSize = it->properties.size();
- for (size_t i = 0; i < propertiesSize; ++i) {
- RefPtr<SVGAnimatedProperty> property = it->properties[i];
+ for (auto& animatedProperties : result) {
+ for (auto& property : animatedProperties.properties) {
if (property->animatedPropertyType() != m_type) {
ASSERT(m_type == AnimatedAngle);
ASSERT(property->animatedPropertyType() == AnimatedEnumeration);
@@ -102,7 +80,7 @@
}
#endif
- return propertiesByInstance;
+ return result;
}
} // namespace WebCore
Modified: trunk/Source/WebCore/svg/SVGAnimatedTypeAnimator.h (179259 => 179260)
--- trunk/Source/WebCore/svg/SVGAnimatedTypeAnimator.h 2015-01-28 17:54:27 UTC (rev 179259)
+++ trunk/Source/WebCore/svg/SVGAnimatedTypeAnimator.h 2015-01-28 17:59:50 UTC (rev 179260)
@@ -29,10 +29,6 @@
namespace WebCore {
struct SVGElementAnimatedProperties {
- SVGElementAnimatedProperties();
-
- SVGElementAnimatedProperties(SVGElement*, Vector<RefPtr<SVGAnimatedProperty>>&);
-
SVGElement* element;
Vector<RefPtr<SVGAnimatedProperty>> properties;
};
@@ -62,7 +58,7 @@
void setContextElement(SVGElement* contextElement) { m_contextElement = contextElement; }
AnimatedPropertyType type() const { return m_type; }
- SVGElementAnimatedPropertyList findAnimatedPropertiesForAttributeName(SVGElement*, const QualifiedName&);
+ SVGElementAnimatedPropertyList findAnimatedPropertiesForAttributeName(SVGElement&, const QualifiedName&);
protected:
SVGAnimatedTypeAnimator(AnimatedPropertyType, SVGAnimationElement*, SVGElement*);
Modified: trunk/Source/WebCore/svg/SVGAnimationElement.cpp (179259 => 179260)
--- trunk/Source/WebCore/svg/SVGAnimationElement.cpp 2015-01-28 17:54:27 UTC (rev 179259)
+++ trunk/Source/WebCore/svg/SVGAnimationElement.cpp 2015-01-28 17:59:50 UTC (rev 179260)
@@ -508,12 +508,9 @@
CalcMode calcMode = this->calcMode();
if (is<SVGAnimateElement>(*this) || is<SVGAnimateColorElement>(*this)) {
- AnimatedPropertyType attributeType = downcast<SVGAnimateElementBase>(*this).determineAnimatedPropertyType(targetElement());
- // Fall back to discrete animations for Strings.
- if (attributeType == AnimatedBoolean
- || attributeType == AnimatedEnumeration
- || attributeType == AnimatedPreserveAspectRatio
- || attributeType == AnimatedString)
+ ASSERT(targetElement());
+ AnimatedPropertyType type = downcast<SVGAnimateElementBase>(*this).determineAnimatedPropertyType(*targetElement());
+ if (type == AnimatedBoolean || type == AnimatedEnumeration || type == AnimatedPreserveAspectRatio || type == AnimatedString)
calcMode = CalcModeDiscrete;
}
if (!m_keyPoints.isEmpty() && calcMode != CalcModePaced)
Modified: trunk/Source/WebCore/svg/SVGElement.cpp (179259 => 179260)
--- trunk/Source/WebCore/svg/SVGElement.cpp 2015-01-28 17:54:27 UTC (rev 179259)
+++ trunk/Source/WebCore/svg/SVGElement.cpp 2015-01-28 17:59:50 UTC (rev 179260)
@@ -281,11 +281,14 @@
SVGElement::~SVGElement()
{
if (m_svgRareData) {
- m_svgRareData->destroyAnimatedSMILStyleProperties();
+ for (SVGElement* instance : m_svgRareData->instances())
+ instance->m_svgRareData->setCorrespondingElement(nullptr);
if (SVGCursorElement* cursorElement = m_svgRareData->cursorElement())
cursorElement->removeClient(this);
if (CSSCursorImageValue* cursorImageValue = m_svgRareData->cursorImageValue())
cursorImageValue->removeReferencedElement(this);
+ if (SVGElement* correspondingElement = m_svgRareData->correspondingElement())
+ correspondingElement->m_svgRareData->instances().remove(this);
m_svgRareData = nullptr;
}
@@ -420,34 +423,13 @@
return nullptr;
}
-void SVGElement::mapInstanceToElement(SVGElementInstance* instance)
+const HashSet<SVGElement*>& SVGElement::instances() const
{
- ASSERT(instance);
-
- HashSet<SVGElementInstance*>& instances = ensureSVGRareData().elementInstances();
- ASSERT(!instances.contains(instance));
-
- instances.add(instance);
-}
-
-void SVGElement::removeInstanceMapping(SVGElementInstance* instance)
-{
- ASSERT(instance);
- ASSERT(m_svgRareData);
-
- HashSet<SVGElementInstance*>& instances = m_svgRareData->elementInstances();
- ASSERT(instances.contains(instance));
-
- instances.remove(instance);
-}
-
-const HashSet<SVGElementInstance*>& SVGElement::instancesForElement() const
-{
if (!m_svgRareData) {
- static NeverDestroyed<HashSet<SVGElementInstance*>> emptyInstances;
+ static NeverDestroyed<HashSet<SVGElement*>> emptyInstances;
return emptyInstances;
}
- return m_svgRareData->elementInstances();
+ return m_svgRareData->instances();
}
bool SVGElement::getBoundingBox(FloatRect& rect, SVGLocatable::StyleUpdateStrategy styleUpdateStrategy)
@@ -495,13 +477,32 @@
SVGElement* SVGElement::correspondingElement()
{
- ASSERT(!m_svgRareData || !m_svgRareData->correspondingElement() || containingShadowRoot());
- return m_svgRareData ? m_svgRareData->correspondingElement() : 0;
+ ASSERT(!m_svgRareData || !m_svgRareData->correspondingElement() || correspondingUseElement());
+ return m_svgRareData ? m_svgRareData->correspondingElement() : nullptr;
}
+SVGUseElement* SVGElement::correspondingUseElement() const
+{
+ auto* root = containingShadowRoot();
+ if (!root)
+ return nullptr;
+ if (root->type() != ShadowRoot::UserAgentShadowRoot)
+ return nullptr;
+ auto* host = root->hostElement();
+ if (!is<SVGUseElement>(host))
+ return nullptr;
+ return &downcast<SVGUseElement>(*host);
+}
+
void SVGElement::setCorrespondingElement(SVGElement* correspondingElement)
{
+ if (m_svgRareData) {
+ if (SVGElement* oldCorrespondingElement = m_svgRareData->correspondingElement())
+ oldCorrespondingElement->m_svgRareData->instances().remove(this);
+ }
ensureSVGRareData().setCorrespondingElement(correspondingElement);
+ if (correspondingElement)
+ correspondingElement->ensureSVGRareData().instances().add(this);
}
void SVGElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
@@ -533,23 +534,31 @@
}
}
-void SVGElement::animatedPropertyTypeForAttribute(const QualifiedName& attributeName, Vector<AnimatedPropertyType>& propertyTypes)
+Vector<AnimatedPropertyType> SVGElement::animatedPropertyTypesForAttribute(const QualifiedName& attributeName)
{
- localAttributeToPropertyMap().animatedPropertyTypeForAttribute(attributeName, propertyTypes);
- if (!propertyTypes.isEmpty())
- return;
+ auto types = localAttributeToPropertyMap().types(attributeName);
+ if (!types.isEmpty())
+ return types;
- auto& map = attributeNameToAnimatedPropertyTypeMap();
- auto it = map.find(attributeName.impl());
- if (it != map.end()) {
- propertyTypes.append(it->value);
- return;
+ {
+ auto& map = attributeNameToAnimatedPropertyTypeMap();
+ auto it = map.find(attributeName.impl());
+ if (it != map.end()) {
+ types.append(it->value);
+ return types;
+ }
}
- auto& cssPropertyWithSVGDOMMap = cssPropertyWithSVGDOMNameToAnimatedPropertyTypeMap();
- auto svgPropertyIterator = cssPropertyWithSVGDOMMap.find(attributeName.impl());
- if (svgPropertyIterator != cssPropertyWithSVGDOMMap.end())
- propertyTypes.append(svgPropertyIterator->value);
+ {
+ auto& map = cssPropertyWithSVGDOMNameToAnimatedPropertyTypeMap();
+ auto it = map.find(attributeName.impl());
+ if (it != map.end()) {
+ types.append(it->value);
+ return types;
+ }
+ }
+
+ return types;
}
bool SVGElement::haveLoadedRequiredResources()
@@ -574,11 +583,9 @@
// Add event listener to all shadow tree DOM element instances
ASSERT(!instanceUpdatesBlocked());
- for (auto& instance : instancesForElement()) {
- ASSERT(instance->shadowTreeElement());
+ for (auto* instance : instances()) {
ASSERT(instance->correspondingElement() == this);
-
- bool result = instance->shadowTreeElement()->Node::addEventListener(eventType, listener, useCapture);
+ bool result = instance->Node::addEventListener(eventType, listener, useCapture);
ASSERT_UNUSED(result, result);
}
@@ -603,13 +610,10 @@
// Remove event listener from all shadow tree DOM element instances
ASSERT(!instanceUpdatesBlocked());
- for (auto& instance : instancesForElement()) {
+ for (auto& instance : instances()) {
ASSERT(instance->correspondingElement() == this);
- SVGElement* shadowTreeElement = instance->shadowTreeElement();
- ASSERT(shadowTreeElement);
-
- if (shadowTreeElement->Node::removeEventListener(eventType, listener, useCapture))
+ if (instance->Node::removeEventListener(eventType, listener, useCapture))
continue;
// This case can only be hit for event listeners created from markup
@@ -620,11 +624,9 @@
// has been created (read: it's not 0 anymore). During shadow tree creation, the event
// listener DOM attribute has been cloned, and another event listener has been setup in
// the shadow tree. If that event listener has not been used yet, m_jsFunction is still 0,
- // and tryRemoveEventListener() above will fail. Work around that very seldom problem.
- EventTargetData* data = ""
- ASSERT(data);
-
- data->eventListenerMap.removeFirstEventListenerCreatedFromMarkup(eventType);
+ // and tryRemoveEventListener() above will fail. Work around that very rare problem.
+ ASSERT(instance->eventTargetData());
+ instance->eventTargetData()->eventListenerMap.removeFirstEventListenerCreatedFromMarkup(eventType);
}
return true;
@@ -754,7 +756,7 @@
ASSERT(svgElement->elementData());
ASSERT(svgElement->elementData()->animatedSVGAttributesAreDirty());
- svgElement->localAttributeToPropertyMap().synchronizeProperties(svgElement);
+ svgElement->localAttributeToPropertyMap().synchronizeProperties(*svgElement);
svgElement->elementData()->setAnimatedSVGAttributesAreDirty(false);
}
@@ -767,7 +769,7 @@
if (name == anyQName())
synchronizeAllAnimatedSVGAttribute(nonConstThis);
else
- nonConstThis->localAttributeToPropertyMap().synchronizeProperty(nonConstThis, name);
+ nonConstThis->localAttributeToPropertyMap().synchronizeProperty(*nonConstThis, name);
}
void SVGElement::synchronizeRequiredFeatures(SVGElement* contextElement)
@@ -1016,9 +1018,7 @@
bool SVGElement::isPresentationAttributeWithSVGDOM(const QualifiedName& attributeName)
{
- Vector<AnimatedPropertyType> propertyTypes;
- localAttributeToPropertyMap().animatedPropertyTypeForAttribute(attributeName, propertyTypes);
- return !propertyTypes.isEmpty();
+ return !localAttributeToPropertyMap().types(attributeName).isEmpty();
}
bool SVGElement::isPresentationAttribute(const QualifiedName& name) const
Modified: trunk/Source/WebCore/svg/SVGElement.h (179259 => 179260)
--- trunk/Source/WebCore/svg/SVGElement.h 2015-01-28 17:54:27 UTC (rev 179259)
+++ trunk/Source/WebCore/svg/SVGElement.h 2015-01-28 17:59:50 UTC (rev 179260)
@@ -49,6 +49,7 @@
class SVGElementInstance;
class SVGElementRareData;
class SVGSVGElement;
+class SVGUseElement;
void mapAttributeToCSSProperty(HashMap<AtomicStringImpl*, CSSPropertyID>* propertyNameToIdMap, const QualifiedName& attrName);
@@ -85,7 +86,7 @@
virtual void svgAttributeChanged(const QualifiedName&);
- void animatedPropertyTypeForAttribute(const QualifiedName&, Vector<AnimatedPropertyType>&);
+ Vector<AnimatedPropertyType> animatedPropertyTypesForAttribute(const QualifiedName&);
void sendSVGLoadEventIfPossible(bool sendParentLoadEvents = false);
void sendSVGLoadEventIfPossibleAsynchronously();
@@ -102,7 +103,8 @@
setNeedsStyleRecalc(InlineStyleChange);
}
- const HashSet<SVGElementInstance*>& instancesForElement() const;
+ // The instances of an element are clones made in shadow trees to implement <use>.
+ const HashSet<SVGElement*>& instances() const;
bool getBoundingBox(FloatRect&, SVGLocatable::StyleUpdateStrategy = SVGLocatable::AllowStyleUpdate);
@@ -112,6 +114,8 @@
void cursorImageValueRemoved();
SVGElement* correspondingElement();
+ SVGUseElement* correspondingUseElement() const;
+
void setCorrespondingElement(SVGElement*);
void synchronizeAnimatedSVGAttribute(const QualifiedName&) const;
@@ -189,9 +193,6 @@
virtual void clearTarget() { }
- void mapInstanceToElement(SVGElementInstance*);
- void removeInstanceMapping(SVGElementInstance*);
-
void buildPendingResourcesIfNeeded();
virtual void accessKeyAction(bool sendMouseEvents) override;
Modified: trunk/Source/WebCore/svg/SVGElementInstance.cpp (179259 => 179260)
--- trunk/Source/WebCore/svg/SVGElementInstance.cpp 2015-01-28 17:54:27 UTC (rev 179259)
+++ trunk/Source/WebCore/svg/SVGElementInstance.cpp 2015-01-28 17:59:50 UTC (rev 179260)
@@ -101,9 +101,6 @@
ASSERT(m_correspondingUseElement);
ASSERT(m_element);
- // Register as instance for passed element.
- m_element->mapInstanceToElement(this);
-
#ifndef NDEBUG
instanceCounter.increment();
#endif
@@ -144,9 +141,6 @@
for (SVGElementInstance* node = firstChild(); node; node = node->nextSibling())
node->detach();
- // Deregister as instance for passed element, if we haven't already.
- if (m_element->instancesForElement().contains(this))
- m_element->removeInstanceMapping(this);
// DO NOT clear ref to m_element because _javascript_Core uses it for garbage collection
m_shadowTreeElement = 0;
@@ -181,24 +175,19 @@
if (element->instanceUpdatesBlocked())
return;
- const HashSet<SVGElementInstance*>& set = element->instancesForElement();
- if (set.isEmpty())
+ auto& instances = element->instances();
+ if (instances.isEmpty())
return;
// Mark all use elements referencing 'element' for rebuilding
- const HashSet<SVGElementInstance*>::const_iterator end = set.end();
- for (HashSet<SVGElementInstance*>::const_iterator it = set.begin(); it != end; ++it) {
- ASSERT((*it)->shadowTreeElement());
- ASSERT((*it)->shadowTreeElement()->correspondingElement());
- ASSERT((*it)->shadowTreeElement()->correspondingElement() == (*it)->correspondingElement());
- ASSERT((*it)->correspondingElement() == element);
- (*it)->shadowTreeElement()->setCorrespondingElement(0);
-
- if (SVGUseElement* element = (*it)->correspondingUseElement()) {
+ do {
+ SVGElement* instance = *instances.begin();
+ if (SVGUseElement* element = instance->correspondingUseElement()) {
ASSERT(element->inDocument());
element->invalidateShadowTree();
}
- }
+ instance->setCorrespondingElement(nullptr);
+ } while (!instances.isEmpty());
element->document().updateStyleIfNeeded();
}
Modified: trunk/Source/WebCore/svg/SVGElementRareData.h (179259 => 179260)
--- trunk/Source/WebCore/svg/SVGElementRareData.h 2015-01-28 17:54:27 UTC (rev 179259)
+++ trunk/Source/WebCore/svg/SVGElementRareData.h 2015-01-28 17:59:50 UTC (rev 179260)
@@ -31,23 +31,19 @@
class CSSCursorImageValue;
class SVGCursorElement;
class SVGElement;
-class SVGElementInstance;
class SVGElementRareData {
WTF_MAKE_NONCOPYABLE(SVGElementRareData); WTF_MAKE_FAST_ALLOCATED;
public:
SVGElementRareData()
- : m_cursorElement(0)
- , m_cursorImageValue(0)
- , m_correspondingElement(0)
- , m_instancesUpdatesBlocked(false)
+ : m_instancesUpdatesBlocked(false)
, m_useOverrideComputedStyle(false)
, m_needsOverrideComputedStyleUpdate(false)
{
}
- HashSet<SVGElementInstance*>& elementInstances() { return m_elementInstances; }
- const HashSet<SVGElementInstance*>& elementInstances() const { return m_elementInstances; }
+ HashSet<SVGElement*>& instances() { return m_instances; }
+ const HashSet<SVGElement*>& instances() const { return m_instances; }
bool instanceUpdatesBlocked() const { return m_instancesUpdatesBlocked; }
void setInstanceUpdatesBlocked(bool value) { m_instancesUpdatesBlocked = value; }
@@ -69,11 +65,6 @@
return *m_animatedSMILStyleProperties;
}
- void destroyAnimatedSMILStyleProperties()
- {
- m_animatedSMILStyleProperties.clear();
- }
-
RenderStyle* overrideComputedStyle(Element* element, RenderStyle* parentStyle)
{
ASSERT(element);
@@ -93,10 +84,10 @@
void setNeedsOverrideComputedStyleUpdate() { m_needsOverrideComputedStyleUpdate = true; }
private:
- HashSet<SVGElementInstance*> m_elementInstances;
- SVGCursorElement* m_cursorElement;
- CSSCursorImageValue* m_cursorImageValue;
- SVGElement* m_correspondingElement;
+ HashSet<SVGElement*> m_instances;
+ SVGCursorElement* m_cursorElement { nullptr };
+ CSSCursorImageValue* m_cursorImageValue { nullptr };
+ SVGElement* m_correspondingElement { nullptr };
bool m_instancesUpdatesBlocked : 1;
bool m_useOverrideComputedStyle : 1;
bool m_needsOverrideComputedStyleUpdate : 1;
Modified: trunk/Source/WebCore/svg/SVGTests.cpp (179259 => 179260)
--- trunk/Source/WebCore/svg/SVGTests.cpp 2015-01-28 17:54:27 UTC (rev 179259)
+++ trunk/Source/WebCore/svg/SVGTests.cpp 2015-01-28 17:59:50 UTC (rev 179260)
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <[email protected]>
* Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <[email protected]>
+ * Copyright (C) 2015 Apple Inc. All right reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -36,77 +37,52 @@
namespace WebCore {
-// Define custom non-animated property 'requiredFeatures'.
-const SVGPropertyInfo* SVGTests::requiredFeaturesPropertyInfo()
-{
- static const SVGPropertyInfo* s_propertyInfo = 0;
- if (!s_propertyInfo) {
- s_propertyInfo = new SVGPropertyInfo(AnimatedUnknown,
- PropertyIsReadWrite,
- SVGNames::requiredFeaturesAttr,
- SVGNames::requiredFeaturesAttr.localName(),
- &SVGElement::synchronizeRequiredFeatures,
- 0);
- }
- return s_propertyInfo;
-}
+using namespace SVGNames;
-// Define custom non-animated property 'requiredExtensions'.
-const SVGPropertyInfo* SVGTests::requiredExtensionsPropertyInfo()
+SVGTests::SVGTests()
+ : m_requiredFeatures(requiredFeaturesAttr)
+ , m_requiredExtensions(requiredExtensionsAttr)
+ , m_systemLanguage(systemLanguageAttr)
{
- static const SVGPropertyInfo* s_propertyInfo = 0;
- if (!s_propertyInfo) {
- s_propertyInfo = new SVGPropertyInfo(AnimatedUnknown,
- PropertyIsReadWrite,
- SVGNames::requiredExtensionsAttr,
- SVGNames::requiredExtensionsAttr.localName(),
- &SVGElement::synchronizeRequiredExtensions,
- 0);
- }
- return s_propertyInfo;
}
-// Define custom non-animated property 'systemLanguage'.
-const SVGPropertyInfo* SVGTests::systemLanguagePropertyInfo()
+static SVGPropertyInfo createSVGTestPropertyInfo(const QualifiedName& attributeName, SVGPropertyInfo::SynchronizeProperty synchronizeFunction)
{
- static const SVGPropertyInfo* s_propertyInfo = 0;
- if (!s_propertyInfo) {
- s_propertyInfo = new SVGPropertyInfo(AnimatedUnknown,
- PropertyIsReadWrite,
- SVGNames::systemLanguageAttr,
- SVGNames::systemLanguageAttr.localName(),
- &SVGElement::synchronizeSystemLanguage,
- 0);
- }
- return s_propertyInfo;
+ return { AnimatedUnknown, PropertyIsReadWrite, attributeName, attributeName.localName(), synchronizeFunction, nullptr };
}
-SVGTests::SVGTests()
- : m_requiredFeatures(SVGNames::requiredFeaturesAttr)
- , m_requiredExtensions(SVGNames::requiredExtensionsAttr)
- , m_systemLanguage(SVGNames::systemLanguageAttr)
+static SVGAttributeToPropertyMap createSVGTextAttributeToPropertyMap()
{
+ typedef NeverDestroyed<const SVGPropertyInfo> Info;
+
+ SVGAttributeToPropertyMap map;
+
+ static Info requiredFeatures = createSVGTestPropertyInfo(requiredFeaturesAttr, SVGElement::synchronizeRequiredFeatures);
+ map.addProperty(requiredFeatures.get());
+
+ static Info requiredExtensions = createSVGTestPropertyInfo(requiredExtensionsAttr, SVGElement::synchronizeRequiredExtensions);
+ map.addProperty(requiredExtensions.get());
+
+ static Info systemLanguage = createSVGTestPropertyInfo(systemLanguageAttr, SVGElement::synchronizeSystemLanguage);
+ map.addProperty(systemLanguage.get());
+
+ return map;
}
-SVGAttributeToPropertyMap& SVGTests::attributeToPropertyMap()
+const SVGAttributeToPropertyMap& SVGTests::attributeToPropertyMap()
{
- static NeverDestroyed<SVGAttributeToPropertyMap> map;
- if (!map.get().isEmpty())
- return map;
- map.get().addProperty(requiredFeaturesPropertyInfo());
- map.get().addProperty(requiredExtensionsPropertyInfo());
- map.get().addProperty(systemLanguagePropertyInfo());
+ static NeverDestroyed<SVGAttributeToPropertyMap> map = createSVGTextAttributeToPropertyMap();
return map;
}
-bool SVGTests::hasExtension(const String& extension) const
+bool SVGTests::hasExtension(const String& extension)
{
// We recognize XHTML and MathML, as implemented in Gecko and suggested in the SVG Tiny recommendation (http://www.w3.org/TR/SVG11/struct.html#RequiredExtensionsAttribute).
#if ENABLE(MATHML)
- return extension == HTMLNames::xhtmlNamespaceURI || extension == MathMLNames::mathmlNamespaceURI;
-#else
- return extension == HTMLNames::xhtmlNamespaceURI;
+ if (extension == MathMLNames::mathmlNamespaceURI)
+ return true;
#endif
+ return extension == HTMLNames::xhtmlNamespaceURI;
}
bool SVGTests::isValid() const
@@ -115,90 +91,80 @@
if (feature.isEmpty() || !DOMImplementation::hasFeature(feature, String()))
return false;
}
-
for (auto& language : m_systemLanguage.value) {
if (language != defaultLanguage().substring(0, 2))
return false;
}
-
for (auto& extension : m_requiredExtensions.value) {
if (!hasExtension(extension))
return false;
}
-
return true;
}
-bool SVGTests::parseAttribute(const QualifiedName& name, const AtomicString& value)
+bool SVGTests::parseAttribute(const QualifiedName& attributeName, const AtomicString& value)
{
- if (name == SVGNames::requiredFeaturesAttr) {
+ if (attributeName == requiredFeaturesAttr) {
m_requiredFeatures.value.reset(value);
return true;
}
- if (name == SVGNames::requiredExtensionsAttr) {
+ if (attributeName == requiredExtensionsAttr) {
m_requiredExtensions.value.reset(value);
return true;
}
- if (name == SVGNames::systemLanguageAttr) {
+ if (attributeName == systemLanguageAttr) {
m_systemLanguage.value.reset(value);
return true;
}
-
return false;
}
-bool SVGTests::isKnownAttribute(const QualifiedName& attrName)
+bool SVGTests::isKnownAttribute(const QualifiedName& attributeName)
{
- return attrName == SVGNames::requiredFeaturesAttr
- || attrName == SVGNames::requiredExtensionsAttr
- || attrName == SVGNames::systemLanguageAttr;
+ return attributeName == requiredFeaturesAttr
+ || attributeName == requiredExtensionsAttr
+ || attributeName == systemLanguageAttr;
}
-bool SVGTests::handleAttributeChange(SVGElement* targetElement, const QualifiedName& attrName)
+bool SVGTests::handleAttributeChange(SVGElement* targetElement, const QualifiedName& attributeName)
{
ASSERT(targetElement);
- if (!isKnownAttribute(attrName))
+ if (!isKnownAttribute(attributeName))
return false;
if (!targetElement->inDocument())
return true;
-
targetElement->setNeedsStyleRecalc(ReconstructRenderTree);
-
return true;
}
void SVGTests::addSupportedAttributes(HashSet<QualifiedName>& supportedAttributes)
{
- supportedAttributes.add(SVGNames::requiredFeaturesAttr);
- supportedAttributes.add(SVGNames::requiredExtensionsAttr);
- supportedAttributes.add(SVGNames::systemLanguageAttr);
+ supportedAttributes.add(requiredFeaturesAttr);
+ supportedAttributes.add(requiredExtensionsAttr);
+ supportedAttributes.add(systemLanguageAttr);
}
-void SVGTests::synchronizeRequiredFeatures(SVGElement* contextElement)
+void SVGTests::synchronizeAttribute(SVGElement* contextElement, SVGSynchronizableAnimatedProperty<SVGStringList>& property, const QualifiedName& attributeName)
{
ASSERT(contextElement);
- if (!m_requiredFeatures.shouldSynchronize)
+ if (!property.shouldSynchronize)
return;
- AtomicString value(m_requiredFeatures.value.valueAsString());
- m_requiredFeatures.synchronize(contextElement, requiredFeaturesPropertyInfo()->attributeName, value);
+ m_requiredFeatures.synchronize(contextElement, attributeName, property.value.valueAsString());
}
+void SVGTests::synchronizeRequiredFeatures(SVGElement* contextElement)
+{
+ synchronizeAttribute(contextElement, m_requiredFeatures, requiredFeaturesAttr);
+}
+
void SVGTests::synchronizeRequiredExtensions(SVGElement* contextElement)
{
- ASSERT(contextElement);
- if (!m_requiredExtensions.shouldSynchronize)
- return;
- AtomicString value(m_requiredExtensions.value.valueAsString());
- m_requiredExtensions.synchronize(contextElement, requiredExtensionsPropertyInfo()->attributeName, value);
+ synchronizeAttribute(contextElement, m_requiredExtensions, requiredExtensionsAttr);
}
void SVGTests::synchronizeSystemLanguage(SVGElement* contextElement)
{
- ASSERT(contextElement);
- if (!m_systemLanguage.shouldSynchronize)
- return;
- AtomicString value(m_systemLanguage.value.valueAsString());
- m_systemLanguage.synchronize(contextElement, systemLanguagePropertyInfo()->attributeName, value);
+ synchronizeAttribute(contextElement, m_systemLanguage, systemLanguageAttr);
}
SVGStringList& SVGTests::requiredFeatures()
Modified: trunk/Source/WebCore/svg/SVGTests.h (179259 => 179260)
--- trunk/Source/WebCore/svg/SVGTests.h 2015-01-28 17:54:27 UTC (rev 179259)
+++ trunk/Source/WebCore/svg/SVGTests.h 2015-01-28 17:59:50 UTC (rev 179260)
@@ -26,8 +26,6 @@
namespace WebCore {
-class Attribute;
-class QualifiedName;
class SVGElement;
class SVGTests {
@@ -36,16 +34,16 @@
SVGStringList& requiredExtensions();
SVGStringList& systemLanguage();
- bool hasExtension(const String&) const;
+ static bool hasExtension(const String&);
bool isValid() const;
bool parseAttribute(const QualifiedName&, const AtomicString&);
- bool isKnownAttribute(const QualifiedName&);
+ static bool isKnownAttribute(const QualifiedName&);
- void addSupportedAttributes(HashSet<QualifiedName>&);
- bool handleAttributeChange(SVGElement*, const QualifiedName&);
+ static void addSupportedAttributes(HashSet<QualifiedName>&);
+ static bool handleAttributeChange(SVGElement*, const QualifiedName&);
- static SVGAttributeToPropertyMap& attributeToPropertyMap();
+ static const SVGAttributeToPropertyMap& attributeToPropertyMap();
protected:
SVGTests();
@@ -55,16 +53,10 @@
void synchronizeSystemLanguage(SVGElement* contextElement);
private:
- // Custom 'requiredFeatures' property
- static const SVGPropertyInfo* requiredFeaturesPropertyInfo();
- SVGSynchronizableAnimatedProperty<SVGStringList> m_requiredFeatures;
+ void synchronizeAttribute(SVGElement* contextElement, SVGSynchronizableAnimatedProperty<SVGStringList>&, const QualifiedName& attributeName);
- // Custom 'requiredExtensions' property
- static const SVGPropertyInfo* requiredExtensionsPropertyInfo();
+ SVGSynchronizableAnimatedProperty<SVGStringList> m_requiredFeatures;
SVGSynchronizableAnimatedProperty<SVGStringList> m_requiredExtensions;
-
- // Custom 'systemLanguage' property
- static const SVGPropertyInfo* systemLanguagePropertyInfo();
SVGSynchronizableAnimatedProperty<SVGStringList> m_systemLanguage;
};
Modified: trunk/Source/WebCore/svg/SVGUseElement.cpp (179259 => 179260)
--- trunk/Source/WebCore/svg/SVGUseElement.cpp 2015-01-28 17:54:27 UTC (rev 179259)
+++ trunk/Source/WebCore/svg/SVGUseElement.cpp 2015-01-28 17:59:50 UTC (rev 179260)
@@ -776,10 +776,8 @@
void SVGUseElement::invalidateDependentShadowTrees()
{
// Recursively invalidate dependent <use> shadow trees
- const HashSet<SVGElementInstance*>& instances = instancesForElement();
- const HashSet<SVGElementInstance*>::const_iterator end = instances.end();
- for (HashSet<SVGElementInstance*>::const_iterator it = instances.begin(); it != end; ++it) {
- if (SVGUseElement* element = (*it)->correspondingUseElement()) {
+ for (auto* instance : instances()) {
+ if (SVGUseElement* element = instance->correspondingUseElement()) {
ASSERT(element->inDocument());
element->invalidateShadowTree();
}
Modified: trunk/Source/WebCore/svg/properties/SVGAnimatedPropertyMacros.h (179259 => 179260)
--- trunk/Source/WebCore/svg/properties/SVGAnimatedPropertyMacros.h 2015-01-28 17:54:27 UTC (rev 179259)
+++ trunk/Source/WebCore/svg/properties/SVGAnimatedPropertyMacros.h 2015-01-28 17:59:50 UTC (rev 179260)
@@ -26,6 +26,7 @@
#include "SVGAnimatedProperty.h"
#include "SVGAttributeToPropertyMap.h"
#include "SVGPropertyTraits.h"
+#include <wtf/NeverDestroyed.h>
#include <wtf/StdLibExtras.h>
namespace WebCore {
@@ -70,23 +71,19 @@
#define BEGIN_REGISTER_ANIMATED_PROPERTIES(OwnerType) \
SVGAttributeToPropertyMap& OwnerType::attributeToPropertyMap() \
{ \
- DEPRECATED_DEFINE_STATIC_LOCAL(SVGAttributeToPropertyMap, s_attributeToPropertyMap, ()); \
- return s_attributeToPropertyMap; \
+ static NeverDestroyed<SVGAttributeToPropertyMap> map; \
+ return map; \
} \
\
static void registerAnimatedPropertiesFor##OwnerType() \
{ \
- SVGAttributeToPropertyMap& map = OwnerType::attributeToPropertyMap(); \
+ auto& map = OwnerType::attributeToPropertyMap(); \
if (!map.isEmpty()) \
return; \
typedef OwnerType UseOwnerType;
-#define REGISTER_LOCAL_ANIMATED_PROPERTY(LowerProperty) \
- map.addProperty(UseOwnerType::LowerProperty##PropertyInfo());
-
-#define REGISTER_PARENT_ANIMATED_PROPERTIES(ClassName) \
- map.addProperties(ClassName::attributeToPropertyMap()); \
-
+#define REGISTER_LOCAL_ANIMATED_PROPERTY(LowerProperty) map.addProperty(*UseOwnerType::LowerProperty##PropertyInfo());
+#define REGISTER_PARENT_ANIMATED_PROPERTIES(ClassName) map.addProperties(ClassName::attributeToPropertyMap());
#define END_REGISTER_ANIMATED_PROPERTIES }
// Property definition helpers (used in SVG*.cpp files)
Modified: trunk/Source/WebCore/svg/properties/SVGAttributeToPropertyMap.cpp (179259 => 179260)
--- trunk/Source/WebCore/svg/properties/SVGAttributeToPropertyMap.cpp 2015-01-28 17:54:27 UTC (rev 179259)
+++ trunk/Source/WebCore/svg/properties/SVGAttributeToPropertyMap.cpp 2015-01-28 17:59:50 UTC (rev 179260)
@@ -1,5 +1,6 @@
/*
* Copyright (C) Research In Motion Limited 2011. All rights reserved.
+ * Copyright (C) 2015 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
@@ -21,106 +22,65 @@
#include "SVGAttributeToPropertyMap.h"
#include "SVGAnimatedProperty.h"
-#include "SVGPropertyInfo.h"
namespace WebCore {
void SVGAttributeToPropertyMap::addProperties(const SVGAttributeToPropertyMap& map)
{
- AttributeToPropertiesMap::const_iterator end = map.m_map.end();
- for (AttributeToPropertiesMap::const_iterator it = map.m_map.begin(); it != end; ++it) {
- const PropertiesVector* vector = it->value.get();
- ASSERT(vector);
-
- // FIXME: This looks up the attribute name in the hash table for each property, even though all the
- // properties in a single vector are guaranteed to have the same attribute name.
- // FIXME: This grows the vector one item at a time, even though we know up front exactly how many
- // elements we are adding to the vector.
- PropertiesVector::const_iterator vectorEnd = vector->end();
- for (PropertiesVector::const_iterator vectorIt = vector->begin(); vectorIt != vectorEnd; ++vectorIt)
- addProperty(*vectorIt);
+ for (auto& vector : map.m_map.values()) {
+ ASSERT(!vector.isEmpty());
+ auto& properties = m_map.add(vector[0]->attributeName, PropertyInfoVector()).iterator->value;
+ properties.reserveCapacity(properties.size() + vector.size());
+ for (auto* property : vector)
+ properties.uncheckedAppend(property);
}
}
-void SVGAttributeToPropertyMap::addProperty(const SVGPropertyInfo* info)
+void SVGAttributeToPropertyMap::addProperty(const SVGPropertyInfo& info)
{
- ASSERT(info);
- ASSERT(info->attributeName != anyQName());
- if (PropertiesVector* vector = m_map.get(info->attributeName)) {
- vector->append(info);
- return;
- }
- // FIXME: This does a second hash table lookup, but with HashMap::add we could instead do only one.
- auto vector = std::make_unique<PropertiesVector>();
- vector->append(info);
- m_map.set(info->attributeName, WTF::move(vector));
+ m_map.add(info.attributeName, PropertyInfoVector()).iterator->value.append(&info);
}
-void SVGAttributeToPropertyMap::animatedPropertiesForAttribute(SVGElement* ownerType, const QualifiedName& attributeName, Vector<RefPtr<SVGAnimatedProperty>>& properties)
+Vector<RefPtr<SVGAnimatedProperty>> SVGAttributeToPropertyMap::properties(SVGElement& contextElement, const QualifiedName& attributeName) const
{
- ASSERT(ownerType);
- PropertiesVector* vector = m_map.get(attributeName);
- if (!vector)
- return;
-
- PropertiesVector::iterator vectorEnd = vector->end();
- for (PropertiesVector::iterator vectorIt = vector->begin(); vectorIt != vectorEnd; ++vectorIt)
- properties.append(animatedProperty(ownerType, attributeName, *vectorIt));
+ Vector<RefPtr<SVGAnimatedProperty>> properties;
+ auto it = m_map.find(attributeName);
+ if (it == m_map.end())
+ return properties;
+ properties.reserveInitialCapacity(it->value.size());
+ for (auto* property : it->value)
+ properties.uncheckedAppend(property->lookupOrCreateWrapperForAnimatedProperty(&contextElement));
+ return properties;
}
-void SVGAttributeToPropertyMap::animatedPropertyTypeForAttribute(const QualifiedName& attributeName, Vector<AnimatedPropertyType>& propertyTypes)
+Vector<AnimatedPropertyType> SVGAttributeToPropertyMap::types(const QualifiedName& attributeName) const
{
- PropertiesVector* vector = m_map.get(attributeName);
- if (!vector)
- return;
-
- PropertiesVector::iterator vectorEnd = vector->end();
- for (PropertiesVector::iterator vectorIt = vector->begin(); vectorIt != vectorEnd; ++vectorIt)
- propertyTypes.append((*vectorIt)->animatedPropertyType);
+ Vector<AnimatedPropertyType> types;
+ auto it = m_map.find(attributeName);
+ if (it == m_map.end())
+ return types;
+ types.reserveInitialCapacity(it->value.size());
+ for (auto* property : it->value)
+ types.uncheckedAppend(property->animatedPropertyType);
+ return types;
}
-void SVGAttributeToPropertyMap::synchronizeProperties(SVGElement* contextElement)
+void SVGAttributeToPropertyMap::synchronizeProperties(SVGElement& contextElement) const
{
- ASSERT(contextElement);
- AttributeToPropertiesMap::iterator end = m_map.end();
- for (AttributeToPropertiesMap::iterator it = m_map.begin(); it != end; ++it) {
- PropertiesVector* vector = it->value.get();
- ASSERT(vector);
-
- PropertiesVector::iterator vectorEnd = vector->end();
- for (PropertiesVector::iterator vectorIt = vector->begin(); vectorIt != vectorEnd; ++vectorIt)
- synchronizeProperty(contextElement, it->key, *vectorIt);
+ for (auto& vector : m_map.values()) {
+ for (auto* property : vector)
+ property->synchronizeProperty(&contextElement);
}
}
-bool SVGAttributeToPropertyMap::synchronizeProperty(SVGElement* contextElement, const QualifiedName& attributeName)
+bool SVGAttributeToPropertyMap::synchronizeProperty(SVGElement& contextElement, const QualifiedName& attributeName) const
{
- ASSERT(contextElement);
- PropertiesVector* vector = m_map.get(attributeName);
- if (!vector)
+ auto it = m_map.find(attributeName);
+ if (it == m_map.end())
return false;
-
- PropertiesVector::iterator vectorEnd = vector->end();
- for (PropertiesVector::iterator vectorIt = vector->begin(); vectorIt != vectorEnd; ++vectorIt)
- synchronizeProperty(contextElement, attributeName, *vectorIt);
-
+ for (auto* property : it->value)
+ property->synchronizeProperty(&contextElement);
return true;
}
-void SVGAttributeToPropertyMap::synchronizeProperty(SVGElement* contextElement, const QualifiedName& attributeName, const SVGPropertyInfo* info)
-{
- ASSERT(info);
- ASSERT_UNUSED(attributeName, attributeName == info->attributeName);
- ASSERT(info->synchronizeProperty);
- (*info->synchronizeProperty)(contextElement);
}
-
-PassRefPtr<SVGAnimatedProperty> SVGAttributeToPropertyMap::animatedProperty(SVGElement* contextElement, const QualifiedName& attributeName, const SVGPropertyInfo* info)
-{
- ASSERT(info);
- ASSERT_UNUSED(attributeName, attributeName == info->attributeName);
- ASSERT(info->lookupOrCreateWrapperForAnimatedProperty);
- return (*info->lookupOrCreateWrapperForAnimatedProperty)(contextElement);
-}
-
-}
Modified: trunk/Source/WebCore/svg/properties/SVGAttributeToPropertyMap.h (179259 => 179260)
--- trunk/Source/WebCore/svg/properties/SVGAttributeToPropertyMap.h 2015-01-28 17:54:27 UTC (rev 179259)
+++ trunk/Source/WebCore/svg/properties/SVGAttributeToPropertyMap.h 2015-01-28 17:59:50 UTC (rev 179260)
@@ -1,5 +1,6 @@
/*
* Copyright (C) Research In Motion Limited 2011. All rights reserved.
+ * Copyright (C) 2015 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
@@ -32,24 +33,18 @@
public:
bool isEmpty() const { return m_map.isEmpty(); }
+ void addProperty(const SVGPropertyInfo&);
void addProperties(const SVGAttributeToPropertyMap&);
- void addProperty(const SVGPropertyInfo*);
- // FIXME: To match WebKit coding style either these functions should have return values instead of out parameters,
- // or the word "get" should be added as a prefix to their names.
- void animatedPropertiesForAttribute(SVGElement* contextElement, const QualifiedName& attributeName, Vector<RefPtr<SVGAnimatedProperty>>&);
- void animatedPropertyTypeForAttribute(const QualifiedName& attributeName, Vector<AnimatedPropertyType>&);
+ Vector<RefPtr<SVGAnimatedProperty>> properties(SVGElement&, const QualifiedName& attributeName) const;
+ Vector<AnimatedPropertyType> types(const QualifiedName& attributeName) const;
- void synchronizeProperties(SVGElement* contextElement);
- bool synchronizeProperty(SVGElement* contextElement, const QualifiedName& attributeName);
+ void synchronizeProperties(SVGElement&) const;
+ bool synchronizeProperty(SVGElement&, const QualifiedName& attributeName) const;
private:
- void synchronizeProperty(SVGElement* contextElement, const QualifiedName& attributeName, const SVGPropertyInfo*);
- PassRefPtr<SVGAnimatedProperty> animatedProperty(SVGElement* contextElement, const QualifiedName& attributeName, const SVGPropertyInfo*);
-
- typedef Vector<const SVGPropertyInfo*> PropertiesVector;
- typedef HashMap<QualifiedName, std::unique_ptr<PropertiesVector>> AttributeToPropertiesMap;
- AttributeToPropertiesMap m_map;
+ typedef Vector<const SVGPropertyInfo*> PropertyInfoVector;
+ HashMap<QualifiedName, PropertyInfoVector> m_map;
};
}