https://bugs.webkit.org/show_bug.cgi?id=141148
Reviewed by Brent Fulgham.
Inspired by this change Rob Buis made in Blink:
http://src.chromium.org/viewvc/blink?view=revision&revision=173343
I actually wrote the whole thing and then discovered we did it almost identically.
* svg/SVGAnimatedTypeAnimator.cpp:
(WebCore::SVGElementAnimatedPropertyList::setInstanceUpdatesBlocked): Added this
helper function to get around a circular header dependency.
* svg/SVGAnimatedTypeAnimator.h:
(WebCore::SVGAnimatedTypeAnimator::executeAction): Use setInstanceUpdatesBlocked.
* svg/SVGElement.cpp:
(WebCore::SVGElement::removedFrom): Use invalidateInstances.
(WebCore::SVGElement::finishParsingChildren): Ditto.
(WebCore::SVGElement::svgAttributeChanged): Ditto.
(WebCore::SVGElement::childrenChanged): Ditto.
(WebCore::SVGElement::setInstanceUpdatesBlocked): Added an assertion that will
catch anyone who nests InstanceUpdateBlocker by accident.
(WebCore::SVGElement::invalidateInstances): Moved this here from
SVGElementInstance::invalidateAllInstancesOfElement. I had already modified this
so it had nothing to do with SVGElementInstance, so it was a simple matter of
converting this into a member function. Added a FIXME about the mysterious
updateStyleIfNeeded that makes multiple tests fail if it's removed.
* svg/SVGElement.h: Added public InstanceUpdateBlocker class, protected
InstanceInvalidationGuard class, and private invalidateInstances function.
Unlike the ones in SVGElementInstance these use references so they are then
not copyable without using the WTF_MAKE_NONCOPYABLE macro.
* svg/SVGElementInstance.cpp:
(WebCore::SVGElementInstance::invalidateAllInstancesOfElement): Deleted.
(WebCore::SVGElementInstance::InstanceUpdateBlocker::InstanceUpdateBlocker): Deleted.
(WebCore::SVGElementInstance::InstanceUpdateBlocker::~InstanceUpdateBlocker): Deleted.
* svg/SVGElementInstance.h: Removed InvalidationGuard, InstanceUpdateBlocker, and
invalidateAllInstancesOfElement. Didn't do any further cleanup since we soon will
delete this entire file.
* svg/SVGAElement.cpp:
(WebCore::SVGAElement::svgAttributeChanged): Updated to use new name and reference
instead of pointer.
* svg/SVGAnimateElementBase.cpp:
(WebCore::applyCSSPropertyToTargetAndInstances): Ditto.
(WebCore::removeCSSPropertyFromTargetAndInstances): Ditto.
(WebCore::notifyTargetAndInstancesAboutAnimValChange): Ditto.
* svg/SVGAnimatedPath.cpp:
(WebCore::SVGAnimatedPathAnimator::startAnimValAnimation): Ditto.
* svg/SVGCircleElement.cpp:
(WebCore::SVGCircleElement::svgAttributeChanged): Ditto.
* svg/SVGClipPathElement.cpp:
(WebCore::SVGClipPathElement::svgAttributeChanged): Ditto.
* svg/SVGComponentTransferFunctionElement.cpp:
(WebCore::SVGComponentTransferFunctionElement::svgAttributeChanged): Ditto.
* svg/SVGCursorElement.cpp:
(WebCore::SVGCursorElement::svgAttributeChanged): Ditto.
* svg/SVGEllipseElement.cpp:
(WebCore::SVGEllipseElement::svgAttributeChanged): Ditto.
* svg/SVGFEBlendElement.cpp:
(WebCore::SVGFEBlendElement::svgAttributeChanged): Ditto.
* svg/SVGFEColorMatrixElement.cpp:
(WebCore::SVGFEColorMatrixElement::svgAttributeChanged): Ditto.
* svg/SVGFECompositeElement.cpp:
(WebCore::SVGFECompositeElement::svgAttributeChanged): Ditto.
* svg/SVGFEConvolveMatrixElement.cpp:
(WebCore::SVGFEConvolveMatrixElement::svgAttributeChanged): Ditto.
* svg/SVGFEDiffuseLightingElement.cpp:
(WebCore::SVGFEDiffuseLightingElement::svgAttributeChanged): Ditto.
* svg/SVGFEDisplacementMapElement.cpp:
(WebCore::SVGFEDisplacementMapElement::svgAttributeChanged): Ditto.
* svg/SVGFEDropShadowElement.cpp:
(WebCore::SVGFEDropShadowElement::svgAttributeChanged): Ditto.
* svg/SVGFEGaussianBlurElement.cpp:
(WebCore::SVGFEGaussianBlurElement::svgAttributeChanged): Ditto.
* svg/SVGFEImageElement.cpp:
(WebCore::SVGFEImageElement::svgAttributeChanged): Ditto.
* svg/SVGFELightElement.cpp:
(WebCore::SVGFELightElement::svgAttributeChanged): Ditto.
* svg/SVGFEMergeNodeElement.cpp:
(WebCore::SVGFEMergeNodeElement::svgAttributeChanged): Ditto.
* svg/SVGFEMorphologyElement.cpp:
(WebCore::SVGFEMorphologyElement::svgAttributeChanged): Ditto.
* svg/SVGFEOffsetElement.cpp:
(WebCore::SVGFEOffsetElement::svgAttributeChanged): Ditto.
* svg/SVGFESpecularLightingElement.cpp:
(WebCore::SVGFESpecularLightingElement::svgAttributeChanged): Ditto.
* svg/SVGFETileElement.cpp:
(WebCore::SVGFETileElement::svgAttributeChanged): Ditto.
* svg/SVGFETurbulenceElement.cpp:
(WebCore::SVGFETurbulenceElement::svgAttributeChanged): Ditto.
* svg/SVGFilterElement.cpp:
(WebCore::SVGFilterElement::svgAttributeChanged): Ditto.
* svg/SVGFilterPrimitiveStandardAttributes.cpp:
(WebCore::SVGFilterPrimitiveStandardAttributes::svgAttributeChanged): Ditto.
* svg/SVGForeignObjectElement.cpp:
(WebCore::SVGForeignObjectElement::svgAttributeChanged): Ditto.
* svg/SVGGElement.cpp:
(WebCore::SVGGElement::svgAttributeChanged): Ditto.
* svg/SVGGradientElement.cpp:
(WebCore::SVGGradientElement::svgAttributeChanged): Ditto.
* svg/SVGGraphicsElement.cpp:
(WebCore::SVGGraphicsElement::svgAttributeChanged): Ditto.
* svg/SVGImageElement.cpp:
(WebCore::SVGImageElement::svgAttributeChanged): Ditto.
* svg/SVGLineElement.cpp:
(WebCore::SVGLineElement::svgAttributeChanged): Ditto.
* svg/SVGLinearGradientElement.cpp:
(WebCore::SVGLinearGradientElement::svgAttributeChanged): Ditto.
* svg/SVGMPathElement.cpp:
(WebCore::SVGMPathElement::svgAttributeChanged): Ditto.
* svg/SVGMarkerElement.cpp:
(WebCore::SVGMarkerElement::svgAttributeChanged): Ditto.
* svg/SVGMaskElement.cpp:
(WebCore::SVGMaskElement::svgAttributeChanged): Ditto.
* svg/SVGPathElement.cpp:
(WebCore::SVGPathElement::svgAttributeChanged): Ditto.
* svg/SVGPatternElement.cpp:
(WebCore::SVGPatternElement::svgAttributeChanged): Ditto.
* svg/SVGPolyElement.cpp:
(WebCore::SVGPolyElement::svgAttributeChanged): Ditto.
* svg/SVGRadialGradientElement.cpp:
(WebCore::SVGRadialGradientElement::svgAttributeChanged): Ditto.
* svg/SVGRectElement.cpp:
(WebCore::SVGRectElement::svgAttributeChanged): Ditto.
* svg/SVGSVGElement.cpp:
(WebCore::SVGSVGElement::svgAttributeChanged): Ditto.
* svg/SVGScriptElement.cpp:
(WebCore::SVGScriptElement::svgAttributeChanged): Ditto.
* svg/SVGStopElement.cpp:
(WebCore::SVGStopElement::svgAttributeChanged): Ditto.
* svg/SVGSymbolElement.cpp:
(WebCore::SVGSymbolElement::svgAttributeChanged): Ditto.
* svg/SVGTRefElement.cpp:
(WebCore::SVGTRefElement::svgAttributeChanged): Ditto.
* svg/SVGTextContentElement.cpp:
(WebCore::SVGTextContentElement::svgAttributeChanged): Ditto.
* svg/SVGTextPathElement.cpp:
(WebCore::SVGTextPathElement::svgAttributeChanged): Ditto.
* svg/SVGTextPositioningElement.cpp:
(WebCore::SVGTextPositioningElement::svgAttributeChanged): Ditto.
* svg/SVGUseElement.cpp:
(WebCore::SVGUseElement::svgAttributeChanged): Ditto.
* svg/animation/SVGSMILElement.cpp:
(WebCore::SVGSMILElement::svgAttributeChanged): Ditto.
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@179548
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2015-02-03 Darin Adler <darin@apple.com>
+
+ Move InstanceInvalidationGuard/UpdateBlocker to SVGElement from SVGElementInstance
+ https://bugs.webkit.org/show_bug.cgi?id=141148
+
+ Reviewed by Brent Fulgham.
+
+ Inspired by this change Rob Buis made in Blink:
+
+ http://src.chromium.org/viewvc/blink?view=revision&revision=173343
+
+ I actually wrote the whole thing and then discovered we did it almost identically.
+
+ * svg/SVGAnimatedTypeAnimator.cpp:
+ (WebCore::SVGElementAnimatedPropertyList::setInstanceUpdatesBlocked): Added this
+ helper function to get around a circular header dependency.
+ * svg/SVGAnimatedTypeAnimator.h:
+ (WebCore::SVGAnimatedTypeAnimator::executeAction): Use setInstanceUpdatesBlocked.
+
+ * svg/SVGElement.cpp:
+ (WebCore::SVGElement::removedFrom): Use invalidateInstances.
+ (WebCore::SVGElement::finishParsingChildren): Ditto.
+ (WebCore::SVGElement::svgAttributeChanged): Ditto.
+ (WebCore::SVGElement::childrenChanged): Ditto.
+ (WebCore::SVGElement::setInstanceUpdatesBlocked): Added an assertion that will
+ catch anyone who nests InstanceUpdateBlocker by accident.
+ (WebCore::SVGElement::invalidateInstances): Moved this here from
+ SVGElementInstance::invalidateAllInstancesOfElement. I had already modified this
+ so it had nothing to do with SVGElementInstance, so it was a simple matter of
+ converting this into a member function. Added a FIXME about the mysterious
+ updateStyleIfNeeded that makes multiple tests fail if it's removed.
+
+ * svg/SVGElement.h: Added public InstanceUpdateBlocker class, protected
+ InstanceInvalidationGuard class, and private invalidateInstances function.
+ Unlike the ones in SVGElementInstance these use references so they are then
+ not copyable without using the WTF_MAKE_NONCOPYABLE macro.
+
+ * svg/SVGElementInstance.cpp:
+ (WebCore::SVGElementInstance::invalidateAllInstancesOfElement): Deleted.
+ (WebCore::SVGElementInstance::InstanceUpdateBlocker::InstanceUpdateBlocker): Deleted.
+ (WebCore::SVGElementInstance::InstanceUpdateBlocker::~InstanceUpdateBlocker): Deleted.
+ * svg/SVGElementInstance.h: Removed InvalidationGuard, InstanceUpdateBlocker, and
+ invalidateAllInstancesOfElement. Didn't do any further cleanup since we soon will
+ delete this entire file.
+
+ * svg/SVGAElement.cpp:
+ (WebCore::SVGAElement::svgAttributeChanged): Updated to use new name and reference
+ instead of pointer.
+ * svg/SVGAnimateElementBase.cpp:
+ (WebCore::applyCSSPropertyToTargetAndInstances): Ditto.
+ (WebCore::removeCSSPropertyFromTargetAndInstances): Ditto.
+ (WebCore::notifyTargetAndInstancesAboutAnimValChange): Ditto.
+ * svg/SVGAnimatedPath.cpp:
+ (WebCore::SVGAnimatedPathAnimator::startAnimValAnimation): Ditto.
+ * svg/SVGCircleElement.cpp:
+ (WebCore::SVGCircleElement::svgAttributeChanged): Ditto.
+ * svg/SVGClipPathElement.cpp:
+ (WebCore::SVGClipPathElement::svgAttributeChanged): Ditto.
+ * svg/SVGComponentTransferFunctionElement.cpp:
+ (WebCore::SVGComponentTransferFunctionElement::svgAttributeChanged): Ditto.
+ * svg/SVGCursorElement.cpp:
+ (WebCore::SVGCursorElement::svgAttributeChanged): Ditto.
+ * svg/SVGEllipseElement.cpp:
+ (WebCore::SVGEllipseElement::svgAttributeChanged): Ditto.
+ * svg/SVGFEBlendElement.cpp:
+ (WebCore::SVGFEBlendElement::svgAttributeChanged): Ditto.
+ * svg/SVGFEColorMatrixElement.cpp:
+ (WebCore::SVGFEColorMatrixElement::svgAttributeChanged): Ditto.
+ * svg/SVGFECompositeElement.cpp:
+ (WebCore::SVGFECompositeElement::svgAttributeChanged): Ditto.
+ * svg/SVGFEConvolveMatrixElement.cpp:
+ (WebCore::SVGFEConvolveMatrixElement::svgAttributeChanged): Ditto.
+ * svg/SVGFEDiffuseLightingElement.cpp:
+ (WebCore::SVGFEDiffuseLightingElement::svgAttributeChanged): Ditto.
+ * svg/SVGFEDisplacementMapElement.cpp:
+ (WebCore::SVGFEDisplacementMapElement::svgAttributeChanged): Ditto.
+ * svg/SVGFEDropShadowElement.cpp:
+ (WebCore::SVGFEDropShadowElement::svgAttributeChanged): Ditto.
+ * svg/SVGFEGaussianBlurElement.cpp:
+ (WebCore::SVGFEGaussianBlurElement::svgAttributeChanged): Ditto.
+ * svg/SVGFEImageElement.cpp:
+ (WebCore::SVGFEImageElement::svgAttributeChanged): Ditto.
+ * svg/SVGFELightElement.cpp:
+ (WebCore::SVGFELightElement::svgAttributeChanged): Ditto.
+ * svg/SVGFEMergeNodeElement.cpp:
+ (WebCore::SVGFEMergeNodeElement::svgAttributeChanged): Ditto.
+ * svg/SVGFEMorphologyElement.cpp:
+ (WebCore::SVGFEMorphologyElement::svgAttributeChanged): Ditto.
+ * svg/SVGFEOffsetElement.cpp:
+ (WebCore::SVGFEOffsetElement::svgAttributeChanged): Ditto.
+ * svg/SVGFESpecularLightingElement.cpp:
+ (WebCore::SVGFESpecularLightingElement::svgAttributeChanged): Ditto.
+ * svg/SVGFETileElement.cpp:
+ (WebCore::SVGFETileElement::svgAttributeChanged): Ditto.
+ * svg/SVGFETurbulenceElement.cpp:
+ (WebCore::SVGFETurbulenceElement::svgAttributeChanged): Ditto.
+ * svg/SVGFilterElement.cpp:
+ (WebCore::SVGFilterElement::svgAttributeChanged): Ditto.
+ * svg/SVGFilterPrimitiveStandardAttributes.cpp:
+ (WebCore::SVGFilterPrimitiveStandardAttributes::svgAttributeChanged): Ditto.
+ * svg/SVGForeignObjectElement.cpp:
+ (WebCore::SVGForeignObjectElement::svgAttributeChanged): Ditto.
+ * svg/SVGGElement.cpp:
+ (WebCore::SVGGElement::svgAttributeChanged): Ditto.
+ * svg/SVGGradientElement.cpp:
+ (WebCore::SVGGradientElement::svgAttributeChanged): Ditto.
+ * svg/SVGGraphicsElement.cpp:
+ (WebCore::SVGGraphicsElement::svgAttributeChanged): Ditto.
+ * svg/SVGImageElement.cpp:
+ (WebCore::SVGImageElement::svgAttributeChanged): Ditto.
+ * svg/SVGLineElement.cpp:
+ (WebCore::SVGLineElement::svgAttributeChanged): Ditto.
+ * svg/SVGLinearGradientElement.cpp:
+ (WebCore::SVGLinearGradientElement::svgAttributeChanged): Ditto.
+ * svg/SVGMPathElement.cpp:
+ (WebCore::SVGMPathElement::svgAttributeChanged): Ditto.
+ * svg/SVGMarkerElement.cpp:
+ (WebCore::SVGMarkerElement::svgAttributeChanged): Ditto.
+ * svg/SVGMaskElement.cpp:
+ (WebCore::SVGMaskElement::svgAttributeChanged): Ditto.
+ * svg/SVGPathElement.cpp:
+ (WebCore::SVGPathElement::svgAttributeChanged): Ditto.
+ * svg/SVGPatternElement.cpp:
+ (WebCore::SVGPatternElement::svgAttributeChanged): Ditto.
+ * svg/SVGPolyElement.cpp:
+ (WebCore::SVGPolyElement::svgAttributeChanged): Ditto.
+ * svg/SVGRadialGradientElement.cpp:
+ (WebCore::SVGRadialGradientElement::svgAttributeChanged): Ditto.
+ * svg/SVGRectElement.cpp:
+ (WebCore::SVGRectElement::svgAttributeChanged): Ditto.
+ * svg/SVGSVGElement.cpp:
+ (WebCore::SVGSVGElement::svgAttributeChanged): Ditto.
+ * svg/SVGScriptElement.cpp:
+ (WebCore::SVGScriptElement::svgAttributeChanged): Ditto.
+ * svg/SVGStopElement.cpp:
+ (WebCore::SVGStopElement::svgAttributeChanged): Ditto.
+ * svg/SVGSymbolElement.cpp:
+ (WebCore::SVGSymbolElement::svgAttributeChanged): Ditto.
+ * svg/SVGTRefElement.cpp:
+ (WebCore::SVGTRefElement::svgAttributeChanged): Ditto.
+ * svg/SVGTextContentElement.cpp:
+ (WebCore::SVGTextContentElement::svgAttributeChanged): Ditto.
+ * svg/SVGTextPathElement.cpp:
+ (WebCore::SVGTextPathElement::svgAttributeChanged): Ditto.
+ * svg/SVGTextPositioningElement.cpp:
+ (WebCore::SVGTextPositioningElement::svgAttributeChanged): Ditto.
+ * svg/SVGUseElement.cpp:
+ (WebCore::SVGUseElement::svgAttributeChanged): Ditto.
+ * svg/animation/SVGSMILElement.cpp:
+ (WebCore::SVGSMILElement::svgAttributeChanged): Ditto.
+
2015-02-02 Darin Adler <darin@apple.com>
REGRESSION (r170576): Storage leaks in parsing of CSS image sizes
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
// Unlike other SVG*Element classes, SVGAElement only listens to SVGURIReference changes
// as none of the other properties changes the linking behaviour for our <a> element.
CSSPropertyID id = cssPropertyID(attributeName.localName());
- SVGElementInstance::InstanceUpdateBlocker blocker(&targetElement);
+ 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.
CSSPropertyID id = cssPropertyID(attributeName.localName());
- SVGElementInstance::InstanceUpdateBlocker blocker(&targetElement);
+ SVGElement::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.
if (attributeName == anyQName() || !targetElement.inDocument() || !targetElement.parentNode())
return;
- SVGElementInstance::InstanceUpdateBlocker blocker(&targetElement);
+ 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 (SVGElementAnimatedPropertyList::const_iterator it = animatedTypes.begin(); it != end; ++it)
result.append(castAnimatedPropertyToActualType<SVGAnimatedPathSegListPropertyTearOff>(it->properties[0].get()));
- SVGElementInstance::InstanceUpdateBlocker blocker(property->contextElement());
+ SVGElement::InstanceUpdateBlocker blocker(*property->contextElement());
size_t resultSize = result.size();
for (size_t i = 0; i < resultSize; ++i)
return result;
}
+void SVGAnimatedTypeAnimator::setInstanceUpdatesBlocked(SVGElement& element, bool blocked)
+{
+ element.setInstanceUpdatesBlocked(blocked);
+}
+
} // namespace WebCore
template<typename AnimValType>
void executeAction(AnimationAction action, const SVGElementAnimatedPropertyList& animatedTypes, unsigned whichProperty, typename AnimValType::ContentType* type = 0)
{
- SVGElementInstance::InstanceUpdateBlocker blocker(animatedTypes[0].element);
+ // FIXME: Can't use SVGElement::InstanceUpdateBlocker because of circular header dependency. Would be nice to untangle this.
+ setInstanceUpdatesBlocked(*animatedTypes[0].element, true);
SVGElementAnimatedPropertyList::const_iterator end = animatedTypes.end();
for (SVGElementAnimatedPropertyList::const_iterator it = animatedTypes.begin(); it != end; ++it) {
break;
}
}
+
+ setInstanceUpdatesBlocked(*animatedTypes[0].element, false);
}
+
+ static void setInstanceUpdatesBlocked(SVGElement&, bool);
};
} // namespace WebCore
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
if (attrName == SVGNames::cxAttr
|| attrName == SVGNames::cyAttr
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
if (RenderObject* object = renderer())
object->setNeedsLayout();
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
invalidateFilterPrimitiveParent(this);
}
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
// Any change of a cursor specific attribute triggers this recalc.
HashSet<SVGElement*>::const_iterator it = m_clients.begin();
document().accessSVGExtensions().clearTargetDependencies(*this);
document().accessSVGExtensions().removeAllElementReferencesForTarget(this);
}
- SVGElementInstance::invalidateAllInstancesOfElement(this);
+ invalidateInstances();
}
SVGSVGElement* SVGElement::ownerSVGElement() const
// Notify all the elements which have references to this element to rebuild their shadow and render
// trees, e.g. a <use> element references a target element before this target element is defined.
- SVGElementInstance::invalidateAllInstancesOfElement(this);
+ invalidateInstances();
}
bool SVGElement::childShouldCreateRenderer(const Node& child) const
{
CSSPropertyID propId = cssPropertyIdForSVGAttributeName(attrName);
if (propId > 0) {
- SVGElementInstance::invalidateAllInstancesOfElement(this);
+ invalidateInstances();
return;
}
if (attrName == HTMLNames::classAttr) {
classAttributeChanged(className());
- SVGElementInstance::invalidateAllInstancesOfElement(this);
+ invalidateInstances();
return;
}
downcast<RenderSVGResourceContainer>(*renderer).idChanged();
if (inDocument())
buildPendingResourcesIfNeeded();
- SVGElementInstance::invalidateAllInstancesOfElement(this);
+ invalidateInstances();
return;
}
}
if (change.source == ChildChangeSourceParser)
return;
- SVGElementInstance::invalidateAllInstancesOfElement(this);
+ invalidateInstances();
}
RefPtr<CSSValue> SVGElement::getPresentationAttribute(const String& name)
void SVGElement::setInstanceUpdatesBlocked(bool value)
{
+ // Catch any callers that calls setInstanceUpdatesBlocked(true) twice in a row.
+ // That probably indicates nested use of InstanceUpdateBlocker and a bug.
+ ASSERT(!value || !instanceUpdatesBlocked());
+
if (m_svgRareData)
m_svgRareData->setInstanceUpdatesBlocked(value);
}
dispatchSimulatedClick(0, sendMouseEvents ? SendMouseUpDownEvents : SendNoEvents);
}
+void SVGElement::invalidateInstances()
+{
+ if (!inDocument())
+ return;
+
+ if (instanceUpdatesBlocked())
+ return;
+
+ auto& instances = this->instances();
+ if (instances.isEmpty())
+ return;
+
+ // Mark all use elements referencing 'element' for rebuilding
+ do {
+ SVGElement* instance = *instances.begin();
+ if (SVGUseElement* element = instance->correspondingUseElement()) {
+ ASSERT(element->inDocument());
+ element->invalidateShadowTree();
+ }
+ instance->setCorrespondingElement(nullptr);
+ } while (!instances.isEmpty());
+
+ // FIXME: Why is this needed?
+ document().updateStyleIfNeeded();
+}
+
}
void callClearTarget() { clearTarget(); }
+ class InstanceUpdateBlocker;
+
protected:
SVGElement(const QualifiedName&, Document&);
virtual ~SVGElement();
void updateRelativeLengthsInformation() { updateRelativeLengthsInformation(selfHasRelativeLengths(), this); }
void updateRelativeLengthsInformation(bool hasRelativeLengths, SVGElement*);
+ class InstanceInvalidationGuard;
+
private:
friend class SVGElementInstance;
virtual bool filterOutAnimatableAttribute(const QualifiedName&) const;
#endif
+ void invalidateInstances();
+
std::unique_ptr<SVGElementRareData> m_svgRareData;
HashSet<SVGElement*> m_elementsWithRelativeLengths;
};
+class SVGElement::InstanceInvalidationGuard {
+public:
+ InstanceInvalidationGuard(SVGElement&);
+ ~InstanceInvalidationGuard();
+private:
+ SVGElement& m_element;
+};
+
+class SVGElement::InstanceUpdateBlocker {
+public:
+ InstanceUpdateBlocker(SVGElement&);
+ ~InstanceUpdateBlocker();
+private:
+ SVGElement& m_element;
+};
+
struct SVGAttributeHashTranslator {
static unsigned hash(const QualifiedName& key)
{
static bool equal(const QualifiedName& a, const QualifiedName& b) { return a.matches(b); }
};
+inline SVGElement::InstanceInvalidationGuard::InstanceInvalidationGuard(SVGElement& element)
+ : m_element(element)
+{
+}
+
+inline SVGElement::InstanceInvalidationGuard::~InstanceInvalidationGuard()
+{
+ m_element.invalidateInstances();
+}
+
+inline SVGElement::InstanceUpdateBlocker::InstanceUpdateBlocker(SVGElement& element)
+ : m_element(element)
+{
+ m_element.setInstanceUpdatesBlocked(true);
+}
+
+inline SVGElement::InstanceUpdateBlocker::~InstanceUpdateBlocker()
+{
+ ASSERT(m_element.instanceUpdatesBlocked());
+ m_element.setInstanceUpdatesBlocked(false);
+}
+
inline bool Node::hasTagName(const SVGQualifiedName& name) const
{
return isSVGElement() && downcast<SVGElement>(*this).hasTagName(name);
appendChildToContainer<SVGElementInstance, SVGElementInstance>(child.get(), *this);
}
-void SVGElementInstance::invalidateAllInstancesOfElement(SVGElement* element)
-{
- if (!element || !element->inDocument())
- return;
-
- if (element->instanceUpdatesBlocked())
- return;
-
- auto& instances = element->instances();
- if (instances.isEmpty())
- return;
-
- // Mark all use elements referencing 'element' for rebuilding
- do {
- SVGElement* instance = *instances.begin();
- if (SVGUseElement* element = instance->correspondingUseElement()) {
- ASSERT(element->inDocument());
- element->invalidateShadowTree();
- }
- instance->setCorrespondingElement(nullptr);
- } while (!instances.isEmpty());
-
- element->document().updateStyleIfNeeded();
-}
-
EventTargetInterface SVGElementInstance::eventTargetInterface() const
{
return SVGElementInstanceEventTargetInterfaceType;
return *eventTargetData();
}
-SVGElementInstance::InstanceUpdateBlocker::InstanceUpdateBlocker(SVGElement* targetElement)
- : m_targetElement(targetElement)
-{
- if (m_targetElement)
- m_targetElement->setInstanceUpdatesBlocked(true);
-}
-
-SVGElementInstance::InstanceUpdateBlocker::~InstanceUpdateBlocker()
-{
- if (m_targetElement)
- m_targetElement->setInstanceUpdatesBlocked(false);
-}
-
}
Document* ownerDocument() const;
- class InvalidationGuard {
- WTF_MAKE_NONCOPYABLE(InvalidationGuard);
- public:
- InvalidationGuard(SVGElement* element) : m_element(element) { }
- ~InvalidationGuard() { SVGElementInstance::invalidateAllInstancesOfElement(m_element); }
- private:
- SVGElement* m_element;
- };
-
- class InstanceUpdateBlocker {
- WTF_MAKE_NONCOPYABLE(InstanceUpdateBlocker);
- public:
- InstanceUpdateBlocker(SVGElement* targetElement);
- ~InstanceUpdateBlocker();
-
- private:
- SVGElement* m_targetElement;
- };
-
- static void invalidateAllInstancesOfElement(SVGElement*);
-
using TreeShared<SVGElementInstance>::ref;
using TreeShared<SVGElementInstance>::deref;
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
if (attrName == SVGNames::cxAttr
|| attrName == SVGNames::cyAttr
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
if (attrName == SVGNames::modeAttr) {
primitiveAttributeChanged(attrName);
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
if (attrName == SVGNames::typeAttr || attrName == SVGNames::valuesAttr) {
primitiveAttributeChanged(attrName);
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
if (attrName == SVGNames::operatorAttr
|| attrName == SVGNames::k1Attr
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
if (attrName == SVGNames::edgeModeAttr
|| attrName == SVGNames::divisorAttr
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
if (attrName == SVGNames::surfaceScaleAttr
|| attrName == SVGNames::diffuseConstantAttr
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
if (attrName == SVGNames::xChannelSelectorAttr || attrName == SVGNames::yChannelSelectorAttr || attrName == SVGNames::scaleAttr) {
primitiveAttributeChanged(attrName);
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
if (attrName == SVGNames::inAttr
|| attrName == SVGNames::stdDeviationAttr
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
if (attrName == SVGNames::inAttr
|| attrName == SVGNames::stdDeviationAttr
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
if (attrName == SVGNames::preserveAspectRatioAttr) {
invalidate();
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
if (attrName == SVGNames::azimuthAttr
|| attrName == SVGNames::elevationAttr
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
if (attrName == SVGNames::inAttr) {
invalidateFilterPrimitiveParent(this);
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
if (attrName == SVGNames::operatorAttr || attrName == SVGNames::radiusAttr) {
primitiveAttributeChanged(attrName);
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
if (attrName == SVGNames::inAttr || attrName == SVGNames::dxAttr || attrName == SVGNames::dyAttr) {
invalidate();
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
if (attrName == SVGNames::surfaceScaleAttr
|| attrName == SVGNames::specularConstantAttr
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
if (attrName == SVGNames::inAttr) {
invalidate();
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
if (attrName == SVGNames::baseFrequencyAttr
|| attrName == SVGNames::numOctavesAttr
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
if (attrName == SVGNames::xAttr
|| attrName == SVGNames::yAttr
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
invalidate();
}
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
if (attrName == SVGNames::widthAttr
|| attrName == SVGNames::heightAttr) {
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
if (auto renderer = this->renderer())
RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer);
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
if (RenderObject* object = renderer())
object->setNeedsLayout();
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
if (SVGTests::handleAttributeChange(this, attrName))
return;
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
if (attrName == SVGNames::widthAttr
|| attrName == SVGNames::heightAttr) {
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
bool isLengthAttribute = attrName == SVGNames::x1Attr
|| attrName == SVGNames::y1Attr
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
updateRelativeLengthsInformation();
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
if (SVGURIReference::isKnownAttribute(attrName)) {
buildPendingResource();
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
if (attrName == SVGNames::refXAttr
|| attrName == SVGNames::refYAttr
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
if (attrName == SVGNames::xAttr
|| attrName == SVGNames::yAttr
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
RenderSVGPath* renderer = downcast<RenderSVGPath>(this->renderer());
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
if (attrName == SVGNames::xAttr
|| attrName == SVGNames::yAttr
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
auto* renderer = downcast<RenderSVGShape>(this->renderer());
if (!renderer)
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
updateRelativeLengthsInformation();
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
if (attrName == SVGNames::xAttr
|| attrName == SVGNames::yAttr
object->setNeedsTransformUpdate();
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
if (updateRelativeLengthsOrViewBox
|| SVGLangSpace::isKnownAttribute(attrName)
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
if (attrName == SVGNames::typeAttr || attrName == HTMLNames::onerrorAttr)
return;
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
if (attrName == SVGNames::offsetAttr) {
if (auto renderer = this->renderer())
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
// Every other property change is ignored.
if (attrName == SVGNames::viewBoxAttr)
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
if (SVGURIReference::isKnownAttribute(attrName)) {
buildPendingResource();
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
if (attrName == SVGNames::textLengthAttr)
m_specifiedTextLength = m_textLength.value;
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
if (SVGURIReference::isKnownAttribute(attrName)) {
buildPendingResource();
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
bool updateRelativeLengths = attrName == SVGNames::xAttr
|| attrName == SVGNames::yAttr
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr || attrName == SVGNames::widthAttr || attrName == SVGNames::heightAttr) {
updateRelativeLengthsInformation();
else if (attrName == SVGNames::attributeNameAttr)
setAttributeName(constructQualifiedName(this, fastGetAttribute(SVGNames::attributeNameAttr)));
else if (attrName.matches(XLinkNames::hrefAttr)) {
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ InstanceInvalidationGuard guard(*this);
buildPendingResource();
} else if (inDocument()) {
if (attrName == SVGNames::beginAttr)