mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1120899 - Extract the animationplayer meta-data UI to a refreshable component; r=bgrins
This commit is contained in:
parent
c159c9c250
commit
97e5971148
@ -138,6 +138,8 @@ function PlayerWidget(player, containerEl) {
|
|||||||
|
|
||||||
this.onStateChanged = this.onStateChanged.bind(this);
|
this.onStateChanged = this.onStateChanged.bind(this);
|
||||||
this.onPlayPauseBtnClick = this.onPlayPauseBtnClick.bind(this);
|
this.onPlayPauseBtnClick = this.onPlayPauseBtnClick.bind(this);
|
||||||
|
|
||||||
|
this.metaDataComponent = new PlayerMetaDataHeader();
|
||||||
}
|
}
|
||||||
|
|
||||||
PlayerWidget.prototype = {
|
PlayerWidget.prototype = {
|
||||||
@ -159,6 +161,7 @@ PlayerWidget.prototype = {
|
|||||||
|
|
||||||
this.stopTimelineAnimation();
|
this.stopTimelineAnimation();
|
||||||
this.stopListeners();
|
this.stopListeners();
|
||||||
|
this.metaDataComponent.destroy();
|
||||||
|
|
||||||
this.el.remove();
|
this.el.remove();
|
||||||
this.playPauseBtnEl = this.currentTimeEl = this.timeDisplayEl = null;
|
this.playPauseBtnEl = this.currentTimeEl = this.timeDisplayEl = null;
|
||||||
@ -184,45 +187,8 @@ PlayerWidget.prototype = {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Animation header
|
this.metaDataComponent.createMarkup(this.el);
|
||||||
let titleEl = createNode({
|
this.metaDataComponent.render(state);
|
||||||
parent: this.el,
|
|
||||||
attributes: {
|
|
||||||
"class": "animation-title"
|
|
||||||
}
|
|
||||||
});
|
|
||||||
let titleHTML = "";
|
|
||||||
|
|
||||||
// Name.
|
|
||||||
if (state.name) {
|
|
||||||
// Css animations have names.
|
|
||||||
titleHTML += L10N.getStr("player.animationNameLabel");
|
|
||||||
titleHTML += "<strong>" + state.name + "</strong>";
|
|
||||||
} else {
|
|
||||||
// Css transitions don't.
|
|
||||||
titleHTML += L10N.getStr("player.transitionNameLabel");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Duration, delay and iteration count.
|
|
||||||
titleHTML += "<span class='meta-data'>";
|
|
||||||
titleHTML += L10N.getStr("player.animationDurationLabel");
|
|
||||||
titleHTML += "<strong>" + L10N.getFormatStr("player.timeLabel",
|
|
||||||
this.getFormattedTime(state.duration)) + "</strong>";
|
|
||||||
|
|
||||||
if (state.delay) {
|
|
||||||
titleHTML += L10N.getStr("player.animationDelayLabel");
|
|
||||||
titleHTML += "<strong>" + L10N.getFormatStr("player.timeLabel",
|
|
||||||
this.getFormattedTime(state.delay)) + "</strong>";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.iterationCount !== 1) {
|
|
||||||
titleHTML += L10N.getStr("player.animationIterationCountLabel");
|
|
||||||
let count = state.iterationCount || L10N.getStr("player.infiniteIterationCount");
|
|
||||||
titleHTML += "<strong>" + count + "</strong>";
|
|
||||||
}
|
|
||||||
|
|
||||||
titleHTML += "</span>";
|
|
||||||
titleEl.innerHTML = titleHTML;
|
|
||||||
|
|
||||||
// Timeline widget.
|
// Timeline widget.
|
||||||
let timelineEl = createNode({
|
let timelineEl = createNode({
|
||||||
@ -296,18 +262,6 @@ PlayerWidget.prototype = {
|
|||||||
this.displayTime(state.currentTime);
|
this.displayTime(state.currentTime);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Format time as a string.
|
|
||||||
* @param {Number} time Defaults to the player's currentTime.
|
|
||||||
* @return {String} The formatted time, e.g. "10.55"
|
|
||||||
*/
|
|
||||||
getFormattedTime: function(time) {
|
|
||||||
return (time/1000).toLocaleString(undefined, {
|
|
||||||
minimumFractionDigits: 2,
|
|
||||||
maximumFractionDigits: 2
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executed when the playPause button is clicked.
|
* Executed when the playPause button is clicked.
|
||||||
* Note that tests may want to call this callback directly rather than
|
* Note that tests may want to call this callback directly rather than
|
||||||
@ -328,7 +282,8 @@ PlayerWidget.prototype = {
|
|||||||
*/
|
*/
|
||||||
onStateChanged: function() {
|
onStateChanged: function() {
|
||||||
let state = this.player.state;
|
let state = this.player.state;
|
||||||
this.updateWidgetState(state.playState);
|
this.updateWidgetState(state);
|
||||||
|
this.metaDataComponent.render(state);
|
||||||
|
|
||||||
switch (state.playState) {
|
switch (state.playState) {
|
||||||
case "finished":
|
case "finished":
|
||||||
@ -354,7 +309,7 @@ PlayerWidget.prototype = {
|
|||||||
pause: function() {
|
pause: function() {
|
||||||
// Switch to the right className on the element right away to avoid waiting
|
// Switch to the right className on the element right away to avoid waiting
|
||||||
// for the next state update to change the playPause icon.
|
// for the next state update to change the playPause icon.
|
||||||
this.updateWidgetState("paused");
|
this.updateWidgetState({playState: "paused"});
|
||||||
return this.player.pause().then(() => {
|
return this.player.pause().then(() => {
|
||||||
this.stopTimelineAnimation();
|
this.stopTimelineAnimation();
|
||||||
});
|
});
|
||||||
@ -368,12 +323,12 @@ PlayerWidget.prototype = {
|
|||||||
play: function() {
|
play: function() {
|
||||||
// Switch to the right className on the element right away to avoid waiting
|
// Switch to the right className on the element right away to avoid waiting
|
||||||
// for the next state update to change the playPause icon.
|
// for the next state update to change the playPause icon.
|
||||||
this.updateWidgetState("running");
|
this.updateWidgetState({playState: "running"});
|
||||||
this.startTimelineAnimation();
|
this.startTimelineAnimation();
|
||||||
return this.player.play();
|
return this.player.play();
|
||||||
},
|
},
|
||||||
|
|
||||||
updateWidgetState: function(playState) {
|
updateWidgetState: function({playState}) {
|
||||||
this.el.className = "player-widget " + playState;
|
this.el.className = "player-widget " + playState;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -417,7 +372,7 @@ PlayerWidget.prototype = {
|
|||||||
|
|
||||||
// Set the time label value.
|
// Set the time label value.
|
||||||
this.timeDisplayEl.textContent = L10N.getFormatStr("player.timeLabel",
|
this.timeDisplayEl.textContent = L10N.getFormatStr("player.timeLabel",
|
||||||
this.getFormattedTime(time));
|
L10N.numberWithDecimals(time / 1000, 2));
|
||||||
|
|
||||||
// Set the timeline slider value.
|
// Set the timeline slider value.
|
||||||
if (!state.iterationCount && time !== state.duration) {
|
if (!state.iterationCount && time !== state.duration) {
|
||||||
@ -437,6 +392,162 @@ PlayerWidget.prototype = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
PlayerMetaDataHeader.prototype = {
|
||||||
|
createMarkup: function(containerEl) {
|
||||||
|
// The main title element.
|
||||||
|
this.el = createNode({
|
||||||
|
parent: containerEl,
|
||||||
|
attributes: {
|
||||||
|
"class": "animation-title"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Animation name (value hidden by default since transitions don't have names).
|
||||||
|
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 duration.
|
||||||
|
this.durationLabel = createNode({
|
||||||
|
parent: metaData,
|
||||||
|
nodeType: "span"
|
||||||
|
});
|
||||||
|
this.durationLabel.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;"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.delayLabel.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;"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.iterationLabel.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;
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function(state) {
|
||||||
|
// Update the name if needed.
|
||||||
|
if (state.name !== this.state.name) {
|
||||||
|
if (state.name) {
|
||||||
|
// Css animations have names.
|
||||||
|
this.nameLabel.textContent = L10N.getStr("player.animationNameLabel");
|
||||||
|
this.nameValue.style.display = "inline";
|
||||||
|
this.nameValue.textContent = state.name;
|
||||||
|
} else {
|
||||||
|
// Css transitions don't.
|
||||||
|
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";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.state = state;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DOM node creation helper function.
|
* DOM node creation helper function.
|
||||||
* @param {Object} Options to customize the node to be created.
|
* @param {Object} Options to customize the node to be created.
|
||||||
|
@ -22,3 +22,4 @@ support-files =
|
|||||||
[browser_animation_timeline_animates.js]
|
[browser_animation_timeline_animates.js]
|
||||||
[browser_animation_timeline_waits_for_delay.js]
|
[browser_animation_timeline_waits_for_delay.js]
|
||||||
[browser_animation_ui_updates_when_animation_changes.js]
|
[browser_animation_ui_updates_when_animation_changes.js]
|
||||||
|
[browser_animation_ui_updates_when_animation_data_changes.js]
|
||||||
|
@ -13,12 +13,22 @@ add_task(function*() {
|
|||||||
info("Selecting a node with an animation that doesn't repeat");
|
info("Selecting a node with an animation that doesn't repeat");
|
||||||
yield selectNode(".long", inspector);
|
yield selectNode(".long", inspector);
|
||||||
let widget = panel.playerWidgets[0];
|
let widget = panel.playerWidgets[0];
|
||||||
let metaDataLabels = widget.el.querySelectorAll(".animation-title .meta-data strong");
|
|
||||||
is(metaDataLabels.length, 1, "Only the duration is shown");
|
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");
|
info("Selecting a node with an animation that repeats several times");
|
||||||
yield selectNode(".delayed", inspector);
|
yield selectNode(".delayed", inspector);
|
||||||
widget = panel.playerWidgets[0];
|
widget = panel.playerWidgets[0];
|
||||||
let iterationLabel = widget.el.querySelectorAll(".animation-title .meta-data strong")[2];
|
|
||||||
is(iterationLabel.textContent, "10", "The iteration is shown");
|
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");
|
||||||
});
|
});
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
// slider don't show values bigger than the animation duration (which would
|
// slider don't show values bigger than the animation duration (which would
|
||||||
// happen if the local requestAnimationFrame loop didn't stop correctly).
|
// happen if the local requestAnimationFrame loop didn't stop correctly).
|
||||||
|
|
||||||
|
let L10N = new ViewHelpers.L10N();
|
||||||
|
|
||||||
add_task(function*() {
|
add_task(function*() {
|
||||||
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
|
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
|
||||||
let {inspector, panel} = yield openAnimationInspector();
|
let {inspector, panel} = yield openAnimationInspector();
|
||||||
@ -35,6 +37,6 @@ add_task(function*() {
|
|||||||
is(widget.currentTimeEl.value, front.state.duration,
|
is(widget.currentTimeEl.value, front.state.duration,
|
||||||
"The timeline slider has the right value");
|
"The timeline slider has the right value");
|
||||||
is(widget.timeDisplayEl.textContent,
|
is(widget.timeDisplayEl.textContent,
|
||||||
widget.getFormattedTime(front.state.duration) + "s",
|
L10N.numberWithDecimals(front.state.duration / 1000, 2) + "s",
|
||||||
"The timeline slider has the right value");
|
"The timeline slider has the right value");
|
||||||
});
|
});
|
||||||
|
@ -26,9 +26,11 @@ add_task(function*() {
|
|||||||
ok(metaDataEl, "The meta-data element exists");
|
ok(metaDataEl, "The meta-data element exists");
|
||||||
|
|
||||||
let metaDataEls = metaDataEl.querySelectorAll("strong");
|
let metaDataEls = metaDataEl.querySelectorAll("strong");
|
||||||
is(metaDataEls.length, 2, "2 meta-data elements were found");
|
is(metaDataEls.length, 3, "3 meta-data elements were found");
|
||||||
is(metaDataEls[0].textContent, "2.00s",
|
is(metaDataEls[0].textContent, "2s",
|
||||||
"The first meta-data is the duration, and is correct");
|
"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");
|
info("Select the node with the delayed animation");
|
||||||
yield selectNode(".delayed", inspector);
|
yield selectNode(".delayed", inspector);
|
||||||
@ -40,10 +42,13 @@ add_task(function*() {
|
|||||||
metaDataEls = titleEl.querySelectorAll(".meta-data strong");
|
metaDataEls = titleEl.querySelectorAll(".meta-data strong");
|
||||||
is(metaDataEls.length, 3,
|
is(metaDataEls.length, 3,
|
||||||
"3 meta-data elements were found for the delayed animation");
|
"3 meta-data elements were found for the delayed animation");
|
||||||
is(metaDataEls[0].textContent, "3.00s",
|
is(metaDataEls[0].textContent, "3s",
|
||||||
"The first meta-data is the duration, and is correct");
|
"The first meta-data is the duration, and is correct");
|
||||||
is(metaDataEls[1].textContent, "60.00s",
|
ok(isNodeVisible(metaDataEls[0]), "The duration is shown");
|
||||||
|
is(metaDataEls[1].textContent, "60s",
|
||||||
"The second meta-data is the delay, and is correct");
|
"The second meta-data is the delay, and is correct");
|
||||||
|
ok(isNodeVisible(metaDataEls[1]), "The delay is shown");
|
||||||
is(metaDataEls[2].textContent, "10",
|
is(metaDataEls[2].textContent, "10",
|
||||||
"The third meta-data is the iteration count, and is correct");
|
"The third meta-data is the iteration count, and is correct");
|
||||||
|
ok(isNodeVisible(metaDataEls[2]), "The iteration count is shown");
|
||||||
});
|
});
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
// Test that once an animation is paused and its widget is refreshed, the right
|
// Test that once an animation is paused and its widget is refreshed, the right
|
||||||
// initial time is displayed.
|
// initial time is displayed.
|
||||||
|
|
||||||
|
let L10N = new ViewHelpers.L10N();
|
||||||
|
|
||||||
add_task(function*() {
|
add_task(function*() {
|
||||||
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
|
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
|
||||||
let {inspector, panel} = yield openAnimationInspector();
|
let {inspector, panel} = yield openAnimationInspector();
|
||||||
@ -25,6 +27,7 @@ add_task(function*() {
|
|||||||
widget = panel.playerWidgets[0];
|
widget = panel.playerWidgets[0];
|
||||||
ok(widget.el.classList.contains("paused"), "The widget is still in paused mode");
|
ok(widget.el.classList.contains("paused"), "The widget is still in paused mode");
|
||||||
is(widget.timeDisplayEl.textContent,
|
is(widget.timeDisplayEl.textContent,
|
||||||
widget.getFormattedTime(widget.player.state.currentTime) + "s",
|
L10N.numberWithDecimals(widget.player.state.currentTime / 1000, 2) + "s",
|
||||||
"The initial time has been set to the player's");
|
"The initial time has been set to the player's");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -20,5 +20,5 @@ add_task(function*() {
|
|||||||
is(timeline.value, 0, "The timeline is at 0 since the animation hasn't started");
|
is(timeline.value, 0, "The timeline is at 0 since the animation hasn't started");
|
||||||
|
|
||||||
let timeLabel = widget.timeDisplayEl;
|
let timeLabel = widget.timeDisplayEl;
|
||||||
is(timeLabel.textContent, "0.00s", "The current time is 0");
|
is(timeLabel.textContent, "0s", "The current time is 0");
|
||||||
});
|
});
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
/* 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's duration, iterations or delay change in
|
||||||
|
// content, then the widget reflects the changes.
|
||||||
|
|
||||||
|
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];
|
||||||
|
|
||||||
|
yield setStyle(widget, "animationDuration", "5.5s");
|
||||||
|
is(widget.metaDataComponent.durationValue.textContent, "5.50s",
|
||||||
|
"The widget shows the new duration");
|
||||||
|
|
||||||
|
yield setStyle(widget, "animationIterationCount", "300");
|
||||||
|
is(widget.metaDataComponent.iterationValue.textContent, "300",
|
||||||
|
"The widget shows the new iteration count");
|
||||||
|
|
||||||
|
yield setStyle(widget, "animationDelay", "45s");
|
||||||
|
is(widget.metaDataComponent.delayValue.textContent, "45s",
|
||||||
|
"The widget shows the new delay");
|
||||||
|
});
|
||||||
|
|
||||||
|
function* setStyle(widget, name, value) {
|
||||||
|
info("Change the animation style via the content DOM. Setting " +
|
||||||
|
name + " to " + value);
|
||||||
|
yield executeInContent("Test:SetNodeStyle", {
|
||||||
|
propertyName: name,
|
||||||
|
propertyValue: value
|
||||||
|
}, {
|
||||||
|
node: getNode(".animated")
|
||||||
|
});
|
||||||
|
|
||||||
|
info("Wait for the next state update");
|
||||||
|
yield widget.player.once(widget.player.AUTO_REFRESH_EVENT);
|
||||||
|
}
|
@ -26,3 +26,21 @@ addMessageListener("Test:ToggleAnimationPlayer", function(msg) {
|
|||||||
|
|
||||||
sendAsyncMessage("Test:ToggleAnimationPlayer");
|
sendAsyncMessage("Test:ToggleAnimationPlayer");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a given style property value on a node. This is useful to dynamically
|
||||||
|
* change an animation's duration or delay for instance.
|
||||||
|
* @param {Object} data
|
||||||
|
* - {String} propertyName The name of the property to set.
|
||||||
|
* - {String} propertyValue The value for the property.
|
||||||
|
* @param {Object} objects
|
||||||
|
* - {DOMNode} node The node to use
|
||||||
|
*/
|
||||||
|
addMessageListener("Test:SetNodeStyle", function(msg) {
|
||||||
|
let {propertyName, propertyValue} = msg.data;
|
||||||
|
let {node} = msg.objects;
|
||||||
|
|
||||||
|
node.style[propertyName] = propertyValue;
|
||||||
|
|
||||||
|
sendAsyncMessage("Test:SetNodeStyle");
|
||||||
|
});
|
||||||
|
@ -54,7 +54,7 @@
|
|||||||
left: 10px;
|
left: 10px;
|
||||||
background: red;
|
background: red;
|
||||||
|
|
||||||
animation: simple-animation 2s
|
animation: simple-animation 2s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.long {
|
.long {
|
||||||
@ -62,7 +62,7 @@
|
|||||||
left: 10px;
|
left: 10px;
|
||||||
background: blue;
|
background: blue;
|
||||||
|
|
||||||
animation: simple-animation 120s
|
animation: simple-animation 120s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes simple-animation {
|
@keyframes simple-animation {
|
||||||
|
@ -5,11 +5,12 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const Cu = Components.utils;
|
const Cu = Components.utils;
|
||||||
let {gDevTools} = Cu.import("resource:///modules/devtools/gDevTools.jsm", {});
|
const {gDevTools} = Cu.import("resource:///modules/devtools/gDevTools.jsm", {});
|
||||||
let {devtools} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
|
const {devtools} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
|
||||||
let {Promise: promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
|
const {Promise: promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
|
||||||
let TargetFactory = devtools.TargetFactory;
|
const TargetFactory = devtools.TargetFactory;
|
||||||
let {console} = Components.utils.import("resource://gre/modules/devtools/Console.jsm", {});
|
const {console} = Components.utils.import("resource://gre/modules/devtools/Console.jsm", {});
|
||||||
|
const {ViewHelpers} = Cu.import("resource:///modules/devtools/ViewHelpers.jsm", {});
|
||||||
|
|
||||||
// All tests are asynchronous
|
// All tests are asynchronous
|
||||||
waitForExplicitFinish();
|
waitForExplicitFinish();
|
||||||
@ -263,12 +264,30 @@ function executeInContent(name, data={}, objects={}, expectResponse=true) {
|
|||||||
* Simulate a click on the playPause button of a playerWidget.
|
* Simulate a click on the playPause button of a playerWidget.
|
||||||
*/
|
*/
|
||||||
let togglePlayPauseButton = Task.async(function*(widget) {
|
let togglePlayPauseButton = Task.async(function*(widget) {
|
||||||
|
let nextState = widget.player.state.playState === "running" ? "paused" : "running";
|
||||||
|
|
||||||
// Note that instead of simulating a real event here, the callback is just
|
// Note that instead of simulating a real event here, the callback is just
|
||||||
// called. This is better because the callback returns a promise, so we know
|
// called. This is better because the callback returns a promise, so we know
|
||||||
// when the player is paused, and we don't really care to test that simulating
|
// when the player is paused, and we don't really care to test that simulating
|
||||||
// a DOM event actually works.
|
// a DOM event actually works.
|
||||||
yield widget.onPlayPauseBtnClick();
|
let onClicked = widget.onPlayPauseBtnClick();
|
||||||
|
|
||||||
|
// Verify that the button's state is changed immediately, even if it will be
|
||||||
|
// changed anyway with the next auto-refresh.
|
||||||
|
ok(widget.el.classList.contains(nextState),
|
||||||
|
"The button's state was changed in the UI before the request was sent");
|
||||||
|
|
||||||
|
yield onClicked;
|
||||||
|
|
||||||
// Wait for the next sate change event to make sure the state is updated
|
// Wait for the next sate change event to make sure the state is updated
|
||||||
yield widget.player.once(widget.player.AUTO_REFRESH_EVENT);
|
yield widget.player.once(widget.player.AUTO_REFRESH_EVENT);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the given node visible in the page (rendered in the frame tree).
|
||||||
|
* @param {DOMNode}
|
||||||
|
* @return {Boolean}
|
||||||
|
*/
|
||||||
|
function isNodeVisible(node) {
|
||||||
|
return !!node.getClientRects().length;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user