Bug 1354086 - fix leaks caused by transitionend listeners that hang around, r?mikedeboer
MozReview-Commit-ID: DvvoAURmxH2
--- a/browser/components/customizableui/PanelMultiView.jsm
+++ b/browser/components/customizableui/PanelMultiView.jsm
@@ -592,41 +592,45 @@ this.PanelMultiView = class {
" var(--panelui-subview-transition-duration)";
nodeToAnimate.style.willChange = "transform";
nodeToAnimate.style.borderInlineStart = "1px solid var(--panel-separator-color)";
// Wait until after the first paint to ensure setting 'current=true'
// has taken full effect; once both views are visible, we want to
// correctly measure rects using `dwu.getBoundsWithoutFlushing`.
window.addEventListener("MozAfterPaint", () => {
+ if (this._panel.state != "open") {
+ onTransitionEnd();
+ return;
+ }
// Now set the viewContainer dimensions to that of the new view, which
// kicks of the height animation.
this._viewContainer.style.height = Math.max(viewRect.height, this._mainViewHeight) + "px";
this._viewContainer.style.width = viewRect.width + "px";
this._panel.removeAttribute("width");
this._panel.removeAttribute("height");
// The 'magic' part: build up the amount of pixels to move right or left.
let moveToLeft = (this._dir == "rtl" && !reverse) || (this._dir == "ltr" && reverse);
let movementX = reverse ? viewRect.width : previousRect.width;
let moveX = (moveToLeft ? "" : "-") + movementX;
nodeToAnimate.style.transform = "translateX(" + moveX + "px)";
// We're setting the width property to prevent flickering during the
// sliding animation with smaller views.
nodeToAnimate.style.width = viewRect.width + "px";
- let listener;
- this._viewContainer.addEventListener("transitionend", listener = ev => {
+ this._viewContainer.addEventListener("transitionend", this._transitionEndListener = ev => {
// It's quite common that `height` on the view container doesn't need
// to transition, so we make sure to do all the work on the transform
// transition-end, because that is guaranteed to happen.
if (ev.target != nodeToAnimate || ev.propertyName != "transform")
return;
- this._viewContainer.removeEventListener("transitionend", listener);
+ this._viewContainer.removeEventListener("transitionend", this._transitionEndListener);
+ this._transitionEndListener = null;
onTransitionEnd();
this._transitioning = false;
this._resetKeyNavigation(previousViewNode);
// Myeah, panel layout auto-resizing is a funky thing. We'll wait
// another few milliseconds to remove the width and height 'fixtures',
// to be sure we don't flicker annoyingly.
// NB: HACK! Bug 1363756 is there to fix this.
@@ -927,16 +931,20 @@ this.PanelMultiView = class {
case "popuphidden":
// WebExtensions consumers can hide the popup from viewshowing, or
// mid-transition, which disrupts our state:
this._viewShowing = null;
this._transitioning = false;
this.node.removeAttribute("panelopen");
this.showMainView();
if (this.panelViews) {
+ if (this._transitionEndListener) {
+ this._viewContainer.removeEventListener("transitionend", this._transitionEndListener);
+ this._transitionEndListener = null;
+ }
for (let panelView of this._viewStack.children) {
if (panelView.nodeName != "children") {
panelView.style.removeProperty("min-width");
panelView.style.removeProperty("max-width");
}
}
this.window.removeEventListener("keydown", this);
this._panel.removeEventListener("mousemove", this);