Bug 1497905 - Avoid destroying the markup iframe on navigation. r=pbro

This commit is contained in:
Gabriel Luong 2018-10-14 22:26:05 -04:00
parent f56ddbca98
commit d3d023f557
5 changed files with 38 additions and 37 deletions

View File

@ -113,9 +113,10 @@ function Inspector(toolbox) {
this.panelWin = window;
this.panelWin.inspector = this;
this.telemetry = toolbox.telemetry;
this.store = Store();
this._markupBox = this.panelDoc.getElementById("markup-box");
// Map [panel id => panel instance]
// Stores all the instances of sidebar panels like rule view, computed view, ...
this._panels = new Map();
@ -1165,8 +1166,8 @@ Inspector.prototype = {
this._pendingSelection = null;
this.selection.setNodeFront(defaultNode, { reason: "navigateaway" });
this._initMarkup();
this.once("markuploaded", this.onMarkupLoaded);
this._initMarkup();
// Setup the toolbar again, since its content may depend on the current document.
this.setupToolbar();
@ -1449,6 +1450,11 @@ Inspector.prototype = {
this._highlighters = null;
}
if (this._markupFrame) {
this._markupFrame.removeEventListener("load", this._onMarkupFrameLoad, true);
this._markupFrame.removeEventListener("contextmenu", this._onContextMenu);
}
if (this._search) {
this._search.destroy();
this._search = null;
@ -1471,6 +1477,8 @@ Inspector.prototype = {
this._is3PaneModeChromeEnabled = null;
this._is3PaneModeEnabled = null;
this._markupBox = null;
this._markupFrame = null;
this._notificationBox = null;
this._target = null;
this._toolbox = null;
@ -1939,42 +1947,36 @@ Inspector.prototype = {
},
_initMarkup: function() {
const doc = this.panelDoc;
if (!this._markupFrame) {
this._markupFrame = this.panelDoc.createElement("iframe");
this._markupFrame.setAttribute("aria-label",
INSPECTOR_L10N.getStr("inspector.panelLabel.markupView"));
this._markupFrame.setAttribute("flex", "1");
// This is needed to enable tooltips inside the iframe document.
this._markupFrame.setAttribute("tooltip", "aHTMLTooltip");
this._markupFrame.addEventListener("contextmenu", this._onContextMenu);
this._markupBox = doc.getElementById("markup-box");
this._markupBox.style.visibility = "hidden";
this._markupBox.appendChild(this._markupFrame);
// create tool iframe
this._markupFrame = doc.createElement("iframe");
this._markupFrame.setAttribute("flex", "1");
// This is needed to enable tooltips inside the iframe document.
this._markupFrame.setAttribute("tooltip", "aHTMLTooltip");
this._markupFrame.addEventListener("contextmenu", this._onContextMenu);
this._markupBox.style.visibility = "hidden";
this._markupBox.appendChild(this._markupFrame);
this._markupFrame.addEventListener("load", this._onMarkupFrameLoad, true);
this._markupFrame.setAttribute("src", "markup/markup.xhtml");
this._markupFrame.setAttribute("aria-label",
INSPECTOR_L10N.getStr("inspector.panelLabel.markupView"));
this._markupFrame.addEventListener("load", this._onMarkupFrameLoad, true);
this._markupFrame.setAttribute("src", "markup/markup.xhtml");
} else {
this._onMarkupFrameLoad();
}
},
_onMarkupFrameLoad: function() {
this._markupFrame.removeEventListener("load", this._onMarkupFrameLoad, true);
this._markupFrame.contentWindow.focus();
this.markup = new MarkupView(this, this._markupFrame, this._toolbox.win);
this._markupBox.style.visibility = "visible";
this.markup = new MarkupView(this, this._markupFrame, this._toolbox.win);
this.emit("markuploaded");
},
_destroyMarkup: function() {
let destroyPromise;
if (this._markupFrame) {
this._markupFrame.removeEventListener("load", this._onMarkupFrameLoad, true);
this._markupFrame.removeEventListener("contextmenu", this._onContextMenu);
}
if (this.markup) {
destroyPromise = this.markup.destroy();
this.markup = null;
@ -1982,12 +1984,7 @@ Inspector.prototype = {
destroyPromise = promise.resolve();
}
if (this._markupFrame) {
this._markupFrame.remove();
this._markupFrame = null;
}
this._markupBox = null;
this._markupBox.style.visibility = "hidden";
return destroyPromise;
},

View File

@ -73,7 +73,7 @@ function MarkupView(inspector, frame, controllerWindow) {
this._frame = frame;
this.win = this._frame.contentWindow;
this.doc = this._frame.contentDocument;
this._elt = this.doc.querySelector("#root");
this._elt = this.doc.getElementById("root");
this.telemetry = this.inspector.telemetry;
this.maxChildren = Services.prefs.getIntPref("devtools.markup.pagesize",
@ -1961,13 +1961,14 @@ MarkupView.prototype = {
this._onCollapseAttributesPrefChange);
this._prefObserver.destroy();
this._elt = null;
for (const [, container] of this._containers) {
container.destroy();
}
this._containers = null;
this._elt.innerHTML = "";
this._elt = null;
this.controllerWindow = null;
this.doc = null;
this.highlighters = null;

View File

@ -37,7 +37,7 @@ add_task(async function() {
}
function assertMarkupViewIsEmpty() {
const markupViewBox = inspector.panelDoc.getElementById("markup-box");
is(markupViewBox.childNodes.length, 0, "The markup-view is unloaded");
const markupViewFrame = inspector._markupFrame.contentDocument.getElementById("root");
is(markupViewFrame.childNodes.length, 0, "The markup-view is unloaded");
}
});

View File

@ -86,6 +86,7 @@ function assertMarkupViewIsLoaded(inspector) {
}
function assertMarkupViewIsEmpty(inspector) {
const markupViewBox = inspector.panelDoc.getElementById("markup-box");
is(markupViewBox.childNodes.length, 0, "The markup-view is unloaded");
const markupFrame = inspector._markupFrame;
is(markupFrame.contentDocument.getElementById("root").childNodes.length, 0,
"The markup-view is unloaded");
}

View File

@ -26,9 +26,11 @@ add_task(async function() {
info("Reload the current page");
const onNewRoot = inspector.once("new-root");
const onRuleViewRefreshed = inspector.once("rule-view-refreshed");
await testActor.reload();
await onNewRoot;
await inspector.markup._waitForChildren();
await onRuleViewRefreshed;
is(numberOfRules(view), 2, "Rule view still has two rules and is not empty.");