Bug 1232681 - Display script-generated animations correctly. r=pbro

MozReview-Commit-ID: 2pk7sxVTHTk
This commit is contained in:
Nicolas Chevobbe 2016-02-03 23:21:44 +01:00
Родитель 0eaf95a6a9
Коммит 19409bcb7c
9 изменённых файлов: 163 добавлений и 18 удалений

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

@ -148,13 +148,24 @@ AnimationTimeBlock.prototype = {
/**
* Get a formatted title for this animation. This will be either:
* "some-name", "some-name : CSS Transition", or "some-name : CSS Animation",
* depending if the server provides the type, and what type it is.
* "some-name", "some-name : CSS Transition", "some-name : CSS Animation",
* "some-name : Script Animation", or "Script Animation", depending
* if the server provides the type, what type it is and if the animation
* has a name
* @param {AnimationPlayerFront} animation
*/
function getFormattedAnimationTitle({state}) {
// Older servers don't send the type.
return state.type
? L10N.getFormatStr("timeline." + state.type + ".nameLabel", state.name)
: state.name;
// Older servers don't send a type, and only know about
// CSSAnimations and CSSTransitions, so it's safe to use
// just the name.
if (!state.type) {
return state.name;
}
// Script-generated animations may not have a name.
if (state.type === "scriptanimation" && !state.name) {
return L10N.getStr("timeline.scriptanimation.unnamedLabel");
}
return L10N.getFormatStr(`timeline.${state.type}.nameLabel`, state.name);
}

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

@ -8,6 +8,7 @@ support-files =
doc_modify_playbackRate.html
doc_negative_animation.html
doc_simple_animation.html
doc_multiple_animation_types.html
head.js
[browser_animation_animated_properties_displayed.js]

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

@ -7,11 +7,41 @@
// Test that player widgets are displayed right when the animation panel is
// initialized, if the selected node (<body> by default) is animated.
const { ANIMATION_TYPES } = require("devtools/server/actors/animation");
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_body_animation.html");
yield new Promise(resolve => {
SpecialPowers.pushPrefEnv({"set": [
["dom.animations-api.core.enabled", true]
]}, resolve);
});
yield addTab(TEST_URL_ROOT + "doc_multiple_animation_types.html");
let {panel} = yield openAnimationInspector();
is(panel.animationsTimelineComponent.animations.length, 1,
"One animation is handled by the timeline after init");
assertAnimationsDisplayed(panel, 1, "One animation is displayed after init");
is(panel.animationsTimelineComponent.animations.length, 3,
"Three animations are handled by the timeline after init");
assertAnimationsDisplayed(panel, 3,
"Three animations are displayed after init");
is(
panel.animationsTimelineComponent
.animationsEl
.querySelectorAll(`.animation.${ANIMATION_TYPES.SCRIPT_ANIMATION}`)
.length,
1,
"One script-generated animation is displayed");
is(
panel.animationsTimelineComponent
.animationsEl
.querySelectorAll(`.animation.${ANIMATION_TYPES.CSS_ANIMATION}`)
.length,
1,
"One CSS animation is displayed");
is(
panel.animationsTimelineComponent
.animationsEl
.querySelectorAll(`.animation.${ANIMATION_TYPES.CSS_TRANSITION}`)
.length,
1,
"One CSS transition is displayed");
});

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

@ -0,0 +1,58 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
.ball {
width: 80px;
height: 80px;
border-radius: 50%;
}
.script-animation {
background: #f06;
}
.css-transition {
background: #006;
transition: background-color 20s;
}
.css-animation {
background: #a06;
animation: flash 10s forwards;
}
@keyframes flash {
0% {
opacity: 1;
}
50% {
opacity: 0;
}
100% {
opacity: 1;
}
}
</style>
</head>
<body>
<div class="ball script-animation"></div>
<div class="ball css-animation"></div>
<div class="ball css-transition"></div>
<script>
setTimeout(function(){
document.querySelector(".css-transition").style.backgroundColor = "yellow";
}, 0);
document.querySelector(".script-animation").animate([
{ opacity: 1, offset: 0 },
{ opacity: .1, offset: 1 }
], {
duration: 10000,
fill: "forwards"
});
</script>
</body>
</html>

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

@ -108,6 +108,17 @@ timeline.cssanimation.nameLabel=%S - CSS Animation
# %S will be replaced by the name of the transition at run-time.
timeline.csstransition.nameLabel=%S - CSS Transition
# LOCALIZATION NOTE (timeline.scriptanimation.nameLabel):
# This string is displayed in a tooltip of the animation panel that is shown
# when hovering over the name of a script-generated animation in the timeline UI.
# %S will be replaced by the name of the animation at run-time.
timeline.scriptanimation.nameLabel=%S - Script Animation
# LOCALIZATION NOTE (timeline.scriptanimation.unnamedLabel):
# This string is displayed in a tooltip of the animation panel that is shown
# when hovering over an unnamed script-generated animation in the timeline UI.
timeline.scriptanimation.unnamedLabel=Script Animation
# LOCALIZATION NOTE (timeline.unknown.nameLabel):
# This string is displayed in a tooltip of the animation panel that is shown
# when hovering over the name of an unknown animation type in the timeline UI.

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

@ -42,6 +42,11 @@
--timeline-background-color: var(--theme-highlight-blue);
}
.animation.scriptanimation {
--timeline-border-color: var(--theme-highlight-green);
--timeline-background-color: var(--theme-graphs-green);
}
html {
height: 100%;
}
@ -529,6 +534,10 @@ body {
background-color: var(--theme-highlight-blue);
}
.keyframes.scriptanimation {
background-color: var(--theme-graphs-green);
}
.keyframes .frame {
position: absolute;
top: 0;

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

@ -39,6 +39,7 @@ const events = require("sdk/event/core");
const ANIMATION_TYPES = {
CSS_ANIMATION: "cssanimation",
CSS_TRANSITION: "csstransition",
SCRIPT_ANIMATION: "scriptanimation",
UNKNOWN: "unknown"
};
exports.ANIMATION_TYPES = ANIMATION_TYPES;
@ -119,19 +120,28 @@ var AnimationPlayerActor = ActorClass({
return data;
},
isAnimation: function(player = this.player) {
isCssAnimation: function(player = this.player) {
return player instanceof this.window.CSSAnimation;
},
isTransition: function(player = this.player) {
isCssTransition: function(player = this.player) {
return player instanceof this.window.CSSTransition;
},
isScriptAnimation: function(player = this.player) {
return player instanceof this.window.Animation && !(
player instanceof this.window.CSSAnimation ||
player instanceof this.window.CSSTransition
);
},
getType: function() {
if (this.isAnimation()) {
if (this.isCssAnimation()) {
return ANIMATION_TYPES.CSS_ANIMATION;
} else if (this.isTransition()) {
} else if (this.isCssTransition()) {
return ANIMATION_TYPES.CSS_TRANSITION;
} else if (this.isScriptAnimation()) {
return ANIMATION_TYPES.SCRIPT_ANIMATION;
}
return ANIMATION_TYPES.UNKNOWN;
@ -146,9 +156,9 @@ var AnimationPlayerActor = ActorClass({
getName: function() {
if (this.player.id) {
return this.player.id;
} else if (this.isAnimation()) {
} else if (this.isCssAnimation()) {
return this.player.animationName;
} else if (this.isTransition()) {
} else if (this.isCssTransition()) {
return this.player.transitionProperty;
}
@ -626,9 +636,9 @@ var AnimationsActor = exports.AnimationsActor = ActorClass({
// a "removed" event for the one we already have.
let index = this.actors.findIndex(a => {
let isSameType = a.player.constructor === player.constructor;
let isSameName = (a.isAnimation() &&
let isSameName = (a.isCssAnimation() &&
a.player.animationName === player.animationName) ||
(a.isTransition() &&
(a.isCssTransition() &&
a.player.transitionProperty === player.transitionProperty);
let isSameNode = a.player.effect.target === player.effect.target;

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

@ -24,6 +24,9 @@ function run_test() {
}
};
window.CSSAnimation.prototype = Object.create(window.Animation.prototype);
window.CSSTransition.prototype = Object.create(window.Animation.prototype);
// Helper to get a mock DOM node.
function getMockNode() {
return {
@ -46,6 +49,11 @@ function run_test() {
animation: new window.Animation(),
props: { id: "animation-id" },
expectedName: "animation-id"
}, {
desc: "Animation without an id",
animation: new window.Animation(),
props: {},
expectedName: ""
}, {
desc: "CSSTransition with an id",
animation: new window.CSSTransition(),

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

@ -24,6 +24,9 @@ function run_test() {
}
};
window.CSSAnimation.prototype = Object.create(window.Animation.prototype);
window.CSSTransition.prototype = Object.create(window.Animation.prototype);
// Helper to get a mock DOM node.
function getMockNode() {
return {
@ -47,6 +50,10 @@ function run_test() {
desc: "Test CSSTransition type",
animation: new window.CSSTransition(),
expectedType: ANIMATION_TYPES.CSS_TRANSITION
}, {
desc: "Test ScriptAnimation type",
animation: new window.Animation(),
expectedType: ANIMATION_TYPES.SCRIPT_ANIMATION
}, {
desc: "Test unknown type",
animation: {effect: {target: getMockNode()}},