Bug 1120852 - 2 - Don't start the animation timeline UI before the animation delay has passed; r=bgrins

This commit is contained in:
Patrick Brosset 2015-01-15 10:40:55 +01:00
parent 9b1ad3b095
commit aacd37d7d8
6 changed files with 125 additions and 27 deletions

View File

@ -193,21 +193,26 @@ PlayerWidget.prototype = {
});
let titleHTML = "";
// Name
// Name.
if (state.name) {
// Css animations have names
// Css animations have names.
titleHTML += L10N.getStr("player.animationNameLabel");
titleHTML += "<strong>" + state.name + "</strong>";
} else {
// Css transitions don't
// Css transitions don't.
titleHTML += L10N.getStr("player.transitionNameLabel");
}
// Duration and iteration count
// Duration, delay and iteration count.
titleHTML += "<span class='meta-data'>";
titleHTML += L10N.getStr("player.animationDurationLabel");
titleHTML += "<strong>" + L10N.getFormatStr("player.timeLabel",
this.getFormattedTime(state.duration)) + "</strong>";
if (state.delay) {
titleHTML += L10N.getStr("player.animationDelayLabel");
titleHTML += "<strong>" + L10N.getFormatStr("player.timeLabel",
this.getFormattedTime(state.delay)) + "</strong>";
}
titleHTML += L10N.getStr("player.animationIterationCountLabel");
let count = state.iterationCount || L10N.getStr("player.infiniteIterationCount");
titleHTML += "<strong>" + count + "</strong>";
@ -215,7 +220,7 @@ PlayerWidget.prototype = {
titleEl.innerHTML = titleHTML;
// Timeline widget
// Timeline widget.
let timelineEl = createNode({
parent: this.el,
attributes: {
@ -223,7 +228,7 @@ PlayerWidget.prototype = {
}
});
// Playback control buttons container
// Playback control buttons container.
let playbackControlsEl = createNode({
parent: timelineEl,
attributes: {
@ -241,7 +246,7 @@ PlayerWidget.prototype = {
}
});
// Sliders container
// Sliders container.
let slidersContainerEl = createNode({
parent: timelineEl,
attributes: {
@ -249,9 +254,9 @@ PlayerWidget.prototype = {
}
});
let max = state.duration; // Infinite iterations
let max = state.duration; // Infinite iterations.
if (state.iterationCount) {
// Finite iterations
// Finite iterations.
max = state.iterationCount * state.duration;
}
@ -267,6 +272,7 @@ PlayerWidget.prototype = {
"min": "0",
"max": max,
"step": "10",
"value": "0",
// The currentTime isn't settable yet, so disable the timeline slider
"disabled": "true"
}
@ -280,7 +286,7 @@ PlayerWidget.prototype = {
}
});
this.timeDisplayEl.textContent = L10N.getFormatStr("player.timeLabel",
this.getFormattedTime());
this.getFormattedTime(0));
this.containerEl.appendChild(this.el);
},
@ -290,14 +296,11 @@ PlayerWidget.prototype = {
* @param {Number} time Defaults to the player's currentTime.
* @return {String} The formatted time, e.g. "10.55"
*/
getFormattedTime: function(time=this.player.state.currentTime) {
let str = time/1000 + "";
str = str.split(".");
if (str.length === 1) {
return str[0] + ".00";
} else {
return str[0] + "." + str[1].substring(0, 2);
}
getFormattedTime: function(time) {
return (time/1000).toLocaleString(undefined, {
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
},
/**
@ -390,6 +393,12 @@ PlayerWidget.prototype = {
displayTime: function(time) {
let state = this.player.state;
// If the animation is delayed, don't start displaying the time until the
// delay has passed.
if (state.delay) {
time = Math.max(0, time - state.delay);
}
this.timeDisplayEl.textContent = L10N.getFormatStr("player.timeLabel",
this.getFormattedTime(time));
if (!state.iterationCount && time !== state.duration) {

View File

@ -11,8 +11,10 @@ support-files =
[browser_animation_play_pause_button.js]
[browser_animation_playerFronts_are_refreshed.js]
[browser_animation_playerWidgets_destroy.js]
[browser_animation_playerWidgets_meta_data.js]
[browser_animation_refresh_when_active.js]
[browser_animation_same_nb_of_playerWidgets_and_playerFronts.js]
[browser_animation_shows_player_on_valid_node.js]
[browser_animation_timeline_animates.js]
[browser_animation_ui_updates_when_animation_changes.js]
[browser_animation_timeline_waits_for_delay.js]
[browser_animation_ui_updates_when_animation_changes.js]

View File

@ -0,0 +1,49 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test that player widgets show the right player meta-data (name, duration,
// iteration count, delay).
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
let {inspector, panel} = yield openAnimationInspector();
info("Select the simple animated node");
yield selectNode(".animated", inspector);
let titleEl = panel.playerWidgets[0].el.querySelector(".animation-title");
ok(titleEl,
"The player widget has a title element, where meta-data should be displayed");
let nameEl = titleEl.querySelector("strong");
ok(nameEl, "The first <strong> tag was retrieved, it should contain the name");
is(nameEl.textContent, "simple-animation", "The animation name is correct");
let metaDataEl = titleEl.querySelector(".meta-data");
ok(metaDataEl, "The meta-data element exists");
let metaDataEls = metaDataEl.querySelectorAll("strong");
is(metaDataEls.length, 2, "2 meta-data elements were found");
is(metaDataEls[0].textContent, "2.00s",
"The first meta-data is the duration, and is correct");
info("Select the node with the delayed animation");
yield selectNode(".delayed", inspector);
titleEl = panel.playerWidgets[0].el.querySelector(".animation-title");
nameEl = titleEl.querySelector("strong");
is(nameEl.textContent, "simple-animation", "The animation name is correct");
metaDataEls = titleEl.querySelectorAll(".meta-data strong");
is(metaDataEls.length, 3,
"3 meta-data elements were found for the delayed animation");
is(metaDataEls[0].textContent, "3.00s",
"The first meta-data is the duration, and is correct");
is(metaDataEls[1].textContent, "60.00s",
"The second meta-data is the delay, and is correct");
is(metaDataEls[2].textContent, "10",
"The third meta-data is the iteration count, and is correct");
});

View File

@ -0,0 +1,24 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test that the currentTime timeline doesn't move if the animation is currently
// waiting for an animation-delay.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
let {inspector, panel} = yield openAnimationInspector();
info("Select the delayed animation node");
yield selectNode(".delayed", inspector);
let widget = panel.playerWidgets[0];
let timeline = widget.currentTimeEl;
is(timeline.value, 0, "The timeline is at 0 since the animation hasn't started");
let timeLabel = widget.timeDisplayEl;
is(timeLabel.textContent, "0.00s", "The current time is 0");
});

View File

@ -4,8 +4,8 @@
<meta charset="UTF-8">
<style>
.ball {
width: 100px;
height: 100px;
width: 80px;
height: 80px;
border-radius: 50%;
background: #f06;
@ -13,25 +13,33 @@
}
.still {
top: 50px;
left: 50px;
top: 0;
left: 10px;
}
.animated {
top: 200px;
left: 200px;
top: 100px;
left: 10px;
animation: simple-animation 2s infinite alternate;
}
.multi {
top: 100px;
left: 400px;
top: 200px;
left: 10px;
animation: simple-animation 2s infinite alternate,
other-animation 5s infinite alternate;
}
.delayed {
top: 300px;
left: 10px;
background: rebeccapurple;
animation: simple-animation 3s 60s 10;
}
@keyframes simple-animation {
100% {
transform: translateX(300px);
@ -50,5 +58,6 @@
<div class="ball still"></div>
<div class="ball animated"></div>
<div class="ball multi"></div>
<div class="ball delayed"></div>
</body>
</html>

View File

@ -26,6 +26,11 @@ player.transitionNameLabel=Transition
# displayed before the animation duration.
player.animationDurationLabel=Duration:
# LOCALIZATION NOTE (player.animationDelayLabel):
# This string is displayed in each animation player widget. It is the label
# displayed before the animation delay.
player.animationDelayLabel=Delay:
# LOCALIZATION NOTE (player.animationIterationCountLabel):
# This string is displayed in each animation player widget. It is the label
# displayed before the number of times the animation is set to repeat.