зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1129454 - 1 - Adds [play|pause]All methods to the AnimationsActor to pause/play all running animations; r=miker
This commit is contained in:
Родитель
5738bd910f
Коммит
20f47d548f
|
@ -25,12 +25,14 @@
|
|||
*/
|
||||
|
||||
const {Cu} = require("chrome");
|
||||
const {Promise: promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
|
||||
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} = protocol;
|
||||
const {NodeActor} = require("devtools/server/actors/inspector");
|
||||
const EventEmitter = require("devtools/toolkit/event-emitter");
|
||||
const events = require("sdk/event/core");
|
||||
|
||||
const PLAYER_DEFAULT_AUTO_REFRESH_TIMEOUT = 500; // ms
|
||||
|
||||
|
@ -149,7 +151,9 @@ let AnimationPlayerActor = ActorClass({
|
|||
iterationText = iterationText.split(",")[this.playerIndex];
|
||||
}
|
||||
|
||||
return parseInt(iterationText, 10);
|
||||
return iterationText === "infinite"
|
||||
? null
|
||||
: parseInt(iterationText, 10);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -379,10 +383,17 @@ let AnimationsActor = exports.AnimationsActor = ActorClass({
|
|||
|
||||
initialize: function(conn, tabActor) {
|
||||
Actor.prototype.initialize.call(this, conn);
|
||||
this.tabActor = tabActor;
|
||||
|
||||
this.allAnimationsPaused = false;
|
||||
this.onNavigate = this.onNavigate.bind(this);
|
||||
events.on(this.tabActor, "navigate", this.onNavigate);
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
Actor.prototype.destroy.call(this);
|
||||
events.off(this.tabActor, "navigate", this.onNavigate);
|
||||
this.tabActor = null;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -417,6 +428,77 @@ let AnimationsActor = exports.AnimationsActor = ActorClass({
|
|||
response: {
|
||||
players: RetVal("array:animationplayer")
|
||||
}
|
||||
}),
|
||||
|
||||
/**
|
||||
* Iterates through all nodes in all of the tabActor's window documents and
|
||||
* finds all existing animation players.
|
||||
* This is currently used to allow playing/pausing all animations at once
|
||||
* until the WebAnimations API provides a way to play/pause via the document
|
||||
* timeline (alternatively, when bug 1123524 is fixed, we will be able to
|
||||
* only iterate once and then listen for changes).
|
||||
*/
|
||||
getAllAnimationPlayers: function() {
|
||||
let players = [];
|
||||
|
||||
// These loops shouldn't be as bad as they look.
|
||||
// Typically, there will be very few windows, and getElementsByTagName is
|
||||
// really fast even on large DOM trees.
|
||||
for (let window of this.tabActor.windows) {
|
||||
let root = window.document.body || window.document;
|
||||
for (let element of root.getElementsByTagNameNS("*", "*")) {
|
||||
players = [...players, ...element.getAnimationPlayers()];
|
||||
}
|
||||
}
|
||||
|
||||
return players;
|
||||
},
|
||||
|
||||
onNavigate: function({isTopLevel}) {
|
||||
if (isTopLevel) {
|
||||
this.allAnimationsPaused = false;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Pause all animations in the current tabActor's frames.
|
||||
*/
|
||||
pauseAll: method(function() {
|
||||
for (let player of this.getAllAnimationPlayers()) {
|
||||
player.pause();
|
||||
}
|
||||
this.allAnimationsPaused = true;
|
||||
}, {
|
||||
request: {},
|
||||
response: {}
|
||||
}),
|
||||
|
||||
/**
|
||||
* Play all animations in the current tabActor's frames.
|
||||
* This method only returns when the animations have left their pending states.
|
||||
*/
|
||||
playAll: method(function() {
|
||||
let readyPromises = [];
|
||||
for (let player of this.getAllAnimationPlayers()) {
|
||||
player.play();
|
||||
readyPromises.push(player.ready);
|
||||
}
|
||||
this.allAnimationsPaused = false;
|
||||
return promise.all(readyPromises);
|
||||
}, {
|
||||
request: {},
|
||||
response: {}
|
||||
}),
|
||||
|
||||
toggleAll: method(function() {
|
||||
if (this.allAnimationsPaused) {
|
||||
return this.playAll();
|
||||
} else {
|
||||
return this.pauseAll();
|
||||
}
|
||||
}, {
|
||||
request: {},
|
||||
response: {}
|
||||
})
|
||||
});
|
||||
|
||||
|
|
|
@ -22,6 +22,8 @@ support-files =
|
|||
[browser_animation_actors_05.js]
|
||||
[browser_animation_actors_06.js]
|
||||
[browser_animation_actors_07.js]
|
||||
[browser_animation_actors_08.js]
|
||||
[browser_animation_actors_09.js]
|
||||
[browser_navigateEvents.js]
|
||||
[browser_storage_dynamic_windows.js]
|
||||
[browser_storage_listings.js]
|
||||
|
|
|
@ -21,6 +21,9 @@ add_task(function*() {
|
|||
|
||||
ok(front, "The AnimationsFront was created");
|
||||
ok(front.getAnimationPlayersForNode, "The getAnimationPlayersForNode method exists");
|
||||
ok(front.toggleAll, "The toggleAll method exists");
|
||||
ok(front.playAll, "The playAll method exists");
|
||||
ok(front.pauseAll, "The pauseAll method exists");
|
||||
|
||||
let didThrow = false;
|
||||
try {
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/* 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 the AnimationsActor can pause/play all animations at once.
|
||||
|
||||
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);
|
||||
|
||||
info("Pause all animations in the test document");
|
||||
yield front.pauseAll();
|
||||
yield checkAllAnimationsStates(walker, front, "paused");
|
||||
|
||||
info("Play all animations in the test document");
|
||||
yield front.playAll();
|
||||
yield checkAllAnimationsStates(walker, front, "running");
|
||||
|
||||
info("Pause all animations in the test document using toggleAll");
|
||||
yield front.toggleAll();
|
||||
yield checkAllAnimationsStates(walker, front, "paused");
|
||||
|
||||
info("Play all animations in the test document using toggleAll");
|
||||
yield front.toggleAll();
|
||||
yield checkAllAnimationsStates(walker, front, "running");
|
||||
|
||||
yield closeDebuggerClient(client);
|
||||
gBrowser.removeCurrentTab();
|
||||
});
|
||||
|
||||
function* checkAllAnimationsStates(walker, front, playState) {
|
||||
info("Checking the playState of all the nodes that have infinite running animations");
|
||||
|
||||
let selectors = [".simple-animation", ".multiple-animations", ".delayed-animation"];
|
||||
for (let selector of selectors) {
|
||||
info("Getting the AnimationPlayerFront for node " + selector);
|
||||
let node = yield walker.querySelector(walker.rootNode, selector);
|
||||
let [player] = yield front.getAnimationPlayersForNode(node);
|
||||
yield player.ready;
|
||||
let state = yield player.getCurrentState();
|
||||
is(state.playState, playState,
|
||||
"The playState of node " + selector + " is " + playState);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/* 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 the AnimationsActor can pause/play all animations even those
|
||||
// within iframes.
|
||||
|
||||
const {AnimationsFront} = require("devtools/server/actors/animation");
|
||||
const {InspectorFront} = require("devtools/server/actors/inspector");
|
||||
|
||||
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='i1' src='" + URL + "'></iframe>" +
|
||||
"<iframe id='i2' src='" + URL + "'></iframe>");
|
||||
|
||||
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);
|
||||
|
||||
info("Getting the 2 iframe container nodes and animated nodes in them");
|
||||
let nodeInFrame1 = yield getNodeInFrame(walker, "#i1", ".simple-animation");
|
||||
let nodeInFrame2 = yield getNodeInFrame(walker, "#i2", ".simple-animation");
|
||||
|
||||
info("Pause all animations in the test document");
|
||||
yield front.pauseAll();
|
||||
yield checkState(front, nodeInFrame1, "paused");
|
||||
yield checkState(front, nodeInFrame2, "paused");
|
||||
|
||||
info("Play all animations in the test document");
|
||||
yield front.playAll();
|
||||
yield checkState(front, nodeInFrame1, "running");
|
||||
yield checkState(front, nodeInFrame2, "running");
|
||||
|
||||
yield closeDebuggerClient(client);
|
||||
gBrowser.removeCurrentTab();
|
||||
});
|
||||
|
||||
function* checkState(front, nodeFront, playState) {
|
||||
info("Getting the AnimationPlayerFront for the test node");
|
||||
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);
|
||||
}
|
||||
|
||||
function* getNodeInFrame(walker, frameSelector, nodeSelector) {
|
||||
let iframe = yield walker.querySelector(walker.rootNode, frameSelector);
|
||||
let {nodes} = yield walker.children(iframe);
|
||||
return walker.querySelector(nodes[0], nodeSelector);
|
||||
}
|
Загрузка…
Ссылка в новой задаче