Bug 1843462 - Prevent filling of off-screen TreeView rows during invalidation. r=leftmostcat

If `invalidate` is called, the TreeView should immediately stop adding buffer rows. And instead
of adding extra rows immediately after invalidation, it should wait to the end of the event loop
in case something else happens first.

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

--HG--
extra : rebase_source : 96556a20c486967a033939038c471d0f0339f983
This commit is contained in:
Geoff Lankow 2023-07-27 22:31:34 +12:00
Родитель 0b3ac176eb
Коммит cbdcf74578
3 изменённых файлов: 10 добавлений и 12 удалений

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

@ -182,12 +182,12 @@ var mailContextMenu = {
window.threadTree._selection.selectEventsSuppressed = true;
window.threadPane.restoreSelection(undefined, false);
this._selectionIsOverridden = false;
window.threadTree.invalidate();
}
window.threadTree
.querySelector(".context-menu-target")
?.classList.remove("context-menu-target");
window.threadTree._selection.selectEventsSuppressed = false;
window.threadTree.invalidate();
window.threadTree.table.body.focus();
},

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

@ -217,15 +217,7 @@ class TreeView extends HTMLElement {
}
disconnectedCallback() {
cancelIdleCallback(this.#bufferFillIdleCallbackHandle);
for (let row of this._rows.values()) {
row.remove();
}
this._rows.clear();
this.replaceChildren();
this.#resetRowBuffer();
this.resizeObserver.disconnect();
}
@ -565,6 +557,7 @@ class TreeView extends HTMLElement {
* Clear all rows from the buffer, empty the table body, and reset spacers.
*/
#resetRowBuffer() {
this.#cancelToleranceFillCallback();
this.table.body.replaceChildren();
this._rows.clear();
this.#firstBufferRowIndex = 0;
@ -682,6 +675,11 @@ class TreeView extends HTMLElement {
);
}
#cancelToleranceFillCallback() {
cancelIdleCallback(this.#bufferFillIdleCallbackHandle);
this.#bufferFillIdleCallbackHandle = null;
}
/**
* Fill the buffer with tolerance rows above and below the visible rows.
*

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

@ -283,7 +283,7 @@ add_task(async function testSingleMessage() {
shownPromise = BrowserTestUtils.waitForEvent(mailContext, "popupshown");
const row = threadTree.getRowAtIndex(0);
await row.focus();
row.focus();
EventUtils.synthesizeMouseAtCenter(
row,
{ type: "contextmenu", button: 0 },
@ -299,9 +299,9 @@ add_task(async function testSingleMessage() {
// Open the menu on a message that is scrolled out of view.
shownPromise = BrowserTestUtils.waitForEvent(mailContext, "popupshown");
await row.focus();
threadTree.scrollToIndex(200, true);
await new Promise(resolve => window.requestAnimationFrame(resolve));
Assert.ok(!row.parentNode, "Row element should no longer be attached");
Assert.equal(threadTree.currentIndex, 0, "Row 0 is the current row");
Assert.ok(
!threadTree.getRowAtIndex(threadTree.currentIndex),