зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1232681 - Display script-generated animations correctly. r=pbro
MozReview-Commit-ID: 2pk7sxVTHTk
This commit is contained in:
Родитель
0eaf95a6a9
Коммит
19409bcb7c
|
@ -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()}},
|
||||
|
|
Загрузка…
Ссылка в новой задаче