Bug 1462229 - Part 3: Guard that not touching null object during creating graph after animation inspector destroyed. r?gl
MozReview-Commit-ID: 2UWt3aq1e4x
--- 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)
];
}