Bug 1265718 - Decouple AnimationsFront from AnimationsActor;r=jryans
☠☠ backed out by 2a2ce43bcafb ☠ ☠
authorEddy Bruel <ejpbruel@mozilla.com>
Wed, 25 May 2016 10:18:27 +0200
changeset 337997 3c599aa289d8df66c7959dd65fd58cb1067c7fa9
parent 337701 242c458c4c61e94c8d12628612ef5e4e83992eaa
child 337998 6f87924204740088e96b5ae8e633963a90d5a359
push id6249
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 13:59:36 +0000
treeherdermozilla-beta@bad9d4f5bf7e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjryans
bugs1265718
milestone49.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1265718 - Decouple AnimationsFront from AnimationsActor;r=jryans
devtools/client/animationinspector/animation-controller.js
devtools/server/actors/animation.js
devtools/server/tests/browser/head.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/server/tests/browser/head.js
+++ b/devtools/server/tests/browser/head.js
@@ -44,17 +44,17 @@ var addTab = Task.async(function* (url) 
     let isBlank = url == "about:blank";
     waitForFocus(resolve, content, isBlank);
   });
 
   return tab.linkedBrowser;
 });
 
 function* initAnimationsFrontForUrl(url) {
-  const {AnimationsFront} = require("devtools/server/actors/animation");
+  const {AnimationsFront} = require("devtools/shared/fronts/animation");
   const {InspectorFront} = require("devtools/shared/fronts/inspector");
 
   yield addTab(url);
 
   initDebuggerServer();
   let client = new DebuggerClient(DebuggerServer.connectPipe());
   let form = yield connectDebuggerClient(client);
   let inspector = InspectorFront(client, form);
--- 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;
+