Bug 1156757 - Turn ON the animation inspector UI v3 by default and remove v2; r=past

--HG--
extra : commitid : CPhS9J1Uiud
extra : rebase_source : b97de661479f5718c55ace89fc330c5fa1e130fd
extra : histedit_source : 709cc4edcf93b6e69f2852c8488c6dbdb7358cf6
This commit is contained in:
Patrick Brosset 2015-09-18 13:12:36 +02:00
Родитель c99e0fba8c
Коммит 82e16df980
62 изменённых файлов: 106 добавлений и 1984 удалений

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

@ -1380,8 +1380,6 @@ pref("devtools.inspector.showUserAgentStyles", false);
pref("devtools.inspector.showAllAnonymousContent", false);
// Enable the MDN docs tooltip
pref("devtools.inspector.mdnDocsTooltip.enabled", true);
// Show the new animation inspector UI
pref("devtools.inspector.animationInspectorV3", false);
// DevTools default color unit
pref("devtools.defaultColorUnit", "hex");

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

@ -23,7 +23,6 @@ loader.lazyRequireGetter(this, "AnimationsFront",
const STRINGS_URI = "chrome://browser/locale/devtools/animationinspector.properties";
const L10N = new ViewHelpers.L10N(STRINGS_URI);
const V3_UI_PREF = "devtools.inspector.animationInspectorV3";
// Global toolbox/inspector, set when startup is called.
var gToolbox, gInspector;
@ -99,9 +98,6 @@ var getServerTraits = Task.async(function*(target) {
traits[name] = yield target.actorHasMethod(actor, method);
}
// Special pref-based UI trait.
traits.isNewUI = Services.prefs.getBoolPref(V3_UI_PREF);
return traits;
});
@ -113,9 +109,6 @@ var getServerTraits = Task.async(function*(target) {
*
* AnimationPlayerFronts are available in AnimationsController.animationPlayers.
*
* Note also that all AnimationPlayerFronts handled by the controller are set to
* auto-refresh (except when the sidebar panel is not visible).
*
* Usage example:
*
* AnimationsController.on(AnimationsController.PLAYERS_UPDATED_EVENT,
@ -182,7 +175,7 @@ var AnimationsController = {
startListeners: function() {
// Re-create the list of players when a new node is selected, except if the
// sidebar isn't visible. And set the players to auto-refresh when needed.
// sidebar isn't visible.
gInspector.selection.on("new-node-front", this.onNewNodeFront);
gInspector.sidebar.on("select", this.onPanelVisibilityChange);
gToolbox.on("select", this.onPanelVisibilityChange);
@ -206,9 +199,6 @@ var AnimationsController = {
onPanelVisibilityChange: Task.async(function*() {
if (this.isPanelVisible()) {
this.onNewNodeFront();
this.startAllAutoRefresh();
} else {
this.stopAllAutoRefresh();
}
}),
@ -304,7 +294,6 @@ var AnimationsController = {
this.animationPlayers = yield this.animationsFront
.getAnimationPlayersForNode(nodeFront);
this.startAllAutoRefresh();
// Start listening for animation mutations only after the first method call
// otherwise events won't be sent.
@ -320,15 +309,9 @@ var AnimationsController = {
for (let {type, player} of changes) {
if (type === "added") {
this.animationPlayers.push(player);
if (!this.traits.isNewUI) {
player.startAutoRefresh();
}
}
if (type === "removed") {
if (!this.traits.isNewUI) {
player.stopAutoRefresh();
}
yield player.release();
let index = this.animationPlayers.indexOf(player);
this.animationPlayers.splice(index, 1);
@ -358,26 +341,6 @@ var AnimationsController = {
return time;
},
startAllAutoRefresh: function() {
if (this.traits.isNewUI) {
return;
}
for (let front of this.animationPlayers) {
front.startAutoRefresh();
}
},
stopAllAutoRefresh: function() {
if (this.traits.isNewUI) {
return;
}
for (let front of this.animationPlayers) {
front.stopAutoRefresh();
}
},
destroyAnimationPlayers: Task.async(function*() {
// Let the server know that we're not interested in receiving updates about
// players for the current node. We're either being destroyed or a new node
@ -385,7 +348,7 @@ var AnimationsController = {
if (this.traits.hasMutationEvents) {
yield this.animationsFront.stopAnimationPlayerUpdates();
}
this.stopAllAutoRefresh();
for (let front of this.animationPlayers) {
yield front.release();
}

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

@ -8,13 +8,7 @@
"use strict";
const {createNode} = require("devtools/animationinspector/utils");
const {
PlayerMetaDataHeader,
PlaybackRateSelector,
AnimationTargetNode,
AnimationsTimeline
} = require("devtools/animationinspector/components");
const {AnimationsTimeline} = require("devtools/animationinspector/components");
/**
* The main animations panel UI.
@ -56,10 +50,8 @@ var AnimationsPanel = {
let hUtils = gToolbox.highlighterUtils;
this.togglePicker = hUtils.togglePicker.bind(hUtils);
if (AnimationsController.traits.isNewUI) {
this.animationsTimelineComponent = new AnimationsTimeline(gInspector);
this.animationsTimelineComponent.init(this.playersEl);
}
this.animationsTimelineComponent = new AnimationsTimeline(gInspector);
this.animationsTimelineComponent.init(this.playersEl);
this.startListeners();
@ -83,10 +75,9 @@ var AnimationsPanel = {
this.stopListeners();
if (this.animationsTimelineComponent) {
this.animationsTimelineComponent.destroy();
this.animationsTimelineComponent = null;
}
this.animationsTimelineComponent.destroy();
this.animationsTimelineComponent = null;
yield this.destroyPlayerWidgets();
this.playersEl = this.errorMessageEl = null;
@ -108,10 +99,8 @@ var AnimationsPanel = {
this.playTimelineButtonEl.addEventListener("click", this.playPauseTimeline);
gToolbox.target.on("navigate", this.onTabNavigated);
if (this.animationsTimelineComponent) {
this.animationsTimelineComponent.on("timeline-data-changed",
this.onTimelineDataChanged);
}
this.animationsTimelineComponent.on("timeline-data-changed",
this.onTimelineDataChanged);
},
stopListeners: function() {
@ -126,18 +115,14 @@ var AnimationsPanel = {
this.playTimelineButtonEl.removeEventListener("click", this.playPauseTimeline);
gToolbox.target.off("navigate", this.onTabNavigated);
if (this.animationsTimelineComponent) {
this.animationsTimelineComponent.off("timeline-data-changed",
this.onTimelineDataChanged);
}
this.animationsTimelineComponent.off("timeline-data-changed",
this.onTimelineDataChanged);
},
togglePlayers: function(isVisible) {
if (isVisible) {
document.body.removeAttribute("empty");
if (AnimationsController.traits.isNewUI) {
document.body.setAttribute("timeline", "true");
}
document.body.setAttribute("timeline", "true");
} else {
document.body.setAttribute("empty", "true");
document.body.removeAttribute("timeline");
@ -153,24 +138,7 @@ var AnimationsPanel = {
},
toggleAll: Task.async(function*() {
let btnClass = this.toggleAllButtonEl.classList;
if (!AnimationsController.traits.isNewUI) {
// Toggling all animations is async and it may be some time before each of
// the current players get their states updated, so toggle locally too, to
// avoid the timelines from jumping back and forth.
if (this.playerWidgets) {
let currentWidgetStateChange = [];
for (let widget of this.playerWidgets) {
currentWidgetStateChange.push(btnClass.contains("paused")
? widget.play() : widget.pause());
}
yield promise.all(currentWidgetStateChange)
.catch(error => console.error(error));
}
}
btnClass.toggle("paused");
this.toggleAllButtonEl.classList.toggle("paused");
yield AnimationsController.toggleAll();
}),
@ -187,7 +155,7 @@ var AnimationsPanel = {
// Now that the playState have been changed make sure the player (the
// fronts) are up to date, and then refresh the UI.
for (let player of AnimationsController.animationPlayers) {
yield player.refreshState(true);
yield player.refreshState();
}
yield this.refreshAnimations();
}),
@ -222,11 +190,9 @@ var AnimationsPanel = {
yield this.destroyPlayerWidgets();
// Re-render the timeline component.
if (this.animationsTimelineComponent) {
this.animationsTimelineComponent.render(
AnimationsController.animationPlayers,
AnimationsController.documentCurrentTime);
}
this.animationsTimelineComponent.render(
AnimationsController.animationPlayers,
AnimationsController.documentCurrentTime);
// If there are no players to show, show the error message instead and
// return.
@ -237,21 +203,6 @@ var AnimationsPanel = {
return;
}
// Otherwise, create player widgets (only when isNewUI is false, the
// timeline has already been re-rendered).
if (!AnimationsController.traits.isNewUI) {
this.playerWidgets = [];
let initPromises = [];
for (let player of AnimationsController.animationPlayers) {
let widget = new PlayerWidget(player, this.playersEl);
initPromises.push(widget.initialize());
this.playerWidgets.push(widget);
}
yield initPromises;
}
this.emit(this.UI_UPDATED_EVENT);
done();
}),
@ -269,407 +220,3 @@ var AnimationsPanel = {
};
EventEmitter.decorate(AnimationsPanel);
/**
* An AnimationPlayer UI widget
*/
function PlayerWidget(player, containerEl) {
EventEmitter.decorate(this);
this.player = player;
this.containerEl = containerEl;
this.onStateChanged = this.onStateChanged.bind(this);
this.onPlayPauseBtnClick = this.onPlayPauseBtnClick.bind(this);
this.onRewindBtnClick = this.onRewindBtnClick.bind(this);
this.onFastForwardBtnClick = this.onFastForwardBtnClick.bind(this);
this.onCurrentTimeChanged = this.onCurrentTimeChanged.bind(this);
this.onPlaybackRateChanged = this.onPlaybackRateChanged.bind(this);
this.metaDataComponent = new PlayerMetaDataHeader();
if (AnimationsController.traits.hasSetPlaybackRate) {
this.rateComponent = new PlaybackRateSelector();
}
if (AnimationsController.traits.hasTargetNode) {
this.targetNodeComponent = new AnimationTargetNode(gInspector);
}
}
PlayerWidget.prototype = {
initialize: Task.async(function*() {
if (this.initialized) {
return;
}
this.initialized = true;
this.createMarkup();
this.startListeners();
}),
destroy: Task.async(function*() {
if (this.destroyed) {
return;
}
this.destroyed = true;
this.stopTimelineAnimation();
this.stopListeners();
this.metaDataComponent.destroy();
if (this.rateComponent) {
this.rateComponent.destroy();
}
if (this.targetNodeComponent) {
this.targetNodeComponent.destroy();
}
this.el.remove();
this.playPauseBtnEl = this.rewindBtnEl = this.fastForwardBtnEl = null;
this.currentTimeEl = this.timeDisplayEl = null;
this.containerEl = this.el = this.player = null;
}),
startListeners: function() {
this.player.on(this.player.AUTO_REFRESH_EVENT, this.onStateChanged);
this.playPauseBtnEl.addEventListener("click", this.onPlayPauseBtnClick);
if (AnimationsController.traits.hasSetCurrentTime) {
this.rewindBtnEl.addEventListener("click", this.onRewindBtnClick);
this.fastForwardBtnEl.addEventListener("click", this.onFastForwardBtnClick);
this.currentTimeEl.addEventListener("input", this.onCurrentTimeChanged);
}
if (this.rateComponent) {
this.rateComponent.on("rate-changed", this.onPlaybackRateChanged);
}
},
stopListeners: function() {
this.player.off(this.player.AUTO_REFRESH_EVENT, this.onStateChanged);
this.playPauseBtnEl.removeEventListener("click", this.onPlayPauseBtnClick);
if (AnimationsController.traits.hasSetCurrentTime) {
this.rewindBtnEl.removeEventListener("click", this.onRewindBtnClick);
this.fastForwardBtnEl.removeEventListener("click", this.onFastForwardBtnClick);
this.currentTimeEl.removeEventListener("input", this.onCurrentTimeChanged);
}
if (this.rateComponent) {
this.rateComponent.off("rate-changed", this.onPlaybackRateChanged);
}
},
createMarkup: function() {
let state = this.player.state;
this.el = createNode({
parent: this.containerEl,
attributes: {
"class": "player-widget " + state.playState
}
});
if (this.targetNodeComponent) {
this.targetNodeComponent.init(this.el);
this.targetNodeComponent.render(this.player);
}
this.metaDataComponent.init(this.el);
this.metaDataComponent.render(state);
// Timeline widget.
let timelineEl = createNode({
parent: this.el,
attributes: {
"class": "timeline"
}
});
// Playback control buttons container.
let playbackControlsEl = createNode({
parent: timelineEl,
attributes: {
"class": "playback-controls"
}
});
// Control buttons.
this.playPauseBtnEl = createNode({
parent: playbackControlsEl,
nodeType: "button",
attributes: {
"class": "toggle devtools-button"
}
});
if (AnimationsController.traits.hasSetCurrentTime) {
this.rewindBtnEl = createNode({
parent: playbackControlsEl,
nodeType: "button",
attributes: {
"class": "rw devtools-button"
}
});
this.fastForwardBtnEl = createNode({
parent: playbackControlsEl,
nodeType: "button",
attributes: {
"class": "ff devtools-button"
}
});
}
if (this.rateComponent) {
this.rateComponent.init(playbackControlsEl);
this.rateComponent.render(state);
}
// Sliders container.
let slidersContainerEl = createNode({
parent: timelineEl,
attributes: {
"class": "sliders-container",
}
});
let max = state.duration;
if (state.iterationCount) {
// If there's a finite nb of iterations.
max = state.iterationCount * state.duration;
}
// For now, keyframes aren't exposed by the actor. So the only range <input>
// displayed in the container is the currentTime. When keyframes are
// available, one input per keyframe can be added here.
this.currentTimeEl = createNode({
nodeType: "input",
parent: slidersContainerEl,
attributes: {
"type": "range",
"class": "current-time",
"min": "0",
"max": max,
"step": "10",
"value": "0"
}
});
if (!AnimationsController.traits.hasSetCurrentTime) {
this.currentTimeEl.setAttribute("disabled", "true");
}
// Time display
this.timeDisplayEl = createNode({
parent: timelineEl,
attributes: {
"class": "time-display"
}
});
// Show the initial time.
this.displayTime(state.currentTime);
},
/**
* Executed when the playPause button is clicked.
* Note that tests may want to call this callback directly rather than
* simulating a click on the button since it returns the promise returned by
* play and paused.
* @return {Promise}
*/
onPlayPauseBtnClick: function() {
if (this.player.state.playState === "running") {
return this.pause();
}
return this.play();
},
onRewindBtnClick: function() {
this.setCurrentTime(0, true);
},
onFastForwardBtnClick: function() {
let state = this.player.state;
let time = state.duration;
if (state.iterationCount) {
time = state.iterationCount * state.duration;
}
this.setCurrentTime(time, true);
},
/**
* Executed when the current-time range input is changed.
*/
onCurrentTimeChanged: function(e) {
let time = e.target.value;
this.setCurrentTime(parseFloat(time), true);
},
/**
* Executed when the playback rate dropdown value changes in the playbackrate
* component.
*/
onPlaybackRateChanged: function(e, rate) {
this.setPlaybackRate(rate);
},
/**
* Whenever a player state update is received.
*/
onStateChanged: function() {
let state = this.player.state;
this.updateWidgetState(state);
this.metaDataComponent.render(state);
if (this.rateComponent) {
this.rateComponent.render(state);
}
switch (state.playState) {
case "finished":
this.stopTimelineAnimation();
this.displayTime(this.player.state.currentTime);
break;
case "running":
this.startTimelineAnimation();
break;
case "paused":
this.stopTimelineAnimation();
this.displayTime(this.player.state.currentTime);
break;
case "idle":
this.stopTimelineAnimation();
this.displayTime(0);
break;
}
},
/**
* Set the current time of the animation.
* @param {Number} time.
* @param {Boolean} shouldPause Should the player be paused too.
* @return {Promise} Resolves when the current time has been set.
*/
setCurrentTime: Task.async(function*(time, shouldPause) {
if (!AnimationsController.traits.hasSetCurrentTime) {
throw new Error("This server version doesn't support setting " +
"animations' currentTime");
}
if (shouldPause) {
this.stopTimelineAnimation();
yield this.pause();
}
if (this.player.state.delay) {
time += this.player.state.delay;
}
// Set the time locally first so it feels instant, even if the request to
// actually set the time is async.
this.displayTime(time);
yield this.player.setCurrentTime(time);
}),
/**
* Set the playback rate of the animation.
* @param {Number} rate.
* @return {Promise} Resolves when the rate has been set.
*/
setPlaybackRate: function(rate) {
if (!AnimationsController.traits.hasSetPlaybackRate) {
throw new Error("This server version doesn't support setting " +
"animations' playbackRate");
}
return this.player.setPlaybackRate(rate);
},
/**
* Pause the animation player via this widget.
* @return {Promise} Resolves when the player is paused, the button is
* switched to the right state, and the timeline animation is stopped.
*/
pause: function() {
// Switch to the right className on the element right away to avoid waiting
// for the next state update to change the playPause icon.
this.updateWidgetState({playState: "paused"});
this.stopTimelineAnimation();
return this.player.pause();
},
/**
* Play the animation player via this widget.
* @return {Promise} Resolves when the player is playing, the button is
* switched to the right state, and the timeline animation is started.
*/
play: function() {
// Switch to the right className on the element right away to avoid waiting
// for the next state update to change the playPause icon.
this.updateWidgetState({playState: "running"});
this.startTimelineAnimation();
return this.player.play();
},
updateWidgetState: function({playState}) {
this.el.className = "player-widget " + playState;
},
/**
* Make the timeline progress smoothly, even though the currentTime is only
* updated at some intervals. This uses a local animation loop.
*/
startTimelineAnimation: function() {
this.stopTimelineAnimation();
let state = this.player.state;
let start = performance.now();
let loop = () => {
this.rafID = requestAnimationFrame(loop);
let delta = (performance.now() - start) * state.playbackRate;
let now = state.currentTime + delta;
this.displayTime(now);
};
loop();
},
/**
* Display the time in the timeDisplayEl and in the currentTimeEl slider.
*/
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);
}
// For finite animations, make sure the displayed time does not go beyond
// the animation total duration (this may happen due to the local
// requestAnimationFrame loop).
if (state.iterationCount) {
time = Math.min(time, state.iterationCount * state.duration);
}
// Set the time label value.
this.timeDisplayEl.textContent = L10N.getFormatStr("player.timeLabel",
L10N.numberWithDecimals(time / 1000, 2));
// Set the timeline slider value.
if (!state.iterationCount && time !== state.duration) {
time = time % state.duration;
}
this.currentTimeEl.value = time;
},
/**
* Stop the animation loop that makes the timeline progress.
*/
stopTimelineAnimation: function() {
if (this.rafID) {
cancelAnimationFrame(this.rafID);
this.rafID = null;
}
}
};

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

@ -35,268 +35,6 @@ const MILLIS_TIME_FORMAT_MAX_DURATION = 4000;
// The minimum spacing between 2 time graduation headers in the timeline (px).
const TIME_GRADUATION_MIN_SPACING = 40;
/**
* UI component responsible for displaying and updating the player meta-data:
* name, duration, iterations, delay.
* The parent UI component for this should drive its updates by calling
* render(state) whenever it wants the component to update.
*/
function PlayerMetaDataHeader() {
// Store the various state pieces we need to only refresh the UI when things
// change.
this.state = {};
}
exports.PlayerMetaDataHeader = PlayerMetaDataHeader;
PlayerMetaDataHeader.prototype = {
init: function(containerEl) {
// The main title element.
this.el = createNode({
parent: containerEl,
attributes: {
"class": "animation-title"
}
});
// Animation name.
this.nameLabel = createNode({
parent: this.el,
nodeType: "span"
});
this.nameValue = createNode({
parent: this.el,
nodeType: "strong",
attributes: {
"style": "display:none;"
}
});
// Animation duration, delay and iteration container.
let metaData = createNode({
parent: this.el,
nodeType: "span",
attributes: {
"class": "meta-data"
}
});
// Animation is running on compositor
this.compositorIcon = createNode({
parent: metaData,
nodeType: "span",
attributes: {
"class": "compositor-icon",
"title": L10N.getStr("player.runningOnCompositorTooltip")
}
});
// Animation duration.
this.durationLabel = createNode({
parent: metaData,
nodeType: "span",
textContent: L10N.getStr("player.animationDurationLabel")
});
this.durationValue = createNode({
parent: metaData,
nodeType: "strong"
});
// Animation delay (hidden by default since there may not be a delay).
this.delayLabel = createNode({
parent: metaData,
nodeType: "span",
attributes: {
"style": "display:none;"
},
textContent: L10N.getStr("player.animationDelayLabel")
});
this.delayValue = createNode({
parent: metaData,
nodeType: "strong"
});
// Animation iteration count (also hidden by default since we don't display
// single iterations).
this.iterationLabel = createNode({
parent: metaData,
nodeType: "span",
attributes: {
"style": "display:none;"
},
textContent: L10N.getStr("player.animationIterationCountLabel")
});
this.iterationValue = createNode({
parent: metaData,
nodeType: "strong",
attributes: {
"style": "display:none;"
}
});
},
destroy: function() {
this.state = null;
this.el.remove();
this.el = null;
this.nameLabel = this.nameValue = null;
this.durationLabel = this.durationValue = null;
this.delayLabel = this.delayValue = null;
this.iterationLabel = this.iterationValue = null;
this.compositorIcon = null;
},
render: function(state) {
// Update the name if needed.
if (state.name !== this.state.name) {
if (state.name) {
// Animations (and transitions since bug 1122414) have names.
this.nameLabel.textContent = L10N.getStr("player.animationNameLabel");
this.nameValue.style.display = "inline";
this.nameValue.textContent = state.name;
} else {
// With older actors, Css transitions don't have names.
this.nameLabel.textContent = L10N.getStr("player.transitionNameLabel");
this.nameValue.style.display = "none";
}
}
// update the duration value if needed.
if (state.duration !== this.state.duration) {
this.durationValue.textContent = L10N.getFormatStr("player.timeLabel",
L10N.numberWithDecimals(state.duration / 1000, 2));
}
// Update the delay if needed.
if (state.delay !== this.state.delay) {
if (state.delay) {
this.delayLabel.style.display = "inline";
this.delayValue.style.display = "inline";
this.delayValue.textContent = L10N.getFormatStr("player.timeLabel",
L10N.numberWithDecimals(state.delay / 1000, 2));
} else {
// Hide the delay elements if there is no delay defined.
this.delayLabel.style.display = "none";
this.delayValue.style.display = "none";
}
}
// Update the iterationCount if needed.
if (state.iterationCount !== this.state.iterationCount) {
if (state.iterationCount !== 1) {
this.iterationLabel.style.display = "inline";
this.iterationValue.style.display = "inline";
let count = state.iterationCount ||
L10N.getStr("player.infiniteIterationCount");
this.iterationValue.innerHTML = count;
} else {
// Hide the iteration elements if iteration is 1.
this.iterationLabel.style.display = "none";
this.iterationValue.style.display = "none";
}
}
// Show the Running on compositor icon if needed.
if (state.isRunningOnCompositor !== this.state.isRunningOnCompositor) {
if (state.isRunningOnCompositor) {
this.compositorIcon.style.display = "inline";
} else {
// Hide the compositor icon
this.compositorIcon.style.display = "none";
}
}
this.state = state;
}
};
/**
* UI component responsible for displaying the playback rate drop-down in each
* player widget, updating it when the state changes, and emitting events when
* the user selects a new value.
* The parent UI component for this should drive its updates by calling
* render(state) whenever it wants the component to update.
*/
function PlaybackRateSelector() {
this.currentRate = null;
this.onSelectionChanged = this.onSelectionChanged.bind(this);
EventEmitter.decorate(this);
}
exports.PlaybackRateSelector = PlaybackRateSelector;
PlaybackRateSelector.prototype = {
PRESETS: [.1, .5, 1, 2, 5, 10],
init: function(containerEl) {
// This component is simple enough that we can re-create the markup every
// time it's rendered. So here we only store the parentEl.
this.parentEl = containerEl;
},
destroy: function() {
this.removeSelect();
this.parentEl = this.el = null;
},
removeSelect: function() {
if (this.el) {
this.el.removeEventListener("change", this.onSelectionChanged);
this.el.remove();
}
},
/**
* Get the ordered list of presets, including the current playbackRate if
* different from the existing presets.
*/
getCurrentPresets: function({playbackRate}) {
return [...new Set([...this.PRESETS, playbackRate])].sort((a, b) => a > b);
},
render: function(state) {
if (state.playbackRate === this.currentRate) {
return;
}
this.removeSelect();
this.el = createNode({
parent: this.parentEl,
nodeType: "select",
attributes: {
"class": "rate devtools-button"
}
});
for (let preset of this.getCurrentPresets(state)) {
let option = createNode({
parent: this.el,
nodeType: "option",
attributes: {
value: preset,
},
textContent: L10N.getFormatStr("player.playbackRateLabel", preset)
});
if (preset === state.playbackRate) {
option.setAttribute("selected", "");
}
}
this.el.addEventListener("change", this.onSelectionChanged);
this.currentRate = state.playbackRate;
},
onSelectionChanged: function() {
this.emit("rate-changed", parseFloat(this.el.value));
}
};
/**
* UI component responsible for displaying a preview of the target dom node of
* a given animation.

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

@ -11,34 +11,18 @@ support-files =
[browser_animation_controller_exposes_document_currentTime.js]
[browser_animation_empty_on_invalid_nodes.js]
[browser_animation_iterationCount_hidden_by_default.js]
[browser_animation_mutations_with_same_names.js]
[browser_animation_panel_exists.js]
[browser_animation_participate_in_inspector_update.js]
[browser_animation_play_pause_button.js]
[browser_animation_playerFronts_are_refreshed.js]
[browser_animation_playerWidgets_appear_on_panel_init.js]
[browser_animation_playerWidgets_compositor_icon.js]
[browser_animation_playerWidgets_destroy.js]
[browser_animation_playerWidgets_disables_on_finished.js]
[browser_animation_playerWidgets_dont_show_time_after_duration.js]
[browser_animation_playerWidgets_have_control_buttons.js]
[browser_animation_playerWidgets_meta_data.js]
[browser_animation_playerWidgets_scrubber_delayed.js]
[browser_animation_playerWidgets_scrubber_enabled.js]
[browser_animation_playerWidgets_scrubber_moves.js]
[browser_animation_playerWidgets_state_after_pause.js]
[browser_animation_playerWidgets_target_nodes.js]
[browser_animation_rate_select_shows_presets.js]
[browser_animation_refresh_on_added_animation.js]
[browser_animation_refresh_on_removed_animation.js]
[browser_animation_refresh_when_active.js]
[browser_animation_same_nb_of_playerWidgets_and_playerFronts.js]
[browser_animation_setting_currentTime_works_and_pauses.js]
[browser_animation_setting_playbackRate_works.js]
[browser_animation_shows_player_on_valid_node.js]
[browser_animation_target_highlight_select.js]
[browser_animation_timeline_displays_with_pref.js]
[browser_animation_timeline_header.js]
[browser_animation_timeline_pause_button.js]
[browser_animation_timeline_scrubber_exists.js]
@ -51,9 +35,5 @@ support-files =
[browser_animation_timeline_ui.js]
[browser_animation_toggle_button_resets_on_navigate.js]
[browser_animation_toggle_button_toggles_animations.js]
[browser_animation_toggle_button_updates_playerWidgets.js]
[browser_animation_toolbar_exists.js]
[browser_animation_ui_updates_when_animation_changes.js]
[browser_animation_ui_updates_when_animation_data_changes.js]
[browser_animation_ui_updates_when_animation_rate_changes.js]
[browser_animation_ui_updates_when_animation_time_changes.js]

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

@ -9,7 +9,7 @@
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
let {panel, controller} = yield openAnimationInspectorNewUI();
let {panel, controller} = yield openAnimationInspector();
ok(controller.documentCurrentTime, "The documentCurrentTime getter exists");
checkDocumentTimeIsCorrect(controller);

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

@ -11,27 +11,19 @@ add_task(function*() {
let {inspector, panel} = yield openAnimationInspector();
yield testEmptyPanel(inspector, panel);
({inspector, panel} = yield closeAnimationInspectorAndRestartWithNewUI());
yield testEmptyPanel(inspector, panel, true);
});
function* testEmptyPanel(inspector, panel, isNewUI=false) {
function* testEmptyPanel(inspector, panel) {
info("Select node .still and check that the panel is empty");
let stillNode = yield getNodeFront(".still", inspector);
let onUpdated = panel.once(panel.UI_UPDATED_EVENT);
yield selectNode(stillNode, inspector);
yield onUpdated;
if (isNewUI) {
is(panel.animationsTimelineComponent.animations.length, 0,
"No animation players stored in the timeline component for a still node");
is(panel.animationsTimelineComponent.animationsEl.childNodes.length, 0,
"No animation displayed in the timeline component for a still node");
} else {
ok(!panel.playerWidgets || !panel.playerWidgets.length,
"No player widgets displayed for a still node");
}
is(panel.animationsTimelineComponent.animations.length, 0,
"No animation players stored in the timeline component for a still node");
is(panel.animationsTimelineComponent.animationsEl.childNodes.length, 0,
"No animation displayed in the timeline component for a still node");
info("Select the comment text node and check that the panel is empty");
let commentNode = yield inspector.walker.previousSibling(stillNode);
@ -39,13 +31,7 @@ function* testEmptyPanel(inspector, panel, isNewUI=false) {
yield selectNode(commentNode, inspector);
yield onUpdated;
if (isNewUI) {
is(panel.animationsTimelineComponent.animations.length, 0,
"No animation players stored in the timeline component for a text node");
is(panel.animationsTimelineComponent.animationsEl.childNodes.length, 0,
"No animation displayed in the timeline component for a text node");
} else {
ok(!panel.playerWidgets || !panel.playerWidgets.length,
"No player widgets displayed for a text node");
}
}
is(panel.animationsTimelineComponent.animations.length, 0,
"No animation players stored in the timeline component for a text node");
is(panel.animationsTimelineComponent.animationsEl.childNodes.length, 0,
"No animation displayed in the timeline component for a text node");}

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

@ -1,34 +0,0 @@
/* 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";
// Check that iteration count is only shown in the UI when it's different than 1
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
let {inspector, panel} = yield openAnimationInspector();
info("Selecting a node with an animation that doesn't repeat");
yield selectNode(".long", inspector);
let widget = panel.playerWidgets[0];
ok(isNodeVisible(widget.metaDataComponent.durationValue),
"The duration value is shown");
ok(!isNodeVisible(widget.metaDataComponent.delayValue),
"The delay value is hidden");
ok(!isNodeVisible(widget.metaDataComponent.iterationValue),
"The iteration count is hidden");
info("Selecting a node with an animation that repeats several times");
yield selectNode(".delayed", inspector);
widget = panel.playerWidgets[0];
ok(isNodeVisible(widget.metaDataComponent.durationValue),
"The duration value is shown");
ok(isNodeVisible(widget.metaDataComponent.delayValue),
"The delay value is shown");
ok(isNodeVisible(widget.metaDataComponent.iterationValue),
"The iteration count is shown");
});

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

@ -11,7 +11,7 @@
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_negative_animation.html");
let {controller, panel} = yield openAnimationInspectorNewUI();
let {controller, panel} = yield openAnimationInspector();
info("Wait until all animations have been added " +
"(they're added with setTimeout)");

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

@ -13,14 +13,6 @@ add_task(function*() {
ok(controller, "The animation controller exists");
ok(controller.animationsFront, "The animation controller has been initialized");
ok(panel, "The animation panel exists");
ok(panel.playersEl, "The animation panel has been initialized");
({panel, controller} = yield closeAnimationInspectorAndRestartWithNewUI());
ok(controller, "The animation controller exists");
ok(controller.animationsFront, "The animation controller has been initialized");
ok(panel, "The animation panel exists");
ok(panel.playersEl, "The animation panel has been initialized");
ok(panel.animationsTimelineComponent, "The animation panel has been initialized");

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

@ -13,9 +13,6 @@ add_task(function*() {
let ui = yield openAnimationInspector();
yield testEventsOrder(ui);
ui = yield closeAnimationInspectorAndRestartWithNewUI();
yield testEventsOrder(ui);
});
function* testEventsOrder({inspector, panel, controller}) {

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

@ -1,32 +0,0 @@
/* 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";
// Check that the play/pause button actually plays and pauses the player.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
let {inspector, panel, controller} = yield openAnimationInspector();
info("Selecting an animated node");
yield selectNode(".animated", inspector);
let player = controller.animationPlayers[0];
let widget = panel.playerWidgets[0];
info("Click the pause button");
yield togglePlayPauseButton(widget);
is(player.state.playState, "paused", "The AnimationPlayerFront is paused");
ok(widget.el.classList.contains("paused"), "The button's state has changed");
ok(!widget.rafID, "The smooth timeline animation has been stopped");
info("Click on the play button");
yield togglePlayPauseButton(widget);
is(player.state.playState, "running", "The AnimationPlayerFront is running");
ok(widget.el.classList.contains("running"), "The button's state has changed");
ok(widget.rafID, "The smooth timeline animation has been started");
});

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

@ -19,17 +19,12 @@ add_task(function*() {
is(controller.animationPlayers.length, 1,
"One AnimationPlayerFront has been created");
ok(controller.animationPlayers[0].autoRefreshTimer,
"The AnimationPlayerFront has been set to auto-refresh");
info("Selecting a node with mutliple animations");
yield selectNode(".multi", inspector);
is(controller.animationPlayers.length, 2,
"2 AnimationPlayerFronts have been created");
ok(controller.animationPlayers[0].autoRefreshTimer &&
controller.animationPlayers[1].autoRefreshTimer,
"The AnimationPlayerFronts have been set to auto-refresh");
// Hold on to one of the AnimationPlayerFront objects and mock its release
// method to test that it is released correctly and that its auto-refresh is
@ -49,7 +44,6 @@ add_task(function*() {
info("Checking the destroyed AnimationPlayerFront object");
ok(releaseCalled, "The AnimationPlayerFront has been released");
ok(!retainedFront.autoRefreshTimer,
"The released AnimationPlayerFront's auto-refresh mode has been turned off");
yield oldRelease.call(retainedFront);
});

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

@ -11,10 +11,6 @@ add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_body_animation.html");
let {panel} = yield openAnimationInspector();
is(panel.playerWidgets.length, 1,
"One animation player is displayed after init");
({panel} = yield closeAnimationInspectorAndRestartWithNewUI());
is(panel.animationsTimelineComponent.animations.length, 1,
"One animation is handled by the timeline after init");
is(panel.animationsTimelineComponent.animationsEl.childNodes.length, 1,

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

@ -1,24 +0,0 @@
/* 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 for the
// isRunningOnCompositor property.
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 compositorEl = panel.playerWidgets[0]
.el.querySelector(".compositor-icon");
ok(compositorEl, "The compositor-icon element exists");
ok(isNodeVisible(compositorEl),
"The compositor icon is visible, since the animation is running on " +
"compositor thread");
});

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

@ -1,23 +0,0 @@
/* 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 are destroyed correctly when needed.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
let {inspector, panel} = yield openAnimationInspector();
info("Select an animated node");
yield selectNode(".multi", inspector);
info("Hold on to one of the player widget instances to test it after destroy");
let widget = panel.playerWidgets[0];
info("Select another node to get the previous widgets destroyed");
yield selectNode(".animated", inspector);
ok(widget.destroyed, "The widget's destroyed flag is true");
});

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

@ -1,38 +0,0 @@
/* 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 when animations end, the corresponding player widgets are disabled.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
let {inspector, panel, controller} = yield openAnimationInspector();
info("Select the test node");
yield selectNode(".still", inspector);
info("Apply 2 finite animations to the test node and wait for the widgets to appear");
let onUiUpdated = panel.once(panel.UI_UPDATED_EVENT);
yield executeInContent("devtools:test:setAttribute", {
selector: ".still",
attributeName: "class",
attributeValue: "ball still multi-finite"
});
yield onUiUpdated;
is(controller.animationPlayers.length, 2, "2 animation players exist");
info("Wait for both animations to end");
let promises = controller.animationPlayers.map(front => {
return waitForPlayState(front, "finished");
});
yield promise.all(promises);
for (let widgetEl of panel.playersEl.querySelectorAll(".player-widget")) {
ok(widgetEl.classList.contains("finished"), "The player widget has the right class");
}
});

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

@ -1,40 +0,0 @@
/* 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 after the animation has ended, the current time label and timeline
// slider don't show values bigger than the animation duration (which would
// happen if the local requestAnimationFrame loop didn't stop correctly).
var L10N = new ViewHelpers.L10N();
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
let {inspector, panel} = yield openAnimationInspector();
info("Select the test node");
yield selectNode(".still", inspector);
info("Start an animation on the test node and wait for the widget to appear");
let onUiUpdated = panel.once(panel.UI_UPDATED_EVENT);
yield executeInContent("devtools:test:setAttribute", {
selector: ".still",
attributeName: "class",
attributeValue: "ball still short"
});
yield onUiUpdated;
info("Wait until the animation ends");
let widget = panel.playerWidgets[0];
let front = widget.player;
yield waitForPlayState(front, "finished");
is(widget.currentTimeEl.value, front.state.duration,
"The timeline slider has the right value");
is(widget.timeDisplayEl.textContent,
L10N.numberWithDecimals(front.state.duration / 1000, 2) + "s",
"The timeline slider has the right value");
});

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

@ -1,70 +0,0 @@
/* 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 playerWidgets have control buttons: play/pause, rewind, fast-forward.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
let {controller, inspector, panel} = yield openAnimationInspector();
info("Select the simple animated node");
yield selectNode(".animated", inspector);
let widget = panel.playerWidgets[0];
let container = widget.el.querySelector(".playback-controls");
ok(container, "The control buttons container exists");
is(container.querySelectorAll("button").length, 3,
"The container contains 3 buttons");
ok(container.children[0].classList.contains("toggle"),
"The first button is the play/pause button");
ok(container.children[1].classList.contains("rw"),
"The second button is the rewind button");
ok(container.children[2].classList.contains("ff"),
"The third button is the fast-forward button");
ok(container.querySelector("select"),
"The container contains the playback rate select");
info("Faking an older server version by setting " +
"AnimationsController.traits.hasSetCurrentTime to false");
// Selecting <div.still> to make sure no widgets are displayed in the panel.
yield selectNode(".still", inspector);
controller.traits.hasSetCurrentTime = false;
info("Selecting the animated node again");
yield selectNode(".animated", inspector);
widget = panel.playerWidgets[0];
container = widget.el.querySelector(".playback-controls");
ok(container, "The control buttons container still exists");
is(container.querySelectorAll("button").length, 1,
"The container only contains 1 button");
ok(container.children[0].classList.contains("toggle"),
"The first button is the play/pause button");
yield selectNode(".still", inspector);
controller.traits.hasSetCurrentTime = true;
info("Faking an older server version by setting " +
"AnimationsController.traits.hasSetPlaybackRate to false");
controller.traits.hasSetPlaybackRate = false;
info("Selecting the animated node again");
yield selectNode(".animated", inspector);
widget = panel.playerWidgets[0];
container = widget.el.querySelector(".playback-controls");
ok(container, "The control buttons container still exists");
ok(!container.querySelector("select"),
"The playback rate select does not exist");
yield selectNode(".still", inspector);
controller.traits.hasSetPlaybackRate = true;
});

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

@ -1,54 +0,0 @@
/* 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, 3, "3 meta-data elements were found");
is(metaDataEls[0].textContent, "2s",
"The first meta-data is the duration, and is correct");
ok(!isNodeVisible(metaDataEls[1]),
"The second meta-data is hidden, since there's no delay on the animation");
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, "3s",
"The first meta-data is the duration, and is correct");
ok(isNodeVisible(metaDataEls[0]), "The duration is shown");
is(metaDataEls[1].textContent, "60s",
"The second meta-data is the delay, and is correct");
ok(isNodeVisible(metaDataEls[1]), "The delay is shown");
is(metaDataEls[2].textContent, "10",
"The third meta-data is the iteration count, and is correct");
ok(isNodeVisible(metaDataEls[2]), "The iteration count is shown");
});

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

@ -1,24 +0,0 @@
/* 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, "0s", "The current time is 0");
});

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

@ -1,39 +0,0 @@
/* 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 widget is enabled and that the associated
// player front supports setting the current time.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
let {controller, inspector, panel} = yield openAnimationInspector();
info("Select the animated node");
yield selectNode(".animated", inspector);
info("Get the player widget's timeline element");
let widget = panel.playerWidgets[0];
let timeline = widget.currentTimeEl;
ok(!timeline.hasAttribute("disabled"), "The timeline input[range] is enabled");
ok(widget.setCurrentTime, "The widget has the setCurrentTime method");
ok(widget.player.setCurrentTime,
"The associated player front has the setCurrentTime method");
info("Faking an older server version by setting " +
"AnimationsController.traits.hasSetCurrentTime to false");
yield selectNode("body", inspector);
controller.traits.hasSetCurrentTime = false;
yield selectNode(".animated", inspector);
info("Get the player widget's timeline element");
widget = panel.playerWidgets[0];
timeline = widget.currentTimeEl;
ok(timeline.hasAttribute("disabled"), "The timeline input[range] is disabled");
});

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

@ -1,28 +0,0 @@
/* 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 widget actually progresses with the
// animation itself.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
let {inspector, panel} = yield openAnimationInspector();
info("Select the animated node");
yield selectNode(".animated", inspector);
info("Get the player widget's timeline element and its current position");
let widget = panel.playerWidgets[0];
let timeline = widget.currentTimeEl;
yield onceNextPlayerRefresh(widget.player);
ok(widget.rafID, "The widget is updating the timeline with a rAF loop");
info("Pause the animation");
yield togglePlayPauseButton(widget);
ok(!widget.rafID, "The rAF loop has been stopped after the animation was paused");
});

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

@ -1,33 +0,0 @@
/* 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 once an animation is paused and its widget is refreshed, the right
// initial time is displayed.
var L10N = new ViewHelpers.L10N();
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
let {inspector, panel} = yield openAnimationInspector();
info("Selecting the test node");
yield selectNode(".animated", inspector);
info("Pausing the animation by using the widget");
let widget = panel.playerWidgets[0];
yield widget.pause();
info("Selecting another node and then the same node again to refresh the widget");
yield selectNode(".still", inspector);
yield selectNode(".animated", inspector);
widget = panel.playerWidgets[0];
ok(widget.el.classList.contains("paused"), "The widget is still in paused mode");
is(widget.timeDisplayEl.textContent,
L10N.numberWithDecimals(widget.player.state.currentTime / 1000, 2) + "s",
"The initial time has been set to the player's");
});

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

@ -13,29 +13,6 @@ add_task(function*() {
info("Select the simple animated node");
yield selectNode(".animated", inspector);
let widget = panel.playerWidgets[0];
// Make sure to wait for the target-retrieved event if the nodeFront hasn't
// yet been retrieved by the TargetNodeComponent.
if (!widget.targetNodeComponent.nodeFront) {
yield widget.targetNodeComponent.once("target-retrieved");
}
let targetEl = widget.el.querySelector(".animation-target");
ok(targetEl, "The player widget has a target element");
is(targetEl.textContent, "<divid=\"\"class=\"ball animated\">",
"The target element's content is correct");
let selectorEl = targetEl.querySelector(".node-selector");
ok(selectorEl,
"The icon to select the target element in the inspector exists");
info("Test again with the new timeline UI");
({inspector, panel} = yield closeAnimationInspectorAndRestartWithNewUI());
info("Select the simple animated node");
yield selectNode(".animated", inspector);
let targetNodeComponent = panel.animationsTimelineComponent.targetNodes[0];
// Make sure to wait for the target-retrieved event if the nodeFront hasn't
// yet been retrieved by the TargetNodeComponent.
@ -46,7 +23,7 @@ add_task(function*() {
is(targetNodeComponent.el.textContent, "div#.ball.animated",
"The target element's content is correct");
selectorEl = targetNodeComponent.el.querySelector(".node-selector");
let selectorEl = targetNodeComponent.el.querySelector(".node-selector");
ok(selectorEl,
"The icon to select the target element in the inspector exists");
});

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

@ -1,49 +0,0 @@
/* 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 playbackRate select element contains a list of presets and
// and that if the animation has a current rate that is not part of this list,
// it is added.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
let {inspector, panel} = yield openAnimationInspector();
info("Selecting the test node");
yield selectNode(".animated", inspector);
info("Get the playback rate UI component");
let widget = panel.playerWidgets[0];
let rateComponent = widget.rateComponent;
let options = rateComponent.el.querySelectorAll("option");
is(options.length, rateComponent.PRESETS.length,
"The playback rate select contains the right number of options");
for (let i = 0; i < rateComponent.PRESETS.length; i ++) {
is(options[i].value, rateComponent.PRESETS[i] + "",
"The playback rate option " + i + " has the right preset value " +
rateComponent.PRESETS[i]);
}
info("Set a custom rate (not part of the presets) via the DOM");
let onRateChanged = waitForStateCondition(widget.player, state => {
return state.playbackRate === 3.6
});
yield executeInContent("Test:SetAnimationPlayerPlaybackRate", {
selector: ".animated",
animationIndex: 0,
playbackRate: 3.6
});
yield onRateChanged;
options = rateComponent.el.querySelectorAll("option");
is(options.length, rateComponent.PRESETS.length + 1,
"The playback rate select contains the right number of options (presets + 1)");
ok([...options].find(option => option.value === "3.6"),
"The custom rate is part of the select");
});

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

@ -11,9 +11,6 @@ add_task(function*() {
let {inspector, panel} = yield openAnimationInspector();
yield testRefreshOnNewAnimation(inspector, panel);
({inspector, panel} = yield closeAnimationInspectorAndRestartWithNewUI());
yield testRefreshOnNewAnimation(inspector, panel);
});
function* testRefreshOnNewAnimation(inspector, panel) {

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

@ -11,11 +11,6 @@ add_task(function*() {
let {inspector, panel} = yield openAnimationInspector();
yield testRefreshOnRemove(inspector, panel);
yield testAddedAnimationWorks(inspector, panel);
info("Reload and test again with the new UI");
({inspector, panel} = yield closeAnimationInspectorAndRestartWithNewUI(true));
yield testRefreshOnRemove(inspector, panel, true);
});
function* testRefreshOnRemove(inspector, panel) {
@ -51,22 +46,3 @@ function* testRefreshOnRemove(inspector, panel) {
assertAnimationsDisplayed(panel, 1);
}
function* testAddedAnimationWorks(inspector, panel) {
info("Now wait until the animation finishes");
let widget = panel.playerWidgets[0];
yield waitForPlayState(widget.player, "finished");
is(panel.playersEl.querySelectorAll(".player-widget").length, 1,
"There is still a player widget in the panel after the animation finished");
info("Checking that the animation's currentTime can still be set");
info("Click at the center of the slider input");
let onPaused = waitForPlayState(widget.player, "paused");
let input = widget.currentTimeEl;
let win = input.ownerDocument.defaultView;
EventUtils.synthesizeMouseAtCenter(input, {type: "mousedown"}, win);
yield onPaused;
ok(widget.el.classList.contains("paused"), "The widget is in paused mode");
}

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

@ -11,9 +11,6 @@ add_task(function*() {
let {inspector, panel} = yield openAnimationInspector();
yield testRefresh(inspector, panel);
({inspector, panel} = yield closeAnimationInspectorAndRestartWithNewUI());
yield testRefresh(inspector, panel);
});
function* testRefresh(inspector, panel) {

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

@ -10,22 +10,6 @@
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
let {inspector, panel, controller} = yield openAnimationInspector();
info("Selecting the test animated node");
yield selectNode(".multi", inspector);
is(controller.animationPlayers.length, panel.playerWidgets.length,
"As many playerWidgets were created as there are playerFronts");
for (let widget of panel.playerWidgets) {
ok(widget.initialized, "The player widget is initialized");
is(widget.el.parentNode, panel.playersEl,
"The player widget has been appended to the panel");
}
info("Test again with the new UI, making sure the same number of " +
"animation timelines is created");
({inspector, panel, controller} = yield closeAnimationInspectorAndRestartWithNewUI());
let timeline = panel.animationsTimelineComponent;
info("Selecting the test animated node again");

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

@ -1,43 +0,0 @@
/* 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 setting an animation's current time by clicking in the input[range]
// or rewind or fast-forward buttons pauses the animation and sets it to the
// right time.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
let {toolbox, inspector, panel} = yield openAnimationInspector();
info("Select an animated node");
yield selectNode(".animated", inspector);
info("Get the player widget for this node");
let widget = panel.playerWidgets[0];
let input = widget.currentTimeEl;
let rwBtn = widget.rewindBtnEl;
let ffBtn = widget.fastForwardBtnEl;
let win = input.ownerDocument.defaultView;
info("Click at the center of the input")
EventUtils.synthesizeMouseAtCenter(input, {type: "mousedown"}, win);
yield checkPausedAt(widget, 1000);
info("Resume the player and wait for an auto-refresh event");
yield widget.player.play();
yield onceNextPlayerRefresh(widget.player);
info("Click on the rewind button");
EventUtils.sendMouseEvent({type: "click"}, rwBtn, win);
yield checkPausedAt(widget, 0);
info("Click on the fast-forward button");
EventUtils.sendMouseEvent({type: "click"}, ffBtn, win);
yield checkPausedAt(widget, 2000);
});

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

@ -1,34 +0,0 @@
/* 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 setting an animation's playback rate by selecting a rate in the
// presets drop-down sets the rate accordingly.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
let {toolbox, inspector, panel} = yield openAnimationInspector();
info("Select an animated node");
yield selectNode(".animated", inspector);
info("Get the player widget for this node");
let widget = panel.playerWidgets[0];
let select = widget.rateComponent.el;
let win = select.ownerDocument.defaultView;
info("Click on the rate drop-down");
EventUtils.synthesizeMouseAtCenter(select, {type: "mousedown"}, win);
info("Click on a rate option");
let option = select.options[select.options.length - 1];
EventUtils.synthesizeMouseAtCenter(option, {type: "mouseup"}, win);
let selectedRate = parseFloat(option.value);
info("Check that the rate was changed on the player at the next update");
yield waitForStateCondition(widget.player, ({playbackRate}) => playbackRate === selectedRate);
is(widget.player.state.playbackRate, selectedRate,
"The rate was changed successfully");
});

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

@ -9,18 +9,11 @@
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
let {inspector, panel} = yield openAnimationInspector();
yield testShowsAnimations(inspector, panel);
({inspector, panel} = yield closeAnimationInspectorAndRestartWithNewUI());
yield testShowsAnimations(inspector, panel);
});
function* testShowsAnimations(inspector, panel) {
info("Select node .animated and check that the panel is not empty");
let node = yield getNodeFront(".animated", inspector);
yield selectNode(node, inspector);
assertAnimationsDisplayed(panel, 1);
}
});

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

@ -12,12 +12,9 @@ add_task(function*() {
let ui = yield openAnimationInspector();
yield testTargetNode(ui);
ui = yield closeAnimationInspectorAndRestartWithNewUI();
yield testTargetNode(ui, true);
});
function* testTargetNode({toolbox, inspector, panel}, isNewUI) {
function* testTargetNode({toolbox, inspector, panel}) {
info("Select the simple animated node");
let onPanelUpdated = panel.once(panel.UI_UPDATED_EVENT);

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

@ -1,24 +0,0 @@
/* 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";
// Check that the timeline-based UI is displayed instead of the playerwidget-
// based UI when the "devtools.inspector.animationInspectorV3" is set.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
let {inspector, panel} = yield openAnimationInspectorNewUI();
info("Selecting the test node");
yield selectNode(".animated", inspector);
let timeline = panel.animationsTimelineComponent;
ok(timeline, "The timeline components was created");
is(timeline.rootWrapperEl.parentNode, panel.playersEl,
"The timeline component was appended in the DOM");
is(panel.playersEl.querySelectorAll(".player-widget").length, 0,
"There are no playerWidgets in the DOM");
});

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

@ -4,8 +4,7 @@
"use strict";
// Check that the timeline-based UI shows correct time graduations in the
// header.
// Check that the timeline shows correct time graduations in the header.
const {findOptimalTimeInterval} = require("devtools/animationinspector/utils");
const {TimeScale} = require("devtools/animationinspector/components");
@ -14,7 +13,7 @@ const TIME_GRADUATION_MIN_SPACING = 40;
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
let {panel} = yield openAnimationInspectorNewUI();
let {panel} = yield openAnimationInspector();
let timeline = panel.animationsTimelineComponent;
let headerEl = timeline.timeHeaderEl;

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

@ -12,7 +12,7 @@
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
let {panel} = yield openAnimationInspectorNewUI();
let {panel} = yield openAnimationInspector();
let btn = panel.playTimelineButtonEl;
ok(btn, "The play/pause button exists");

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

@ -4,11 +4,11 @@
"use strict";
// Check that the timeline-based UI does have a scrubber element.
// Check that the timeline does have a scrubber element.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
let {panel} = yield openAnimationInspectorNewUI();
let {panel} = yield openAnimationInspector();
let timeline = panel.animationsTimelineComponent;
let scrubberEl = timeline.scrubberEl;

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

@ -4,15 +4,15 @@
"use strict";
// Check that the scrubber in the timeline-based UI can be moved by clicking &
// dragging in the header area.
// Check that the scrubber in the timeline can be moved by clicking & dragging
// in the header area.
// Also check that doing so changes the timeline's play/pause button to paused
// state.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
let {panel} = yield openAnimationInspectorNewUI();
let {panel} = yield openAnimationInspector();
let timeline = panel.animationsTimelineComponent;
let win = timeline.win;

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

@ -4,15 +4,14 @@
"use strict";
// Check that the scrubber in the timeline-based UI moves when animations are
// playing.
// Check that the scrubber in the timeline moves when animations are playing.
// The animations in the test page last for a very long time, so the test just
// measures the position of the scrubber once, then waits for some time to pass
// and measures its position again.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
let {panel} = yield openAnimationInspectorNewUI();
let {panel} = yield openAnimationInspector();
let timeline = panel.animationsTimelineComponent;
let scrubberEl = timeline.scrubberEl;

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

@ -4,14 +4,14 @@
"use strict";
// Check that animation delay is visualized in the timeline-based UI when the
// animation is delayed.
// Check that animation delay is visualized in the timeline when the animation
// is delayed.
// Also check that negative delays do not overflow the UI, and are shown like
// positive delays.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
let {inspector, panel} = yield openAnimationInspectorNewUI();
let {inspector, panel} = yield openAnimationInspector();
info("Selecting a delayed animated node");
yield selectNode(".delayed", inspector);

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

@ -4,12 +4,12 @@
"use strict";
// Check that the timeline-based UI is displays as many iteration elements as
// there are iterations in an animation.
// Check that the timeline is displays as many iteration elements as there are
// iterations in an animation.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
let {inspector, panel} = yield openAnimationInspectorNewUI();
let {inspector, panel} = yield openAnimationInspector();
info("Selecting the test node");
yield selectNode(".delayed", inspector);

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

@ -4,12 +4,12 @@
"use strict";
// Check that the timeline-based UI displays animations' duration, delay and
// iteration counts in tooltips.
// Check that the timeline displays animations' duration, delay and iteration
// counts in tooltips.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
let {panel} = yield openAnimationInspectorNewUI();
let {panel} = yield openAnimationInspector();
info("Getting the animation element from the panel");
let timelineEl = panel.animationsTimelineComponent.rootWrapperEl;

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

@ -14,7 +14,7 @@
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_modify_playbackRate.html");
let {panel} = yield openAnimationInspectorNewUI();
let {panel} = yield openAnimationInspector();
let timelineEl = panel.animationsTimelineComponent.rootWrapperEl;

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

@ -4,11 +4,11 @@
"use strict";
// Check that the timeline-based UI contains the right elements.
// Check that the timeline contains the right elements.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
let {panel} = yield openAnimationInspectorNewUI();
let {panel} = yield openAnimationInspector();
let timeline = panel.animationsTimelineComponent;
let el = timeline.rootWrapperEl;

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

@ -1,38 +0,0 @@
/* 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 pressing the main toggle button also updates the displayed
// player widgets.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
let {inspector, panel} = yield openAnimationInspector();
info("Select an animated node");
yield selectNode(".animated", inspector);
let widget = panel.playerWidgets[0];
let player = widget.player;
info("Listen to animation state changes and click the toggle button to " +
"pause all animations");
let onPaused = waitForPlayState(player, "paused");
yield panel.toggleAll();
yield onPaused;
info("Checking the selected node's animation player widget's state");
is(player.state.playState, "paused", "The player front's state is paused");
ok(widget.el.classList.contains("paused"), "The widget's UI is in paused state");
info("Listen to animation state changes and click the toggle button to " +
"play all animations");
let onRunning = waitForPlayState(player, "running");
yield panel.toggleAll();
yield onRunning;
info("Checking the selected node's animation player widget's state again");
is(player.state.playState, "running", "The player front's state is running");
ok(widget.el.classList.contains("running"), "The widget's UI is in running state");
});

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

@ -6,30 +6,14 @@
// Test that the animation panel has a top toolbar that contains the play/pause
// button and that is displayed at all times.
// Also test that with the new UI, that toolbar gets replaced by the timeline
// toolbar when there are animations to be displayed.
// Also test that this toolbar gets replaced by the timeline toolbar when there
// are animations to be displayed.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
let {inspector, window} = yield openAnimationInspector();
let doc = window.document;
let toolbar = doc.querySelector("#global-toolbar");
ok(toolbar, "The panel contains the toolbar element");
ok(toolbar.querySelector("#toggle-all"),
"The toolbar contains the toggle button");
ok(isNodeVisible(toolbar), "The toolbar is visible");
info("Select an animated node");
yield selectNode(".animated", inspector);
toolbar = doc.querySelector("#global-toolbar");
ok(toolbar, "The panel still contains the toolbar element");
ok(isNodeVisible(toolbar), "The toolbar is still visible");
({inspector, window} = yield closeAnimationInspectorAndRestartWithNewUI());
doc = window.document;
toolbar = doc.querySelector("#global-toolbar");
ok(toolbar, "The panel contains the toolbar element with the new UI");
ok(!isNodeVisible(toolbar),

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

@ -1,52 +0,0 @@
/* 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";
// Verify that if the animation object changes in content, then the widget
// reflects that change.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
let {panel, inspector} = yield openAnimationInspector();
info("Select the test node");
yield selectNode(".animated", inspector);
info("Get the player widget");
let widget = panel.playerWidgets[0];
let player = widget.player;
info("Wait for paused playState");
let onPaused = waitForPlayState(player, "paused");
info("Pause the animation via the content DOM");
yield executeInContent("Test:ToggleAnimationPlayer", {
selector: ".animated",
animationIndex: 0,
pause: true
});
yield onPaused;
is(player.state.playState, "paused", "The AnimationPlayerFront is paused");
ok(widget.el.classList.contains("paused"), "The button's state has changed");
ok(!widget.rafID, "The smooth timeline animation has been stopped");
info("Wait for running playState");
let onRunning = waitForPlayState(player, "running");
info("Play the animation via the content DOM");
yield executeInContent("Test:ToggleAnimationPlayer", {
selector: ".animated",
animationIndex: 0,
pause: false
});
yield onRunning;
is(player.state.playState, "running", "The AnimationPlayerFront is running");
ok(widget.el.classList.contains("running"), "The button's state has changed");
ok(widget.rafID, "The smooth timeline animation has been started");
});

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

@ -12,47 +12,33 @@ add_task(function*() {
let ui = yield openAnimationInspector();
yield testDataUpdates(ui);
info("Close the toolbox, reload the tab, and try again with the new UI");
ui = yield closeAnimationInspectorAndRestartWithNewUI(true);
yield testDataUpdates(ui, true);
});
function* testDataUpdates({panel, controller, inspector}, isNewUI=false) {
function* testDataUpdates({panel, controller, inspector}) {
info("Select the test node");
yield selectNode(".animated", inspector);
let animation = controller.animationPlayers[0];
yield setStyle(animation, panel, "animationDuration", "5.5s", isNewUI);
yield setStyle(animation, panel, "animationIterationCount", "300", isNewUI);
yield setStyle(animation, panel, "animationDelay", "45s", isNewUI);
yield setStyle(animation, panel, "animationDuration", "5.5s");
yield setStyle(animation, panel, "animationIterationCount", "300");
yield setStyle(animation, panel, "animationDelay", "45s");
if (isNewUI) {
let animationsEl = panel.animationsTimelineComponent.animationsEl;
let timeBlockEl = animationsEl.querySelector(".time-block");
let animationsEl = panel.animationsTimelineComponent.animationsEl;
let timeBlockEl = animationsEl.querySelector(".time-block");
// 45s delay + (300 * 5.5)s duration
let expectedTotalDuration = 1695 * 1000;
let timeRatio = expectedTotalDuration / timeBlockEl.offsetWidth;
// 45s delay + (300 * 5.5)s duration
let expectedTotalDuration = 1695 * 1000;
let timeRatio = expectedTotalDuration / timeBlockEl.offsetWidth;
// XXX: the nb and size of each iteration cannot be tested easily (displayed
// using a linear-gradient background and capped at 2px wide). They should
// be tested in bug 1173761.
let delayWidth = parseFloat(timeBlockEl.querySelector(".delay").style.width);
is(Math.round(delayWidth * timeRatio), 45 * 1000,
"The timeline has the right delay");
} else {
let widget = panel.playerWidgets[0];
is(widget.metaDataComponent.durationValue.textContent, "5.50s",
"The widget shows the new duration");
is(widget.metaDataComponent.iterationValue.textContent, "300",
"The widget shows the new iteration count");
is(widget.metaDataComponent.delayValue.textContent, "45s",
"The widget shows the new delay");
}
// XXX: the nb and size of each iteration cannot be tested easily (displayed
// using a linear-gradient background and capped at 2px wide). They should
// be tested in bug 1173761.
let delayWidth = parseFloat(timeBlockEl.querySelector(".delay").style.width);
is(Math.round(delayWidth * timeRatio), 45 * 1000,
"The timeline has the right delay");
}
function* setStyle(animation, panel, name, value, isNewUI=false) {
function* setStyle(animation, panel, name, value) {
info("Change the animation style via the content DOM. Setting " +
name + " to " + value);
@ -67,10 +53,4 @@ function* setStyle(animation, panel, name, value, isNewUI=false) {
// Also wait for the target node previews to be loaded if the panel got
// refreshed as a result of this animation mutation.
yield waitForAllAnimationTargets(panel);
// If this is the playerWidget-based UI, wait for the auto-refresh event too
// to make sure the UI has updated.
if (!isNewUI) {
yield once(animation, animation.AUTO_REFRESH_EVENT);
}
}

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

@ -1,47 +0,0 @@
/* 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 setting an animation's playbackRate via the WebAnimations API (from
// content), actually changes the rate in the corresponding widget too.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
let {inspector, panel} = yield openAnimationInspector();
info("Selecting the test node");
yield selectNode(".animated", inspector);
info("Get the player widget");
let widget = panel.playerWidgets[0];
info("Change the animation's playbackRate via the content DOM");
let onRateChanged = waitForStateCondition(widget.player, state => {
return state.playbackRate === 2;
}, "playbackRate === 2");
yield executeInContent("Test:SetAnimationPlayerPlaybackRate", {
selector: ".animated",
animationIndex: 0,
playbackRate: 2
});
yield onRateChanged;
is(widget.rateComponent.el.value, "2",
"The playbackRate select value was changed");
info("Change the animation's playbackRate again via the content DOM");
onRateChanged = waitForStateCondition(widget.player, state => {
return state.playbackRate === 0.3;
}, "playbackRate === 0.3");
yield executeInContent("Test:SetAnimationPlayerPlaybackRate", {
selector: ".animated",
animationIndex: 0,
playbackRate: 0.3
});
yield onRateChanged;
is(widget.rateComponent.el.value, "0.3",
"The playbackRate select value was changed again");
});

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

@ -1,52 +0,0 @@
/* 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 setting an animation's currentTime via the WebAnimations API (from
// content), actually changes the time in the corresponding widget too.
var L10N = new ViewHelpers.L10N();
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
let {inspector, panel} = yield openAnimationInspector();
info("Selecting the test node");
yield selectNode(".animated", inspector);
info("Get the player widget");
let widget = panel.playerWidgets[0];
info("Pause the player so we can compare times easily");
yield executeInContent("Test:ToggleAnimationPlayer", {
selector: ".animated",
animationIndex: 0,
pause: true
});
yield onceNextPlayerRefresh(widget.player);
ok(widget.el.classList.contains("paused"), "The widget is in pause mode");
info("Change the animation's currentTime via the content DOM");
yield executeInContent("Test:SetAnimationPlayerCurrentTime", {
selector: ".animated",
animationIndex: 0,
currentTime: 0
});
yield onceNextPlayerRefresh(widget.player);
is(widget.currentTimeEl.value, 0, "The currentTime slider's value was changed");
info("Change the animation's currentTime again via the content DOM");
yield executeInContent("Test:SetAnimationPlayerCurrentTime", {
selector: ".animated",
animationIndex: 0,
currentTime: 300
});
yield onceNextPlayerRefresh(widget.player);
is(widget.currentTimeEl.value, 300,
"The currentTime slider's value was changed again");
});

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

@ -83,13 +83,6 @@ function addTab(url) {
return def.promise;
}
/**
* Switch ON the new UI pref.
*/
function enableNewUI() {
Services.prefs.setBoolPref(NEW_UI_PREF, true);
}
/**
* Reload the current tab location.
*/
@ -147,15 +140,9 @@ var selectNode = Task.async(function*(data, inspector, reason="test") {
* @param {String} msg An optional string to be used as the assertion message.
*/
function assertAnimationsDisplayed(panel, nbAnimations, msg="") {
let isNewUI = Services.prefs.getBoolPref(NEW_UI_PREF);
msg = msg || `There are ${nbAnimations} animations in the panel`;
if (isNewUI) {
is(panel.animationsTimelineComponent.animationsEl.childNodes.length,
nbAnimations, msg);
} else {
is(panel.playersEl.querySelectorAll(".player-widget").length,
nbAnimations, msg);
}
is(panel.animationsTimelineComponent.animationsEl.childNodes.length,
nbAnimations, msg);
}
/**
@ -229,16 +216,6 @@ var openAnimationInspector = Task.async(function*() {
};
});
/**
* Turn on the new timeline-based UI pref ON, and then open the toolbox, with
* the inspector tool visible and the animationinspector sidebar selected.
* @return a promise that resolves when the inspector is ready.
*/
function openAnimationInspectorNewUI() {
enableNewUI();
return openAnimationInspector();
}
/**
* Close the toolbox.
* @return a promise that resolves when the toolbox has closed.
@ -248,24 +225,6 @@ var closeAnimationInspector = Task.async(function*() {
yield gDevTools.closeToolbox(target);
});
/**
* During the time period we migrate from the playerWidgets-based UI to the new
* AnimationTimeline UI, we'll want to run certain tests against both UI.
* This closes the toolbox, switch the new UI pref ON, and opens the toolbox
* again, with the animation inspector panel selected.
* @param {Boolean} reload Optionally reload the page after the toolbox was
* closed and before it is opened again.
* @return a promise that resolves when the animation inspector is ready.
*/
var closeAnimationInspectorAndRestartWithNewUI = Task.async(function*(reload) {
info("Close the toolbox and test again with the new UI");
yield closeAnimationInspector();
if (reload) {
yield reloadTab();
}
return yield openAnimationInspectorNewUI();
});
/**
* Wait for the toolbox frame to receive focus after it loads
* @param {Toolbox} toolbox
@ -481,13 +440,7 @@ function isNodeVisible(node) {
* @return {Array} all AnimationTargetNode instances
*/
var waitForAllAnimationTargets = Task.async(function*(panel) {
let targets = [];
if (panel.animationsTimelineComponent) {
targets = targets.concat(panel.animationsTimelineComponent.targetNodes);
}
if (panel.playerWidgets) {
targets = targets.concat(panel.playerWidgets.map(w => w.targetNodeComponent));
}
let targets = panel.animationsTimelineComponent.targetNodes;
yield promise.all(targets.map(t => {
if (!t.nodeFront) {
return t.once("target-retrieved");

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

@ -28,7 +28,6 @@
const {Cu} = require("chrome");
const promise = require("promise");
const {Task} = Cu.import("resource://gre/modules/Task.jsm", {});
const {setInterval, clearInterval} = require("sdk/timers");
const protocol = require("devtools/server/protocol");
const {ActorClass, Actor, FrontClass, Front,
Arg, method, RetVal, types} = protocol;
@ -36,10 +35,6 @@ const {ActorClass, Actor, FrontClass, Front,
const {NodeActor} = require("devtools/server/actors/inspector");
const events = require("sdk/event/core");
// How long (in ms) should we wait before polling again the state of an
// animationPlayer.
const PLAYER_DEFAULT_AUTO_REFRESH_TIMEOUT = 500;
// Types of animations.
const ANIMATION_TYPES = {
CSS_ANIMATION: "cssanimation",
@ -423,8 +418,6 @@ var AnimationPlayerActor = ActorClass({
});
var AnimationPlayerFront = FrontClass(AnimationPlayerActor, {
AUTO_REFRESH_EVENT: "updated-state",
initialize: function(conn, form, detail, ctx) {
Front.prototype.initialize.call(this, conn, form, detail, ctx);
@ -441,7 +434,6 @@ var AnimationPlayerFront = FrontClass(AnimationPlayerActor, {
},
destroy: function() {
this.stopAutoRefresh();
Front.prototype.destroy.call(this);
},
@ -475,75 +467,14 @@ var AnimationPlayerFront = FrontClass(AnimationPlayerActor, {
this.state = state;
}),
// About auto-refresh:
//
// The AnimationPlayerFront is capable of automatically refreshing its state
// by calling the getCurrentState method at regular intervals. This allows
// consumers to update their knowledge of the player's currentTime, playState,
// ... dynamically.
//
// Calling startAutoRefresh will start the automatic refreshing of the state,
// and calling stopAutoRefresh will stop it.
// Once the automatic refresh has been started, the AnimationPlayerFront emits
// "updated-state" events everytime the state changes.
//
// Note that given the time-related nature of animations, the actual state
// changes a lot more often than "updated-state" events are emitted. This is
// to avoid making many protocol requests.
/**
* Start auto-refreshing this player's state.
* @param {Number} interval Optional auto-refresh timer interval to override
* the default value.
* Refresh the current state of this animation on the client from information
* found on the server. Doesn't return anything, just stores the new state.
*/
startAutoRefresh: function(interval=PLAYER_DEFAULT_AUTO_REFRESH_TIMEOUT) {
if (this.autoRefreshTimer) {
return;
}
this.autoRefreshTimer = setInterval(() => {
// Save the refresh promise for tests. The tests need to detect when the
// last request completes or they might finish too early.
// Storing the latest Promise is enough to know that there is no pending
// requests left as p.js guarantees the last request will get the reply
// last.
this.pendingRefreshStatePromise = this.refreshState();
this.pendingRefreshStatePromise.then(() => {
this.pendingRefreshStatePromise = null;
});
}, interval);
},
/**
* Stop auto-refreshing this player's state.
*/
stopAutoRefresh: function() {
if (!this.autoRefreshTimer) {
return;
}
clearInterval(this.autoRefreshTimer);
this.autoRefreshTimer = null;
},
/**
* Called automatically when auto-refresh is on. Doesn't return anything, but
* emits the "updated-state" event.
* @param {Boolean} forceRefresh This function is normally called by the
* auto-refresh loop. If you need to call it but are not using this mechanism,
* then set this to true.
*/
refreshState: Task.async(function*(forceRefresh) {
refreshState: Task.async(function*() {
let data = yield this.getCurrentState();
// By the time the new state is received, auto-refresh might be stopped.
if (!this.autoRefreshTimer && !forceRefresh) {
return;
}
if (this.currentStateHasChanged) {
this.state = data;
events.emit(this, this.AUTO_REFRESH_EVENT, this.state);
}
}),

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

@ -26,8 +26,6 @@ support-files =
[browser_animation_actors_03.js]
[browser_animation_actors_04.js]
skip-if = e10s # Bug 1183605 - toolkit/devtools/server/tests/browser/ tests are still disabled in E10S
[browser_animation_actors_05.js]
skip-if = e10s # Bug 1183605 - toolkit/devtools/server/tests/browser/ tests are still disabled in E10S
[browser_animation_actors_06.js]
[browser_animation_actors_07.js]
[browser_animation_actors_08.js]

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

@ -1,64 +0,0 @@
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Check that AnimationPlayers can auto-refresh their states.
const {AnimationsFront} = require("devtools/server/actors/animation");
const {InspectorFront} = require("devtools/server/actors/inspector");
add_task(function*() {
let doc = yield addTab(MAIN_DOMAIN + "animation.html");
initDebuggerServer();
let client = new DebuggerClient(DebuggerServer.connectPipe());
let form = yield connectDebuggerClient(client);
let inspector = InspectorFront(client, form);
let walker = yield inspector.getWalker();
let front = AnimationsFront(client, form);
let node = yield walker.querySelector(walker.rootNode, ".simple-animation");
let [player] = yield front.getAnimationPlayersForNode(node);
ok(player.startAutoRefresh, "The startAutoRefresh function is available");
ok(player.stopAutoRefresh, "The stopAutoRefresh function is available");
ok(player.state, "The current state is stored on the player");
info("Subscribe to the refresh event, start the auto-refresh and wait for " +
"a few events to be received");
player.startAutoRefresh();
let onAllEventsReceived = new Promise(resolve => {
let expected = 5;
let previousState = player.initialState;
let onNewState = state => {
ok(state.currentTime !== previousState.currentTime,
"The time has changed since the last update");
expected --;
previousState = state;
if (expected === 0) {
player.off(player.AUTO_REFRESH_EVENT, onNewState);
info("Stop the auto-refresh");
player.stopAutoRefresh();
if (player.pendingRefreshStatePromise) {
// A new request was fired before we had chance to stop it. Wait for
// it to complete.
player.pendingRefreshStatePromise.then(resolve);
} else {
resolve();
}
}
};
player.on(player.AUTO_REFRESH_EVENT, onNewState);
});
yield onAllEventsReceived;
yield closeDebuggerClient(client);
gBrowser.removeCurrentTab();
});

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

@ -11,7 +11,7 @@ const {AnimationsFront} = require("devtools/server/actors/animation");
const {InspectorFront} = require("devtools/server/actors/inspector");
add_task(function*() {
let doc = yield addTab(MAIN_DOMAIN + "animation.html");
yield addTab(MAIN_DOMAIN + "animation.html");
initDebuggerServer();
let client = new DebuggerClient(DebuggerServer.connectPipe());
@ -37,10 +37,11 @@ function* playerHasCompleteStateAtAllTimes(walker, front) {
// Get the state over and over again and check that the object returned
// contains all keys.
// Normally, only the currentTime will have changed in between 2 calls.
for (let i = 0; i < 10; i ++) {
for (let i = 0; i < 10; i++) {
let state = yield player.getCurrentState();
keys.forEach(key => {
ok(typeof state[key] !== "undefined", "The state retrieved has key " + key);
ok(typeof state[key] !== "undefined",
"The state retrieved has key " + key);
});
}
}

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

@ -14,7 +14,7 @@ const URL = MAIN_DOMAIN + "animation.html";
add_task(function*() {
info("Creating a test document with 2 iframes containing animated nodes");
let doc = yield addTab("data:text/html;charset=utf-8," +
yield addTab("data:text/html;charset=utf-8," +
"<iframe id='i1' src='" + URL + "'></iframe>" +
"<iframe id='i2' src='" + URL + "'></iframe>");
@ -48,7 +48,8 @@ function* checkState(front, nodeFront, playState) {
let [player] = yield front.getAnimationPlayersForNode(nodeFront);
yield player.ready;
let state = yield player.getCurrentState();
is(state.playState, playState, "The playState of the test node is " + playState);
is(state.playState, playState,
"The playState of the test node is " + playState);
}
function* getNodeInFrame(walker, frameSelector, nodeSelector) {

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

@ -14,7 +14,7 @@ const {AnimationsFront} = require("devtools/server/actors/animation");
const {InspectorFront} = require("devtools/server/actors/inspector");
add_task(function*() {
let doc = yield addTab(MAIN_DOMAIN + "animation.html");
yield addTab(MAIN_DOMAIN + "animation.html");
initDebuggerServer();
let client = new DebuggerClient(DebuggerServer.connectPipe());
@ -31,8 +31,8 @@ add_task(function*() {
{attributeName: "class", newValue: "multiple-animations-2"}
]);
info("Get the list of players, by the time this executes, the first, short, " +
"animation should have ended.");
info("Get the list of players, by the time this executes, the first, " +
"short, animation should have ended.");
let players = yield front.getAnimationPlayersForNode(node);
if (players.length === 3) {
info("The short animation hasn't ended yet, wait for a bit.");
@ -45,13 +45,19 @@ add_task(function*() {
is(players.length, 2, "2 animations remain on the node");
is(players[0].state.duration, 1000, "The duration of the first animation is correct");
is(players[0].state.delay, 2000, "The delay of the first animation is correct");
is(players[0].state.iterationCount, null, "The iterationCount of the first animation is correct");
is(players[0].state.duration, 1000,
"The duration of the first animation is correct");
is(players[0].state.delay, 2000,
"The delay of the first animation is correct");
is(players[0].state.iterationCount, null,
"The iterationCount of the first animation is correct");
is(players[1].state.duration, 3000, "The duration of the second animation is correct");
is(players[1].state.delay, 1000, "The delay of the second animation is correct");
is(players[1].state.iterationCount, 100, "The iterationCount of the second animation is correct");
is(players[1].state.duration, 3000,
"The duration of the second animation is correct");
is(players[1].state.delay, 1000,
"The delay of the second animation is correct");
is(players[1].state.iterationCount, 100,
"The iterationCount of the second animation is correct");
yield closeDebuggerClient(client);
gBrowser.removeCurrentTab();

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

@ -10,7 +10,7 @@ const {AnimationsFront} = require("devtools/server/actors/animation");
const {InspectorFront} = require("devtools/server/actors/inspector");
add_task(function*() {
let doc = yield addTab(MAIN_DOMAIN + "animation.html");
yield addTab(MAIN_DOMAIN + "animation.html");
initDebuggerServer();
let client = new DebuggerClient(DebuggerServer.connectPipe());

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

@ -11,7 +11,7 @@ const {AnimationsFront} = require("devtools/server/actors/animation");
const {InspectorFront} = require("devtools/server/actors/inspector");
add_task(function*() {
let doc = yield addTab(MAIN_DOMAIN + "animation.html");
yield addTab(MAIN_DOMAIN + "animation.html");
initDebuggerServer();
let client = new DebuggerClient(DebuggerServer.connectPipe());

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

@ -13,7 +13,7 @@ const {AnimationsFront} = require("devtools/server/actors/animation");
const {InspectorFront} = require("devtools/server/actors/inspector");
add_task(function*() {
let doc = yield addTab(MAIN_DOMAIN + "animation.html");
yield addTab(MAIN_DOMAIN + "animation.html");
initDebuggerServer();
let client = new DebuggerClient(DebuggerServer.connectPipe());

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

@ -14,8 +14,8 @@ const URL = MAIN_DOMAIN + "animation.html";
add_task(function*() {
info("Creating a test document with 2 iframes containing animated nodes");
let doc = yield addTab("data:text/html;charset=utf-8," +
"<iframe id='iframe' src='" + URL + "'></iframe>");
yield addTab("data:text/html;charset=utf-8," +
"<iframe id='iframe' src='" + URL + "'></iframe>");
initDebuggerServer();
let client = new DebuggerClient(DebuggerServer.connectPipe());