Bug 1367407 - Early return from timeline render if destroy was called; r=daisuke draft
authorPatrick Brosset <pbrosset@mozilla.com>
Tue, 13 Jun 2017 13:56:22 +0200
changeset 593849 da1b35b969b9e58b339b4962eb2d5f661b0ad81a
parent 593303 a8f8e440d627d686fa8898483aa9c5da928a8fa4
child 633241 4125054be8512677b8dfada523cd43f39588cb19
push id63839
push userbmo:pbrosset@mozilla.com
push dateWed, 14 Jun 2017 07:26:38 +0000
reviewersdaisuke
bugs1367407
milestone56.0a1
Bug 1367407 - Early return from timeline render if destroy was called; r=daisuke MozReview-Commit-ID: L1I1qSSIOBf
devtools/client/animationinspector/components/animation-timeline.js
--- a/devtools/client/animationinspector/components/animation-timeline.js
+++ b/devtools/client/animationinspector/components/animation-timeline.js
@@ -257,16 +257,18 @@ AnimationsTimeline.prototype = {
     this.inspector = null;
     this.serverTraits = null;
     this.animationDetailEl = null;
     this.animationAnimationNameEl = null;
     this.animatedPropertiesEl = null;
     this.animationDetailCloseButton = null;
     this.animationRootEl = null;
     this.selectedAnimation = null;
+
+    this.isDestroyed = true;
   },
 
   /**
    * Destroy sub-components that have been created and stored on this instance.
    * @param {String} name An array of components will be expected in this[name]
    * @param {Array} handlers An option list of event handlers information that
    * should be used to remove these handlers.
    */
@@ -481,16 +483,21 @@ AnimationsTimeline.prototype = {
         parent: animationEl,
         attributes: {
           "class": "time-block track-container"
         }
       });
 
       // Draw the animation time block.
       const tracks = yield this.getTracks(animation);
+      // If we're destroyed by now, just give up.
+      if (this.isDestroyed) {
+        return;
+      }
+
       let timeBlock = new AnimationTimeBlock();
       timeBlock.init(timeBlockEl);
       timeBlock.render(animation, tracks);
       this.timeBlocks.push(timeBlock);
       this.tracksMap.set(animation, tracks);
 
       timeBlock.on("selected", this.onAnimationSelected);
     }
@@ -669,29 +676,47 @@ AnimationsTimeline.prototype = {
      * A new AnimationPlayerActor function, getProperties, is introduced,
      * that returns the animated css properties of the animation and their
      * keyframes values.
      * If the animation actor has the getProperties function, we use it, and if
      * not, we fall back to getFrames, which then returns values we used to
      * handle.
      */
     if (this.serverTraits.hasGetProperties) {
-      let properties = yield animation.getProperties();
+      let properties = [];
+      try {
+        properties = yield animation.getProperties();
+      } catch (e) {
+        // Expected if we've already been destroyed in the meantime.
+        if (!this.isDestroyed) {
+          throw e;
+        }
+      }
+
       for (let {name, values} of properties) {
         if (!tracks[name]) {
           tracks[name] = [];
         }
 
         for (let {value, offset, easing, distance} of values) {
           distance = distance ? distance : 0;
           tracks[name].push({value, offset, easing, distance});
         }
       }
     } else {
-      let frames = yield animation.getFrames();
+      let frames = [];
+      try {
+        frames = yield animation.getFrames();
+      } catch (e) {
+        // Expected if we've already been destroyed in the meantime.
+        if (!this.isDestroyed) {
+          throw e;
+        }
+      }
+
       for (let frame of frames) {
         for (let name in frame) {
           if (this.NON_PROPERTIES.indexOf(name) != -1) {
             continue;
           }
 
           // We have to change to CSS property name
           // since GetKeyframes returns JS property name.