Commit ff18f34b authored by krit@webkit.org's avatar krit@webkit.org
Browse files

2011-02-15 Dirk Schulze <krit@webkit.org>

        Reviewed by Nikolas Zimmermann.

        SVG animation doesn't support attribute value 'inherit'
        https://bugs.webkit.org/show_bug.cgi?id=54410

        Check support for 'inherit' and 'currentColor' on SVG animations.

        * svg/animations/animate-currentColor-expected.txt: Added.
        * svg/animations/animate-currentColor.html: Added.
        * svg/animations/animate-inherit-css-property-expected.txt: Added.
        * svg/animations/animate-inherit-css-property.html: Added.
        * svg/animations/script-tests/animate-currentColor.js: Added.
        (sample1):
        (sample2):
        (sample3):
        (executeTest):
        * svg/animations/script-tests/animate-inherit-css-property.js: Added.
        (sample1):
        (sample2):
        (sample3):
        (executeTest):
2011-02-15  Dirk Schulze  <krit@webkit.org>

        Reviewed by Nikolas Zimmermann.

        SVG animation doesn't support attribute value 'inherit'
        https://bugs.webkit.org/show_bug.cgi?id=54410

        SVG animation does not support 'inherit' as value for CSS property animations. With the patch, SVG determines
        if the attribute of the target element is an animatable CSS Property and computes the style during the
        animation.

        This fixes the following tests on the W3C test suite:
        * animate-elem-84-t.svg
        * animate-elem-85-t.svg

        Tests: svg/animations/animate-currentColor.html
               svg/animations/animate-inherit-css-property.html

        * svg/SVGAnimateElement.cpp:
        (WebCore::adjustForCurrentColor):
        (WebCore::adjustForInheritance):
        (WebCore::SVGAnimateElement::calculateAnimatedValue): When a property value is 'inherit' or 'currentColor'
        during the animation, get the computed style of the property since the values could be animated themselves.
        (WebCore::inheritsFromProperty):
        (WebCore::attributeValueIsCurrentColor):
        (WebCore::SVGAnimateElement::calculateFromAndToValues): Check if 'from', 'by' or 'to' value has the
        string 'inherit' or 'currentColor' and if the attribute supports one of these values.
        (WebCore::SVGAnimateElement::calculateFromAndByValues): Ditto.
        * svg/SVGAnimateElement.h:
        * svg/SVGAnimationElement.cpp:
        (WebCore::SVGAnimationElement::isTargetAttributeCSSProperty): Check if target element is stylable and
        the attribute is an animatable CSS property by using the CSS property map in SVGStyledElement.
        (WebCore::SVGAnimationElement::setTargetAttributeAnimatedValue): s/target/targetElement/ for consistency.
        * svg/SVGAnimationElement.h:
        * svg/SVGStyledElement.cpp: 
        (WebCore::SVGStyledElement::isAnimatableCSSProperty): Checks if the CSS property is animatable.
        * svg/SVGStyledElement.h:
        * svg/animation/SMILTimeContainer.cpp: Use the new function isTargetAttributeCSSProperty to determine
        if the target element is stylable and the attribute is an animatable CSS property.
        (WebCore::SMILTimeContainer::baseValueFor):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@78543 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent f7452e9d
2011-02-15 Dirk Schulze <krit@webkit.org>
Reviewed by Nikolas Zimmermann.
SVG animation doesn't support attribute value 'inherit'
https://bugs.webkit.org/show_bug.cgi?id=54410
Check support for 'inherit' and 'currentColor' on SVG animations.
* svg/animations/animate-currentColor-expected.txt: Added.
* svg/animations/animate-currentColor.html: Added.
* svg/animations/animate-inherit-css-property-expected.txt: Added.
* svg/animations/animate-inherit-css-property.html: Added.
* svg/animations/script-tests/animate-currentColor.js: Added.
(sample1):
(sample2):
(sample3):
(executeTest):
* svg/animations/script-tests/animate-inherit-css-property.js: Added.
(sample1):
(sample2):
(sample3):
(executeTest):
2011-02-15 Pavel Feldman <pfeldman@chromium.org>
 
Not reviewed: inspector tests expectations update.
SVG 1.1 dynamic animation tests
Tests animation on 'currentColor'.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
PASS rect.style.fill is '#FF0000'
PASS rect.style.fill is '#804000'
PASS rect.style.fill is '#008000'
PASS successfullyParsed is true
TEST COMPLETE
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<link rel="stylesheet" href="../../fast/js/resources/js-test-style.css">
<script src="../../fast/js/resources/js-test-pre.js"></script>
<script src="../dynamic-updates/resources/SVGTestCase.js"></script>
<script src="resources/SVGAnimationTestCase.js"></script>
</head>
<body>
<h1>SVG 1.1 dynamic animation tests</h1>
<p id="description"></p>
<div id="console"></div>
<script src="script-tests/animate-currentColor.js"></script>
</body>
</html>
SVG 1.1 dynamic animation tests
Tests animation with 'inherit'.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
PASS rect.style.fill is '#FF0000'
PASS rect.style.fill is '#804000'
PASS rect.style.fill is '#008000'
PASS successfullyParsed is true
TEST COMPLETE
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<link rel="stylesheet" href="../../fast/js/resources/js-test-style.css">
<script src="../../fast/js/resources/js-test-pre.js"></script>
<script src="../dynamic-updates/resources/SVGTestCase.js"></script>
<script src="resources/SVGAnimationTestCase.js"></script>
</head>
<body>
<h1>SVG 1.1 dynamic animation tests</h1>
<p id="description"></p>
<div id="console"></div>
<script src="script-tests/animate-inherit-css-property.js"></script>
</body>
</html>
description("Tests animation on 'currentColor'.");
createSVGTestCase();
// Setup test document
var rect = createSVGElement("rect");
rect.setAttribute("id", "rect");
rect.setAttribute("width", "100px");
rect.setAttribute("height", "100px");
rect.setAttribute("fill", "red");
rect.setAttribute("color", "green");
var animateCurrentColor = createSVGElement("animateColor");
animateCurrentColor.setAttribute("id", "animateCurrentColor");
animateCurrentColor.setAttribute("attributeName", "fill");
animateCurrentColor.setAttribute("from", "red");
animateCurrentColor.setAttribute("to", "currentColor");
animateCurrentColor.setAttribute("dur", "3s");
animateCurrentColor.setAttribute("begin", "click");
animateCurrentColor.setAttribute("fill", "freeze");
rect.appendChild(animateCurrentColor);
rootSVGElement.appendChild(rect);
// Setup animation test
function sample1() {
// Check initial/end conditions
shouldBe("rect.style.fill", "'#FF0000'");
}
function sample2() {
// Check half-time conditions
shouldBe("rect.style.fill", "'#804000'");
}
function sample3() {
// Check half-time conditions
shouldBe("rect.style.fill", "'#008000'");
}
function executeTest() {
const expectedValues = [
// [animationId, time, elementId, sampleCallback]
["animateCurrentColor", 0.0, "rect", sample1],
["animateCurrentColor", 1.5, "rect", sample2],
["animateCurrentColor", 3.0, "rect", sample3]
];
runAnimationTest(expectedValues);
}
// Begin test async
rect.setAttribute("onclick", "executeTest()");
window.setTimeout("triggerUpdate(50, 50)", 0);
var successfullyParsed = true;
description("Tests animation with 'inherit'.");
createSVGTestCase();
// Setup test document
var g = createSVGElement("g");
g.setAttribute("fill", "green");
var rect = createSVGElement("rect");
rect.setAttribute("id", "rect");
rect.setAttribute("width", "100px");
rect.setAttribute("height", "100px");
rect.setAttribute("fill", "red");
g.appendChild(rect);
var animateInherit = createSVGElement("animateColor");
animateInherit.setAttribute("id", "animateInherit");
animateInherit.setAttribute("attributeName", "fill");
animateInherit.setAttribute("from", "red");
animateInherit.setAttribute("to", "inherit");
animateInherit.setAttribute("dur", "3s");
animateInherit.setAttribute("begin", "click");
animateInherit.setAttribute("fill", "freeze");
rect.appendChild(animateInherit);
rootSVGElement.appendChild(g);
// Setup animation test
function sample1() {
// Check initial/end conditions
shouldBe("rect.style.fill", "'#FF0000'");
}
function sample2() {
// Check half-time conditions
shouldBe("rect.style.fill", "'#804000'");
}
function sample3() {
// Check half-time conditions
shouldBe("rect.style.fill", "'#008000'");
}
function executeTest() {
const expectedValues = [
// [animationId, time, elementId, sampleCallback]
["animateInherit", 0.0, "rect", sample1],
["animateInherit", 1.5, "rect", sample2],
["animateInherit", 3.0, "rect", sample3]
];
runAnimationTest(expectedValues);
}
// Begin test async
rect.setAttribute("onclick", "executeTest()");
window.setTimeout("triggerUpdate(50, 50)", 0);
var successfullyParsed = true;
2011-02-15 Dirk Schulze <krit@webkit.org>
Reviewed by Nikolas Zimmermann.
SVG animation doesn't support attribute value 'inherit'
https://bugs.webkit.org/show_bug.cgi?id=54410
SVG animation does not support 'inherit' as value for CSS property animations. With the patch, SVG determines
if the attribute of the target element is an animatable CSS Property and computes the style during the
animation.
This fixes the following tests on the W3C test suite:
* animate-elem-84-t.svg
* animate-elem-85-t.svg
Tests: svg/animations/animate-currentColor.html
svg/animations/animate-inherit-css-property.html
* svg/SVGAnimateElement.cpp:
(WebCore::adjustForCurrentColor):
(WebCore::adjustForInheritance):
(WebCore::SVGAnimateElement::calculateAnimatedValue): When a property value is 'inherit' or 'currentColor'
during the animation, get the computed style of the property since the values could be animated themselves.
(WebCore::inheritsFromProperty):
(WebCore::attributeValueIsCurrentColor):
(WebCore::SVGAnimateElement::calculateFromAndToValues): Check if 'from', 'by' or 'to' value has the
string 'inherit' or 'currentColor' and if the attribute supports one of these values.
(WebCore::SVGAnimateElement::calculateFromAndByValues): Ditto.
* svg/SVGAnimateElement.h:
* svg/SVGAnimationElement.cpp:
(WebCore::SVGAnimationElement::isTargetAttributeCSSProperty): Check if target element is stylable and
the attribute is an animatable CSS property by using the CSS property map in SVGStyledElement.
(WebCore::SVGAnimationElement::setTargetAttributeAnimatedValue): s/target/targetElement/ for consistency.
* svg/SVGAnimationElement.h:
* svg/SVGStyledElement.cpp:
(WebCore::SVGStyledElement::isAnimatableCSSProperty): Checks if the CSS property is animatable.
* svg/SVGStyledElement.h:
* svg/animation/SMILTimeContainer.cpp: Use the new function isTargetAttributeCSSProperty to determine
if the target element is stylable and the attribute is an animatable CSS property.
(WebCore::SMILTimeContainer::baseValueFor):
2011-02-15 Antti Koivisto <antti@apple.com>
 
Reviewed by Andreas Kling.
......@@ -24,6 +24,8 @@
#if ENABLE(SVG) && ENABLE(SVG_ANIMATION)
#include "SVGAnimateElement.h"
#include "CSSComputedStyleDeclaration.h"
#include "CSSParser.h"
#include "CSSPropertyNames.h"
#include "ColorDistance.h"
#include "FloatConversion.h"
......@@ -35,6 +37,7 @@
#include "SVGPathParserFactory.h"
#include "SVGPathSegList.h"
#include "SVGPointList.h"
#include "SVGStyledElement.h"
using namespace std;
......@@ -85,15 +88,29 @@ static bool parseNumberValueAndUnit(const String& in, double& value, String& uni
return ok;
}
static inline bool adjustForCurrentColor(Color& color, const String& value, SVGElement* target)
static inline void adjustForCurrentColor(SVGElement* targetElement, Color& color)
{
if (!target || !target->isStyled() || value != "currentColor")
return false;
ASSERT(targetElement);
if (RenderObject* targetRenderer = target->renderer())
if (RenderObject* targetRenderer = targetElement->renderer())
color = targetRenderer->style()->visitedDependentColor(CSSPropertyColor);
else
color = Color();
}
return true;
static inline void adjustForInheritance(SVGElement* targetElement, const String& attributeName, String& value)
{
// FIXME: At the moment the computed style gets returned as a String and needs to get parsed again.
// In the future we might want to work with the value type directly to avoid the String parsing.
ASSERT(targetElement);
Element* parent = targetElement->parentElement();
if (!parent || !parent->isSVGElement())
return;
SVGElement* svgParent = static_cast<SVGElement*>(parent);
if (svgParent->isStyled())
value = computedStyle(svgParent)->getPropertyValue(cssPropertyID(attributeName));
}
SVGAnimateElement::PropertyType SVGAnimateElement::determinePropertyType(const String& attribute) const
......@@ -115,13 +132,21 @@ SVGAnimateElement::PropertyType SVGAnimateElement::determinePropertyType(const S
void SVGAnimateElement::calculateAnimatedValue(float percentage, unsigned repeat, SVGSMILElement* resultElement)
{
ASSERT(percentage >= 0.f && percentage <= 1.f);
ASSERT(percentage >= 0 && percentage <= 1);
ASSERT(resultElement);
bool isInFirstHalfOfAnimation = percentage < 0.5;
bool isInFirstHalfOfAnimation = percentage < 0.5f;
AnimationMode animationMode = this->animationMode();
SVGElement* targetElement = 0;
// Avoid targetElement() call if possible. It might slow down animations.
if (m_fromPropertyValueType == InheritValue || m_toPropertyValueType == InheritValue
|| m_fromPropertyValueType == CurrentColorValue || m_toPropertyValueType == CurrentColorValue) {
targetElement = this->targetElement();
if (!targetElement)
return;
}
if (hasTagName(SVGNames::setTag))
percentage = 1.f;
percentage = 1;
if (!resultElement->hasTagName(SVGNames::animateTag) && !resultElement->hasTagName(SVGNames::animateColorTag)
&& !resultElement->hasTagName(SVGNames::setTag))
return;
......@@ -134,6 +159,20 @@ void SVGAnimateElement::calculateAnimatedValue(float percentage, unsigned repeat
if (animationMode == ToAnimation)
m_fromNumber = results->m_animatedNumber;
// Replace 'currentColor' / 'inherit' by their computed property values.
if (m_fromPropertyValueType == InheritValue) {
String fromNumberString;
adjustForInheritance(targetElement, attributeName(), fromNumberString);
if (!parseNumberValueAndUnit(fromNumberString, m_fromNumber, m_numberUnit))
return;
}
if (m_toPropertyValueType == InheritValue) {
String toNumberString;
adjustForInheritance(targetElement, attributeName(), toNumberString);
if (!parseNumberValueAndUnit(toNumberString, m_toNumber, m_numberUnit))
return;
}
double number;
if (calcMode() == CalcModeDiscrete)
number = isInFirstHalfOfAnimation ? m_fromNumber : m_toNumber;
......@@ -152,6 +191,23 @@ void SVGAnimateElement::calculateAnimatedValue(float percentage, unsigned repeat
if (m_propertyType == ColorProperty) {
if (animationMode == ToAnimation)
m_fromColor = results->m_animatedColor;
// Replace 'currentColor' / 'inherit' by their computed property values.
if (m_fromPropertyValueType == CurrentColorValue)
adjustForCurrentColor(targetElement, m_fromColor);
else if (m_fromPropertyValueType == InheritValue) {
String fromColorString;
adjustForInheritance(targetElement, attributeName(), fromColorString);
m_fromColor = SVGColor::colorFromRGBColorString(fromColorString);
}
if (m_toPropertyValueType == CurrentColorValue)
adjustForCurrentColor(targetElement, m_toColor);
else if (m_toPropertyValueType == InheritValue) {
String toColorString;
adjustForInheritance(targetElement, attributeName(), toColorString);
m_toColor = SVGColor::colorFromRGBColorString(toColorString);
}
Color color;
if (calcMode() == CalcModeDiscrete)
color = isInFirstHalfOfAnimation ? m_fromColor : m_toColor;
......@@ -216,7 +272,13 @@ void SVGAnimateElement::calculateAnimatedValue(float percentage, unsigned repeat
return;
}
ASSERT(animationMode == FromToAnimation || animationMode == ToAnimation || animationMode == ValuesAnimation);
if ((animationMode == FromToAnimation && percentage > 0.5f) || animationMode == ToAnimation || percentage == 1.0f)
// Replace 'currentColor' / 'inherit' by their computed property values.
if (m_fromPropertyValueType == InheritValue)
adjustForInheritance(targetElement, attributeName(), m_fromString);
if (m_toPropertyValueType == InheritValue)
adjustForInheritance(targetElement, attributeName(), m_toString);
if ((animationMode == FromToAnimation && percentage > 0.5f) || animationMode == ToAnimation || percentage == 1)
results->m_animatedString = m_toString;
else
results->m_animatedString = m_fromString;
......@@ -224,17 +286,45 @@ void SVGAnimateElement::calculateAnimatedValue(float percentage, unsigned repeat
results->m_propertyType = StringProperty;
}
static bool inheritsFromProperty(SVGElement* targetElement, const String& attributeName, const String& value)
{
ASSERT(targetElement);
DEFINE_STATIC_LOCAL(const AtomicString, inherit, ("inherit"));
if (value.isEmpty() || value != inherit || !targetElement->isStyled())
return false;
return SVGStyledElement::isAnimatableCSSProperty(QualifiedName(nullAtom, attributeName, nullAtom));
}
static bool attributeValueIsCurrentColor(const String& value)
{
DEFINE_STATIC_LOCAL(const AtomicString, currentColor, ("currentColor"));
return value == currentColor;
}
bool SVGAnimateElement::calculateFromAndToValues(const String& fromString, const String& toString)
{
SVGElement* targetElement = this->targetElement();
if (!targetElement)
return false;
m_fromPropertyValueType = inheritsFromProperty(targetElement, attributeName(), fromString) ? InheritValue : CurrentColorValue;
m_toPropertyValueType = inheritsFromProperty(targetElement, attributeName(), toString) ? InheritValue : CurrentColorValue;
// FIXME: Needs more solid way determine target attribute type.
m_propertyType = determinePropertyType(attributeName());
if (m_propertyType == ColorProperty) {
SVGElement* targetElement = this->targetElement();
if (!adjustForCurrentColor(m_fromColor, fromString, targetElement))
bool fromIsCurrentColor = attributeValueIsCurrentColor(fromString);
bool toIsCurrentColor = attributeValueIsCurrentColor(toString);
if (fromIsCurrentColor)
m_fromPropertyValueType = CurrentColorValue;
else
m_fromColor = SVGColor::colorFromRGBColorString(fromString);
if (!adjustForCurrentColor(m_toColor, toString, targetElement))
if (toIsCurrentColor)
m_toPropertyValueType = CurrentColorValue;
else
m_toColor = SVGColor::colorFromRGBColorString(toString);
if ((m_fromColor.isValid() && m_toColor.isValid()) || (m_toColor.isValid() && animationMode() == ToAnimation))
if (((m_fromColor.isValid() || fromIsCurrentColor) && (m_toColor.isValid() || toIsCurrentColor))
|| ((m_toColor.isValid() || toIsCurrentColor) && animationMode() == ToAnimation))
return true;
} else if (m_propertyType == NumberProperty) {
m_numberUnit = String();
......@@ -268,16 +358,28 @@ bool SVGAnimateElement::calculateFromAndToValues(const String& fromString, const
bool SVGAnimateElement::calculateFromAndByValues(const String& fromString, const String& byString)
{
SVGElement* targetElement = this->targetElement();
if (!targetElement)
return false;
m_fromPropertyValueType = inheritsFromProperty(targetElement, attributeName(), fromString) ? InheritValue : CurrentColorValue;
m_toPropertyValueType = inheritsFromProperty(targetElement, attributeName(), byString) ? InheritValue : CurrentColorValue;
ASSERT(!hasTagName(SVGNames::setTag));
m_propertyType = determinePropertyType(attributeName());
if (m_propertyType == ColorProperty) {
SVGElement* targetElement = this->targetElement();
if (!adjustForCurrentColor(m_fromColor, fromString, targetElement))
m_fromColor = fromString.isEmpty() ? Color() : SVGColor::colorFromRGBColorString(fromString);
if (!adjustForCurrentColor(m_toColor, byString, targetElement))
bool fromIsCurrentColor = attributeValueIsCurrentColor(fromString);
bool byIsCurrentColor = attributeValueIsCurrentColor(byString);
if (fromIsCurrentColor)
m_fromPropertyValueType = CurrentColorValue;
else
m_fromColor = SVGColor::colorFromRGBColorString(fromString);
if (byIsCurrentColor)
m_toPropertyValueType = CurrentColorValue;
else
m_toColor = SVGColor::colorFromRGBColorString(byString);
m_toColor = ColorDistance::addColorsAndClamp(m_fromColor, m_toColor);
if (!m_fromColor.isValid() || !m_toColor.isValid())
if ((!m_fromColor.isValid() && !fromIsCurrentColor)
|| (!m_toColor.isValid() && !byIsCurrentColor))
return false;
} else {
m_numberUnit = String();
......
......@@ -51,10 +51,19 @@ protected:
virtual float calculateDistance(const String& fromString, const String& toString);
private:
// If we have 'currentColor' or 'inherit' as animation value, we need to grab the value during the animation
// since the value can be animated itself.
enum AnimatedPropertyValueType {
RegularPropertyValue,
CurrentColorValue,
InheritValue
};
enum PropertyType { NumberProperty, ColorProperty, StringProperty, PathProperty, PointsProperty };
PropertyType determinePropertyType(const String& attribute) const;
PropertyType m_propertyType;
AnimatedPropertyValueType m_fromPropertyValueType;
AnimatedPropertyValueType m_toPropertyValueType;
double m_fromNumber;
double m_toNumber;
double m_animatedNumber;
......
......@@ -41,6 +41,7 @@
#include "SVGElementInstance.h"
#include "SVGNames.h"
#include "SVGParserUtilities.h"
#include "SVGStyledElement.h"
#include "SVGURIReference.h"
#include "SVGUseElement.h"
#include "XLinkNames.h"
......@@ -293,67 +294,56 @@ bool SVGAnimationElement::hasValidTarget() const
{
return targetElement();
}
bool SVGAnimationElement::attributeIsCSS(const String& attributeName)
{
// FIXME: We should have a map of all SVG properties and their attribute types so we
// could validate animations better. The spec is very vague about this.
unsigned id = cssPropertyID(attributeName);
// SVG range
if (id >= CSSPropertyClipPath && id <= CSSPropertyWritingMode)
return true;
// Regular CSS properties also in SVG
return id == CSSPropertyColor || id == CSSPropertyDisplay || id == CSSPropertyOpacity
|| (id >= CSSPropertyFont && id <= CSSPropertyFontWeight)
|| id == CSSPropertyOverflow || id == CSSPropertyVisibility;
}
bool SVGAnimationElement::targetAttributeIsCSS() const
bool SVGAnimationElement::isTargetAttributeCSSProperty(SVGElement* targetElement, const String& attributeName)
{
AttributeType type = attributeType();
if (type == AttributeTypeCSS)
return true;
if (type == AttributeTypeXML)
ASSERT(targetElement);
if (!targetElement->isStyled())
return false;
return attributeIsCSS(attributeName());
return SVGStyledElement::isAnimatableCSSProperty(QualifiedName(nullAtom, attributeName, nullAtom));
}
void SVGAnimationElement::setTargetAttributeAnimatedValue(const String& value)
{
if (!hasValidTarget())
return;
SVGElement* target = targetElement();
SVGElement* targetElement = this->targetElement();
String attributeName = this->attributeName();
if (!target || attributeName.isEmpty() || value.isNull())
if (!targetElement || attributeName.isEmpty() || value.isNull())
return;
// We don't want the instance tree to get rebuild. Instances are updated in the loop below.
if (target->isStyled())
static_cast<SVGStyledElement*>(target)->setInstanceUpdatesBlocked(true);
if (targetElement->isStyled())
static_cast<SVGStyledElement*>(targetElement)->setInstanceUpdatesBlocked(true);
bool attributeIsCSSProperty = isTargetAttributeCSSProperty(targetElement, attributeName);
// Stop animation, if attributeType is set to CSS by the user, but the attribute itself is not a CSS property.
if (!attributeIsCSSProperty && attributeType() == AttributeTypeCSS)
return;
ExceptionCode ec;
bool isCSS = targetAttributeIsCSS();
if (isCSS) {
if (attributeIsCSSProperty) {
// FIXME: This should set the override style, not the inline style.
// Sadly override styles are not yet implemented.
target->style()->setProperty(attributeName, value, "", ec);
targetElement->style()->setProperty(attributeName, value, "", ec);
} else {
// FIXME: This should set the 'presentation' value, not the actual
// attribute value. Whatever that means in practice.
target->setAttribute(attributeName, value, ec);
targetElement->setAttribute(attributeName, value, ec);
}
if (target->isStyled())
static_cast<SVGStyledElement*>(target)->setInstanceUpdatesBlocked(false);
if (targetElement->isStyled())
static_cast<SVGStyledElement*>(targetElement)->setInstanceUpdatesBlocked(false);
// If the target element is used in an <use> instance tree, update that as well.
const HashSet<SVGElementInstance*>& instances = target->instancesForElement();
const HashSet<SVGElementInstance*>& instances = targetElement->instancesForElement();
const HashSet<SVGElementInstance*>::const_iterator end = instances.end();
for (HashSet<SVGElementInstance*>::const_iterator it = instances.begin(); it != end; ++it) {
SVGElement* shadowTreeElement = (*it)->shadowTreeElement();
if (!shadowTreeElement)
continue;
if (isCSS)
if (attributeIsCSSProperty)
shadowTreeElement->style()->setProperty(attributeName, value, "", ec);
else
shadowTreeElement->setAttribute(attributeName, value, ec);
......