Bug 1211886 - Make infinite animations that iterated at least once pausable; r=miker

--HG--
extra : commitid : 6fsU8jaKtl3
extra : rebase_source : 2942d9a1b483720118d091beff6e4beb2d5c9944
This commit is contained in:
Patrick Brosset 2015-10-28 12:58:39 +01:00
Родитель 8ca07522b9
Коммит d17a5d87d5
5 изменённых файлов: 81 добавлений и 11 удалений

Просмотреть файл

@ -179,7 +179,7 @@ var AnimationsPanel = {
onTimelineDataChanged: function(e, data) {
this.timelineData = data;
let {isMoving, isUserDrag, time} = data;
let {isMoving, isPaused, isUserDrag, time} = data;
this.playTimelineButtonEl.classList.toggle("paused", !isMoving);

Просмотреть файл

@ -684,13 +684,22 @@ AnimationsTimeline.prototype = {
this.animations.every(({state}) => state.currentTime === 0);
},
hasInfiniteAnimations: function() {
return this.animations.some(({state}) => !state.iterationCount);
},
startAnimatingScrubber: function(time) {
let x = TimeScale.startTimeToDistance(time, this.timeHeaderEl.offsetWidth);
this.scrubberEl.style.left = x + "px";
if (time < TimeScale.minStartTime ||
time > TimeScale.maxEndTime ||
!this.isAtLeastOneAnimationPlaying()) {
// Only stop the scrubber if it's out of bounds or all animations have been
// paused, but not if at least an animation is infinite.
let isOutOfBounds = time < TimeScale.minStartTime ||
time > TimeScale.maxEndTime;
let isAllPaused = !this.isAtLeastOneAnimationPlaying();
let hasInfinite = this.hasInfiniteAnimations();
if (isAllPaused || (isOutOfBounds && !hasInfinite)) {
this.stopAnimatingScrubber();
this.emit("timeline-data-changed", {
isPaused: !this.isAtLeastOneAnimationPlaying(),

Просмотреть файл

@ -8,11 +8,17 @@
// button can be clicked. Check that when it is, the current animations
// displayed in the timeline get their playstates changed accordingly, and check
// that the scrubber resumes/stops moving.
// Also checks that the button goes to the right state when the scrubber has
// reached the end of the timeline: continues to be in playing mode for infinite
// animations, goes to paused mode otherwise.
// And test that clicking the button once the scrubber has reached the end of
// the timeline does the right thing.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
let {panel} = yield openAnimationInspector();
let {panel, inspector} = yield openAnimationInspector();
let timeline = panel.animationsTimelineComponent;
let btn = panel.playTimelineButtonEl;
ok(btn, "The play/pause button exists");
@ -32,4 +38,57 @@ add_task(function*() {
ok(!btn.classList.contains("paused"),
"The play/pause button is in its playing state again");
yield assertScrubberMoving(panel, true);
// Some animations on the test page are infinite, so the scrubber won't stop
// at the end of the timeline, and the button should remain in play mode.
info("Select an infinite animation, reload the page and wait for the " +
"animation to complete");
yield selectNode(".multi", inspector);
yield reloadTab(inspector);
yield waitForOutOfBoundScrubber(timeline);
ok(!btn.classList.contains("paused"),
"The button is in its playing state still, animations are infinite.");
yield assertScrubberMoving(panel, true);
info("Click on the button after the scrubber has moved out of bounds");
yield clickTimelinePlayPauseButton(panel);
ok(btn.classList.contains("paused"),
"The button can be paused after the scrubber has moved out of bounds");
yield assertScrubberMoving(panel, false);
// For a finite animation though, once the scrubber reaches the end of the
// timeline, it should go back to paused mode.
info("Select a finite animation, reload the page and wait for the " +
"animation to complete");
yield selectNode(".negative-delay", inspector);
yield reloadTab(inspector);
yield waitForOutOfBoundScrubber(timeline);
ok(btn.classList.contains("paused"),
"The button is in paused state once finite animations are done");
yield assertScrubberMoving(panel, false);
info("Click again on the button to play the animation from the start again");
yield clickTimelinePlayPauseButton(panel);
ok(!btn.classList.contains("paused"),
"Clicking the button once finite animations are done should restart them");
yield assertScrubberMoving(panel, true);
});
function waitForOutOfBoundScrubber({win, scrubberEl}) {
return new Promise(resolve => {
function check() {
let pos = scrubberEl.getBoxQuads()[0].bounds.right;
let width = win.document.documentElement.offsetWidth;
if (pos >= width) {
setTimeout(resolve, 50);
} else {
setTimeout(check, 50);
}
}
check();
});
}

Просмотреть файл

@ -22,10 +22,7 @@ add_task(function*() {
"The toggle button now is in its paused state");
info("Reloading the page");
let onNewRoot = inspector.once("new-root");
yield reloadTab();
yield onNewRoot;
yield inspector.once("inspector-updated");
yield reloadTab(inspector);
ok(!panel.toggleAllButtonEl.classList.contains("paused"),
"The toggle button is back in its running state");

Просмотреть файл

@ -85,9 +85,14 @@ function addTab(url) {
/**
* Reload the current tab location.
* @param {InspectorPanel} inspector The instance of InspectorPanel currently
* loaded in the toolbox
*/
function reloadTab() {
return executeInContent("devtools:test:reload", {}, {}, false);
function* reloadTab(inspector) {
let onNewRoot = inspector.once("new-root");
yield executeInContent("devtools:test:reload", {}, {}, false);
yield onNewRoot;
yield inspector.once("inspector-updated");
}
/**