Bug 1364127 - Set the initial tab label to the URL for new tabs and to the saved title for restored tabs, and make sure that label doesn't subsequently get clobbered with a placeholder r=past

MozReview-Commit-ID: 9t07uAVE13H

--HG--
extra : rebase_source : c3e317bf0d149593b5a5119a878be96ef36b81db
This commit is contained in:
Dão Gottwald 2017-05-12 13:35:44 +02:00
parent d8e30095b3
commit 569c55f5cb
4 changed files with 125 additions and 9 deletions

View File

@ -1409,6 +1409,20 @@
<body/>
</method>
<method name="setInitialTabTitle">
<parameter name="aTab"/>
<parameter name="aTitle"/>
<body><![CDATA[
if (aTitle) {
aTab.setAttribute("label", aTitle);
// Don't replace the set label with the empty tab label or the URL
// while the tab is loading.
aTab._suppressTransientPlaceholderLabel = true;
}
]]></body>
</method>
<method name="setTabTitle">
<parameter name="aTab"/>
<body>
@ -1416,6 +1430,13 @@
var browser = this.getBrowserForTab(aTab);
var title = browser.contentTitle;
if (aTab._suppressTransientPlaceholderLabel) {
if (!title) {
return false;
}
delete aTab._suppressTransientPlaceholderLabel;
}
if (!title) {
if (browser.currentURI.spec) {
try {
@ -1465,7 +1486,6 @@
<parameter name="aPostData"/>
<parameter name="aLoadInBackground"/>
<parameter name="aAllowThirdPartyFixup"/>
<parameter name="aIsPrerendered"/>
<body>
<![CDATA[
var aTriggeringPrincipal;
@ -1481,6 +1501,7 @@
var aSameProcessAsFrameLoader;
var aOriginPrincipal;
var aOpener;
var aIsPrerendered;
var aCreateLazyBrowser;
var aNextTabParentId;
if (arguments.length == 2 &&
@ -2219,7 +2240,6 @@
<parameter name="aPostData"/>
<parameter name="aOwner"/>
<parameter name="aAllowThirdPartyFixup"/>
<parameter name="aIsPrerendered"/>
<body>
<![CDATA[
"use strict";
@ -2240,9 +2260,11 @@
var aOriginPrincipal;
var aDisallowInheritPrincipal;
var aOpener;
var aIsPrerendered;
var aCreateLazyBrowser;
var aSkipBackgroundNotify;
var aNextTabParentId;
var aNoInitialLabel;
if (arguments.length == 2 &&
typeof arguments[1] == "object" &&
!(arguments[1] instanceof Ci.nsIURI)) {
@ -2271,6 +2293,7 @@
aCreateLazyBrowser = params.createLazyBrowser;
aSkipBackgroundNotify = params.skipBackgroundNotify;
aNextTabParentId = params.nextTabParentId;
aNoInitialLabel = params.noInitialLabel;
}
// if we're adding tabs, we're past interrupt mode, ditch the owner
@ -2289,11 +2312,13 @@
var uriIsAboutBlank = aURI == "about:blank";
if (isBlankPageURL(aURI)) {
t.setAttribute("label", this.mStringBundle.getString("tabs.emptyTabTitle"));
} else if (aURI.toLowerCase().startsWith("javascript:")) {
// This can go away when bug 672618 or bug 55696 are fixed.
t.setAttribute("label", aURI);
if (!aNoInitialLabel) {
if (isBlankPageURL(aURI)) {
t.setAttribute("label", this.mStringBundle.getString("tabs.emptyTabTitle"));
} else {
// Set URL as label so that the tab isn't empty initially.
this.setInitialTabTitle(t, aURI);
}
}
if (aIsPrerendered) {

View File

@ -2644,9 +2644,9 @@ var SessionStoreInternal = {
// If the page has a title, set it.
if (activePageData) {
if (activePageData.title) {
tab.label = activePageData.title;
win.gBrowser.setInitialTabTitle(tab, activePageData.title);
} else if (activePageData.url != "about:blank") {
tab.label = activePageData.url;
win.gBrowser.setInitialTabTitle(tab, activePageData.url);
}
} else if (tab.hasAttribute("customizemode")) {
win.gCustomizeMode.setTab(tab);
@ -3291,9 +3291,13 @@ var SessionStoreInternal = {
url = tabData.entries[activeIndex].url;
}
// Setting noInitialLabel is a perf optimization. Rendering tab labels
// would make resizing the tabs more expensive as we're adding them.
// Each tab will get its initial label set in restoreTab.
let tab = tabbrowser.addTab(url,
{ createLazyBrowser,
skipAnimation: true,
noInitialLabel: true,
userContextId,
skipBackgroundNotify: true });

View File

@ -112,11 +112,13 @@ skip-if = e10s # Bug 1271024
[browser_sessionHistory.js]
[browser_sessionStorage.js]
[browser_sessionStorage_size.js]
[browser_tab_label_during_restore.js]
[browser_swapDocShells.js]
[browser_switch_remoteness.js]
run-if = e10s
[browser_upgrade_backup.js]
[browser_windowRestore_perwindowpb.js]
[browser_248970_b_perwindowpb.js]
# Disabled because of leaks.
# Re-enabling and rewriting this test is tracked in bug 936919.

View File

@ -0,0 +1,85 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Test that we don't do unnecessary tab label changes while restoring a tab.
*/
add_task(async function() {
await SpecialPowers.pushPrefEnv({
"set": [
["browser.sessionstore.restore_on_demand", true],
["browser.sessionstore.restore_tabs_lazily", true],
]
});
const BACKUP_STATE = SessionStore.getBrowserState();
const TEST_URL = "http://example.com/";
function observeLabelChanges(tab) {
info("observing tab label changes. initial label: " + tab.label);
let labelChangeCount = 0;
function TabAttrModifiedListener(event) {
if (event.detail.changed.some(attr => { return attr == "label" })) {
info("tab label change: " + tab.label);
labelChangeCount++;
}
}
tab.addEventListener("TabAttrModified", TabAttrModifiedListener);
return (expectedCount) => {
tab.removeEventListener("TabAttrModified", TabAttrModifiedListener);
is(labelChangeCount, expectedCount, "observed tab label changes");
}
}
info("setting test browser state");
let browserLoadedPromise = BrowserTestUtils.firstBrowserLoaded(window, false);
await promiseBrowserState({
windows: [{
tabs: [
{ entries: [{ url: TEST_URL }] },
{ entries: [{ url: TEST_URL }] },
]
}]
});
let [firstTab, secondTab] = gBrowser.tabs;
is(gBrowser.selectedTab, firstTab, "first tab is selected");
await browserLoadedPromise;
const CONTENT_TITLE = firstTab.linkedBrowser.contentTitle;
is(firstTab.linkedBrowser.currentURI.spec, TEST_URL, "correct URL loaded in first tab");
is(typeof CONTENT_TITLE, "string", "content title is a string");
isnot(CONTENT_TITLE.length, 0, "content title isn't empty");
isnot(CONTENT_TITLE, TEST_URL, "content title is different from the URL");
is(firstTab.label, CONTENT_TITLE, "first tab displays content title");
ok(secondTab.hasAttribute("pending"), "second tab is pending");
is(secondTab.label, TEST_URL, "second tab displays URL as its title");
info("selecting the second tab");
let checkLabelChangeCount = observeLabelChanges(secondTab);
browserLoadedPromise = BrowserTestUtils.browserLoaded(secondTab.linkedBrowser, false, TEST_URL);
gBrowser.selectedTab = secondTab;
await browserLoadedPromise;
ok(!secondTab.hasAttribute("pending"), "second tab isn't pending anymore");
is(gBrowser.selectedTab.label, CONTENT_TITLE, "second tab displays content title");
checkLabelChangeCount(1);
info("restoring the modified browser state");
await TabStateFlusher.flushWindow(window);
await promiseBrowserState(SessionStore.getBrowserState());
[firstTab, secondTab] = gBrowser.tabs;
is(secondTab, gBrowser.selectedTab, "second tab is selected after restoring");
ok(firstTab.hasAttribute("pending"), "first tab is pending after restoring");
is(firstTab.label, CONTENT_TITLE, "first tab displays content title in pending state");
info("selecting the first tab");
checkLabelChangeCount = observeLabelChanges(firstTab);
let tabContentRestored = TestUtils.topicObserved("sessionstore-debug-tab-restored");
gBrowser.selectedTab = firstTab;
await tabContentRestored;
ok(!firstTab.hasAttribute("pending"), "first tab isn't pending anymore");
checkLabelChangeCount(0);
is(firstTab.label, CONTENT_TITLE, "first tab displays content title after restoring content");
await promiseBrowserState(BACKUP_STATE);
});