Make things snappier

This commit is contained in:
Simon Kornblith 2011-08-21 05:47:07 +00:00
parent 44225aa4d1
commit 8b51c3e069

View file

@ -73,68 +73,69 @@ Zotero.ItemTreeView.prototype._runCallbacks = function() {
*/
Zotero.ItemTreeView.prototype.setTree = function(treebox)
{
//Zotero.debug("Calling setTree()");
// Try to set the window document if not yet set
if (treebox && !this._ownerDocument) {
try {
this._ownerDocument = treebox.treeBody.ownerDocument;
try {
//Zotero.debug("Calling setTree()");
var start = Date.now();
// Try to set the window document if not yet set
if (treebox && !this._ownerDocument) {
try {
this._ownerDocument = treebox.treeBody.ownerDocument;
}
catch (e) {}
}
catch (e) {}
}
if (this._treebox) {
if (this._needsSort) {
this.sort();
if (this._treebox) {
if (this._needsSort) {
this.sort();
}
return;
}
return;
}
if (!treebox) {
Components.utils.reportError("Passed treebox empty in setTree()");
}
this._treebox = treebox;
if (this._ownerDocument.defaultView.ZoteroPane_Local) {
this._ownerDocument.defaultView.ZoteroPane_Local.setItemsPaneMessage(Zotero.getString('pane.items.loading'));
}
// Generate the tree contents in a timer to allow message above to display
var paneLoader = function(obj) {
if (!treebox) {
Components.utils.reportError("Passed treebox empty in setTree()");
}
this._treebox = treebox;
if (this._ownerDocument.defaultView.ZoteroPane_Local) {
this._ownerDocument.defaultView.ZoteroPane_Local.setItemsPaneMessage(Zotero.getString('pane.items.loading'));
this._waitAfter = start + 100;
}
if (Zotero.locked) {
var msg = "Zotero is locked -- not loading items tree";
Zotero.debug(msg, 2);
if (obj._ownerDocument.defaultView.ZoteroPane_Local) {
obj._ownerDocument.defaultView.ZoteroPane_Local.clearItemsPaneMessage();
if (this._ownerDocument.defaultView.ZoteroPane_Local) {
this._ownerDocument.defaultView.ZoteroPane_Local.clearItemsPaneMessage();
}
return;
}
// If a DB transaction is open, display error message and bail
if (!Zotero.stateCheck()) {
if (obj._ownerDocument.defaultView.ZoteroPane_Local) {
obj._ownerDocument.defaultView.ZoteroPane_Local.displayErrorMessage();
if (this._ownerDocument.defaultView.ZoteroPane_Local) {
this._ownerDocument.defaultView.ZoteroPane_Local.displayErrorMessage();
}
return;
}
obj.refresh();
this.refresh();
// Add a keypress listener for expand/collapse
var tree = obj._treebox.treeBody.parentNode;
var tree = this._treebox.treeBody.parentNode;
var listener = function(event) {
// Handle arrow keys specially on multiple selection, since
// otherwise the tree just applies it to the last-selected row
if (event.keyCode == 39 || event.keyCode == 37) {
if (obj._treebox.view.selection.count > 1) {
if (this._treebox.view.selection.count > 1) {
switch (event.keyCode) {
case 39:
obj.expandSelectedRows();
this.expandSelectedRows();
break;
case 37:
obj.collapseSelectedRows();
this.collapseSelectedRows();
break;
}
@ -146,40 +147,56 @@ Zotero.ItemTreeView.prototype.setTree = function(treebox)
var key = String.fromCharCode(event.which);
if (key == '+' && !(event.ctrlKey || event.altKey || event.metaKey)) {
obj.expandAllRows();
this.expandAllRows();
event.preventDefault();
return;
}
else if (key == '-' && !(event.shiftKey || event.ctrlKey || event.altKey || event.metaKey)) {
obj.collapseAllRows();
this.collapseAllRows();
event.preventDefault();
return;
}
};
// Store listener so we can call removeEventListener()
// in overlay.js::onCollectionSelected()
obj.listener = listener;
this.listener = listener;
tree.addEventListener('keypress', listener, false);
obj.sort();
obj.expandMatchParents();
this.sort();
this.expandMatchParents();
//Zotero.debug('Running callbacks in itemTreeView.setTree()', 4);
obj._runCallbacks();
this._runCallbacks();
if (obj._ownerDocument.defaultView.ZoteroPane_Local) {
obj._ownerDocument.defaultView.ZoteroPane_Local.clearItemsPaneMessage();
if (this._ownerDocument.defaultView.ZoteroPane_Local) {
this._ownerDocument.defaultView.ZoteroPane_Local.clearItemsPaneMessage();
}
// Select a queued item from selectItem()
if (obj._itemGroup && obj._itemGroup.itemToSelect) {
var item = obj._itemGroup.itemToSelect;
obj.selectItem(item['id'], item['expand']);
obj._itemGroup.itemToSelect = null;
if (this._itemGroup && this._itemGroup.itemToSelect) {
var item = this._itemGroup.itemToSelect;
this.selectItem(item['id'], item['expand']);
this._itemGroup.itemToSelect = null;
}
delete this._waitAfter;
Zotero.debug("Set tree in "+(Date.now()-start)+" ms");
Zotero.wait();
} catch(e) {
Zotero.logError(e);
}
}
/**
* Checks whether it's taken long enough to load the item pane that we should show a "loading"
* message. This should be called at semi-regular intervals throughout functions that consume a lot
* of time.
*/
Zotero.ItemTreeView.prototype.showLoadingMessageIfNecessary = function() {
if(this._waitAfter && Date.now() > this._waitAfter) {
Zotero.wait();
delete this._waitAfter;
}
this._ownerDocument.defaultView.setTimeout(paneLoader, 50, this);
}
@ -246,6 +263,10 @@ Zotero.ItemTreeView.prototype.refresh = function()
added++;
}
this._searchItemIDs[newRows[i].id] = true;
if(i % 100 === 0) {
this.showLoadingMessageIfNecessary();
}
}
// Add parents of matches if not matches themselves
@ -968,13 +989,14 @@ Zotero.ItemTreeView.prototype.sort = function(itemID)
// Cache primary values while sorting, since base-field-mapped getField()
// calls are relatively expensive
var cache = [];
var cache = {};
// Get the display field for a row (which might be a placeholder title)
function getField(row) {
var field;
var type = row.ref.itemTypeID;
if (columnField == 'title') {
var getField;
if (columnField == 'title') {
getField = function (row) {
var field;
var type = row.ref.itemTypeID;
switch (type) {
case 8: // letter
case 10: // interview
@ -986,24 +1008,29 @@ Zotero.ItemTreeView.prototype.sort = function(itemID)
field = row.getField(columnField, unformatted);
}
// Ignore some leading and trailing characters when sorting
field = Zotero.Items.getSortTitle(field);
return Zotero.Items.getSortTitle(field);
}
else {
field = row.getField(columnField, unformatted);
}
return field;
} else {
getField = function(row) row.getField(columnField, unformatted);
}
var includeTrashed = this._itemGroup.isTrash();
var i = 0, me = this;
function rowSort(a, b) {
if(i === 1000) {
me.showLoadingMessageIfNecessary();
i = 0;
}
i++;
var cmp, fieldA, fieldB;
var aItemID = a.ref.id;
var aItemID = a.id;
if (cache[aItemID]) {
fieldA = cache[aItemID];
}
var bItemID = b.ref.id;
var bItemID = b.id;
if (cache[bItemID]) {
fieldB = cache[bItemID];
}
@ -1069,14 +1096,14 @@ Zotero.ItemTreeView.prototype.sort = function(itemID)
}
}
if (columnField != 'firstCreator') {
if (columnField !== 'firstCreator') {
cmp = creatorSort(a, b);
if (cmp) {
return cmp;
}
}
if (columnField != 'date') {
if (columnField !== 'date') {
fieldA = a.getField('date', true).substr(0, 10);
fieldB = b.getField('date', true).substr(0, 10);
@ -1097,18 +1124,18 @@ Zotero.ItemTreeView.prototype.sort = function(itemID)
//
// Try sorting by first word in firstCreator field, since we already have it
//
var fieldA = firstCreatorSortCache[a.ref.id];
var fieldA = firstCreatorSortCache[a.id];
if (fieldA == undefined) {
var matches = Zotero.Items.getSortTitle(a.getField('firstCreator')).match(/^[^\s]+/);
var fieldA = matches ? matches[0] : '';
firstCreatorSortCache[a.ref.id] = fieldA;
firstCreatorSortCache[a.id] = fieldA;
}
var fieldB = firstCreatorSortCache[b.ref.id];
var fieldB = firstCreatorSortCache[b.id];
if (fieldB == undefined) {
var matches = Zotero.Items.getSortTitle(b.getField('firstCreator')).match(/^[^\s]+/);
var fieldB = matches ? matches[0] : '';
firstCreatorSortCache[b.ref.id] = fieldB;
firstCreatorSortCache[b.id] = fieldB;
}
if (!fieldA && !fieldB) {
@ -1271,10 +1298,6 @@ Zotero.ItemTreeView.prototype.sort = function(itemID)
return (a > b) ? -1 : (a < b) ? 1 : 0;
}
function reverseSort(a, b) {
return rowSort(a,b) * -1;
}
// Need to close all containers before sorting
var openItemIDs = this.saveOpenState(true);
@ -1287,7 +1310,7 @@ Zotero.ItemTreeView.prototype.sort = function(itemID)
}
if (order) {
var cmp = reverseSort(this._dataItems[i], this._dataItems[row]);
var cmp = -1*rowSort(this._dataItems[i], this._dataItems[row]);
}
else {
var cmp = rowSort(this._dataItems[i], this._dataItems[row]);
@ -1312,12 +1335,8 @@ Zotero.ItemTreeView.prototype.sort = function(itemID)
}
// Full sort
else {
if (order) {
this._dataItems.sort(rowSort);
}
else {
this._dataItems.sort(reverseSort);
}
this._dataItems.sort(rowSort);
if(!order) this._dataItems.reverse();
}
this._refreshHashMap();
@ -1471,7 +1490,7 @@ Zotero.ItemTreeView.prototype.getSelectedItems = function(asIDs)
this.selection.getRangeAt(i,start,end);
for (var j=start.value; j<=end.value; j++) {
if (asIDs) {
items.push(this._getItemAtRow(j).ref.id);
items.push(this._getItemAtRow(j).id);
}
else {
items.push(this._getItemAtRow(j).ref);
@ -1515,7 +1534,7 @@ Zotero.ItemTreeView.prototype.deleteSelection = function (force)
{
this.selection.getRangeAt(i,start,end);
for (var j=start.value; j<=end.value; j++)
ids.push(this._getItemAtRow(j).ref.id);
ids.push(this._getItemAtRow(j).id);
}
var itemGroup = this._itemGroup;
@ -2608,6 +2627,7 @@ Zotero.ItemTreeView.TreeRow = function(ref, level, isOpen)
this.ref = ref; //the item associated with this
this.level = level;
this.isOpen = isOpen;
this.id = ref.id;
}
Zotero.ItemTreeView.TreeRow.prototype.getField = function(field, unformatted)