Bug 1691576 - [devtools] Update DevTools window title on DOCUMENT_EVENT resource. r=ochameau.

Differential Revision: https://phabricator.services.mozilla.com/D104540
This commit is contained in:
Nicolas Chevobbe 2021-05-19 16:58:05 +00:00
Родитель c17e990ce7
Коммит 3f72673a8e
3 изменённых файлов: 105 добавлений и 125 удалений

Просмотреть файл

@ -159,7 +159,6 @@ run-if = e10s
[browser_toolbox_window_reload_target_force.js]
[browser_toolbox_window_shortcuts.js]
[browser_toolbox_window_title_changes.js]
skip-if = fission
[browser_toolbox_window_title_frame_select.js]
fail-if = fission
[browser_toolbox_zoom.js]

Просмотреть файл

@ -5,121 +5,93 @@ requestLongerTimeout(5);
var { Toolbox } = require("devtools/client/framework/toolbox");
function test() {
const URL_1 = "data:text/plain;charset=UTF-8,abcde";
const URL_2 = "data:text/plain;charset=UTF-8,12345";
const URL_3 = URL_ROOT + "browser_toolbox_window_title_changes_page.html";
const NAME_1 = "";
const NAME_2 = "Toolbox test for title update";
const NAME_3 = NAME_2;
const NAME_4 = "Toolbox test for another title update";
const TOOL_ID_1 = "webconsole";
const TOOL_ID_2 = "jsdebugger";
const URL_1 = "data:text/plain;charset=UTF-8,abcde";
const URL_2 = URL_ROOT_ORG + "browser_toolbox_window_title_changes_page.html";
const URL_3 = URL_ROOT_COM + "browser_toolbox_window_title_changes_page.html";
const URL_4 = `http://example.com/document-builder.sjs?html=<head><title>${NAME_4}</title></head><h1>Hello`;
const NAME_1 = "";
const NAME_2 = "";
const NAME_3 = "Toolbox test for title update";
add_task(async function test() {
await addTab(URL_1);
let toolbox;
let panel;
addTab(URL_1).then(async function() {
const tab = gBrowser.selectedTab;
gDevTools
.showToolboxForTab(tab, { hostType: Toolbox.HostType.BOTTOM })
.then(function(aToolbox) {
toolbox = aToolbox;
})
.then(() => toolbox.selectTool(TOOL_ID_1))
// undock toolbox and check title
.then(() => {
// We have to first switch the host in order to spawn the new top level window
// on which we are going to listen from title change event
return toolbox
.switchHost(Toolbox.HostType.WINDOW)
.then(() => waitForTitleChange(toolbox));
})
.then(checkTitle.bind(null, NAME_1, URL_1, "toolbox undocked"))
// switch to different tool and check title
.then(async () => {
const onTitleChanged = waitForTitleChange(toolbox);
panel = await toolbox.selectTool(TOOL_ID_2);
return onTitleChanged;
})
.then(checkTitle.bind(null, NAME_1, URL_1, "tool changed"))
// navigate to different local url and check title
.then(async function() {
const onTitleChanged = waitForTitleChange(toolbox);
const waitForReloaded = panel.once("reloaded");
await navigateTo(URL_2);
await waitForReloaded;
return onTitleChanged;
})
.then(checkTitle.bind(null, NAME_2, URL_2, "url changed"))
// navigate to a real url and check title
.then(async () => {
const onTitleChanged = waitForTitleChange(toolbox);
const waitForReloaded = panel.once("reloaded");
await navigateTo(URL_3);
await waitForReloaded;
return onTitleChanged;
})
.then(checkTitle.bind(null, NAME_3, URL_3, "url changed"))
// destroy toolbox, create new one hosted in a window (with a
// different tool id), and check title
.then(function() {
// Give the tools a chance to handle the navigation event before
// destroying the toolbox.
executeSoon(function() {
toolbox
.destroy()
.then(async function() {
// After destroying the toolbox, open a new one.
return gDevTools.showToolboxForTab(tab, {
hostType: Toolbox.HostType.WINDOW,
});
})
.then(function(aToolbox) {
toolbox = aToolbox;
})
.then(() => {
const onTitleChanged = waitForTitleChange(toolbox);
toolbox.selectTool(TOOL_ID_1);
return onTitleChanged;
})
.then(
checkTitle.bind(
null,
NAME_3,
URL_3,
"toolbox destroyed and recreated"
)
)
// clean up
.then(() => toolbox.destroy())
.then(function() {
toolbox = null;
gBrowser.removeCurrentTab();
Services.prefs.clearUserPref("devtools.toolbox.host");
Services.prefs.clearUserPref("devtools.toolbox.selectedTool");
Services.prefs.clearUserPref("devtools.toolbox.sideEnabled");
finish();
});
});
});
const tab = gBrowser.selectedTab;
let toolbox = await gDevTools.showToolboxForTab(tab, {
hostType: Toolbox.HostType.BOTTOM,
});
await toolbox.selectTool("webconsole");
info("Undock toolbox and check title");
// We have to first switch the host in order to spawn the new top level window
// on which we are going to listen from title change event
await toolbox.switchHost(Toolbox.HostType.WINDOW);
await checkTitle(NAME_1, URL_1, "toolbox undocked");
info("switch to different tool and check title again");
await toolbox.selectTool("jsdebugger");
await checkTitle(NAME_1, URL_1, "tool changed");
info("navigate to different local url and check title");
await navigateTo(URL_2);
info("wait for title change");
await checkTitle(NAME_2, URL_2, "url changed");
info("navigate to a real url and check title");
await navigateTo(URL_3);
info("wait for title change");
await checkTitle(NAME_3, URL_3, "url changed");
info("navigate to another page on the same domain");
await navigateTo(URL_4);
await checkTitle(NAME_4, URL_4, "title changed");
info(
"destroy toolbox, create new one hosted in a window (with a different tool id), and check title"
);
// Give the tools a chance to handle the navigation event before
// destroying the toolbox.
await new Promise(resolve => executeSoon(resolve));
await toolbox.destroy();
// After destroying the toolbox, open a new one.
toolbox = await gDevTools.showToolboxForTab(tab, {
hostType: Toolbox.HostType.WINDOW,
});
toolbox.selectTool("webconsole");
await checkTitle(NAME_4, URL_4, "toolbox destroyed and recreated");
info("clean up");
await toolbox.destroy();
gBrowser.removeCurrentTab();
Services.prefs.clearUserPref("devtools.toolbox.host");
Services.prefs.clearUserPref("devtools.toolbox.selectedTool");
Services.prefs.clearUserPref("devtools.toolbox.sideEnabled");
});
function getExpectedTitle(name, url) {
if (name) {
return `Developer Tools — ${name}${url}`;
}
return `Developer Tools — ${url}`;
}
function checkTitle(name, url, context) {
const win = Services.wm.getMostRecentWindow("devtools:toolbox");
let expectedTitle;
if (name) {
expectedTitle = `Developer Tools — ${name}${url}`;
} else {
expectedTitle = `Developer Tools — ${url}`;
}
is(win.document.title, expectedTitle, context);
async function checkTitle(name, url, context) {
info("Check title - " + context);
await waitFor(
() => getToolboxWindowTitle() === getExpectedTitle(name, url),
`Didn't get the expected title ("${getExpectedTitle(name, url)}"`,
200,
50
);
const expectedTitle = getExpectedTitle(name, url);
is(getToolboxWindowTitle(), expectedTitle, context);
}
function getToolboxWindowTitle() {
return Services.wm.getMostRecentWindow("devtools:toolbox").document.title;
}

Просмотреть файл

@ -330,7 +330,6 @@ function Toolbox(
this._onResumedState = this._onResumedState.bind(this);
this._onTargetAvailable = this._onTargetAvailable.bind(this);
this._onTargetDestroyed = this._onTargetDestroyed.bind(this);
this._onNavigate = this._onNavigate.bind(this);
this._onResourceAvailable = this._onResourceAvailable.bind(this);
this._onResourceUpdated = this._onResourceUpdated.bind(this);
@ -696,7 +695,6 @@ Toolbox.prototype = {
// Attach to a new top-level target.
// For now, register these event listeners only on the top level target
targetFront.on("will-navigate", this._onWillNavigate);
targetFront.on("navigate", this._onNavigate);
targetFront.on("frame-update", this._updateFrames);
targetFront.on("inspect-object", this._onInspectObject);
}
@ -732,7 +730,6 @@ Toolbox.prototype = {
if (targetFront.isTopLevel) {
this.target.off("inspect-object", this._onInspectObject);
this.target.off("will-navigate", this._onWillNavigate);
this.target.off("navigate", this._onNavigate);
this.target.off("frame-update", this._updateFrames);
}
@ -801,10 +798,10 @@ Toolbox.prototype = {
this._onTargetDestroyed
);
// Watch for console API messages, errors and network events in order to populate
// the error count icon in the toolbox.
const onResourcesWatched = this.resourceCommand.watchResources(
[
// Watch for console API messages, errors and network events in order to populate
// the error count icon in the toolbox.
this.resourceCommand.TYPES.CONSOLE_MESSAGE,
this.resourceCommand.TYPES.ERROR_MESSAGE,
// Independently of watching network event resources for the error count icon,
@ -813,6 +810,7 @@ Toolbox.prototype = {
// for network events across the lifetime of the various panels, so stopping
// the resource command from clearing out its cache of network event resources.
this.resourceCommand.TYPES.NETWORK_EVENT,
this.resourceCommand.TYPES.DOCUMENT_EVENT,
],
{
onAvailable: this._onResourceAvailable,
@ -3762,6 +3760,7 @@ Toolbox.prototype = {
this.resourceCommand.TYPES.CONSOLE_MESSAGE,
this.resourceCommand.TYPES.ERROR_MESSAGE,
this.resourceCommand.TYPES.NETWORK_EVENT,
this.resourceCommand.TYPES.DOCUMENT_EVENT,
],
{ onAvailable: this._onResourceAvailable }
);
@ -4279,14 +4278,6 @@ Toolbox.prototype = {
return id;
},
/**
* Fired when the user navigates to another page.
*/
_onNavigate: function() {
this._refreshHostTitle();
this._setDebugTargetData();
},
/**
* Sets basic information on the DebugTargetInfo component
*/
@ -4325,6 +4316,24 @@ Toolbox.prototype = {
errors = 0;
}
}
if (
resource.resourceType === this.resourceCommand.TYPES.DOCUMENT_EVENT &&
resource?.targetFront.isTopLevel &&
!resource.isFrameSwitching &&
// `url` is set on the targetFront when we receive dom-loading, and `title` when
// `dom-interactive` is received. Here we're only updating the window title in
// the "newer" event.
resource.name === "dom-interactive"
) {
// the targetFront title and url are update on dom-interactive, so delay refreshing
// the host title a bit in order for the event listener in targetCommand to be
// executed.
setTimeout(() => {
this._refreshHostTitle();
}, 0);
this._setDebugTargetData();
}
}
this.setErrorCount(errors);