bug 1507146 - make getting animation front async in animation panel; r=ochameau
authoryulia <ystartsev@mozilla.com>
Wed, 21 Nov 2018 14:34:42 +0000
changeset 503923 8ae1895193586cbd409ae6a9282cdf67793b4add
parent 503922 5990eabd10965f59d4a33c9fd2453a5cc96794dd
child 503924 d65ba27b4b5d5640c7a19b47ec30eb9646f8f077
push id10290
push userffxbld-merge
push dateMon, 03 Dec 2018 16:23:23 +0000
treeherdermozilla-beta@700bed2445e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersochameau
bugs1507146
milestone65.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 1507146 - make getting animation front async in animation panel; r=ochameau Animations panel also had a sync getTarget location. Unfortunately this animation front was used in a number of locations. In this case, I used getFront in each call location, as these were always async. I am not sure if this was the best way Depends on D11887 Differential Revision: https://phabricator.services.mozilla.com/D11888
devtools/client/inspector/animation/animation.js
--- a/devtools/client/inspector/animation/animation.js
+++ b/devtools/client/inspector/animation/animation.js
@@ -94,20 +94,18 @@ class AnimationInspector {
       setDetailVisibility,
       setHighlightedNode,
       setSelectedNode,
       simulateAnimation,
       simulateAnimationForKeyframesProgressBar,
       toggleElementPicker,
     } = this;
 
-    const target = this.inspector.target;
     const direction = this.win.document.dir;
-    this.animationsFront = target.getFront("animations");
-    this.animationsFront.setWalkerActor(this.inspector.walker);
+    this._getAnimationsFront();
 
     this.animationsCurrentTimeListeners = [];
     this.isCurrentTimeSet = false;
 
     const provider = createElement(Provider,
       {
         id: "animationinspector",
         key: "animationinspector",
@@ -143,27 +141,42 @@ class AnimationInspector {
     this.provider = provider;
 
     this.inspector.sidebar.on("select", this.onSidebarSelectionChanged);
     this.inspector.toolbox.on("picker-started", this.onElementPickerStarted);
     this.inspector.toolbox.on("picker-stopped", this.onElementPickerStopped);
     this.inspector.toolbox.on("select", this.onSidebarSelectionChanged);
   }
 
+  _getAnimationsFront() {
+    if (this.animationsFrontPromise) {
+      return this.animationsFrontPromise;
+    }
+    this.animationsFrontPromise = new Promise(async resolve => {
+      const target = this.inspector.target;
+      const front = await target.getFront("animations");
+      front.setWalkerActor(this.inspector.walker);
+      resolve(front);
+    });
+    return this.animationsFrontPromise;
+  }
+
   destroy() {
     this.setAnimationStateChangedListenerEnabled(false);
     this.inspector.off("new-root", this.onNavigate);
     this.inspector.selection.off("new-node-front", this.update);
     this.inspector.sidebar.off("select", this.onSidebarSelectionChanged);
     this.inspector.toolbox.off("inspector-sidebar-resized", this.onSidebarResized);
     this.inspector.toolbox.off("picker-started", this.onElementPickerStarted);
     this.inspector.toolbox.off("picker-stopped", this.onElementPickerStopped);
     this.inspector.toolbox.off("select", this.onSidebarSelectionChanged);
 
-    this.animationsFront.off("mutations", this.onAnimationsMutation);
+    this.animationsFrontPromise.then(front => {
+      front.off("mutations", this.onAnimationsMutation);
+    });
 
     if (this.simulatedAnimation) {
       this.simulatedAnimation.cancel();
       this.simulatedAnimation = null;
     }
 
     if (this.simulatedElement) {
       this.simulatedElement.remove();
@@ -192,17 +205,18 @@ class AnimationInspector {
   /**
    * This function calls AnimationsFront.setCurrentTimes with considering the createdTime.
    *
    * @param {Number} currentTime
    */
   async doSetCurrentTimes(currentTime) {
     const { animations, timeScale } = this.state;
     currentTime = currentTime + timeScale.minStartTime;
-    await this.animationsFront.setCurrentTimes(animations, currentTime, true,
+    const animationsFront = await this.animationsFrontPromise;
+    await animationsFront.setCurrentTimes(animations, currentTime, true,
                                                { relativeToCreatedTime: true });
   }
 
   /**
    * Return a map of animated property from given animation actor.
    *
    * @param {Object} animation
    * @return {Map} A map of animated property
@@ -364,26 +378,27 @@ class AnimationInspector {
     if (this.wasPanelVisibled === isPanelVisibled) {
       // onSidebarSelectionChanged is called some times even same state
       // from sidebar and toolbar.
       return;
     }
 
     this.wasPanelVisibled = isPanelVisibled;
 
+    const animationsFront = await this.animationsFrontPromise;
     if (this.isPanelVisible()) {
       await this.update();
       this.onSidebarResized(null, this.inspector.getSidebarSize());
-      this.animationsFront.on("mutations", this.onAnimationsMutation);
+      animationsFront.on("mutations", this.onAnimationsMutation);
       this.inspector.on("new-root", this.onNavigate);
       this.inspector.selection.on("new-node-front", this.update);
       this.inspector.toolbox.on("inspector-sidebar-resized", this.onSidebarResized);
     } else {
       this.stopAnimationsCurrentTimeTimer();
-      this.animationsFront.off("mutations", this.onAnimationsMutation);
+      animationsFront.off("mutations", this.onAnimationsMutation);
       this.inspector.off("new-root", this.onNavigate);
       this.inspector.selection.off("new-node-front", this.update);
       this.inspector.toolbox.off("inspector-sidebar-resized", this.onSidebarResized);
       this.setAnimationStateChangedListenerEnabled(false);
     }
   }
 
   onSidebarResized(size) {
@@ -444,17 +459,18 @@ class AnimationInspector {
   async setAnimationsPlaybackRate(playbackRate) {
     let animations = this.state.animations;
     // "changed" event on each animation will fire respectively when the playback
     // rate changed. Since for each occurrence of event, change of UI is urged.
     // To avoid this, disable the listeners once in order to not capture the event.
     this.setAnimationStateChangedListenerEnabled(false);
 
     try {
-      await this.animationsFront.setPlaybackRates(animations, playbackRate);
+      const animationsFront = await this.animationsFrontPromise;
+      await animationsFront.setPlaybackRates(animations, playbackRate);
       animations = await this.updateAnimations(animations);
     } catch (e) {
       // Expected if we've already been destroyed or other node have been selected
       // in the meantime.
       console.error(e);
       return;
     } finally {
       this.setAnimationStateChangedListenerEnabled(true);
@@ -475,26 +491,27 @@ class AnimationInspector {
       if (doPlay && animations.every(animation =>
                       timeScale.getEndTime(animation) <= animation.state.currentTime)) {
         await this.doSetCurrentTimes(timeScale.zeroPositionTime);
       }
 
       // If the server does not support pauseSome/playSome function, (which happens
       // when connected to server older than FF62), use pauseAll/playAll instead.
       // See bug 1456857.
+      const animationsFront = await this.animationsFrontPromise;
       if (this.hasPausePlaySome) {
         if (doPlay) {
-          await this.animationsFront.playSome(animations);
+          await animationsFront.playSome(animations);
         } else {
-          await this.animationsFront.pauseSome(animations);
+          await animationsFront.pauseSome(animations);
         }
       } else if (doPlay) {
-        await this.animationsFront.playAll();
+        await animationsFront.playAll();
       } else {
-        await this.animationsFront.pauseAll();
+        await animationsFront.pauseAll();
       }
 
       animations = await this.updateAnimations(animations);
     } catch (e) {
       // Expected if we've already been destroyed or other node have been selected
       // in the meantime.
       console.error(e);
       return;
@@ -633,19 +650,20 @@ class AnimationInspector {
   toggleElementPicker() {
     this.inspector.toolbox.highlighterUtils.togglePicker();
   }
 
   async update() {
     const done = this.inspector.updating("animationinspector");
 
     const selection = this.inspector.selection;
+    const animationsFront = await this.animationsFrontPromise;
     const animations =
       selection.isConnected() && selection.isElementNode()
-      ? await this.animationsFront.getAnimationPlayersForNode(selection.nodeFront)
+      ? await animationsFront.getAnimationPlayersForNode(selection.nodeFront)
       : [];
     this.updateState(animations);
     this.setAnimationStateChangedListenerEnabled(true);
 
     done();
   }
 
   async updateAnimations(animations) {