2011-05-21 Nikolas Zimmermann <nzimmermann@rim.com>
authorzimmermann@webkit.org <zimmermann@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 21 May 2011 06:15:40 +0000 (06:15 +0000)
committerzimmermann@webkit.org <zimmermann@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 21 May 2011 06:15:40 +0000 (06:15 +0000)
        Reviewed by Rob Buis.

        SVG svgAttributeChanged/synchronizeProperty/parseMappedAttribute should be optimized
        https://bugs.webkit.org/show_bug.cgi?id=61183

        Example: rect.x.baseVal.value = 100;
        What happens: SVGRectElement::svgAttributeChanged(const QualifiedName& attrName) is invoked with "SVGNames::rectAttr" as parameter.

        void SVGRectElement::svgAttributeChanged(const QualifiedName& attrName)
        {
            SVGStyledTransformableElement::svgAttributeChanged(attrName);
            // Handle my own attribute changes...
        }

        Currently we always traverse the base class hierarchy, when invoking svgAttributeChanged. Every svgAttributeChanged call from a class
        like SVGRectElement has to reach the base class SVGStyledElement::svgAttributeChanged, as it handles invalidation of the instances of
        an element. Say that a <rect> is referenced by a <use> and we change the 'x' attribute of the <rect>, then SVGStyledElement::svgAttributeChanged,
        calls SVGElementInstance::invalidateAllInstancesOfElement(this), so that the <use> can rebuild its shadow tree...
        That's the only reason all svgAttributeChanged implementations call the base class immediately, so SVGStyledElement is always reached.

        Switch to a more efficient pattern, by providing a "bool isSupportedAttribute(const QualifiedName&);" function for all SVG*Elements.
        It contains all attributes the particular SVG*Element class handles (but not its parent classes attributes). For example SVGRectElement
        contains x/y/width/height/rx/ry attributes, and the ones from SVGTests/SVGLangSpace/SVGExternalResourcesRequired (xml:space/lang, etc.),
        but not eg. transform as that's handled by the parent class SVGStyledTransformableElement.

        void SVGRectElement::svgAttributeChanged(const QualifiedName& attrName)
        {
            if (!isSupportedAttribute.contains(attrName)) {
                SVGStyledTransformableElement::svgAttributeChanged(attrName);
                return;
            }

            // When we get here, we know for sure it's one of our attributes that has changed.
            // Note for eg. SVGNames::transformAttr, the call from SVGRectElement::svgAttributeChanged, would be immediately forwarded to the base class, which handles transformAttr changes)

            if (attrName == SVGNames::xAttr) { do_work(); return; }
            if (attrName == SVGNames::yAttr) { do_work(); return; }
            ...
            // Assure that we handled all properties we claim support for in "isSupportedAttribute()".
            ASSERT_NOT_REACHED();
        }

        Exactly the same pattern can be applied to synchronizeProperty and parseMappedAttribute to speed them up as well.

        Add "SVGElementInstance::InvalidationGuard guard(this)" statements in all svgAttributeChanged implementations, that calls invalidateAllInstancesOfElement(this)
        upon destruction, after we've reacted to the svg attribute change. This assures we never forget to call the invalidation method anywhere, and don't
        need to rely on the base class svgAttributeChanged() call to do it.

        It's a slight overal performance progression.

        * svg/SVGAElement.cpp:
        (WebCore::SVGAElement::isSupportedAttribute):
        (WebCore::SVGAElement::parseMappedAttribute):
        (WebCore::SVGAElement::svgAttributeChanged):
        (WebCore::SVGAElement::synchronizeProperty):
        * svg/SVGAElement.h:
        * svg/SVGAnimateMotionElement.cpp:
        (WebCore::SVGAnimateMotionElement::isSupportedAttribute):
        (WebCore::SVGAnimateMotionElement::parseMappedAttribute):
        * svg/SVGAnimateMotionElement.h:
        * svg/SVGAnimateTransformElement.cpp:
        (WebCore::SVGAnimateTransformElement::isSupportedAttribute):
        (WebCore::SVGAnimateTransformElement::parseMappedAttribute):
        * svg/SVGAnimateTransformElement.h:
        * svg/SVGAnimationElement.cpp:
        (WebCore::SVGAnimationElement::isSupportedAttribute):
        (WebCore::SVGAnimationElement::parseMappedAttribute):
        * svg/SVGAnimationElement.h:
        * svg/SVGCircleElement.cpp:
        (WebCore::SVGCircleElement::isSupportedAttribute):
        (WebCore::SVGCircleElement::parseMappedAttribute):
        (WebCore::SVGCircleElement::svgAttributeChanged):
        (WebCore::SVGCircleElement::synchronizeProperty):
        * svg/SVGCircleElement.h:
        * svg/SVGClipPathElement.cpp:
        (WebCore::SVGClipPathElement::isSupportedAttribute):
        (WebCore::SVGClipPathElement::parseMappedAttribute):
        (WebCore::SVGClipPathElement::svgAttributeChanged):
        (WebCore::SVGClipPathElement::synchronizeProperty):
        * svg/SVGClipPathElement.h:
        * svg/SVGComponentTransferFunctionElement.cpp:
        (WebCore::SVGComponentTransferFunctionElement::isSupportedAttribute):
        (WebCore::SVGComponentTransferFunctionElement::parseMappedAttribute):
        (WebCore::SVGComponentTransferFunctionElement::synchronizeProperty):
        * svg/SVGComponentTransferFunctionElement.h:
        * svg/SVGCursorElement.cpp:
        (WebCore::SVGCursorElement::isSupportedAttribute):
        (WebCore::SVGCursorElement::parseMappedAttribute):
        (WebCore::SVGCursorElement::svgAttributeChanged):
        (WebCore::SVGCursorElement::synchronizeProperty):
        * svg/SVGCursorElement.h:
        * svg/SVGElementInstance.h:
        (WebCore::SVGElementInstance::InvalidationGuard::InvalidationGuard):
        (WebCore::SVGElementInstance::InvalidationGuard::~InvalidationGuard):
        * svg/SVGEllipseElement.cpp:
        (WebCore::SVGEllipseElement::isSupportedAttribute):
        (WebCore::SVGEllipseElement::parseMappedAttribute):
        (WebCore::SVGEllipseElement::svgAttributeChanged):
        (WebCore::SVGEllipseElement::synchronizeProperty):
        * svg/SVGEllipseElement.h:
        * svg/SVGExternalResourcesRequired.cpp:
        (WebCore::SVGExternalResourcesRequired::addSupportedAttributes):
        * svg/SVGExternalResourcesRequired.h:
        * svg/SVGFEBlendElement.cpp:
        (WebCore::SVGFEBlendElement::isSupportedAttribute):
        (WebCore::SVGFEBlendElement::parseMappedAttribute):
        (WebCore::SVGFEBlendElement::svgAttributeChanged):
        (WebCore::SVGFEBlendElement::synchronizeProperty):
        * svg/SVGFEBlendElement.h:
        * svg/SVGFEColorMatrixElement.cpp:
        (WebCore::SVGFEColorMatrixElement::isSupportedAttribute):
        (WebCore::SVGFEColorMatrixElement::parseMappedAttribute):
        (WebCore::SVGFEColorMatrixElement::svgAttributeChanged):
        (WebCore::SVGFEColorMatrixElement::synchronizeProperty):
        * svg/SVGFEColorMatrixElement.h:
        * svg/SVGFEComponentTransferElement.cpp:
        (WebCore::SVGFEComponentTransferElement::isSupportedAttribute):
        (WebCore::SVGFEComponentTransferElement::parseMappedAttribute):
        (WebCore::SVGFEComponentTransferElement::synchronizeProperty):
        * svg/SVGFEComponentTransferElement.h:
        * svg/SVGFECompositeElement.cpp:
        (WebCore::SVGFECompositeElement::isSupportedAttribute):
        (WebCore::SVGFECompositeElement::parseMappedAttribute):
        (WebCore::SVGFECompositeElement::svgAttributeChanged):
        (WebCore::SVGFECompositeElement::synchronizeProperty):
        * svg/SVGFECompositeElement.h:
        * svg/SVGFEConvolveMatrixElement.cpp:
        (WebCore::SVGFEConvolveMatrixElement::isSupportedAttribute):
        (WebCore::SVGFEConvolveMatrixElement::parseMappedAttribute):
        (WebCore::SVGFEConvolveMatrixElement::svgAttributeChanged):
        (WebCore::SVGFEConvolveMatrixElement::synchronizeProperty):
        * svg/SVGFEConvolveMatrixElement.h:
        * svg/SVGFEDiffuseLightingElement.cpp:
        (WebCore::SVGFEDiffuseLightingElement::isSupportedAttribute):
        (WebCore::SVGFEDiffuseLightingElement::parseMappedAttribute):
        (WebCore::SVGFEDiffuseLightingElement::svgAttributeChanged):
        (WebCore::SVGFEDiffuseLightingElement::synchronizeProperty):
        * svg/SVGFEDiffuseLightingElement.h:
        * svg/SVGFEDisplacementMapElement.cpp:
        (WebCore::SVGFEDisplacementMapElement::isSupportedAttribute):
        (WebCore::SVGFEDisplacementMapElement::parseMappedAttribute):
        (WebCore::SVGFEDisplacementMapElement::svgAttributeChanged):
        (WebCore::SVGFEDisplacementMapElement::synchronizeProperty):
        * svg/SVGFEDisplacementMapElement.h:
        * svg/SVGFEDropShadowElement.cpp:
        (WebCore::SVGFEDropShadowElement::isSupportedAttribute):
        (WebCore::SVGFEDropShadowElement::parseMappedAttribute):
        (WebCore::SVGFEDropShadowElement::svgAttributeChanged):
        (WebCore::SVGFEDropShadowElement::synchronizeProperty):
        * svg/SVGFEDropShadowElement.h:
        * svg/SVGFEGaussianBlurElement.cpp:
        (WebCore::SVGFEGaussianBlurElement::isSupportedAttribute):
        (WebCore::SVGFEGaussianBlurElement::parseMappedAttribute):
        (WebCore::SVGFEGaussianBlurElement::svgAttributeChanged):
        (WebCore::SVGFEGaussianBlurElement::synchronizeProperty):
        * svg/SVGFEGaussianBlurElement.h:
        * svg/SVGFEImageElement.cpp:
        (WebCore::SVGFEImageElement::isSupportedAttribute):
        (WebCore::SVGFEImageElement::parseMappedAttribute):
        (WebCore::SVGFEImageElement::svgAttributeChanged):
        (WebCore::SVGFEImageElement::synchronizeProperty):
        * svg/SVGFEImageElement.h:
        * svg/SVGFELightElement.cpp:
        (WebCore::SVGFELightElement::isSupportedAttribute):
        (WebCore::SVGFELightElement::parseMappedAttribute):
        (WebCore::SVGFELightElement::svgAttributeChanged):
        (WebCore::SVGFELightElement::synchronizeProperty):
        * svg/SVGFELightElement.h:
        * svg/SVGFEMergeNodeElement.cpp:
        (WebCore::SVGFEMergeNodeElement::isSupportedAttribute):
        (WebCore::SVGFEMergeNodeElement::parseMappedAttribute):
        (WebCore::SVGFEMergeNodeElement::svgAttributeChanged):
        (WebCore::SVGFEMergeNodeElement::synchronizeProperty):
        * svg/SVGFEMergeNodeElement.h:
        * svg/SVGFEMorphologyElement.cpp:
        (WebCore::SVGFEMorphologyElement::isSupportedAttribute):
        (WebCore::SVGFEMorphologyElement::parseMappedAttribute):
        (WebCore::SVGFEMorphologyElement::svgAttributeChanged):
        (WebCore::SVGFEMorphologyElement::synchronizeProperty):
        * svg/SVGFEMorphologyElement.h:
        * svg/SVGFEOffsetElement.cpp:
        (WebCore::SVGFEOffsetElement::isSupportedAttribute):
        (WebCore::SVGFEOffsetElement::parseMappedAttribute):
        (WebCore::SVGFEOffsetElement::svgAttributeChanged):
        (WebCore::SVGFEOffsetElement::synchronizeProperty):
        * svg/SVGFEOffsetElement.h:
        * svg/SVGFESpecularLightingElement.cpp:
        (WebCore::SVGFESpecularLightingElement::isSupportedAttribute):
        (WebCore::SVGFESpecularLightingElement::parseMappedAttribute):
        (WebCore::SVGFESpecularLightingElement::svgAttributeChanged):
        (WebCore::SVGFESpecularLightingElement::synchronizeProperty):
        * svg/SVGFESpecularLightingElement.h:
        * svg/SVGFETileElement.cpp:
        (WebCore::SVGFETileElement::isSupportedAttribute):
        (WebCore::SVGFETileElement::parseMappedAttribute):
        (WebCore::SVGFETileElement::svgAttributeChanged):
        (WebCore::SVGFETileElement::synchronizeProperty):
        * svg/SVGFETileElement.h:
        * svg/SVGFETurbulenceElement.cpp:
        (WebCore::SVGFETurbulenceElement::isSupportedAttribute):
        (WebCore::SVGFETurbulenceElement::parseMappedAttribute):
        (WebCore::SVGFETurbulenceElement::svgAttributeChanged):
        (WebCore::SVGFETurbulenceElement::synchronizeProperty):
        * svg/SVGFETurbulenceElement.h:
        * svg/SVGFilterElement.cpp:
        (WebCore::SVGFilterElement::isSupportedAttribute):
        (WebCore::SVGFilterElement::parseMappedAttribute):
        (WebCore::SVGFilterElement::svgAttributeChanged):
        (WebCore::SVGFilterElement::synchronizeProperty):
        * svg/SVGFilterElement.h:
        * svg/SVGFilterPrimitiveStandardAttributes.cpp:
        (WebCore::SVGFilterPrimitiveStandardAttributes::isSupportedAttribute):
        (WebCore::SVGFilterPrimitiveStandardAttributes::parseMappedAttribute):
        (WebCore::SVGFilterPrimitiveStandardAttributes::svgAttributeChanged):
        (WebCore::SVGFilterPrimitiveStandardAttributes::synchronizeProperty):
        * svg/SVGFilterPrimitiveStandardAttributes.h:
        * svg/SVGFitToViewBox.cpp:
        (WebCore::SVGFitToViewBox::parseMappedAttribute):
        (WebCore::SVGFitToViewBox::synchronizeProperties):
        (WebCore::SVGFitToViewBox::addSupportedAttributes):
        * svg/SVGFitToViewBox.h:
        * svg/SVGForeignObjectElement.cpp:
        (WebCore::SVGForeignObjectElement::isSupportedAttribute):
        (WebCore::SVGForeignObjectElement::parseMappedAttribute):
        (WebCore::SVGForeignObjectElement::svgAttributeChanged):
        (WebCore::SVGForeignObjectElement::synchronizeProperty):
        * svg/SVGForeignObjectElement.h:
        * svg/SVGGElement.cpp:
        (WebCore::SVGGElement::isSupportedAttribute):
        (WebCore::SVGGElement::parseMappedAttribute):
        (WebCore::SVGGElement::svgAttributeChanged):
        (WebCore::SVGGElement::synchronizeProperty):
        * svg/SVGGElement.h:
        * svg/SVGGradientElement.cpp:
        (WebCore::SVGGradientElement::isSupportedAttribute):
        (WebCore::SVGGradientElement::parseMappedAttribute):
        (WebCore::SVGGradientElement::svgAttributeChanged):
        (WebCore::SVGGradientElement::synchronizeProperty):
        * svg/SVGGradientElement.h:
        * svg/SVGImageElement.cpp:
        (WebCore::SVGImageElement::isSupportedAttribute):
        (WebCore::SVGImageElement::parseMappedAttribute):
        (WebCore::SVGImageElement::svgAttributeChanged):
        (WebCore::SVGImageElement::synchronizeProperty):
        * svg/SVGImageElement.h:
        * svg/SVGLangSpace.cpp:
        (WebCore::SVGLangSpace::addSupportedAttributes):
        * svg/SVGLangSpace.h:
        * svg/SVGLineElement.cpp:
        (WebCore::SVGLineElement::isSupportedAttribute):
        (WebCore::SVGLineElement::parseMappedAttribute):
        (WebCore::SVGLineElement::svgAttributeChanged):
        (WebCore::SVGLineElement::synchronizeProperty):
        * svg/SVGLineElement.h:
        * svg/SVGLinearGradientElement.cpp:
        (WebCore::SVGLinearGradientElement::isSupportedAttribute):
        (WebCore::SVGLinearGradientElement::parseMappedAttribute):
        (WebCore::SVGLinearGradientElement::svgAttributeChanged):
        (WebCore::SVGLinearGradientElement::synchronizeProperty):
        * svg/SVGLinearGradientElement.h:
        * svg/SVGMPathElement.cpp:
        (WebCore::SVGMPathElement::isSupportedAttribute):
        (WebCore::SVGMPathElement::parseMappedAttribute):
        (WebCore::SVGMPathElement::synchronizeProperty):
        * svg/SVGMPathElement.h:
        * svg/SVGMarkerElement.cpp:
        (WebCore::SVGMarkerElement::isSupportedAttribute):
        (WebCore::SVGMarkerElement::parseMappedAttribute):
        (WebCore::SVGMarkerElement::svgAttributeChanged):
        (WebCore::SVGMarkerElement::synchronizeProperty):
        * svg/SVGMarkerElement.h:
        * svg/SVGMaskElement.cpp:
        (WebCore::SVGMaskElement::isSupportedAttribute):
        (WebCore::SVGMaskElement::parseMappedAttribute):
        (WebCore::SVGMaskElement::svgAttributeChanged):
        (WebCore::SVGMaskElement::synchronizeProperty):
        * svg/SVGMaskElement.h:
        * svg/SVGPathElement.cpp:
        (WebCore::SVGPathElement::isSupportedAttribute):
        (WebCore::SVGPathElement::parseMappedAttribute):
        (WebCore::SVGPathElement::svgAttributeChanged):
        (WebCore::SVGPathElement::synchronizeProperty):
        * svg/SVGPathElement.h:
        * svg/SVGPatternElement.cpp:
        (WebCore::SVGPatternElement::isSupportedAttribute):
        (WebCore::SVGPatternElement::parseMappedAttribute):
        (WebCore::SVGPatternElement::svgAttributeChanged):
        (WebCore::SVGPatternElement::synchronizeProperty):
        * svg/SVGPatternElement.h:
        * svg/SVGPolyElement.cpp:
        (WebCore::SVGPolyElement::isSupportedAttribute):
        (WebCore::SVGPolyElement::parseMappedAttribute):
        (WebCore::SVGPolyElement::svgAttributeChanged):
        * svg/SVGPolyElement.h:
        * svg/SVGRadialGradientElement.cpp:
        (WebCore::SVGRadialGradientElement::isSupportedAttribute):
        (WebCore::SVGRadialGradientElement::parseMappedAttribute):
        (WebCore::SVGRadialGradientElement::svgAttributeChanged):
        (WebCore::SVGRadialGradientElement::synchronizeProperty):
        * svg/SVGRadialGradientElement.h:
        * svg/SVGRectElement.cpp:
        (WebCore::SVGRectElement::isSupportedAttribute):
        (WebCore::SVGRectElement::parseMappedAttribute):
        (WebCore::SVGRectElement::svgAttributeChanged):
        (WebCore::SVGRectElement::synchronizeProperty):
        * svg/SVGRectElement.h:
        * svg/SVGSVGElement.cpp:
        (WebCore::SVGSVGElement::svgAttributeChanged):
        (WebCore::SVGSVGElement::synchronizeProperty):
        * svg/SVGScriptElement.cpp:
        (WebCore::SVGScriptElement::isSupportedAttribute):
        (WebCore::SVGScriptElement::parseMappedAttribute):
        (WebCore::SVGScriptElement::svgAttributeChanged):
        (WebCore::SVGScriptElement::synchronizeProperty):
        * svg/SVGScriptElement.h:
        * svg/SVGStopElement.cpp:
        (WebCore::SVGStopElement::isSupportedAttribute):
        (WebCore::SVGStopElement::parseMappedAttribute):
        (WebCore::SVGStopElement::svgAttributeChanged):
        (WebCore::SVGStopElement::synchronizeProperty):
        * svg/SVGStopElement.h:
        * svg/SVGStyleElement.cpp:
        (WebCore::SVGStyleElement::isSupportedAttribute):
        (WebCore::SVGStyleElement::parseMappedAttribute):
        * svg/SVGStyleElement.h:
        * svg/SVGStyledElement.cpp:
        (WebCore::SVGStyledElement::parseMappedAttribute):
        (WebCore::SVGStyledElement::svgAttributeChanged):
        (WebCore::SVGStyledElement::synchronizeProperty):
        * svg/SVGStyledTransformableElement.cpp:
        (WebCore::SVGStyledTransformableElement::isSupportedAttribute):
        (WebCore::SVGStyledTransformableElement::parseMappedAttribute):
        (WebCore::SVGStyledTransformableElement::svgAttributeChanged):
        (WebCore::SVGStyledTransformableElement::synchronizeProperty):
        * svg/SVGStyledTransformableElement.h:
        * svg/SVGSymbolElement.cpp:
        (WebCore::SVGSymbolElement::isSupportedAttribute):
        (WebCore::SVGSymbolElement::parseMappedAttribute):
        (WebCore::SVGSymbolElement::svgAttributeChanged):
        (WebCore::SVGSymbolElement::synchronizeProperty):
        * svg/SVGSymbolElement.h:
        * svg/SVGTRefElement.cpp:
        (WebCore::SVGTRefElement::isSupportedAttribute):
        (WebCore::SVGTRefElement::parseMappedAttribute):
        (WebCore::SVGTRefElement::svgAttributeChanged):
        (WebCore::SVGTRefElement::synchronizeProperty):
        * svg/SVGTRefElement.h:
        * svg/SVGTests.cpp:
        (WebCore::SVGTests::addSupportedAttributes):
        * svg/SVGTests.h:
        * svg/SVGTextContentElement.cpp:
        (WebCore::SVGTextContentElement::isSupportedAttribute):
        (WebCore::SVGTextContentElement::parseMappedAttribute):
        (WebCore::SVGTextContentElement::synchronizeProperty):
        (WebCore::SVGTextContentElement::svgAttributeChanged):
        * svg/SVGTextContentElement.h:
        * svg/SVGTextElement.cpp:
        (WebCore::SVGTextElement::isSupportedAttribute):
        (WebCore::SVGTextElement::parseMappedAttribute):
        (WebCore::SVGTextElement::svgAttributeChanged):
        (WebCore::SVGTextElement::synchronizeProperty):
        * svg/SVGTextElement.h:
        * svg/SVGTextPathElement.cpp:
        (WebCore::SVGTextPathElement::isSupportedAttribute):
        (WebCore::SVGTextPathElement::parseMappedAttribute):
        (WebCore::SVGTextPathElement::svgAttributeChanged):
        (WebCore::SVGTextPathElement::synchronizeProperty):
        * svg/SVGTextPathElement.h:
        * svg/SVGTextPositioningElement.cpp:
        (WebCore::SVGTextPositioningElement::isSupportedAttribute):
        (WebCore::SVGTextPositioningElement::parseMappedAttribute):
        (WebCore::SVGTextPositioningElement::svgAttributeChanged):
        (WebCore::SVGTextPositioningElement::synchronizeProperty):
        * svg/SVGTextPositioningElement.h:
        * svg/SVGTransformable.cpp:
        * svg/SVGTransformable.h:
        * svg/SVGURIReference.cpp:
        (WebCore::SVGURIReference::addSupportedAttributes):
        * svg/SVGURIReference.h:
        * svg/SVGUseElement.cpp:
        (WebCore::SVGUseElement::isSupportedAttribute):
        (WebCore::SVGUseElement::parseMappedAttribute):
        (WebCore::SVGUseElement::svgAttributeChanged):
        (WebCore::SVGUseElement::synchronizeProperty):
        * svg/SVGUseElement.h:
        * svg/SVGViewElement.cpp:
        (WebCore::SVGViewElement::isSupportedAttribute):
        (WebCore::SVGViewElement::parseMappedAttribute):
        (WebCore::SVGViewElement::synchronizeProperty):
        * svg/SVGViewElement.h:
        * svg/SVGZoomAndPan.cpp:
        (WebCore::SVGZoomAndPan::addSupportedAttributes):
        * svg/SVGZoomAndPan.h:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@87010 268f45cc-cd09-0410-ab3c-d52691b4dbfc

126 files changed:
Source/WebCore/ChangeLog
Source/WebCore/svg/SVGAElement.cpp
Source/WebCore/svg/SVGAElement.h
Source/WebCore/svg/SVGAnimateMotionElement.cpp
Source/WebCore/svg/SVGAnimateMotionElement.h
Source/WebCore/svg/SVGAnimateTransformElement.cpp
Source/WebCore/svg/SVGAnimateTransformElement.h
Source/WebCore/svg/SVGAnimationElement.cpp
Source/WebCore/svg/SVGAnimationElement.h
Source/WebCore/svg/SVGCircleElement.cpp
Source/WebCore/svg/SVGCircleElement.h
Source/WebCore/svg/SVGClipPathElement.cpp
Source/WebCore/svg/SVGClipPathElement.h
Source/WebCore/svg/SVGComponentTransferFunctionElement.cpp
Source/WebCore/svg/SVGComponentTransferFunctionElement.h
Source/WebCore/svg/SVGCursorElement.cpp
Source/WebCore/svg/SVGCursorElement.h
Source/WebCore/svg/SVGElementInstance.h
Source/WebCore/svg/SVGEllipseElement.cpp
Source/WebCore/svg/SVGEllipseElement.h
Source/WebCore/svg/SVGExternalResourcesRequired.cpp
Source/WebCore/svg/SVGExternalResourcesRequired.h
Source/WebCore/svg/SVGFEBlendElement.cpp
Source/WebCore/svg/SVGFEBlendElement.h
Source/WebCore/svg/SVGFEColorMatrixElement.cpp
Source/WebCore/svg/SVGFEColorMatrixElement.h
Source/WebCore/svg/SVGFEComponentTransferElement.cpp
Source/WebCore/svg/SVGFEComponentTransferElement.h
Source/WebCore/svg/SVGFECompositeElement.cpp
Source/WebCore/svg/SVGFECompositeElement.h
Source/WebCore/svg/SVGFEConvolveMatrixElement.cpp
Source/WebCore/svg/SVGFEConvolveMatrixElement.h
Source/WebCore/svg/SVGFEDiffuseLightingElement.cpp
Source/WebCore/svg/SVGFEDiffuseLightingElement.h
Source/WebCore/svg/SVGFEDisplacementMapElement.cpp
Source/WebCore/svg/SVGFEDisplacementMapElement.h
Source/WebCore/svg/SVGFEDropShadowElement.cpp
Source/WebCore/svg/SVGFEDropShadowElement.h
Source/WebCore/svg/SVGFEGaussianBlurElement.cpp
Source/WebCore/svg/SVGFEGaussianBlurElement.h
Source/WebCore/svg/SVGFEImageElement.cpp
Source/WebCore/svg/SVGFEImageElement.h
Source/WebCore/svg/SVGFELightElement.cpp
Source/WebCore/svg/SVGFELightElement.h
Source/WebCore/svg/SVGFEMergeNodeElement.cpp
Source/WebCore/svg/SVGFEMergeNodeElement.h
Source/WebCore/svg/SVGFEMorphologyElement.cpp
Source/WebCore/svg/SVGFEMorphologyElement.h
Source/WebCore/svg/SVGFEOffsetElement.cpp
Source/WebCore/svg/SVGFEOffsetElement.h
Source/WebCore/svg/SVGFESpecularLightingElement.cpp
Source/WebCore/svg/SVGFESpecularLightingElement.h
Source/WebCore/svg/SVGFETileElement.cpp
Source/WebCore/svg/SVGFETileElement.h
Source/WebCore/svg/SVGFETurbulenceElement.cpp
Source/WebCore/svg/SVGFETurbulenceElement.h
Source/WebCore/svg/SVGFilterElement.cpp
Source/WebCore/svg/SVGFilterElement.h
Source/WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp
Source/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h
Source/WebCore/svg/SVGFitToViewBox.cpp
Source/WebCore/svg/SVGFitToViewBox.h
Source/WebCore/svg/SVGForeignObjectElement.cpp
Source/WebCore/svg/SVGForeignObjectElement.h
Source/WebCore/svg/SVGGElement.cpp
Source/WebCore/svg/SVGGElement.h
Source/WebCore/svg/SVGGradientElement.cpp
Source/WebCore/svg/SVGGradientElement.h
Source/WebCore/svg/SVGImageElement.cpp
Source/WebCore/svg/SVGImageElement.h
Source/WebCore/svg/SVGLangSpace.cpp
Source/WebCore/svg/SVGLangSpace.h
Source/WebCore/svg/SVGLineElement.cpp
Source/WebCore/svg/SVGLineElement.h
Source/WebCore/svg/SVGLinearGradientElement.cpp
Source/WebCore/svg/SVGLinearGradientElement.h
Source/WebCore/svg/SVGMPathElement.cpp
Source/WebCore/svg/SVGMPathElement.h
Source/WebCore/svg/SVGMarkerElement.cpp
Source/WebCore/svg/SVGMarkerElement.h
Source/WebCore/svg/SVGMaskElement.cpp
Source/WebCore/svg/SVGMaskElement.h
Source/WebCore/svg/SVGPathElement.cpp
Source/WebCore/svg/SVGPathElement.h
Source/WebCore/svg/SVGPatternElement.cpp
Source/WebCore/svg/SVGPatternElement.h
Source/WebCore/svg/SVGPolyElement.cpp
Source/WebCore/svg/SVGPolyElement.h
Source/WebCore/svg/SVGRadialGradientElement.cpp
Source/WebCore/svg/SVGRadialGradientElement.h
Source/WebCore/svg/SVGRectElement.cpp
Source/WebCore/svg/SVGRectElement.h
Source/WebCore/svg/SVGSVGElement.cpp
Source/WebCore/svg/SVGScriptElement.cpp
Source/WebCore/svg/SVGScriptElement.h
Source/WebCore/svg/SVGStopElement.cpp
Source/WebCore/svg/SVGStopElement.h
Source/WebCore/svg/SVGStyleElement.cpp
Source/WebCore/svg/SVGStyleElement.h
Source/WebCore/svg/SVGStyledElement.cpp
Source/WebCore/svg/SVGStyledTransformableElement.cpp
Source/WebCore/svg/SVGStyledTransformableElement.h
Source/WebCore/svg/SVGSymbolElement.cpp
Source/WebCore/svg/SVGSymbolElement.h
Source/WebCore/svg/SVGTRefElement.cpp
Source/WebCore/svg/SVGTRefElement.h
Source/WebCore/svg/SVGTests.cpp
Source/WebCore/svg/SVGTests.h
Source/WebCore/svg/SVGTextContentElement.cpp
Source/WebCore/svg/SVGTextContentElement.h
Source/WebCore/svg/SVGTextElement.cpp
Source/WebCore/svg/SVGTextElement.h
Source/WebCore/svg/SVGTextPathElement.cpp
Source/WebCore/svg/SVGTextPathElement.h
Source/WebCore/svg/SVGTextPositioningElement.cpp
Source/WebCore/svg/SVGTextPositioningElement.h
Source/WebCore/svg/SVGTransformable.cpp
Source/WebCore/svg/SVGTransformable.h
Source/WebCore/svg/SVGURIReference.cpp
Source/WebCore/svg/SVGURIReference.h
Source/WebCore/svg/SVGUseElement.cpp
Source/WebCore/svg/SVGUseElement.h
Source/WebCore/svg/SVGViewElement.cpp
Source/WebCore/svg/SVGViewElement.h
Source/WebCore/svg/SVGZoomAndPan.cpp
Source/WebCore/svg/SVGZoomAndPan.h

index 11047b3..a6cafc2 100644 (file)
@@ -1,3 +1,399 @@
+2011-05-21  Nikolas Zimmermann  <nzimmermann@rim.com>
+
+        Reviewed by Rob Buis.
+
+        SVG svgAttributeChanged/synchronizeProperty/parseMappedAttribute should be optimized
+        https://bugs.webkit.org/show_bug.cgi?id=61183
+
+        Example: rect.x.baseVal.value = 100;
+        What happens: SVGRectElement::svgAttributeChanged(const QualifiedName& attrName) is invoked with "SVGNames::rectAttr" as parameter.
+
+        void SVGRectElement::svgAttributeChanged(const QualifiedName& attrName)
+        {
+            SVGStyledTransformableElement::svgAttributeChanged(attrName);
+            // Handle my own attribute changes...
+        }
+
+        Currently we always traverse the base class hierarchy, when invoking svgAttributeChanged. Every svgAttributeChanged call from a class
+        like SVGRectElement has to reach the base class SVGStyledElement::svgAttributeChanged, as it handles invalidation of the instances of
+        an element. Say that a <rect> is referenced by a <use> and we change the 'x' attribute of the <rect>, then SVGStyledElement::svgAttributeChanged,
+        calls SVGElementInstance::invalidateAllInstancesOfElement(this), so that the <use> can rebuild its shadow tree...
+        That's the only reason all svgAttributeChanged implementations call the base class immediately, so SVGStyledElement is always reached.
+
+        Switch to a more efficient pattern, by providing a "bool isSupportedAttribute(const QualifiedName&);" function for all SVG*Elements.
+        It contains all attributes the particular SVG*Element class handles (but not its parent classes attributes). For example SVGRectElement
+        contains x/y/width/height/rx/ry attributes, and the ones from SVGTests/SVGLangSpace/SVGExternalResourcesRequired (xml:space/lang, etc.),
+        but not eg. transform as that's handled by the parent class SVGStyledTransformableElement.
+
+        void SVGRectElement::svgAttributeChanged(const QualifiedName& attrName)
+        {
+            if (!isSupportedAttribute.contains(attrName)) {
+                SVGStyledTransformableElement::svgAttributeChanged(attrName);
+                return;
+            }
+
+            // When we get here, we know for sure it's one of our attributes that has changed.
+            // Note for eg. SVGNames::transformAttr, the call from SVGRectElement::svgAttributeChanged, would be immediately forwarded to the base class, which handles transformAttr changes)
+
+            if (attrName == SVGNames::xAttr) { do_work(); return; }
+            if (attrName == SVGNames::yAttr) { do_work(); return; }
+            ...
+            // Assure that we handled all properties we claim support for in "isSupportedAttribute()".
+            ASSERT_NOT_REACHED();
+        }
+
+        Exactly the same pattern can be applied to synchronizeProperty and parseMappedAttribute to speed them up as well.
+
+        Add "SVGElementInstance::InvalidationGuard guard(this)" statements in all svgAttributeChanged implementations, that calls invalidateAllInstancesOfElement(this)
+        upon destruction, after we've reacted to the svg attribute change. This assures we never forget to call the invalidation method anywhere, and don't
+        need to rely on the base class svgAttributeChanged() call to do it.
+       
+        It's a slight overal performance progression.
+
+        * svg/SVGAElement.cpp:
+        (WebCore::SVGAElement::isSupportedAttribute):
+        (WebCore::SVGAElement::parseMappedAttribute):
+        (WebCore::SVGAElement::svgAttributeChanged):
+        (WebCore::SVGAElement::synchronizeProperty):
+        * svg/SVGAElement.h:
+        * svg/SVGAnimateMotionElement.cpp:
+        (WebCore::SVGAnimateMotionElement::isSupportedAttribute):
+        (WebCore::SVGAnimateMotionElement::parseMappedAttribute):
+        * svg/SVGAnimateMotionElement.h:
+        * svg/SVGAnimateTransformElement.cpp:
+        (WebCore::SVGAnimateTransformElement::isSupportedAttribute):
+        (WebCore::SVGAnimateTransformElement::parseMappedAttribute):
+        * svg/SVGAnimateTransformElement.h:
+        * svg/SVGAnimationElement.cpp:
+        (WebCore::SVGAnimationElement::isSupportedAttribute):
+        (WebCore::SVGAnimationElement::parseMappedAttribute):
+        * svg/SVGAnimationElement.h:
+        * svg/SVGCircleElement.cpp:
+        (WebCore::SVGCircleElement::isSupportedAttribute):
+        (WebCore::SVGCircleElement::parseMappedAttribute):
+        (WebCore::SVGCircleElement::svgAttributeChanged):
+        (WebCore::SVGCircleElement::synchronizeProperty):
+        * svg/SVGCircleElement.h:
+        * svg/SVGClipPathElement.cpp:
+        (WebCore::SVGClipPathElement::isSupportedAttribute):
+        (WebCore::SVGClipPathElement::parseMappedAttribute):
+        (WebCore::SVGClipPathElement::svgAttributeChanged):
+        (WebCore::SVGClipPathElement::synchronizeProperty):
+        * svg/SVGClipPathElement.h:
+        * svg/SVGComponentTransferFunctionElement.cpp:
+        (WebCore::SVGComponentTransferFunctionElement::isSupportedAttribute):
+        (WebCore::SVGComponentTransferFunctionElement::parseMappedAttribute):
+        (WebCore::SVGComponentTransferFunctionElement::synchronizeProperty):
+        * svg/SVGComponentTransferFunctionElement.h:
+        * svg/SVGCursorElement.cpp:
+        (WebCore::SVGCursorElement::isSupportedAttribute):
+        (WebCore::SVGCursorElement::parseMappedAttribute):
+        (WebCore::SVGCursorElement::svgAttributeChanged):
+        (WebCore::SVGCursorElement::synchronizeProperty):
+        * svg/SVGCursorElement.h:
+        * svg/SVGElementInstance.h:
+        (WebCore::SVGElementInstance::InvalidationGuard::InvalidationGuard):
+        (WebCore::SVGElementInstance::InvalidationGuard::~InvalidationGuard):
+        * svg/SVGEllipseElement.cpp:
+        (WebCore::SVGEllipseElement::isSupportedAttribute):
+        (WebCore::SVGEllipseElement::parseMappedAttribute):
+        (WebCore::SVGEllipseElement::svgAttributeChanged):
+        (WebCore::SVGEllipseElement::synchronizeProperty):
+        * svg/SVGEllipseElement.h:
+        * svg/SVGExternalResourcesRequired.cpp:
+        (WebCore::SVGExternalResourcesRequired::addSupportedAttributes):
+        * svg/SVGExternalResourcesRequired.h:
+        * svg/SVGFEBlendElement.cpp:
+        (WebCore::SVGFEBlendElement::isSupportedAttribute):
+        (WebCore::SVGFEBlendElement::parseMappedAttribute):
+        (WebCore::SVGFEBlendElement::svgAttributeChanged):
+        (WebCore::SVGFEBlendElement::synchronizeProperty):
+        * svg/SVGFEBlendElement.h:
+        * svg/SVGFEColorMatrixElement.cpp:
+        (WebCore::SVGFEColorMatrixElement::isSupportedAttribute):
+        (WebCore::SVGFEColorMatrixElement::parseMappedAttribute):
+        (WebCore::SVGFEColorMatrixElement::svgAttributeChanged):
+        (WebCore::SVGFEColorMatrixElement::synchronizeProperty):
+        * svg/SVGFEColorMatrixElement.h:
+        * svg/SVGFEComponentTransferElement.cpp:
+        (WebCore::SVGFEComponentTransferElement::isSupportedAttribute):
+        (WebCore::SVGFEComponentTransferElement::parseMappedAttribute):
+        (WebCore::SVGFEComponentTransferElement::synchronizeProperty):
+        * svg/SVGFEComponentTransferElement.h:
+        * svg/SVGFECompositeElement.cpp:
+        (WebCore::SVGFECompositeElement::isSupportedAttribute):
+        (WebCore::SVGFECompositeElement::parseMappedAttribute):
+        (WebCore::SVGFECompositeElement::svgAttributeChanged):
+        (WebCore::SVGFECompositeElement::synchronizeProperty):
+        * svg/SVGFECompositeElement.h:
+        * svg/SVGFEConvolveMatrixElement.cpp:
+        (WebCore::SVGFEConvolveMatrixElement::isSupportedAttribute):
+        (WebCore::SVGFEConvolveMatrixElement::parseMappedAttribute):
+        (WebCore::SVGFEConvolveMatrixElement::svgAttributeChanged):
+        (WebCore::SVGFEConvolveMatrixElement::synchronizeProperty):
+        * svg/SVGFEConvolveMatrixElement.h:
+        * svg/SVGFEDiffuseLightingElement.cpp:
+        (WebCore::SVGFEDiffuseLightingElement::isSupportedAttribute):
+        (WebCore::SVGFEDiffuseLightingElement::parseMappedAttribute):
+        (WebCore::SVGFEDiffuseLightingElement::svgAttributeChanged):
+        (WebCore::SVGFEDiffuseLightingElement::synchronizeProperty):
+        * svg/SVGFEDiffuseLightingElement.h:
+        * svg/SVGFEDisplacementMapElement.cpp:
+        (WebCore::SVGFEDisplacementMapElement::isSupportedAttribute):
+        (WebCore::SVGFEDisplacementMapElement::parseMappedAttribute):
+        (WebCore::SVGFEDisplacementMapElement::svgAttributeChanged):
+        (WebCore::SVGFEDisplacementMapElement::synchronizeProperty):
+        * svg/SVGFEDisplacementMapElement.h:
+        * svg/SVGFEDropShadowElement.cpp:
+        (WebCore::SVGFEDropShadowElement::isSupportedAttribute):
+        (WebCore::SVGFEDropShadowElement::parseMappedAttribute):
+        (WebCore::SVGFEDropShadowElement::svgAttributeChanged):
+        (WebCore::SVGFEDropShadowElement::synchronizeProperty):
+        * svg/SVGFEDropShadowElement.h:
+        * svg/SVGFEGaussianBlurElement.cpp:
+        (WebCore::SVGFEGaussianBlurElement::isSupportedAttribute):
+        (WebCore::SVGFEGaussianBlurElement::parseMappedAttribute):
+        (WebCore::SVGFEGaussianBlurElement::svgAttributeChanged):
+        (WebCore::SVGFEGaussianBlurElement::synchronizeProperty):
+        * svg/SVGFEGaussianBlurElement.h:
+        * svg/SVGFEImageElement.cpp:
+        (WebCore::SVGFEImageElement::isSupportedAttribute):
+        (WebCore::SVGFEImageElement::parseMappedAttribute):
+        (WebCore::SVGFEImageElement::svgAttributeChanged):
+        (WebCore::SVGFEImageElement::synchronizeProperty):
+        * svg/SVGFEImageElement.h:
+        * svg/SVGFELightElement.cpp:
+        (WebCore::SVGFELightElement::isSupportedAttribute):
+        (WebCore::SVGFELightElement::parseMappedAttribute):
+        (WebCore::SVGFELightElement::svgAttributeChanged):
+        (WebCore::SVGFELightElement::synchronizeProperty):
+        * svg/SVGFELightElement.h:
+        * svg/SVGFEMergeNodeElement.cpp:
+        (WebCore::SVGFEMergeNodeElement::isSupportedAttribute):
+        (WebCore::SVGFEMergeNodeElement::parseMappedAttribute):
+        (WebCore::SVGFEMergeNodeElement::svgAttributeChanged):
+        (WebCore::SVGFEMergeNodeElement::synchronizeProperty):
+        * svg/SVGFEMergeNodeElement.h:
+        * svg/SVGFEMorphologyElement.cpp:
+        (WebCore::SVGFEMorphologyElement::isSupportedAttribute):
+        (WebCore::SVGFEMorphologyElement::parseMappedAttribute):
+        (WebCore::SVGFEMorphologyElement::svgAttributeChanged):
+        (WebCore::SVGFEMorphologyElement::synchronizeProperty):
+        * svg/SVGFEMorphologyElement.h:
+        * svg/SVGFEOffsetElement.cpp:
+        (WebCore::SVGFEOffsetElement::isSupportedAttribute):
+        (WebCore::SVGFEOffsetElement::parseMappedAttribute):
+        (WebCore::SVGFEOffsetElement::svgAttributeChanged):
+        (WebCore::SVGFEOffsetElement::synchronizeProperty):
+        * svg/SVGFEOffsetElement.h:
+        * svg/SVGFESpecularLightingElement.cpp:
+        (WebCore::SVGFESpecularLightingElement::isSupportedAttribute):
+        (WebCore::SVGFESpecularLightingElement::parseMappedAttribute):
+        (WebCore::SVGFESpecularLightingElement::svgAttributeChanged):
+        (WebCore::SVGFESpecularLightingElement::synchronizeProperty):
+        * svg/SVGFESpecularLightingElement.h:
+        * svg/SVGFETileElement.cpp:
+        (WebCore::SVGFETileElement::isSupportedAttribute):
+        (WebCore::SVGFETileElement::parseMappedAttribute):
+        (WebCore::SVGFETileElement::svgAttributeChanged):
+        (WebCore::SVGFETileElement::synchronizeProperty):
+        * svg/SVGFETileElement.h:
+        * svg/SVGFETurbulenceElement.cpp:
+        (WebCore::SVGFETurbulenceElement::isSupportedAttribute):
+        (WebCore::SVGFETurbulenceElement::parseMappedAttribute):
+        (WebCore::SVGFETurbulenceElement::svgAttributeChanged):
+        (WebCore::SVGFETurbulenceElement::synchronizeProperty):
+        * svg/SVGFETurbulenceElement.h:
+        * svg/SVGFilterElement.cpp:
+        (WebCore::SVGFilterElement::isSupportedAttribute):
+        (WebCore::SVGFilterElement::parseMappedAttribute):
+        (WebCore::SVGFilterElement::svgAttributeChanged):
+        (WebCore::SVGFilterElement::synchronizeProperty):
+        * svg/SVGFilterElement.h:
+        * svg/SVGFilterPrimitiveStandardAttributes.cpp:
+        (WebCore::SVGFilterPrimitiveStandardAttributes::isSupportedAttribute):
+        (WebCore::SVGFilterPrimitiveStandardAttributes::parseMappedAttribute):
+        (WebCore::SVGFilterPrimitiveStandardAttributes::svgAttributeChanged):
+        (WebCore::SVGFilterPrimitiveStandardAttributes::synchronizeProperty):
+        * svg/SVGFilterPrimitiveStandardAttributes.h:
+        * svg/SVGFitToViewBox.cpp:
+        (WebCore::SVGFitToViewBox::parseMappedAttribute):
+        (WebCore::SVGFitToViewBox::synchronizeProperties):
+        (WebCore::SVGFitToViewBox::addSupportedAttributes):
+        * svg/SVGFitToViewBox.h:
+        * svg/SVGForeignObjectElement.cpp:
+        (WebCore::SVGForeignObjectElement::isSupportedAttribute):
+        (WebCore::SVGForeignObjectElement::parseMappedAttribute):
+        (WebCore::SVGForeignObjectElement::svgAttributeChanged):
+        (WebCore::SVGForeignObjectElement::synchronizeProperty):
+        * svg/SVGForeignObjectElement.h:
+        * svg/SVGGElement.cpp:
+        (WebCore::SVGGElement::isSupportedAttribute):
+        (WebCore::SVGGElement::parseMappedAttribute):
+        (WebCore::SVGGElement::svgAttributeChanged):
+        (WebCore::SVGGElement::synchronizeProperty):
+        * svg/SVGGElement.h:
+        * svg/SVGGradientElement.cpp:
+        (WebCore::SVGGradientElement::isSupportedAttribute):
+        (WebCore::SVGGradientElement::parseMappedAttribute):
+        (WebCore::SVGGradientElement::svgAttributeChanged):
+        (WebCore::SVGGradientElement::synchronizeProperty):
+        * svg/SVGGradientElement.h:
+        * svg/SVGImageElement.cpp:
+        (WebCore::SVGImageElement::isSupportedAttribute):
+        (WebCore::SVGImageElement::parseMappedAttribute):
+        (WebCore::SVGImageElement::svgAttributeChanged):
+        (WebCore::SVGImageElement::synchronizeProperty):
+        * svg/SVGImageElement.h:
+        * svg/SVGLangSpace.cpp:
+        (WebCore::SVGLangSpace::addSupportedAttributes):
+        * svg/SVGLangSpace.h:
+        * svg/SVGLineElement.cpp:
+        (WebCore::SVGLineElement::isSupportedAttribute):
+        (WebCore::SVGLineElement::parseMappedAttribute):
+        (WebCore::SVGLineElement::svgAttributeChanged):
+        (WebCore::SVGLineElement::synchronizeProperty):
+        * svg/SVGLineElement.h:
+        * svg/SVGLinearGradientElement.cpp:
+        (WebCore::SVGLinearGradientElement::isSupportedAttribute):
+        (WebCore::SVGLinearGradientElement::parseMappedAttribute):
+        (WebCore::SVGLinearGradientElement::svgAttributeChanged):
+        (WebCore::SVGLinearGradientElement::synchronizeProperty):
+        * svg/SVGLinearGradientElement.h:
+        * svg/SVGMPathElement.cpp:
+        (WebCore::SVGMPathElement::isSupportedAttribute):
+        (WebCore::SVGMPathElement::parseMappedAttribute):
+        (WebCore::SVGMPathElement::synchronizeProperty):
+        * svg/SVGMPathElement.h:
+        * svg/SVGMarkerElement.cpp:
+        (WebCore::SVGMarkerElement::isSupportedAttribute):
+        (WebCore::SVGMarkerElement::parseMappedAttribute):
+        (WebCore::SVGMarkerElement::svgAttributeChanged):
+        (WebCore::SVGMarkerElement::synchronizeProperty):
+        * svg/SVGMarkerElement.h:
+        * svg/SVGMaskElement.cpp:
+        (WebCore::SVGMaskElement::isSupportedAttribute):
+        (WebCore::SVGMaskElement::parseMappedAttribute):
+        (WebCore::SVGMaskElement::svgAttributeChanged):
+        (WebCore::SVGMaskElement::synchronizeProperty):
+        * svg/SVGMaskElement.h:
+        * svg/SVGPathElement.cpp:
+        (WebCore::SVGPathElement::isSupportedAttribute):
+        (WebCore::SVGPathElement::parseMappedAttribute):
+        (WebCore::SVGPathElement::svgAttributeChanged):
+        (WebCore::SVGPathElement::synchronizeProperty):
+        * svg/SVGPathElement.h:
+        * svg/SVGPatternElement.cpp:
+        (WebCore::SVGPatternElement::isSupportedAttribute):
+        (WebCore::SVGPatternElement::parseMappedAttribute):
+        (WebCore::SVGPatternElement::svgAttributeChanged):
+        (WebCore::SVGPatternElement::synchronizeProperty):
+        * svg/SVGPatternElement.h:
+        * svg/SVGPolyElement.cpp:
+        (WebCore::SVGPolyElement::isSupportedAttribute):
+        (WebCore::SVGPolyElement::parseMappedAttribute):
+        (WebCore::SVGPolyElement::svgAttributeChanged):
+        * svg/SVGPolyElement.h:
+        * svg/SVGRadialGradientElement.cpp:
+        (WebCore::SVGRadialGradientElement::isSupportedAttribute):
+        (WebCore::SVGRadialGradientElement::parseMappedAttribute):
+        (WebCore::SVGRadialGradientElement::svgAttributeChanged):
+        (WebCore::SVGRadialGradientElement::synchronizeProperty):
+        * svg/SVGRadialGradientElement.h:
+        * svg/SVGRectElement.cpp:
+        (WebCore::SVGRectElement::isSupportedAttribute):
+        (WebCore::SVGRectElement::parseMappedAttribute):
+        (WebCore::SVGRectElement::svgAttributeChanged):
+        (WebCore::SVGRectElement::synchronizeProperty):
+        * svg/SVGRectElement.h:
+        * svg/SVGSVGElement.cpp:
+        (WebCore::SVGSVGElement::svgAttributeChanged):
+        (WebCore::SVGSVGElement::synchronizeProperty):
+        * svg/SVGScriptElement.cpp:
+        (WebCore::SVGScriptElement::isSupportedAttribute):
+        (WebCore::SVGScriptElement::parseMappedAttribute):
+        (WebCore::SVGScriptElement::svgAttributeChanged):
+        (WebCore::SVGScriptElement::synchronizeProperty):
+        * svg/SVGScriptElement.h:
+        * svg/SVGStopElement.cpp:
+        (WebCore::SVGStopElement::isSupportedAttribute):
+        (WebCore::SVGStopElement::parseMappedAttribute):
+        (WebCore::SVGStopElement::svgAttributeChanged):
+        (WebCore::SVGStopElement::synchronizeProperty):
+        * svg/SVGStopElement.h:
+        * svg/SVGStyleElement.cpp:
+        (WebCore::SVGStyleElement::isSupportedAttribute):
+        (WebCore::SVGStyleElement::parseMappedAttribute):
+        * svg/SVGStyleElement.h:
+        * svg/SVGStyledElement.cpp:
+        (WebCore::SVGStyledElement::parseMappedAttribute):
+        (WebCore::SVGStyledElement::svgAttributeChanged):
+        (WebCore::SVGStyledElement::synchronizeProperty):
+        * svg/SVGStyledTransformableElement.cpp:
+        (WebCore::SVGStyledTransformableElement::isSupportedAttribute):
+        (WebCore::SVGStyledTransformableElement::parseMappedAttribute):
+        (WebCore::SVGStyledTransformableElement::svgAttributeChanged):
+        (WebCore::SVGStyledTransformableElement::synchronizeProperty):
+        * svg/SVGStyledTransformableElement.h:
+        * svg/SVGSymbolElement.cpp:
+        (WebCore::SVGSymbolElement::isSupportedAttribute):
+        (WebCore::SVGSymbolElement::parseMappedAttribute):
+        (WebCore::SVGSymbolElement::svgAttributeChanged):
+        (WebCore::SVGSymbolElement::synchronizeProperty):
+        * svg/SVGSymbolElement.h:
+        * svg/SVGTRefElement.cpp:
+        (WebCore::SVGTRefElement::isSupportedAttribute):
+        (WebCore::SVGTRefElement::parseMappedAttribute):
+        (WebCore::SVGTRefElement::svgAttributeChanged):
+        (WebCore::SVGTRefElement::synchronizeProperty):
+        * svg/SVGTRefElement.h:
+        * svg/SVGTests.cpp:
+        (WebCore::SVGTests::addSupportedAttributes):
+        * svg/SVGTests.h:
+        * svg/SVGTextContentElement.cpp:
+        (WebCore::SVGTextContentElement::isSupportedAttribute):
+        (WebCore::SVGTextContentElement::parseMappedAttribute):
+        (WebCore::SVGTextContentElement::synchronizeProperty):
+        (WebCore::SVGTextContentElement::svgAttributeChanged):
+        * svg/SVGTextContentElement.h:
+        * svg/SVGTextElement.cpp:
+        (WebCore::SVGTextElement::isSupportedAttribute):
+        (WebCore::SVGTextElement::parseMappedAttribute):
+        (WebCore::SVGTextElement::svgAttributeChanged):
+        (WebCore::SVGTextElement::synchronizeProperty):
+        * svg/SVGTextElement.h:
+        * svg/SVGTextPathElement.cpp:
+        (WebCore::SVGTextPathElement::isSupportedAttribute):
+        (WebCore::SVGTextPathElement::parseMappedAttribute):
+        (WebCore::SVGTextPathElement::svgAttributeChanged):
+        (WebCore::SVGTextPathElement::synchronizeProperty):
+        * svg/SVGTextPathElement.h:
+        * svg/SVGTextPositioningElement.cpp:
+        (WebCore::SVGTextPositioningElement::isSupportedAttribute):
+        (WebCore::SVGTextPositioningElement::parseMappedAttribute):
+        (WebCore::SVGTextPositioningElement::svgAttributeChanged):
+        (WebCore::SVGTextPositioningElement::synchronizeProperty):
+        * svg/SVGTextPositioningElement.h:
+        * svg/SVGTransformable.cpp:
+        * svg/SVGTransformable.h:
+        * svg/SVGURIReference.cpp:
+        (WebCore::SVGURIReference::addSupportedAttributes):
+        * svg/SVGURIReference.h:
+        * svg/SVGUseElement.cpp:
+        (WebCore::SVGUseElement::isSupportedAttribute):
+        (WebCore::SVGUseElement::parseMappedAttribute):
+        (WebCore::SVGUseElement::svgAttributeChanged):
+        (WebCore::SVGUseElement::synchronizeProperty):
+        * svg/SVGUseElement.h:
+        * svg/SVGViewElement.cpp:
+        (WebCore::SVGViewElement::isSupportedAttribute):
+        (WebCore::SVGViewElement::parseMappedAttribute):
+        (WebCore::SVGViewElement::synchronizeProperty):
+        * svg/SVGViewElement.h:
+        * svg/SVGZoomAndPan.cpp:
+        (WebCore::SVGZoomAndPan::addSupportedAttributes):
+        * svg/SVGZoomAndPan.h:
+
 2011-05-20  Simon Fraser  <simon.fraser@apple.com>
 
         Reviewed by Dan Bernstein.
index 0bdde7e..63f586e 100644 (file)
@@ -41,6 +41,7 @@
 #include "RenderSVGInline.h"
 #include "RenderSVGTransformableContainer.h"
 #include "ResourceRequest.h"
+#include "SVGElementInstance.h"
 #include "SVGNames.h"
 #include "SVGSMILElement.h"
 #include "XLinkNames.h"
@@ -74,26 +75,51 @@ String SVGAElement::title() const
     return SVGStyledElement::title();
 }
 
+bool SVGAElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty()) {
+        SVGURIReference::addSupportedAttributes(supportedAttributes);
+        SVGTests::addSupportedAttributes(supportedAttributes);
+        SVGLangSpace::addSupportedAttributes(supportedAttributes);
+        SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
+        supportedAttributes.add(SVGNames::targetAttr);
+    }
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGAElement::parseMappedAttribute(Attribute* attr)
 {
-    if (attr->name() == SVGNames::targetAttr)
-        setSVGTargetBaseValue(attr->value());
-    else {
-        if (SVGURIReference::parseMappedAttribute(attr))
-            return;
-        if (SVGTests::parseMappedAttribute(attr))
-            return;
-        if (SVGLangSpace::parseMappedAttribute(attr))
-            return;
-        if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
-            return;
+    if (!isSupportedAttribute(attr->name())) {
         SVGStyledTransformableElement::parseMappedAttribute(attr);
+        return;
     }
+
+    if (attr->name() == SVGNames::targetAttr) {
+        setSVGTargetBaseValue(attr->value());
+        return;
+    }
+
+    if (SVGURIReference::parseMappedAttribute(attr))
+        return;
+    if (SVGTests::parseMappedAttribute(attr))
+        return;
+    if (SVGLangSpace::parseMappedAttribute(attr))
+        return;
+    if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
+        return;
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGAElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    SVGStyledTransformableElement::svgAttributeChanged(attrName);
+    if (!isSupportedAttribute(attrName)) {
+        SVGStyledTransformableElement::svgAttributeChanged(attrName);
+        return;
+    }
+
+    SVGElementInstance::InvalidationGuard invalidationGuard(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.
@@ -123,24 +149,41 @@ void SVGAElement::fillAttributeToPropertyTypeMap()
 
 void SVGAElement::synchronizeProperty(const QualifiedName& attrName)
 {
-    SVGStyledTransformableElement::synchronizeProperty(attrName);
-
     if (attrName == anyQName()) {
         synchronizeSVGTarget();
         synchronizeHref();
         synchronizeExternalResourcesRequired();
         SVGTests::synchronizeProperties(this, attrName);
+        SVGStyledTransformableElement::synchronizeProperty(attrName);
+        return;
+    }
+
+    if (!isSupportedAttribute(attrName)) {
+        SVGStyledTransformableElement::synchronizeProperty(attrName);
         return;
     }
 
-    if (attrName == SVGNames::targetAttr)
+    if (attrName == SVGNames::targetAttr) {
         synchronizeSVGTarget();
-    else if (SVGURIReference::isKnownAttribute(attrName))
+        return;
+    }
+
+    if (SVGURIReference::isKnownAttribute(attrName)) {
         synchronizeHref();
-    else if (SVGExternalResourcesRequired::isKnownAttribute(attrName))
+        return;
+    }
+
+    if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) {
         synchronizeExternalResourcesRequired();
-    else if (SVGTests::isKnownAttribute(attrName))
+        return;
+    }
+
+    if (SVGTests::isKnownAttribute(attrName)) {
         SVGTests::synchronizeProperties(this, attrName);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 RenderObject* SVGAElement::createRenderer(RenderArena* arena, RenderStyle*)
index 6d9cd43..1f82d7e 100644 (file)
@@ -48,6 +48,7 @@ private:
     virtual String title() const;
     virtual String target() const { return svgTarget(); }
 
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*);
     virtual void svgAttributeChanged(const QualifiedName&);
     virtual void synchronizeProperty(const QualifiedName&);
index b1016b8..94e28a4 100644 (file)
@@ -89,14 +89,29 @@ bool SVGAnimateMotionElement::hasValidAttributeType() const
     return false;
 }
 
+bool SVGAnimateMotionElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty())
+        supportedAttributes.add(SVGNames::pathAttr);
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGAnimateMotionElement::parseMappedAttribute(Attribute* attr)
 {
+    if (!isSupportedAttribute(attr->name())) {
+        SVGAnimationElement::parseMappedAttribute(attr);
+        return;
+    }
+
     if (attr->name() == SVGNames::pathAttr) {
         m_path = Path();
         SVGPathParserFactory* factory = SVGPathParserFactory::self();
         factory->buildPathFromString(attr->value(), m_path);
-    } else
-        SVGAnimationElement::parseMappedAttribute(attr);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
     
 SVGAnimateMotionElement::RotateMode SVGAnimateMotionElement::rotateMode() const
index 96861b6..5789726 100644 (file)
@@ -36,6 +36,7 @@ private:
 
     virtual bool hasValidAttributeType() const;
 
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*);
 
     virtual void resetToBaseValue(const String&);
index 76c26dc..5a0c3cc 100644 (file)
@@ -81,24 +81,39 @@ AnimatedAttributeType SVGAnimateTransformElement::determineAnimatedAttributeType
     return AnimatedTransformList;
 }
 
+bool SVGAnimateTransformElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty())
+        supportedAttributes.add(SVGNames::typeAttr);
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGAnimateTransformElement::parseMappedAttribute(Attribute* attr)
 {
+    if (!isSupportedAttribute(attr->name())) {
+        SVGAnimationElement::parseMappedAttribute(attr);
+        return;
+    }
+
     if (attr->name() == SVGNames::typeAttr) {
-        if (attr->value() == "translate")
+        const AtomicString& value = attr->value();
+        if (value == "translate")
             m_type = SVGTransform::SVG_TRANSFORM_TRANSLATE;
-        else if (attr->value() == "scale")
+        else if (value == "scale")
             m_type = SVGTransform::SVG_TRANSFORM_SCALE;
-        else if (attr->value() == "rotate")
+        else if (value == "rotate")
             m_type = SVGTransform::SVG_TRANSFORM_ROTATE;
-        else if (attr->value() == "skewX")
+        else if (value == "skewX")
             m_type = SVGTransform::SVG_TRANSFORM_SKEWX;
-        else if (attr->value() == "skewY")
+        else if (value == "skewY")
             m_type = SVGTransform::SVG_TRANSFORM_SKEWY;
-    } else
-        SVGAnimationElement::parseMappedAttribute(attr);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
-    
 static SVGTransformList* transformListFor(SVGElement* element)
 {
     ASSERT(element);
index 6ebc97e..db10a1b 100644 (file)
@@ -42,6 +42,7 @@ private:
     virtual bool hasValidAttributeType() const;
     AnimatedAttributeType determineAnimatedAttributeType(SVGElement*) const;
 
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*);
 
     virtual void resetToBaseValue(const String&);
index 4634493..6bdd9f6 100644 (file)
@@ -136,25 +136,57 @@ static void parseKeySplines(const String& parse, Vector<UnitBezier>& result)
         result.clear();
 }
 
+bool SVGAnimationElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty()) {
+        SVGTests::addSupportedAttributes(supportedAttributes);
+        SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
+        supportedAttributes.add(SVGNames::valuesAttr);
+        supportedAttributes.add(SVGNames::keyTimesAttr);
+        supportedAttributes.add(SVGNames::keyPointsAttr);
+        supportedAttributes.add(SVGNames::keySplinesAttr);
+    }
+    return supportedAttributes.contains(attrName);
+}
+     
 void SVGAnimationElement::parseMappedAttribute(Attribute* attr)
 {
-    if (attr->name() == SVGNames::valuesAttr)
+    if (!isSupportedAttribute(attr->name())) {
+        SVGSMILElement::parseMappedAttribute(attr);
+        return;
+    }
+
+    if (attr->name() == SVGNames::valuesAttr) {
         attr->value().string().split(';', m_values);
-    else if (attr->name() == SVGNames::keyTimesAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::keyTimesAttr) {
         parseKeyTimes(attr->value(), m_keyTimes, true);
-    else if (attr->name() == SVGNames::keyPointsAttr && hasTagName(SVGNames::animateMotionTag)) {
-        // This is specified to be an animateMotion attribute only but it is simpler to put it here 
-        // where the other timing calculatations are.
-        parseKeyTimes(attr->value(), m_keyPoints, false);
-    } else if (attr->name() == SVGNames::keySplinesAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::keyPointsAttr) {
+        if (hasTagName(SVGNames::animateMotionTag)) {
+            // This is specified to be an animateMotion attribute only but it is simpler to put it here 
+            // where the other timing calculatations are.
+            parseKeyTimes(attr->value(), m_keyPoints, false);
+        }
+        return;
+    }
+
+    if (attr->name() == SVGNames::keySplinesAttr) {
         parseKeySplines(attr->value(), m_keySplines);
-    else {
-        if (SVGTests::parseMappedAttribute(attr))
-            return;
-        if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
-            return;
-        SVGSMILElement::parseMappedAttribute(attr);
+        return;
     }
+
+    if (SVGTests::parseMappedAttribute(attr))
+        return;
+    if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
+        return;
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGAnimationElement::attributeChanged(Attribute* attr, bool preserveDecls)
index 8aa2cdb..5fe3f7d 100644 (file)
@@ -61,6 +61,7 @@ public:
 protected:
     SVGAnimationElement(const QualifiedName&, Document*);
 
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*);
 
     enum CalcMode { CalcModeDiscrete, CalcModeLinear, CalcModePaced, CalcModeSpline };
index d4e12bd..6665349 100644 (file)
@@ -27,6 +27,7 @@
 #include "FloatPoint.h"
 #include "RenderSVGPath.h"
 #include "RenderSVGResource.h"
+#include "SVGElementInstance.h"
 #include "SVGLength.h"
 #include "SVGNames.h"
 
@@ -52,30 +53,62 @@ PassRefPtr<SVGCircleElement> SVGCircleElement::create(const QualifiedName& tagNa
     return adoptRef(new SVGCircleElement(tagName, document));
 }
 
+bool SVGCircleElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty()) {
+        SVGTests::addSupportedAttributes(supportedAttributes);
+        SVGLangSpace::addSupportedAttributes(supportedAttributes);
+        SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
+        supportedAttributes.add(SVGNames::cxAttr);
+        supportedAttributes.add(SVGNames::cyAttr);
+        supportedAttributes.add(SVGNames::rAttr);
+    }
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGCircleElement::parseMappedAttribute(Attribute* attr)
 {
-    if (attr->name() == SVGNames::cxAttr)
-        setCxBaseValue(SVGLength(LengthModeWidth, attr->value()));       
-    else if (attr->name() == SVGNames::cyAttr)
+    if (!isSupportedAttribute(attr->name())) {
+        SVGStyledTransformableElement::parseMappedAttribute(attr);
+        return;
+    }
+
+    if (attr->name() == SVGNames::cxAttr) {
+        setCxBaseValue(SVGLength(LengthModeWidth, attr->value()));
+        return;
+    }
+
+    if (attr->name() == SVGNames::cyAttr) {
         setCyBaseValue(SVGLength(LengthModeHeight, attr->value()));
-    else if (attr->name() == SVGNames::rAttr) {
+        return;
+    }
+
+    if (attr->name() == SVGNames::rAttr) {
         setRBaseValue(SVGLength(LengthModeOther, attr->value()));
         if (rBaseValue().value(this) < 0.0)
             document()->accessSVGExtensions()->reportError("A negative value for circle <r> is not allowed");
-    } else {
-        if (SVGTests::parseMappedAttribute(attr))
-            return;
-        if (SVGLangSpace::parseMappedAttribute(attr))
-            return;
-        if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
-            return;
-        SVGStyledTransformableElement::parseMappedAttribute(attr);
+        return;
     }
+
+    if (SVGTests::parseMappedAttribute(attr))
+        return;
+    if (SVGLangSpace::parseMappedAttribute(attr))
+        return;
+    if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
+        return;
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGCircleElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    SVGStyledTransformableElement::svgAttributeChanged(attrName);
+    if (!isSupportedAttribute(attrName)) {
+        SVGStyledTransformableElement::svgAttributeChanged(attrName);
+        return;
+    }
+
+    SVGElementInstance::InvalidationGuard invalidationGuard(this);
 
     bool isLengthAttribute = attrName == SVGNames::cxAttr
                           || attrName == SVGNames::cyAttr
@@ -97,34 +130,57 @@ void SVGCircleElement::svgAttributeChanged(const QualifiedName& attrName)
         return;
     }
 
-    if (SVGLangSpace::isKnownAttribute(attrName)
-        || SVGExternalResourcesRequired::isKnownAttribute(attrName))
+    if (SVGLangSpace::isKnownAttribute(attrName) || SVGExternalResourcesRequired::isKnownAttribute(attrName)) {
         RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGCircleElement::synchronizeProperty(const QualifiedName& attrName)
 {
-    SVGStyledTransformableElement::synchronizeProperty(attrName);
-
     if (attrName == anyQName()) {
         synchronizeCx();
         synchronizeCy();
         synchronizeR();
         synchronizeExternalResourcesRequired();
         SVGTests::synchronizeProperties(this, attrName);
+        SVGStyledTransformableElement::synchronizeProperty(attrName);
+        return;
+    }
+   
+    if (!isSupportedAttribute(attrName)) {
+        SVGStyledTransformableElement::synchronizeProperty(attrName);
         return;
     }
 
-    if (attrName == SVGNames::cxAttr)
+    if (attrName == SVGNames::cxAttr) {
         synchronizeCx();
-    else if (attrName == SVGNames::cyAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::cyAttr) {
         synchronizeCy();
-    else if (attrName == SVGNames::rAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::rAttr) {
         synchronizeR();
-    else if (SVGExternalResourcesRequired::isKnownAttribute(attrName))
+        return;
+    }
+
+    if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) {
         synchronizeExternalResourcesRequired();
-    else if (SVGTests::isKnownAttribute(attrName))
+        return;
+    }
+
+    if (SVGTests::isKnownAttribute(attrName)) {
         SVGTests::synchronizeProperties(this, attrName);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 AttributeToPropertyTypeMap& SVGCircleElement::attributeToPropertyTypeMap()
index 32d3a22..b5e2b97 100644 (file)
@@ -43,6 +43,7 @@ private:
 
     virtual bool isValid() const { return SVGTests::isValid(); }
 
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*);
     virtual void svgAttributeChanged(const QualifiedName&);
     virtual void synchronizeProperty(const QualifiedName&);
index 6afd6ad..6397c05 100644 (file)
@@ -28,6 +28,7 @@
 #include "CSSStyleSelector.h"
 #include "Document.h"
 #include "RenderSVGResourceClipper.h"
+#include "SVGElementInstance.h"
 #include "SVGNames.h"
 #include "SVGTransformList.h"
 
@@ -49,56 +50,86 @@ PassRefPtr<SVGClipPathElement> SVGClipPathElement::create(const QualifiedName& t
     return adoptRef(new SVGClipPathElement(tagName, document));
 }
 
+bool SVGClipPathElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty()) {
+        SVGTests::addSupportedAttributes(supportedAttributes);
+        SVGLangSpace::addSupportedAttributes(supportedAttributes);
+        SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
+        supportedAttributes.add(SVGNames::clipPathUnitsAttr);
+    }
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGClipPathElement::parseMappedAttribute(Attribute* attr)
 {
+    if (!isSupportedAttribute(attr->name())) {
+        SVGStyledTransformableElement::parseMappedAttribute(attr);
+        return;
+    }
+
     if (attr->name() == SVGNames::clipPathUnitsAttr) {
         SVGUnitTypes::SVGUnitType propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(attr->value());
         if (propertyValue > 0)
             setClipPathUnitsBaseValue(propertyValue);
-    } else {
-        if (SVGTests::parseMappedAttribute(attr))
-            return;
-        if (SVGLangSpace::parseMappedAttribute(attr))
-            return;
-        if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
-            return;
-        SVGStyledTransformableElement::parseMappedAttribute(attr);
+        return;
     }
+
+    if (SVGTests::parseMappedAttribute(attr))
+        return;
+    if (SVGLangSpace::parseMappedAttribute(attr))
+        return;
+    if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
+        return;
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGClipPathElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    SVGStyledTransformableElement::svgAttributeChanged(attrName);
-
-    RenderObject* object = renderer();
-    if (!object)
+    if (!isSupportedAttribute(attrName)) {
+        SVGStyledTransformableElement::svgAttributeChanged(attrName);
         return;
+    }
+
+    SVGElementInstance::InvalidationGuard invalidationGuard(this);
 
-    if (attrName == SVGNames::clipPathUnitsAttr
-        || SVGTests::isKnownAttribute(attrName)
-        || SVGLangSpace::isKnownAttribute(attrName)
-        || SVGExternalResourcesRequired::isKnownAttribute(attrName)
-        || SVGStyledTransformableElement::isKnownAttribute(attrName))
+    if (RenderObject* object = renderer())
         object->setNeedsLayout(true);
 }
 
 void SVGClipPathElement::synchronizeProperty(const QualifiedName& attrName)
 {
-    SVGStyledTransformableElement::synchronizeProperty(attrName);
-
     if (attrName == anyQName()) {
         synchronizeClipPathUnits();
         synchronizeExternalResourcesRequired();
         SVGTests::synchronizeProperties(this, attrName);
+        SVGStyledTransformableElement::synchronizeProperty(attrName);
         return;
     }
 
-    if (attrName == SVGNames::clipPathUnitsAttr)
+    if (!isSupportedAttribute(attrName)) {
+        SVGStyledTransformableElement::synchronizeProperty(attrName);
+        return;
+    }
+
+    if (attrName == SVGNames::clipPathUnitsAttr) {
         synchronizeClipPathUnits();
-    else if (SVGExternalResourcesRequired::isKnownAttribute(attrName))
+        return;
+    }
+
+    if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) {
         synchronizeExternalResourcesRequired();
-    else if (SVGTests::isKnownAttribute(attrName))
+        return;
+    }
+
+    if (SVGTests::isKnownAttribute(attrName)) {
         SVGTests::synchronizeProperties(this, attrName);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 AttributeToPropertyTypeMap& SVGClipPathElement::attributeToPropertyTypeMap()
index f8c6f61..26a4595 100644 (file)
@@ -47,6 +47,7 @@ private:
     virtual bool isValid() const { return SVGTests::isValid(); }
     virtual bool needsPendingResourceHandling() const { return false; }
 
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*);
     virtual void svgAttributeChanged(const QualifiedName&);
     virtual void synchronizeProperty(const QualifiedName&);
index 755ba04..e616364 100644 (file)
@@ -48,36 +48,74 @@ SVGComponentTransferFunctionElement::SVGComponentTransferFunctionElement(const Q
 {
 }
 
+bool SVGComponentTransferFunctionElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty()) {
+        supportedAttributes.add(SVGNames::typeAttr);
+        supportedAttributes.add(SVGNames::tableValuesAttr);
+        supportedAttributes.add(SVGNames::slopeAttr);
+        supportedAttributes.add(SVGNames::interceptAttr);
+        supportedAttributes.add(SVGNames::amplitudeAttr);
+        supportedAttributes.add(SVGNames::exponentAttr);
+        supportedAttributes.add(SVGNames::offsetAttr);
+    }
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGComponentTransferFunctionElement::parseMappedAttribute(Attribute* attr)
 {
-    const String& value = attr->value();
+    if (!isSupportedAttribute(attr->name())) {
+        SVGElement::parseMappedAttribute(attr);
+        return;
+    }
+
+    const AtomicString& value = attr->value();
     if (attr->name() == SVGNames::typeAttr) {
         ComponentTransferType propertyValue = SVGPropertyTraits<ComponentTransferType>::fromString(value);
         if (propertyValue > 0)
             setTypeBaseValue(propertyValue);
-    } else if (attr->name() == SVGNames::tableValuesAttr) {
+        return;
+    }
+
+    if (attr->name() == SVGNames::tableValuesAttr) {
         SVGNumberList newList;
         newList.parse(value);
         detachAnimatedTableValuesListWrappers(newList.size());
         setTableValuesBaseValue(newList);
-    } else if (attr->name() == SVGNames::slopeAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::slopeAttr) {
         setSlopeBaseValue(value.toFloat());
-    else if (attr->name() == SVGNames::interceptAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::interceptAttr) {
         setInterceptBaseValue(value.toFloat());
-    else if (attr->name() == SVGNames::amplitudeAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::amplitudeAttr) {
         setAmplitudeBaseValue(value.toFloat());
-    else if (attr->name() == SVGNames::exponentAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::exponentAttr) {
         setExponentBaseValue(value.toFloat());
-    else if (attr->name() == SVGNames::offsetAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::offsetAttr) {
         setOffsetBaseValue(value.toFloat());
-    else
-        SVGElement::parseMappedAttribute(attr);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGComponentTransferFunctionElement::synchronizeProperty(const QualifiedName& attrName)
 {
-    SVGElement::synchronizeProperty(attrName);
-
     if (attrName == anyQName()) {
         synchronizeType();
         synchronizeTableValues();
@@ -86,23 +124,51 @@ void SVGComponentTransferFunctionElement::synchronizeProperty(const QualifiedNam
         synchronizeAmplitude();
         synchronizeExponent();
         synchronizeOffset();
+        SVGElement::synchronizeProperty(attrName);
         return;
     }
 
-    if (attrName == SVGNames::typeAttr)
+    if (!isSupportedAttribute(attrName)) {
+        SVGElement::synchronizeProperty(attrName);
+        return;
+    }
+
+    if (attrName == SVGNames::typeAttr) {
         synchronizeType();
-    else if (attrName == SVGNames::tableValuesAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::tableValuesAttr) {
         synchronizeTableValues();
-    else if (attrName == SVGNames::slopeAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::slopeAttr) {
         synchronizeSlope();
-    else if (attrName == SVGNames::interceptAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::interceptAttr) {
         synchronizeIntercept();
-    else if (attrName == SVGNames::amplitudeAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::amplitudeAttr) {
         synchronizeAmplitude();
-    else if (attrName == SVGNames::exponentAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::exponentAttr) {
         synchronizeExponent();
-    else if (attrName == SVGNames::offsetAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::offsetAttr) {
         synchronizeOffset();
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 AttributeToPropertyTypeMap& SVGComponentTransferFunctionElement::attributeToPropertyTypeMap()
index 909e680..9116a6d 100644 (file)
@@ -36,6 +36,8 @@ public:
 protected:
     SVGComponentTransferFunctionElement(const QualifiedName&, Document*);
 
+    // FIXME: svgAttributeChanged missing.
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*);
     virtual void synchronizeProperty(const QualifiedName&);
     virtual void fillAttributeToPropertyTypeMap();
index 921e2bd..4e4b009 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "Attr.h"
 #include "Document.h"
+#include "SVGElementInstance.h"
 #include "SVGNames.h"
 
 namespace WebCore {
@@ -55,22 +56,44 @@ SVGCursorElement::~SVGCursorElement()
         (*it)->cursorElementRemoved();
 }
 
+bool SVGCursorElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty()) {
+        SVGTests::addSupportedAttributes(supportedAttributes);
+        SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
+        SVGURIReference::addSupportedAttributes(supportedAttributes);
+        supportedAttributes.add(SVGNames::xAttr);
+        supportedAttributes.add(SVGNames::yAttr);
+    }
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGCursorElement::parseMappedAttribute(Attribute* attr)
 {
-    if (attr->name() == SVGNames::xAttr)
+    if (!isSupportedAttribute(attr->name())) {
+        SVGElement::parseMappedAttribute(attr);
+        return;
+    }
+
+    if (attr->name() == SVGNames::xAttr) {
         setXBaseValue(SVGLength(LengthModeWidth, attr->value()));
-    else if (attr->name() == SVGNames::yAttr)
-        setYBaseValue(SVGLength(LengthModeHeight, attr->value()));
-    else {
-        if (SVGTests::parseMappedAttribute(attr))
-            return;
-        if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
-            return;
-        if (SVGURIReference::parseMappedAttribute(attr))
-            return;
+        return;
+    }
 
-        SVGElement::parseMappedAttribute(attr);
+    if (attr->name() == SVGNames::yAttr) {
+        setYBaseValue(SVGLength(LengthModeHeight, attr->value()));
+        return;
     }
+    
+    if (SVGTests::parseMappedAttribute(attr))
+        return;
+    if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
+        return;
+    if (SVGURIReference::parseMappedAttribute(attr))
+        return;
+
+    ASSERT_NOT_REACHED();
 }
 
 AttributeToPropertyTypeMap& SVGCursorElement::attributeToPropertyTypeMap()
@@ -109,44 +132,64 @@ void SVGCursorElement::removeReferencedElement(SVGElement* element)
 
 void SVGCursorElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    SVGElement::svgAttributeChanged(attrName);
-
-    if (attrName == SVGNames::xAttr
-        || attrName == SVGNames::yAttr
-        || SVGTests::isKnownAttribute(attrName)
-        || SVGExternalResourcesRequired::isKnownAttribute(attrName)
-        || SVGURIReference::isKnownAttribute(attrName)) {
-        HashSet<SVGElement*>::const_iterator it = m_clients.begin();
-        HashSet<SVGElement*>::const_iterator end = m_clients.end();
-
-        for (; it != end; ++it)
-            (*it)->setNeedsStyleRecalc();
+    if (!isSupportedAttribute(attrName)) {
+        SVGElement::svgAttributeChanged(attrName);
+        return;
     }
+
+    SVGElementInstance::InvalidationGuard invalidationGuard(this);
+
+    // Any change of a cursor specific attribute triggers this recalc.
+    HashSet<SVGElement*>::const_iterator it = m_clients.begin();
+    HashSet<SVGElement*>::const_iterator end = m_clients.end();
+
+    for (; it != end; ++it)
+        (*it)->setNeedsStyleRecalc();
 }
 
 void SVGCursorElement::synchronizeProperty(const QualifiedName& attrName)
 {
-    SVGElement::synchronizeProperty(attrName);
-
     if (attrName == anyQName()) {
         synchronizeX();
         synchronizeY();
         synchronizeExternalResourcesRequired();
         synchronizeHref();
         SVGTests::synchronizeProperties(this, attrName);
+        SVGElement::synchronizeProperty(attrName);
+        return;
+    }
+
+    if (!isSupportedAttribute(attrName)) {
+        SVGElement::synchronizeProperty(attrName);
         return;
     }
 
-    if (attrName == SVGNames::xAttr)
+    if (attrName == SVGNames::xAttr) {
         synchronizeX();
-    else if (attrName == SVGNames::yAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::yAttr) {
         synchronizeY();
-    else if (SVGExternalResourcesRequired::isKnownAttribute(attrName))
+        return;
+    }
+
+    if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) {
         synchronizeExternalResourcesRequired();
-    else if (SVGURIReference::isKnownAttribute(attrName))
+        return;
+    }
+
+    if (SVGURIReference::isKnownAttribute(attrName)) {
         synchronizeHref();
-    else if (SVGTests::isKnownAttribute(attrName))
+        return;
+    }
+
+    if (SVGTests::isKnownAttribute(attrName)) {
         SVGTests::synchronizeProperties(this, attrName);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGCursorElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
index c670009..b9fb071 100644 (file)
@@ -50,6 +50,7 @@ private:
 
     virtual bool isValid() const { return SVGTests::isValid(); }
 
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*);
     virtual void svgAttributeChanged(const QualifiedName&);
     virtual void synchronizeProperty(const QualifiedName&);
index 2a8c52f..d96cff7 100644 (file)
@@ -76,6 +76,15 @@ public:
 
     Document* ownerDocument() const { return m_element ? m_element->ownerDocument() : 0; }
 
+    class InvalidationGuard {
+        WTF_MAKE_NONCOPYABLE(InvalidationGuard);
+    public:    
+        InvalidationGuard(SVGElement* element) : m_element(element) { }
+        ~InvalidationGuard() { SVGElementInstance::invalidateAllInstancesOfElement(m_element); }
+    private:
+        SVGElement* m_element;
+    };
+
     static void invalidateAllInstancesOfElement(SVGElement*);
 
     using TreeShared<SVGElementInstance>::ref;
index fd5ccd4..a15f049 100644 (file)
@@ -27,6 +27,7 @@
 #include "FloatPoint.h"
 #include "RenderSVGPath.h"
 #include "RenderSVGResource.h"
+#include "SVGElementInstance.h"
 #include "SVGLength.h"
 #include "SVGNames.h"
 
@@ -54,34 +55,70 @@ PassRefPtr<SVGEllipseElement> SVGEllipseElement::create(const QualifiedName& tag
     return adoptRef(new SVGEllipseElement(tagName, document));
 }
 
+bool SVGEllipseElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty()) {
+        SVGTests::addSupportedAttributes(supportedAttributes);
+        SVGLangSpace::addSupportedAttributes(supportedAttributes);
+        SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
+        supportedAttributes.add(SVGNames::cxAttr);
+        supportedAttributes.add(SVGNames::cyAttr);
+        supportedAttributes.add(SVGNames::rxAttr);
+        supportedAttributes.add(SVGNames::ryAttr);
+    }
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGEllipseElement::parseMappedAttribute(Attribute* attr)
 {
-    if (attr->name() == SVGNames::cxAttr)
+    if (!isSupportedAttribute(attr->name())) {
+        SVGStyledTransformableElement::parseMappedAttribute(attr);
+        return;
+    }
+
+    if (attr->name() == SVGNames::cxAttr) {
         setCxBaseValue(SVGLength(LengthModeWidth, attr->value()));
-    else if (attr->name() == SVGNames::cyAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::cyAttr) {
         setCyBaseValue(SVGLength(LengthModeHeight, attr->value()));
-    else if (attr->name() == SVGNames::rxAttr) {
+        return;
+    }
+
+    if (attr->name() == SVGNames::rxAttr) {
         setRxBaseValue(SVGLength(LengthModeWidth, attr->value()));
         if (rxBaseValue().value(this) < 0.0)
             document()->accessSVGExtensions()->reportError("A negative value for ellipse <rx> is not allowed");
-    } else if (attr->name() == SVGNames::ryAttr) {
+        return;
+    }
+
+    if (attr->name() == SVGNames::ryAttr) {
         setRyBaseValue(SVGLength(LengthModeHeight, attr->value()));
         if (ryBaseValue().value(this) < 0.0)
             document()->accessSVGExtensions()->reportError("A negative value for ellipse <ry> is not allowed");
-    } else {
-        if (SVGTests::parseMappedAttribute(attr))
-            return;
-        if (SVGLangSpace::parseMappedAttribute(attr))
-            return;
-        if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
-            return;
-        SVGStyledTransformableElement::parseMappedAttribute(attr);
+        return;
     }
+
+    if (SVGTests::parseMappedAttribute(attr))
+        return;
+    if (SVGLangSpace::parseMappedAttribute(attr))
+        return;
+    if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
+        return;
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGEllipseElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    SVGStyledTransformableElement::svgAttributeChanged(attrName);
+    if (!isSupportedAttribute(attrName)) {
+        SVGStyledTransformableElement::svgAttributeChanged(attrName);
+        return;
+    }
+
+    SVGElementInstance::InvalidationGuard invalidationGuard(this);
 
     bool isLengthAttribute = attrName == SVGNames::cxAttr
                           || attrName == SVGNames::cyAttr
@@ -104,15 +141,16 @@ void SVGEllipseElement::svgAttributeChanged(const QualifiedName& attrName)
         return;
     }
 
-    if (SVGLangSpace::isKnownAttribute(attrName)
-        || SVGExternalResourcesRequired::isKnownAttribute(attrName))
+    if (SVGLangSpace::isKnownAttribute(attrName) || SVGExternalResourcesRequired::isKnownAttribute(attrName)) {
         RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGEllipseElement::synchronizeProperty(const QualifiedName& attrName)
 {
-    SVGStyledTransformableElement::synchronizeProperty(attrName);
-
     if (attrName == anyQName()) {
         synchronizeCx();
         synchronizeCy();
@@ -120,21 +158,46 @@ void SVGEllipseElement::synchronizeProperty(const QualifiedName& attrName)
         synchronizeRy();
         synchronizeExternalResourcesRequired();
         SVGTests::synchronizeProperties(this, attrName);
+        SVGStyledTransformableElement::synchronizeProperty(attrName);
         return;
     }
 
-    if (attrName == SVGNames::cxAttr)
+    if (!isSupportedAttribute(attrName)) {
+        SVGStyledTransformableElement::synchronizeProperty(attrName);
+        return;
+    }
+
+    if (attrName == SVGNames::cxAttr) {
         synchronizeCx();
-    else if (attrName == SVGNames::cyAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::cyAttr) {
         synchronizeCy();
-    else if (attrName == SVGNames::rxAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::rxAttr) {
         synchronizeRx();
-    else if (attrName == SVGNames::ryAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::ryAttr) {
         synchronizeRy();
-    else if (SVGExternalResourcesRequired::isKnownAttribute(attrName))
+        return;
+    }
+
+    if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) {
         synchronizeExternalResourcesRequired();
-    else if (SVGTests::isKnownAttribute(attrName))
+        return;
+    }
+
+    if (SVGTests::isKnownAttribute(attrName)) {
         SVGTests::synchronizeProperties(this, attrName);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 AttributeToPropertyTypeMap& SVGEllipseElement::attributeToPropertyTypeMap()
index 2c8a864..231935e 100644 (file)
@@ -43,6 +43,7 @@ private:
     
     virtual bool isValid() const { return SVGTests::isValid(); }
 
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*);
     virtual void svgAttributeChanged(const QualifiedName&);
     virtual void synchronizeProperty(const QualifiedName&);
index beae203..61c5743 100644 (file)
@@ -43,6 +43,11 @@ bool SVGExternalResourcesRequired::isKnownAttribute(const QualifiedName& attrNam
     return attrName == SVGNames::externalResourcesRequiredAttr;
 }
 
+void SVGExternalResourcesRequired::addSupportedAttributes(HashSet<QualifiedName>& supportedAttributes)
+{
+    supportedAttributes.add(SVGNames::externalResourcesRequiredAttr);
+}
+
 }
 
 #endif // ENABLE(SVG)
index 7a37267..9050b59 100644 (file)
 #define SVGExternalResourcesRequired_h
 
 #if ENABLE(SVG)
+#include "QualifiedName.h"
+#include <wtf/HashSet.h>
+
 namespace WebCore {
 
 class Attribute;
-class QualifiedName;
 
 // Notes on a SVG 1.1 spec discrepancy:
 // The SVG DOM defines the attribute externalResourcesRequired as being of type SVGAnimatedBoolean, whereas the 
@@ -38,6 +40,7 @@ public:
 
     bool parseMappedAttribute(Attribute*);
     bool isKnownAttribute(const QualifiedName&);
+    void addSupportedAttributes(HashSet<QualifiedName>&);
 
 protected:
     virtual void setExternalResourcesRequiredBaseValue(const bool&) = 0;
index 96f75d2..9234dbb 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "Attribute.h"
 #include "FilterEffect.h"
+#include "SVGElementInstance.h"
 #include "SVGFilterBuilder.h"
 #include "SVGNames.h"
 
@@ -47,19 +48,43 @@ PassRefPtr<SVGFEBlendElement> SVGFEBlendElement::create(const QualifiedName& tag
     return adoptRef(new SVGFEBlendElement(tagName, document));
 }
 
+bool SVGFEBlendElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty()) {
+        supportedAttributes.add(SVGNames::modeAttr);
+        supportedAttributes.add(SVGNames::inAttr);
+        supportedAttributes.add(SVGNames::in2Attr);
+    }
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGFEBlendElement::parseMappedAttribute(Attribute* attr)
 {
-    const String& value = attr->value();
+    if (!isSupportedAttribute(attr->name())) {
+        SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr);
+        return;
+    }
+
+    const AtomicString& value = attr->value();
     if (attr->name() == SVGNames::modeAttr) {
         BlendModeType propertyValue = SVGPropertyTraits<BlendModeType>::fromString(value);
         if (propertyValue > 0)
             setModeBaseValue(propertyValue);
-    } else if (attr->name() == SVGNames::inAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::inAttr) {
         setIn1BaseValue(value);
-    else if (attr->name() == SVGNames::in2Attr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::in2Attr) {
         setIn2BaseValue(value);
-    else
-        SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 bool SVGFEBlendElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
@@ -74,33 +99,57 @@ bool SVGFEBlendElement::setFilterEffectAttribute(FilterEffect* effect, const Qua
 
 void SVGFEBlendElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
+    if (!isSupportedAttribute(attrName)) {
+        SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
+        return;
+    }
 
-    if (attrName == SVGNames::modeAttr)
+    SVGElementInstance::InvalidationGuard invalidationGuard(this);
+
+    if (attrName == SVGNames::modeAttr) {
         primitiveAttributeChanged(attrName);
+        return;
+    }
 
-    if (attrName == SVGNames::inAttr
-        || attrName == SVGNames::in2Attr)
+    if (attrName == SVGNames::inAttr || attrName == SVGNames::in2Attr) {
         invalidate();
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGFEBlendElement::synchronizeProperty(const QualifiedName& attrName)
 {
-    SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
-
     if (attrName == anyQName()) {
         synchronizeMode();
         synchronizeIn1();
         synchronizeIn2();
+        SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
         return;
     }
 
-    if (attrName == SVGNames::modeAttr)
+    if (!isSupportedAttribute(attrName)) {
+        SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
+        return;
+    }
+
+    if (attrName == SVGNames::modeAttr) {
         synchronizeMode();
-    else if (attrName == SVGNames::inAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::inAttr) {
         synchronizeIn1();
-    else if (attrName == SVGNames::in2Attr)
+        return;
+    }
+
+    if (attrName == SVGNames::in2Attr) {
         synchronizeIn2();
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 AttributeToPropertyTypeMap& SVGFEBlendElement::attributeToPropertyTypeMap()
index 7565103..58798ad 100644 (file)
@@ -35,6 +35,7 @@ public:
 private:
     SVGFEBlendElement(const QualifiedName&, Document*);
 
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*);
     virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName& attrName);
     virtual void svgAttributeChanged(const QualifiedName&);
index d4413e4..c3cd8cb 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "Attribute.h"
 #include "FilterEffect.h"
+#include "SVGElementInstance.h"
 #include "SVGFilterBuilder.h"
 #include "SVGNames.h"
 
@@ -47,22 +48,46 @@ PassRefPtr<SVGFEColorMatrixElement> SVGFEColorMatrixElement::create(const Qualif
     return adoptRef(new SVGFEColorMatrixElement(tagName, document));
 }
 
+bool SVGFEColorMatrixElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty()) {
+        supportedAttributes.add(SVGNames::typeAttr);
+        supportedAttributes.add(SVGNames::valuesAttr);
+        supportedAttributes.add(SVGNames::inAttr);
+    }
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGFEColorMatrixElement::parseMappedAttribute(Attribute* attr)
 {
-    const String& value = attr->value();
+    if (!isSupportedAttribute(attr->name())) {
+        SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr);
+        return;
+    }
+
+    const AtomicString& value = attr->value();
     if (attr->name() == SVGNames::typeAttr) {
         ColorMatrixType propertyValue = SVGPropertyTraits<ColorMatrixType>::fromString(attr->value());
         if (propertyValue > 0)
             setTypeBaseValue(propertyValue);
-    } else if (attr->name() == SVGNames::inAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::inAttr) {
         setIn1BaseValue(value);
-    else if (attr->name() == SVGNames::valuesAttr) {
+        return;
+    }
+
+    if (attr->name() == SVGNames::valuesAttr) {
         SVGNumberList newList;
         newList.parse(value);
         detachAnimatedValuesListWrappers(newList.size());
         setValuesBaseValue(newList);
-    } else
-        SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 bool SVGFEColorMatrixElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
@@ -79,32 +104,57 @@ bool SVGFEColorMatrixElement::setFilterEffectAttribute(FilterEffect* effect, con
 
 void SVGFEColorMatrixElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
+    if (!isSupportedAttribute(attrName)) {
+        SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
+        return;
+    }
+
+    SVGElementInstance::InvalidationGuard invalidationGuard(this);
 
-    if (attrName == SVGNames::typeAttr
-        || attrName == SVGNames::valuesAttr)
+    if (attrName == SVGNames::typeAttr || attrName == SVGNames::valuesAttr) {
         primitiveAttributeChanged(attrName);
-    if (attrName == SVGNames::inAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::inAttr) {
         invalidate();
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGFEColorMatrixElement::synchronizeProperty(const QualifiedName& attrName)
 {
-    SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
-
     if (attrName == anyQName()) {
         synchronizeType();
         synchronizeIn1();
         synchronizeValues();
+        SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
         return;
     }
 
-    if (attrName == SVGNames::typeAttr)
+    if (!isSupportedAttribute(attrName)) {
+        SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
+        return;
+    }
+
+    if (attrName == SVGNames::typeAttr) {
         synchronizeType();
-    else if (attrName == SVGNames::inAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::inAttr) {
         synchronizeIn1();
-    else if (attrName == SVGNames::valuesAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::valuesAttr) {
         synchronizeValues();
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 AttributeToPropertyTypeMap& SVGFEColorMatrixElement::attributeToPropertyTypeMap()
index 0a65713..14b782b 100644 (file)
@@ -36,6 +36,7 @@ public:
 private:
     SVGFEColorMatrixElement(const QualifiedName&, Document*);
 
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*);
     virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&);
     virtual void svgAttributeChanged(const QualifiedName&);
index ebff801..1885caa 100644 (file)
@@ -48,21 +48,49 @@ PassRefPtr<SVGFEComponentTransferElement> SVGFEComponentTransferElement::create(
     return adoptRef(new SVGFEComponentTransferElement(tagName, document));
 }
 
+bool SVGFEComponentTransferElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty())
+        supportedAttributes.add(SVGNames::inAttr);
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGFEComponentTransferElement::parseMappedAttribute(Attribute* attr)
 {
-    const String& value = attr->value();
-    if (attr->name() == SVGNames::inAttr)
-        setIn1BaseValue(value);
-    else
+    if (!isSupportedAttribute(attr->name())) {
         SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr);
+        return;
+    }
+
+    const AtomicString& value = attr->value();
+    if (attr->name() == SVGNames::inAttr) {
+        setIn1BaseValue(value);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGFEComponentTransferElement::synchronizeProperty(const QualifiedName& attrName)
 {
-    SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
+    if (attrName == anyQName()) {
+        synchronizeIn1();
+        SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
+        return;
+    }
 
-    if (attrName == anyQName() || attrName == SVGNames::inAttr)
+    if (!isSupportedAttribute(attrName)) {
+        SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
+        return;
+    }
+
+    if (attrName == SVGNames::inAttr) {
         synchronizeIn1();
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 AttributeToPropertyTypeMap& SVGFEComponentTransferElement::attributeToPropertyTypeMap()
index 0b3608c..1b77ae5 100644 (file)
@@ -34,6 +34,8 @@ public:
 private:
     SVGFEComponentTransferElement(const QualifiedName&, Document*);
 
+    // FIXME: svgAttributeChanged missing.
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*);
     virtual void synchronizeProperty(const QualifiedName&);
     virtual void fillAttributeToPropertyTypeMap();
index 96add07..07dbbe5 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "Attribute.h"
 #include "FilterEffect.h"
+#include "SVGElementInstance.h"
 #include "SVGFilterBuilder.h"
 #include "SVGNames.h"
 
@@ -51,27 +52,67 @@ PassRefPtr<SVGFECompositeElement> SVGFECompositeElement::create(const QualifiedN
     return adoptRef(new SVGFECompositeElement(tagName, document));
 }
 
+bool SVGFECompositeElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty()) {
+        supportedAttributes.add(SVGNames::inAttr);
+        supportedAttributes.add(SVGNames::in2Attr);
+        supportedAttributes.add(SVGNames::operatorAttr);
+        supportedAttributes.add(SVGNames::k1Attr);
+        supportedAttributes.add(SVGNames::k2Attr);
+        supportedAttributes.add(SVGNames::k3Attr);
+        supportedAttributes.add(SVGNames::k4Attr);
+    }
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGFECompositeElement::parseMappedAttribute(Attribute* attr)
 {
-    const String& value = attr->value();
+    if (!isSupportedAttribute(attr->name())) {
+        SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr);
+        return;
+    }
+
+    const AtomicString& value = attr->value();
     if (attr->name() == SVGNames::operatorAttr) {
         CompositeOperationType propertyValue = SVGPropertyTraits<CompositeOperationType>::fromString(value);
         if (propertyValue > 0)
             set_operatorBaseValue(propertyValue);
-    } else if (attr->name() == SVGNames::inAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::inAttr) {
         setIn1BaseValue(value);
-    else if (attr->name() == SVGNames::in2Attr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::in2Attr) {
         setIn2BaseValue(value);
-    else if (attr->name() == SVGNames::k1Attr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::k1Attr) {
         setK1BaseValue(value.toFloat());
-    else if (attr->name() == SVGNames::k2Attr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::k2Attr) {
         setK2BaseValue(value.toFloat());
-    else if (attr->name() == SVGNames::k3Attr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::k3Attr) {
         setK3BaseValue(value.toFloat());
-    else if (attr->name() == SVGNames::k4Attr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::k4Attr) {
         setK4BaseValue(value.toFloat());
-    else
-        SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 bool SVGFECompositeElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
@@ -95,24 +136,32 @@ bool SVGFECompositeElement::setFilterEffectAttribute(FilterEffect* effect, const
 
 void SVGFECompositeElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
+    if (!isSupportedAttribute(attrName)) {
+        SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
+        return;
+    }
+
+    SVGElementInstance::InvalidationGuard invalidationGuard(this);
 
     if (attrName == SVGNames::operatorAttr
         || attrName == SVGNames::k1Attr
         || attrName == SVGNames::k2Attr
         || attrName == SVGNames::k3Attr
-        || attrName == SVGNames::k4Attr)
+        || attrName == SVGNames::k4Attr) {
         primitiveAttributeChanged(attrName);
+        return;
+    }
 
-    if (attrName == SVGNames::inAttr
-        || attrName == SVGNames::in2Attr)
+    if (attrName == SVGNames::inAttr || attrName == SVGNames::in2Attr) {
         invalidate();
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGFECompositeElement::synchronizeProperty(const QualifiedName& attrName)
 {
-    SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
-
     if (attrName == anyQName()) {
         synchronize_operator();
         synchronizeIn1();
@@ -121,23 +170,51 @@ void SVGFECompositeElement::synchronizeProperty(const QualifiedName& attrName)
         synchronizeK2();
         synchronizeK3();
         synchronizeK4();
+        SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
         return;
     }
 
-    if (attrName == SVGNames::operatorAttr)
+    if (!isSupportedAttribute(attrName)) {
+        SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
+        return;
+    }
+
+    if (attrName == SVGNames::operatorAttr) {
         synchronize_operator();
-    else if (attrName == SVGNames::inAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::inAttr) {
         synchronizeIn1();
-    else if (attrName == SVGNames::in2Attr)
+        return;
+    }
+
+    if (attrName == SVGNames::in2Attr) {
         synchronizeIn2();
-    else if (attrName == SVGNames::k1Attr)
+        return;
+    }
+
+    if (attrName == SVGNames::k1Attr) {
         synchronizeK1();
-    else if (attrName == SVGNames::k2Attr)
+        return;
+    }
+
+    if (attrName == SVGNames::k2Attr) {
         synchronizeK2();
-    else if (attrName == SVGNames::k3Attr)
+        return;
+    }
+
+    if (attrName == SVGNames::k3Attr) {
         synchronizeK3();
-    else if (attrName == SVGNames::k4Attr)
+        return;
+    }
+
+    if (attrName == SVGNames::k4Attr) {
         synchronizeK4();
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 AttributeToPropertyTypeMap& SVGFECompositeElement::attributeToPropertyTypeMap()
index 51c2e5a..aef9ae9 100644 (file)
@@ -36,6 +36,7 @@ public:
 private:
     SVGFECompositeElement(const QualifiedName&, Document*);
 
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*);
     virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&);
     virtual void svgAttributeChanged(const QualifiedName&);
index 9ee2514..b5597be 100644 (file)
@@ -27,6 +27,7 @@
 #include "FloatPoint.h"
 #include "IntPoint.h"
 #include "IntSize.h"
+#include "SVGElementInstance.h"
 #include "SVGFilterBuilder.h"
 #include "SVGNames.h"
 #include "SVGParserUtilities.h"
@@ -83,47 +84,99 @@ const AtomicString& SVGFEConvolveMatrixElement::orderYIdentifier()
     return s_identifier;
 }
 
+bool SVGFEConvolveMatrixElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty()) {
+        supportedAttributes.add(SVGNames::inAttr);
+        supportedAttributes.add(SVGNames::orderAttr);
+        supportedAttributes.add(SVGNames::kernelMatrixAttr);
+        supportedAttributes.add(SVGNames::edgeModeAttr);
+        supportedAttributes.add(SVGNames::divisorAttr);
+        supportedAttributes.add(SVGNames::biasAttr);
+        supportedAttributes.add(SVGNames::targetXAttr);
+        supportedAttributes.add(SVGNames::targetYAttr);
+        supportedAttributes.add(SVGNames::kernelUnitLengthAttr);
+        supportedAttributes.add(SVGNames::preserveAlphaAttr);
+    }
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGFEConvolveMatrixElement::parseMappedAttribute(Attribute* attr)
 {
-    const String& value = attr->value();
-    if (attr->name() == SVGNames::inAttr)
+    if (!isSupportedAttribute(attr->name())) {
+        SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr);
+        return;
+    }
+
+    const AtomicString& value = attr->value();
+    if (attr->name() == SVGNames::inAttr) {
         setIn1BaseValue(value);
-    else if (attr->name() == SVGNames::orderAttr) {
+        return;
+    }
+
+    if (attr->name() == SVGNames::orderAttr) {
         float x, y;
         if (parseNumberOptionalNumber(value, x, y)) {
             setOrderXBaseValue(x);
             setOrderYBaseValue(y);
         }
-    } else if (attr->name() == SVGNames::edgeModeAttr) {
+        return;
+    }
+
+    if (attr->name() == SVGNames::edgeModeAttr) {
         EdgeModeType propertyValue = SVGPropertyTraits<EdgeModeType>::fromString(attr->value());
         if (propertyValue > 0)
             setEdgeModeBaseValue(propertyValue);
-    } else if (attr->name() == SVGNames::kernelMatrixAttr) {
+        return;
+    }
+
+    if (attr->name() == SVGNames::kernelMatrixAttr) {
         SVGNumberList newList;
         newList.parse(value);
         detachAnimatedKernelMatrixListWrappers(newList.size());
         setKernelMatrixBaseValue(newList);
-    } else if (attr->name() == SVGNames::divisorAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::divisorAttr) {
         setDivisorBaseValue(value.toFloat());
-    else if (attr->name() == SVGNames::biasAttr)
+        return;
+    }
+    
+    if (attr->name() == SVGNames::biasAttr) {
         setBiasBaseValue(value.toFloat());
-    else if (attr->name() == SVGNames::targetXAttr)
-        setTargetXBaseValue(value.toUIntStrict());
-    else if (attr->name() == SVGNames::targetYAttr)
-        setTargetYBaseValue(value.toUIntStrict());
-    else if (attr->name() == SVGNames::kernelUnitLengthAttr) {
+        return;
+    }
+
+    if (attr->name() == SVGNames::targetXAttr) {
+        setTargetXBaseValue(value.string().toUIntStrict());
+        return;
+    }
+
+    if (attr->name() == SVGNames::targetYAttr) {
+        setTargetYBaseValue(value.string().toUIntStrict());
+        return;
+    }
+
+    if (attr->name() == SVGNames::kernelUnitLengthAttr) {
         float x, y;
         if (parseNumberOptionalNumber(value, x, y)) {
             setKernelUnitLengthXBaseValue(x);
             setKernelUnitLengthYBaseValue(y);
         }
-    } else if (attr->name() == SVGNames::preserveAlphaAttr) {
+        return;
+    }
+
+    if (attr->name() == SVGNames::preserveAlphaAttr) {
         if (value == "true")
             setPreserveAlphaBaseValue(true);
         else if (value == "false")
             setPreserveAlphaBaseValue(false);
-    } else
-        SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 bool SVGFEConvolveMatrixElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
@@ -164,7 +217,12 @@ void SVGFEConvolveMatrixElement::setKernelUnitLength(float x, float y)
 
 void SVGFEConvolveMatrixElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
+    if (!isSupportedAttribute(attrName)) {
+        SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
+        return;
+    }
+
+    SVGElementInstance::InvalidationGuard invalidationGuard(this);
 
     if (attrName == SVGNames::edgeModeAttr
         || attrName == SVGNames::divisorAttr
@@ -172,19 +230,23 @@ void SVGFEConvolveMatrixElement::svgAttributeChanged(const QualifiedName& attrNa
         || attrName == SVGNames::targetXAttr
         || attrName == SVGNames::targetYAttr
         || attrName == SVGNames::kernelUnitLengthAttr
-        || attrName == SVGNames::preserveAlphaAttr)
+        || attrName == SVGNames::preserveAlphaAttr) {
         primitiveAttributeChanged(attrName);
+        return;
+    }
 
     if (attrName == SVGNames::inAttr
         || attrName == SVGNames::orderAttr
-        || attrName == SVGNames::kernelMatrixAttr)
+        || attrName == SVGNames::kernelMatrixAttr) {
         invalidate();
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGFEConvolveMatrixElement::synchronizeProperty(const QualifiedName& attrName)
 {
-    SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
-
     if (attrName == anyQName()) {
         synchronizeEdgeMode();
         synchronizeDivisor();
@@ -194,24 +256,52 @@ void SVGFEConvolveMatrixElement::synchronizeProperty(const QualifiedName& attrNa
         synchronizeKernelUnitLengthX();
         synchronizeKernelUnitLengthY();
         synchronizePreserveAlpha();
+        SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
         return;
     }
 
-    if (attrName == SVGNames::edgeModeAttr)
+    if (!isSupportedAttribute(attrName)) {
+        SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
+        return;
+    }
+
+    if (attrName == SVGNames::edgeModeAttr) {
         synchronizeEdgeMode();
-    else if (attrName == SVGNames::divisorAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::divisorAttr) {
         synchronizeDivisor();
-    else if (attrName == SVGNames::biasAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::biasAttr) {
         synchronizeBias();
-    else if (attrName == SVGNames::targetXAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::targetXAttr) {
         synchronizeTargetX();
-    else if (attrName == SVGNames::targetYAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::targetYAttr) {
         synchronizeTargetY();
-    else if (attrName == SVGNames::kernelUnitLengthAttr) {
+        return;
+    }
+
+    if (attrName == SVGNames::kernelUnitLengthAttr) {
         synchronizeKernelUnitLengthX();
         synchronizeKernelUnitLengthY();
-    } else if (attrName == SVGNames::preserveAlphaAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::preserveAlphaAttr) {
         synchronizePreserveAlpha();
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 AttributeToPropertyTypeMap& SVGFEConvolveMatrixElement::attributeToPropertyTypeMap()
index 351b061..2049ecb 100644 (file)
@@ -41,6 +41,7 @@ public:
 private:
     SVGFEConvolveMatrixElement(const QualifiedName&, Document*);
 
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*);
     virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&);
     virtual void svgAttributeChanged(const QualifiedName&);
index 5cfbf6a..ee2dacf 100644 (file)
@@ -27,6 +27,7 @@
 #include "FilterEffect.h"
 #include "RenderStyle.h"
 #include "SVGColor.h"
+#include "SVGElementInstance.h"
 #include "SVGFELightElement.h"
 #include "SVGFilterBuilder.h"
 #include "SVGNames.h"
@@ -66,23 +67,52 @@ const AtomicString& SVGFEDiffuseLightingElement::kernelUnitLengthYIdentifier()
     return s_identifier;
 }
 
+bool SVGFEDiffuseLightingElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty()) {
+        supportedAttributes.add(SVGNames::inAttr);
+        supportedAttributes.add(SVGNames::diffuseConstantAttr);
+        supportedAttributes.add(SVGNames::surfaceScaleAttr);
+        supportedAttributes.add(SVGNames::kernelUnitLengthAttr);
+        supportedAttributes.add(SVGNames::lighting_colorAttr); // Even though it's a SVG-CSS property, we override its handling here.
+    }
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGFEDiffuseLightingElement::parseMappedAttribute(Attribute* attr)
 {
-    const String& value = attr->value();
-    if (attr->name() == SVGNames::inAttr)
+    if (!isSupportedAttribute(attr->name()) || attr->name() == SVGNames::lighting_colorAttr) {
+        SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr);
+        return;
+    }
+
+    const AtomicString& value = attr->value();
+    if (attr->name() == SVGNames::inAttr) {
         setIn1BaseValue(value);
-    else if (attr->name() == SVGNames::surfaceScaleAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::surfaceScaleAttr) {
         setSurfaceScaleBaseValue(value.toFloat());
-    else if (attr->name() == SVGNames::diffuseConstantAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::diffuseConstantAttr) {
         setDiffuseConstantBaseValue(value.toFloat());
-    else if (attr->name() == SVGNames::kernelUnitLengthAttr) {
+        return;
+    }
+
+    if (attr->name() == SVGNames::kernelUnitLengthAttr) {
         float x, y;
         if (parseNumberOptionalNumber(value, x, y)) {
             setKernelUnitLengthXBaseValue(x);
             setKernelUnitLengthYBaseValue(y);
         }
-    } else
-        SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 bool SVGFEDiffuseLightingElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
@@ -132,16 +162,27 @@ bool SVGFEDiffuseLightingElement::setFilterEffectAttribute(FilterEffect* effect,
 
 void SVGFEDiffuseLightingElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
+    if (!isSupportedAttribute(attrName)) {
+        SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
+        return;
+    }
 
+    SVGElementInstance::InvalidationGuard invalidationGuard(this);
+    
     if (attrName == SVGNames::surfaceScaleAttr
         || attrName == SVGNames::diffuseConstantAttr
         || attrName == SVGNames::kernelUnitLengthAttr
-        || attrName == SVGNames::lighting_colorAttr)
+        || attrName == SVGNames::lighting_colorAttr) {
         primitiveAttributeChanged(attrName);
+        return;
+    }
 
-    if (attrName == SVGNames::inAttr)
+    if (attrName == SVGNames::inAttr) {
         invalidate();
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGFEDiffuseLightingElement::lightElementAttributeChanged(const SVGFELightElement* lightElement, const QualifiedName& attrName)
@@ -155,27 +196,46 @@ void SVGFEDiffuseLightingElement::lightElementAttributeChanged(const SVGFELightE
 
 void SVGFEDiffuseLightingElement::synchronizeProperty(const QualifiedName& attrName)
 {
-    SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
-
     if (attrName == anyQName()) {
         synchronizeIn1();
         synchronizeSurfaceScale();
         synchronizeDiffuseConstant();
         synchronizeKernelUnitLengthX();
         synchronizeKernelUnitLengthY();
+        SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
+        return;
+    }
+
+    if (!isSupportedAttribute(attrName)) {
+        SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
         return;
     }
 
-    if (attrName == SVGNames::inAttr)
+    if (attrName == SVGNames::lighting_colorAttr)
+        return;
+
+    if (attrName == SVGNames::inAttr) {
         synchronizeIn1();
-    else if (attrName == SVGNames::surfaceScaleAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::surfaceScaleAttr) {
         synchronizeSurfaceScale();
-    else if (attrName == SVGNames::diffuseConstantAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::diffuseConstantAttr) {
         synchronizeDiffuseConstant();
-    else if (attrName == SVGNames::kernelUnitLengthAttr) {
+        return;
+    }
+
+    if (attrName == SVGNames::kernelUnitLengthAttr) {
         synchronizeKernelUnitLengthX();
         synchronizeKernelUnitLengthY();
+        return;
     }
+
+    ASSERT_NOT_REACHED();
 }
 
 AttributeToPropertyTypeMap& SVGFEDiffuseLightingElement::attributeToPropertyTypeMap()
index 99dcfde..b4ab426 100644 (file)
@@ -39,6 +39,7 @@ public:
 private:
     SVGFEDiffuseLightingElement(const QualifiedName&, Document*);
 
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*);
     virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&);
     virtual void svgAttributeChanged(const QualifiedName&);
index 1198f64..c0966ee 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "Attribute.h"
 #include "FilterEffect.h"
+#include "SVGElementInstance.h"
 #include "SVGFilterBuilder.h"
 #include "SVGNames.h"
 
@@ -49,25 +50,57 @@ PassRefPtr<SVGFEDisplacementMapElement> SVGFEDisplacementMapElement::create(cons
     return adoptRef(new SVGFEDisplacementMapElement(tagName, document));
 }
 
+bool SVGFEDisplacementMapElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty()) {
+        supportedAttributes.add(SVGNames::inAttr);
+        supportedAttributes.add(SVGNames::in2Attr);
+        supportedAttributes.add(SVGNames::xChannelSelectorAttr);
+        supportedAttributes.add(SVGNames::yChannelSelectorAttr);
+        supportedAttributes.add(SVGNames::scaleAttr);
+    }
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGFEDisplacementMapElement::parseMappedAttribute(Attribute* attr)
 {
-    const String& value = attr->value();
+    if (!isSupportedAttribute(attr->name())) {
+        SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr);
+        return;
+    }
+
+    const AtomicString& value = attr->value();
     if (attr->name() == SVGNames::xChannelSelectorAttr) {
         ChannelSelectorType propertyValue = SVGPropertyTraits<ChannelSelectorType>::fromString(value);
         if (propertyValue > 0)
             setXChannelSelectorBaseValue(propertyValue);
-    } else if (attr->name() == SVGNames::yChannelSelectorAttr) {
+        return;
+    }
+
+    if (attr->name() == SVGNames::yChannelSelectorAttr) {
         ChannelSelectorType propertyValue = SVGPropertyTraits<ChannelSelectorType>::fromString(value);
         if (propertyValue > 0)
             setYChannelSelectorBaseValue(propertyValue);
-    } else if (attr->name() == SVGNames::inAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::inAttr) {
         setIn1BaseValue(value);
-    else if (attr->name() == SVGNames::in2Attr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::in2Attr) {
         setIn2BaseValue(value);
-    else if (attr->name() == SVGNames::scaleAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::scaleAttr) {
         setScaleBaseValue(value.toFloat());
-    else
-        SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 bool SVGFEDisplacementMapElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
@@ -86,37 +119,69 @@ bool SVGFEDisplacementMapElement::setFilterEffectAttribute(FilterEffect* effect,
 
 void SVGFEDisplacementMapElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
+    if (!isSupportedAttribute(attrName)) {
+        SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
+        return;
+    }
 
-    if (attrName == SVGNames::xChannelSelectorAttr || attrName == SVGNames::yChannelSelectorAttr || attrName == SVGNames::scaleAttr)
+    SVGElementInstance::InvalidationGuard invalidationGuard(this);
+    
+    if (attrName == SVGNames::xChannelSelectorAttr || attrName == SVGNames::yChannelSelectorAttr || attrName == SVGNames::scaleAttr) {
         primitiveAttributeChanged(attrName);
-    else if (attrName == SVGNames::inAttr || attrName == SVGNames::in2Attr)
+        return;
+    }
+
+    if (attrName == SVGNames::inAttr || attrName == SVGNames::in2Attr) {
         invalidate();
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGFEDisplacementMapElement::synchronizeProperty(const QualifiedName& attrName)
 {
-    SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
-
     if (attrName == anyQName()) {
         synchronizeXChannelSelector();
         synchronizeYChannelSelector();
         synchronizeIn1();
         synchronizeIn2();
         synchronizeScale();
+        SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
         return;
     }
 
-    if (attrName == SVGNames::xChannelSelectorAttr)
+    if (!isSupportedAttribute(attrName)) {
+        SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
+        return;
+    }
+
+    if (attrName == SVGNames::xChannelSelectorAttr) {
         synchronizeXChannelSelector();
-    else if (attrName == SVGNames::yChannelSelectorAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::yChannelSelectorAttr) {
         synchronizeYChannelSelector();
-    else if (attrName == SVGNames::inAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::inAttr) {
         synchronizeIn1();
-    else if (attrName == SVGNames::in2Attr)
+        return;
+    }
+
+    if (attrName == SVGNames::in2Attr) {
         synchronizeIn2();
-    else if (attrName == SVGNames::scaleAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::scaleAttr) {
         synchronizeScale();
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 AttributeToPropertyTypeMap& SVGFEDisplacementMapElement::attributeToPropertyTypeMap()
index d3d1aab..b4e41d6 100644 (file)
@@ -37,6 +37,7 @@ public:
 private:
     SVGFEDisplacementMapElement(const QualifiedName& tagName, Document*);
     
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*);
     virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName& attrName);
     virtual void svgAttributeChanged(const QualifiedName&);
index c86372e..ad9d3c9 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "Attribute.h"
 #include "RenderStyle.h"
+#include "SVGElementInstance.h"
 #include "SVGFilterBuilder.h"
 #include "SVGNames.h"
 #include "SVGParserUtilities.h"
@@ -72,58 +73,112 @@ void SVGFEDropShadowElement::setStdDeviation(float x, float y)
     invalidate();
 }
 
+bool SVGFEDropShadowElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty()) {
+        supportedAttributes.add(SVGNames::inAttr);
+        supportedAttributes.add(SVGNames::dxAttr);
+        supportedAttributes.add(SVGNames::dyAttr);
+        supportedAttributes.add(SVGNames::stdDeviationAttr);
+    }
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGFEDropShadowElement::parseMappedAttribute(Attribute* attr)
 {
-    const String& value = attr->value();
+    if (!isSupportedAttribute(attr->name())) {
+        SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr);
+        return;
+    }
+
+    const AtomicString& value = attr->value();
     if (attr->name() == SVGNames::stdDeviationAttr) {
         float x, y;
         if (parseNumberOptionalNumber(value, x, y)) {
             setStdDeviationXBaseValue(x);
             setStdDeviationYBaseValue(y);
         }
-    } else if (attr->name() == SVGNames::inAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::inAttr) {
         setIn1BaseValue(value);
-    else if (attr->name() == SVGNames::dxAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::dxAttr) {
         setDxBaseValue(attr->value().toFloat());
-    else if (attr->name() == SVGNames::dyAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::dyAttr) {
         setDyBaseValue(attr->value().toFloat());
-    else
-        SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGFEDropShadowElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
+    if (!isSupportedAttribute(attrName)) {
+        SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
+        return;
+    }
+
+    SVGElementInstance::InvalidationGuard invalidationGuard(this);
     
     if (attrName == SVGNames::inAttr
         || attrName == SVGNames::stdDeviationAttr
         || attrName == SVGNames::dxAttr
-        || attrName == SVGNames::dyAttr)
+        || attrName == SVGNames::dyAttr) {
         invalidate();
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGFEDropShadowElement::synchronizeProperty(const QualifiedName& attrName)
 {
-    SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
-    
     if (attrName == anyQName()) {
         synchronizeStdDeviationX();
         synchronizeStdDeviationY();
         synchronizeDx();
         synchronizeDy();
         synchronizeIn1();
+        SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
         return;
     }
-    
+
+    if (!isSupportedAttribute(attrName)) {
+        SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
+        return;
+    }
+
     if (attrName == SVGNames::stdDeviationAttr) {
         synchronizeStdDeviationX();
         synchronizeStdDeviationY();
-    } else if (attrName == SVGNames::inAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::inAttr) {
         synchronizeIn1();
-    else if (attrName == SVGNames::dxAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::dxAttr) {
         synchronizeDx();
-    else if (attrName == SVGNames::dyAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::dyAttr) {
         synchronizeDy();
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 PassRefPtr<FilterEffect> SVGFEDropShadowElement::build(SVGFilterBuilder* filterBuilder, Filter* filter)
index 0290dce..3aeb782 100644 (file)
@@ -36,6 +36,7 @@ public:
 private:
     SVGFEDropShadowElement(const QualifiedName&, Document*);
     
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*);
     virtual void svgAttributeChanged(const QualifiedName&);
     virtual void synchronizeProperty(const QualifiedName&);
index 10c451b..96b7b2e 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "Attribute.h"
 #include "FilterEffect.h"
+#include "SVGElementInstance.h"
 #include "SVGFilterBuilder.h"
 #include "SVGNames.h"
 #include "SVGParserUtilities.h"
@@ -66,46 +67,85 @@ void SVGFEGaussianBlurElement::setStdDeviation(float x, float y)
     invalidate();
 }
 
+bool SVGFEGaussianBlurElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty()) {
+        supportedAttributes.add(SVGNames::inAttr);
+        supportedAttributes.add(SVGNames::stdDeviationAttr);
+    }
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGFEGaussianBlurElement::parseMappedAttribute(Attribute* attr)
 {
-    const String& value = attr->value();
+    if (!isSupportedAttribute(attr->name())) {
+        SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr);
+        return;
+    }
+
+    const AtomicString& value = attr->value();
     if (attr->name() == SVGNames::stdDeviationAttr) {
         float x, y;
         if (parseNumberOptionalNumber(value, x, y)) {
             setStdDeviationXBaseValue(x);
             setStdDeviationYBaseValue(y);
         }
-    } else if (attr->name() == SVGNames::inAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::inAttr) {
         setIn1BaseValue(value);
-    else
-        SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGFEGaussianBlurElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
+    if (!isSupportedAttribute(attrName)) {
+        SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
+        return;
+    }
 
-    if (attrName == SVGNames::inAttr
-        || attrName == SVGNames::stdDeviationAttr)
+    SVGElementInstance::InvalidationGuard invalidationGuard(this);
+    
+    if (attrName == SVGNames::inAttr || attrName == SVGNames::stdDeviationAttr) {
         invalidate();
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGFEGaussianBlurElement::synchronizeProperty(const QualifiedName& attrName)
 {
-    SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
-
     if (attrName == anyQName()) {
         synchronizeStdDeviationX();
         synchronizeStdDeviationY();
         synchronizeIn1();
+        SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
+        return;
+    }
+
+    if (!isSupportedAttribute(attrName)) {
+        SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
         return;
     }
 
     if (attrName == SVGNames::stdDeviationAttr) {
         synchronizeStdDeviationX();
         synchronizeStdDeviationY();
-    } else if (attrName == SVGNames::inAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::inAttr) {
         synchronizeIn1();
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 AttributeToPropertyTypeMap& SVGFEGaussianBlurElement::attributeToPropertyTypeMap()
index 0c8d8a3..7b13488 100644 (file)
@@ -37,6 +37,7 @@ public:
 private:
     SVGFEGaussianBlurElement(const QualifiedName&, Document*);
 
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*);
     virtual void svgAttributeChanged(const QualifiedName&);
     virtual void synchronizeProperty(const QualifiedName&);
index e2af970..25a4699 100644 (file)
@@ -32,6 +32,7 @@
 #include "Image.h"
 #include "RenderObject.h"
 #include "RenderSVGResource.h"
+#include "SVGElementInstance.h"
 #include "SVGImageBufferTools.h"
 #include "SVGNames.h"
 #include "SVGPreserveAspectRatio.h"
@@ -77,50 +78,96 @@ void SVGFEImageElement::requestImageResource()
         m_cachedImage->addClient(this);
 }
 
+bool SVGFEImageElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty()) {
+        SVGURIReference::addSupportedAttributes(supportedAttributes);
+        SVGLangSpace::addSupportedAttributes(supportedAttributes);
+        SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
+        supportedAttributes.add(SVGNames::preserveAspectRatioAttr);
+    }
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGFEImageElement::parseMappedAttribute(Attribute* attr)
 {
-    const String& value = attr->value();
-    if (attr->name() == SVGNames::preserveAspectRatioAttr)
+    if (!isSupportedAttribute(attr->name())) {
+        SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr);
+        return;
+    }
+
+    const AtomicString& value = attr->value();
+    if (attr->name() == SVGNames::preserveAspectRatioAttr) {
         SVGPreserveAspectRatio::parsePreserveAspectRatio(this, value);
-    else {
-        if (SVGURIReference::parseMappedAttribute(attr)) {
-            requestImageResource();
-            return;
-        }
-        if (SVGLangSpace::parseMappedAttribute(attr))
-            return;
-        if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
-            return;
+        return;
+    }
 
-        SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr);
+    if (SVGURIReference::parseMappedAttribute(attr)) {
+        requestImageResource();
+        return;
     }
+
+    if (SVGLangSpace::parseMappedAttribute(attr))
+        return;
+    if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
+        return;
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGFEImageElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
+    if (!isSupportedAttribute(attrName)) {
+        SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
+        return;
+    }
 
-    if (attrName == SVGNames::preserveAspectRatioAttr)
+    SVGElementInstance::InvalidationGuard invalidationGuard(this);
+    
+    if (attrName == SVGNames::preserveAspectRatioAttr) {
         invalidate();
+        return;
+    }
+
+    // FIXME: This can't be correct, I'm just preserving existing code. <feImage> + SVG DOM 'href' changes need testing.
+    if (SVGLangSpace::isKnownAttribute(attrName) || SVGExternalResourcesRequired::isKnownAttribute(attrName) || SVGURIReference::isKnownAttribute(attrName))
+        return;
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGFEImageElement::synchronizeProperty(const QualifiedName& attrName)
 {
-    SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
-
     if (attrName == anyQName()) {
         synchronizePreserveAspectRatio();
         synchronizeHref();
         synchronizeExternalResourcesRequired();
+        SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
         return;
     }
 
-    if (attrName == SVGNames::preserveAspectRatioAttr)
+    if (!isSupportedAttribute(attrName)) {
+        SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
+        return;
+    }   
+
+    if (attrName == SVGNames::preserveAspectRatioAttr) {
         synchronizePreserveAspectRatio();
-    else if (SVGURIReference::isKnownAttribute(attrName))
+        return;
+    }
+
+    if (SVGURIReference::isKnownAttribute(attrName)) {
         synchronizeHref();
-    else if (SVGExternalResourcesRequired::isKnownAttribute(attrName))
+        return;
+    }
+
+    if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) {
         synchronizeExternalResourcesRequired();
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 AttributeToPropertyTypeMap& SVGFEImageElement::attributeToPropertyTypeMap()
index 8a63fc9..b6b9a37 100644 (file)
@@ -48,6 +48,7 @@ public:
 private:
     SVGFEImageElement(const QualifiedName&, Document*);
 
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*);
     virtual void svgAttributeChanged(const QualifiedName&);
     virtual void synchronizeProperty(const QualifiedName&);
index 110011f..7b0772c 100644 (file)
@@ -27,6 +27,7 @@
 #include "Attribute.h"
 #include "RenderObject.h"
 #include "RenderSVGResource.h"
+#include "SVGElementInstance.h"
 #include "SVGFEDiffuseLightingElement.h"
 #include "SVGFESpecularLightingElement.h"
 #include "SVGFilterElement.h"
@@ -73,37 +74,94 @@ PassRefPtr<LightSource> SVGFELightElement::findLightSource(const SVGElement* svg
     return lightNode->lightSource();
 }
 
+bool SVGFELightElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty()) {
+        supportedAttributes.add(SVGNames::azimuthAttr);
+        supportedAttributes.add(SVGNames::elevationAttr);
+        supportedAttributes.add(SVGNames::xAttr);
+        supportedAttributes.add(SVGNames::yAttr);
+        supportedAttributes.add(SVGNames::zAttr);
+        supportedAttributes.add(SVGNames::pointsAtXAttr);
+        supportedAttributes.add(SVGNames::pointsAtYAttr);
+        supportedAttributes.add(SVGNames::pointsAtZAttr);
+        supportedAttributes.add(SVGNames::specularExponentAttr);
+        supportedAttributes.add(SVGNames::limitingConeAngleAttr);
+    }
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGFELightElement::parseMappedAttribute(Attribute* attr)
 {
-    const String& value = attr->value();
-    if (attr->name() == SVGNames::azimuthAttr)
+    if (!isSupportedAttribute(attr->name())) {
+        SVGElement::parseMappedAttribute(attr);
+        return;
+    }
+
+    const AtomicString& value = attr->value();
+    if (attr->name() == SVGNames::azimuthAttr) {
         setAzimuthBaseValue(value.toFloat());
-    else if (attr->name() == SVGNames::elevationAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::elevationAttr) {
         setElevationBaseValue(value.toFloat());
-    else if (attr->name() == SVGNames::xAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::xAttr) {
         setXBaseValue(value.toFloat());
-    else if (attr->name() == SVGNames::yAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::yAttr) {
         setYBaseValue(value.toFloat());
-    else if (attr->name() == SVGNames::zAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::zAttr) {
         setZBaseValue(value.toFloat());
-    else if (attr->name() == SVGNames::pointsAtXAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::pointsAtXAttr) {
         setPointsAtXBaseValue(value.toFloat());
-    else if (attr->name() == SVGNames::pointsAtYAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::pointsAtYAttr) {
         setPointsAtYBaseValue(value.toFloat());
-    else if (attr->name() == SVGNames::pointsAtZAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::pointsAtZAttr) {
         setPointsAtZBaseValue(value.toFloat());
-    else if (attr->name() == SVGNames::specularExponentAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::specularExponentAttr) {
         setSpecularExponentBaseValue(value.toFloat());
-    else if (attr->name() == SVGNames::limitingConeAngleAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::limitingConeAngleAttr) {
         setLimitingConeAngleBaseValue(value.toFloat());
-    else
-        SVGElement::parseMappedAttribute(attr);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGFELightElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    SVGElement::svgAttributeChanged(attrName);
+    if (!isSupportedAttribute(attrName)) {
+        SVGElement::svgAttributeChanged(attrName);
+        return;
+    }
 
+    SVGElementInstance::InvalidationGuard invalidationGuard(this);
+    
     if (attrName == SVGNames::azimuthAttr
         || attrName == SVGNames::elevationAttr
         || attrName == SVGNames::xAttr
@@ -132,12 +190,12 @@ void SVGFELightElement::svgAttributeChanged(const QualifiedName& attrName)
             return;
         }
     }
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGFELightElement::synchronizeProperty(const QualifiedName& attrName)
 {
-    SVGElement::synchronizeProperty(attrName);
-
     if (attrName == anyQName()) {
         synchronizeAzimuth();
         synchronizeElevation();
@@ -149,29 +207,66 @@ void SVGFELightElement::synchronizeProperty(const QualifiedName& attrName)
         synchronizePointsAtZ();
         synchronizeSpecularExponent();
         synchronizeLimitingConeAngle();
+        SVGElement::synchronizeProperty(attrName);
         return;
     }
 
-    if (attrName == SVGNames::azimuthAttr)
+    if (!isSupportedAttribute(attrName)) {
+        SVGElement::synchronizeProperty(attrName);
+        return;
+    }
+    
+    if (attrName == SVGNames::azimuthAttr) {
         synchronizeAzimuth();
-    else if (attrName == SVGNames::elevationAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::elevationAttr) {
         synchronizeElevation();
-    else if (attrName == SVGNames::xAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::xAttr) {
         synchronizeX();
-    else if (attrName == SVGNames::yAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::yAttr) {
         synchronizeY();
-    else if (attrName == SVGNames::zAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::zAttr) {
         synchronizeZ();
-    else if (attrName == SVGNames::pointsAtXAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::pointsAtXAttr) {
         synchronizePointsAtX();
-    else if (attrName == SVGNames::pointsAtYAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::pointsAtYAttr) {
         synchronizePointsAtY();
-    else if (attrName == SVGNames::pointsAtZAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::pointsAtZAttr) {
         synchronizePointsAtZ();
-    else if (attrName == SVGNames::specularExponentAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::specularExponentAttr) {
         synchronizeSpecularExponent();
-    else if (attrName == SVGNames::limitingConeAngleAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::limitingConeAngleAttr) {
         synchronizeLimitingConeAngle();
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 AttributeToPropertyTypeMap& SVGFELightElement::attributeToPropertyTypeMap()
index 1e88a49..f6814b3 100644 (file)
@@ -39,6 +39,7 @@ protected:
     SVGFELightElement(const QualifiedName&, Document*);
 
 private:
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*);
     virtual void svgAttributeChanged(const QualifiedName&);
     virtual void synchronizeProperty(const QualifiedName&);
index 69a7ede..b4789cd 100644 (file)
@@ -26,6 +26,7 @@
 #include "Attribute.h"
 #include "RenderObject.h"
 #include "RenderSVGResource.h"
+#include "SVGElementInstance.h"
 #include "SVGFilterElement.h"
 #include "SVGNames.h"
 
@@ -45,31 +46,52 @@ PassRefPtr<SVGFEMergeNodeElement> SVGFEMergeNodeElement::create(const QualifiedN
     return adoptRef(new SVGFEMergeNodeElement(tagName, document));
 }
 
+bool SVGFEMergeNodeElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty())
+        supportedAttributes.add(SVGNames::inAttr);
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGFEMergeNodeElement::parseMappedAttribute(Attribute* attr)
 {
-    const String& value = attr->value();
-    if (attr->name() == SVGNames::inAttr)
-        setIn1BaseValue(value);
-    else
+    if (!isSupportedAttribute(attr->name())) {
         SVGElement::parseMappedAttribute(attr);
+        return;
+    }
+
+    if (attr->name() == SVGNames::inAttr) {
+        setIn1BaseValue(attr->value());
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGFEMergeNodeElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    SVGElement::svgAttributeChanged(attrName);
-
-    if (attrName != SVGNames::inAttr)
+    if (!isSupportedAttribute(attrName)) {
+        SVGElement::svgAttributeChanged(attrName);
         return;
+    }
 
-    ContainerNode* parent = parentNode();
-    if (!parent)
-        return;
+    SVGElementInstance::InvalidationGuard invalidationGuard(this);
+    
+    if (attrName == SVGNames::inAttr) {
+        ContainerNode* parent = parentNode();
+        if (!parent)
+            return;
 
-    RenderObject* renderer = parent->renderer();
-    if (!renderer || !renderer->isSVGResourceFilterPrimitive())
+        RenderObject* renderer = parent->renderer();
+        if (!renderer || !renderer->isSVGResourceFilterPrimitive())
+            return;
+
+        RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
         return;
-    
-    RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 AttributeToPropertyTypeMap& SVGFEMergeNodeElement::attributeToPropertyTypeMap()
@@ -85,10 +107,23 @@ void SVGFEMergeNodeElement::fillAttributeToPropertyTypeMap()
 
 void SVGFEMergeNodeElement::synchronizeProperty(const QualifiedName& attrName)
 {
-    SVGElement::synchronizeProperty(attrName);
+    if (attrName == anyQName()) {
+        synchronizeIn1();
+        SVGElement::synchronizeProperty(attrName);
+        return;
+    }
 
-    if (attrName == anyQName() || attrName == SVGNames::inAttr)
+    if (!isSupportedAttribute(attrName)) {
+        SVGElement::synchronizeProperty(attrName);
+        return;
+    }   
+
+    if (attrName == SVGNames::inAttr) {
         synchronizeIn1();
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 }
index d986829..7e64237 100644 (file)
@@ -34,6 +34,7 @@ public:
 private:
     SVGFEMergeNodeElement(const QualifiedName&, Document*);
 
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*);
     virtual void svgAttributeChanged(const QualifiedName&);
     virtual void synchronizeProperty(const QualifiedName&);
index ea1d64e..7395678 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "Attribute.h"
 #include "FilterEffect.h"
+#include "SVGElementInstance.h"
 #include "SVGFilterBuilder.h"
 #include "SVGNames.h"
 #include "SVGParserUtilities.h"
@@ -67,23 +68,47 @@ void SVGFEMorphologyElement::setRadius(float x, float y)
     invalidate();
 }
 
+bool SVGFEMorphologyElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty()) {
+        supportedAttributes.add(SVGNames::inAttr);
+        supportedAttributes.add(SVGNames::operatorAttr);
+        supportedAttributes.add(SVGNames::radiusAttr);
+    }
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGFEMorphologyElement::parseMappedAttribute(Attribute* attr)
 {
-    const String& value = attr->value();
+    if (!isSupportedAttribute(attr->name())) {
+        SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr);
+        return;
+    }
+
+    const AtomicString& value = attr->value();
     if (attr->name() == SVGNames::operatorAttr) {
         MorphologyOperatorType propertyValue = SVGPropertyTraits<MorphologyOperatorType>::fromString(value);
         if (propertyValue > 0)
             set_operatorBaseValue(propertyValue);
-    } else if (attr->name() == SVGNames::inAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::inAttr) {
         setIn1BaseValue(value);
-    else if (attr->name() == SVGNames::radiusAttr) {
+        return;
+    }
+
+    if (attr->name() == SVGNames::radiusAttr) {
         float x, y;
         if (parseNumberOptionalNumber(value, x, y)) {
             setRadiusXBaseValue(x);
             setRadiusYBaseValue(y);
         }
-    } else
-        SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 bool SVGFEMorphologyElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
@@ -100,36 +125,59 @@ bool SVGFEMorphologyElement::setFilterEffectAttribute(FilterEffect* effect, cons
 
 void SVGFEMorphologyElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
+    if (!isSupportedAttribute(attrName)) {
+        SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
+        return;
+    }
 
-    if (attrName == SVGNames::operatorAttr
-        || attrName == SVGNames::radiusAttr)
+    SVGElementInstance::InvalidationGuard invalidationGuard(this);
+    
+    if (attrName == SVGNames::operatorAttr || attrName == SVGNames::radiusAttr) {
         primitiveAttributeChanged(attrName);
+        return;
+    }
 
-    if (attrName == SVGNames::inAttr)
+    if (attrName == SVGNames::inAttr) {
         invalidate();
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGFEMorphologyElement::synchronizeProperty(const QualifiedName& attrName)
 {
-    SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
-
     if (attrName == anyQName()) {
         synchronize_operator();
         synchronizeIn1();
         synchronizeRadiusX();
         synchronizeRadiusY();
+        SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
         return;
     }
 
-    if (attrName == SVGNames::operatorAttr)
+    if (!isSupportedAttribute(attrName)) {
+        SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
+        return;
+    }
+
+    if (attrName == SVGNames::operatorAttr) {
         synchronize_operator();
-    else if (attrName == SVGNames::inAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::inAttr) {
         synchronizeIn1();
-    else if (attrName == SVGNames::radiusAttr) {
+        return;
+    }
+
+    if (attrName == SVGNames::radiusAttr) {
         synchronizeRadiusX();
         synchronizeRadiusY();
+        return;
     }
+
+    ASSERT_NOT_REACHED();
 }
 
 AttributeToPropertyTypeMap& SVGFEMorphologyElement::attributeToPropertyTypeMap()
index bed9db7..8b92e4a 100644 (file)
@@ -37,6 +37,7 @@ public:
 private:
     SVGFEMorphologyElement(const QualifiedName&, Document*);
 
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*);
     virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&);
     virtual void svgAttributeChanged(const QualifiedName&);
index dd188a4..1071f76 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "Attribute.h"
 #include "FilterEffect.h"
+#include "SVGElementInstance.h"
 #include "SVGFilterBuilder.h"
 #include "SVGNames.h"
 
@@ -46,46 +47,91 @@ PassRefPtr<SVGFEOffsetElement> SVGFEOffsetElement::create(const QualifiedName& t
     return adoptRef(new SVGFEOffsetElement(tagName, document));
 }
 
+bool SVGFEOffsetElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty()) {
+        supportedAttributes.add(SVGNames::inAttr);
+        supportedAttributes.add(SVGNames::dxAttr);
+        supportedAttributes.add(SVGNames::dyAttr);
+    }
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGFEOffsetElement::parseMappedAttribute(Attribute* attr)
 {
-    const String& value = attr->value();
-    if (attr->name() == SVGNames::dxAttr)
+    if (!isSupportedAttribute(attr->name())) {
+        SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr);
+        return;
+    }
+
+    const AtomicString& value = attr->value();
+    if (attr->name() == SVGNames::dxAttr) {
         setDxBaseValue(value.toFloat());
-    else if (attr->name() == SVGNames::dyAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::dyAttr) {
         setDyBaseValue(value.toFloat());
-    else if (attr->name() == SVGNames::inAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::inAttr) {
         setIn1BaseValue(value);
-    else
-        SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGFEOffsetElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
+    if (!isSupportedAttribute(attrName)) {
+        SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
+        return;
+    }
 
-    if (attrName == SVGNames::inAttr
-        || attrName == SVGNames::dxAttr
-        || attrName == SVGNames::dyAttr)
+    SVGElementInstance::InvalidationGuard invalidationGuard(this);
+    
+    if (attrName == SVGNames::inAttr || attrName == SVGNames::dxAttr || attrName == SVGNames::dyAttr) {
         invalidate();
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGFEOffsetElement::synchronizeProperty(const QualifiedName& attrName)
 {
-    SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
-
     if (attrName == anyQName()) {
         synchronizeDx();
         synchronizeDy();
         synchronizeIn1();
+        SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
+        return;
+    }
+
+    if (!isSupportedAttribute(attrName)) {
+        SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
         return;
     }
 
-    if (attrName == SVGNames::dxAttr)
+    if (attrName == SVGNames::dxAttr) {
         synchronizeDx();
-    else if (attrName == SVGNames::dyAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::dyAttr) {
         synchronizeDy();
-    else if (attrName == SVGNames::inAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::inAttr) {
         synchronizeIn1();
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 AttributeToPropertyTypeMap& SVGFEOffsetElement::attributeToPropertyTypeMap()
index e5b6fd1..f59eeb5 100644 (file)
@@ -35,6 +35,7 @@ public:
 private:
     SVGFEOffsetElement(const QualifiedName&, Document*);
 
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*);
     virtual void svgAttributeChanged(const QualifiedName&);
     virtual void synchronizeProperty(const QualifiedName&);
index fc4aa53..0d377d4 100644 (file)
@@ -28,6 +28,7 @@
 #include "FilterEffect.h"
 #include "RenderStyle.h"
 #include "SVGColor.h"
+#include "SVGElementInstance.h"
 #include "SVGFELightElement.h"
 #include "SVGFilterBuilder.h"
 #include "SVGNames.h"
@@ -69,25 +70,57 @@ const AtomicString& SVGFESpecularLightingElement::kernelUnitLengthYIdentifier()
     return s_identifier;
 }
 
+bool SVGFESpecularLightingElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty()) {
+        supportedAttributes.add(SVGNames::inAttr);
+        supportedAttributes.add(SVGNames::specularConstantAttr);
+        supportedAttributes.add(SVGNames::specularExponentAttr);
+        supportedAttributes.add(SVGNames::surfaceScaleAttr);
+        supportedAttributes.add(SVGNames::kernelUnitLengthAttr);
+    }
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGFESpecularLightingElement::parseMappedAttribute(Attribute* attr)
-{    
-    const String& value = attr->value();
-    if (attr->name() == SVGNames::inAttr)
+{
+    if (!isSupportedAttribute(attr->name())) {
+        SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr);
+        return;
+    }
+
+    const AtomicString& value = attr->value();
+    if (attr->name() == SVGNames::inAttr) {
         setIn1BaseValue(value);
-    else if (attr->name() == SVGNames::surfaceScaleAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::surfaceScaleAttr) {
         setSurfaceScaleBaseValue(value.toFloat());
-    else if (attr->name() == SVGNames::specularConstantAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::specularConstantAttr) {
         setSpecularConstantBaseValue(value.toFloat());
-    else if (attr->name() == SVGNames::specularExponentAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::specularExponentAttr) {
         setSpecularExponentBaseValue(value.toFloat());
-    else if (attr->name() == SVGNames::kernelUnitLengthAttr) {
+        return;
+    }
+
+    if (attr->name() == SVGNames::kernelUnitLengthAttr) {
         float x, y;
         if (parseNumberOptionalNumber(value, x, y)) {
             setKernelUnitLengthXBaseValue(x);
             setKernelUnitLengthYBaseValue(y);
         }
-    } else
-        SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 bool SVGFESpecularLightingElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
@@ -139,16 +172,27 @@ bool SVGFESpecularLightingElement::setFilterEffectAttribute(FilterEffect* effect
 
 void SVGFESpecularLightingElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
+    if (!isSupportedAttribute(attrName)) {
+        SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
+        return;
+    }
 
+    SVGElementInstance::InvalidationGuard invalidationGuard(this);
+    
     if (attrName == SVGNames::surfaceScaleAttr
         || attrName == SVGNames::specularConstantAttr
         || attrName == SVGNames::specularExponentAttr
-        || attrName == SVGNames::kernelUnitLengthAttr)
+        || attrName == SVGNames::kernelUnitLengthAttr) {
         primitiveAttributeChanged(attrName);
+        return;
+    }
 
-    if (attrName == SVGNames::inAttr)
+    if (attrName == SVGNames::inAttr) {
         invalidate();
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGFESpecularLightingElement::lightElementAttributeChanged(const SVGFELightElement* lightElement, const QualifiedName& attrName)
@@ -162,8 +206,6 @@ void SVGFESpecularLightingElement::lightElementAttributeChanged(const SVGFELight
 
 void SVGFESpecularLightingElement::synchronizeProperty(const QualifiedName& attrName)
 {
-    SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
-
     if (attrName == anyQName()) {
         synchronizeIn1();
         synchronizeSurfaceScale();
@@ -171,21 +213,42 @@ void SVGFESpecularLightingElement::synchronizeProperty(const QualifiedName& attr
         synchronizeSpecularExponent();
         synchronizeKernelUnitLengthX();
         synchronizeKernelUnitLengthY();
+        SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
+        return;
+    }
+
+    if (!isSupportedAttribute(attrName)) {
+        SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
         return;
     }
 
-    if (attrName == SVGNames::inAttr)
+    if (attrName == SVGNames::inAttr) {
         synchronizeIn1();
-    else if (attrName == SVGNames::surfaceScaleAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::surfaceScaleAttr) {
         synchronizeSurfaceScale();
-    else if (attrName == SVGNames::specularConstantAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::specularConstantAttr) {
         synchronizeSpecularConstant();
-    else if (attrName == SVGNames::specularExponentAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::specularExponentAttr) {
         synchronizeSpecularExponent();
-    else if (attrName == SVGNames::kernelUnitLengthAttr) {
+        return;
+    }
+
+    if (attrName == SVGNames::kernelUnitLengthAttr) {
         synchronizeKernelUnitLengthX();
         synchronizeKernelUnitLengthY();
+        return;
     }
+
+    ASSERT_NOT_REACHED();
 }
 
 AttributeToPropertyTypeMap& SVGFESpecularLightingElement::attributeToPropertyTypeMap()
index cfceb44..d43e479 100644 (file)
@@ -38,6 +38,7 @@ public:
 private:
     SVGFESpecularLightingElement(const QualifiedName&, Document*);
     
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*);
     virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&);
     virtual void svgAttributeChanged(const QualifiedName&);
index d299806..e2215f5 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "Attribute.h"
 #include "FilterEffect.h"
+#include "SVGElementInstance.h"
 #include "SVGFilterBuilder.h"
 #include "SVGNames.h"
 #include "SVGRenderStyle.h"
@@ -45,29 +46,65 @@ PassRefPtr<SVGFETileElement> SVGFETileElement::create(const QualifiedName& tagNa
     return adoptRef(new SVGFETileElement(tagName, document));
 }
 
+bool SVGFETileElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty())
+        supportedAttributes.add(SVGNames::inAttr);
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGFETileElement::parseMappedAttribute(Attribute* attr)
 {
-    const String& value = attr->value();
-    if (attr->name() == SVGNames::inAttr)
-        setIn1BaseValue(value);
-    else
+    if (!isSupportedAttribute(attr->name())) {
         SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr);
+        return;
+    }
+
+    if (attr->name() == SVGNames::inAttr) {
+        setIn1BaseValue(attr->value());
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGFETileElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
-    
-    if (attrName == SVGNames::inAttr)
+    if (!isSupportedAttribute(attrName)) {
+        SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
+        return;
+    }
+
+    SVGElementInstance::InvalidationGuard invalidationGuard(this);
+
+    if (attrName == SVGNames::inAttr) {
         invalidate();
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGFETileElement::synchronizeProperty(const QualifiedName& attrName)
 {
-    SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
-
-    if (attrName == anyQName() || attrName == SVGNames::inAttr)
+    if (attrName == anyQName()) {
         synchronizeIn1();
+        SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
+        return;
+    }
+
+    if (!isSupportedAttribute(attrName)) {
+        SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
+        return;
+    }
+    
+    if (attrName == SVGNames::inAttr) {
+        synchronizeIn1();
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 AttributeToPropertyTypeMap& SVGFETileElement::attributeToPropertyTypeMap()
index 447827c..d6a9972 100644 (file)
@@ -34,6 +34,7 @@ public:
 private:
     SVGFETileElement(const QualifiedName&, Document*);
 
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*);
     virtual void svgAttributeChanged(const QualifiedName&);
     virtual void synchronizeProperty(const QualifiedName&);
index f710ddb..843b7d7 100644 (file)
@@ -24,6 +24,7 @@
 #include "SVGFETurbulenceElement.h"
 
 #include "Attribute.h"
+#include "SVGElementInstance.h"
 #include "SVGNames.h"
 #include "SVGParserUtilities.h"
 
@@ -63,29 +64,61 @@ const AtomicString& SVGFETurbulenceElement::baseFrequencyYIdentifier()
     return s_identifier;
 }
 
+bool SVGFETurbulenceElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty()) {
+        supportedAttributes.add(SVGNames::baseFrequencyAttr);
+        supportedAttributes.add(SVGNames::numOctavesAttr);
+        supportedAttributes.add(SVGNames::seedAttr);
+        supportedAttributes.add(SVGNames::stitchTilesAttr);
+        supportedAttributes.add(SVGNames::typeAttr);
+    }
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGFETurbulenceElement::parseMappedAttribute(Attribute* attr)
 {
-    const String& value = attr->value();
+    if (!isSupportedAttribute(attr->name())) {
+        SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr);
+        return;
+    }
+
+    const AtomicString& value = attr->value();
     if (attr->name() == SVGNames::typeAttr) {
         TurbulenceType propertyValue = SVGPropertyTraits<TurbulenceType>::fromString(value);
         if (propertyValue > 0)
             setTypeBaseValue(propertyValue);
-    } else if (attr->name() == SVGNames::stitchTilesAttr) {
+        return;
+    }
+
+    if (attr->name() == SVGNames::stitchTilesAttr) {
         SVGStitchOptions propertyValue = SVGPropertyTraits<SVGStitchOptions>::fromString(value);
         if (propertyValue > 0)
             setStitchTilesBaseValue(propertyValue);
-    } else if (attr->name() == SVGNames::baseFrequencyAttr) {
+        return;
+    }
+
+    if (attr->name() == SVGNames::baseFrequencyAttr) {
         float x, y;
         if (parseNumberOptionalNumber(value, x, y)) {
             setBaseFrequencyXBaseValue(x);
             setBaseFrequencyYBaseValue(y);
         }
-    } else if (attr->name() == SVGNames::seedAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::seedAttr) {
         setSeedBaseValue(value.toFloat());
-    else if (attr->name() == SVGNames::numOctavesAttr)
-        setNumOctavesBaseValue(value.toUIntStrict());
-    else
-        SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr);
+        return;
+    }
+
+    if (attr->name() == SVGNames::numOctavesAttr) {
+        setNumOctavesBaseValue(value.string().toUIntStrict());
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 bool SVGFETurbulenceElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
@@ -108,20 +141,27 @@ bool SVGFETurbulenceElement::setFilterEffectAttribute(FilterEffect* effect, cons
 
 void SVGFETurbulenceElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
+    if (!isSupportedAttribute(attrName)) {
+        SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(attrName);
+        return;
+    }
 
+    SVGElementInstance::InvalidationGuard invalidationGuard(this);
+    
     if (attrName == SVGNames::baseFrequencyAttr
         || attrName == SVGNames::numOctavesAttr
         || attrName == SVGNames::seedAttr
         || attrName == SVGNames::stitchTilesAttr
-        || attrName == SVGNames::typeAttr)
+        || attrName == SVGNames::typeAttr) {
         primitiveAttributeChanged(attrName);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGFETurbulenceElement::synchronizeProperty(const QualifiedName& attrName)
 {
-    SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
-
     if (attrName == anyQName()) {
         synchronizeType();
         synchronizeStitchTiles();
@@ -129,20 +169,42 @@ void SVGFETurbulenceElement::synchronizeProperty(const QualifiedName& attrName)
         synchronizeBaseFrequencyY();
         synchronizeSeed();
         synchronizeNumOctaves();
+        SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
         return;
     }
 
-    if (attrName == SVGNames::typeAttr)
+    if (!isSupportedAttribute(attrName)) {
+        SVGFilterPrimitiveStandardAttributes::synchronizeProperty(attrName);
+        return;
+    }
+
+    if (attrName == SVGNames::typeAttr) {
         synchronizeType();
-    else if (attrName == SVGNames::stitchTilesAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::stitchTilesAttr) {
         synchronizeStitchTiles();
-    else if (attrName == SVGNames::baseFrequencyAttr) {
+        return;
+    }
+
+    if (attrName == SVGNames::baseFrequencyAttr) {
         synchronizeBaseFrequencyX();
         synchronizeBaseFrequencyY();
-    } else if (attrName == SVGNames::seedAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::seedAttr) {
         synchronizeSeed();
-    else if (attrName == SVGNames::numOctavesAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::numOctavesAttr) {
         synchronizeNumOctaves();
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 AttributeToPropertyTypeMap& SVGFETurbulenceElement::attributeToPropertyTypeMap()
index 15dbe53..705e966 100644 (file)
@@ -43,6 +43,7 @@ public:
 private:
     SVGFETurbulenceElement(const QualifiedName&, Document*);
 
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*);
     virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName& attrName);
     virtual void svgAttributeChanged(const QualifiedName&);
index 9270b4b..169778b 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "Attr.h"
 #include "RenderSVGResourceFilter.h"
+#include "SVGElementInstance.h"
 #include "SVGFilterBuilder.h"
 #include "SVGFilterPrimitiveStandardAttributes.h"
 #include "SVGNames.h"
@@ -90,75 +91,106 @@ void SVGFilterElement::setFilterRes(unsigned long filterResX, unsigned long filt
         object->setNeedsLayout(true);
 }
 
+bool SVGFilterElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty()) {
+        SVGURIReference::addSupportedAttributes(supportedAttributes);
+        SVGLangSpace::addSupportedAttributes(supportedAttributes);
+        SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
+        supportedAttributes.add(SVGNames::filterUnitsAttr);
+        supportedAttributes.add(SVGNames::primitiveUnitsAttr);
+        supportedAttributes.add(SVGNames::xAttr);
+        supportedAttributes.add(SVGNames::yAttr);
+        supportedAttributes.add(SVGNames::widthAttr);
+        supportedAttributes.add(SVGNames::heightAttr);
+        supportedAttributes.add(SVGNames::filterResAttr);
+    }
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGFilterElement::parseMappedAttribute(Attribute* attr)
 {
-    const String& value = attr->value();
+    if (!isSupportedAttribute(attr->name())) {
+        SVGStyledElement::parseMappedAttribute(attr);
+        return;
+    }
+
+    const AtomicString& value = attr->value();
     if (attr->name() == SVGNames::filterUnitsAttr) {
         SVGUnitTypes::SVGUnitType propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value);
         if (propertyValue > 0)
             setFilterUnitsBaseValue(propertyValue);
-    } else if (attr->name() == SVGNames::primitiveUnitsAttr) {
+        return;
+    }
+
+    if (attr->name() == SVGNames::primitiveUnitsAttr) {
         SVGUnitTypes::SVGUnitType propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value);
         if (propertyValue > 0)
             setPrimitiveUnitsBaseValue(propertyValue);
-    } else if (attr->name() == SVGNames::xAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::xAttr) {
         setXBaseValue(SVGLength(LengthModeWidth, value));
-    else if (attr->name() == SVGNames::yAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::yAttr) {
         setYBaseValue(SVGLength(LengthModeHeight, value));
-    else if (attr->name() == SVGNames::widthAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::widthAttr) {
         setWidthBaseValue(SVGLength(LengthModeWidth, value));
-    else if (attr->name() == SVGNames::heightAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::heightAttr) {
         setHeightBaseValue(SVGLength(LengthModeHeight, value));
-    else if (attr->name() == SVGNames::filterResAttr) {
+        return;
+    }
+
+    if (attr->name() == SVGNames::filterResAttr) {
         float x, y;
         if (parseNumberOptionalNumber(value, x, y)) {
             setFilterResXBaseValue(x);
             setFilterResYBaseValue(y);
         }
-    } else {
-        if (SVGURIReference::parseMappedAttribute(attr))
-            return;
-        if (SVGLangSpace::parseMappedAttribute(attr))
-            return;
-        if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
-            return;
-
-        SVGStyledElement::parseMappedAttribute(attr);
+        return;
     }
+
+    if (SVGURIReference::parseMappedAttribute(attr))
+        return;
+    if (SVGLangSpace::parseMappedAttribute(attr))
+        return;
+    if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
+        return;
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGFilterElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    SVGStyledElement::svgAttributeChanged(attrName);
+    if (!isSupportedAttribute(attrName)) {
+        SVGStyledElement::svgAttributeChanged(attrName);
+        return;
+    }
 
-    bool invalidateClients = false;
+    SVGElementInstance::InvalidationGuard invalidationGuard(this);
+    
     if (attrName == SVGNames::xAttr
         || attrName == SVGNames::yAttr
         || attrName == SVGNames::widthAttr
-        || attrName == SVGNames::heightAttr) {
-        invalidateClients = true;
+        || attrName == SVGNames::heightAttr)
         updateRelativeLengthsInformation();
-    }
-
-    RenderObject* object = renderer();
-    if (!object)
-        return;
 
-    if (invalidateClients
-        || attrName == SVGNames::filterUnitsAttr
-        || attrName == SVGNames::primitiveUnitsAttr
-        || attrName == SVGNames::filterResAttr
-        || SVGStyledElement::isKnownAttribute(attrName)
-        || SVGURIReference::isKnownAttribute(attrName)
-        || SVGLangSpace::isKnownAttribute(attrName)
-        || SVGExternalResourcesRequired::isKnownAttribute(attrName))
+    if (RenderObject* object = renderer())
         object->setNeedsLayout(true);
 }
 
 void SVGFilterElement::synchronizeProperty(const QualifiedName& attrName)
 {
-    SVGStyledElement::synchronizeProperty(attrName);
-
     if (attrName == anyQName()) {
         synchronizeX();
         synchronizeY();
@@ -170,28 +202,62 @@ void SVGFilterElement::synchronizeProperty(const QualifiedName& attrName)
         synchronizeFilterResY();
         synchronizeExternalResourcesRequired();
         synchronizeHref();
+        SVGStyledElement::synchronizeProperty(attrName);
         return;
     }
 
-    if (attrName == SVGNames::xAttr)
+    if (!isSupportedAttribute(attrName)) {
+        SVGStyledElement::synchronizeProperty(attrName);
+        return;
+    }
+
+    if (attrName == SVGNames::xAttr) {
         synchronizeX();
-    else if (attrName == SVGNames::yAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::yAttr) {
         synchronizeY();
-    else if (attrName == SVGNames::widthAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::widthAttr) {
         synchronizeWidth();
-    else if (attrName == SVGNames::heightAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::heightAttr) {
         synchronizeHeight();
-    else if (attrName == SVGNames::filterUnitsAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::filterUnitsAttr) {
         synchronizeFilterUnits();
-    else if (attrName == SVGNames::primitiveUnitsAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::primitiveUnitsAttr) {
         synchronizePrimitiveUnits();
-    else if (attrName == SVGNames::filterResAttr) {
+        return;
+    }
+
+    if (attrName == SVGNames::filterResAttr) {
         synchronizeFilterResX();
         synchronizeFilterResY();
-    } else if (SVGExternalResourcesRequired::isKnownAttribute(attrName))
+        return;
+    }
+
+    if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) {
         synchronizeExternalResourcesRequired();
-    else if (SVGURIReference::isKnownAttribute(attrName))
+        return;
+    }
+
+    if (SVGURIReference::isKnownAttribute(attrName)) {
         synchronizeHref();
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 AttributeToPropertyTypeMap& SVGFilterElement::attributeToPropertyTypeMap()
index 891d432..6b3ef44 100644 (file)
@@ -51,6 +51,7 @@ private:
 
     virtual bool needsPendingResourceHandling() const { return false; }
 
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*);
     virtual void svgAttributeChanged(const QualifiedName&);
     virtual void synchronizeProperty(const QualifiedName&);
index fe5d09c..a42650a 100644 (file)
@@ -27,6 +27,7 @@
 #include "Attribute.h"
 #include "FilterEffect.h"
 #include "RenderSVGResourceFilterPrimitive.h"
+#include "SVGElementInstance.h"
 #include "SVGFilterBuilder.h"
 #include "SVGLength.h"
 #include "SVGNames.h"
@@ -53,21 +54,53 @@ SVGFilterPrimitiveStandardAttributes::SVGFilterPrimitiveStandardAttributes(const
     // Spec: If the width/height attribute is not specified, the effect is as if a value of "100%" were specified.
 }
 
+bool SVGFilterPrimitiveStandardAttributes::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty()) {
+        supportedAttributes.add(SVGNames::xAttr);
+        supportedAttributes.add(SVGNames::yAttr);
+        supportedAttributes.add(SVGNames::widthAttr);
+        supportedAttributes.add(SVGNames::heightAttr);
+        supportedAttributes.add(SVGNames::resultAttr);
+    }
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(Attribute* attr)
 {
+    if (!isSupportedAttribute(attr->name())) {
+        SVGStyledElement::parseMappedAttribute(attr);
+        return;
+    }
+
     const AtomicString& value = attr->value();
-    if (attr->name() == SVGNames::xAttr)
+    if (attr->name() == SVGNames::xAttr) {
         setXBaseValue(SVGLength(LengthModeWidth, value));
-    else if (attr->name() == SVGNames::yAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::yAttr) {
         setYBaseValue(SVGLength(LengthModeHeight, value));
-    else if (attr->name() == SVGNames::widthAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::widthAttr) {
         setWidthBaseValue(SVGLength(LengthModeWidth, value));
-    else if (attr->name() == SVGNames::heightAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::heightAttr) {
         setHeightBaseValue(SVGLength(LengthModeHeight, value));
-    else if (attr->name() == SVGNames::resultAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::resultAttr) {
         setResultBaseValue(value);
-    else
-        return SVGStyledElement::parseMappedAttribute(attr);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 bool SVGFilterPrimitiveStandardAttributes::setFilterEffectAttribute(FilterEffect*, const QualifiedName&)
@@ -79,39 +112,58 @@ bool SVGFilterPrimitiveStandardAttributes::setFilterEffectAttribute(FilterEffect
 
 void SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(const QualifiedName& attrName)
 {
-    SVGStyledElement::svgAttributeChanged(attrName);
+    if (!isSupportedAttribute(attrName)) {
+        SVGStyledElement::svgAttributeChanged(attrName);
+        return;
+    }
 
-    if (attrName == SVGNames::xAttr
-        || attrName == SVGNames::yAttr
-        || attrName == SVGNames::widthAttr
-        || attrName == SVGNames::heightAttr
-        || attrName == SVGNames::resultAttr)
-        invalidate();
+    SVGElementInstance::InvalidationGuard invalidationGuard(this);    
+    invalidate();
 }
 
 void SVGFilterPrimitiveStandardAttributes::synchronizeProperty(const QualifiedName& attrName)
-{
-    SVGStyledElement::synchronizeProperty(attrName);
-
+{    
     if (attrName == anyQName()) {
         synchronizeX();
         synchronizeY();
         synchronizeWidth();
         synchronizeHeight();
         synchronizeResult();
+        SVGStyledElement::synchronizeProperty(attrName);
+        return;
+    }
+
+    if (!isSupportedAttribute(attrName)) {
+        SVGStyledElement::synchronizeProperty(attrName);
         return;
     }
 
-    if (attrName == SVGNames::xAttr)
+    if (attrName == SVGNames::xAttr) {
         synchronizeX();
-    else if (attrName == SVGNames::yAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::yAttr) {
         synchronizeY();
-    else if (attrName == SVGNames::widthAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::widthAttr) {
         synchronizeWidth();
-    else if (attrName == SVGNames::heightAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::heightAttr) {
         synchronizeHeight();
-    else if (attrName == SVGNames::resultAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::resultAttr) {
         synchronizeResult();
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGFilterPrimitiveStandardAttributes::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
index 795bc11..ad6f538 100644 (file)
@@ -48,6 +48,7 @@ public:
 protected:
     SVGFilterPrimitiveStandardAttributes(const QualifiedName&, Document*);
 
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*);
     virtual void svgAttributeChanged(const QualifiedName&);
     virtual void synchronizeProperty(const QualifiedName&);
index fadb982..4303c26 100644 (file)
@@ -92,11 +92,10 @@ bool SVGFitToViewBox::parseMappedAttribute(Document* document, Attribute* attr)
 {
     if (attr->name() == SVGNames::viewBoxAttr) {
         FloatRect viewBox;
-        if (!attr->value().isNull()) {
-            if (!parseViewBox(document, attr->value(), viewBox))
-                return true;
-        }
+        if (!attr->value().isNull())
+            parseViewBox(document, attr->value(), viewBox);
         setViewBoxBaseValue(viewBox);
+        return true;
     } else if (attr->name() == SVGNames::preserveAspectRatioAttr) {
         SVGPreserveAspectRatio::parsePreserveAspectRatio(this, attr->value());
         return true;
@@ -105,11 +104,31 @@ bool SVGFitToViewBox::parseMappedAttribute(Document* document, Attribute* attr)
     return false;
 }
 
+void SVGFitToViewBox::synchronizeProperties(const QualifiedName& attrName)
+{
+    if (attrName == anyQName()) {
+        synchronizeViewBox();
+        synchronizePreserveAspectRatio();
+        return;
+    }
+
+    if (attrName == SVGNames::viewBoxAttr)
+        synchronizeViewBox();
+    else if (attrName == SVGNames::preserveAspectRatioAttr)
+        synchronizePreserveAspectRatio();
+}
+
 bool SVGFitToViewBox::isKnownAttribute(const QualifiedName& attrName)
 {
     return attrName == SVGNames::viewBoxAttr || attrName == SVGNames::preserveAspectRatioAttr;
 }
 
+void SVGFitToViewBox::addSupportedAttributes(HashSet<QualifiedName>& supportedAttributes)
+{
+    supportedAttributes.add(SVGNames::viewBoxAttr);
+    supportedAttributes.add(SVGNames::preserveAspectRatioAttr);
+}
+
 }
 
 #endif // ENABLE(SVG)
index 3d62271..1d3de3f 100644 (file)
@@ -22,7 +22,8 @@
 #define SVGFitToViewBox_h
 
 #if ENABLE(SVG)
-#include <wtf/text/WTFString.h>
+#include "QualifiedName.h"
+#include <wtf/HashSet.h>
 
 namespace WebCore {
 
@@ -30,7 +31,6 @@ class AffineTransform;
 class Attribute;
 class Document;
 class FloatRect;
-class QualifiedName;
 class SVGPreserveAspectRatio;
 
 class SVGFitToViewBox {
@@ -42,10 +42,15 @@ public:
 
     bool parseMappedAttribute(Document*, Attribute*);
     bool isKnownAttribute(const QualifiedName&);
+    void addSupportedAttributes(HashSet<QualifiedName>&);
+    void synchronizeProperties(const QualifiedName&);
 
     virtual void setViewBoxBaseValue(const FloatRect&) = 0;
     virtual void setPreserveAspectRatioBaseValue(const SVGPreserveAspectRatio&) = 0;
 
+    virtual void synchronizeViewBox() = 0;
+    virtual void synchronizePreserveAspectRatio() = 0;
+
 private:
     bool parseViewBox(Document*, const String&, FloatRect&);
 };
index 6765687..10370e3 100644 (file)
@@ -27,6 +27,7 @@
 #include "CSSPropertyNames.h"
 #include "RenderSVGForeignObject.h"
 #include "RenderSVGResource.h"
+#include "SVGElementInstance.h"
 #include "SVGLength.h"
 #include "SVGNames.h"
 #include <wtf/Assertions.h>
@@ -56,32 +57,68 @@ PassRefPtr<SVGForeignObjectElement> SVGForeignObjectElement::create(const Qualif
     return adoptRef(new SVGForeignObjectElement(tagName, document));
 }
 
+bool SVGForeignObjectElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty()) {
+        SVGTests::addSupportedAttributes(supportedAttributes);
+        SVGLangSpace::addSupportedAttributes(supportedAttributes);
+        SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
+        supportedAttributes.add(SVGNames::xAttr);
+        supportedAttributes.add(SVGNames::yAttr);
+        supportedAttributes.add(SVGNames::widthAttr);
+        supportedAttributes.add(SVGNames::heightAttr);
+    }
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGForeignObjectElement::parseMappedAttribute(Attribute* attr)
 {
+    if (!isSupportedAttribute(attr->name())) {
+        SVGStyledTransformableElement::parseMappedAttribute(attr);
+        return;
+    }
+
     const AtomicString& value = attr->value();
-    if (attr->name() == SVGNames::xAttr)
+    if (attr->name() == SVGNames::xAttr) {
         setXBaseValue(SVGLength(LengthModeWidth, value));
-    else if (attr->name() == SVGNames::yAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::yAttr) {
         setYBaseValue(SVGLength(LengthModeHeight, value));
-    else if (attr->name() == SVGNames::widthAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::widthAttr) {
         setWidthBaseValue(SVGLength(LengthModeWidth, value));
-    else if (attr->name() == SVGNames::heightAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::heightAttr) {
         setHeightBaseValue(SVGLength(LengthModeHeight, value));
-    else {
-        if (SVGTests::parseMappedAttribute(attr))
-            return;
-        if (SVGLangSpace::parseMappedAttribute(attr))
-            return;
-        if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
-            return;
-        SVGStyledTransformableElement::parseMappedAttribute(attr);
+        return;
     }
+
+    if (SVGTests::parseMappedAttribute(attr))
+        return;
+    if (SVGLangSpace::parseMappedAttribute(attr))
+        return;
+    if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
+        return;
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGForeignObjectElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    SVGStyledTransformableElement::svgAttributeChanged(attrName);
+    if (!isSupportedAttribute(attrName)) {
+        SVGStyledTransformableElement::svgAttributeChanged(attrName);
+        return;
+    }
 
+    SVGElementInstance::InvalidationGuard invalidationGuard(this);
+    
     bool isLengthAttribute = attrName == SVGNames::xAttr
                           || attrName == SVGNames::yAttr
                           || attrName == SVGNames::widthAttr
@@ -93,20 +130,12 @@ void SVGForeignObjectElement::svgAttributeChanged(const QualifiedName& attrName)
     if (SVGTests::handleAttributeChange(this, attrName))
         return;
 
-    RenderObject* renderer = this->renderer();
-    if (!renderer)
-        return;
-
-    if (isLengthAttribute
-        || SVGLangSpace::isKnownAttribute(attrName)
-        || SVGExternalResourcesRequired::isKnownAttribute(attrName))
+    if (RenderObject* renderer = this->renderer())
         RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
 }
 
 void SVGForeignObjectElement::synchronizeProperty(const QualifiedName& attrName)
 {
-    SVGStyledTransformableElement::synchronizeProperty(attrName);
-
     if (attrName == anyQName()) {
         synchronizeX();
         synchronizeY();
@@ -115,21 +144,46 @@ void SVGForeignObjectElement::synchronizeProperty(const QualifiedName& attrName)
         synchronizeExternalResourcesRequired();
         synchronizeHref();
         SVGTests::synchronizeProperties(this, attrName);
+        SVGStyledTransformableElement::synchronizeProperty(attrName);
+        return;
+    }
+
+    if (!isSupportedAttribute(attrName)) {
+        SVGStyledTransformableElement::synchronizeProperty(attrName);
         return;
     }
 
-    if (attrName == SVGNames::xAttr)
+    if (attrName == SVGNames::xAttr) {
         synchronizeX();
-    else if (attrName == SVGNames::yAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::yAttr) {
         synchronizeY();
-    else if (attrName == SVGNames::widthAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::widthAttr) {
         synchronizeWidth();
-    else if (attrName == SVGNames::heightAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::heightAttr) {
         synchronizeHeight();
-    else if (SVGExternalResourcesRequired::isKnownAttribute(attrName))
+        return;
+    }
+
+    if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) {
         synchronizeExternalResourcesRequired();
-    else if (SVGTests::isKnownAttribute(attrName))
+        return;
+    }
+
+    if (SVGTests::isKnownAttribute(attrName)) {
         SVGTests::synchronizeProperties(this, attrName);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 AttributeToPropertyTypeMap& SVGForeignObjectElement::attributeToPropertyTypeMap()
index 82f21b4..6695cf4 100644 (file)
@@ -42,6 +42,7 @@ private:
     SVGForeignObjectElement(const QualifiedName&, Document*);
 
     virtual bool isValid() const { return SVGTests::isValid(); }
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*);
     virtual void svgAttributeChanged(const QualifiedName&);
     virtual void synchronizeProperty(const QualifiedName&);
index 9955800..c91572c 100644 (file)
@@ -26,6 +26,7 @@
 #include "RenderSVGHiddenContainer.h"
 #include "RenderSVGResource.h"
 #include "RenderSVGTransformableContainer.h"
+#include "SVGElementInstance.h"
 #include "SVGNames.h"
 
 namespace WebCore {
@@ -44,8 +45,24 @@ PassRefPtr<SVGGElement> SVGGElement::create(const QualifiedName& tagName, Docume
     return adoptRef(new SVGGElement(tagName, document));
 }
 
+bool SVGGElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty()) {
+        SVGTests::addSupportedAttributes(supportedAttributes);
+        SVGLangSpace::addSupportedAttributes(supportedAttributes);
+        SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
+    }
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGGElement::parseMappedAttribute(Attribute* attr)
 {
+    if (!isSupportedAttribute(attr->name())) {
+        SVGStyledTransformableElement::parseMappedAttribute(attr);
+        return;
+    }
+
     if (SVGTests::parseMappedAttribute(attr))
         return;
     if (SVGLangSpace::parseMappedAttribute(attr))
@@ -53,39 +70,50 @@ void SVGGElement::parseMappedAttribute(Attribute* attr)
     if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
         return;
 
-    SVGStyledTransformableElement::parseMappedAttribute(attr);
+    ASSERT_NOT_REACHED();
 }
 
 void SVGGElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    SVGStyledTransformableElement::svgAttributeChanged(attrName);
-
-    if (SVGTests::handleAttributeChange(this, attrName))
+    if (!isSupportedAttribute(attrName)) {
+        SVGStyledTransformableElement::svgAttributeChanged(attrName);
         return;
+    }
 
-    RenderObject* renderer = this->renderer();
-    if (!renderer)
+    SVGElementInstance::InvalidationGuard invalidationGuard(this);
+    
+    if (SVGTests::handleAttributeChange(this, attrName))
         return;
 
-    if (SVGLangSpace::isKnownAttribute(attrName)
-        || SVGExternalResourcesRequired::isKnownAttribute(attrName))
+    if (RenderObject* renderer = this->renderer())
         RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
 }
 
 void SVGGElement::synchronizeProperty(const QualifiedName& attrName)
 {
-    SVGStyledTransformableElement::synchronizeProperty(attrName);
-
     if (attrName == anyQName()) {
         synchronizeExternalResourcesRequired();
         SVGTests::synchronizeProperties(this, attrName);
+        SVGStyledTransformableElement::synchronizeProperty(attrName);
         return;
     }
 
-    if (SVGExternalResourcesRequired::isKnownAttribute(attrName))
+    if (!isSupportedAttribute(attrName)) {
+        SVGStyledTransformableElement::synchronizeProperty(attrName);
+        return;
+    }
+
+    if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) {
         synchronizeExternalResourcesRequired();
-    else if (SVGTests::isKnownAttribute(attrName))
+        return;
+    }
+
+    if (SVGTests::isKnownAttribute(attrName)) {
         SVGTests::synchronizeProperties(this, attrName);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 AttributeToPropertyTypeMap& SVGGElement::attributeToPropertyTypeMap()
index c306f4a..7b3e080 100644 (file)
@@ -47,6 +47,7 @@ protected:
 private:
     virtual bool isValid() const { return SVGTests::isValid(); }
 
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*);
     virtual void svgAttributeChanged(const QualifiedName&);
     virtual void synchronizeProperty(const QualifiedName&);
index d1b8079..e766723 100644 (file)
@@ -30,6 +30,7 @@
 #include "RenderSVGPath.h"
 #include "RenderSVGResourceLinearGradient.h"
 #include "RenderSVGResourceRadialGradient.h"
+#include "SVGElementInstance.h"
 #include "SVGNames.h"
 #include "SVGStopElement.h"
 #include "SVGTransformList.h"
@@ -51,73 +52,114 @@ SVGGradientElement::SVGGradientElement(const QualifiedName& tagName, Document* d
 {
 }
 
+bool SVGGradientElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty()) {
+        SVGURIReference::addSupportedAttributes(supportedAttributes);
+        SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
+        supportedAttributes.add(SVGNames::gradientUnitsAttr);
+        supportedAttributes.add(SVGNames::gradientTransformAttr);
+        supportedAttributes.add(SVGNames::spreadMethodAttr);
+    }
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGGradientElement::parseMappedAttribute(Attribute* attr)
 {
+    if (!isSupportedAttribute(attr->name())) {
+        SVGStyledElement::parseMappedAttribute(attr);
+        return;
+    }
+
     if (attr->name() == SVGNames::gradientUnitsAttr) {
         SVGUnitTypes::SVGUnitType propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(attr->value());
         if (propertyValue > 0)
             setGradientUnitsBaseValue(propertyValue);
-    } else if (attr->name() == SVGNames::gradientTransformAttr) {
+        return;
+    }
+
+    if (attr->name() == SVGNames::gradientTransformAttr) {
         SVGTransformList newList;
         if (!SVGTransformable::parseTransformAttribute(newList, attr->value()))
             newList.clear();
 
         detachAnimatedGradientTransformListWrappers(newList.size());
         setGradientTransformBaseValue(newList);
-    } else if (attr->name() == SVGNames::spreadMethodAttr) {
+        return;
+    }
+
+    if (attr->name() == SVGNames::spreadMethodAttr) {
         SVGSpreadMethodType propertyValue = SVGPropertyTraits<SVGSpreadMethodType>::fromString(attr->value());
         if (propertyValue > 0)
             setSpreadMethodBaseValue(propertyValue);
-    } else {
-        if (SVGURIReference::parseMappedAttribute(attr))
-            return;
-        if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
-            return;
-        
-        SVGStyledElement::parseMappedAttribute(attr);
+        return;
     }
+
+    if (SVGURIReference::parseMappedAttribute(attr))
+        return;
+    if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
+        return;
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGGradientElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    SVGStyledElement::svgAttributeChanged(attrName);
-
-    RenderObject* object = renderer();
-    if (!object)
+    if (!isSupportedAttribute(attrName)) {
+        SVGStyledElement::svgAttributeChanged(attrName);
         return;
+    }
 
-    if (attrName == SVGNames::gradientUnitsAttr
-        || attrName == SVGNames::gradientTransformAttr
-        || attrName == SVGNames::spreadMethodAttr
-        || SVGURIReference::isKnownAttribute(attrName)
-        || SVGExternalResourcesRequired::isKnownAttribute(attrName)
-        || SVGStyledElement::isKnownAttribute(attrName))
+    SVGElementInstance::InvalidationGuard invalidationGuard(this);
+    
+    if (RenderObject* object = renderer())
         object->setNeedsLayout(true);
 }
 
 void SVGGradientElement::synchronizeProperty(const QualifiedName& attrName)
 {
-    SVGStyledElement::synchronizeProperty(attrName);
-
     if (attrName == anyQName()) {
         synchronizeGradientUnits();
         synchronizeGradientTransform();
         synchronizeSpreadMethod();
         synchronizeExternalResourcesRequired();
         synchronizeHref();
+        SVGStyledElement::synchronizeProperty(attrName);
+        return;
+    }
+
+    if (!isSupportedAttribute(attrName)) {
+        SVGStyledElement::synchronizeProperty(attrName);
         return;
     }
 
-    if (attrName == SVGNames::gradientUnitsAttr)
+    if (attrName == SVGNames::gradientUnitsAttr) {
         synchronizeGradientUnits();
-    else if (attrName == SVGNames::gradientTransformAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::gradientTransformAttr) {
         synchronizeGradientTransform();
-    else if (attrName == SVGNames::spreadMethodAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::spreadMethodAttr) {
         synchronizeSpreadMethod();
-    else if (SVGExternalResourcesRequired::isKnownAttribute(attrName))
+        return;
+    }
+
+    if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) {
         synchronizeExternalResourcesRequired();
-    else if (SVGURIReference::isKnownAttribute(attrName))
+        return;
+    }
+
+    if (SVGURIReference::isKnownAttribute(attrName)) {
         synchronizeHref();
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGGradientElement::fillPassedAttributeToPropertyTypeMap(AttributeToPropertyTypeMap& attributeToPropertyTypeMap)
index fdaec60..7ffc492 100644 (file)
@@ -49,6 +49,7 @@ public:
 protected:
     SVGGradientElement(const QualifiedName&, Document*);
 
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*);
     virtual void svgAttributeChanged(const QualifiedName&);
     virtual void synchronizeProperty(const QualifiedName&);
index 3607984..c208157 100644 (file)
@@ -29,6 +29,7 @@
 #include "RenderImageResource.h"
 #include "RenderSVGImage.h"
 #include "RenderSVGResource.h"
+#include "SVGElementInstance.h"
 #include "SVGNames.h"
 #include "SVGSVGElement.h"
 #include "XLinkNames.h"
@@ -60,44 +61,82 @@ PassRefPtr<SVGImageElement> SVGImageElement::create(const QualifiedName& tagName
     return adoptRef(new SVGImageElement(tagName, document));
 }
 
+bool SVGImageElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty()) {
+        SVGTests::addSupportedAttributes(supportedAttributes);
+        SVGLangSpace::addSupportedAttributes(supportedAttributes);
+        SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
+        SVGURIReference::addSupportedAttributes(supportedAttributes);
+        supportedAttributes.add(SVGNames::xAttr);
+        supportedAttributes.add(SVGNames::yAttr);
+        supportedAttributes.add(SVGNames::widthAttr);
+        supportedAttributes.add(SVGNames::heightAttr);
+        supportedAttributes.add(SVGNames::preserveAspectRatioAttr);
+    }
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGImageElement::parseMappedAttribute(Attribute* attr)
 {
-    if (attr->name() == SVGNames::xAttr)
+    if (!isSupportedAttribute(attr->name())) {
+        SVGStyledTransformableElement::parseMappedAttribute(attr);
+        return;
+    }
+
+    if (attr->name() == SVGNames::xAttr) {
         setXBaseValue(SVGLength(LengthModeWidth, attr->value()));
-    else if (attr->name() == SVGNames::yAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::yAttr) {
         setYBaseValue(SVGLength(LengthModeHeight, attr->value()));
-    else if (attr->name() == SVGNames::preserveAspectRatioAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::preserveAspectRatioAttr) {
         SVGPreserveAspectRatio::parsePreserveAspectRatio(this, attr->value());
-    else if (attr->name() == SVGNames::widthAttr) {
+        return;
+    }
+
+    if (attr->name() == SVGNames::widthAttr) {
         setWidthBaseValue(SVGLength(LengthModeWidth, attr->value()));
         addCSSProperty(attr, CSSPropertyWidth, attr->value());
         if (widthBaseValue().value(this) < 0.0)
             document()->accessSVGExtensions()->reportError("A negative value for image attribute <width> is not allowed");
-    } else if (attr->name() == SVGNames::heightAttr) {
+        return;
+    }
+
+    if (attr->name() == SVGNames::heightAttr) {
         setHeightBaseValue(SVGLength(LengthModeHeight, attr->value()));
         addCSSProperty(attr, CSSPropertyHeight, attr->value());
         if (heightBaseValue().value(this) < 0.0)
             document()->accessSVGExtensions()->reportError("A negative value for image attribute <height> is not allowed");
-    } else {
-        if (SVGTests::parseMappedAttribute(attr))
-            return;
-        if (SVGLangSpace::parseMappedAttribute(attr))
-            return;
-        if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
-            return;
-        if (SVGURIReference::parseMappedAttribute(attr))
-            return;
-        SVGStyledTransformableElement::parseMappedAttribute(attr);
+        return;
     }
+
+    if (SVGTests::parseMappedAttribute(attr))
+        return;
+    if (SVGLangSpace::parseMappedAttribute(attr))
+        return;
+    if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
+        return;
+    if (SVGURIReference::parseMappedAttribute(attr))
+        return;
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGImageElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    SVGStyledTransformableElement::svgAttributeChanged(attrName);
-
-    if (SVGURIReference::isKnownAttribute(attrName))
-        m_imageLoader.updateFromElementIgnoringPreviousError();
+    if (!isSupportedAttribute(attrName)) {
+        SVGStyledTransformableElement::svgAttributeChanged(attrName);
+        return;
+    }
 
+    SVGElementInstance::InvalidationGuard invalidationGuard(this);
+    
     bool isLengthAttribute = attrName == SVGNames::xAttr
                           || attrName == SVGNames::yAttr
                           || attrName == SVGNames::widthAttr
@@ -109,6 +148,11 @@ void SVGImageElement::svgAttributeChanged(const QualifiedName& attrName)
     if (SVGTests::handleAttributeChange(this, attrName))
         return;
 
+    if (SVGURIReference::isKnownAttribute(attrName)) {
+        m_imageLoader.updateFromElementIgnoringPreviousError();
+        return;
+    }
+
     RenderObject* renderer = this->renderer();
     if (!renderer)
         return;
@@ -121,14 +165,16 @@ void SVGImageElement::svgAttributeChanged(const QualifiedName& attrName)
 
     if (attrName == SVGNames::preserveAspectRatioAttr
         || SVGLangSpace::isKnownAttribute(attrName)
-        || SVGExternalResourcesRequired::isKnownAttribute(attrName))
+        || SVGExternalResourcesRequired::isKnownAttribute(attrName)) {
         RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGImageElement::synchronizeProperty(const QualifiedName& attrName)
 {
-    SVGStyledTransformableElement::synchronizeProperty(attrName);
-
     if (attrName == anyQName()) {
         synchronizeX();
         synchronizeY();
@@ -138,25 +184,56 @@ void SVGImageElement::synchronizeProperty(const QualifiedName& attrName)
         synchronizeExternalResourcesRequired();
         synchronizeHref();
         SVGTests::synchronizeProperties(this, attrName);
+        SVGStyledTransformableElement::synchronizeProperty(attrName);
+        return;
+    }
+
+    if (!isSupportedAttribute(attrName)) {
+        SVGStyledTransformableElement::synchronizeProperty(attrName);
         return;
     }
 
-    if (attrName == SVGNames::xAttr)
+    if (attrName == SVGNames::xAttr) {
         synchronizeX();
-    else if (attrName == SVGNames::yAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::yAttr) {
         synchronizeY();
-    else if (attrName == SVGNames::widthAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::widthAttr) {
         synchronizeWidth();
-    else if (attrName == SVGNames::heightAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::heightAttr) {
         synchronizeHeight();
-    else if (attrName == SVGNames::preserveAspectRatioAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::preserveAspectRatioAttr) {
         synchronizePreserveAspectRatio();
-    else if (SVGExternalResourcesRequired::isKnownAttribute(attrName))
+        return;
+    }
+
+    if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) {
         synchronizeExternalResourcesRequired();
-    else if (SVGURIReference::isKnownAttribute(attrName))
+        return;
+    }
+
+    if (SVGURIReference::isKnownAttribute(attrName)) {
         synchronizeHref();
-    else if (SVGTests::isKnownAttribute(attrName))
+        return;
+    }
+
+    if (SVGTests::isKnownAttribute(attrName)) {
         SVGTests::synchronizeProperties(this, attrName);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 AttributeToPropertyTypeMap& SVGImageElement::attributeToPropertyTypeMap()
index ec67823..42f4b4a 100644 (file)
@@ -47,6 +47,7 @@ private:
     
     virtual bool isValid() const { return SVGTests::isValid(); }
 
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*);
     virtual void svgAttributeChanged(const QualifiedName&);
     virtual void synchronizeProperty(const QualifiedName&);
index 73a52e9..01695f0 100644 (file)
@@ -68,6 +68,21 @@ bool SVGLangSpace::isKnownAttribute(const QualifiedName& attrName)
 {
     return attrName.matches(XMLNames::langAttr) || attrName.matches(XMLNames::spaceAttr);
 }
+    
+void SVGLangSpace::addSupportedAttributes(HashSet<QualifiedName>& supportedAttributes)
+{
+    DEFINE_STATIC_LOCAL(AtomicString, xmlPrefix, ("xml"));
+
+    QualifiedName langWithPrefix = XMLNames::langAttr;
+    langWithPrefix.setPrefix(xmlPrefix);
+    supportedAttributes.add(langWithPrefix);
+    supportedAttributes.add(XMLNames::langAttr);
+
+    QualifiedName spaceWithPrefix = XMLNames::spaceAttr;
+    spaceWithPrefix.setPrefix(xmlPrefix);
+    supportedAttributes.add(spaceWithPrefix);
+    supportedAttributes.add(XMLNames::spaceAttr);
+}
 
 }
 
index 61c6edf..a5c9c0e 100644 (file)
 #define SVGLangSpace_h
 
 #if ENABLE(SVG)
-#include <wtf/text/AtomicString.h>
+#include "QualifiedName.h"
+#include <wtf/HashSet.h>
 
 namespace WebCore {
 
 class Attribute;
-class QualifiedName;
 
 class SVGLangSpace {
 public:
@@ -39,6 +39,7 @@ public:
 
     bool parseMappedAttribute(Attribute*);
     bool isKnownAttribute(const QualifiedName&);
+    void addSupportedAttributes(HashSet<QualifiedName>&);
 
 private:
     AtomicString m_lang;
index 47deb6c..8428417 100644 (file)
@@ -27,6 +27,7 @@
 #include "FloatPoint.h"
 #include "RenderSVGPath.h"
 #include "RenderSVGResource.h"
+#include "SVGElementInstance.h"
 #include "SVGLength.h"
 #include "SVGNames.h"
 
@@ -54,31 +55,67 @@ PassRefPtr<SVGLineElement> SVGLineElement::create(const QualifiedName& tagName,
     return adoptRef(new SVGLineElement(tagName, document));
 }
 
+bool SVGLineElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty()) {
+        SVGTests::addSupportedAttributes(supportedAttributes);
+        SVGLangSpace::addSupportedAttributes(supportedAttributes);
+        SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
+        supportedAttributes.add(SVGNames::x1Attr);
+        supportedAttributes.add(SVGNames::x2Attr);
+        supportedAttributes.add(SVGNames::y1Attr);
+        supportedAttributes.add(SVGNames::y2Attr);
+    }
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGLineElement::parseMappedAttribute(Attribute* attr)
 {
-    if (attr->name() == SVGNames::x1Attr)
+    if (!isSupportedAttribute(attr->name())) {
+        SVGStyledTransformableElement::parseMappedAttribute(attr);
+        return;
+    }
+
+    if (attr->name() == SVGNames::x1Attr) {
         setX1BaseValue(SVGLength(LengthModeWidth, attr->value()));
-    else if (attr->name() == SVGNames::y1Attr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::y1Attr) {
         setY1BaseValue(SVGLength(LengthModeHeight, attr->value()));
-    else if (attr->name() == SVGNames::x2Attr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::x2Attr) {
         setX2BaseValue(SVGLength(LengthModeWidth, attr->value()));
-    else if (attr->name() == SVGNames::y2Attr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::y2Attr) {
         setY2BaseValue(SVGLength(LengthModeHeight, attr->value()));
-    else {
-        if (SVGTests::parseMappedAttribute(attr))
-            return;
-        if (SVGLangSpace::parseMappedAttribute(attr))
-            return;
-        if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
-            return;
-        SVGStyledTransformableElement::parseMappedAttribute(attr);
+        return;
     }
+
+    if (SVGTests::parseMappedAttribute(attr))
+        return;
+    if (SVGLangSpace::parseMappedAttribute(attr))
+        return;
+    if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
+        return;
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGLineElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    SVGStyledTransformableElement::svgAttributeChanged(attrName);
+    if (!isSupportedAttribute(attrName)) {
+        SVGStyledTransformableElement::svgAttributeChanged(attrName);
+        return;
+    }
 
+    SVGElementInstance::InvalidationGuard invalidationGuard(this);
+    
     bool isLengthAttribute = attrName == SVGNames::x1Attr
                           || attrName == SVGNames::y1Attr
                           || attrName == SVGNames::x2Attr
@@ -100,15 +137,16 @@ void SVGLineElement::svgAttributeChanged(const QualifiedName& attrName)
         return;
     }
 
-    if (SVGLangSpace::isKnownAttribute(attrName)
-        || SVGExternalResourcesRequired::isKnownAttribute(attrName))
+    if (SVGLangSpace::isKnownAttribute(attrName) || SVGExternalResourcesRequired::isKnownAttribute(attrName)) {
         RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGLineElement::synchronizeProperty(const QualifiedName& attrName)
 {
-    SVGStyledTransformableElement::synchronizeProperty(attrName);
-
     if (attrName == anyQName()) {
         synchronizeX1();
         synchronizeY1();
@@ -116,21 +154,46 @@ void SVGLineElement::synchronizeProperty(const QualifiedName& attrName)
         synchronizeY2();
         synchronizeExternalResourcesRequired();
         SVGTests::synchronizeProperties(this, attrName);
+        SVGStyledTransformableElement::synchronizeProperty(attrName);
+        return;
+    }
+
+    if (!isSupportedAttribute(attrName)) {
+        SVGStyledTransformableElement::synchronizeProperty(attrName);
         return;
     }
 
-    if (attrName == SVGNames::x1Attr)
+    if (attrName == SVGNames::x1Attr) {
         synchronizeX1();
-    else if (attrName == SVGNames::y1Attr)
+        return;
+    }
+
+    if (attrName == SVGNames::y1Attr) {
         synchronizeY1();
-    else if (attrName == SVGNames::x2Attr)
+        return;
+    }
+
+    if (attrName == SVGNames::x2Attr) {
         synchronizeX2();
-    else if (attrName == SVGNames::y2Attr)
+        return;
+    }
+
+    if (attrName == SVGNames::y2Attr) {
         synchronizeY2();
-    else if (SVGExternalResourcesRequired::isKnownAttribute(attrName))
+        return;
+    }
+
+    if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) {
         synchronizeExternalResourcesRequired();
-    else if (SVGTests::isKnownAttribute(attrName))
+        return;
+    }
+
+    if (SVGTests::isKnownAttribute(attrName)) {
         SVGTests::synchronizeProperties(this, attrName);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 AttributeToPropertyTypeMap& SVGLineElement::attributeToPropertyTypeMap()
index 4ba4ec1..f766100 100644 (file)
@@ -43,6 +43,7 @@ private:
     
     virtual bool isValid() const { return SVGTests::isValid(); }
 
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*);
     virtual void svgAttributeChanged(const QualifiedName&);
     virtual void synchronizeProperty(const QualifiedName&);
index 9cbd47a..ae7bf39 100644 (file)
@@ -31,6 +31,7 @@
 #include "FloatPoint.h"
 #include "LinearGradientAttributes.h"
 #include "RenderSVGResourceLinearGradient.h"
+#include "SVGElementInstance.h"
 #include "SVGLength.h"
 #include "SVGNames.h"
 #include "SVGTransform.h"
@@ -61,58 +62,100 @@ PassRefPtr<SVGLinearGradientElement> SVGLinearGradientElement::create(const Qual
     return adoptRef(new SVGLinearGradientElement(tagName, document));
 }
 
+bool SVGLinearGradientElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty()) {
+        supportedAttributes.add(SVGNames::x1Attr);
+        supportedAttributes.add(SVGNames::x2Attr);
+        supportedAttributes.add(SVGNames::y1Attr);
+        supportedAttributes.add(SVGNames::y2Attr);
+    }
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGLinearGradientElement::parseMappedAttribute(Attribute* attr)
 {
-    if (attr->name() == SVGNames::x1Attr)
+    if (!isSupportedAttribute(attr->name())) {
+        SVGGradientElement::parseMappedAttribute(attr);
+        return;
+    }
+
+    if (attr->name() == SVGNames::x1Attr) {
         setX1BaseValue(SVGLength(LengthModeWidth, attr->value()));
-    else if (attr->name() == SVGNames::y1Attr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::y1Attr) {
         setY1BaseValue(SVGLength(LengthModeHeight, attr->value()));
-    else if (attr->name() == SVGNames::x2Attr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::x2Attr) {
         setX2BaseValue(SVGLength(LengthModeWidth, attr->value()));
-    else if (attr->name() == SVGNames::y2Attr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::y2Attr) {
         setY2BaseValue(SVGLength(LengthModeHeight, attr->value()));
-    else
-        SVGGradientElement::parseMappedAttribute(attr);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGLinearGradientElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    SVGGradientElement::svgAttributeChanged(attrName);
-
-    if (attrName == SVGNames::x1Attr
-        || attrName == SVGNames::y1Attr
-        || attrName == SVGNames::x2Attr
-        || attrName == SVGNames::y2Attr) {
-        updateRelativeLengthsInformation();
+    if (!isSupportedAttribute(attrName)) {
+        SVGGradientElement::svgAttributeChanged(attrName);
+        return;
+    }
 
-        RenderObject* object = renderer();
-        if (!object)
-            return;
+    SVGElementInstance::InvalidationGuard invalidationGuard(this);
+    
+    updateRelativeLengthsInformation();
 
+    if (RenderObject* object = renderer())
         object->setNeedsLayout(true);
-    }
 }
 
 void SVGLinearGradientElement::synchronizeProperty(const QualifiedName& attrName)
-{
-    SVGGradientElement::synchronizeProperty(attrName);
-
+{    
     if (attrName == anyQName()) {
         synchronizeX1();
         synchronizeY1();
         synchronizeX2();
         synchronizeY2();
+        SVGGradientElement::synchronizeProperty(attrName);
         return;
     }
 
-    if (attrName == SVGNames::x1Attr)
+    if (!isSupportedAttribute(attrName)) {
+        SVGGradientElement::synchronizeProperty(attrName);
+        return;
+    }   
+
+    if (attrName == SVGNames::x1Attr) {
         synchronizeX1();
-    else if (attrName == SVGNames::y1Attr)
+        return;
+    }
+
+    if (attrName == SVGNames::y1Attr) {
         synchronizeY1();
-    else if (attrName == SVGNames::x2Attr)
+        return;
+    }
+
+    if (attrName == SVGNames::x2Attr) {
         synchronizeX2();
-    else if (attrName == SVGNames::y2Attr)
+        return;
+    }
+
+    if (attrName == SVGNames::y2Attr) {
         synchronizeY2();
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 AttributeToPropertyTypeMap& SVGLinearGradientElement::attributeToPropertyTypeMap()
index 1c91556..c9ef634 100644 (file)
@@ -39,6 +39,7 @@ public:
 private:
     SVGLinearGradientElement(const QualifiedName&, Document*);
 
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*);
     virtual void svgAttributeChanged(const QualifiedName&);
     virtual void synchronizeProperty(const QualifiedName&);
index 76f5b0c..995759d 100644 (file)
@@ -43,27 +43,53 @@ PassRefPtr<SVGMPathElement> SVGMPathElement::create(const QualifiedName& tagName
     return adoptRef(new SVGMPathElement(tagName, document));
 }
 
+bool SVGMPathElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty()) {
+        SVGURIReference::addSupportedAttributes(supportedAttributes);
+        SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
+    }
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGMPathElement::parseMappedAttribute(Attribute* attr)
 {
+    if (!isSupportedAttribute(attr->name())) {
+        SVGElement::parseMappedAttribute(attr);
+        return;
+    }
+
     if (SVGURIReference::parseMappedAttribute(attr))
         return;
-    SVGElement::parseMappedAttribute(attr);
+    if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
+        return;
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGMPathElement::synchronizeProperty(const QualifiedName& attrName)
 {
-    SVGElement::synchronizeProperty(attrName);
-
     if (attrName == anyQName()) {
         synchronizeExternalResourcesRequired();
         synchronizeHref();
         return;
     }
 
-    if (SVGExternalResourcesRequired::isKnownAttribute(attrName))
+    if (!isSupportedAttribute(attrName))
+        return;
+
+    if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) {
         synchronizeExternalResourcesRequired();
-    else if (SVGURIReference::isKnownAttribute(attrName))
+        return;
+    }
+
+    if (SVGURIReference::isKnownAttribute(attrName)) {
         synchronizeHref();
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 AttributeToPropertyTypeMap& SVGMPathElement::attributeToPropertyTypeMap()
index ad59650..5fada0e 100644 (file)
@@ -40,7 +40,9 @@ public:
     
 private:
     SVGMPathElement(const QualifiedName&, Document*);
-    
+
+    // FIXME: svgAttributeChanged missing.
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*);
     virtual void synchronizeProperty(const QualifiedName&);
     virtual void fillAttributeToPropertyTypeMap();
index 43e7b1b..68c0a40 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "Attribute.h"
 #include "RenderSVGResourceMarker.h"
+#include "SVGElementInstance.h"
 #include "SVGFitToViewBox.h"
 #include "SVGNames.h"
 #include "SVGSVGElement.h"
@@ -78,71 +79,99 @@ AffineTransform SVGMarkerElement::viewBoxToViewTransform(float viewWidth, float
     return SVGFitToViewBox::viewBoxToViewTransform(viewBox(), preserveAspectRatio(), viewWidth, viewHeight);
 }
 
+bool SVGMarkerElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty()) {
+        SVGLangSpace::addSupportedAttributes(supportedAttributes);
+        SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
+        SVGFitToViewBox::addSupportedAttributes(supportedAttributes);
+        supportedAttributes.add(SVGNames::markerUnitsAttr);
+        supportedAttributes.add(SVGNames::refXAttr);
+        supportedAttributes.add(SVGNames::refYAttr);
+        supportedAttributes.add(SVGNames::markerWidthAttr);
+        supportedAttributes.add(SVGNames::markerHeightAttr);
+        supportedAttributes.add(SVGNames::orientAttr);
+    }
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGMarkerElement::parseMappedAttribute(Attribute* attr)
 {
-    const String& value = attr->value();
+    if (!isSupportedAttribute(attr->name())) {
+        SVGStyledElement::parseMappedAttribute(attr);
+        return;
+    }
+
+    const AtomicString& value = attr->value();
     if (attr->name() == SVGNames::markerUnitsAttr) {
         SVGMarkerUnitsType propertyValue = SVGPropertyTraits<SVGMarkerUnitsType>::fromString(value);
         if (propertyValue > 0)
             setMarkerUnitsBaseValue(propertyValue);
-    } else if (attr->name() == SVGNames::refXAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::refXAttr) {
         setRefXBaseValue(SVGLength(LengthModeWidth, value));
-    else if (attr->name() == SVGNames::refYAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::refYAttr) {
         setRefYBaseValue(SVGLength(LengthModeHeight, value));
-    else if (attr->name() == SVGNames::markerWidthAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::markerWidthAttr) {
         setMarkerWidthBaseValue(SVGLength(LengthModeWidth, value));
-    else if (attr->name() == SVGNames::markerHeightAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::markerHeightAttr) {
         setMarkerHeightBaseValue(SVGLength(LengthModeHeight, value));
-    else if (attr->name() == SVGNames::orientAttr) {
+        return;
+    }
+
+    if (attr->name() == SVGNames::orientAttr) {
         SVGAngle angle;
         SVGMarkerOrientType orientType = SVGPropertyTraits<SVGMarkerOrientType>::fromString(value, angle);
         if (orientType > 0)
             setOrientTypeBaseValue(orientType);
         if (orientType == SVG_MARKER_ORIENT_ANGLE)
             setOrientAngleBaseValue(angle);
-    } else {
-        if (SVGLangSpace::parseMappedAttribute(attr))
-            return;
-        if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
-            return;
-        if (SVGFitToViewBox::parseMappedAttribute(document(), attr))
-            return;
-
-        SVGStyledElement::parseMappedAttribute(attr);
+        return;
     }
+
+    if (SVGLangSpace::parseMappedAttribute(attr))
+        return;
+    if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
+        return;
+    if (SVGFitToViewBox::parseMappedAttribute(document(), attr))
+        return;
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGMarkerElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    SVGStyledElement::svgAttributeChanged(attrName);
+    if (!isSupportedAttribute(attrName)) {
+        SVGStyledElement::svgAttributeChanged(attrName);
+        return;
+    }
 
-    bool invalidateClients = false;
+    SVGElementInstance::InvalidationGuard invalidationGuard(this);
+    
     if (attrName == SVGNames::refXAttr
         || attrName == SVGNames::refYAttr
         || attrName == SVGNames::markerWidthAttr
-        || attrName == SVGNames::markerHeightAttr) {
-        invalidateClients = true;
+        || attrName == SVGNames::markerHeightAttr)
         updateRelativeLengthsInformation();
-    }
-
-    RenderObject* object = renderer();
-    if (!object)
-        return;
 
-    if (invalidateClients
-        || attrName == SVGNames::markerUnitsAttr
-        || attrName == SVGNames::orientAttr
-        || SVGLangSpace::isKnownAttribute(attrName)
-        || SVGExternalResourcesRequired::isKnownAttribute(attrName)
-        || SVGFitToViewBox::isKnownAttribute(attrName)
-        || SVGStyledElement::isKnownAttribute(attrName))
+    if (RenderObject* object = renderer())
         object->setNeedsLayout(true);
 }
 
 void SVGMarkerElement::synchronizeProperty(const QualifiedName& attrName)
 {
-    SVGStyledElement::synchronizeProperty(attrName);
-
     if (attrName == anyQName()) {
         synchronizeMarkerUnits();
         synchronizeRefX();
@@ -152,30 +181,58 @@ void SVGMarkerElement::synchronizeProperty(const QualifiedName& attrName)
         synchronizeOrientAngle();
         synchronizeOrientType();
         synchronizeExternalResourcesRequired();
-        synchronizeViewBox();
-        synchronizePreserveAspectRatio();
+        SVGFitToViewBox::synchronizeProperties(attrName);
+        SVGStyledElement::synchronizeProperty(attrName);
+        return;
+    }
+
+    if (!isSupportedAttribute(attrName)) {
+        SVGStyledElement::synchronizeProperty(attrName);
         return;
     }
 
-    if (attrName == SVGNames::markerUnitsAttr)
+    if (attrName == SVGNames::markerUnitsAttr) {
         synchronizeMarkerUnits();
-    else if (attrName == SVGNames::refXAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::refXAttr) {
         synchronizeRefX();
-    else if (attrName == SVGNames::refYAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::refYAttr) {
         synchronizeRefY();
-    else if (attrName == SVGNames::markerWidthAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::markerWidthAttr) {
         synchronizeMarkerWidth();
-    else if (attrName == SVGNames::markerHeightAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::markerHeightAttr) {
         synchronizeMarkerHeight();
-    else if (attrName == SVGNames::orientAttr) {
+        return;
+    }
+
+    if (attrName == SVGNames::orientAttr) {
         synchronizeOrientAngle();
         synchronizeOrientType();
-    } else if (SVGExternalResourcesRequired::isKnownAttribute(attrName))
+        return;
+    }
+
+    if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) {
         synchronizeExternalResourcesRequired();
-    else if (SVGFitToViewBox::isKnownAttribute(attrName)) {
-        synchronizeViewBox();
-        synchronizePreserveAspectRatio();
+        return;
     }
+
+    if (SVGFitToViewBox::isKnownAttribute(attrName)) {
+        SVGFitToViewBox::synchronizeProperties(attrName);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 AttributeToPropertyTypeMap& SVGMarkerElement::attributeToPropertyTypeMap()
index 24ce624..40f8a04 100644 (file)
@@ -64,6 +64,7 @@ private:
 
     virtual bool needsPendingResourceHandling() const { return false; }
 
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*);
     virtual void svgAttributeChanged(const QualifiedName&);
     virtual void synchronizeProperty(const QualifiedName&);
index b999d23..bcde099 100644 (file)
@@ -29,6 +29,7 @@
 #include "Attribute.h"
 #include "CSSStyleSelector.h"
 #include "RenderSVGResourceMasker.h"
+#include "SVGElementInstance.h"
 #include "SVGNames.h"
 #include "SVGRenderSupport.h"
 #include "SVGUnitTypes.h"
@@ -63,88 +64,154 @@ PassRefPtr<SVGMaskElement> SVGMaskElement::create(const QualifiedName& tagName,
     return adoptRef(new SVGMaskElement(tagName, document));
 }
 
+bool SVGMaskElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty()) {
+        SVGTests::addSupportedAttributes(supportedAttributes);
+        SVGLangSpace::addSupportedAttributes(supportedAttributes);
+        SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
+        supportedAttributes.add(SVGNames::maskUnitsAttr);
+        supportedAttributes.add(SVGNames::maskContentUnitsAttr);
+        supportedAttributes.add(SVGNames::xAttr);
+        supportedAttributes.add(SVGNames::yAttr);
+        supportedAttributes.add(SVGNames::widthAttr);
+        supportedAttributes.add(SVGNames::heightAttr);
+    }
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGMaskElement::parseMappedAttribute(Attribute* attr)
 {
+    if (!isSupportedAttribute(attr->name())) {
+        SVGStyledElement::parseMappedAttribute(attr);
+        return;
+    }
+
     if (attr->name() == SVGNames::maskUnitsAttr) {
         SVGUnitTypes::SVGUnitType propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(attr->value());
         if (propertyValue > 0)
             setMaskUnitsBaseValue(propertyValue);
-    } else if (attr->name() == SVGNames::maskContentUnitsAttr) {
+        return;
+    }
+
+    if (attr->name() == SVGNames::maskContentUnitsAttr) {
         SVGUnitTypes::SVGUnitType propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(attr->value());
         if (propertyValue > 0)
             setMaskContentUnitsBaseValue(propertyValue);
-    } else if (attr->name() == SVGNames::xAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::xAttr) {
         setXBaseValue(SVGLength(LengthModeWidth, attr->value()));
-    else if (attr->name() == SVGNames::yAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::yAttr) {
         setYBaseValue(SVGLength(LengthModeHeight, attr->value()));
-    else if (attr->name() == SVGNames::widthAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::widthAttr) {
         setWidthBaseValue(SVGLength(LengthModeWidth, attr->value()));
-    else if (attr->name() == SVGNames::heightAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::heightAttr) {
         setHeightBaseValue(SVGLength(LengthModeHeight, attr->value()));
-    else {
-        if (SVGTests::parseMappedAttribute(attr))
-            return;
-        if (SVGLangSpace::parseMappedAttribute(attr))
-            return;
-        if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
-            return;
-        SVGStyledElement::parseMappedAttribute(attr);
+        return;
     }
+
+    if (SVGTests::parseMappedAttribute(attr))
+        return;
+    if (SVGLangSpace::parseMappedAttribute(attr))
+        return;
+    if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
+        return;
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGMaskElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    SVGStyledElement::svgAttributeChanged(attrName);
+    if (!isSupportedAttribute(attrName)) {
+        SVGStyledElement::svgAttributeChanged(attrName);
+        return;
+    }
 
-    bool invalidateClients = false;
+    SVGElementInstance::InvalidationGuard invalidationGuard(this);
+    
     if (attrName == SVGNames::xAttr
         || attrName == SVGNames::yAttr
         || attrName == SVGNames::widthAttr
-        || attrName == SVGNames::heightAttr) {
-        invalidateClients = true;
+        || attrName == SVGNames::heightAttr)
         updateRelativeLengthsInformation();
-    }
-
-    RenderObject* object = renderer();
-    if (!object)
-        return;
 
-    if (invalidateClients
-        || attrName == SVGNames::maskUnitsAttr
-        || attrName == SVGNames::maskContentUnitsAttr
-        || SVGTests::isKnownAttribute(attrName)
-        || SVGLangSpace::isKnownAttribute(attrName)
-        || SVGExternalResourcesRequired::isKnownAttribute(attrName)
-        || SVGStyledElement::isKnownAttribute(attrName))
+    if (RenderObject* object = renderer())
         object->setNeedsLayout(true);
 }
 
 void SVGMaskElement::synchronizeProperty(const QualifiedName& attrName)
 {
-    SVGStyledElement::synchronizeProperty(attrName);
-
     if (attrName == anyQName()) {
         synchronizeMaskUnits();
         synchronizeMaskContentUnits();
         synchronizeX();
         synchronizeY();
+        synchronizeWidth();
+        synchronizeHeight();
         synchronizeExternalResourcesRequired();
         SVGTests::synchronizeProperties(this, attrName);
+        SVGStyledElement::synchronizeProperty(attrName);
+        return;
+    }
+
+    if (!isSupportedAttribute(attrName)) {
+        SVGStyledElement::synchronizeProperty(attrName);
         return;
     }
 
-    if (attrName == SVGNames::maskUnitsAttr)
+    if (attrName == SVGNames::maskUnitsAttr) {
         synchronizeMaskUnits();
-    else if (attrName == SVGNames::maskContentUnitsAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::maskContentUnitsAttr) {
         synchronizeMaskContentUnits();
-    else if (attrName == SVGNames::xAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::xAttr) {
         synchronizeX();
-    else if (attrName == SVGNames::yAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::yAttr) {
         synchronizeY();
-    else if (SVGExternalResourcesRequired::isKnownAttribute(attrName))
+        return;
+    }
+
+    if (attrName == SVGNames::widthAttr) {
+        synchronizeWidth();
+        return;
+    }
+
+    if (attrName == SVGNames::heightAttr) {
+        synchronizeHeight();
+        return;
+    }
+
+    if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) {
         synchronizeExternalResourcesRequired();
-    else if (SVGTests::isKnownAttribute(attrName))
+        return;
+    }
+
+    if (SVGTests::isKnownAttribute(attrName)) {
         SVGTests::synchronizeProperties(this, attrName);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 AttributeToPropertyTypeMap& SVGMaskElement::attributeToPropertyTypeMap()
index efbbdf8..faa1025 100644 (file)
@@ -47,6 +47,7 @@ private:
     virtual bool isValid() const { return SVGTests::isValid(); }
     virtual bool needsPendingResourceHandling() const { return false; }
 
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*);
     virtual void svgAttributeChanged(const QualifiedName&);
     virtual void synchronizeProperty(const QualifiedName&);
index 598d207..2a37af1 100644 (file)
@@ -26,6 +26,7 @@
 #include "Attribute.h"
 #include "RenderSVGPath.h"
 #include "RenderSVGResource.h"
+#include "SVGElementInstance.h"
 #include "SVGNames.h"
 #include "SVGPathParserFactory.h"
 #include "SVGPathSegArc.h"
@@ -178,31 +179,59 @@ PassRefPtr<SVGPathSegCurvetoQuadraticSmoothRel> SVGPathElement::createSVGPathSeg
     return SVGPathSegCurvetoQuadraticSmoothRel::create(this, role, x, y);
 }
 
+bool SVGPathElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty()) {
+        SVGTests::addSupportedAttributes(supportedAttributes);
+        SVGLangSpace::addSupportedAttributes(supportedAttributes);
+        SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
+        supportedAttributes.add(SVGNames::dAttr);
+        supportedAttributes.add(SVGNames::pathLengthAttr);
+    }
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGPathElement::parseMappedAttribute(Attribute* attr)
 {
+    if (!isSupportedAttribute(attr->name())) {
+        SVGStyledTransformableElement::parseMappedAttribute(attr);
+        return;
+    }
+
     if (attr->name() == SVGNames::dAttr) {
         SVGPathParserFactory* factory = SVGPathParserFactory::self();
         if (!factory->buildSVGPathByteStreamFromString(attr->value(), m_pathByteStream, UnalteredParsing))
             document()->accessSVGExtensions()->reportError("Problem parsing d=\"" + attr->value() + "\"");
-    } else if (attr->name() == SVGNames::pathLengthAttr) {
+        return;
+    }
+
+    if (attr->name() == SVGNames::pathLengthAttr) {
         setPathLengthBaseValue(attr->value().toFloat());
-        if (pathLengthBaseValue() < 0.0f)
+        if (pathLengthBaseValue() < 0)
             document()->accessSVGExtensions()->reportError("A negative value for path attribute <pathLength> is not allowed");
-    } else {
-        if (SVGTests::parseMappedAttribute(attr))
-            return;
-        if (SVGLangSpace::parseMappedAttribute(attr))
-            return;
-        if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
-            return;
-        SVGStyledTransformableElement::parseMappedAttribute(attr);
+        return;
     }
+
+    if (SVGTests::parseMappedAttribute(attr))
+        return;
+    if (SVGLangSpace::parseMappedAttribute(attr))
+        return;
+    if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
+        return;
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGPathElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    SVGStyledTransformableElement::svgAttributeChanged(attrName);
+    if (!isSupportedAttribute(attrName)) {
+        SVGStyledTransformableElement::svgAttributeChanged(attrName);
+        return;
+    }
 
+    SVGElementInstance::InvalidationGuard invalidationGuard(this);
+    
     if (SVGTests::handleAttributeChange(this, attrName))
         return;
 
@@ -216,43 +245,51 @@ void SVGPathElement::svgAttributeChanged(const QualifiedName& attrName)
             m_pathSegList.value = newList;
         }
 
-        if (!renderer)
-            return;
-
-        renderer->setNeedsPathUpdate();
-        RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
-        return;
+        if (renderer)
+            renderer->setNeedsPathUpdate();
     }
 
-    if (!renderer)
-        return;
-
-    if (attrName == SVGNames::pathLengthAttr
-        || SVGLangSpace::isKnownAttribute(attrName)
-        || SVGExternalResourcesRequired::isKnownAttribute(attrName))
+    if (renderer)
         RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
 }
 
 void SVGPathElement::synchronizeProperty(const QualifiedName& attrName)
 {
-    SVGStyledTransformableElement::synchronizeProperty(attrName);
-
     if (attrName == anyQName()) {
         synchronizeD();
         synchronizePathLength();
         synchronizeExternalResourcesRequired();
         SVGTests::synchronizeProperties(this, attrName);
+        SVGStyledTransformableElement::synchronizeProperty(attrName);
         return;
     }
 
-    if (attrName == SVGNames::dAttr)
+    if (!isSupportedAttribute(attrName)) {
+        SVGStyledTransformableElement::synchronizeProperty(attrName);
+        return;
+    }
+
+    if (attrName == SVGNames::dAttr) {
         synchronizeD();
-    else if (attrName == SVGNames::pathLengthAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::pathLengthAttr) {
         synchronizePathLength();
-    else if (SVGExternalResourcesRequired::isKnownAttribute(attrName))
+        return;
+    }
+
+    if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) {
         synchronizeExternalResourcesRequired();
-    else if (SVGTests::isKnownAttribute(attrName))
+        return;
+    }
+
+    if (SVGTests::isKnownAttribute(attrName)) {
         SVGTests::synchronizeProperties(this, attrName);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGPathElement::synchronizeD()
index 7f836c4..3fd632d 100644 (file)
@@ -101,6 +101,7 @@ private:
 
     virtual bool isValid() const { return SVGTests::isValid(); }
 
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*);
     virtual void synchronizeProperty(const QualifiedName&);
     virtual void svgAttributeChanged(const QualifiedName&);
index 2deb4f7..a58b30f 100644 (file)
@@ -33,6 +33,7 @@
 #include "PatternAttributes.h"
 #include "RenderSVGContainer.h"
 #include "RenderSVGResourcePattern.h"
+#include "SVGElementInstance.h"
 #include "SVGNames.h"
 #include "SVGRenderSupport.h"
 #include "SVGSVGElement.h"
@@ -71,85 +72,116 @@ PassRefPtr<SVGPatternElement> SVGPatternElement::create(const QualifiedName& tag
     return adoptRef(new SVGPatternElement(tagName, document));
 }
 
+bool SVGPatternElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty()) {
+        SVGURIReference::addSupportedAttributes(supportedAttributes);
+        SVGTests::addSupportedAttributes(supportedAttributes);
+        SVGLangSpace::addSupportedAttributes(supportedAttributes);
+        SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
+        SVGFitToViewBox::addSupportedAttributes(supportedAttributes);
+        supportedAttributes.add(SVGNames::patternUnitsAttr);
+        supportedAttributes.add(SVGNames::patternContentUnitsAttr);
+        supportedAttributes.add(SVGNames::patternTransformAttr);
+        supportedAttributes.add(SVGNames::xAttr);
+        supportedAttributes.add(SVGNames::yAttr);
+        supportedAttributes.add(SVGNames::widthAttr);
+        supportedAttributes.add(SVGNames::heightAttr);
+    }
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGPatternElement::parseMappedAttribute(Attribute* attr)
 {
+    if (!isSupportedAttribute(attr->name())) {
+        SVGStyledElement::parseMappedAttribute(attr);
+        return;
+    }
+
     if (attr->name() == SVGNames::patternUnitsAttr) {
         SVGUnitTypes::SVGUnitType propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(attr->value());
         if (propertyValue > 0)
             setPatternUnitsBaseValue(propertyValue);
-    } else if (attr->name() == SVGNames::patternContentUnitsAttr) {
+        return;
+    }
+
+    if (attr->name() == SVGNames::patternContentUnitsAttr) {
         SVGUnitTypes::SVGUnitType propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(attr->value());
         if (propertyValue > 0)
             setPatternContentUnitsBaseValue(propertyValue);
-    } else if (attr->name() == SVGNames::patternTransformAttr) {
+        return;
+    }
+
+    if (attr->name() == SVGNames::patternTransformAttr) {
         SVGTransformList newList;
         if (!SVGTransformable::parseTransformAttribute(newList, attr->value()))
             newList.clear();
 
         detachAnimatedPatternTransformListWrappers(newList.size());
         setPatternTransformBaseValue(newList);
-    } else if (attr->name() == SVGNames::xAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::xAttr) {
         setXBaseValue(SVGLength(LengthModeWidth, attr->value()));
-    else if (attr->name() == SVGNames::yAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::yAttr) {
         setYBaseValue(SVGLength(LengthModeHeight, attr->value()));
-    else if (attr->name() == SVGNames::widthAttr) {
+        return;
+    }
+
+    if (attr->name() == SVGNames::widthAttr) {
         setWidthBaseValue(SVGLength(LengthModeWidth, attr->value()));
-        if (widthBaseValue().value(this) < 0.0)
+        if (widthBaseValue().value(this) < 0)
             document()->accessSVGExtensions()->reportError("A negative value for pattern attribute <width> is not allowed");
-    } else if (attr->name() == SVGNames::heightAttr) {
+        return;
+    }
+
+    if (attr->name() == SVGNames::heightAttr) {
         setHeightBaseValue(SVGLength(LengthModeHeight, attr->value()));
-        if (heightBaseValue().value(this) < 0.0)
+        if (heightBaseValue().value(this) < 0)
             document()->accessSVGExtensions()->reportError("A negative value for pattern attribute <height> is not allowed");
-    } else {
-        if (SVGURIReference::parseMappedAttribute(attr))
-            return;
-        if (SVGTests::parseMappedAttribute(attr))
-            return;
-        if (SVGLangSpace::parseMappedAttribute(attr))
-            return;
-        if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
-            return;
-        if (SVGFitToViewBox::parseMappedAttribute(document(), attr))
-            return;
-
-        SVGStyledElement::parseMappedAttribute(attr);
+        return;
     }
+
+    if (SVGURIReference::parseMappedAttribute(attr))
+        return;
+    if (SVGTests::parseMappedAttribute(attr))
+        return;
+    if (SVGLangSpace::parseMappedAttribute(attr))
+        return;
+    if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
+        return;
+    if (SVGFitToViewBox::parseMappedAttribute(document(), attr))
+        return;
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGPatternElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    SVGStyledElement::svgAttributeChanged(attrName);
+    if (!isSupportedAttribute(attrName)) {
+        SVGStyledElement::svgAttributeChanged(attrName);
+        return;
+    }
 
-    bool invalidateClients = false;
+    SVGElementInstance::InvalidationGuard invalidationGuard(this);
+    
     if (attrName == SVGNames::xAttr
         || attrName == SVGNames::yAttr
         || attrName == SVGNames::widthAttr
-        || attrName == SVGNames::heightAttr) {
-        invalidateClients = true;
+        || attrName == SVGNames::heightAttr)
         updateRelativeLengthsInformation();
-    }
-
-    RenderObject* object = renderer();
-    if (!object)
-        return;
 
-    if (invalidateClients
-        || attrName == SVGNames::patternUnitsAttr
-        || attrName == SVGNames::patternContentUnitsAttr
-        || attrName == SVGNames::patternTransformAttr
-        || SVGURIReference::isKnownAttribute(attrName)
-        || SVGTests::isKnownAttribute(attrName)
-        || SVGLangSpace::isKnownAttribute(attrName)
-        || SVGExternalResourcesRequired::isKnownAttribute(attrName)
-        || SVGFitToViewBox::isKnownAttribute(attrName)
-        || SVGStyledElement::isKnownAttribute(attrName))
+    if (RenderObject* object = renderer())
         object->setNeedsLayout(true);
 }
 
 void SVGPatternElement::synchronizeProperty(const QualifiedName& attrName)
-{
-    SVGStyledElement::synchronizeProperty(attrName);
-
+{    
     if (attrName == anyQName()) {
         synchronizePatternUnits();
         synchronizePatternContentUnits();
@@ -159,37 +191,74 @@ void SVGPatternElement::synchronizeProperty(const QualifiedName& attrName)
         synchronizeWidth();
         synchronizeHeight();
         synchronizeExternalResourcesRequired();
-        synchronizeViewBox();
-        synchronizePreserveAspectRatio();
         synchronizeHref();
+        SVGFitToViewBox::synchronizeProperties(attrName);
         SVGTests::synchronizeProperties(this, attrName);
+        SVGStyledElement::synchronizeProperty(attrName);
+        return;
+    }
+
+    if (!isSupportedAttribute(attrName)) {
+        SVGStyledElement::synchronizeProperty(attrName);
         return;
     }
 
-    if (attrName == SVGNames::patternUnitsAttr)
+    if (attrName == SVGNames::patternUnitsAttr) {
         synchronizePatternUnits();
-    else if (attrName == SVGNames::patternContentUnitsAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::patternContentUnitsAttr) {
         synchronizePatternContentUnits();
-    else if (attrName == SVGNames::patternTransformAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::patternTransformAttr) {
         synchronizePatternTransform();
-    else if (attrName == SVGNames::xAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::xAttr) {
         synchronizeX();
-    else if (attrName == SVGNames::yAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::yAttr) {
         synchronizeY();
-    else if (attrName == SVGNames::widthAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::widthAttr) {
         synchronizeWidth();
-    else if (attrName == SVGNames::heightAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::heightAttr) {
         synchronizeHeight();
-    else if (SVGExternalResourcesRequired::isKnownAttribute(attrName))
+        return;
+    }
+
+    if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) {
         synchronizeExternalResourcesRequired();
-    else if (attrName == SVGNames::viewBoxAttr)
-        synchronizeViewBox();
-    else if (attrName == SVGNames::preserveAspectRatioAttr)
-        synchronizePreserveAspectRatio();
-    else if (SVGURIReference::isKnownAttribute(attrName))
+        return;
+    }
+
+    if (SVGFitToViewBox::isKnownAttribute(attrName)) {
+        SVGFitToViewBox::synchronizeProperties(attrName);
+        return;
+    }
+
+    if (SVGURIReference::isKnownAttribute(attrName)) {
         synchronizeHref();
-    else if (SVGTests::isKnownAttribute(attrName))
+        return;
+    }
+
+    if (SVGTests::isKnownAttribute(attrName)) {
         SVGTests::synchronizeProperties(this, attrName);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 AttributeToPropertyTypeMap& SVGPatternElement::attributeToPropertyTypeMap()
index 0ad5250..c1db4cb 100644 (file)
@@ -57,6 +57,7 @@ private:
     virtual bool isValid() const { return SVGTests::isValid(); }
     virtual bool needsPendingResourceHandling() const { return false; }
 
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*);
     virtual void svgAttributeChanged(const QualifiedName&);
     virtual void synchronizeProperty(const QualifiedName&);
index 331e5ec..a4c9dc6 100644 (file)
@@ -28,6 +28,7 @@
 #include "FloatPoint.h"
 #include "RenderSVGPath.h"
 #include "RenderSVGResource.h"
+#include "SVGElementInstance.h"
 #include "SVGNames.h"
 #include "SVGParserUtilities.h"
 #include "SVGPointList.h"
@@ -42,8 +43,25 @@ SVGPolyElement::SVGPolyElement(const QualifiedName& tagName, Document* document)
 {
 }
 
+bool SVGPolyElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty()) {
+        SVGTests::addSupportedAttributes(supportedAttributes);
+        SVGLangSpace::addSupportedAttributes(supportedAttributes);
+        SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
+        supportedAttributes.add(SVGNames::pointsAttr);
+    }
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGPolyElement::parseMappedAttribute(Attribute* attr)
 {
+    if (!isSupportedAttribute(attr->name())) {
+        SVGStyledTransformableElement::parseMappedAttribute(attr);
+        return;
+    }
+
     const AtomicString& value = attr->value();
     if (attr->name() == SVGNames::pointsAttr) {
         SVGPointList newList;
@@ -54,21 +72,28 @@ void SVGPolyElement::parseMappedAttribute(Attribute* attr)
             list->detachListWrappers(newList.size());
 
         m_points.value = newList;
-    } else {
-        if (SVGTests::parseMappedAttribute(attr))
-            return;
-        if (SVGLangSpace::parseMappedAttribute(attr))
-            return;
-        if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
-            return;
-        SVGStyledTransformableElement::parseMappedAttribute(attr);
+        return;
     }
+
+    if (SVGTests::parseMappedAttribute(attr))
+        return;
+    if (SVGLangSpace::parseMappedAttribute(attr))
+        return;
+    if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
+        return;
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGPolyElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    SVGStyledTransformableElement::svgAttributeChanged(attrName);
+    if (!isSupportedAttribute(attrName)) {
+        SVGStyledTransformableElement::svgAttributeChanged(attrName);
+        return;
+    }
 
+    SVGElementInstance::InvalidationGuard invalidationGuard(this);
+    
     if (SVGTests::handleAttributeChange(this, attrName))
         return;
 
@@ -82,9 +107,12 @@ void SVGPolyElement::svgAttributeChanged(const QualifiedName& attrName)
         return;
     }
 
-    if (SVGLangSpace::isKnownAttribute(attrName)
-        || SVGExternalResourcesRequired::isKnownAttribute(attrName))
+    if (SVGLangSpace::isKnownAttribute(attrName) || SVGExternalResourcesRequired::isKnownAttribute(attrName)) {
         RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGPolyElement::synchronizeProperty(const QualifiedName& attrName)
index 7e3248e..3156d6a 100644 (file)
@@ -47,6 +47,7 @@ protected:
 private:
     virtual bool isValid() const { return SVGTests::isValid(); }
 
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*); 
     virtual void svgAttributeChanged(const QualifiedName&);
     virtual void synchronizeProperty(const QualifiedName&);
index 682f187..d2ecdc9 100644 (file)
@@ -31,6 +31,7 @@
 #include "FloatPoint.h"
 #include "RadialGradientAttributes.h"
 #include "RenderSVGResourceRadialGradient.h"
+#include "SVGElementInstance.h"
 #include "SVGNames.h"
 #include "SVGStopElement.h"
 #include "SVGTransform.h"
@@ -63,66 +64,114 @@ PassRefPtr<SVGRadialGradientElement> SVGRadialGradientElement::create(const Qual
     return adoptRef(new SVGRadialGradientElement(tagName, document));
 }
 
+bool SVGRadialGradientElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty()) {
+        supportedAttributes.add(SVGNames::cxAttr);
+        supportedAttributes.add(SVGNames::cyAttr);
+        supportedAttributes.add(SVGNames::fxAttr);
+        supportedAttributes.add(SVGNames::fyAttr);
+        supportedAttributes.add(SVGNames::rAttr);
+    }
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGRadialGradientElement::parseMappedAttribute(Attribute* attr)
 {
-    if (attr->name() == SVGNames::cxAttr)
+    if (!isSupportedAttribute(attr->name())) {
+        SVGGradientElement::parseMappedAttribute(attr);
+        return;
+    }
+
+    if (attr->name() == SVGNames::cxAttr) {
         setCxBaseValue(SVGLength(LengthModeWidth, attr->value()));
-    else if (attr->name() == SVGNames::cyAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::cyAttr) {
         setCyBaseValue(SVGLength(LengthModeHeight, attr->value()));
-    else if (attr->name() == SVGNames::rAttr) {
+        return;
+    }
+
+    if (attr->name() == SVGNames::rAttr) {
         setRBaseValue(SVGLength(LengthModeOther, attr->value()));
-        if (rBaseValue().value(this) < 0.0)
+        if (rBaseValue().value(this) < 0)
             document()->accessSVGExtensions()->reportError("A negative value for radial gradient radius <r> is not allowed");
-    } else if (attr->name() == SVGNames::fxAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::fxAttr) {
         setFxBaseValue(SVGLength(LengthModeWidth, attr->value()));
-    else if (attr->name() == SVGNames::fyAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::fyAttr) {
         setFyBaseValue(SVGLength(LengthModeHeight, attr->value()));
-    else
-        SVGGradientElement::parseMappedAttribute(attr);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGRadialGradientElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    SVGGradientElement::svgAttributeChanged(attrName);
-
-    if (attrName == SVGNames::cxAttr
-        || attrName == SVGNames::cyAttr
-        || attrName == SVGNames::fxAttr
-        || attrName == SVGNames::fyAttr
-        || attrName == SVGNames::rAttr) {
-        updateRelativeLengthsInformation();
-        
-        RenderObject* object = renderer();
-        if (!object)
-            return;
+    if (!isSupportedAttribute(attrName)) {
+        SVGGradientElement::svgAttributeChanged(attrName);
+        return;
+    }
 
+    SVGElementInstance::InvalidationGuard invalidationGuard(this);
+    
+    updateRelativeLengthsInformation();
+        
+    if (RenderObject* object = renderer())
         object->setNeedsLayout(true);
-    }
 }
 
 void SVGRadialGradientElement::synchronizeProperty(const QualifiedName& attrName)
 {
-    SVGGradientElement::synchronizeProperty(attrName);
-
     if (attrName == anyQName()) {
         synchronizeCx();
         synchronizeCy();
         synchronizeFx();
         synchronizeFy();
         synchronizeR();
+        SVGGradientElement::synchronizeProperty(attrName);
         return;
     }
 
-    if (attrName == SVGNames::cxAttr)
+    if (!isSupportedAttribute(attrName)) {
+        SVGGradientElement::synchronizeProperty(attrName);
+        return;
+    }
+
+    if (attrName == SVGNames::cxAttr) {
         synchronizeCx();
-    else if (attrName == SVGNames::cyAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::cyAttr) {
         synchronizeCy();
-    else if (attrName == SVGNames::fxAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::fxAttr) {
         synchronizeFx();
-    else if (attrName == SVGNames::fyAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::fyAttr) {
         synchronizeFy();
-    else if (attrName == SVGNames::rAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::rAttr) {
         synchronizeR();
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 AttributeToPropertyTypeMap& SVGRadialGradientElement::attributeToPropertyTypeMap()
index 40af133..7c9c75d 100644 (file)
@@ -39,6 +39,7 @@ public:
 private:
     SVGRadialGradientElement(const QualifiedName&, Document*);
 
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*);
     virtual void svgAttributeChanged(const QualifiedName&);
     virtual void synchronizeProperty(const QualifiedName&);
index 82df35f..e66cf40 100644 (file)
@@ -26,6 +26,7 @@
 #include "Attribute.h"
 #include "RenderSVGPath.h"
 #include "RenderSVGResource.h"
+#include "SVGElementInstance.h"
 #include "SVGLength.h"
 #include "SVGNames.h"
 
@@ -57,43 +58,87 @@ PassRefPtr<SVGRectElement> SVGRectElement::create(const QualifiedName& tagName,
     return adoptRef(new SVGRectElement(tagName, document));
 }
 
+bool SVGRectElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty()) {
+        SVGTests::addSupportedAttributes(supportedAttributes);
+        SVGLangSpace::addSupportedAttributes(supportedAttributes);
+        SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
+        supportedAttributes.add(SVGNames::xAttr);
+        supportedAttributes.add(SVGNames::yAttr);
+        supportedAttributes.add(SVGNames::widthAttr);
+        supportedAttributes.add(SVGNames::heightAttr);
+        supportedAttributes.add(SVGNames::rxAttr);
+        supportedAttributes.add(SVGNames::ryAttr);
+    }
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGRectElement::parseMappedAttribute(Attribute* attr)
 {
-    if (attr->name() == SVGNames::xAttr)
+    if (!isSupportedAttribute(attr->name())) {
+        SVGStyledTransformableElement::parseMappedAttribute(attr);
+        return;
+    }
+
+    if (attr->name() == SVGNames::xAttr) {
         setXBaseValue(SVGLength(LengthModeWidth, attr->value()));
-    else if (attr->name() == SVGNames::yAttr)
+        return;
+    }
+
+    if (attr->name() == SVGNames::yAttr) {
         setYBaseValue(SVGLength(LengthModeHeight, attr->value()));
-    else if (attr->name() == SVGNames::rxAttr) {
+        return;
+    }
+
+    if (attr->name() == SVGNames::rxAttr) {
         setRxBaseValue(SVGLength(LengthModeWidth, attr->value()));
-        if (rxBaseValue().value(this) < 0.0)
+        if (rxBaseValue().value(this) < 0)
             document()->accessSVGExtensions()->reportError("A negative value for rect <rx> is not allowed");
-    } else if (attr->name() == SVGNames::ryAttr) {
+        return;
+    }
+
+    if (attr->name() == SVGNames::ryAttr) {
         setRyBaseValue(SVGLength(LengthModeHeight, attr->value()));
-        if (ryBaseValue().value(this) < 0.0)
+        if (ryBaseValue().value(this) < 0)
             document()->accessSVGExtensions()->reportError("A negative value for rect <ry> is not allowed");
-    } else if (attr->name() == SVGNames::widthAttr) {
+        return;
+    }
+
+    if (attr->name() == SVGNames::widthAttr) {
         setWidthBaseValue(SVGLength(LengthModeWidth, attr->value()));
-        if (widthBaseValue().value(this) < 0.0)
+        if (widthBaseValue().value(this) < 0)
             document()->accessSVGExtensions()->reportError("A negative value for rect <width> is not allowed");
-    } else if (attr->name() == SVGNames::heightAttr) {
+        return;
+    }
+
+    if (attr->name() == SVGNames::heightAttr) {
         setHeightBaseValue(SVGLength(LengthModeHeight, attr->value()));
-        if (heightBaseValue().value(this) < 0.0)
+        if (heightBaseValue().value(this) < 0)
             document()->accessSVGExtensions()->reportError("A negative value for rect <height> is not allowed");
-    } else {
-        if (SVGTests::parseMappedAttribute(attr))
-            return;
-        if (SVGLangSpace::parseMappedAttribute(attr))
-            return;
-        if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
-            return;
-        SVGStyledTransformableElement::parseMappedAttribute(attr);
+        return;
     }
+
+    if (SVGTests::parseMappedAttribute(attr))
+        return;
+    if (SVGLangSpace::parseMappedAttribute(attr))
+        return;
+    if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
+        return;
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGRectElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    SVGStyledTransformableElement::svgAttributeChanged(attrName);
+    if (!isSupportedAttribute(attrName)) {
+        SVGStyledTransformableElement::svgAttributeChanged(attrName);
+        return;
+    }
 
+    SVGElementInstance::InvalidationGuard invalidationGuard(this);
+    
     bool isLengthAttribute = attrName == SVGNames::xAttr
                           || attrName == SVGNames::yAttr
                           || attrName == SVGNames::widthAttr
@@ -117,15 +162,16 @@ void SVGRectElement::svgAttributeChanged(const QualifiedName& attrName)
         return;
     }
 
-    if (SVGLangSpace::isKnownAttribute(attrName) 
-        || SVGExternalResourcesRequired::isKnownAttribute(attrName))
+    if (SVGLangSpace::isKnownAttribute(attrName) || SVGExternalResourcesRequired::isKnownAttribute(attrName)) {
         RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGRectElement::synchronizeProperty(const QualifiedName& attrName)
 {
-    SVGStyledTransformableElement::synchronizeProperty(attrName);
-
     if (attrName == anyQName()) {
         synchronizeX();
         synchronizeY();
@@ -135,25 +181,56 @@ void SVGRectElement::synchronizeProperty(const QualifiedName& attrName)
         synchronizeRy();
         synchronizeExternalResourcesRequired();
         SVGTests::synchronizeProperties(this, attrName);
+        SVGStyledTransformableElement::synchronizeProperty(attrName);
         return;
     }
 
-    if (attrName == SVGNames::xAttr)
+    if (!isSupportedAttribute(attrName)) {
+        SVGStyledTransformableElement::synchronizeProperty(attrName);
+        return;
+    }
+
+    if (attrName == SVGNames::xAttr) {
         synchronizeX();
-    else if (attrName == SVGNames::yAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::yAttr) {
         synchronizeY();
-    else if (attrName == SVGNames::widthAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::widthAttr) {
         synchronizeWidth();
-    else if (attrName == SVGNames::heightAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::heightAttr) {
         synchronizeHeight();
-    else if (attrName == SVGNames::rxAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::rxAttr) {
         synchronizeRx();
-    else if (attrName == SVGNames::ryAttr)
+        return;
+    }
+
+    if (attrName == SVGNames::ryAttr) {
         synchronizeRy();
-    else if (SVGExternalResourcesRequired::isKnownAttribute(attrName))
+        return;
+    }
+
+    if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) {
         synchronizeExternalResourcesRequired();
-    else if (SVGTests::isKnownAttribute(attrName))
+        return;
+    }
+
+    if (SVGTests::isKnownAttribute(attrName)) {
         SVGTests::synchronizeProperties(this, attrName);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 AttributeToPropertyTypeMap& SVGRectElement::attributeToPropertyTypeMap()
index 08ab4bf..ad5af26 100644 (file)
@@ -43,6 +43,7 @@ private:
     
     virtual bool isValid() const { return SVGTests::isValid(); }
 
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*);
     virtual void svgAttributeChanged(const QualifiedName&);
     virtual void synchronizeProperty(const QualifiedName&);
index 9c316c6..63f43aa 100644 (file)
@@ -42,6 +42,7 @@
 #include "RenderSVGViewportContainer.h"
 #include "SMILTimeContainer.h"
 #include "SVGAngle.h"
+#include "SVGElementInstance.h"
 #include "SVGNames.h"
 #include "SVGPreserveAspectRatio.h"
 #include "SVGTransform.h"
@@ -299,9 +300,7 @@ static void updateCSSForAttribute(SVGSVGElement* element, const QualifiedName& a
 }
 
 void SVGSVGElement::svgAttributeChanged(const QualifiedName& attrName)
-{
-    SVGStyledElement::svgAttributeChanged(attrName);
-
+{ 
     // FIXME: Ugly, ugly hack to around that parseMappedAttribute is not called
     // when svg.width.baseValue = 100 is evaluated.
     // Thus the CSS length value for width is not updated, and width() computeLogicalWidth()
@@ -324,33 +323,33 @@ void SVGSVGElement::svgAttributeChanged(const QualifiedName& attrName)
         updateRelativeLengthsInformation();
     }
 
+    SVGElementInstance::InvalidationGuard invalidationGuard(this);
     if (SVGTests::handleAttributeChange(this, attrName))
         return;
 
-    if (!renderer())
-        return;
-
     if (updateRelativeLengths
         || SVGLangSpace::isKnownAttribute(attrName)
         || SVGExternalResourcesRequired::isKnownAttribute(attrName)
-        || SVGZoomAndPan::isKnownAttribute(attrName)
-        || SVGStyledLocatableElement::isKnownAttribute(attrName))
-        RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer());
+        || SVGZoomAndPan::isKnownAttribute(attrName)) {
+        if (renderer())
+            RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer());
+        return;
+    }
+
+    SVGStyledElement::svgAttributeChanged(attrName);
 }
 
 void SVGSVGElement::synchronizeProperty(const QualifiedName& attrName)
 {
-    SVGStyledElement::synchronizeProperty(attrName);
-
     if (attrName == anyQName()) {
         synchronizeX();
         synchronizeY();
         synchronizeWidth();
         synchronizeHeight();
         synchronizeExternalResourcesRequired();
-        synchronizeViewBox();
-        synchronizePreserveAspectRatio();
+        SVGFitToViewBox::synchronizeProperties(attrName);
         SVGTests::synchronizeProperties(this, attrName);
+        SVGStyledElement::synchronizeProperty(attrName);
         return;
     }
 
@@ -364,12 +363,12 @@ void SVGSVGElement::synchronizeProperty(const QualifiedName& attrName)
         synchronizeHeight();
     else if (SVGExternalResourcesRequired::isKnownAttribute(attrName))
         synchronizeExternalResourcesRequired();
-    else if (attrName == SVGNames::viewBoxAttr)
-        synchronizeViewBox();
-    else if (attrName == SVGNames::preserveAspectRatioAttr)
-        synchronizePreserveAspectRatio();
+    else if (SVGFitToViewBox::isKnownAttribute(attrName)) 
+        SVGFitToViewBox::synchronizeProperties(attrName);
     else if (SVGTests::isKnownAttribute(attrName))
         SVGTests::synchronizeProperties(this, attrName);
+    else
+        SVGStyledElement::synchronizeProperty(attrName);
 }
 
 AttributeToPropertyTypeMap& SVGSVGElement::attributeToPropertyTypeMap()
index b812d5d..c018c59 100644 (file)
@@ -28,6 +28,7 @@
 #include "Event.h"
 #include "EventNames.h"
 #include "HTMLNames.h"
+#include "SVGElementInstance.h"
 #include "SVGNames.h"
 #include "ScriptEventListener.h"
 
@@ -49,31 +50,61 @@ PassRefPtr<SVGScriptElement> SVGScriptElement::create(const QualifiedName& tagNa
     return adoptRef(new SVGScriptElement(tagName, document, insertedByParser, false));
 }
 
+bool SVGScriptElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty()) {
+        SVGURIReference::addSupportedAttributes(supportedAttributes);
+        SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
+        supportedAttributes.add(SVGNames::typeAttr);
+        supportedAttributes.add(HTMLNames::onerrorAttr);
+    }
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGScriptElement::parseMappedAttribute(Attribute* attr)
 {
-    const QualifiedName& attrName = attr->name();
+    if (!isSupportedAttribute(attr->name())) {
+        SVGElement::parseMappedAttribute(attr);
+        return;
+    }
 
-    if (attrName == SVGNames::typeAttr)
+    if (attr->name() == SVGNames::typeAttr) {
         setType(attr->value());
-    else if (attr->name() == HTMLNames::onerrorAttr)
-        setAttributeEventListener(eventNames().errorEvent, createAttributeEventListener(this, attr));
-    else {
-        if (SVGURIReference::parseMappedAttribute(attr))
-            return;
-        if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
-            return;
+        return;
+    }
 
-        SVGElement::parseMappedAttribute(attr);
+    if (attr->name() == HTMLNames::onerrorAttr) {
+        setAttributeEventListener(eventNames().errorEvent, createAttributeEventListener(this, attr));
+        return;
     }
+
+    if (SVGURIReference::parseMappedAttribute(attr))
+        return;
+    if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
+        return;
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGScriptElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    SVGElement::svgAttributeChanged(attrName);
+    if (!isSupportedAttribute(attrName)) {
+        SVGElement::svgAttributeChanged(attrName);
+        return;
+    }
+
+    SVGElementInstance::InvalidationGuard invalidationGuard(this);
+
+    if (attrName == SVGNames::typeAttr || attrName == HTMLNames::onerrorAttr)
+        return;
 
-    if (SVGURIReference::isKnownAttribute(attrName))
+    if (SVGURIReference::isKnownAttribute(attrName)) {
         handleSourceAttribute(href());
-    else if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) {
+        return;
+    }
+
+    if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) {
         // Handle dynamic updates of the 'externalResourcesRequired' attribute. Only possible case: changing from 'true' to 'false'
         // causes an immediate dispatch of the SVGLoad event. If the attribute value was 'false' before inserting the script element
         // in the document, the SVGLoad event has already been dispatched.
@@ -83,23 +114,37 @@ void SVGScriptElement::svgAttributeChanged(const QualifiedName& attrName)
 
             sendSVGLoadEventIfPossible();
         }
+        return;
     }
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGScriptElement::synchronizeProperty(const QualifiedName& attrName)
 {
-    SVGElement::synchronizeProperty(attrName);
-
     if (attrName == anyQName()) {
         synchronizeExternalResourcesRequired();
         synchronizeHref();
+        SVGElement::synchronizeProperty(attrName);
         return;
     }
 
-    if (SVGExternalResourcesRequired::isKnownAttribute(attrName))
+    if (!isSupportedAttribute(attrName)) {
+        SVGElement::synchronizeProperty(attrName);
+        return;
+    }   
+
+    if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) {
         synchronizeExternalResourcesRequired();
-    else if (SVGURIReference::isKnownAttribute(attrName))
+        return;
+    }
+
+    if (SVGURIReference::isKnownAttribute(attrName)) {
         synchronizeHref();
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 AttributeToPropertyTypeMap& SVGScriptElement::attributeToPropertyTypeMap()
index 5e62800..664a7f8 100644 (file)
@@ -44,6 +44,7 @@ public:
 private:
     SVGScriptElement(const QualifiedName&, Document*, bool wasInsertedByParser, bool alreadyStarted);
 
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*);
     virtual void insertedIntoDocument();
     virtual void removedFromDocument();
index 2ef6642..1ca52a2 100644 (file)
@@ -27,6 +27,7 @@
 #include "Document.h"
 #include "RenderSVGGradientStop.h"
 #include "RenderSVGResource.h"
+#include "SVGElementInstance.h"
 #include "SVGGradientElement.h"
 #include "SVGNames.h"
 
@@ -47,35 +48,72 @@ PassRefPtr<SVGStopElement> SVGStopElement::create(const QualifiedName& tagName,
     return adoptRef(new SVGStopElement(tagName, document));
 }
 
+bool SVGStopElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty())
+        supportedAttributes.add(SVGNames::offsetAttr);
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGStopElement::parseMappedAttribute(Attribute* attr)
 {
+    if (!isSupportedAttribute(attr->name())) {
+        SVGStyledElement::parseMappedAttribute(attr);
+        return;
+    }
+
     if (attr->name() == SVGNames::offsetAttr) {
         const String& value = attr->value();
         if (value.endsWith("%"))
             setOffsetBaseValue(value.left(value.length() - 1).toFloat() / 100.0f);
         else
             setOffsetBaseValue(value.toFloat());
-    } else
-        SVGStyledElement::parseMappedAttribute(attr);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGStopElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    SVGStyledElement::svgAttributeChanged(attrName);
+    if (!isSupportedAttribute(attrName)) {
+        SVGStyledElement::svgAttributeChanged(attrName);
+        return;
+    }
+
+    SVGElementInstance::InvalidationGuard invalidationGuard(this);
 
     if (!renderer())
         return;
 
-    if (attrName == SVGNames::offsetAttr)
+    if (attrName == SVGNames::offsetAttr) {
         RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer());
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGStopElement::synchronizeProperty(const QualifiedName& attrName)
 {
-    SVGStyledElement::synchronizeProperty(attrName);
+    if (attrName == anyQName()) {
+        synchronizeOffset();
+        SVGStyledElement::synchronizeProperty(attrName);
+        return;
+    }
 
-    if (attrName == anyQName() || attrName == SVGNames::offsetAttr)
+    if (!isSupportedAttribute(attrName)) {
+        SVGStyledElement::synchronizeProperty(attrName);
+        return;
+    }
+
+    if (attrName == SVGNames::offsetAttr) {
         synchronizeOffset();
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 AttributeToPropertyTypeMap& SVGStopElement::attributeToPropertyTypeMap()
index 8ea1cf5..8d2ee8c 100644 (file)
@@ -36,6 +36,7 @@ public:
 private:
     SVGStopElement(const QualifiedName&, Document*);
 
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*);
     virtual void svgAttributeChanged(const QualifiedName&);
     virtual void synchronizeProperty(const QualifiedName&);
index 6be1158..ac8e6fa 100644 (file)
@@ -86,15 +86,33 @@ void SVGStyleElement::setTitle(const AtomicString& title, ExceptionCode& ec)
     setAttribute(SVGNames::titleAttr, title, ec);
 }
 
+bool SVGStyleElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty()) {
+        SVGLangSpace::addSupportedAttributes(supportedAttributes);
+        supportedAttributes.add(SVGNames::titleAttr);
+    }
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGStyleElement::parseMappedAttribute(Attribute* attr)
 {
-    if (attr->name() == SVGNames::titleAttr && m_sheet)
-        m_sheet->setTitle(attr->value());
-    else {
-        if (SVGLangSpace::parseMappedAttribute(attr))
-            return;
+    if (!isSupportedAttribute(attr->name())) {
         SVGElement::parseMappedAttribute(attr);
+        return;
     }
+
+    if (attr->name() == SVGNames::titleAttr) {
+        if (m_sheet)
+            m_sheet->setTitle(attr->value());
+        return;
+    }
+
+    if (SVGLangSpace::parseMappedAttribute(attr))
+        return;
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGStyleElement::finishParsingChildren()
index acf358e..9f0ff31 100644 (file)
@@ -49,6 +49,7 @@ public:
 private:
     SVGStyleElement(const QualifiedName&, Document*, bool createdByParser);
 
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*);
     virtual void insertedIntoDocument();
     virtual void removedFromDocument();
index 6da8f48..0309128 100644 (file)
@@ -297,10 +297,9 @@ bool SVGStyledElement::mapToEntry(const QualifiedName& attrName, MappedAttribute
 
 void SVGStyledElement::parseMappedAttribute(Attribute* attr)
 {
-    const QualifiedName& attrName = attr->name();
     // NOTE: Any subclass which overrides parseMappedAttribute for a property handled by
     // cssPropertyIdForSVGAttributeName will also have to override mapToEntry to disable the default eSVG mapping
-    int propId = SVGStyledElement::cssPropertyIdForSVGAttributeName(attrName);
+    int propId = SVGStyledElement::cssPropertyIdForSVGAttributeName(attr->name());
     if (propId > 0) {
         addCSSProperty(attr, propId, attr->value());
         setNeedsStyleRecalc();
@@ -311,11 +310,13 @@ void SVGStyledElement::parseMappedAttribute(Attribute* attr)
     // the className here.  svgAttributeChanged actually causes the resulting
     // style updates (instead of StyledElement::parseMappedAttribute). We don't
     // tell StyledElement about the change to avoid parsing the class list twice
-    if (attrName.matches(HTMLNames::classAttr))
+    if (attr->name() == HTMLNames::classAttr) {
         setClassNameBaseValue(attr->value());
-    else
-        // id is handled by StyledElement which SVGElement inherits from
-        SVGElement::parseMappedAttribute(attr);
+        return;
+    }
+
+    // id is handled by StyledElement which SVGElement inherits from
+    SVGElement::parseMappedAttribute(attr);
 }
 
 bool SVGStyledElement::isKnownAttribute(const QualifiedName& attrName)
@@ -325,30 +326,33 @@ bool SVGStyledElement::isKnownAttribute(const QualifiedName& attrName)
 
 void SVGStyledElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    SVGElement::svgAttributeChanged(attrName);
+    int propId = SVGStyledElement::cssPropertyIdForSVGAttributeName(attrName);
+    if (propId > 0) {
+        SVGElementInstance::invalidateAllInstancesOfElement(this);
+        return;
+    }
 
-    if (attrName.matches(HTMLNames::classAttr))
+    if (attrName == HTMLNames::classAttr) {
         classAttributeChanged(className());
-
-    RenderObject* object = renderer();
+        SVGElementInstance::invalidateAllInstancesOfElement(this);
+        return;
+    }
 
     if (isIdAttributeName(attrName)) {
+        RenderObject* object = renderer();
         // Notify resources about id changes, this is important as we cache resources by id in SVGDocumentExtensions
         if (object && object->isSVGResourceContainer())
             object->toRenderSVGResourceContainer()->idChanged();
         if (inDocument())
             buildPendingResourcesIfNeeded();
+        SVGElementInstance::invalidateAllInstancesOfElement(this);
+        return;
     }
-
-    // Invalidate all SVGElementInstances associated with us
-    SVGElementInstance::invalidateAllInstancesOfElement(this);
 }
 
 void SVGStyledElement::synchronizeProperty(const QualifiedName& attrName)
 {
-    SVGElement::synchronizeProperty(attrName);
-
-    if (attrName == anyQName() || attrName.matches(HTMLNames::classAttr))
+    if (attrName == anyQName() || attrName == HTMLNames::classAttr)
         synchronizeClassName();
 }
 
index d349d7c..0fb3443 100644 (file)
@@ -27,6 +27,7 @@
 #include "Attribute.h"
 #include "RenderSVGPath.h"
 #include "RenderSVGResource.h"
+#include "SVGElementInstance.h"
 #include "SVGNames.h"
 
 namespace WebCore {
@@ -69,44 +70,74 @@ AffineTransform* SVGStyledTransformableElement::supplementalTransform()
     return m_supplementalTransform.get();
 }
 
+bool SVGStyledTransformableElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty())
+        supportedAttributes.add(SVGNames::transformAttr);
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGStyledTransformableElement::parseMappedAttribute(Attribute* attr)
 {
-    if (SVGTransformable::isKnownAttribute(attr->name())) {
+    if (!isSupportedAttribute(attr->name())) {
+        SVGStyledLocatableElement::parseMappedAttribute(attr);
+        return;
+    }
+
+    if (attr->name() == SVGNames::transformAttr) {
         SVGTransformList newList;
         if (!SVGTransformable::parseTransformAttribute(newList, attr->value()))
             newList.clear();
         detachAnimatedTransformListWrappers(newList.size());
         setTransformBaseValue(newList);
-    } else 
-        SVGStyledLocatableElement::parseMappedAttribute(attr);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGStyledTransformableElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    SVGStyledLocatableElement::svgAttributeChanged(attrName);
-
-    if (!SVGStyledTransformableElement::isKnownAttribute(attrName))
+    if (!isSupportedAttribute(attrName)) {
+        SVGStyledLocatableElement::svgAttributeChanged(attrName);
         return;
+    }
+
+    SVGElementInstance::InvalidationGuard invalidationGuard(this);
 
     RenderObject* object = renderer();
     if (!object)
         return;
 
-    object->setNeedsTransformUpdate();
-    RenderSVGResource::markForLayoutAndParentResourceInvalidation(object);
+    if (attrName == SVGNames::transformAttr) {
+        object->setNeedsTransformUpdate();
+        RenderSVGResource::markForLayoutAndParentResourceInvalidation(object);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 void SVGStyledTransformableElement::synchronizeProperty(const QualifiedName& attrName)
 {
-    SVGStyledLocatableElement::synchronizeProperty(attrName);
+    if (attrName == anyQName()) {
+        synchronizeTransform();
+        SVGStyledLocatableElement::synchronizeProperty(attrName);
+        return;
+    }
 
-    if (attrName == anyQName() || SVGTransformable::isKnownAttribute(attrName))
+    if (!isSupportedAttribute(attrName)) {
+        SVGStyledLocatableElement::synchronizeProperty(attrName);
+        return;
+    }
+
+    if (attrName == SVGNames::transformAttr) {
         synchronizeTransform();
-}
+        return;
+    }
 
-bool SVGStyledTransformableElement::isKnownAttribute(const QualifiedName& attrName)
-{
-    return SVGTransformable::isKnownAttribute(attrName) || SVGStyledLocatableElement::isKnownAttribute(attrName);
+    ASSERT_NOT_REACHED();
 }
 
 SVGElement* SVGStyledTransformableElement::nearestViewportElement() const
index 9d6834a..454dac1 100644 (file)
@@ -47,8 +47,6 @@ public:
 
     virtual FloatRect getBBox(StyleUpdateStrategy = AllowStyleUpdate) const;
 
-    bool isKnownAttribute(const QualifiedName&);
-
     // "base class" methods for all the elements which render as paths
     virtual void toPathData(Path&) const { }
     virtual void toClipPath(Path&) const;
@@ -57,6 +55,7 @@ public:
 protected:
     SVGStyledTransformableElement(const QualifiedName&, Document*);
 
+    bool isSupportedAttribute(const QualifiedName&);
     virtual void parseMappedAttribute(Attribute*);
     virtual void svgAttributeChanged(const QualifiedName&);
     virtual void synchronizeProperty(const QualifiedName&);
index b658a99..700cc78 100644 (file)
@@ -23,6 +23,7 @@
 #if ENABLE(SVG)
 #include "SVGSymbolElement.h"
 
+#include "SVGElementInstance.h"
 #include "SVGFitToViewBox.h"
 #include "SVGNames.h"
 
@@ -44,8 +45,24 @@ PassRefPtr<SVGSymbolElement> SVGSymbolElement::create(const QualifiedName& tagNa
     return adoptRef(new SVGSymbolElement(tagName, document));
 }
 
+bool SVGSymbolElement::isSupportedAttribute(const QualifiedName& attrName)
+{
+    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
+    if (supportedAttributes.isEmpty()) {
+        SVGLangSpace::addSupportedAttributes(supportedAttributes);
+        SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
+        SVGFitToViewBox::addSupportedAttributes(supportedAttributes);
+    }
+    return supportedAttributes.contains(attrName);
+}
+
 void SVGSymbolElement::parseMappedAttribute(Attribute* attr)
 {
+    if (!isSupportedAttribute(attr->name())) {
+        SVGStyledElement::parseMappedAttribute(attr);
+        return;
+    }
+
     if (SVGLangSpace::parseMappedAttribute(attr))
         return;
     if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
@@ -53,40 +70,48 @@ void SVGSymbolElement::parseMappedAttribute(Attribute* attr)
     if (SVGFitToViewBox::parseMappedAttribute(document(), attr))
         return;
 
-    SVGStyledElement::parseMappedAttribute(attr);
+    ASSERT_NOT_REACHED();
 }
 
 void SVGSymbolElement::svgAttributeChanged(const QualifiedName& attrName)
 {
-    SVGStyledElement::svgAttributeChanged(attrName);
+    if (!isSupportedAttribute(attrName)) {
+        SVGStyledElement::svgAttributeChanged(attrName);
+        return;
+    }
+
+    SVGElementInstance::InvalidationGuard invalidationGuard(this);
 
+    // Every other property change is ignored.
     if (attrName == SVGNames::viewBoxAttr)
         updateRelativeLengthsInformation();
 }
 
 void SVGSymbolElement::synchronizeProperty(const QualifiedName& attrName)
 {
-    SVGStyledElement::synchronizeProperty(attrName);
-
     if (attrName == anyQName()) {
-        synchronizePreserveAspectRatio();
-        synchronizeViewBox();
         synchronizeExternalResourcesRequired();
-        synchronizeViewBox();
-        synchronizePreserveAspectRatio();
+        SVGFitToViewBox::synchronizeProperties(attrName);
+        SVGStyledElement::synchronizeProperty(attrName);
         return;
     }
 
-    if (attrName == SVGNames::preserveAspectRatioAttr)
-        synchronizePreserveAspectRatio();
-    else if (attrName == SVGNames::viewBoxAttr)
-        synchronizeViewBox();
-    else if (SVGExternalResourcesRequired::isKnownAttribute(attrName))
+    if (!isSupportedAttribute(attrName)) {
+        SVGStyledElement::synchronizeProperty(attrName);
+        return;
+    }
+
+    if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) {
         synchronizeExternalResourcesRequired();
-    else if (SVGFitToViewBox::isKnownAttribute(attrName)) {
-        synchronizeViewBox();
-        synchronizePreserveAspectRatio();
-    } 
+        return;
+    }
+
+    if (SVGFitToViewBox::isKnownAttribute(attrName)) {
+        SVGFitToViewBox::synchronizeProperties(attrName);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 AttributeToPropertyTypeMap& SVGSymbolElement::attributeToPropertyTypeMap()