Bug 1462229 - Part 3: Guard that not touching null object during creating graph after animation inspector destroyed. r=gl
authorDaisuke Akatsuka <dakatsuka@mozilla.com>
Mon, 28 May 2018 09:27:55 +0900
changeset 420092 6fa5b5963b06eb4984a59629b1fc1d005579e462
parent 420091 452e577be2f4e4ffc7e7415572187e1d4c5f60af
child 420093 443ff1adf8abe46d484d1b18c30bbd3ff007f640
push id64504
push userdakatsuka@mozilla.com
push dateMon, 28 May 2018 04:53:06 +0000
treeherderautoland@443ff1adf8ab [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgl
bugs1462229
milestone62.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 1462229 - Part 3: Guard that not touching null object during creating graph after animation inspector destroyed. r=gl MozReview-Commit-ID: 2UWt3aq1e4x
devtools/client/inspector/animation/animation.js
devtools/client/inspector/animation/components/graph/ComputedTimingPath.js
devtools/client/inspector/animation/components/graph/EffectTimingPath.js
devtools/client/inspector/animation/components/graph/NegativePath.js
devtools/client/inspector/animation/components/keyframes-graph/ComputedStylePath.js
--- a/devtools/client/inspector/animation/animation.js
+++ b/devtools/client/inspector/animation/animation.js
@@ -527,16 +527,21 @@ class AnimationInspector {
    *        true:  create animation with an element.
    *               If want to know computed value of the element, turn on.
    *        false: create animation without an element,
    *               If need to know only timing progress.
    * @return {Animation}
    *         https://drafts.csswg.org/web-animations/#the-animation-interface
    */
   simulateAnimation(keyframes, effectTiming, isElementNeeded) {
+    // Don't simulate animation if the animation inspector is already destroyed.
+    if (!this.win) {
+      return null;
+    }
+
     let targetEl = null;
 
     if (isElementNeeded) {
       if (!this.simulatedElement) {
         this.simulatedElement = this.win.document.createElement("div");
         this.win.document.documentElement.appendChild(this.simulatedElement);
       } else {
         // Reset styles.
@@ -637,16 +642,21 @@ class AnimationInspector {
             }
           }
         });
       }
     });
   }
 
   updateState(animations) {
+    // Animation inspector already destroyed
+    if (!this.inspector) {
+      return;
+    }
+
     this.stopAnimationsCurrentTimeTimer();
 
     this.inspector.store.dispatch(updateAnimations(animations));
 
     if (hasRunningAnimation(animations)) {
       this.startAnimationsCurrentTimeTimer();
     }
   }
--- a/devtools/client/inspector/animation/components/graph/ComputedTimingPath.js
+++ b/devtools/client/inspector/animation/components/graph/ComputedTimingPath.js
@@ -45,17 +45,23 @@ class ComputedTimingPath extends TimingP
     // is not affected by the easing in keyframes at all, computed value reflects that.
     const frames = keyframes.map(keyframe => {
       return {
         opacity: keyframe.offset,
         offset: keyframe.offset,
         easing: keyframe.easing
       };
     });
+
     const simulatedAnimation = simulateAnimation(frames, effectTiming, true);
+
+    if (!simulatedAnimation) {
+      return null;
+    }
+
     const simulatedElement = simulatedAnimation.effect.target;
     const win = simulatedElement.ownerGlobal;
     const endTime = simulatedAnimation.effect.getComputedTiming().endTime;
 
     // Set the underlying opacity to zero so that if we sample the animation's output
     // during the delay phase and it is not filling backwards, we get zero.
     simulatedElement.style.opacity = 0;
 
--- a/devtools/client/inspector/animation/components/graph/EffectTimingPath.js
+++ b/devtools/client/inspector/animation/components/graph/EffectTimingPath.js
@@ -31,16 +31,21 @@ class EffectTimingPath extends TimingPat
     } = this.props;
 
     const { state } = animation;
     const effectTiming = Object.assign({}, state, {
       iterations: state.iterationCount ? state.iterationCount : Infinity
     });
 
     const simulatedAnimation = simulateAnimation(null, effectTiming, false);
+
+    if (!simulatedAnimation) {
+      return null;
+    }
+
     const endTime = simulatedAnimation.effect.getComputedTiming().endTime;
 
     const getValueFunc = time => {
       if (time < 0) {
         return { x: time, y: 0 };
       }
 
       simulatedAnimation.currentTime = time < endTime ? time : endTime;
--- a/devtools/client/inspector/animation/components/graph/NegativePath.js
+++ b/devtools/client/inspector/animation/components/graph/NegativePath.js
@@ -47,16 +47,21 @@ class NegativePath extends PureComponent
       return {
         opacity: keyframe.offset,
         offset: keyframe.offset,
         easing: keyframe.easing
       };
     });
 
     const simulatedAnimation = simulateAnimation(frames, effectTiming, true);
+
+    if (!simulatedAnimation) {
+      return null;
+    }
+
     const simulatedElement = simulatedAnimation.effect.target;
     const win = simulatedElement.ownerGlobal;
 
     // Set the underlying opacity to zero so that if we sample the animation's output
     // during the delay phase and it is not filling backwards, we get zero.
     simulatedElement.style.opacity = 0;
 
     const getValueFunc = time => {
--- a/devtools/client/inspector/animation/components/keyframes-graph/ComputedStylePath.js
+++ b/devtools/client/inspector/animation/components/keyframes-graph/ComputedStylePath.js
@@ -78,17 +78,23 @@ class ComputedStylePath extends PureComp
         easing: keyframe.easing,
         [getJsPropertyName(propertyName)]: this.getPropertyValue(keyframe),
       };
     });
     const effect = {
       duration,
       fill: "forwards",
     };
+
     const simulatedAnimation = simulateAnimation(keyframes, effect, true);
+
+    if (!simulatedAnimation) {
+      return null;
+    }
+
     const simulatedElement = simulatedAnimation.effect.target;
     const win = simulatedElement.ownerGlobal;
     const threshold = getPreferredProgressThresholdByKeyframes(keyframes);
 
     const getSegment = time => {
       simulatedAnimation.currentTime = time;
       const computedStyle =
         win.getComputedStyle(simulatedElement).getPropertyValue(propertyName);
@@ -176,17 +182,23 @@ class ComputedStylePath extends PureComp
   renderGraph() {
     const { keyframes } = this.props;
 
     const segments = [];
 
     for (let i = 0; i < keyframes.length - 1; i++) {
       const startKeyframe = keyframes[i];
       const endKeyframe = keyframes[i + 1];
-      segments.push(...this.getPathSegments(startKeyframe, endKeyframe));
+      const keyframesSegments = this.getPathSegments(startKeyframe, endKeyframe);
+
+      if (!keyframesSegments) {
+        return null;
+      }
+
+      segments.push(...keyframesSegments);
     }
 
     return [
       this.renderPathSegments(segments),
       this.renderEasingHint(segments)
     ];
   }