Bug 1265718 - Decouple AnimationsFront from AnimationsActor;r=jryans
☠☠ backed out by 74fe05a5f015 ☠ ☠
authorEddy Bruel <ejpbruel@mozilla.com>
Tue, 24 May 2016 11:33:25 +0200
changeset 298269 25a5ae2711f38f202ab57b20518d3554072f2f47
parent 298268 be24ee25a35bcf318572fc1ff879de460dd37e37
child 298270 0e747813be13880fda46dca14981b47cae8688b3
push id19347
push userejpbruel@mozilla.com
push dateTue, 24 May 2016 09:34:07 +0000
treeherderfx-team@25a5ae2711f3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjryans
bugs1265718
milestone49.0a1
Bug 1265718 - Decouple AnimationsFront from AnimationsActor;r=jryans
devtools/client/animationinspector/animation-controller.js
devtools/server/actors/animation.js
devtools/shared/fronts/animation.js
devtools/shared/specs/animation.js
--- a/devtools/client/animationinspector/animation-controller.js
+++ b/devtools/client/animationinspector/animation-controller.js
@@ -14,17 +14,17 @@
 
 var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 
 var { loader, require } = Cu.import("resource://devtools/shared/Loader.jsm");
 var { Task } = require("devtools/shared/task");
 
 loader.lazyRequireGetter(this, "promise");
 loader.lazyRequireGetter(this, "EventEmitter", "devtools/shared/event-emitter");
-loader.lazyRequireGetter(this, "AnimationsFront", "devtools/server/actors/animation", true);
+loader.lazyRequireGetter(this, "AnimationsFront", "devtools/shared/fronts/animation", true);
 
 const { LocalizationHelper } = require("devtools/client/shared/l10n");
 
 const STRINGS_URI = "chrome://devtools/locale/animationinspector.properties";
 const L10N = new LocalizationHelper(STRINGS_URI);
 
 // Global toolbox/inspector, set when startup is called.
 var gToolbox, gInspector;
--- a/devtools/server/actors/animation.js
+++ b/devtools/server/actors/animation.js
@@ -26,20 +26,17 @@
  */
 
 const {Cu} = require("chrome");
 const promise = require("promise");
 const {Task} = require("devtools/shared/task");
 const protocol = require("devtools/shared/protocol");
 const {ActorClass, Actor, FrontClass, Front,
        Arg, method, RetVal, types} = protocol;
-// Make sure the nodeActor type is know here.
-const {NodeActor} = require("devtools/server/actors/inspector");
-const {AnimationPlayerFront} = require("devtools/shared/fronts/animation");
-const {animationPlayerSpec} = require("devtools/shared/specs/animation");
+const {animationPlayerSpec, animationsSpec} = require("devtools/shared/specs/animation");
 const events = require("sdk/event/core");
 
 // Types of animations.
 const ANIMATION_TYPES = {
   CSS_ANIMATION: "cssanimation",
   CSS_TRANSITION: "csstransition",
   SCRIPT_ANIMATION: "scriptanimation",
   UNKNOWN: "unknown"
@@ -429,41 +426,21 @@ var AnimationPlayerActor = protocol.Acto
     return this.player.effect.getProperties().map(property => {
       return {name: property.property, values: property.values};
     });
   }
 });
 
 exports.AnimationPlayerActor = AnimationPlayerActor;
 
- /**
- * Sent with the 'mutations' event as part of an array of changes, used to
- * inform fronts of the type of change that occured.
- */
-types.addDictType("animationMutationChange", {
-  // The type of change ("added" or "removed").
-  type: "string",
-  // The changed AnimationPlayerActor.
-  player: "animationplayer"
-});
-
 /**
  * The Animations actor lists animation players for a given node.
  */
-var AnimationsActor = exports.AnimationsActor = ActorClass({
-  typeName: "animations",
-
-  events: {
-    "mutations": {
-      type: "mutations",
-      changes: Arg(0, "array:animationMutationChange")
-    }
-  },
-
-  initialize: function (conn, tabActor) {
+var AnimationsActor = exports.AnimationsActor = protocol.ActorClassWithSpec(animationsSpec, {
+  initialize: function(conn, tabActor) {
     Actor.prototype.initialize.call(this, conn);
     this.tabActor = tabActor;
 
     this.onWillNavigate = this.onWillNavigate.bind(this);
     this.onNavigate = this.onNavigate.bind(this);
     this.onAnimationMutation = this.onAnimationMutation.bind(this);
 
     this.allAnimationsPaused = false;
@@ -491,36 +468,31 @@ var AnimationsActor = exports.Animations
   /**
    * Clients can optionally call this with a reference to their WalkerActor.
    * If they do, then AnimationPlayerActor's forms are going to also include
    * NodeActor IDs when the corresponding NodeActors do exist.
    * This, in turns, is helpful for clients to avoid having to go back once more
    * to the server to get a NodeActor for a particular animation.
    * @param {WalkerActor} walker
    */
-  setWalkerActor: method(function (walker) {
+  setWalkerActor: function (walker) {
     this.walker = walker;
-  }, {
-    request: {
-      walker: Arg(0, "domwalker")
-    },
-    response: {}
-  }),
+  },
 
   /**
    * Retrieve the list of AnimationPlayerActor actors for currently running
    * animations on a node and its descendants.
    * Note that calling this method a second time will destroy all previously
    * retrieved AnimationPlayerActors. Indeed, the lifecycle of these actors
    * is managed here on the server and tied to getAnimationPlayersForNode
    * being called.
    * @param {NodeActor} nodeActor The NodeActor as defined in
    * /devtools/server/actors/inspector
    */
-  getAnimationPlayersForNode: method(function (nodeActor) {
+  getAnimationPlayersForNode: function (nodeActor) {
     let animations = nodeActor.rawNode.getAnimations({subtree: true});
 
     // Destroy previously stored actors
     if (this.actors) {
       this.actors.forEach(actor => actor.destroy());
     }
     this.actors = [];
 
@@ -537,24 +509,17 @@ var AnimationsActor = exports.Animations
     let win = nodeActor.rawNode.ownerDocument.defaultView;
     this.observer = new win.MutationObserver(this.onAnimationMutation);
     this.observer.observe(nodeActor.rawNode, {
       animations: true,
       subtree: true
     });
 
     return this.actors;
-  }, {
-    request: {
-      actorID: Arg(0, "domnode")
-    },
-    response: {
-      players: RetVal("array:animationplayer")
-    }
-  }),
+  },
 
   onAnimationMutation: function (mutations) {
     let eventData = [];
     let readyPromises = [];
 
     for (let {addedAnimations, removedAnimations} of mutations) {
       for (let player of removedAnimations) {
         // Note that animations are reported as removed either when they are
@@ -624,24 +589,21 @@ var AnimationsActor = exports.Animations
     }
   },
 
   /**
    * After the client has called getAnimationPlayersForNode for a given DOM
    * node, the actor starts sending animation mutations for this node. If the
    * client doesn't want this to happen anymore, it should call this method.
    */
-  stopAnimationPlayerUpdates: method(function () {
+  stopAnimationPlayerUpdates: function () {
     if (this.observer && !Cu.isDeadWrapper(this.observer)) {
       this.observer.disconnect();
     }
-  }, {
-    request: {},
-    response: {}
-  }),
+  },
 
   /**
    * Iterates through all nodes below a given rootNode (optionally also in
    * nested frames) and finds all existing animation players.
    * @param {DOMNode} rootNode The root node to start iterating at. Animation
    * players will *not* be reported for this node.
    * @param {Boolean} traverseFrames Whether we should iterate through nested
    * frames too.
@@ -669,120 +631,81 @@ var AnimationsActor = exports.Animations
     if (isTopLevel) {
       this.allAnimationsPaused = false;
     }
   },
 
   /**
    * Pause all animations in the current tabActor's frames.
    */
-  pauseAll: method(function () {
+  pauseAll: function () {
     let readyPromises = [];
     // Until the WebAnimations API provides a way to play/pause via the document
     // timeline, we have to iterate through the whole DOM to find all players.
     for (let player of
          this.getAllAnimations(this.tabActor.window.document, true)) {
       player.pause();
       readyPromises.push(player.ready);
     }
     this.allAnimationsPaused = true;
     return promise.all(readyPromises);
-  }, {
-    request: {},
-    response: {}
-  }),
+  },
 
   /**
    * Play all animations in the current tabActor's frames.
    * This method only returns when animations have left their pending states.
    */
-  playAll: method(function () {
+  playAll: function () {
     let readyPromises = [];
     // Until the WebAnimations API provides a way to play/pause via the document
     // timeline, we have to iterate through the whole DOM to find all players.
     for (let player of
          this.getAllAnimations(this.tabActor.window.document, true)) {
       player.play();
       readyPromises.push(player.ready);
     }
     this.allAnimationsPaused = false;
     return promise.all(readyPromises);
-  }, {
-    request: {},
-    response: {}
-  }),
+  },
 
-  toggleAll: method(function () {
+  toggleAll: function () {
     if (this.allAnimationsPaused) {
       return this.playAll();
     }
     return this.pauseAll();
-  }, {
-    request: {},
-    response: {}
-  }),
+  },
 
   /**
    * Toggle (play/pause) several animations at the same time.
    * @param {Array} players A list of AnimationPlayerActor objects.
    * @param {Boolean} shouldPause If set to true, the players will be paused,
    * otherwise they will be played.
    */
-  toggleSeveral: method(function (players, shouldPause) {
+  toggleSeveral: function (players, shouldPause) {
     return promise.all(players.map(player => {
       return shouldPause ? player.pause() : player.play();
     }));
-  }, {
-    request: {
-      players: Arg(0, "array:animationplayer"),
-      shouldPause: Arg(1, "boolean")
-    },
-    response: {}
-  }),
+  },
 
   /**
    * Set the current time of several animations at the same time.
    * @param {Array} players A list of AnimationPlayerActor.
    * @param {Number} time The new currentTime.
    * @param {Boolean} shouldPause Should the players be paused too.
    */
-  setCurrentTimes: method(function (players, time, shouldPause) {
+  setCurrentTimes: function (players, time, shouldPause) {
     return promise.all(players.map(player => {
       let pause = shouldPause ? player.pause() : promise.resolve();
       return pause.then(() => player.setCurrentTime(time));
     }));
-  }, {
-    request: {
-      players: Arg(0, "array:animationplayer"),
-      time: Arg(1, "number"),
-      shouldPause: Arg(2, "boolean")
-    },
-    response: {}
-  }),
+  },
 
   /**
    * Set the playback rate of several animations at the same time.
    * @param {Array} players A list of AnimationPlayerActor.
    * @param {Number} rate The new rate.
    */
-  setPlaybackRates: method(function (players, rate) {
+  setPlaybackRates: function (players, rate) {
     for (let player of players) {
       player.setPlaybackRate(rate);
     }
-  }, {
-    request: {
-      players: Arg(0, "array:animationplayer"),
-      rate: Arg(1, "number")
-    },
-    response: {}
-  })
-});
-
-var AnimationsFront = exports.AnimationsFront = FrontClass(AnimationsActor, {
-  initialize: function (client, {animationsActor}) {
-    Front.prototype.initialize.call(this, client, {actor: animationsActor});
-    this.manage(this);
-  },
-
-  destroy: function () {
-    Front.prototype.destroy.call(this);
   }
 });
--- a/devtools/shared/fronts/animation.js
+++ b/devtools/shared/fronts/animation.js
@@ -4,17 +4,20 @@
 "use strict";
 
 const {
   Front,
   FrontClassWithSpec,
   custom,
   preEvent
 } = require("devtools/shared/protocol");
-const { animationPlayerSpec } = require("devtools/shared/specs/animation");
+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 = {};
   },
@@ -114,8 +117,21 @@ const AnimationPlayerFront = FrontClassW
       }
     }
 
     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;
--- a/devtools/shared/specs/animation.js
+++ b/devtools/shared/specs/animation.js
@@ -1,14 +1,31 @@
 /* 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 { Arg, RetVal, generateActorSpec } = require("devtools/shared/protocol");
+const {
+  Arg,
+  RetVal,
+  generateActorSpec,
+  types
+} = require("devtools/shared/protocol");
+require("devtools/shared/specs/inspector");
+
+/**
+ * Sent with the 'mutations' event as part of an array of changes, used to
+ * inform fronts of the type of change that occured.
+ */
+types.addDictType("animationMutationChange", {
+  // The type of change ("added" or "removed").
+  type: "string",
+  // The changed AnimationPlayerActor.
+  player: "animationplayer"
+});
 
 const animationPlayerSpec = generateActorSpec({
   typeName: "animationplayer",
 
   events: {
     "changed": {
       type: "changed",
       state: Arg(0, "json")
@@ -58,8 +75,77 @@ const animationPlayerSpec = generateActo
       response: {
         properties: RetVal("array:json")
       }
     }
   }
 });
 
 exports.animationPlayerSpec = animationPlayerSpec;
+
+const animationsSpec = generateActorSpec({
+  typeName: "animations",
+
+  events: {
+    "mutations": {
+      type: "mutations",
+      changes: Arg(0, "array:animationMutationChange")
+    }
+  },
+
+  methods: {
+    setWalkerActor: {
+      request: {
+        walker: Arg(0, "domwalker")
+      },
+      response: {}
+    },
+    getAnimationPlayersForNode: {
+      request: {
+        actorID: Arg(0, "domnode")
+      },
+      response: {
+        players: RetVal("array:animationplayer")
+      }
+    },
+    stopAnimationPlayerUpdates: {
+      request: {},
+      response: {}
+    },
+    pauseAll: {
+      request: {},
+      response: {}
+    },
+    playAll: {
+      request: {},
+      response: {}
+    },
+    toggleAll: {
+      request: {},
+      response: {}
+    },
+    toggleSeveral: {
+      request: {
+        players: Arg(0, "array:animationplayer"),
+        shouldPause: Arg(1, "boolean")
+      },
+      response: {}
+    },
+    setCurrentTimes: {
+      request: {
+        players: Arg(0, "array:animationplayer"),
+        time: Arg(1, "number"),
+        shouldPause: Arg(2, "boolean")
+      },
+      response: {}
+    },
+    setPlaybackRates: {
+      request: {
+        players: Arg(0, "array:animationplayer"),
+        rate: Arg(1, "number")
+      },
+      response: {}
+    }
+  }
+});
+
+exports.animationsSpec = animationsSpec;
+