[SCM] WebKit Debian packaging branch, webkit-1.2, updated. upstream/1.1.90-6072-g9a69373

zimmermann at webkit.org zimmermann at webkit.org
Thu Apr 8 00:09:54 UTC 2010


The following commit has been merged in the webkit-1.2 branch:
commit 840d1766e5204e2a8fd058c32b5bedb2fc6489c7
Author: zimmermann at webkit.org <zimmermann at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Wed Dec 2 00:41:29 2009 +0000

    2009-12-01  Nikolas Zimmermann  <nzimmermann at rim.com>
    
            Reviewed by Simon Fraser.
    
            Add SVG animation test framework with 'snapshot' functionality
            https://bugs.webkit.org/show_bug.cgi?id=31897
    
            Add API used by the new 'sampleSVGAnimationForElementAtTime' DRT method,
            forwarding the call to SVGDocumentExtensions, if SVG is enabled.
    
            Implemented just like the existing pauseAnimation* methods for CSS animations.
    
            * Api/qwebframe.cpp:
            (qt_drt_pauseSVGAnimation):
    2009-12-01  Nikolas Zimmermann  <nzimmermann at rim.com>
    
            Reviewed by Simon Fraser.
    
            Add SVG animation test framework with 'snapshot' functionality
            https://bugs.webkit.org/show_bug.cgi?id=31897
    
            Add API used by the new 'sampleSVGAnimationForElementAtTime' DRT method,
            forwarding the call to SVGDocumentExtensions, if SVG is enabled.
    
            Implemented just like the existing pauseAnimation* methods for CSS animations.
    
            * webkit/webkitprivate.h:
            * webkit/webkitwebframe.cpp:
            (webkit_web_frame_pause_svg_animation):
    2009-12-01  Nikolas Zimmermann  <nzimmermann at rim.com>
    
            Reviewed by Simon Fraser.
    
            Add SVG animation test framework with 'snapshot' functionality
            https://bugs.webkit.org/show_bug.cgi?id=31897
    
            Add API used by the new 'sampleSVGAnimationForElementAtTime' DRT method,
            forwarding the call to SVGDocumentExtensions, if SVG is enabled.
    
            Implemented just like the existing pauseAnimation* methods for CSS animations.
    
            * Interfaces/IWebFramePrivate.idl:
            * WebFrame.cpp:
            (WebFrame::pauseSVGAnimation):
            * WebFrame.h:
    2009-12-01  Nikolas Zimmermann  <nzimmermann at rim.com>
    
            Reviewed by Simon Fraser.
    
            Add SVG animation test framework with 'snapshot' functionality
            https://bugs.webkit.org/show_bug.cgi?id=31897
    
            Add API used by the new 'sampleSVGAnimationForElementAtTime' DRT method,
            forwarding the call to SVGDocumentExtensions, if SVG is enabled.
    
            Implemented just like the existing pauseAnimation* methods for CSS animations.
    
            * WebView/WebFrame.mm:
            (-[WebFrame _pauseSVGAnimation:onSMILNode:atTime:]):
            * WebView/WebFramePrivate.h:
    2009-12-01  Nikolas Zimmermann  <nzimmermann at rim.com>
    
            Reviewed by Simon Fraser.
    
            Add SVG animation test framework with 'snapshot' functionality
            https://bugs.webkit.org/show_bug.cgi?id=31897
    
            Add 'sampleSVGAnimationForElementAtTime' method to the LayoutTestController,
            for the use within the new SVG animation test framework (LayoutTests/svg/animations/)
    
            layoutTestController.sampleAnimationAtTime(<svg animation id>, <absolute time>, <svg element id>);
            to sample a svg animateMotion/animateColor/animate/set element at certain times.
    
            After the desired SVG animation starts and calling the method above, it's immediately forwarded to
            the desired sampling time. After JS returns from the 'sampleSVGAnimationForElementAtTime' method
            a callback is fired used to sample the animation value at the target time. It's modelled similar
            to the CSS animation/transition testing framework, inspired by
            LayoutTests/animations/animation-test-helpers.js.
    
            Though it has been extended to integrate within the fast/js/js-test-* framework, that's used for
            the SVG dynamic-updates tests, to simplify test creation, by utilizing script-tests/* only.
    
            Adding a simple testcase testing the DRT methods, it will soon be extended to test animVal/baseVal
            interaction, while animating.
    
            Test: svg/animations/animVal-basics.html
    
            * WebCore.base.exp:
            * WebCore.xcodeproj/project.pbxproj:
            * svg/SVGDocumentExtensions.cpp:
            (WebCore::SVGDocumentExtensions::sampleAnimationAtTime):
            * svg/SVGDocumentExtensions.h:
            * svg/animation/SMILTimeContainer.cpp:
            (WebCore::SMILTimeContainer::SMILTimeContainer):
            (WebCore::SMILTimeContainer::sampleAnimationAtTime):
            (WebCore::SMILTimeContainer::updateAnimations):
            * svg/animation/SMILTimeContainer.h:
    2009-12-01  Nikolas Zimmermann  <nzimmermann at rim.com>
    
            Reviewed by Simon Fraser.
    
            Add SVG animation test framework with 'snapshot' functionality
            https://bugs.webkit.org/show_bug.cgi?id=31897
    
            Add LayoutTests/svg/animations directory, containing a new
            framework for SVG animation test with sampling at certain times.
    
            Added one example test, which will be extended soon to cover animVal
            support, once basic support has been implemented.
    
            * svg/animations: Added.
            * svg/animations/animVal-basics-expected.txt: Added.
            * svg/animations/animVal-basics.html: Added.
            * svg/animations/resources: Added.
            * svg/animations/resources/SVGAnimationTestCase.js: Added.
            (isCloseEnough):
            (moveAnimationTimelineAndSample):
            (startTest):
            (sampleAnimation):
            (runAnimationTest):
            * svg/animations/script-tests: Added.
            * svg/animations/script-tests/TEMPLATE.html: Added.
            * svg/animations/script-tests/animVal-basics.js: Added.
            (sample1):
            (sample2):
            (sample3):
            (executeTest):
    2009-12-01  Nikolas Zimmermann  <nzimmermann at rim.com>
    
            Reviewed by Simon Fraser.
    
            Add SVG animation test framework with 'snapshot' functionality
            https://bugs.webkit.org/show_bug.cgi?id=31897
    
            Add new 'sampleSVGAnimationForElementAtTime' DRT method,
            used by the new SVG animation testing framework, implemented
            for qt/gtk/win/mac.
    
            * DumpRenderTree/LayoutTestController.cpp:
            (sampleSVGAnimationForElementAtTimeCallback):
            (LayoutTestController::staticFunctions):
            * DumpRenderTree/LayoutTestController.h:
            * DumpRenderTree/gtk/LayoutTestControllerGtk.cpp:
            (LayoutTestController::sampleSVGAnimationForElementAtTime):
            * DumpRenderTree/mac/LayoutTestControllerMac.mm:
            (LayoutTestController::sampleSVGAnimationForElementAtTime):
            * DumpRenderTree/qt/LayoutTestControllerQt.cpp:
            (LayoutTestController::sampleSVGAnimationForElementAtTime):
            * DumpRenderTree/qt/LayoutTestControllerQt.h:
            * DumpRenderTree/win/LayoutTestControllerWin.cpp:
            (LayoutTestController::sampleSVGAnimationForElementAtTime):
            * DumpRenderTree/wx/LayoutTestControllerWx.cpp:
            (LayoutTestController::sampleSVGAnimationForElementAtTime):
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@51567 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index e4c506f..18d8bd9 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,34 @@
+2009-12-01  Nikolas Zimmermann  <nzimmermann at rim.com>
+
+        Reviewed by Simon Fraser.
+
+        Add SVG animation test framework with 'snapshot' functionality
+        https://bugs.webkit.org/show_bug.cgi?id=31897
+
+        Add LayoutTests/svg/animations directory, containing a new
+        framework for SVG animation test with sampling at certain times.
+
+        Added one example test, which will be extended soon to cover animVal
+        support, once basic support has been implemented.
+
+        * svg/animations: Added.
+        * svg/animations/animVal-basics-expected.txt: Added.
+        * svg/animations/animVal-basics.html: Added.
+        * svg/animations/resources: Added.
+        * svg/animations/resources/SVGAnimationTestCase.js: Added.
+        (isCloseEnough):
+        (moveAnimationTimelineAndSample):
+        (startTest):
+        (sampleAnimation):
+        (runAnimationTest):
+        * svg/animations/script-tests: Added.
+        * svg/animations/script-tests/TEMPLATE.html: Added.
+        * svg/animations/script-tests/animVal-basics.js: Added.
+        (sample1):
+        (sample2):
+        (sample3):
+        (executeTest):
+
 2009-12-01  Adam Roben  <aroben at apple.com>
 
         Skip more tests that fail with specific versions of CFNetwork on
diff --git a/LayoutTests/svg/animations/animVal-basics-expected.txt b/LayoutTests/svg/animations/animVal-basics-expected.txt
new file mode 100644
index 0000000..dc7b0a1
--- /dev/null
+++ b/LayoutTests/svg/animations/animVal-basics-expected.txt
@@ -0,0 +1,19 @@
+SVG 1.1 dynamic animation tests
+
+Trivial animVal testcase, to see wheter we support it at all. Should result in a 200x200 rect and only PASS messages
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS rect.width.animVal.value is 200
+PASS rect.width.baseVal.value is 200
+PASS rect.width.animVal.value is 150
+PASS rect.width.baseVal.value is 150
+PASS rect.width.animVal.value is almost 100, just before-end
+PASS rect.width.baseVal.value is almost 100, just before-end
+PASS rect.width.animVal.value is 200
+PASS rect.width.baseVal.value is 200
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/svg/animations/animVal-basics.html b/LayoutTests/svg/animations/animVal-basics.html
new file mode 100644
index 0000000..a54bfb8
--- /dev/null
+++ b/LayoutTests/svg/animations/animVal-basics.html
@@ -0,0 +1,15 @@
+<!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/animVal-basics.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/svg/animations/resources/SVGAnimationTestCase.js b/LayoutTests/svg/animations/resources/SVGAnimationTestCase.js
new file mode 100644
index 0000000..258f480
--- /dev/null
+++ b/LayoutTests/svg/animations/resources/SVGAnimationTestCase.js
@@ -0,0 +1,78 @@
+// Inspired by Layoutests/animations/animation-test-helpers.js
+// Modified to work with SVG and together with LayoutTests/svg/dynamic-updates/resources/SVGTestCase.js
+
+function isCloseEnough(actual, desired, tolerance)
+{
+    var diff = Math.abs(actual - desired);
+    return diff <= tolerance;
+}
+
+function moveAnimationTimelineAndSample(index)
+{
+    var animationId = expectedResults[index][0];
+    var time = expectedResults[index][1];
+    var elementId = expectedResults[index][2];
+    var sampleCallback = expectedResults[index][3];
+
+    if (!layoutTestController.sampleSVGAnimationForElementAtTime(animationId, time, elementId)) {
+        testFailed("animation \"" + animationId + "\" is not running");
+        return;
+    }
+
+    sampleCallback();
+}
+
+var currentTest = 0;
+var expectedResults;
+
+function startTest(callback) {
+    if (currentTest > 0)
+        throw("Not allowed to call startTest() twice");
+
+    testCount = expectedResults.length;
+    currentTest = 0;
+
+    if (callback)
+        callback();
+
+    // Immediately sample, if the first time is 0
+    if (expectedResults[0][1] == '0') {
+        expectedResults[0][3]();
+        ++currentTest;
+    }
+
+    // We may have just sampled on animation-begin, give the
+    // document some time to invoke the SVG animation.
+    // If we fix the animation to start with the SVGLoad event
+    // not on implicitClose(), we can even avoid this hack.
+    window.setTimeout(sampleAnimation, 0);
+}
+
+function sampleAnimation() {
+    if (currentTest == expectedResults.length) {
+        completeTest();
+        return;
+    }
+
+    moveAnimationTimelineAndSample(currentTest);
+    ++currentTest;
+
+    sampleAnimation();
+}
+
+var hasPauseAnimationAPI;
+var globalCallback;
+
+function runAnimationTest(expected, callback)
+{
+    if (!expected)
+        throw("Expected results are missing!");
+
+    expectedResults = expected;
+
+    hasPauseAnimationAPI = ('layoutTestController' in window) && ('sampleSVGAnimationForElementAtTime' in layoutTestController);
+    if (!hasPauseAnimationAPI)
+        throw("SVG animation pause API missing!");
+
+    startTest(callback);
+}
diff --git a/LayoutTests/svg/animations/script-tests/TEMPLATE.html b/LayoutTests/svg/animations/script-tests/TEMPLATE.html
new file mode 100644
index 0000000..c740a55
--- /dev/null
+++ b/LayoutTests/svg/animations/script-tests/TEMPLATE.html
@@ -0,0 +1,15 @@
+<!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="YOUR_JS_FILE_HERE"></script>
+</body>
+</html>
diff --git a/LayoutTests/svg/animations/script-tests/animVal-basics.js b/LayoutTests/svg/animations/script-tests/animVal-basics.js
new file mode 100644
index 0000000..b80d15b
--- /dev/null
+++ b/LayoutTests/svg/animations/script-tests/animVal-basics.js
@@ -0,0 +1,73 @@
+// FIXME: This test will become useful once we have basic animVal support. For now it's just testing the SVG animation test infrastructure
+description("Trivial animVal testcase, to see wheter we support it at all. Should result in a 200x200 rect and only PASS messages");
+createSVGTestCase();
+
+// Setup test document
+var rect = createSVGElement("rect");
+rect.setAttribute("id", "rect");
+rect.setAttribute("width", "200");
+rect.setAttribute("height", "200");
+rect.setAttribute("fill", "green");
+rect.setAttribute("onclick", "executeTest()");
+
+var animate = createSVGElement("animate");
+animate.setAttribute("id", "animation");
+animate.setAttribute("attributeName", "width");
+animate.setAttribute("from", "200");
+animate.setAttribute("to", "100");
+animate.setAttribute("begin", "click");
+animate.setAttribute("dur", "4s");
+rect.appendChild(animate);
+rootSVGElement.appendChild(rect);
+
+// Setup animation test
+function sample1() {
+    // Check initial/end conditions
+    shouldBe("rect.width.animVal.value", "200");
+    shouldBe("rect.width.baseVal.value", "200");
+}
+
+function sample2() {
+    // FIXME: Add animVal support. Animates baseVal at the moment.
+    // shouldBe("rect.width.animVal.value", "150");
+    // shouldBe("rect.width.baseVal.value", "200");
+
+    // Check half-time conditions
+    shouldBe("rect.width.animVal.value", "150");
+    shouldBe("rect.width.baseVal.value", "150");
+}
+
+function sample3() {
+    // FIXME: Add animVal support. Animates baseVal at the moment.
+    // shouldBe("rect.width.animVal.value", "100");
+    // shouldBe("rect.width.baseVal.value", "200");
+
+    // Check just before-end conditions
+    var ok = isCloseEnough(rect.width.animVal.value, 100, 0.01);
+    if (ok)
+        testPassed("rect.width.animVal.value is almost 100, just before-end");
+    else
+        testFailed("rect.width.animVal.value is NOT almost 100, as expected");
+
+    ok = isCloseEnough(rect.width.baseVal.value, 100, 0.01);
+    if (ok)
+        testPassed("rect.width.baseVal.value is almost 100, just before-end");
+    else
+        testFailed("rect.width.baseVal.value is NOT almost 100, as expected");
+}
+
+function executeTest() {
+    const expectedValues = [
+        // [animationId, time, elementId, sampleCallback]
+        ["animation", 0.0,    "rect", sample1],
+        ["animation", 2.0,    "rect", sample2],
+        ["animation", 3.9999, "rect", sample3],
+        ["animation", 4.0 ,   "rect", sample1]
+    ];
+
+    runAnimationTest(expectedValues);
+}
+
+// Begin test async
+window.setTimeout("triggerUpdate(15, 30)", 0);
+var successfullyParsed = true;
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 11e3fd0..b962cd8 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,41 @@
+2009-12-01  Nikolas Zimmermann  <nzimmermann at rim.com>
+
+        Reviewed by Simon Fraser.
+
+        Add SVG animation test framework with 'snapshot' functionality
+        https://bugs.webkit.org/show_bug.cgi?id=31897
+
+        Add 'sampleSVGAnimationForElementAtTime' method to the LayoutTestController,
+        for the use within the new SVG animation test framework (LayoutTests/svg/animations/)
+
+        layoutTestController.sampleAnimationAtTime(<svg animation id>, <absolute time>, <svg element id>);
+        to sample a svg animateMotion/animateColor/animate/set element at certain times.
+
+        After the desired SVG animation starts and calling the method above, it's immediately forwarded to
+        the desired sampling time. After JS returns from the 'sampleSVGAnimationForElementAtTime' method
+        a callback is fired used to sample the animation value at the target time. It's modelled similar
+        to the CSS animation/transition testing framework, inspired by
+        LayoutTests/animations/animation-test-helpers.js.
+
+        Though it has been extended to integrate within the fast/js/js-test-* framework, that's used for
+        the SVG dynamic-updates tests, to simplify test creation, by utilizing script-tests/* only.
+
+        Adding a simple testcase testing the DRT methods, it will soon be extended to test animVal/baseVal
+        interaction, while animating.
+
+        Test: svg/animations/animVal-basics.html
+
+        * WebCore.base.exp:
+        * WebCore.xcodeproj/project.pbxproj:
+        * svg/SVGDocumentExtensions.cpp:
+        (WebCore::SVGDocumentExtensions::sampleAnimationAtTime):
+        * svg/SVGDocumentExtensions.h:
+        * svg/animation/SMILTimeContainer.cpp:
+        (WebCore::SMILTimeContainer::SMILTimeContainer):
+        (WebCore::SMILTimeContainer::sampleAnimationAtTime):
+        (WebCore::SMILTimeContainer::updateAnimations):
+        * svg/animation/SMILTimeContainer.h:
+
 2009-12-01  Jens Alfke  <snej at chromium.org>
 
         Reviewed by Darin Adler.
diff --git a/WebCore/WebCore.base.exp b/WebCore/WebCore.base.exp
index 5f94bbe..ced6fa0 100644
--- a/WebCore/WebCore.base.exp
+++ b/WebCore/WebCore.base.exp
@@ -984,6 +984,10 @@ __ZTVN7WebCore12ChromeClientE
 __ZTVN7WebCore17FileChooserClientE
 __ZTVN7WebCore17FrameLoaderClientE
 __ZTVN7WebCore25HistoryPropertyListWriterE
+__ZN7WebCore14SVGSMILElement13isSMILElementEPNS_4NodeE
+__ZN7WebCore21SVGDocumentExtensions21sampleAnimationAtTimeERKNS_6StringEPNS_14SVGSMILElementEd
+__ZN7WebCore8Document19accessSVGExtensionsEv
+__ZN7WebCore8Document13svgExtensionsEv
 _filenameByFixingIllegalCharacters
 _hasCaseInsensitiveSubstring
 _hasCaseInsensitiveSuffix
diff --git a/WebCore/WebCore.xcodeproj/project.pbxproj b/WebCore/WebCore.xcodeproj/project.pbxproj
index d630eb6..4e245c8 100644
--- a/WebCore/WebCore.xcodeproj/project.pbxproj
+++ b/WebCore/WebCore.xcodeproj/project.pbxproj
@@ -90,10 +90,10 @@
 		087281580F26B9B600AFC596 /* OptionGroupElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 087281540F26B9B600AFC596 /* OptionGroupElement.h */; };
 		08744BAA0EDB7D86004C9E63 /* WMLOnEventElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08744BA90EDB7D86004C9E63 /* WMLOnEventElement.cpp */; };
 		08744BAE0EDB7D92004C9E63 /* WMLOnEventElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 08744BAD0EDB7D92004C9E63 /* WMLOnEventElement.h */; };
-		0878B1FD10874E3F00A55097 /* SVGAnimatedProperty.h in Headers */ = {isa = PBXBuildFile; fileRef = 0878B1F910874E3F00A55097 /* SVGAnimatedProperty.h */; };
+		0878B1FD10874E3F00A55097 /* SVGAnimatedProperty.h in Headers */ = {isa = PBXBuildFile; fileRef = 0878B1F910874E3F00A55097 /* SVGAnimatedProperty.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0878B1FE10874E3F00A55097 /* SynchronizablePropertyController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0878B1FA10874E3F00A55097 /* SynchronizablePropertyController.cpp */; };
-		0878B1FF10874E3F00A55097 /* SynchronizablePropertyController.h in Headers */ = {isa = PBXBuildFile; fileRef = 0878B1FB10874E3F00A55097 /* SynchronizablePropertyController.h */; };
-		0878B20010874E3F00A55097 /* SynchronizableTypeWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 0878B1FC10874E3F00A55097 /* SynchronizableTypeWrapper.h */; };
+		0878B1FF10874E3F00A55097 /* SynchronizablePropertyController.h in Headers */ = {isa = PBXBuildFile; fileRef = 0878B1FB10874E3F00A55097 /* SynchronizablePropertyController.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		0878B20010874E3F00A55097 /* SynchronizableTypeWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 0878B1FC10874E3F00A55097 /* SynchronizableTypeWrapper.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		087FFA0F0EFF3ED3009DBD88 /* WMLInsertedLegendElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 087FFA0D0EFF3ED3009DBD88 /* WMLInsertedLegendElement.cpp */; };
 		087FFA100EFF3ED3009DBD88 /* WMLInsertedLegendElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 087FFA0E0EFF3ED3009DBD88 /* WMLInsertedLegendElement.h */; };
 		08807B760ED709AB003F6975 /* WMLGoElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08807B6A0ED709AB003F6975 /* WMLGoElement.cpp */; };
@@ -3325,7 +3325,7 @@
 		B22279850D00BF220071B782 /* SVGAnimatedPathData.h in Headers */ = {isa = PBXBuildFile; fileRef = B22277EF0D00BF1F0071B782 /* SVGAnimatedPathData.h */; };
 		B22279870D00BF220071B782 /* SVGAnimatedPoints.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B22277F10D00BF1F0071B782 /* SVGAnimatedPoints.cpp */; };
 		B22279880D00BF220071B782 /* SVGAnimatedPoints.h in Headers */ = {isa = PBXBuildFile; fileRef = B22277F20D00BF1F0071B782 /* SVGAnimatedPoints.h */; };
-		B222798D0D00BF220071B782 /* SVGAnimatedTemplate.h in Headers */ = {isa = PBXBuildFile; fileRef = B22277F70D00BF1F0071B782 /* SVGAnimatedTemplate.h */; };
+		B222798D0D00BF220071B782 /* SVGAnimatedTemplate.h in Headers */ = {isa = PBXBuildFile; fileRef = B22277F70D00BF1F0071B782 /* SVGAnimatedTemplate.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		B222798F0D00BF220071B782 /* SVGAnimateElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B22277F90D00BF1F0071B782 /* SVGAnimateElement.cpp */; };
 		B22279900D00BF220071B782 /* SVGAnimateElement.h in Headers */ = {isa = PBXBuildFile; fileRef = B22277FA0D00BF1F0071B782 /* SVGAnimateElement.h */; };
 		B22279920D00BF220071B782 /* SVGAnimateMotionElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B22277FC0D00BF1F0071B782 /* SVGAnimateMotionElement.cpp */; };
@@ -3351,7 +3351,7 @@
 		B22279B30D00BF220071B782 /* SVGDocument.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B222781D0D00BF1F0071B782 /* SVGDocument.cpp */; };
 		B22279B40D00BF220071B782 /* SVGDocument.h in Headers */ = {isa = PBXBuildFile; fileRef = B222781E0D00BF1F0071B782 /* SVGDocument.h */; };
 		B22279B60D00BF220071B782 /* SVGElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B22278200D00BF1F0071B782 /* SVGElement.cpp */; };
-		B22279B70D00BF220071B782 /* SVGElement.h in Headers */ = {isa = PBXBuildFile; fileRef = B22278210D00BF1F0071B782 /* SVGElement.h */; };
+		B22279B70D00BF220071B782 /* SVGElement.h in Headers */ = {isa = PBXBuildFile; fileRef = B22278210D00BF1F0071B782 /* SVGElement.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		B22279B90D00BF220071B782 /* SVGElementInstance.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B22278230D00BF1F0071B782 /* SVGElementInstance.cpp */; };
 		B22279BA0D00BF220071B782 /* SVGElementInstance.h in Headers */ = {isa = PBXBuildFile; fileRef = B22278240D00BF1F0071B782 /* SVGElementInstance.h */; };
 		B22279BC0D00BF220071B782 /* SVGElementInstanceList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B22278260D00BF1F0071B782 /* SVGElementInstanceList.cpp */; };
@@ -3434,7 +3434,7 @@
 		B2227A2F0D00BF220071B782 /* SVGLangSpace.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B22278990D00BF200071B782 /* SVGLangSpace.cpp */; };
 		B2227A300D00BF220071B782 /* SVGLangSpace.h in Headers */ = {isa = PBXBuildFile; fileRef = B222789A0D00BF200071B782 /* SVGLangSpace.h */; };
 		B2227A320D00BF220071B782 /* SVGLength.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B222789C0D00BF200071B782 /* SVGLength.cpp */; };
-		B2227A330D00BF220071B782 /* SVGLength.h in Headers */ = {isa = PBXBuildFile; fileRef = B222789D0D00BF200071B782 /* SVGLength.h */; };
+		B2227A330D00BF220071B782 /* SVGLength.h in Headers */ = {isa = PBXBuildFile; fileRef = B222789D0D00BF200071B782 /* SVGLength.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		B2227A350D00BF220071B782 /* SVGLengthList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B222789F0D00BF200071B782 /* SVGLengthList.cpp */; };
 		B2227A360D00BF220071B782 /* SVGLengthList.h in Headers */ = {isa = PBXBuildFile; fileRef = B22278A00D00BF200071B782 /* SVGLengthList.h */; };
 		B2227A380D00BF220071B782 /* SVGLinearGradientElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B22278A20D00BF200071B782 /* SVGLinearGradientElement.cpp */; };
@@ -3696,7 +3696,7 @@
 		B27B285D0CEF0D7200D39D54 /* DOMSVGGlyphElement.h in Copy Generated Headers */ = {isa = PBXBuildFile; fileRef = B27B28300CEF0C3500D39D54 /* DOMSVGGlyphElement.h */; };
 		B27B285E0CEF0D7200D39D54 /* DOMSVGMissingGlyphElement.h in Copy Generated Headers */ = {isa = PBXBuildFile; fileRef = B27B28330CEF0C3500D39D54 /* DOMSVGMissingGlyphElement.h */; };
 		B28C6A270D00C44800334AA4 /* SVGDocumentExtensions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B28C6A1E0D00C44800334AA4 /* SVGDocumentExtensions.cpp */; };
-		B28C6A280D00C44800334AA4 /* SVGDocumentExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = B28C6A1F0D00C44800334AA4 /* SVGDocumentExtensions.h */; };
+		B28C6A280D00C44800334AA4 /* SVGDocumentExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = B28C6A1F0D00C44800334AA4 /* SVGDocumentExtensions.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		B28C6A290D00C44800334AA4 /* SVGImageLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B28C6A200D00C44800334AA4 /* SVGImageLoader.cpp */; };
 		B28C6A2A0D00C44800334AA4 /* SVGImageLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = B28C6A210D00C44800334AA4 /* SVGImageLoader.h */; };
 		B297BC700B3C14CF0045A590 /* JSSVGPathSegListCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B297BC6F0B3C14CF0045A590 /* JSSVGPathSegListCustom.cpp */; };
@@ -4731,11 +4731,11 @@
 		E49626C30D80D94900E3405C /* PreloadScanner.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D4ABE10D7542F100F96869 /* PreloadScanner.h */; };
 		E4AFCFA50DAF29A300F5F55C /* UnitBezier.h in Headers */ = {isa = PBXBuildFile; fileRef = E4AFCFA40DAF29A300F5F55C /* UnitBezier.h */; };
 		E4AFD00B0DAF335400F5F55C /* SMILTime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4AFD0050DAF335400F5F55C /* SMILTime.cpp */; };
-		E4AFD00C0DAF335400F5F55C /* SMILTime.h in Headers */ = {isa = PBXBuildFile; fileRef = E4AFD0060DAF335400F5F55C /* SMILTime.h */; };
+		E4AFD00C0DAF335400F5F55C /* SMILTime.h in Headers */ = {isa = PBXBuildFile; fileRef = E4AFD0060DAF335400F5F55C /* SMILTime.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E4AFD00D0DAF335500F5F55C /* SMILTimeContainer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4AFD0070DAF335400F5F55C /* SMILTimeContainer.cpp */; };
 		E4AFD00E0DAF335500F5F55C /* SMILTimeContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = E4AFD0080DAF335400F5F55C /* SMILTimeContainer.h */; };
 		E4AFD00F0DAF335500F5F55C /* SVGSMILElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4AFD0090DAF335400F5F55C /* SVGSMILElement.cpp */; };
-		E4AFD0100DAF335500F5F55C /* SVGSMILElement.h in Headers */ = {isa = PBXBuildFile; fileRef = E4AFD00A0DAF335400F5F55C /* SVGSMILElement.h */; };
+		E4AFD0100DAF335500F5F55C /* SVGSMILElement.h in Headers */ = {isa = PBXBuildFile; fileRef = E4AFD00A0DAF335400F5F55C /* SVGSMILElement.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E4C1789A0EE6903800824D69 /* CSSSelectorList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4C178950EE6903800824D69 /* CSSSelectorList.cpp */; };
 		E4C1789B0EE6903800824D69 /* CSSSelectorList.h in Headers */ = {isa = PBXBuildFile; fileRef = E4C178960EE6903800824D69 /* CSSSelectorList.h */; };
 		E4C279580CF9741900E97B98 /* RenderMedia.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4C279560CF9741900E97B98 /* RenderMedia.cpp */; };
diff --git a/WebCore/svg/SVGDocumentExtensions.cpp b/WebCore/svg/SVGDocumentExtensions.cpp
index 61645f4..b2492b4 100644
--- a/WebCore/svg/SVGDocumentExtensions.cpp
+++ b/WebCore/svg/SVGDocumentExtensions.cpp
@@ -34,6 +34,7 @@
 #include "Frame.h"
 #include "FrameLoader.h"
 #include "Page.h"
+#include "SVGSMILElement.h"
 #include "SVGSVGElement.h"
 #include "SMILTimeContainer.h"
 #include "XMLTokenizer.h"
@@ -86,6 +87,17 @@ void SVGDocumentExtensions::unpauseAnimations()
         (*itr)->unpauseAnimations();
 }
 
+bool SVGDocumentExtensions::sampleAnimationAtTime(const String& elementId, SVGSMILElement* element, double time)
+{
+    ASSERT(element);
+    SMILTimeContainer* container = element->timeContainer();
+    if (!container || container->isPaused())
+        return false;
+
+    container->sampleAnimationAtTime(elementId, time);
+    return true;
+}
+
 void SVGDocumentExtensions::reportWarning(const String& message)
 {
     if (Frame* frame = m_doc->frame())
diff --git a/WebCore/svg/SVGDocumentExtensions.h b/WebCore/svg/SVGDocumentExtensions.h
index cd20a30..e7d6fc1 100644
--- a/WebCore/svg/SVGDocumentExtensions.h
+++ b/WebCore/svg/SVGDocumentExtensions.h
@@ -41,6 +41,7 @@ class Node;
 class String;
 class SVGElementInstance;
 class SVGStyledElement;
+class SVGSMILElement;
 class SVGSVGElement;
 
 class SVGDocumentExtensions {
@@ -54,6 +55,7 @@ public:
     void startAnimations();
     void pauseAnimations();
     void unpauseAnimations();
+    bool sampleAnimationAtTime(const String& elementId, SVGSMILElement*, double time);
 
     void reportWarning(const String&);
     void reportError(const String&);
diff --git a/WebCore/svg/animation/SMILTimeContainer.cpp b/WebCore/svg/animation/SMILTimeContainer.cpp
index a37e481..f0b479d 100644
--- a/WebCore/svg/animation/SMILTimeContainer.cpp
+++ b/WebCore/svg/animation/SMILTimeContainer.cpp
@@ -46,6 +46,7 @@ SMILTimeContainer::SMILTimeContainer(SVGSVGElement* owner)
     : m_beginTime(0)
     , m_pauseTime(0)
     , m_accumulatedPauseTime(0)
+    , m_nextManualSampleTime(0)
     , m_documentOrderIndexesDirty(false)
     , m_timer(this, &SMILTimeContainer::timerFired)
     , m_ownerSVGElement(owner)
@@ -207,14 +208,45 @@ String SMILTimeContainer::baseValueFor(ElementAttributePair key)
     m_savedBaseValues.add(key, baseValue);
     return baseValue;
 }
-      
+
+void SMILTimeContainer::sampleAnimationAtTime(const String& elementId, double newTime)
+{
+    ASSERT(m_beginTime);
+    ASSERT(!isPaused());
+
+    // Fast-forward to the time DRT wants to sample
+    m_timer.stop();
+    m_nextSamplingTarget = elementId;
+    m_nextManualSampleTime = newTime;
+
+    updateAnimations(elapsed());
+}
+
 void SMILTimeContainer::updateAnimations(SMILTime elapsed)
 {
     SMILTime earliersFireTime = SMILTime::unresolved();
 
     Vector<SVGSMILElement*> toAnimate;
     copyToVector(m_scheduledAnimations, toAnimate);
-    
+
+    if (m_nextManualSampleTime) {
+        SMILTime samplingDiff;
+        for (unsigned n = 0; n < toAnimate.size(); ++n) {
+            SVGSMILElement* animation = toAnimate[n];
+            ASSERT(animation->timeContainer() == this);
+
+            SVGElement* targetElement = animation->targetElement();
+            if (!targetElement || targetElement->getIDAttribute() != m_nextSamplingTarget)
+                continue;
+
+            samplingDiff = animation->intervalBegin();
+            break;
+        }
+
+        elapsed = SMILTime(m_nextManualSampleTime) + samplingDiff;
+        m_nextManualSampleTime = 0;
+    }
+
     // Sort according to priority. Elements with later begin time have higher priority.
     // In case of a tie, document order decides. 
     // FIXME: This should also consider timing relationships between the elements. Dependents
diff --git a/WebCore/svg/animation/SMILTimeContainer.h b/WebCore/svg/animation/SMILTimeContainer.h
index 5cef507..a6a61c0 100644
--- a/WebCore/svg/animation/SMILTimeContainer.h
+++ b/WebCore/svg/animation/SMILTimeContainer.h
@@ -60,6 +60,9 @@ namespace WebCore {
         
         void setDocumentOrderIndexesDirty() { m_documentOrderIndexesDirty = true; }
 
+        // Move to a specific time. Only used for DRT testing purposes.
+        void sampleAnimationAtTime(const String& elementId, double seconds);
+
     private:
         SMILTimeContainer(SVGSVGElement* owner);
         
@@ -76,7 +79,9 @@ namespace WebCore {
         double m_beginTime;
         double m_pauseTime;
         double m_accumulatedPauseTime;
-        
+        double m_nextManualSampleTime;
+        String m_nextSamplingTarget;
+
         bool m_documentOrderIndexesDirty;
         
         Timer<SMILTimeContainer> m_timer;
diff --git a/WebKit/gtk/ChangeLog b/WebKit/gtk/ChangeLog
index 3f87532..f589813 100644
--- a/WebKit/gtk/ChangeLog
+++ b/WebKit/gtk/ChangeLog
@@ -1,3 +1,19 @@
+2009-12-01  Nikolas Zimmermann  <nzimmermann at rim.com>
+
+        Reviewed by Simon Fraser.
+
+        Add SVG animation test framework with 'snapshot' functionality
+        https://bugs.webkit.org/show_bug.cgi?id=31897
+
+        Add API used by the new 'sampleSVGAnimationForElementAtTime' DRT method,
+        forwarding the call to SVGDocumentExtensions, if SVG is enabled.
+
+        Implemented just like the existing pauseAnimation* methods for CSS animations.
+
+        * webkit/webkitprivate.h:
+        * webkit/webkitwebframe.cpp:
+        (webkit_web_frame_pause_svg_animation):
+
 2009-11-30  Xan Lopez  <xlopez at igalia.com>
 
         Reviewed by Gustavo Noronha.
diff --git a/WebKit/gtk/webkit/webkitprivate.h b/WebKit/gtk/webkit/webkitprivate.h
index 3b7e161..bd95896 100644
--- a/WebKit/gtk/webkit/webkitprivate.h
+++ b/WebKit/gtk/webkit/webkitprivate.h
@@ -301,6 +301,9 @@ extern "C" {
     WEBKIT_API bool
     webkit_web_frame_pause_transition(WebKitWebFrame* frame, const gchar* name, double time, const gchar* element);
 
+    WEBKIT_API bool
+    webkit_web_frame_pause_svg_animation(WebKitWebFrame* frame, const gchar* animationId, double time, const gchar* elementId);
+
     WEBKIT_API unsigned int
     webkit_web_frame_number_of_active_animations(WebKitWebFrame* frame);
 
diff --git a/WebKit/gtk/webkit/webkitwebframe.cpp b/WebKit/gtk/webkit/webkitwebframe.cpp
index 331e5e8..6ffd011 100644
--- a/WebKit/gtk/webkit/webkitwebframe.cpp
+++ b/WebKit/gtk/webkit/webkitwebframe.cpp
@@ -54,6 +54,7 @@
 #include "JSDOMBinding.h"
 #include "ScriptController.h"
 #include "SubstituteData.h"
+#include "SVGSMILElement.h"
 
 #include <atk/atk.h>
 #include <JavaScriptCore/APICast.h>
@@ -959,6 +960,22 @@ bool webkit_web_frame_pause_transition(WebKitWebFrame* frame, const gchar* name,
     return core(frame)->animation()->pauseTransitionAtTime(coreElement->renderer(), AtomicString(name), time);
 }
 
+bool webkit_web_frame_pause_svg_animation(WebKitWebFrame* frame, const gchar* animationId, double time, const gchar* elementId)
+{
+    ASSERT(core(frame));
+    Document* document = core(frame)->document();
+    if (!document || !document->svgExtensions())
+        return false;
+    Element* coreElement = document->getElementById(AtomicString(animationId));
+    if (!coreElement || !SVGSMILElement::isSMILElement(coreElement))
+        return false;
+#if ENABLE(SVG)
+    return document->accessSVGExtensions()->sampleAnimationAtTime(elementId, static_cast<SVGSMILElement*>(coreElement), time);
+#else
+    return false;
+#endif
+}
+
 unsigned int webkit_web_frame_number_of_active_animations(WebKitWebFrame* frame)
 {
     Frame* coreFrame = core(frame);
diff --git a/WebKit/mac/ChangeLog b/WebKit/mac/ChangeLog
index 44dcb62..7bccb36 100644
--- a/WebKit/mac/ChangeLog
+++ b/WebKit/mac/ChangeLog
@@ -1,3 +1,19 @@
+2009-12-01  Nikolas Zimmermann  <nzimmermann at rim.com>
+
+        Reviewed by Simon Fraser.
+
+        Add SVG animation test framework with 'snapshot' functionality
+        https://bugs.webkit.org/show_bug.cgi?id=31897
+
+        Add API used by the new 'sampleSVGAnimationForElementAtTime' DRT method,
+        forwarding the call to SVGDocumentExtensions, if SVG is enabled.
+
+        Implemented just like the existing pauseAnimation* methods for CSS animations.
+
+        * WebView/WebFrame.mm:
+        (-[WebFrame _pauseSVGAnimation:onSMILNode:atTime:]):
+        * WebView/WebFramePrivate.h:
+
 2009-12-01  Sam Weinig  <sam at webkit.org>
 
         Reviewed by Mark Rowe.
diff --git a/WebKit/mac/WebView/WebFrame.mm b/WebKit/mac/WebView/WebFrame.mm
index 158346d..58400d6 100644
--- a/WebKit/mac/WebView/WebFrame.mm
+++ b/WebKit/mac/WebView/WebFrame.mm
@@ -79,6 +79,7 @@
 #import <WebCore/RuntimeApplicationChecks.h>
 #import <WebCore/ScriptValue.h>
 #import <WebCore/SmartReplace.h>
+#import <WebCore/SVGSMILElement.h>
 #import <WebCore/TextIterator.h>
 #import <WebCore/ThreadCheck.h>
 #import <WebCore/TypingCommand.h>
@@ -1116,6 +1117,29 @@ static inline WebDataSource *dataSource(DocumentLoader* loader)
     return controller->pauseTransitionAtTime(coreNode->renderer(), name, time);
 }
 
+// Pause a given SVG animation on the target node at a specific time.
+// This method is only intended to be used for testing the SVG animation system.
+- (BOOL)_pauseSVGAnimation:(NSString*)elementId onSMILNode:(DOMNode *)node atTime:(NSTimeInterval)time
+{
+    Frame* frame = core(self);
+    if (!frame)
+        return false;
+ 
+    Document* document = frame->document();
+    if (!document || !document->svgExtensions())
+        return false;
+
+    Node* coreNode = core(node);
+    if (!coreNode || !SVGSMILElement::isSMILElement(coreNode))
+        return false;
+
+#if ENABLE(SVG)
+    return document->accessSVGExtensions()->sampleAnimationAtTime(elementId, static_cast<SVGSMILElement*>(coreNode), time);
+#else
+    return false;
+#endif
+}
+
 - (unsigned) _numberOfActiveAnimations
 {
     Frame* frame = core(self);
diff --git a/WebKit/mac/WebView/WebFramePrivate.h b/WebKit/mac/WebView/WebFramePrivate.h
index 526b7e9..462686f 100644
--- a/WebKit/mac/WebView/WebFramePrivate.h
+++ b/WebKit/mac/WebView/WebFramePrivate.h
@@ -106,6 +106,10 @@ typedef enum {
 - (BOOL)_pauseAnimation:(NSString*)name onNode:(DOMNode *)node atTime:(NSTimeInterval)time;
 - (BOOL)_pauseTransitionOfProperty:(NSString*)name onNode:(DOMNode*)node atTime:(NSTimeInterval)time;
 
+// Pause a given SVG animation on the target node at a specific time.
+// This method is only intended to be used for testing the SVG animation system.
+- (BOOL)_pauseSVGAnimation:(NSString*)elementId onSMILNode:(DOMNode *)node atTime:(NSTimeInterval)time;
+
 // Returns the total number of currently running animations (includes both CSS transitions and CSS animations).
 - (unsigned) _numberOfActiveAnimations;
 
diff --git a/WebKit/qt/Api/qwebframe.cpp b/WebKit/qt/Api/qwebframe.cpp
index a51f89d..2a11b01 100644
--- a/WebKit/qt/Api/qwebframe.cpp
+++ b/WebKit/qt/Api/qwebframe.cpp
@@ -56,6 +56,7 @@
 #include "Scrollbar.h"
 #include "SelectionController.h"
 #include "SubstituteData.h"
+#include "SVGSMILElement.h"
 #include "htmlediting.h"
 #include "markup.h"
 #include "qt_instance.h"
@@ -148,6 +149,31 @@ bool QWEBKIT_EXPORT qt_drt_pauseTransitionOfProperty(QWebFrame *qframe, const QS
     return controller->pauseTransitionAtTime(coreNode->renderer(), propertyName, time);
 }
 
+// Pause a given SVG animation on the target node at a specific time.
+// This method is only intended to be used for testing the SVG animation system.
+bool QWEBKIT_EXPORT qt_drt_pauseSVGAnimation(QWebFrame *qframe, const QString &animationId, double time, const QString &elementId)
+{
+    Frame* frame = QWebFramePrivate::core(qframe);
+    if (!frame)
+        return false;
+
+    Document* doc = frame->document();
+    Q_ASSERT(doc);
+
+    if (!doc->svgExtensions())
+        return false;
+
+    Node* coreNode = doc->getElementById(animationId);
+    if (!coreNode || !SVGSMILElement::isSMILElement(coreNode))
+        return false;
+
+#if ENABLE(SVG)
+    return document->accessSVGExtensions()->sampleAnimationAtTime(elementId, static_cast<SVGSMILElement*>(coreNode), time);
+#else
+    return false;
+#endif
+}
+
 // Returns the total number of currently running animations (includes both CSS transitions and CSS animations).
 int QWEBKIT_EXPORT qt_drt_numberOfActiveAnimations(QWebFrame *qframe)
 {
diff --git a/WebKit/qt/ChangeLog b/WebKit/qt/ChangeLog
index a563aaa..ff3fc9f 100644
--- a/WebKit/qt/ChangeLog
+++ b/WebKit/qt/ChangeLog
@@ -1,3 +1,18 @@
+2009-12-01  Nikolas Zimmermann  <nzimmermann at rim.com>
+
+        Reviewed by Simon Fraser.
+
+        Add SVG animation test framework with 'snapshot' functionality
+        https://bugs.webkit.org/show_bug.cgi?id=31897
+
+        Add API used by the new 'sampleSVGAnimationForElementAtTime' DRT method,
+        forwarding the call to SVGDocumentExtensions, if SVG is enabled.
+
+        Implemented just like the existing pauseAnimation* methods for CSS animations.
+
+        * Api/qwebframe.cpp:
+        (qt_drt_pauseSVGAnimation):
+
 2009-12-01  Daniel Bates  <dbates at webkit.org>
 
         Reviewed by Kenneth Rohde Christiansen.
diff --git a/WebKit/win/ChangeLog b/WebKit/win/ChangeLog
index 514bd74..f5c5e46 100644
--- a/WebKit/win/ChangeLog
+++ b/WebKit/win/ChangeLog
@@ -1,3 +1,20 @@
+2009-12-01  Nikolas Zimmermann  <nzimmermann at rim.com>
+
+        Reviewed by Simon Fraser.
+
+        Add SVG animation test framework with 'snapshot' functionality
+        https://bugs.webkit.org/show_bug.cgi?id=31897
+
+        Add API used by the new 'sampleSVGAnimationForElementAtTime' DRT method,
+        forwarding the call to SVGDocumentExtensions, if SVG is enabled.
+
+        Implemented just like the existing pauseAnimation* methods for CSS animations.
+
+        * Interfaces/IWebFramePrivate.idl:
+        * WebFrame.cpp:
+        (WebFrame::pauseSVGAnimation):
+        * WebFrame.h:
+
 2009-11-30  Adam Roben  <aroben at apple.com>
 
         Fix double-free of BSTRs passed to WebNavigationData::createInstance
diff --git a/WebKit/win/Interfaces/IWebFramePrivate.idl b/WebKit/win/Interfaces/IWebFramePrivate.idl
index 26996b9..3ba71c8 100644
--- a/WebKit/win/Interfaces/IWebFramePrivate.idl
+++ b/WebKit/win/Interfaces/IWebFramePrivate.idl
@@ -89,6 +89,7 @@ interface IWebFramePrivate : IUnknown
 
     HRESULT pauseAnimation([in] BSTR animationName, [in] IDOMNode* node, [in] double secondsFromNow, [out, retval] BOOL* animationWasRunning);
     HRESULT pauseTransition([in] BSTR propertyName, [in] IDOMNode* node, [in] double secondsFromNow, [out, retval] BOOL* transitionWasRunning);
+    HRESULT pauseSVGAnimation([in] BSTR elementId, [in] IDOMNode* node, [in] double secondsFromNow, [out, retval] BOOL* animationWasRunning);
     HRESULT numberOfActiveAnimations([out, retval] UINT* number);
 
     HRESULT isDisplayingStandaloneImage([out, retval] BOOL* result);
diff --git a/WebKit/win/WebFrame.cpp b/WebKit/win/WebFrame.cpp
index eea4bdb..a2c5766 100644
--- a/WebKit/win/WebFrame.cpp
+++ b/WebKit/win/WebFrame.cpp
@@ -92,6 +92,7 @@
 #include <WebCore/RenderView.h>
 #include <WebCore/RenderTreeAsText.h>
 #include <WebCore/Settings.h>
+#include <WebCore/SVGSMILElement.h>
 #include <WebCore/TextIterator.h>
 #include <WebCore/JSDOMBinding.h>
 #include <WebCore/ScriptController.h>
@@ -1156,6 +1157,34 @@ HRESULT WebFrame::pauseTransition(BSTR propertyName, IDOMNode* node, double seco
     return S_OK;
 }
 
+HRESULT WebFrame::pauseSVGAnimation(BSTR elementId, IDOMNode* node, double secondsFromNow, BOOL* animationWasRunning)
+{
+    if (!node || !animationWasRunning)
+        return E_POINTER;
+
+    *animationWasRunning = FALSE;
+
+    Frame* frame = core(this);
+    if (!frame)
+        return E_FAIL;
+
+    Document* document = frame->document();
+    if (!document || !document->svgExtensions())
+        return E_FAIL;
+
+    COMPtr<DOMNode> domNode(Query, node);
+    if (!domNode || !SVGSMILElement::isSMILElement(domNode))
+        return E_FAIL;
+
+#if ENABLE(SVG)
+    *animationWasRunning = document->accessSVGExtensions()->sampleAnimationAtTime(String(elementId, SysStringLen(elementId)), static_cast<SVGSMILElement*>(domNode), secondsFromNow);
+#else
+    *animationWasRunning = FALSE;
+#endif
+
+    return S_OK;
+}
+
 HRESULT WebFrame::numberOfActiveAnimations(UINT* number)
 {
     if (!number)
diff --git a/WebKit/win/WebFrame.h b/WebKit/win/WebFrame.h
index fa7dd4b..91b8e14 100644
--- a/WebKit/win/WebFrame.h
+++ b/WebKit/win/WebFrame.h
@@ -240,6 +240,7 @@ public:
 
     virtual HRESULT STDMETHODCALLTYPE pauseAnimation(BSTR animationName, IDOMNode*, double secondsFromNow, BOOL* animationWasRunning);
     virtual HRESULT STDMETHODCALLTYPE pauseTransition(BSTR propertyName, IDOMNode*, double secondsFromNow, BOOL* transitionWasRunning);
+    virtual HRESULT STDMETHODCALLTYPE pauseSVGAnimation(BSTR elementId, IDOMNode*, double secondsFromNow, BOOL* animationWasRunning);
     virtual HRESULT STDMETHODCALLTYPE numberOfActiveAnimations(UINT*);
 
     virtual HRESULT STDMETHODCALLTYPE isDisplayingStandaloneImage(BOOL*);
diff --git a/WebKitTools/ChangeLog b/WebKitTools/ChangeLog
index c2f788a..9e77bf6 100644
--- a/WebKitTools/ChangeLog
+++ b/WebKitTools/ChangeLog
@@ -1,3 +1,30 @@
+2009-12-01  Nikolas Zimmermann  <nzimmermann at rim.com>
+
+        Reviewed by Simon Fraser.
+
+        Add SVG animation test framework with 'snapshot' functionality
+        https://bugs.webkit.org/show_bug.cgi?id=31897
+
+        Add new 'sampleSVGAnimationForElementAtTime' DRT method,
+        used by the new SVG animation testing framework, implemented
+        for qt/gtk/win/mac.
+
+        * DumpRenderTree/LayoutTestController.cpp:
+        (sampleSVGAnimationForElementAtTimeCallback):
+        (LayoutTestController::staticFunctions):
+        * DumpRenderTree/LayoutTestController.h:
+        * DumpRenderTree/gtk/LayoutTestControllerGtk.cpp:
+        (LayoutTestController::sampleSVGAnimationForElementAtTime):
+        * DumpRenderTree/mac/LayoutTestControllerMac.mm:
+        (LayoutTestController::sampleSVGAnimationForElementAtTime):
+        * DumpRenderTree/qt/LayoutTestControllerQt.cpp:
+        (LayoutTestController::sampleSVGAnimationForElementAtTime):
+        * DumpRenderTree/qt/LayoutTestControllerQt.h:
+        * DumpRenderTree/win/LayoutTestControllerWin.cpp:
+        (LayoutTestController::sampleSVGAnimationForElementAtTime):
+        * DumpRenderTree/wx/LayoutTestControllerWx.cpp:
+        (LayoutTestController::sampleSVGAnimationForElementAtTime):
+
 2009-12-01  Adam Roben  <aroben at apple.com>
 
         Remove user content before running each test on Windows
diff --git a/WebKitTools/DumpRenderTree/LayoutTestController.cpp b/WebKitTools/DumpRenderTree/LayoutTestController.cpp
index d199d6f..fcc527b 100644
--- a/WebKitTools/DumpRenderTree/LayoutTestController.cpp
+++ b/WebKitTools/DumpRenderTree/LayoutTestController.cpp
@@ -1073,6 +1073,22 @@ static JSValueRef pauseTransitionAtTimeOnElementWithIdCallback(JSContextRef cont
     return JSValueMakeBoolean(context, controller->pauseTransitionAtTimeOnElementWithId(propertyName.get(), time, elementId.get()));
 }
 
+static JSValueRef sampleSVGAnimationForElementAtTimeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+    if (argumentCount != 3)
+        return JSValueMakeUndefined(context);
+
+    JSRetainPtr<JSStringRef> animationId(Adopt, JSValueToStringCopy(context, arguments[0], exception));
+    ASSERT(!*exception);
+    double time = JSValueToNumber(context, arguments[1], exception);
+    ASSERT(!*exception);
+    JSRetainPtr<JSStringRef> elementId(Adopt, JSValueToStringCopy(context, arguments[2], exception));
+    ASSERT(!*exception);
+
+    LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+    return JSValueMakeBoolean(context, controller->sampleSVGAnimationForElementAtTime(animationId.get(), time, elementId.get()));
+}
+
 static JSValueRef numberOfActiveAnimationsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
 {
     if (argumentCount != 0)
@@ -1244,6 +1260,7 @@ JSStaticFunction* LayoutTestController::staticFunctions()
         { "pathToLocalResource", pathToLocalResourceCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "pauseAnimationAtTimeOnElementWithId", pauseAnimationAtTimeOnElementWithIdCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "pauseTransitionAtTimeOnElementWithId", pauseTransitionAtTimeOnElementWithIdCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+        { "sampleSVGAnimationForElementAtTime", sampleSVGAnimationForElementAtTimeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "printToPDF", dumpAsPDFCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "queueBackNavigation", queueBackNavigationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "queueForwardNavigation", queueForwardNavigationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
diff --git a/WebKitTools/DumpRenderTree/LayoutTestController.h b/WebKitTools/DumpRenderTree/LayoutTestController.h
index 2fffde9..7e18dce 100644
--- a/WebKitTools/DumpRenderTree/LayoutTestController.h
+++ b/WebKitTools/DumpRenderTree/LayoutTestController.h
@@ -202,6 +202,7 @@ public:
     
     bool pauseAnimationAtTimeOnElementWithId(JSStringRef animationName, double time, JSStringRef elementId);
     bool pauseTransitionAtTimeOnElementWithId(JSStringRef propertyName, double time, JSStringRef elementId);
+    bool sampleSVGAnimationForElementAtTime(JSStringRef animationId, double time, JSStringRef elementId);
     unsigned numberOfActiveAnimations() const;
 
     void whiteListAccessFromOrigin(JSStringRef sourceOrigin, JSStringRef destinationProtocol, JSStringRef destinationHost, bool allowDestinationSubdomains);
diff --git a/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp b/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp
index 2d9efe8..2b9c458 100644
--- a/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp
+++ b/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp
@@ -448,6 +448,14 @@ bool LayoutTestController::pauseTransitionAtTimeOnElementWithId(JSStringRef prop
     return returnValue;
 }
 
+bool LayoutTestController::sampleSVGAnimationForElementAtTime(JSStringRef animationId, double time, JSStringRef elementId)
+{    
+    gchar* animationElement = JSStringCopyUTF8CString(animationId);
+    bool returnValue = webkit_web_frame_pause_svg_animation(mainFrame, elementId, time, animationElement);
+    g_free(element);
+    return returnValue;
+}
+
 unsigned LayoutTestController::numberOfActiveAnimations() const
 {
     return webkit_web_frame_number_of_active_animations(mainFrame);
diff --git a/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm b/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm
index 42aa788..69fe19f 100644
--- a/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm
+++ b/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm
@@ -486,6 +486,16 @@ bool LayoutTestController::pauseTransitionAtTimeOnElementWithId(JSStringRef prop
     return [mainFrame _pauseTransitionOfProperty:nameNS onNode:[[mainFrame DOMDocument] getElementById:idNS] atTime:time];
 }
 
+bool LayoutTestController::sampleSVGAnimationForElementAtTime(JSStringRef animationId, double time, JSStringRef elementId)
+{
+    RetainPtr<CFStringRef> animationIDCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, animationId));
+    NSString *animationIDNS = (NSString *)animationIDCF.get();
+    RetainPtr<CFStringRef> elementIDCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, elementId));
+    NSString *elementIDNS = (NSString *)elementIDCF.get();
+
+    return [mainFrame _pauseSVGAnimation:elementIDNS onSMILNode:[[mainFrame DOMDocument] getElementById:animationIDNS] atTime:time];
+}
+
 unsigned LayoutTestController::numberOfActiveAnimations() const
 {
     return [mainFrame _numberOfActiveAnimations];
diff --git a/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp b/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp
index 96b521d..12ba1b3 100644
--- a/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp
+++ b/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.cpp
@@ -39,7 +39,9 @@ extern void qt_dump_resource_load_callbacks(bool b);
 extern void qt_drt_setJavaScriptProfilingEnabled(QWebFrame*, bool enabled);
 extern bool qt_drt_pauseAnimation(QWebFrame*, const QString& name, double time, const QString& elementId);
 extern bool qt_drt_pauseTransitionOfProperty(QWebFrame*, const QString& name, double time, const QString& elementId);
+extern bool qt_drt_pauseSVGAnimation(QWebFrame*, const QString& animationId, double time, const QString& elementId);
 extern int qt_drt_numberOfActiveAnimations(QWebFrame*);
+
 extern void qt_drt_whiteListAccessFromOrigin(const QString& sourceOrigin, const QString& destinationProtocol, const QString& destinationHost, bool allowDestinationSubdomains);
 extern QString qt_drt_counterValueForElementById(QWebFrame* qFrame, const QString& id);
 
@@ -280,6 +282,15 @@ bool LayoutTestController::pauseTransitionAtTimeOnElementWithId(const QString& p
     return qt_drt_pauseTransitionOfProperty(frame, propertyName, time, elementId);
 }
 
+bool LayoutTestController::sampleSVGAnimationForElementAtTime(const QString& animationId,
+                                                              double time,
+                                                              const QString& elementId)
+{
+    QWebFrame* frame = m_drt->webPage()->mainFrame();
+    Q_ASSERT(frame);
+    return qt_drt_pauseSVGAnimation(frame, animationId, time, elementId);
+}
+
 unsigned LayoutTestController::numberOfActiveAnimations() const
 {
     QWebFrame* frame = m_drt->webPage()->mainFrame();
diff --git a/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h b/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h
index e0add61..ecad947 100644
--- a/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h
+++ b/WebKitTools/DumpRenderTree/qt/LayoutTestControllerQt.h
@@ -115,6 +115,7 @@ public slots:
 
     bool pauseAnimationAtTimeOnElementWithId(const QString& animationName, double time, const QString& elementId);
     bool pauseTransitionAtTimeOnElementWithId(const QString& propertyName, double time, const QString& elementId);
+    bool pauseSVGAnimationAtTimeOnElementWithId(double time, const QString& elementId);
     unsigned numberOfActiveAnimations() const;
 
     void whiteListAccessFromOrigin(const QString& sourceOrigin, const QString& destinationProtocol, const QString& destinationHost, bool allowDestinationSubdomains);
diff --git a/WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp b/WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp
index 362729e..5debf16 100644
--- a/WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp
+++ b/WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp
@@ -861,6 +861,31 @@ bool LayoutTestController::pauseTransitionAtTimeOnElementWithId(JSStringRef prop
     return SUCCEEDED(hr) && wasRunning;
 }
 
+bool LayoutTestController::sampleSVGAnimationForElementAtTime(JSStringRef animationId, double time, JSStringRef elementId)
+{
+    COMPtr<IDOMDocument> document;
+    if (FAILED(frame->DOMDocument(&document)))
+        return false;
+
+    BSTR idBSTR = JSStringCopyBSTR(animationId);
+    COMPtr<IDOMElement> element;
+    HRESULT hr = document->getElementById(idBSTR, &element);
+    SysFreeString(idBSTR);
+    if (FAILED(hr))
+        return false;
+
+    COMPtr<IWebFramePrivate> framePrivate(Query, frame);
+    if (!framePrivate)
+        return false;
+
+    BSTR elementIdBSTR = JSStringCopyBSTR(elementId);
+    BOOL wasRunning = FALSE;
+    hr = framePrivate->pauseSVGAnimation(elementIdBSTR, element.get(), time, &wasRunning);
+    SysFreeString(elementIdBSTR);
+
+    return SUCCEEDED(hr) && wasRunning;
+}
+
 unsigned LayoutTestController::numberOfActiveAnimations() const
 {
     COMPtr<IWebFramePrivate> framePrivate(Query, frame);
diff --git a/WebKitTools/DumpRenderTree/wx/LayoutTestControllerWx.cpp b/WebKitTools/DumpRenderTree/wx/LayoutTestControllerWx.cpp
index 218480f..8bccdda 100644
--- a/WebKitTools/DumpRenderTree/wx/LayoutTestControllerWx.cpp
+++ b/WebKitTools/DumpRenderTree/wx/LayoutTestControllerWx.cpp
@@ -267,6 +267,12 @@ bool LayoutTestController::pauseAnimationAtTimeOnElementWithId(JSStringRef anima
     return false;
 }
 
+bool LayoutTestController::sampleSVGAnimationForElementAtTime(JSStringRef animationId, double time, JSStringRef elementId)
+{
+    // FIXME: implement
+    return false;
+}
+
 void LayoutTestController::setCacheModel(int)
 {
     // FIXME: implement

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list