forked from mirrors/gecko-dev
Bug 1852622 - Track a lastSetActive property on each tab and use that when sorting open tabs for recency in firefox view. r=jsudiaman,Gijs,fxview-reviewers,tabbrowser-reviewers,mak,sclements
Differential Revision: https://phabricator.services.mozilla.com/D189444
This commit is contained in:
parent
e3a5f85385
commit
6e6ac6197e
7 changed files with 403 additions and 2 deletions
|
|
@ -259,6 +259,21 @@
|
||||||
return this._lastAccessed == Infinity ? Date.now() : this._lastAccessed;
|
return this._lastAccessed == Infinity ? Date.now() : this._lastAccessed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get lastSeenActive() {
|
||||||
|
const isForegroundWindow =
|
||||||
|
this.ownerGlobal ==
|
||||||
|
BrowserWindowTracker.getTopWindow({ allowPopups: true });
|
||||||
|
// the timestamp for the selected tab in the active window is always now
|
||||||
|
if (isForegroundWindow && this.selected) {
|
||||||
|
return Date.now();
|
||||||
|
}
|
||||||
|
if (this._lastSeenActive) {
|
||||||
|
return this._lastSeenActive;
|
||||||
|
}
|
||||||
|
// Use the application start time as the fallback value
|
||||||
|
return Services.startup.getStartupInfo().start.getTime();
|
||||||
|
}
|
||||||
|
|
||||||
get _overPlayingIcon() {
|
get _overPlayingIcon() {
|
||||||
return this.overlayIcon?.matches(":hover");
|
return this.overlayIcon?.matches(":hover");
|
||||||
}
|
}
|
||||||
|
|
@ -291,6 +306,10 @@
|
||||||
this._lastAccessed = this.selected ? Infinity : aDate || Date.now();
|
this._lastAccessed = this.selected ? Infinity : aDate || Date.now();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateLastSeenActive() {
|
||||||
|
this._lastSeenActive = Date.now();
|
||||||
|
}
|
||||||
|
|
||||||
updateLastUnloadedByTabUnloader() {
|
updateLastUnloadedByTabUnloader() {
|
||||||
this._lastUnloaded = Date.now();
|
this._lastUnloaded = Date.now();
|
||||||
Services.telemetry.scalarAdd("browser.engagement.tab_unload_count", 1);
|
Services.telemetry.scalarAdd("browser.engagement.tab_unload_count", 1);
|
||||||
|
|
|
||||||
|
|
@ -111,6 +111,8 @@
|
||||||
Services.els.addSystemEventListener(document, "keypress", this, false);
|
Services.els.addSystemEventListener(document, "keypress", this, false);
|
||||||
document.addEventListener("visibilitychange", this);
|
document.addEventListener("visibilitychange", this);
|
||||||
window.addEventListener("framefocusrequested", this);
|
window.addEventListener("framefocusrequested", this);
|
||||||
|
window.addEventListener("activate", this);
|
||||||
|
window.addEventListener("deactivate", this);
|
||||||
|
|
||||||
this.tabContainer.init();
|
this.tabContainer.init();
|
||||||
this._setupInitialBrowserAndTab();
|
this._setupInitialBrowserAndTab();
|
||||||
|
|
@ -1201,6 +1203,11 @@
|
||||||
newTab.recordTimeFromUnloadToReload();
|
newTab.recordTimeFromUnloadToReload();
|
||||||
newTab.updateLastAccessed();
|
newTab.updateLastAccessed();
|
||||||
oldTab.updateLastAccessed();
|
oldTab.updateLastAccessed();
|
||||||
|
// if this is the foreground window, update the last-seen timestamps.
|
||||||
|
if (this.ownerGlobal == BrowserWindowTracker.getTopWindow()) {
|
||||||
|
newTab.updateLastSeenActive();
|
||||||
|
oldTab.updateLastSeenActive();
|
||||||
|
}
|
||||||
|
|
||||||
let oldFindBar = oldTab._findBar;
|
let oldFindBar = oldTab._findBar;
|
||||||
if (
|
if (
|
||||||
|
|
@ -5762,6 +5769,11 @@
|
||||||
this.selectedBrowser.docShellIsActive = !inactive;
|
this.selectedBrowser.docShellIsActive = !inactive;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "activate":
|
||||||
|
// Intentional fallthrough
|
||||||
|
case "deactivate":
|
||||||
|
this.selectedTab.updateLastSeenActive();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -5875,6 +5887,8 @@
|
||||||
}
|
}
|
||||||
document.removeEventListener("visibilitychange", this);
|
document.removeEventListener("visibilitychange", this);
|
||||||
window.removeEventListener("framefocusrequested", this);
|
window.removeEventListener("framefocusrequested", this);
|
||||||
|
window.removeEventListener("activate", this);
|
||||||
|
window.removeEventListener("deactivate", this);
|
||||||
|
|
||||||
if (gMultiProcessBrowser) {
|
if (gMultiProcessBrowser) {
|
||||||
if (this._switcher) {
|
if (this._switcher) {
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ ChromeUtils.defineLazyGetter(lazy, "fxAccounts", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const TOPIC_DEVICELIST_UPDATED = "fxaccounts:devicelist_updated";
|
const TOPIC_DEVICELIST_UPDATED = "fxaccounts:devicelist_updated";
|
||||||
|
const TOPIC_CURRENT_BROWSER_CHANGED = "net:current-browser-id";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A collection of open tabs grouped by window.
|
* A collection of open tabs grouped by window.
|
||||||
|
|
@ -65,6 +66,9 @@ class OpenTabsInView extends ViewPage {
|
||||||
tabContainer.addEventListener("TabOpen", this);
|
tabContainer.addEventListener("TabOpen", this);
|
||||||
tabContainer.addEventListener("TabPinned", this);
|
tabContainer.addEventListener("TabPinned", this);
|
||||||
tabContainer.addEventListener("TabUnpinned", this);
|
tabContainer.addEventListener("TabUnpinned", this);
|
||||||
|
// BrowserWindowWatcher doesnt always notify "net:current-browser-id" when
|
||||||
|
// restoring a window, so we need to listen for "activate" events here as well.
|
||||||
|
win.addEventListener("activate", this);
|
||||||
this._updateOpenTabsList();
|
this._updateOpenTabsList();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -77,6 +81,7 @@ class OpenTabsInView extends ViewPage {
|
||||||
tabContainer.removeEventListener("TabOpen", this);
|
tabContainer.removeEventListener("TabOpen", this);
|
||||||
tabContainer.removeEventListener("TabPinned", this);
|
tabContainer.removeEventListener("TabPinned", this);
|
||||||
tabContainer.removeEventListener("TabUnpinned", this);
|
tabContainer.removeEventListener("TabUnpinned", this);
|
||||||
|
win.removeEventListener("activate", this);
|
||||||
this._updateOpenTabsList();
|
this._updateOpenTabsList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -98,6 +103,10 @@ class OpenTabsInView extends ViewPage {
|
||||||
if (!this.observerAdded) {
|
if (!this.observerAdded) {
|
||||||
Services.obs.addObserver(this.boundObserve, lazy.UIState.ON_UPDATE);
|
Services.obs.addObserver(this.boundObserve, lazy.UIState.ON_UPDATE);
|
||||||
Services.obs.addObserver(this.boundObserve, TOPIC_DEVICELIST_UPDATED);
|
Services.obs.addObserver(this.boundObserve, TOPIC_DEVICELIST_UPDATED);
|
||||||
|
Services.obs.addObserver(
|
||||||
|
this.boundObserve,
|
||||||
|
TOPIC_CURRENT_BROWSER_CHANGED
|
||||||
|
);
|
||||||
this.observerAdded = true;
|
this.observerAdded = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -106,6 +115,10 @@ class OpenTabsInView extends ViewPage {
|
||||||
if (this.observerAdded) {
|
if (this.observerAdded) {
|
||||||
Services.obs.removeObserver(this.boundObserve, lazy.UIState.ON_UPDATE);
|
Services.obs.removeObserver(this.boundObserve, lazy.UIState.ON_UPDATE);
|
||||||
Services.obs.removeObserver(this.boundObserve, TOPIC_DEVICELIST_UPDATED);
|
Services.obs.removeObserver(this.boundObserve, TOPIC_DEVICELIST_UPDATED);
|
||||||
|
Services.obs.removeObserver(
|
||||||
|
this.boundObserve,
|
||||||
|
TOPIC_CURRENT_BROWSER_CHANGED
|
||||||
|
);
|
||||||
this.observerAdded = false;
|
this.observerAdded = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -123,6 +136,10 @@ class OpenTabsInView extends ViewPage {
|
||||||
if (deviceListUpdated) {
|
if (deviceListUpdated) {
|
||||||
this.devices = this.currentWindow.gSync.getSendTabTargets();
|
this.devices = this.currentWindow.gSync.getSendTabTargets();
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case TOPIC_CURRENT_BROWSER_CHANGED:
|
||||||
|
this.requestUpdate();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -220,7 +237,17 @@ class OpenTabsInView extends ViewPage {
|
||||||
getRecentBrowsingTemplate() {
|
getRecentBrowsingTemplate() {
|
||||||
const tabs = Array.from(this.windows.values())
|
const tabs = Array.from(this.windows.values())
|
||||||
.flat()
|
.flat()
|
||||||
.sort((a, b) => b.lastAccessed - a.lastAccessed);
|
.sort((a, b) => {
|
||||||
|
let dt = b.lastSeenActive - a.lastSeenActive;
|
||||||
|
if (dt) {
|
||||||
|
return dt;
|
||||||
|
}
|
||||||
|
// try to break a deadlock by sorting the selected tab higher
|
||||||
|
if (!(a.selected || b.selected)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return a.selected ? -1 : 1;
|
||||||
|
});
|
||||||
return html`<view-opentabs-card
|
return html`<view-opentabs-card
|
||||||
.tabs=${tabs}
|
.tabs=${tabs}
|
||||||
.recentBrowsing=${true}
|
.recentBrowsing=${true}
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,11 @@ async function openFirefoxViewTab(win) {
|
||||||
const alreadyLoaded =
|
const alreadyLoaded =
|
||||||
fxViewTab?.linkedBrowser?.currentURI.spec.split("#")[0] ==
|
fxViewTab?.linkedBrowser?.currentURI.spec.split("#")[0] ==
|
||||||
getFirefoxViewURL();
|
getFirefoxViewURL();
|
||||||
const enteredPromise = TestUtils.topicObserved("firefoxview-entered");
|
const enteredPromise =
|
||||||
|
alreadyLoaded &&
|
||||||
|
fxViewTab.linkedBrowser.contentDocument.visibilityState == "visible"
|
||||||
|
? Promise.resolve()
|
||||||
|
: TestUtils.topicObserved("firefoxview-entered");
|
||||||
await BrowserTestUtils.synthesizeMouseAtCenter(
|
await BrowserTestUtils.synthesizeMouseAtCenter(
|
||||||
"#firefox-view-button",
|
"#firefox-view-button",
|
||||||
{ type: "mousedown" },
|
{ type: "mousedown" },
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,9 @@ support-files = [ "../head.js"]
|
||||||
|
|
||||||
["browser_opentabs_firefoxview_next.js"]
|
["browser_opentabs_firefoxview_next.js"]
|
||||||
|
|
||||||
|
["browser_opentabs_recency_next.js"]
|
||||||
|
skip-if = ["os == 'mac' && verify"] # macos times out, see bug 1857293
|
||||||
|
|
||||||
["browser_recentlyclosed_firefoxview_next.js"]
|
["browser_recentlyclosed_firefoxview_next.js"]
|
||||||
|
|
||||||
["browser_syncedtabs_errors_firefoxview_next.js"]
|
["browser_syncedtabs_errors_firefoxview_next.js"]
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,333 @@
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
/* import-globals-from ../head.js */
|
||||||
|
|
||||||
|
const tabURL1 = "data:,Tab1";
|
||||||
|
const tabURL2 = "data:,Tab2";
|
||||||
|
const tabURL3 = "data:,Tab3";
|
||||||
|
const tabURL4 = "data:,Tab4";
|
||||||
|
|
||||||
|
let gInitialTab;
|
||||||
|
let gInitialTabURL;
|
||||||
|
|
||||||
|
add_setup(function () {
|
||||||
|
gInitialTab = gBrowser.selectedTab;
|
||||||
|
gInitialTabURL = tabUrl(gInitialTab);
|
||||||
|
});
|
||||||
|
|
||||||
|
function tabUrl(tab) {
|
||||||
|
return tab.linkedBrowser.currentURI?.spec;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function minimizeWindow(win) {
|
||||||
|
let promiseSizeModeChange = BrowserTestUtils.waitForEvent(
|
||||||
|
win,
|
||||||
|
"sizemodechange"
|
||||||
|
);
|
||||||
|
win.minimize();
|
||||||
|
await promiseSizeModeChange;
|
||||||
|
ok(
|
||||||
|
!win.gBrowser.selectedTab.linkedBrowser.docShellIsActive,
|
||||||
|
"Docshell should be Inactive"
|
||||||
|
);
|
||||||
|
ok(win.document.hidden, "Top level window should be hidden");
|
||||||
|
}
|
||||||
|
|
||||||
|
async function restoreWindow(win) {
|
||||||
|
ok(win.document.hidden, "Top level window should be hidden");
|
||||||
|
let promiseSizeModeChange = BrowserTestUtils.waitForEvent(
|
||||||
|
win,
|
||||||
|
"sizemodechange"
|
||||||
|
);
|
||||||
|
info("Calling window.restore");
|
||||||
|
win.restore();
|
||||||
|
// From browser/base/content/test/general/browser_minimize.js:
|
||||||
|
// On Ubuntu `window.restore` doesn't seem to work, use a timer to make the
|
||||||
|
// test fail faster and more cleanly than with a test timeout.
|
||||||
|
info("Waiting for sizemodechange event");
|
||||||
|
let timer;
|
||||||
|
await Promise.race([
|
||||||
|
promiseSizeModeChange,
|
||||||
|
new Promise((resolve, reject) => {
|
||||||
|
// eslint-disable-next-line mozilla/no-arbitrary-setTimeout
|
||||||
|
timer = setTimeout(() => {
|
||||||
|
reject("timed out waiting for sizemodechange event");
|
||||||
|
}, 5000);
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
clearTimeout(timer);
|
||||||
|
info(
|
||||||
|
"Waiting occlusionstatechange if win.isFullyOccluded: " +
|
||||||
|
win.isFullyOccluded
|
||||||
|
);
|
||||||
|
// From browser/base/content/test/general/browser_minimize.js:
|
||||||
|
// The sizemodechange event can sometimes be fired before the
|
||||||
|
// occlusionstatechange event, especially in chaos mode.
|
||||||
|
if (win.isFullyOccluded) {
|
||||||
|
await BrowserTestUtils.waitForEvent(win, "occlusionstatechange");
|
||||||
|
}
|
||||||
|
ok(
|
||||||
|
win.gBrowser.selectedTab.linkedBrowser.docShellIsActive,
|
||||||
|
"Docshell should be active again"
|
||||||
|
);
|
||||||
|
ok(!win.document.hidden, "Top level window should be visible");
|
||||||
|
}
|
||||||
|
|
||||||
|
async function prepareOpenTabs(urls, win = window) {
|
||||||
|
const reusableTabURLs = ["about:newtab", "about:blank"];
|
||||||
|
const gBrowser = win.gBrowser;
|
||||||
|
|
||||||
|
for (let url of urls) {
|
||||||
|
if (
|
||||||
|
gBrowser.visibleTabs.length == 1 &&
|
||||||
|
reusableTabURLs.includes(gBrowser.selectedBrowser.currentURI.spec)
|
||||||
|
) {
|
||||||
|
// we'll load into this tab rather than opening a new one
|
||||||
|
info(
|
||||||
|
`Loading ${url} into blank tab: ${gBrowser.selectedBrowser.currentURI.spec}`
|
||||||
|
);
|
||||||
|
BrowserTestUtils.startLoadingURIString(gBrowser.selectedBrowser, url);
|
||||||
|
await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser, null, url);
|
||||||
|
} else {
|
||||||
|
info(`Loading ${url} into new tab`);
|
||||||
|
await BrowserTestUtils.openNewForegroundTab(gBrowser, url);
|
||||||
|
}
|
||||||
|
await new Promise(res => win.requestAnimationFrame(res));
|
||||||
|
}
|
||||||
|
Assert.equal(
|
||||||
|
gBrowser.visibleTabs.length,
|
||||||
|
urls.length,
|
||||||
|
`Prepared ${urls.length} tabs as expected`
|
||||||
|
);
|
||||||
|
Assert.equal(
|
||||||
|
tabUrl(gBrowser.selectedTab),
|
||||||
|
urls[urls.length - 1],
|
||||||
|
"The selectedTab is the last of the URLs given as expected"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function cleanup(...windowsToClose) {
|
||||||
|
await Promise.all(
|
||||||
|
windowsToClose.map(win => BrowserTestUtils.closeWindow(win))
|
||||||
|
);
|
||||||
|
|
||||||
|
while (gBrowser.visibleTabs.length > 1) {
|
||||||
|
await SessionStoreTestUtils.closeTab(gBrowser.tabs.at(-1));
|
||||||
|
}
|
||||||
|
if (gBrowser.selectedBrowser.currentURI.spec !== gInitialTabURL) {
|
||||||
|
BrowserTestUtils.startLoadingURIString(
|
||||||
|
gBrowser.selectedBrowser,
|
||||||
|
gInitialTabURL
|
||||||
|
);
|
||||||
|
await BrowserTestUtils.browserLoaded(
|
||||||
|
gBrowser.selectedBrowser,
|
||||||
|
null,
|
||||||
|
gInitialTabURL
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function checkTabList(document, expected) {
|
||||||
|
const tabsView = document.querySelector("view-opentabs");
|
||||||
|
const openTabsCard = tabsView.shadowRoot.querySelector("view-opentabs-card");
|
||||||
|
await openTabsCard.updateCompleted;
|
||||||
|
const tabList = openTabsCard.shadowRoot.querySelector("fxview-tab-list");
|
||||||
|
Assert.ok(tabList, "Found the tab list element");
|
||||||
|
|
||||||
|
let actual = Array.from(tabList.rowEls).map(row => row.url);
|
||||||
|
Assert.deepEqual(
|
||||||
|
actual,
|
||||||
|
expected,
|
||||||
|
"Tab list has items with URLs in the expected order"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
add_task(async function test_single_window_tabs() {
|
||||||
|
await prepareOpenTabs([tabURL1, tabURL2]);
|
||||||
|
await openFirefoxViewTab(window).then(async viewTab => {
|
||||||
|
const browser = viewTab.linkedBrowser;
|
||||||
|
await checkTabList(browser.contentDocument, [tabURL2, tabURL1]);
|
||||||
|
});
|
||||||
|
|
||||||
|
// switch to the first tab
|
||||||
|
await BrowserTestUtils.switchTab(gBrowser, gBrowser.visibleTabs[0]);
|
||||||
|
// and check the results in the open tabs section of Recent Browsing
|
||||||
|
await openFirefoxViewTab(window).then(async viewTab => {
|
||||||
|
const browser = viewTab.linkedBrowser;
|
||||||
|
await checkTabList(browser.contentDocument, [tabURL1, tabURL2]);
|
||||||
|
});
|
||||||
|
await cleanup();
|
||||||
|
});
|
||||||
|
|
||||||
|
add_task(async function test_multiple_window_tabs() {
|
||||||
|
const fxViewURL = getFirefoxViewURL();
|
||||||
|
const win1 = window;
|
||||||
|
await prepareOpenTabs([tabURL1, tabURL2]);
|
||||||
|
const win2 = await BrowserTestUtils.openNewBrowserWindow();
|
||||||
|
await prepareOpenTabs([tabURL3, tabURL4], win2);
|
||||||
|
|
||||||
|
// to avoid confusing the results by activating different windows,
|
||||||
|
// check fxview in the current window - which is win2
|
||||||
|
info("Switching to fxview tab in win2");
|
||||||
|
await openFirefoxViewTab(win2).then(async viewTab => {
|
||||||
|
const browser = viewTab.linkedBrowser;
|
||||||
|
await checkTabList(browser.contentDocument, [
|
||||||
|
tabURL4,
|
||||||
|
tabURL3,
|
||||||
|
tabURL2,
|
||||||
|
tabURL1,
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
Assert.equal(
|
||||||
|
tabUrl(win2.gBrowser.selectedTab),
|
||||||
|
fxViewURL,
|
||||||
|
`The selected tab in window 2 is ${fxViewURL}`
|
||||||
|
);
|
||||||
|
|
||||||
|
info("Switching to first tab (tab3) in win2");
|
||||||
|
await BrowserTestUtils.switchTab(win2.gBrowser, win2.gBrowser.visibleTabs[0]);
|
||||||
|
Assert.equal(
|
||||||
|
tabUrl(win2.gBrowser.selectedTab),
|
||||||
|
tabURL3,
|
||||||
|
`The selected tab in window 2 is ${tabURL3}`
|
||||||
|
);
|
||||||
|
|
||||||
|
info("Opening fxview in win2 to confirm tab3 is most recent");
|
||||||
|
await openFirefoxViewTab(win2).then(async viewTab => {
|
||||||
|
const browser = viewTab.linkedBrowser;
|
||||||
|
info("Check result of selecting 1ist tab in window 2");
|
||||||
|
await checkTabList(browser.contentDocument, [
|
||||||
|
tabURL3,
|
||||||
|
tabURL4,
|
||||||
|
tabURL2,
|
||||||
|
tabURL1,
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
info("Focusing win1, where tab2 should be selected");
|
||||||
|
await SimpleTest.promiseFocus(win1);
|
||||||
|
Assert.equal(
|
||||||
|
tabUrl(win1.gBrowser.selectedTab),
|
||||||
|
tabURL2,
|
||||||
|
`The selected tab in window 1 is ${tabURL2}`
|
||||||
|
);
|
||||||
|
|
||||||
|
info("Opening fxview in win1 to confirm tab2 is most recent");
|
||||||
|
await openFirefoxViewTab(win1).then(async viewTab => {
|
||||||
|
const browser = viewTab.linkedBrowser;
|
||||||
|
info(
|
||||||
|
"In fxview, check result of activating window 1, where tab 2 is selected"
|
||||||
|
);
|
||||||
|
await checkTabList(browser.contentDocument, [
|
||||||
|
tabURL2,
|
||||||
|
tabURL3,
|
||||||
|
tabURL4,
|
||||||
|
tabURL1,
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
info("Switching to first visible tab (tab1) in win1");
|
||||||
|
await BrowserTestUtils.switchTab(win1.gBrowser, win1.gBrowser.visibleTabs[0]);
|
||||||
|
|
||||||
|
// check result in the fxview in the 1st window
|
||||||
|
info("Opening fxview in win1 to confirm tab1 is most recent");
|
||||||
|
await openFirefoxViewTab(win1).then(async viewTab => {
|
||||||
|
const browser = viewTab.linkedBrowser;
|
||||||
|
info("Check result of selecting 1st tab in win1");
|
||||||
|
await checkTabList(browser.contentDocument, [
|
||||||
|
tabURL1,
|
||||||
|
tabURL2,
|
||||||
|
tabURL3,
|
||||||
|
tabURL4,
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
await cleanup(win2);
|
||||||
|
});
|
||||||
|
|
||||||
|
add_task(async function test_windows_activation() {
|
||||||
|
const win1 = window;
|
||||||
|
await prepareOpenTabs([tabURL1], win1);
|
||||||
|
let fxViewTab;
|
||||||
|
info("switch to firefox-view and leave it selected");
|
||||||
|
await openFirefoxViewTab(win1).then(tab => (fxViewTab = tab));
|
||||||
|
|
||||||
|
const win2 = await BrowserTestUtils.openNewBrowserWindow();
|
||||||
|
await prepareOpenTabs([tabURL2], win2);
|
||||||
|
const win3 = await BrowserTestUtils.openNewBrowserWindow();
|
||||||
|
await prepareOpenTabs([tabURL3], win3);
|
||||||
|
|
||||||
|
await SimpleTest.promiseFocus(win1);
|
||||||
|
|
||||||
|
const browser = fxViewTab.linkedBrowser;
|
||||||
|
await checkTabList(browser.contentDocument, [tabURL3, tabURL2, tabURL1]);
|
||||||
|
|
||||||
|
info("switch to win2 and confirm its selected tab becomes most recent");
|
||||||
|
await SimpleTest.promiseFocus(win2);
|
||||||
|
await checkTabList(browser.contentDocument, [tabURL2, tabURL3, tabURL1]);
|
||||||
|
await cleanup(win2, win3);
|
||||||
|
});
|
||||||
|
|
||||||
|
add_task(async function test_minimize_restore_windows() {
|
||||||
|
const win1 = window;
|
||||||
|
await prepareOpenTabs([tabURL1, tabURL2]);
|
||||||
|
const win2 = await BrowserTestUtils.openNewBrowserWindow();
|
||||||
|
await prepareOpenTabs([tabURL3, tabURL4], win2);
|
||||||
|
|
||||||
|
// to avoid confusing the results by activating different windows,
|
||||||
|
// check fxview in the current window - which is win2
|
||||||
|
info("Opening fxview in win2 to confirm tab4 is most recent");
|
||||||
|
await openFirefoxViewTab(win2).then(async viewTab => {
|
||||||
|
const browser = viewTab.linkedBrowser;
|
||||||
|
await checkTabList(browser.contentDocument, [
|
||||||
|
tabURL4,
|
||||||
|
tabURL3,
|
||||||
|
tabURL2,
|
||||||
|
tabURL1,
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
//
|
||||||
|
info("Switching to the first tab (tab3) in 2nd window");
|
||||||
|
await BrowserTestUtils.switchTab(win2.gBrowser, win2.gBrowser.visibleTabs[0]);
|
||||||
|
|
||||||
|
// then minimize the window, focusing the 1st window
|
||||||
|
info("Minimizing win2, leaving tab 3 selected");
|
||||||
|
await minimizeWindow(win2);
|
||||||
|
info("Focusing win1, where tab2 is selected - making it most recent");
|
||||||
|
await SimpleTest.promiseFocus(win1);
|
||||||
|
|
||||||
|
Assert.equal(
|
||||||
|
tabUrl(win1.gBrowser.selectedTab),
|
||||||
|
tabURL2,
|
||||||
|
`The selected tab in window 1 is ${tabURL2}`
|
||||||
|
);
|
||||||
|
|
||||||
|
info("Opening fxview in win1 to confirm tab2 is most recent");
|
||||||
|
await openFirefoxViewTab(win1).then(async viewTab => {
|
||||||
|
const browser = viewTab.linkedBrowser;
|
||||||
|
await checkTabList(browser.contentDocument, [
|
||||||
|
tabURL2,
|
||||||
|
tabURL3,
|
||||||
|
tabURL4,
|
||||||
|
tabURL1,
|
||||||
|
]);
|
||||||
|
info(
|
||||||
|
"Restoring win2 and focusing it - which should make its selected tab most recent"
|
||||||
|
);
|
||||||
|
await restoreWindow(win2);
|
||||||
|
await SimpleTest.promiseFocus(win2);
|
||||||
|
|
||||||
|
info(
|
||||||
|
"Checking tab order in fxview in win1, to confirm tab3 is most recent"
|
||||||
|
);
|
||||||
|
await checkTabList(browser.contentDocument, [
|
||||||
|
tabURL3,
|
||||||
|
tabURL2,
|
||||||
|
tabURL4,
|
||||||
|
tabURL1,
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
await cleanup(win2);
|
||||||
|
});
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
getFirefoxViewURL,
|
||||||
withFirefoxView,
|
withFirefoxView,
|
||||||
assertFirefoxViewTab,
|
assertFirefoxViewTab,
|
||||||
assertFirefoxViewTabSelected,
|
assertFirefoxViewTabSelected,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue