| Index: Source/core/svg/SVGElement.cpp
|
| diff --git a/Source/core/svg/SVGElement.cpp b/Source/core/svg/SVGElement.cpp
|
| index 244f5b93a93fe416a20f93dca2b974f7e344faad..698e6d8adecbed0d2001ea3571d7df0029d1c472 100644
|
| --- a/Source/core/svg/SVGElement.cpp
|
| +++ b/Source/core/svg/SVGElement.cpp
|
| @@ -98,8 +98,8 @@ SVGElement::~SVGElement()
|
|
|
| // With Oilpan, either removedFrom has been called or the document is dead
|
| // as well and there is no reason to clear out the references.
|
| - document().accessSVGExtensions().rebuildAllElementReferencesForTarget(this);
|
| - document().accessSVGExtensions().removeAllElementReferencesForTarget(this);
|
| + rebuildAllIncomingReferences();
|
| + removeAllIncomingReferences();
|
| }
|
| #endif
|
| }
|
| @@ -317,8 +317,8 @@ void SVGElement::removedFrom(ContainerNode* rootParent)
|
| Element::removedFrom(rootParent);
|
|
|
| if (wasInDocument) {
|
| - document().accessSVGExtensions().rebuildAllElementReferencesForTarget(this);
|
| - document().accessSVGExtensions().removeAllElementReferencesForTarget(this);
|
| + rebuildAllIncomingReferences();
|
| + removeAllIncomingReferences();
|
| }
|
|
|
| invalidateInstances();
|
| @@ -897,7 +897,7 @@ void SVGElement::attributeChanged(const QualifiedName& name, const AtomicString&
|
| Element::attributeChanged(name, newValue);
|
|
|
| if (isIdAttributeName(name))
|
| - document().accessSVGExtensions().rebuildAllElementReferencesForTarget(this);
|
| + rebuildAllIncomingReferences();
|
|
|
| // Changes to the style attribute are processed lazily (see Element::getAttribute() and related methods),
|
| // so we don't want changes to the style attribute to result in extra work here.
|
| @@ -1152,6 +1152,70 @@ bool SVGElement::isAnimatableAttribute(const QualifiedName& name) const
|
| }
|
| #endif
|
|
|
| +SVGElementSet* SVGElement::setOfIncomingReferences() const
|
| +{
|
| + if (!hasSVGRareData())
|
| + return 0;
|
| + return &svgRareData()->incomingReferences();
|
| +}
|
| +
|
| +void SVGElement::addReferenceTo(SVGElement* targetElement)
|
| +{
|
| + ASSERT(targetElement);
|
| +
|
| + ensureSVGRareData()->outgoingReferences().add(targetElement);
|
| + targetElement->ensureSVGRareData()->incomingReferences().add(this);
|
| +}
|
| +
|
| +void SVGElement::rebuildAllIncomingReferences()
|
| +{
|
| + if (!hasSVGRareData())
|
| + return;
|
| +
|
| + const SVGElementSet& incomingReferences = svgRareData()->incomingReferences();
|
| +
|
| + // Iterate on a snapshot as |incomingReferences| may be altered inside loop.
|
| + WillBeHeapVector<RawPtrWillBeMember<SVGElement> > incomingReferencesSnapshot;
|
| + copyToVector(incomingReferences, incomingReferencesSnapshot);
|
| +
|
| + // Force rebuilding the |sourceElement| so it knows about this change.
|
| + for (WillBeHeapVector<RawPtrWillBeMember<SVGElement> >::iterator it = incomingReferencesSnapshot.begin(), itEnd = incomingReferencesSnapshot.end(); it != itEnd; ++it) {
|
| + SVGElement* sourceElement = *it;
|
| +
|
| + // Before rebuilding |sourceElement| ensure it was not removed from under us.
|
| + if (incomingReferences.contains(sourceElement))
|
| + sourceElement->svgAttributeChanged(XLinkNames::hrefAttr);
|
| + }
|
| +}
|
| +
|
| +void SVGElement::removeAllIncomingReferences()
|
| +{
|
| + if (!hasSVGRareData())
|
| + return;
|
| +
|
| + SVGElementSet& incomingReferences = svgRareData()->incomingReferences();
|
| + for (SVGElementSet::iterator it = incomingReferences.begin(), itEnd = incomingReferences.end(); it != itEnd; ++it) {
|
| + SVGElement* sourceElement = *it;
|
| + ASSERT(sourceElement->hasSVGRareData());
|
| + sourceElement->ensureSVGRareData()->outgoingReferences().remove(this);
|
| + }
|
| + incomingReferences.clear();
|
| +}
|
| +
|
| +void SVGElement::removeAllOutgoingReferences()
|
| +{
|
| + if (!hasSVGRareData())
|
| + return;
|
| +
|
| + SVGElementSet& outgoingReferences = svgRareData()->outgoingReferences();
|
| + for (SVGElementSet::iterator it = outgoingReferences.begin(), itEnd = outgoingReferences.end(); it != itEnd; ++it) {
|
| + SVGElement* targetElement = *it;
|
| + ASSERT(targetElement->hasSVGRareData());
|
| + targetElement->ensureSVGRareData()->incomingReferences().remove(this);
|
| + }
|
| + outgoingReferences.clear();
|
| +}
|
| +
|
| void SVGElement::trace(Visitor* visitor)
|
| {
|
| visitor->trace(m_elementsWithRelativeLengths);
|
|
|