Skip to content
Permalink
Browse files
SVG Animations update baseVal instead of animVal
https://bugs.webkit.org/show_bug.cgi?id=12437

Reviewed by Dirk Schulze.

Source/WebCore:

Cleanup animation code, remove last remaining crufts of the old setAttribute() animation model.
Now only two animation modes remain: animate SVG DOM animVal properties or CSS properties.

Stop caching base values per string in SMILTimeContainer, as it breaks additive="sum" for CSS
properties if the underlying base value is changed from the outside (eg. when calling
style.fontSize="20px", if font-size was 10px, and we're running an additive by-animation with 50px).

This requires us to cache the computed style of a SVGElement, without SMIL style property changes,
in SVGElementRareData, similar to how the computed style itself is cached in ElementRareData.
To be able to compute the base value for a CSS property at any time, we have to exclude any
previous animation effects residing in the SMIL animated style properties, per SMIL2/3 specs.

NOTE: This doesn't change or affect the way CSS Animations/Transitions are applied, we still
      have some bugs in that area, but this patch doesn't address them. The idea is to only
      remove the cache, to pave the way for future additive="sum" patches.

Tests: svg/animations/change-css-property-while-animating-fill-freeze.html
       svg/animations/change-css-property-while-animating-fill-remove.html

* dom/Element.cpp:
(WebCore::Element::recalcStyle):
* dom/Node.h:
* svg/SVGAnimateElement.cpp:
(WebCore::propertyTypesAreConsistent):
(WebCore::SVGAnimateElement::resetToBaseValue):
(WebCore::SVGAnimateElement::applyResultsToTarget):
* svg/SVGAnimateElement.h:
(SVGAnimateElement):
* svg/SVGAnimateMotionElement.cpp:
(WebCore::SVGAnimateMotionElement::resetToBaseValue):
* svg/SVGAnimateMotionElement.h:
(SVGAnimateMotionElement):
* svg/SVGAnimationElement.cpp:
(WebCore::applyCSSPropertyToTarget):
(WebCore::SVGAnimationElement::setTargetAttributeAnimatedCSSValue):
* svg/SVGAnimationElement.h:
* svg/SVGElement.cpp:
(WebCore::SVGElement::SVGElement):
(WebCore::SVGElement::willRecalcStyle):
(WebCore):
(WebCore::SVGElement::rareSVGData):
(WebCore::SVGElement::ensureRareSVGData):
(WebCore::SVGElement::computedStyle):
(WebCore::SVGElement::isAnimatableAttribute):
* svg/SVGElement.h:
(SVGElement):
* svg/SVGElementRareData.h:
(WebCore::SVGElementRareData::SVGElementRareData):
(WebCore::SVGElementRareData::ensureAnimatedSMILStyleProperties):
(WebCore::SVGElementRareData::destroyAnimatedSMILStyleProperties):
(WebCore::SVGElementRareData::overrideComputedStyle):
(WebCore::SVGElementRareData::setUseOverrideComputedStyle):
* svg/animation/SMILTimeContainer.cpp:
(WebCore::SMILTimeContainer::updateAnimations):
* svg/animation/SMILTimeContainer.h:
(SMILTimeContainer):
* svg/animation/SVGSMILElement.h:
(SVGSMILElement):

LayoutTests:

Add tests that change the CSS property while an animation is running, finally fixed now for both SVG DOM & CSS animations.

* svg/animations/change-css-property-while-animating-fill-freeze-expected.txt: Added.
* svg/animations/change-css-property-while-animating-fill-freeze.html: Added.
* svg/animations/change-css-property-while-animating-fill-remove-expected.txt: Added.
* svg/animations/change-css-property-while-animating-fill-remove.html: Added.
* svg/animations/resources/change-css-property-while-animating-fill-freeze.svg: Added.
* svg/animations/resources/change-css-property-while-animating-fill-remove.svg: Added.
* svg/animations/script-tests/change-css-property-while-animating-fill-freeze.js: Added.
(sample1):
(sample2):
(sample3):
(sample4):
(sample5):
(executeTest):
* svg/animations/script-tests/change-css-property-while-animating-fill-remove.js: Added.
(sample1):
(sample2):
(sample3):
(sample4):
(sample5):
(executeTest):

Canonical link: https://commits.webkit.org/102560@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@115423 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
Nikolas Zimmermann committed Apr 27, 2012
1 parent 6b72bd1 commit c09e4412209696292972870ef84a4d204b5dff52
Showing 24 changed files with 395 additions and 100 deletions.
@@ -1,3 +1,33 @@
2012-04-27 Nikolas Zimmermann <nzimmermann@rim.com>

SVG Animations update baseVal instead of animVal
https://bugs.webkit.org/show_bug.cgi?id=12437

Reviewed by Dirk Schulze.

Add tests that change the CSS property while an animation is running, finally fixed now for both SVG DOM & CSS animations.

* svg/animations/change-css-property-while-animating-fill-freeze-expected.txt: Added.
* svg/animations/change-css-property-while-animating-fill-freeze.html: Added.
* svg/animations/change-css-property-while-animating-fill-remove-expected.txt: Added.
* svg/animations/change-css-property-while-animating-fill-remove.html: Added.
* svg/animations/resources/change-css-property-while-animating-fill-freeze.svg: Added.
* svg/animations/resources/change-css-property-while-animating-fill-remove.svg: Added.
* svg/animations/script-tests/change-css-property-while-animating-fill-freeze.js: Added.
(sample1):
(sample2):
(sample3):
(sample4):
(sample5):
(executeTest):
* svg/animations/script-tests/change-css-property-while-animating-fill-remove.js: Added.
(sample1):
(sample2):
(sample3):
(sample4):
(sample5):
(executeTest):

2012-04-27 Philippe Normand <pnormand@igalia.com>

Unreviewed, GTK test_expectations update.
@@ -0,0 +1,18 @@
SVG 1.1 dynamic animation tests


This tests scripting a CSS property while animation is running

On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".


PASS getComputedStyle(rect).getPropertyCSSValue('opacity').getFloatValue(CSSPrimitiveValue.CSS_NUMBER) is 0
PASS getComputedStyle(rect).getPropertyCSSValue('opacity').getFloatValue(CSSPrimitiveValue.CSS_NUMBER) is 0.25
PASS getComputedStyle(rect).getPropertyCSSValue('opacity').getFloatValue(CSSPrimitiveValue.CSS_NUMBER) is 0.25
PASS getComputedStyle(rect).getPropertyCSSValue('opacity').getFloatValue(CSSPrimitiveValue.CSS_NUMBER) is 0.5
PASS getComputedStyle(rect).getPropertyCSSValue('opacity').getFloatValue(CSSPrimitiveValue.CSS_NUMBER) is 0.5
PASS getComputedStyle(rect).getPropertyCSSValue('opacity').getFloatValue(CSSPrimitiveValue.CSS_NUMBER) is 0.5
PASS successfullyParsed is true

TEST COMPLETE

@@ -0,0 +1,14 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<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 onload="runSMILTest()">
<h1>SVG 1.1 dynamic animation tests</h1>
<p id="description"></p>
<div id="console"></div>
<script src="script-tests/change-css-property-while-animating-fill-freeze.js"></script>
</body>
</html>
@@ -0,0 +1,18 @@
SVG 1.1 dynamic animation tests


This tests scripting a CSS property while animation is running

On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".


PASS getComputedStyle(rect).getPropertyCSSValue('opacity').getFloatValue(CSSPrimitiveValue.CSS_NUMBER) is 0
PASS getComputedStyle(rect).getPropertyCSSValue('opacity').getFloatValue(CSSPrimitiveValue.CSS_NUMBER) is 0.25
PASS getComputedStyle(rect).getPropertyCSSValue('opacity').getFloatValue(CSSPrimitiveValue.CSS_NUMBER) is 0.25
PASS getComputedStyle(rect).getPropertyCSSValue('opacity').getFloatValue(CSSPrimitiveValue.CSS_NUMBER) is 0.5
PASS getComputedStyle(rect).getPropertyCSSValue('opacity').getFloatValue(CSSPrimitiveValue.CSS_NUMBER) is 1
PASS getComputedStyle(rect).getPropertyCSSValue('opacity').getFloatValue(CSSPrimitiveValue.CSS_NUMBER) is 1
PASS successfullyParsed is true

TEST COMPLETE

@@ -0,0 +1,14 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<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 onload="runSMILTest()">
<h1>SVG 1.1 dynamic animation tests</h1>
<p id="description"></p>
<div id="console"></div>
<script src="script-tests/change-css-property-while-animating-fill-remove.js"></script>
</body>
</html>
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -0,0 +1,43 @@
description("This tests scripting a CSS property while animation is running");
embedSVGTestCase("resources/change-css-property-while-animating-fill-freeze.svg");

// Setup animation test
function sample1() {
shouldBeCloseEnough("getComputedStyle(rect).getPropertyCSSValue('opacity').getFloatValue(CSSPrimitiveValue.CSS_NUMBER)", "0");
}

function sample2() {
shouldBeCloseEnough("getComputedStyle(rect).getPropertyCSSValue('opacity').getFloatValue(CSSPrimitiveValue.CSS_NUMBER)", "0.25");
rect.setAttribute("opacity", "1");
}

function sample3() {
shouldBeCloseEnough("getComputedStyle(rect).getPropertyCSSValue('opacity').getFloatValue(CSSPrimitiveValue.CSS_NUMBER)", "0.25");
}

function sample4() {
shouldBeCloseEnough("getComputedStyle(rect).getPropertyCSSValue('opacity').getFloatValue(CSSPrimitiveValue.CSS_NUMBER)", "0.5");
}

function sample5() {
shouldBeCloseEnough("getComputedStyle(rect).getPropertyCSSValue('opacity').getFloatValue(CSSPrimitiveValue.CSS_NUMBER)", "0.5");
}

function executeTest() {
rect = rootSVGElement.ownerDocument.getElementsByTagName("rect")[0];

const expectedValues = [
// [animationId, time, sampleCallback]
["an1", 0.0, sample1],
["an1", 2.0, sample2],
["an1", 2.001, sample3],
["an1", 3.999, sample4],
["an1", 4.001, sample5],
["an1", 60.0, sample5]
];

runAnimationTest(expectedValues);
}

window.animationStartsImmediately = true;
var successfullyParsed = true;
@@ -0,0 +1,43 @@
description("This tests scripting a CSS property while animation is running");
embedSVGTestCase("resources/change-css-property-while-animating-fill-remove.svg");

// Setup animation test
function sample1() {
shouldBeCloseEnough("getComputedStyle(rect).getPropertyCSSValue('opacity').getFloatValue(CSSPrimitiveValue.CSS_NUMBER)", "0");
}

function sample2() {
shouldBeCloseEnough("getComputedStyle(rect).getPropertyCSSValue('opacity').getFloatValue(CSSPrimitiveValue.CSS_NUMBER)", "0.25");
rect.setAttribute("opacity", "1");
}

function sample3() {
shouldBeCloseEnough("getComputedStyle(rect).getPropertyCSSValue('opacity').getFloatValue(CSSPrimitiveValue.CSS_NUMBER)", "0.25");
}

function sample4() {
shouldBeCloseEnough("getComputedStyle(rect).getPropertyCSSValue('opacity').getFloatValue(CSSPrimitiveValue.CSS_NUMBER)", "0.5");
}

function sample5() {
shouldBeCloseEnough("getComputedStyle(rect).getPropertyCSSValue('opacity').getFloatValue(CSSPrimitiveValue.CSS_NUMBER)", "1");
}

function executeTest() {
rect = rootSVGElement.ownerDocument.getElementsByTagName("rect")[0];

const expectedValues = [
// [animationId, time, sampleCallback]
["an1", 0.0, sample1],
["an1", 2.0, sample2],
["an1", 2.001, sample3],
["an1", 3.999, sample4],
["an1", 4.001, sample5],
["an1", 60.0, sample5]
];

runAnimationTest(expectedValues);
}

window.animationStartsImmediately = true;
var successfullyParsed = true;
@@ -1,3 +1,69 @@
2012-04-27 Nikolas Zimmermann <nzimmermann@rim.com>

SVG Animations update baseVal instead of animVal
https://bugs.webkit.org/show_bug.cgi?id=12437

Reviewed by Dirk Schulze.

Cleanup animation code, remove last remaining crufts of the old setAttribute() animation model.
Now only two animation modes remain: animate SVG DOM animVal properties or CSS properties.

Stop caching base values per string in SMILTimeContainer, as it breaks additive="sum" for CSS
properties if the underlying base value is changed from the outside (eg. when calling
style.fontSize="20px", if font-size was 10px, and we're running an additive by-animation with 50px).

This requires us to cache the computed style of a SVGElement, without SMIL style property changes,
in SVGElementRareData, similar to how the computed style itself is cached in ElementRareData.
To be able to compute the base value for a CSS property at any time, we have to exclude any
previous animation effects residing in the SMIL animated style properties, per SMIL2/3 specs.

NOTE: This doesn't change or affect the way CSS Animations/Transitions are applied, we still
have some bugs in that area, but this patch doesn't address them. The idea is to only
remove the cache, to pave the way for future additive="sum" patches.

Tests: svg/animations/change-css-property-while-animating-fill-freeze.html
svg/animations/change-css-property-while-animating-fill-remove.html

* dom/Element.cpp:
(WebCore::Element::recalcStyle):
* dom/Node.h:
* svg/SVGAnimateElement.cpp:
(WebCore::propertyTypesAreConsistent):
(WebCore::SVGAnimateElement::resetToBaseValue):
(WebCore::SVGAnimateElement::applyResultsToTarget):
* svg/SVGAnimateElement.h:
(SVGAnimateElement):
* svg/SVGAnimateMotionElement.cpp:
(WebCore::SVGAnimateMotionElement::resetToBaseValue):
* svg/SVGAnimateMotionElement.h:
(SVGAnimateMotionElement):
* svg/SVGAnimationElement.cpp:
(WebCore::applyCSSPropertyToTarget):
(WebCore::SVGAnimationElement::setTargetAttributeAnimatedCSSValue):
* svg/SVGAnimationElement.h:
* svg/SVGElement.cpp:
(WebCore::SVGElement::SVGElement):
(WebCore::SVGElement::willRecalcStyle):
(WebCore):
(WebCore::SVGElement::rareSVGData):
(WebCore::SVGElement::ensureRareSVGData):
(WebCore::SVGElement::computedStyle):
(WebCore::SVGElement::isAnimatableAttribute):
* svg/SVGElement.h:
(SVGElement):
* svg/SVGElementRareData.h:
(WebCore::SVGElementRareData::SVGElementRareData):
(WebCore::SVGElementRareData::ensureAnimatedSMILStyleProperties):
(WebCore::SVGElementRareData::destroyAnimatedSMILStyleProperties):
(WebCore::SVGElementRareData::overrideComputedStyle):
(WebCore::SVGElementRareData::setUseOverrideComputedStyle):
* svg/animation/SMILTimeContainer.cpp:
(WebCore::SMILTimeContainer::updateAnimations):
* svg/animation/SMILTimeContainer.h:
(SMILTimeContainer):
* svg/animation/SVGSMILElement.h:
(SVGSMILElement):

2012-04-26 Alexander Pavlov <apavlov@chromium.org>

Web Inspector: Implement the "Disable JavaScript" option in the settings dialog
@@ -1075,7 +1075,7 @@ void StyleResolver::sortMatchedRules()
std::sort(m_matchedRules.begin(), m_matchedRules.end(), compareRules);
}

void StyleResolver::matchAllRules(MatchResult& result)
void StyleResolver::matchAllRules(MatchResult& result, bool includeSMILProperties)
{
matchUARules(result);

@@ -1115,7 +1115,7 @@ void StyleResolver::matchAllRules(MatchResult& result)

#if ENABLE(SVG)
// Now check SMIL animation override style.
if (m_matchAuthorAndUserStyles && m_styledElement && m_styledElement->isSVGElement())
if (includeSMILProperties && m_matchAuthorAndUserStyles && m_styledElement && m_styledElement->isSVGElement())
addElementStyleProperties(result, static_cast<SVGElement*>(m_styledElement)->animatedSMILStyleProperties(), false /* isCacheable */);
#endif
}
@@ -1623,7 +1623,7 @@ PassRefPtr<RenderStyle> StyleResolver::styleForElement(Element* element, RenderS
if (matchingBehavior == MatchOnlyUserAgentRules)
matchUARules(matchResult);
else
matchAllRules(matchResult);
matchAllRules(matchResult, matchingBehavior != MatchAllRulesExcludingSMIL);

applyMatchedProperties(matchResult);

@@ -114,6 +114,7 @@ enum StyleSharingBehavior {

enum RuleMatchingBehavior {
MatchAllRules,
MatchAllRulesExcludingSMIL,
MatchOnlyUserAgentRules,
};

@@ -336,7 +337,7 @@ class StyleResolver {
static void addMatchedProperties(MatchResult&, StylePropertySet* properties, StyleRule* = 0, unsigned linkMatchType = SelectorChecker::MatchAll, bool inRegionRule = false);
void addElementStyleProperties(MatchResult&, StylePropertySet*, bool isCacheable = true);

void matchAllRules(MatchResult&);
void matchAllRules(MatchResult&, bool includeSMILProperties);
void matchUARules(MatchResult&);
void matchUARules(MatchResult&, RuleSet*);
void matchAuthorRules(MatchResult&, bool includeEmptyRules);

0 comments on commit c09e441

Please sign in to comment.