summaryrefslogtreecommitdiffstats
path: root/devtools/shared/fronts/animation.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/shared/fronts/animation.js')
-rw-r--r--devtools/shared/fronts/animation.js140
1 files changed, 140 insertions, 0 deletions
diff --git a/devtools/shared/fronts/animation.js b/devtools/shared/fronts/animation.js
new file mode 100644
index 000000000..01c9f0bfa
--- /dev/null
+++ b/devtools/shared/fronts/animation.js
@@ -0,0 +1,140 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+"use strict";
+
+const {
+ Front,
+ FrontClassWithSpec,
+ custom,
+ preEvent
+} = require("devtools/shared/protocol");
+const {
+ animationPlayerSpec,
+ animationsSpec
+} = require("devtools/shared/specs/animation");
+const { Task } = require("devtools/shared/task");
+
+const AnimationPlayerFront = FrontClassWithSpec(animationPlayerSpec, {
+ initialize: function (conn, form, detail, ctx) {
+ Front.prototype.initialize.call(this, conn, form, detail, ctx);
+
+ this.state = {};
+ },
+
+ form: function (form, detail) {
+ if (detail === "actorid") {
+ this.actorID = form;
+ return;
+ }
+ this._form = form;
+ this.state = this.initialState;
+ },
+
+ destroy: function () {
+ Front.prototype.destroy.call(this);
+ },
+
+ /**
+ * If the AnimationsActor was given a reference to the WalkerActor previously
+ * then calling this getter will return the animation target NodeFront.
+ */
+ get animationTargetNodeFront() {
+ if (!this._form.animationTargetNodeActorID) {
+ return null;
+ }
+
+ return this.conn.getActor(this._form.animationTargetNodeActorID);
+ },
+
+ /**
+ * Getter for the initial state of the player. Up to date states can be
+ * retrieved by calling the getCurrentState method.
+ */
+ get initialState() {
+ return {
+ type: this._form.type,
+ startTime: this._form.startTime,
+ previousStartTime: this._form.previousStartTime,
+ currentTime: this._form.currentTime,
+ playState: this._form.playState,
+ playbackRate: this._form.playbackRate,
+ name: this._form.name,
+ duration: this._form.duration,
+ delay: this._form.delay,
+ endDelay: this._form.endDelay,
+ iterationCount: this._form.iterationCount,
+ iterationStart: this._form.iterationStart,
+ easing: this._form.easing,
+ fill: this._form.fill,
+ direction: this._form.direction,
+ isRunningOnCompositor: this._form.isRunningOnCompositor,
+ propertyState: this._form.propertyState,
+ documentCurrentTime: this._form.documentCurrentTime
+ };
+ },
+
+ /**
+ * Executed when the AnimationPlayerActor emits a "changed" event. Used to
+ * update the local knowledge of the state.
+ */
+ onChanged: preEvent("changed", function (partialState) {
+ let {state} = this.reconstructState(partialState);
+ this.state = state;
+ }),
+
+ /**
+ * 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.
+ */
+ refreshState: Task.async(function* () {
+ let data = yield this.getCurrentState();
+ if (this.currentStateHasChanged) {
+ this.state = data;
+ }
+ }),
+
+ /**
+ * getCurrentState interceptor re-constructs incomplete states since the actor
+ * only sends the values that have changed.
+ */
+ getCurrentState: custom(function () {
+ this.currentStateHasChanged = false;
+ return this._getCurrentState().then(partialData => {
+ let {state, hasChanged} = this.reconstructState(partialData);
+ this.currentStateHasChanged = hasChanged;
+ return state;
+ });
+ }, {
+ impl: "_getCurrentState"
+ }),
+
+ reconstructState: function (data) {
+ let hasChanged = false;
+
+ for (let key in this.state) {
+ if (typeof data[key] === "undefined") {
+ data[key] = this.state[key];
+ } else if (data[key] !== this.state[key]) {
+ hasChanged = true;
+ }
+ }
+
+ return {state: data, hasChanged};
+ }
+});
+
+exports.AnimationPlayerFront = AnimationPlayerFront;
+
+const AnimationsFront = FrontClassWithSpec(animationsSpec, {
+ initialize: function (client, {animationsActor}) {
+ Front.prototype.initialize.call(this, client, {actor: animationsActor});
+ this.manage(this);
+ },
+
+ destroy: function () {
+ Front.prototype.destroy.call(this);
+ }
+});
+
+exports.AnimationsFront = AnimationsFront;