Bug 1819856 - When restoring thread tree selection, select the root of selected collapsed threads. r=aleca

Differential Revision: https://phabricator.services.mozilla.com/D171443

--HG--
extra : rebase_source : 884a89f161b92e24363cec8cf083700237c48d63
extra : amend_source : d2924e6c3f8a54b275fc6a95803e19c280ec4c90
This commit is contained in:
Geoff Lankow 2023-03-02 15:55:12 +13:00
Родитель 5cb0f8d98b
Коммит 84bd8506f2
2 изменённых файлов: 208 добавлений и 8 удалений

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

@ -2451,15 +2451,41 @@ var threadPane = {
}
let { currentKey, selectedKeys } = this._savedSelections.get(gFolder.URI);
threadTree.selectedIndices = selectedKeys
.map(gDBView.findIndexFromKey)
.filter(i => i != nsMsgViewIndex_None);
let currentIndex = nsMsgViewIndex_None;
let indices = new Set();
for (let key of selectedKeys) {
let index = gDBView.findIndexFromKey(key, false);
if (index != nsMsgViewIndex_None) {
indices.add(index);
if (key == currentKey) {
currentIndex = index;
}
continue;
}
let index = gDBView.findIndexFromKey(currentKey, false);
if (index != nsMsgViewIndex_None) {
// The message for this key can't be found. Perhaps the thread it's in
// has been collapsed? Select the root message in that case.
try {
let msgHdr = gFolder.GetMessageHeader(key);
let thread = gDBView.getThreadContainingMsgHdr(msgHdr);
let rootMsgHdr = thread.getRootHdr();
index = gDBView.findIndexOfMsgHdr(rootMsgHdr, false);
if (index != nsMsgViewIndex_None) {
indices.add(index);
if (key == currentKey) {
currentIndex = index;
}
}
} catch (ex) {
console.error(ex);
}
}
threadTree.selectedIndices = indices.values();
if (currentIndex != nsMsgViewIndex_None) {
// Do an instant scroll before setting the index to avoid animation.
threadTree.scrollToIndex(index, true);
threadTree.currentIndex = index;
threadTree.scrollToIndex(currentIndex, true);
threadTree.currentIndex = currentIndex;
}
this._savedSelections.delete(gFolder.URI);
},
@ -3763,7 +3789,6 @@ commandController.registerCallback(
() => {
threadPane.saveSelection();
gViewWrapper.dbView.doCommand(Ci.nsMsgViewCommandType.collapseAll);
// TODO: this reopens threads containing a selected message.
threadPane.restoreSelection();
},
() => !!gViewWrapper?.dbView

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

@ -56,6 +56,181 @@ add_setup(async function() {
});
});
add_task(async function testExpandCollapseUpdates() {
about3Pane.restoreState({
messagePaneVisible: true,
folderURI: folderA.URI,
});
// Clicking the twisty to collapse a row should update the message display.
goDoCommand("cmd_expandAllThreads");
threadTree.selectedIndex = 5;
await BrowserTestUtils.browserLoaded(messagePaneBrowser);
Assert.equal(
aboutMessage.gMessage.messageId,
sourceMessageIDs[10],
"correct message loaded"
);
let selectPromise = BrowserTestUtils.waitForEvent(threadTree, "select");
EventUtils.synthesizeMouseAtCenter(
threadTree.getRowAtIndex(5).querySelector(".twisty"),
{},
about3Pane
);
await selectPromise;
Assert.equal(threadTree.view.rowCount, 11, "thread collapsed");
Assert.equal(threadTree.selectedIndex, 5, "thread root still selected");
Assert.ok(
BrowserTestUtils.is_hidden(about3Pane.messageBrowser),
"messageBrowser became hidden"
);
Assert.ok(
BrowserTestUtils.is_visible(about3Pane.multiMessageBrowser),
"multiMessageBrowser became visible"
);
// Clicking the twisty to expand a row should update the message display.
selectPromise = BrowserTestUtils.waitForEvent(threadTree, "select");
EventUtils.synthesizeMouseAtCenter(
threadTree.getRowAtIndex(5).querySelector(".twisty"),
{},
about3Pane
);
await selectPromise;
Assert.equal(threadTree.view.rowCount, 15, "thread expanded");
Assert.equal(threadTree.selectedIndex, 5, "thread root still selected");
Assert.ok(
BrowserTestUtils.is_hidden(about3Pane.multiMessageBrowser),
"multiMessageBrowser became hidden"
);
Assert.ok(
BrowserTestUtils.is_visible(about3Pane.messageBrowser),
"messageBrowser became visible"
);
await BrowserTestUtils.browserLoaded(messagePaneBrowser);
Assert.equal(
aboutMessage.gMessage.messageId,
sourceMessageIDs[10],
"correct message loaded"
);
// Collapsing all rows while the first message in a thread is selected should
// update the message display.
selectPromise = BrowserTestUtils.waitForEvent(threadTree, "select");
goDoCommand("cmd_collapseAllThreads");
await selectPromise;
Assert.equal(threadTree.view.rowCount, 3, "all threads collapsed");
Assert.equal(threadTree.selectedIndex, 1, "thread root still selected");
Assert.ok(
BrowserTestUtils.is_hidden(about3Pane.messageBrowser),
"messageBrowser became hidden"
);
Assert.ok(
BrowserTestUtils.is_visible(about3Pane.multiMessageBrowser),
"multiMessageBrowser became visible"
);
// Expanding all rows while the first message in a thread is selected should
// update the message display.
selectPromise = BrowserTestUtils.waitForEvent(threadTree, "select");
goDoCommand("cmd_expandAllThreads");
await selectPromise;
Assert.equal(threadTree.view.rowCount, 15, "all threads expanded");
Assert.equal(threadTree.selectedIndex, 5, "thread root still selected");
Assert.ok(
BrowserTestUtils.is_hidden(about3Pane.multiMessageBrowser),
"multiMessageBrowser became hidden"
);
Assert.ok(
BrowserTestUtils.is_visible(about3Pane.messageBrowser),
"messageBrowser became visible"
);
await BrowserTestUtils.browserLoaded(messagePaneBrowser);
Assert.equal(
aboutMessage.gMessage.messageId,
sourceMessageIDs[10],
"correct message loaded"
);
// Collapsing all rows while a message inside a thread is selected should
// select the first message in the thread and update the message display.
threadTree.selectedIndex = 2;
await BrowserTestUtils.browserLoaded(messagePaneBrowser);
Assert.equal(
aboutMessage.gMessage.messageId,
sourceMessageIDs[7],
"correct message loaded"
);
selectPromise = BrowserTestUtils.waitForEvent(threadTree, "select");
goDoCommand("cmd_collapseAllThreads");
await selectPromise;
Assert.equal(threadTree.view.rowCount, 3, "all threads collapsed");
Assert.equal(threadTree.selectedIndex, 0, "thread root became selected");
Assert.ok(
BrowserTestUtils.is_hidden(about3Pane.messageBrowser),
"messageBrowser became hidden"
);
Assert.ok(
BrowserTestUtils.is_visible(about3Pane.multiMessageBrowser),
"multiMessageBrowser became visible"
);
// Expanding all rows while the first message in a thread is selected should
// update the message display. (This is effectively the same test as earlier.)
selectPromise = BrowserTestUtils.waitForEvent(threadTree, "select");
goDoCommand("cmd_expandAllThreads");
await selectPromise;
Assert.equal(threadTree.view.rowCount, 15, "all threads expanded");
Assert.equal(threadTree.selectedIndex, 0, "thread root still selected");
Assert.ok(
BrowserTestUtils.is_hidden(about3Pane.multiMessageBrowser),
"multiMessageBrowser became hidden"
);
Assert.ok(
BrowserTestUtils.is_visible(about3Pane.messageBrowser),
"messageBrowser became visible"
);
await BrowserTestUtils.browserLoaded(messagePaneBrowser);
Assert.equal(
aboutMessage.gMessage.messageId,
sourceMessageIDs[5],
"correct message loaded"
);
// Select several things and collapse all.
selectPromise = BrowserTestUtils.waitForEvent(threadTree, "select");
threadTree.selectedIndices = [2, 3, 5];
await selectPromise;
Assert.ok(
BrowserTestUtils.is_hidden(about3Pane.messageBrowser),
"messageBrowser became hidden"
);
Assert.ok(
BrowserTestUtils.is_visible(about3Pane.multiMessageBrowser),
"multiMessageBrowser became visible"
);
selectPromise = BrowserTestUtils.waitForEvent(threadTree, "select");
goDoCommand("cmd_collapseAllThreads");
await selectPromise;
Assert.equal(threadTree.view.rowCount, 3, "all threads collapsed");
Assert.deepEqual(
threadTree.selectedIndices,
[0, 1],
"thread roots became selected"
);
Assert.ok(
BrowserTestUtils.is_hidden(about3Pane.messageBrowser),
"messageBrowser stayed hidden"
);
Assert.ok(
BrowserTestUtils.is_visible(about3Pane.multiMessageBrowser),
"multiMessageBrowser stayed visible"
);
});
add_task(async function testThreadUpdateKeepsSelection() {
about3Pane.restoreState({
messagePaneVisible: true,