Commit b3eaa571 authored by Fredrik Söderquist's avatar Fredrik Söderquist Committed by Commit Bot

Clear the current interval when no more intervals can be resolved

When no more intervals can be resolved, ResolveInterval(...) will return
an interval that return false from IsResolved() (meaning it has no
finite begin time). When this happens we should "clear" |interval_| by
setting it to an unresolved interval.

This fixes the behavior of SVGAnimationElement.getStartTime() which now
correctly report (throws) when the last interval of element has ended.
Add a new test for that and move an old somewhat related test to WPT.
Also adjust SVGAnimationTestCase.js which uses this to offset the sample
times (although in most cases) to avoid the debug dump when there's no
current interval (no tests actually rely on the old broken behavior).

This makes us match Firefox.

Bug: 998526
Change-Id: Idcf348343768ffc9392e29af2e976b9a3a1e31aa
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1849897Reviewed-by: default avatarStephen Chenney <schenney@chromium.org>
Commit-Queue: Fredrik Söderquist <fs@opera.com>
Cr-Commit-Position: refs/heads/master@{#705019}
parent 1de78aac
...@@ -918,10 +918,18 @@ void SVGSMILElement::UpdateInterval(SMILTime presentation_time) { ...@@ -918,10 +918,18 @@ void SVGSMILElement::UpdateInterval(SMILTime presentation_time) {
? interval_.end ? interval_.end
: SMILTime::Earliest(); : SMILTime::Earliest();
SMILInterval next_interval = ResolveInterval(begin_after, presentation_time); SMILInterval next_interval = ResolveInterval(begin_after, presentation_time);
if (!next_interval.IsResolved() || next_interval == interval_) // It's the same interval that we resolved before. Do nothing.
if (next_interval == interval_)
return; return;
if (interval_.IsResolved()) if (interval_.IsResolved())
previous_interval_ = interval_; previous_interval_ = interval_;
// If there are no more intervals to resolve, we have to wait for an event to
// occur in order to get a new instance time.
if (!next_interval.IsResolved()) {
interval_ = next_interval;
next_interval_time_ = SMILTime::Unresolved();
return;
}
SetNewInterval(next_interval, presentation_time); SetNewInterval(next_interval, presentation_time);
interval_has_changed_ = true; interval_has_changed_ = true;
} }
......
<!DOCTYPE html> <!DOCTYPE html>
<title>SVGAnimationElement exceptions</title> <title>SVGAnimationElement exceptions</title>
<script src=../../resources/testharness.js></script> <script src="/resources/testharness.js"></script>
<script src=../../resources/testharnessreport.js></script> <script src="/resources/testharnessreport.js"></script>
<svg height="0"><animate begin="foo.begin"/></svg> <svg height="0"><animate begin="foo.begin"/></svg>
<script> <script>
setup(function() { setup(function() {
......
<!DOCTYPE html>
<title>SVGAnimationElement.getStartTime() returns the start time of the current interval.</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<svg height="0">
<animate attributeName="visibility" begin="1s; 3s" dur="1s"/>
<animate attributeName="visibility" begin="1s; 3s" dur="1s" fill="freeze"/>
</svg>
<script>
setup(function() {
window.animationElements = document.querySelectorAll('animate');
window.timeContainer = document.querySelector('svg');
});
function checkStartTime(values, t) {
assert_equals(animationElements[0].getStartTime(), values[0],
'start time @ ' + t);
assert_equals(animationElements[1].getStartTime(), values[1],
'start time @ ' + t);
}
function checkHasNoCurrentInterval(t) {
assert_throws('InvalidStateError', () => {
animationElements[0].getStartTime()
}, 'no interval @ ' + t);
assert_throws('InvalidStateError', () => {
animationElements[1].getStartTime()
}, 'no interval @ ' + t);
}
async_test(t => {
timeContainer.pauseAnimations();
// Wait for the timeline to start.
onload = t.step_func(() => {
t.step_timeout(function() {
assert_equals(timeContainer.getCurrentTime(), 0);
checkStartTime([1, 1], 0);
timeContainer.setCurrentTime(1);
checkStartTime([1, 1], 1);
timeContainer.setCurrentTime(1.5);
checkStartTime([1, 1], 1.5);
timeContainer.setCurrentTime(2);
checkStartTime([3, 3], 2);
timeContainer.setCurrentTime(2.5);
checkStartTime([3, 3], 2.5);
timeContainer.setCurrentTime(3);
checkStartTime([3, 3], 3);
timeContainer.setCurrentTime(4);
checkHasNoCurrentInterval(4);
timeContainer.setCurrentTime(5);
checkHasNoCurrentInterval(5);
t.done();
}, 0);
});
});
</script>
...@@ -78,7 +78,7 @@ function moveAnimationTimelineAndSample(index) { ...@@ -78,7 +78,7 @@ function moveAnimationTimelineAndSample(index) {
try { try {
newTime += animation.getStartTime(); newTime += animation.getStartTime();
} catch(e) { } catch(e) {
debug('Exception thrown: ' + e); // No current interval.
} }
// The sample time is relative to the start time of the animation, take that into account. // The sample time is relative to the start time of the animation, take that into account.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment