зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1105825 - Add auto state refresh to AnimationPlayerActors; r=bgrins
This commit is contained in:
Родитель
cc33239ad9
Коммит
440967c333
|
@ -24,10 +24,16 @@
|
|||
* /dom/webidl/Animation*.webidl
|
||||
*/
|
||||
|
||||
const {Cu} = require("chrome");
|
||||
const {Task} = Cu.import("resource://gre/modules/Task.jsm", {});
|
||||
const {setInterval, clearInterval} = require("sdk/timers");
|
||||
const {ActorClass, Actor,
|
||||
FrontClass, Front,
|
||||
Arg, method, RetVal} = require("devtools/server/protocol");
|
||||
const {NodeActor} = require("devtools/server/actors/inspector");
|
||||
const EventEmitter = require("devtools/toolkit/event-emitter");
|
||||
|
||||
const PLAYER_DEFAULT_AUTO_REFRESH_TIMEOUT = 500; // ms
|
||||
|
||||
/**
|
||||
* The AnimationPlayerActor provides information about a given animation: its
|
||||
|
@ -179,8 +185,13 @@ let AnimationPlayerActor = ActorClass({
|
|||
});
|
||||
|
||||
let AnimationPlayerFront = FrontClass(AnimationPlayerActor, {
|
||||
AUTO_REFRESH_EVENT: "updated-state",
|
||||
|
||||
initialize: function(conn, form, detail, ctx) {
|
||||
EventEmitter.decorate(this);
|
||||
Front.prototype.initialize.call(this, conn, form, detail, ctx);
|
||||
|
||||
this.state = {};
|
||||
},
|
||||
|
||||
form: function(form, detail) {
|
||||
|
@ -189,9 +200,11 @@ let AnimationPlayerFront = FrontClass(AnimationPlayerActor, {
|
|||
return;
|
||||
}
|
||||
this._form = form;
|
||||
this.state = this.initialState;
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
this.stopAutoRefresh();
|
||||
Front.prototype.destroy.call(this);
|
||||
},
|
||||
|
||||
|
@ -209,7 +222,75 @@ let AnimationPlayerFront = FrontClass(AnimationPlayerActor, {
|
|||
iterationCount: this._form.iterationCount,
|
||||
isRunningOnCompositor: this._form.isRunningOnCompositor
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// 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.
|
||||
*/
|
||||
startAutoRefresh: function(interval=PLAYER_DEFAULT_AUTO_REFRESH_TIMEOUT) {
|
||||
if (this.autoRefreshTimer) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.autoRefreshTimer = setInterval(this.refreshState.bind(this), 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.
|
||||
*/
|
||||
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) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if something has changed
|
||||
let hasChanged = false;
|
||||
for (let key in data) {
|
||||
if (this.state[key] !== data[key]) {
|
||||
hasChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasChanged) {
|
||||
this.state = data;
|
||||
this.emit(this.AUTO_REFRESH_EVENT, this.state);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
/**
|
||||
|
|
|
@ -18,6 +18,7 @@ support-files =
|
|||
[browser_animation_actors_02.js]
|
||||
[browser_animation_actors_03.js]
|
||||
[browser_animation_actors_04.js]
|
||||
[browser_animation_actors_05.js]
|
||||
[browser_navigateEvents.js]
|
||||
[browser_storage_dynamic_windows.js]
|
||||
[browser_storage_listings.js]
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
/* 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 = (e, 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);
|
||||
resolve();
|
||||
}
|
||||
};
|
||||
player.on(player.AUTO_REFRESH_EVENT, onNewState);
|
||||
});
|
||||
|
||||
yield onAllEventsReceived;
|
||||
|
||||
info("Stop the auto-refresh");
|
||||
player.stopAutoRefresh();
|
||||
|
||||
yield closeDebuggerClient(client);
|
||||
gBrowser.removeCurrentTab();
|
||||
});
|
Загрузка…
Ссылка в новой задаче