Bug 1208204 - Pressing space in the animation inspector should toggle play/pause. r?pbrosset
MozReview-Commit-ID: 3NxNIaPjemt
--- a/devtools/client/animationinspector/animation-controller.js
+++ b/devtools/client/animationinspector/animation-controller.js
@@ -121,17 +121,17 @@ var getServerTraits = Task.async(functio
* function onPlayers() {
* for (let player of AnimationsController.animationPlayers) {
* // do something with player
* }
* }
*/
var AnimationsController = {
PLAYERS_UPDATED_EVENT: "players-updated",
-
+ ALL_ANIMATIONS_TOGGLED_EVENT: "all-animations-toggled",
initialize: Task.async(function*() {
if (this.initialized) {
yield this.initialized.promise;
return;
}
this.initialized = promise.defer();
this.onPanelVisibilityChange = this.onPanelVisibilityChange.bind(this);
@@ -250,17 +250,19 @@ var AnimationsController = {
/**
* Toggle (pause/play) all animations in the current target.
*/
toggleAll: function() {
if (!this.traits.hasToggleAll) {
return promise.resolve();
}
- return this.animationsFront.toggleAll().catch(e => console.error(e));
+ return this.animationsFront.toggleAll()
+ .then(() => this.emit(this.ALL_ANIMATIONS_TOGGLED_EVENT, this))
+ .catch(e => console.error(e));
},
/**
* Similar to toggleAll except that it only plays/pauses the currently known
* animations (those listed in this.animationPlayers).
* @param {Boolean} shouldPause True if the animations should be paused, false
* if they should be played.
* @return {Promise} Resolves when the playState has been changed.
--- a/devtools/client/animationinspector/animation-panel.js
+++ b/devtools/client/animationinspector/animation-panel.js
@@ -47,20 +47,20 @@ var AnimationsPanel = {
// If the server doesn't support toggling all animations at once, hide the
// whole global toolbar.
if (!AnimationsController.traits.hasToggleAll) {
$("#global-toolbar").style.display = "none";
}
// Binding functions that need to be called in scope.
- for (let functionName of ["onPickerStarted", "onPickerStopped",
- "refreshAnimationsUI", "toggleAll", "onTabNavigated",
- "onTimelineDataChanged", "playPauseTimeline", "rewindTimeline",
- "onRateChanged"]) {
+ for (let functionName of ["onKeyDown", "onPickerStarted",
+ "onPickerStopped", "refreshAnimationsUI", "onToggleAllClicked",
+ "onTabNavigated", "onTimelineDataChanged", "onTimelinePlayClicked",
+ "onTimelineRewindClicked", "onRateChanged"]) {
this[functionName] = this[functionName].bind(this);
}
let hUtils = gToolbox.highlighterUtils;
this.togglePicker = hUtils.togglePicker.bind(hUtils);
this.animationsTimelineComponent = new AnimationsTimeline(gInspector);
this.animationsTimelineComponent.init(this.playersEl);
@@ -109,19 +109,23 @@ var AnimationsPanel = {
startListeners: function() {
AnimationsController.on(AnimationsController.PLAYERS_UPDATED_EVENT,
this.refreshAnimationsUI);
this.pickerButtonEl.addEventListener("click", this.togglePicker);
gToolbox.on("picker-started", this.onPickerStarted);
gToolbox.on("picker-stopped", this.onPickerStopped);
- this.toggleAllButtonEl.addEventListener("click", this.toggleAll);
- this.playTimelineButtonEl.addEventListener("click", this.playPauseTimeline);
- this.rewindTimelineButtonEl.addEventListener("click", this.rewindTimeline);
+ this.toggleAllButtonEl.addEventListener("click", this.onToggleAllClicked);
+ this.playTimelineButtonEl.addEventListener(
+ "click", this.onTimelinePlayClicked);
+ this.rewindTimelineButtonEl.addEventListener(
+ "click", this.onTimelineRewindClicked);
+
+ document.addEventListener("keydown", this.onKeyDown, false);
gToolbox.target.on("navigate", this.onTabNavigated);
this.animationsTimelineComponent.on("timeline-data-changed",
this.onTimelineDataChanged);
if (this.rateSelectorComponent) {
this.rateSelectorComponent.on("rate-changed", this.onRateChanged);
@@ -131,30 +135,50 @@ var AnimationsPanel = {
stopListeners: function() {
AnimationsController.off(AnimationsController.PLAYERS_UPDATED_EVENT,
this.refreshAnimationsUI);
this.pickerButtonEl.removeEventListener("click", this.togglePicker);
gToolbox.off("picker-started", this.onPickerStarted);
gToolbox.off("picker-stopped", this.onPickerStopped);
- this.toggleAllButtonEl.removeEventListener("click", this.toggleAll);
- this.playTimelineButtonEl.removeEventListener("click", this.playPauseTimeline);
- this.rewindTimelineButtonEl.removeEventListener("click", this.rewindTimeline);
+ this.toggleAllButtonEl.removeEventListener("click", this.onToggleAllClicked);
+ this.playTimelineButtonEl.removeEventListener(
+ "click", this.onTimelinePlayClicked);
+ this.rewindTimelineButtonEl.removeEventListener(
+ "click", this.onTimelineRewindClicked);
+
+ document.removeEventListener("keydown", this.onKeyDown, false);
gToolbox.target.off("navigate", this.onTabNavigated);
this.animationsTimelineComponent.off("timeline-data-changed",
this.onTimelineDataChanged);
if (this.rateSelectorComponent) {
this.rateSelectorComponent.off("rate-changed", this.onRateChanged);
}
},
+ onKeyDown: function(event) {
+ let keyEvent = Ci.nsIDOMKeyEvent;
+
+ // If the space key is pressed, it should toggle the play state of
+ // the animations displayed in the panel, or of all the animations on
+ // the page if the selected node does not have any animation on it.
+ if (event.keyCode === keyEvent.DOM_VK_SPACE) {
+ if (AnimationsController.animationPlayers.length > 0) {
+ this.playPauseTimeline().catch(ex => console.error(ex));
+ } else {
+ this.toggleAll().catch(ex => console.error(ex));
+ }
+ event.preventDefault();
+ }
+ },
+
togglePlayers: function(isVisible) {
if (isVisible) {
document.body.removeAttribute("empty");
document.body.setAttribute("timeline", "true");
} else {
document.body.setAttribute("empty", "true");
document.body.removeAttribute("timeline");
}
@@ -163,52 +187,73 @@ var AnimationsPanel = {
onPickerStarted: function() {
this.pickerButtonEl.setAttribute("checked", "true");
},
onPickerStopped: function() {
this.pickerButtonEl.removeAttribute("checked");
},
+ onToggleAllClicked: function() {
+ this.toggleAll().catch(ex => console.error(ex));
+ },
+
+ /**
+ * Toggle (pause/play) all animations in the current target
+ * and update the UI the toggleAll button.
+ */
toggleAll: Task.async(function*() {
this.toggleAllButtonEl.classList.toggle("paused");
yield AnimationsController.toggleAll();
}),
+ onTimelinePlayClicked: function() {
+ this.playPauseTimeline().catch(ex => console.error(ex));
+ },
+
/**
* Depending on the state of the timeline either pause or play the animations
* displayed in it.
* If the animations are finished, this will play them from the start again.
* If the animations are playing, this will pause them.
* If the animations are paused, this will resume them.
+ *
+ * @return {Promise} Resolves when the playState is changed and the UI
+ * is refreshed
*/
playPauseTimeline: function() {
- AnimationsController.toggleCurrentAnimations(this.timelineData.isMoving)
- .then(() => this.refreshAnimationsStateAndUI())
- .catch(e => console.error(e));
+ return AnimationsController
+ .toggleCurrentAnimations(this.timelineData.isMoving)
+ .then(() => this.refreshAnimationsStateAndUI());
+ },
+
+ onTimelineRewindClicked: function() {
+ this.rewindTimeline().catch(ex => console.error(ex));
},
/**
* Reset the startTime of all current animations shown in the timeline and
* pause them.
+ *
+ * @return {Promise} Resolves when currentTime is set and the UI is refreshed
*/
rewindTimeline: function() {
- AnimationsController.setCurrentTimeAll(0, true)
- .then(() => this.refreshAnimationsStateAndUI())
- .catch(e => console.error(e));
+ return AnimationsController
+ .setCurrentTimeAll(0, true)
+ .then(() => this.refreshAnimationsStateAndUI());
},
/**
* Set the playback rate of all current animations shown in the timeline to
* the value of this.rateSelectorEl.
*/
onRateChanged: function(e, rate) {
AnimationsController.setPlaybackRateAll(rate)
.then(() => this.refreshAnimationsStateAndUI())
- .catch(e => console.error(e));
+ .catch(ex => console.error(ex));
},
onTabNavigated: function() {
this.toggleAllButtonEl.classList.remove("paused");
},
onTimelineDataChanged: function(e, data) {
this.timelineData = data;
--- a/devtools/client/animationinspector/test/browser.ini
+++ b/devtools/client/animationinspector/test/browser.ini
@@ -25,16 +25,18 @@ skip-if = os == "linux" && !debug # Bug
[browser_animation_playerWidgets_target_nodes.js]
[browser_animation_refresh_on_added_animation.js]
[browser_animation_refresh_on_removed_animation.js]
skip-if = os == "linux" && !debug # Bug 1227792
[browser_animation_refresh_when_active.js]
[browser_animation_running_on_compositor.js]
[browser_animation_same_nb_of_playerWidgets_and_playerFronts.js]
[browser_animation_shows_player_on_valid_node.js]
+[browser_animation_spacebar_toggles_animations.js]
+[browser_animation_spacebar_toggles_node_animations.js]
[browser_animation_target_highlight_select.js]
[browser_animation_target_highlighter_lock.js]
[browser_animation_timeline_currentTime.js]
[browser_animation_timeline_header.js]
[browser_animation_timeline_pause_button.js]
skip-if = os == "linux" && bits == 32 # Bug 1220974
[browser_animation_timeline_rate_selector.js]
[browser_animation_timeline_rewind_button.js]
new file mode 100644
--- /dev/null
+++ b/devtools/client/animationinspector/test/browser_animation_spacebar_toggles_animations.js
@@ -0,0 +1,43 @@
+/* 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 spacebar key press toggles the toggleAll button state
+// when a node with no animation is selected.
+// This test doesn't need to test if animations actually pause/resume
+// because there's an other test that does this :
+// browser_animation_toggle_button_toggles_animation.js
+
+add_task(function*() {
+ yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
+ let {panel, inspector, window, controller} = yield openAnimationInspector();
+ let {toggleAllButtonEl} = panel;
+
+ // select a node without animations
+ yield selectNode(".still", inspector);
+
+ // ensure the focus is on the animation panel
+ window.focus();
+
+ info("Simulate spacebar stroke and check toggleAll button" +
+ " is in paused state");
+
+ // sending the key will lead to a ALL_ANIMATIONS_TOGGLED_EVENT
+ let onToggled = once(controller, controller.ALL_ANIMATIONS_TOGGLED_EVENT);
+ EventUtils.sendKey("SPACE", window);
+ yield onToggled;
+ ok(toggleAllButtonEl.classList.contains("paused"),
+ "The toggle all button is in its paused state");
+
+ info("Simulate spacebar stroke and check toggleAll button" +
+ " is in playing state");
+
+ // sending the key will lead to a ALL_ANIMATIONS_TOGGLED_EVENT
+ onToggled = once(controller, controller.ALL_ANIMATIONS_TOGGLED_EVENT);
+ EventUtils.sendKey("SPACE", window);
+ yield onToggled;
+ ok(!toggleAllButtonEl.classList.contains("paused"),
+ "The toggle all button is in its playing state again");
+});
new file mode 100644
--- /dev/null
+++ b/devtools/client/animationinspector/test/browser_animation_spacebar_toggles_node_animations.js
@@ -0,0 +1,38 @@
+/* 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 spacebar key press toggles the play/resume button state.
+// This test doesn't need to test if animations actually pause/resume
+// because there's an other test that does this.
+
+add_task(function*() {
+ yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
+ let {panel, window} = yield openAnimationInspector();
+ let {playTimelineButtonEl} = panel;
+
+ // ensure the focus is on the animation panel
+ window.focus();
+
+ info("Simulate spacebar stroke and check playResume button" +
+ " is in paused state");
+
+ // sending the key will lead to a UI_UPDATE_EVENT
+ let onUpdated = panel.once(panel.UI_UPDATED_EVENT);
+ EventUtils.sendKey("SPACE", window);
+ yield onUpdated;
+ ok(playTimelineButtonEl.classList.contains("paused"),
+ "The play/resume button is in its paused state");
+
+ info("Simulate spacebar stroke and check playResume button" +
+ " is in playing state");
+
+ // sending the key will lead to a UI_UPDATE_EVENT
+ onUpdated = panel.once(panel.UI_UPDATED_EVENT);
+ EventUtils.sendKey("SPACE", window);
+ yield onUpdated;
+ ok(!playTimelineButtonEl.classList.contains("paused"),
+ "The play/resume button is in its play state again");
+});