2016-05-24 12:27:38 +03:00
|
|
|
/* 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,
|
2016-08-22 17:25:57 +03:00
|
|
|
FrontClassWithSpec,
|
2016-05-24 12:27:38 +03:00
|
|
|
custom,
|
|
|
|
preEvent
|
|
|
|
} = require("devtools/shared/protocol");
|
2016-05-26 16:47:52 +03:00
|
|
|
const {
|
|
|
|
animationPlayerSpec,
|
|
|
|
animationsSpec
|
|
|
|
} = require("devtools/shared/specs/animation");
|
2016-05-24 12:27:38 +03:00
|
|
|
const { Task } = require("devtools/shared/task");
|
|
|
|
|
2016-08-22 17:25:57 +03:00
|
|
|
const AnimationPlayerFront = FrontClassWithSpec(animationPlayerSpec, {
|
2017-01-12 01:21:56 +03:00
|
|
|
initialize: function (conn, form, detail, ctx) {
|
2016-05-24 12:27:38 +03:00
|
|
|
Front.prototype.initialize.call(this, conn, form, detail, ctx);
|
|
|
|
|
|
|
|
this.state = {};
|
|
|
|
},
|
|
|
|
|
2017-01-12 01:21:56 +03:00
|
|
|
form: function (form, detail) {
|
2016-05-24 12:27:38 +03:00
|
|
|
if (detail === "actorid") {
|
|
|
|
this.actorID = form;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
this._form = form;
|
|
|
|
this.state = this.initialState;
|
|
|
|
},
|
|
|
|
|
2017-01-12 01:21:56 +03:00
|
|
|
destroy: function () {
|
2016-05-24 12:27:38 +03:00
|
|
|
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,
|
2016-10-25 11:35:56 +03:00
|
|
|
easing: this._form.easing,
|
|
|
|
fill: this._form.fill,
|
|
|
|
direction: this._form.direction,
|
2016-05-24 12:27:38 +03:00
|
|
|
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"
|
|
|
|
}),
|
|
|
|
|
2017-01-12 01:21:56 +03:00
|
|
|
reconstructState: function (data) {
|
2016-05-24 12:27:38 +03:00
|
|
|
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;
|
2016-05-26 16:47:52 +03:00
|
|
|
|
2016-08-22 17:25:57 +03:00
|
|
|
const AnimationsFront = FrontClassWithSpec(animationsSpec, {
|
2017-01-12 01:21:56 +03:00
|
|
|
initialize: function (client, {animationsActor}) {
|
2016-05-26 16:47:52 +03:00
|
|
|
Front.prototype.initialize.call(this, client, {actor: animationsActor});
|
|
|
|
this.manage(this);
|
|
|
|
},
|
|
|
|
|
2017-01-12 01:21:56 +03:00
|
|
|
destroy: function () {
|
2016-05-26 16:47:52 +03:00
|
|
|
Front.prototype.destroy.call(this);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
exports.AnimationsFront = AnimationsFront;
|