Remove some unnecessary asyncness in tree views

E.g., closing a container doesn't need to yield
This commit is contained in:
Dan Stillman 2015-05-04 02:35:52 -04:00
parent d22f762bb6
commit 8ec248f7ec
2 changed files with 132 additions and 106 deletions

View File

@ -639,39 +639,47 @@ Zotero.CollectionTreeView.prototype.hasNextSibling = function(row, afterIndex)
/* /*
* Opens/closes the specified row * Opens/closes the specified row
*/ */
Zotero.CollectionTreeView.prototype.toggleOpenState = Zotero.Promise.coroutine(function* (row) Zotero.CollectionTreeView.prototype.toggleOpenState = Zotero.Promise.coroutine(function* (row) {
{
var count = 0;
var thisLevel = this.getLevel(row);
//this._treebox.beginUpdateBatch();
if (this.isContainerOpen(row)) { if (this.isContainerOpen(row)) {
while((row + 1 < this._rows.length) && (this.getLevel(row + 1) > thisLevel)) return this._closeContainer(row);
{
this._removeRow(row+1);
count--;
}
// Remove from the end of the row's children
this._treebox.rowCountChanged(row + 1 + Math.abs(count), count);
} }
else {
var treeRow = this.getRow(row); var count = 0;
if (treeRow.isLibrary(true) || treeRow.isCollection()) {
count = yield this._expandRow(this._rows, row, true); var treeRow = this.getRow(row);
} if (treeRow.isLibrary(true) || treeRow.isCollection()) {
this.rowCount += count; count = yield this._expandRow(this._rows, row, true);
this._treebox.rowCountChanged(row + 1, count);
} }
this.rowCount += count;
this._treebox.rowCountChanged(row + 1, count);
// Toggle container open value // Toggle container open value
this._rows[row][1] = !this._rows[row][1]; this._rows[row][1] = true;
this._treebox.invalidateRow(row); this._treebox.invalidateRow(row);
//this._treebox.endUpdateBatch();
this._refreshRowMap(); this._refreshRowMap();
yield this._rememberOpenStates();
}); });
Zotero.CollectionTreeView.prototype._closeContainer = function (row) {
if (!this.isContainerOpen(row)) return;
var count = 0;
var level = this.getLevel(row);
// Remove child rows
while ((row + 1 < this._rows.length) && (this.getLevel(row + 1) > level)) {
this._removeRow(row + 1);
count--;
}
// Mark as removed from the end of the row's children
this._treebox.rowCountChanged(row + 1 + Math.abs(count), count);
this._rows[row][1] = false;
this._treebox.invalidateRow(row);
this._refreshRowMap();
}
Zotero.CollectionTreeView.prototype.isSelectable = function (row, col) { Zotero.CollectionTreeView.prototype.isSelectable = function (row, col) {
var treeRow = this.getRow(row); var treeRow = this.getRow(row);
switch (treeRow.type) { switch (treeRow.type) {
@ -744,7 +752,7 @@ Zotero.CollectionTreeView.prototype.expandLibrary = Zotero.Promise.coroutine(fun
}); });
Zotero.CollectionTreeView.prototype.collapseLibrary = Zotero.Promise.coroutine(function* () { Zotero.CollectionTreeView.prototype.collapseLibrary = function () {
var selectedLibraryID = this.getSelectedLibraryID(); var selectedLibraryID = this.getSelectedLibraryID();
if (selectedLibraryID === false) { if (selectedLibraryID === false) {
return; return;
@ -764,8 +772,8 @@ Zotero.CollectionTreeView.prototype.collapseLibrary = Zotero.Promise.coroutine(f
found = true; found = true;
if (this.isContainer(i) && this.isContainerOpen(i)) { if (this.isContainer(i)) {
yield this.toggleOpenState(i); this._closeContainer(i);
} }
} }
@ -773,7 +781,7 @@ Zotero.CollectionTreeView.prototype.collapseLibrary = Zotero.Promise.coroutine(f
// Select the collapsed library // Select the collapsed library
this.selectLibrary(selectedLibraryID); this.selectLibrary(selectedLibraryID);
}); };
Zotero.CollectionTreeView.prototype.expandToCollection = Zotero.Promise.coroutine(function* (collectionID) { Zotero.CollectionTreeView.prototype.expandToCollection = Zotero.Promise.coroutine(function* (collectionID) {
@ -870,7 +878,7 @@ Zotero.CollectionTreeView.prototype.selectCollection = Zotero.Promise.coroutine(
}); });
Zotero.CollectionTreeView.prototype.selectTrash = function (libraryID) { Zotero.CollectionTreeView.prototype.selectTrash = Zotero.Promise.coroutine(function* (libraryID) {
if (Zotero.suppressUIUpdates) { if (Zotero.suppressUIUpdates) {
Zotero.debug("UI updates suppressed -- not changing library selection"); Zotero.debug("UI updates suppressed -- not changing library selection");
return false; return false;
@ -887,7 +895,7 @@ Zotero.CollectionTreeView.prototype.selectTrash = function (libraryID) {
// If in My Library and it's collapsed, open it // If in My Library and it's collapsed, open it
if (!libraryID && !this.isContainerOpen(0)) { if (!libraryID && !this.isContainerOpen(0)) {
this.toggleOpenState(0); yield this.toggleOpenState(0);
} }
// Find library trash // Find library trash
@ -897,13 +905,13 @@ Zotero.CollectionTreeView.prototype.selectTrash = function (libraryID) {
// If group header is closed, open it // If group header is closed, open it
if (itemGroup.isHeader() && itemGroup.ref.id == 'group-libraries-header' if (itemGroup.isHeader() && itemGroup.ref.id == 'group-libraries-header'
&& !this.isContainerOpen(i)) { && !this.isContainerOpen(i)) {
this.toggleOpenState(i); yield this.toggleOpenState(i);
continue; continue;
} }
if (itemGroup.isLibrary(true) && itemGroup.ref.libraryID == libraryID if (itemGroup.isLibrary(true) && itemGroup.ref.libraryID == libraryID
&& !this.isContainerOpen(i)) { && !this.isContainerOpen(i)) {
this.toggleOpenState(i); yield this.toggleOpenState(i);
continue; continue;
} }
@ -915,7 +923,7 @@ Zotero.CollectionTreeView.prototype.selectTrash = function (libraryID) {
} }
return false; return false;
} });
/** /**
@ -1001,8 +1009,8 @@ Zotero.CollectionTreeView.prototype.deleteSelection = Zotero.Promise.coroutine(f
//collapse open collections //collapse open collections
for (let i=0; i<this.rowCount; i++) { for (let i=0; i<this.rowCount; i++) {
if (this.selection.isSelected(i) && this.isContainer(i) && this.isContainerOpen(i)) { if (this.selection.isSelected(i) && this.isContainer(i)) {
yield this.toggleOpenState(i); this._closeContainer(i);
} }
} }
this._refreshRowMap(); this._refreshRowMap();

View File

@ -92,7 +92,6 @@ Zotero.ItemTreeView.prototype.setTree = Zotero.Promise.coroutine(function* (tree
if (this._ownerDocument.defaultView.ZoteroPane_Local) { if (this._ownerDocument.defaultView.ZoteroPane_Local) {
this._ownerDocument.defaultView.ZoteroPane_Local.setItemsPaneMessage(Zotero.getString('pane.items.loading')); this._ownerDocument.defaultView.ZoteroPane_Local.setItemsPaneMessage(Zotero.getString('pane.items.loading'));
this._waitAfter = start + 100;
} }
if (Zotero.locked) { if (Zotero.locked) {
@ -237,9 +236,6 @@ Zotero.ItemTreeView.prototype.setTree = Zotero.Promise.coroutine(function* (tree
yield this.sort(); yield this.sort();
// Only yield if there are callbacks; otherwise, we're almost done
if (this._listeners.load.length && this._waitAfter && Date.now() > this._waitAfter) yield Zotero.Promise.resolve();
yield this.expandMatchParents(); yield this.expandMatchParents();
@ -254,7 +250,6 @@ Zotero.ItemTreeView.prototype.setTree = Zotero.Promise.coroutine(function* (tree
this.collectionTreeRow.itemToSelect = null; this.collectionTreeRow.itemToSelect = null;
} }
delete this._waitAfter;
Zotero.debug("Set tree in "+(Date.now()-start)+" ms"); Zotero.debug("Set tree in "+(Date.now()-start)+" ms");
this._initialized = true; this._initialized = true;
@ -323,7 +318,7 @@ Zotero.ItemTreeView.prototype.refresh = Zotero.serial(Zotero.Promise.coroutine(f
//this._treebox.beginUpdateBatch(); //this._treebox.beginUpdateBatch();
} }
var savedSelection = this.getSelectedItems(true); var savedSelection = this.getSelectedItems(true);
var savedOpenState = yield this.saveOpenState(); var savedOpenState = this._saveOpenState();
var oldCount = this.rowCount; var oldCount = this.rowCount;
var newSearchItemIDs = {}; var newSearchItemIDs = {};
@ -372,8 +367,6 @@ Zotero.ItemTreeView.prototype.refresh = Zotero.serial(Zotero.Promise.coroutine(f
} }
} }
if(this._waitAfter && Date.now() > this._waitAfter) yield Zotero.Promise.resolve();
this._rows = newRows; this._rows = newRows;
this.rowCount = this._rows.length; this.rowCount = this._rows.length;
var diff = this.rowCount - oldCount; var diff = this.rowCount - oldCount;
@ -1194,58 +1187,53 @@ Zotero.ItemTreeView.prototype.toggleOpenState = Zotero.Promise.coroutine(functio
return; return;
} }
var count = 0;
var thisLevel = this.getLevel(row);
// Close
if (this.isContainerOpen(row)) { if (this.isContainerOpen(row)) {
while((row + 1 < this._rows.length) && (this.getLevel(row + 1) > thisLevel)) return this._closeContainer(row, skipItemMapRefresh);
{
this._removeRow(row+1);
count--;
}
// Remove from the end of the row's children
this._treebox.rowCountChanged(row + 1 + Math.abs(count), count);
} }
var count = 0;
var level = this.getLevel(row);
//
// Open // Open
else { //
var item = this.getRow(row).ref; var item = this.getRow(row).ref;
yield item.loadChildItems(); yield item.loadChildItems();
//Get children //Get children
var includeTrashed = this.collectionTreeRow.isTrash(); var includeTrashed = this.collectionTreeRow.isTrash();
var attachments = item.getAttachments(includeTrashed); var attachments = item.getAttachments(includeTrashed);
var notes = item.getNotes(includeTrashed); var notes = item.getNotes(includeTrashed);
var newRows; var newRows;
if(attachments && notes) if (attachments.length && notes.length) {
newRows = notes.concat(attachments); newRows = notes.concat(attachments);
else if(attachments) }
newRows = attachments; else if (attachments.length) {
else if(notes) newRows = attachments;
newRows = notes; }
else if (notes.length) {
if (newRows) { newRows = notes;
newRows = yield Zotero.Items.getAsync(newRows);
for(var i = 0; i < newRows.length; i++)
{
count++;
this._addRow(
this._rows,
new Zotero.ItemTreeRow(newRows[i], thisLevel + 1, false),
row + i + 1
);
}
this.rowCount += count;
this._treebox.rowCountChanged(row + 1, count);
}
} }
// Toggle container open value if (newRows) {
this._rows[row].isOpen = !this._rows[row].isOpen; newRows = yield Zotero.Items.getAsync(newRows);
if (!count) { for (let i = 0; i < newRows.length; i++) {
count++;
this._addRow(
this._rows,
new Zotero.ItemTreeRow(newRows[i], level + 1, false),
row + i + 1
);
}
this.rowCount += count;
this._treebox.rowCountChanged(row + 1, count);
}
this._rows[row].isOpen = true;
if (count == 0) {
return; return;
} }
@ -1258,6 +1246,39 @@ Zotero.ItemTreeView.prototype.toggleOpenState = Zotero.Promise.coroutine(functio
}); });
Zotero.ItemTreeView.prototype._closeContainer = function (row, skipItemMapRefresh) {
// isContainer == false shouldn't happen but does if an item is dragged over a closed
// container until it opens and then released, since the container is no longer in the same
// place when the spring-load closes
if (!this.isContainer(row)) return;
if (!this.isContainerOpen(row)) return;
var count = 0;
var level = this.getLevel(row);
// Remove child rows
while ((row + 1 < this._rows.length) && (this.getLevel(row + 1) > level)) {
this._removeRow(row+1);
count--;
}
// Mark as removed from the end of the row's children
this._treebox.rowCountChanged(row + 1 + Math.abs(count), count);
this._rows[row].isOpen = false;
if (count == 0) {
return;
}
this._treebox.invalidateRow(row);
if (!skipItemMapRefresh) {
Zotero.debug('Refreshing hash map');
this._refreshItemRowMap();
}
}
Zotero.ItemTreeView.prototype.isSorted = function() Zotero.ItemTreeView.prototype.isSorted = function()
{ {
// We sort by the first column if none selected, so return true // We sort by the first column if none selected, so return true
@ -1320,11 +1341,11 @@ Zotero.ItemTreeView.prototype.sort = Zotero.Promise.coroutine(function* (itemID)
} }
this._needsSort = false; this._needsSort = false;
// Single child item sort -- just toggle parent open and closed // Single child item sort -- just toggle parent closed and open
if (itemID && this._itemRowMap[itemID] && if (itemID && this._itemRowMap[itemID] &&
this.getRow(this._itemRowMap[itemID]).ref.parentKey) { this.getRow(this._itemRowMap[itemID]).ref.parentKey) {
let parentIndex = this.getParentIndex(this._itemRowMap[itemID]); let parentIndex = this.getParentIndex(this._itemRowMap[itemID]);
yield this.toggleOpenState(parentIndex); this._closeContainer(parentIndex);
yield this.toggleOpenState(parentIndex); yield this.toggleOpenState(parentIndex);
return; return;
} }
@ -1527,7 +1548,7 @@ Zotero.ItemTreeView.prototype.sort = Zotero.Promise.coroutine(function* (itemID)
//this._treebox.beginUpdateBatch(); //this._treebox.beginUpdateBatch();
} }
var savedSelection = this.getSelectedItems(true); var savedSelection = this.getSelectedItems(true);
var openItemIDs = yield this.saveOpenState(true); var openItemIDs = this._saveOpenState(true);
// Single-row sort // Single-row sort
if (itemID) { if (itemID) {
@ -1646,9 +1667,8 @@ Zotero.ItemTreeView.prototype.selectItem = Zotero.Promise.coroutine(function* (i
// If parent is already open and we haven't found the item, the child // If parent is already open and we haven't found the item, the child
// hasn't yet been added to the view, so close parent to allow refresh // hasn't yet been added to the view, so close parent to allow refresh
if (this.isContainerOpen(parentRow)) { this._closeContainer(parentRow);
yield this.toggleOpenState(parentRow);
}
// Open the parent // Open the parent
yield this.toggleOpenState(parentRow); yield this.toggleOpenState(parentRow);
row = this._itemRowMap[id]; row = this._itemRowMap[id];
@ -1792,8 +1812,8 @@ Zotero.ItemTreeView.prototype.deleteSelection = Zotero.Promise.coroutine(functio
// Collapse open items // Collapse open items
for (var i=0; i<this.rowCount; i++) { for (var i=0; i<this.rowCount; i++) {
if (this.selection.isSelected(i) && this.isContainer(i) && this.isContainerOpen(i)) { if (this.selection.isSelected(i) && this.isContainer(i)) {
yield this.toggleOpenState(i, true); this._closeContainer(i, true);
} }
} }
this._refreshItemRowMap(); this._refreshItemRowMap();
@ -1948,9 +1968,7 @@ Zotero.ItemTreeView.prototype.rememberSelection = Zotero.Promise.coroutine(funct
} }
if (this._itemRowMap[parent] != null) { if (this._itemRowMap[parent] != null) {
if (this.isContainerOpen(this._itemRowMap[parent])) { this._closeContainer(this._itemRowMap[parent]);
yield this.toggleOpenState(this._itemRowMap[parent]);
}
yield this.toggleOpenState(this._itemRowMap[parent]); yield this.toggleOpenState(this._itemRowMap[parent]);
this.selection.toggleSelect(this._itemRowMap[selection[i]]); this.selection.toggleSelect(this._itemRowMap[selection[i]]);
} }
@ -1977,7 +1995,7 @@ Zotero.ItemTreeView.prototype.selectSearchMatches = Zotero.Promise.coroutine(fun
}); });
Zotero.ItemTreeView.prototype.saveOpenState = Zotero.Promise.coroutine(function* (close) { Zotero.ItemTreeView.prototype._saveOpenState = function (close) {
var itemIDs = []; var itemIDs = [];
if (close) { if (close) {
if (!this.selection.selectEventsSuppressed) { if (!this.selection.selectEventsSuppressed) {
@ -1989,7 +2007,7 @@ Zotero.ItemTreeView.prototype.saveOpenState = Zotero.Promise.coroutine(function*
if (this.isContainer(i) && this.isContainerOpen(i)) { if (this.isContainer(i) && this.isContainerOpen(i)) {
itemIDs.push(this.getRow(i).ref.id); itemIDs.push(this.getRow(i).ref.id);
if (close) { if (close) {
yield this.toggleOpenState(i, true); this._closeContainer(i, true);
} }
} }
} }
@ -2001,7 +2019,7 @@ Zotero.ItemTreeView.prototype.saveOpenState = Zotero.Promise.coroutine(function*
} }
} }
return itemIDs; return itemIDs;
}); }
Zotero.ItemTreeView.prototype.rememberOpenState = Zotero.Promise.coroutine(function* (itemIDs) { Zotero.ItemTreeView.prototype.rememberOpenState = Zotero.Promise.coroutine(function* (itemIDs) {
@ -2097,8 +2115,8 @@ Zotero.ItemTreeView.prototype.collapseAllRows = Zotero.Promise.coroutine(functio
var unsuppress = this.selection.selectEventsSuppressed = true; var unsuppress = this.selection.selectEventsSuppressed = true;
//this._treebox.beginUpdateBatch(); //this._treebox.beginUpdateBatch();
for (var i=0; i<this.rowCount; i++) { for (var i=0; i<this.rowCount; i++) {
if (this.isContainer(i) && this.isContainerOpen(i)) { if (this.isContainer(i)) {
yield this.toggleOpenState(i, true); this._closeContainer(i, true);
} }
} }
this._refreshItemRowMap(); this._refreshItemRowMap();
@ -2132,8 +2150,8 @@ Zotero.ItemTreeView.prototype.collapseSelectedRows = Zotero.Promise.coroutine(fu
for (var i = 0, len = this.selection.getRangeCount(); i<len; i++) { for (var i = 0, len = this.selection.getRangeCount(); i<len; i++) {
this.selection.getRangeAt(i, start, end); this.selection.getRangeAt(i, start, end);
for (var j = start.value; j <= end.value; j++) { for (var j = start.value; j <= end.value; j++) {
if (this.isContainer(j) && this.isContainerOpen(j)) { if (this.isContainer(j)) {
yield this.toggleOpenState(j, true); this._closeContainer(j, true);
} }
} }
} }