Fix various issues with rapid UI/data changes due to asyncification
This commit is contained in:
parent
fc428f8e1b
commit
02a36eab9b
8 changed files with 69 additions and 42 deletions
|
@ -600,20 +600,18 @@
|
|||
|
||||
<method name="clearVisible">
|
||||
<body><![CDATA[
|
||||
return Zotero.spawn(function* () {
|
||||
var tagsToggleBox = this.id('tags-toggle');
|
||||
|
||||
var labels = Zotero.Utilities.xpath(tagsToggleBox, 'label[@selected="true"]');
|
||||
for (var i=0; i<labels.length; i++){
|
||||
var label = labels[i];
|
||||
label.setAttribute('selected', 'false');
|
||||
delete this.selection[label.value];
|
||||
}
|
||||
|
||||
if (this.onchange) {
|
||||
this.onchange();
|
||||
}
|
||||
}, this);
|
||||
var tagsToggleBox = this.id('tags-toggle');
|
||||
|
||||
var labels = Zotero.Utilities.xpath(tagsToggleBox, 'label[@selected="true"]');
|
||||
for (var i=0; i<labels.length; i++){
|
||||
var label = labels[i];
|
||||
label.setAttribute('selected', 'false');
|
||||
delete this.selection[label.value];
|
||||
}
|
||||
|
||||
if (this.onchange) {
|
||||
this.onchange();
|
||||
}
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
|
|
|
@ -93,7 +93,12 @@ var ZoteroOverlay = new function()
|
|||
prefBranch.clearUserPref('statusBarIcon');
|
||||
|
||||
// Add toolbar icon
|
||||
Services.scriptloader.loadSubScript("chrome://zotero/content/icon.js", {}, "UTF-8");
|
||||
try {
|
||||
Services.scriptloader.loadSubScript("chrome://zotero/content/icon.js", {}, "UTF-8");
|
||||
}
|
||||
catch (e) {
|
||||
Zotero.logError(e);
|
||||
}
|
||||
|
||||
// TODO: Add only when progress window is open
|
||||
document.getElementById('appcontent').addEventListener('mousemove', Zotero.ProgressWindowSet.updateTimers, false);
|
||||
|
|
|
@ -2392,7 +2392,7 @@ Zotero.CollectionTreeRow.prototype.getItems = Zotero.Promise.coroutine(function*
|
|||
if (!ids.length) {
|
||||
return []
|
||||
}
|
||||
return Zotero.Items.get(ids);
|
||||
return Zotero.Items.getAsync(ids);
|
||||
});
|
||||
|
||||
Zotero.CollectionTreeRow.prototype.getSearchResults = Zotero.Promise.coroutine(function* (asTempTable) {
|
||||
|
@ -2493,7 +2493,7 @@ Zotero.CollectionTreeRow.prototype.getSearchObject = Zotero.Promise.coroutine(fu
|
|||
*
|
||||
* @return {Promise}
|
||||
*/
|
||||
Zotero.CollectionTreeRow.prototype.getChildTags = Zotero.Promise.method(function () {
|
||||
Zotero.CollectionTreeRow.prototype.getChildTags = Zotero.Promise.coroutine(function* () {
|
||||
switch (this.type) {
|
||||
// TODO: implement?
|
||||
case 'share':
|
||||
|
@ -2502,8 +2502,8 @@ Zotero.CollectionTreeRow.prototype.getChildTags = Zotero.Promise.method(function
|
|||
case 'bucket':
|
||||
return false;
|
||||
}
|
||||
|
||||
return Zotero.Tags.getAllWithinSearchResults(this.getSearchResults(true));
|
||||
var results = yield this.getSearchResults(true);
|
||||
return Zotero.Tags.getAllWithinSearchResults(results);
|
||||
});
|
||||
|
||||
|
||||
|
|
|
@ -155,13 +155,11 @@ Zotero.Tags = new function() {
|
|||
/**
|
||||
* Get all tags within the items of a temporary table of search results
|
||||
*
|
||||
* @param {String|Promise<String>} tmpTable Temporary table with items to use
|
||||
* @param {String} tmpTable Temporary table with items to use
|
||||
* @param {Array} [types] Array of tag types to fetch
|
||||
* @return {Promise<Object>} Promise for object with tag data in API JSON format, keyed by tagID
|
||||
*/
|
||||
this.getAllWithinSearchResults = Zotero.Promise.coroutine(function* (tmpTable, types) {
|
||||
tmpTable = yield Zotero.Promise.resolve(tmpTable);
|
||||
|
||||
var sql = "SELECT DISTINCT name AS tag, type FROM itemTags "
|
||||
+ "JOIN tags USING (tagID) WHERE itemID IN "
|
||||
+ "(SELECT itemID FROM " + tmpTable + ") ";
|
||||
|
|
|
@ -64,10 +64,10 @@ Zotero.ItemTreeView.prototype.type = 'item';
|
|||
/**
|
||||
* Called by the tree itself
|
||||
*/
|
||||
Zotero.ItemTreeView.prototype.setTree = Zotero.Promise.coroutine(function* (treebox)
|
||||
Zotero.ItemTreeView.prototype.setTree = Zotero.serial(Zotero.Promise.coroutine(function* (treebox)
|
||||
{
|
||||
try {
|
||||
//Zotero.debug("Calling setTree()");
|
||||
Zotero.debug("Setting item tree");
|
||||
var start = Date.now();
|
||||
// Try to set the window document if not yet set
|
||||
if (treebox && !this._ownerDocument) {
|
||||
|
@ -85,7 +85,13 @@ Zotero.ItemTreeView.prototype.setTree = Zotero.Promise.coroutine(function* (tree
|
|||
}
|
||||
|
||||
if (!treebox) {
|
||||
Components.utils.reportError("Passed treebox empty in setTree()");
|
||||
Zotero.debug("Treebox not passed in setTree()", 2);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this._ownerDocument) {
|
||||
Zotero.debug("No owner document in setTree()", 2);
|
||||
return;
|
||||
}
|
||||
|
||||
this._treebox = treebox;
|
||||
|
@ -103,8 +109,6 @@ Zotero.ItemTreeView.prototype.setTree = Zotero.Promise.coroutine(function* (tree
|
|||
return;
|
||||
}
|
||||
|
||||
yield Zotero.DB.waitForTransaction();
|
||||
|
||||
yield this.refresh();
|
||||
|
||||
// Add a keypress listener for expand/collapse
|
||||
|
@ -235,10 +239,8 @@ Zotero.ItemTreeView.prototype.setTree = Zotero.Promise.coroutine(function* (tree
|
|||
tree._handleEnter = function () {};
|
||||
|
||||
yield this.sort();
|
||||
|
||||
yield this.expandMatchParents();
|
||||
|
||||
|
||||
if (this._ownerDocument.defaultView.ZoteroPane_Local) {
|
||||
this._ownerDocument.defaultView.ZoteroPane_Local.clearItemsPaneMessage();
|
||||
}
|
||||
|
@ -256,13 +258,14 @@ Zotero.ItemTreeView.prototype.setTree = Zotero.Promise.coroutine(function* (tree
|
|||
yield this._runListeners('load');
|
||||
}
|
||||
catch (e) {
|
||||
Zotero.debug(e, 1);
|
||||
Components.utils.reportError(e);
|
||||
if (this.onError) {
|
||||
this.onError(e);
|
||||
}
|
||||
throw e;
|
||||
};
|
||||
});
|
||||
}
|
||||
}));
|
||||
|
||||
|
||||
/**
|
||||
|
@ -331,27 +334,32 @@ Zotero.ItemTreeView.prototype.refresh = Zotero.serial(Zotero.Promise.coroutine(f
|
|||
var added = 0;
|
||||
|
||||
for (let i=0, len=newItems.length; i < len; i++) {
|
||||
let item = newItems[i];
|
||||
|
||||
// Only add regular items if sourcesOnly is set
|
||||
if (this._sourcesOnly && !newItems[i].isRegularItem()) {
|
||||
if (this._sourcesOnly && !item.isRegularItem()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Don't add child items directly (instead mark their parents for
|
||||
// inclusion below)
|
||||
let parentItemID = newItems[i].parentItemID;
|
||||
let parentItemID = item.parentItemID;
|
||||
if (parentItemID) {
|
||||
newSearchParentIDs[parentItemID] = true;
|
||||
}
|
||||
// Add top-level items
|
||||
else {
|
||||
yield item.loadItemData();
|
||||
yield item.loadCollections();
|
||||
|
||||
this._addRow(
|
||||
newRows,
|
||||
new Zotero.ItemTreeRow(newItems[i], 0, false),
|
||||
new Zotero.ItemTreeRow(item, 0, false),
|
||||
added + 1
|
||||
);
|
||||
added++;
|
||||
}
|
||||
newSearchItemIDs[newItems[i].id] = true;
|
||||
newSearchItemIDs[item.id] = true;
|
||||
}
|
||||
|
||||
// Add parents of matches if not matches themselves
|
||||
|
@ -925,9 +933,13 @@ Zotero.ItemTreeView.prototype.notify = Zotero.Promise.coroutine(function* (actio
|
|||
}
|
||||
|
||||
//this._treebox.endUpdateBatch();
|
||||
var promise = this._getItemSelectedPromise();
|
||||
if (madeChanges) {
|
||||
var promise = this._getItemSelectedPromise();
|
||||
}
|
||||
this.selection.selectEventsSuppressed = false;
|
||||
yield promise;
|
||||
if (madeChanges) {
|
||||
yield promise;
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
|
|
|
@ -1111,9 +1111,10 @@ var ZoteroPane = new function()
|
|||
|
||||
|
||||
this.onCollectionSelected = Zotero.Promise.coroutine(function* () {
|
||||
yield Zotero.DB.waitForTransaction();
|
||||
|
||||
var collectionTreeRow = this.getCollectionTreeRow();
|
||||
if (!collectionTreeRow) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.itemsView && this.itemsView.collectionTreeRow == collectionTreeRow) {
|
||||
Zotero.debug("Collection selection hasn't changed");
|
||||
|
@ -1131,7 +1132,12 @@ var ZoteroPane = new function()
|
|||
|
||||
// Clear quick search and tag selector when switching views
|
||||
document.getElementById('zotero-tb-search').value = "";
|
||||
yield document.getElementById('zotero-tag-selector').clearAll();
|
||||
|
||||
// XBL functions might not yet be available
|
||||
var tagSelector = document.getElementById('zotero-tag-selector');
|
||||
if (tagSelector.clearAll) {
|
||||
tagSelector.clearAll();
|
||||
}
|
||||
|
||||
// Not necessary with seltype="cell", which calls nsITreeView::isSelectable()
|
||||
/*if (collectionTreeRow.isSeparator()) {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
"use strict";
|
||||
|
||||
describe("Zotero.CollectionTreeView", function() {
|
||||
var win, collectionsView;
|
||||
|
||||
|
|
|
@ -1,11 +1,17 @@
|
|||
describe("Zotero.DB", function() {
|
||||
var tmpTable = "tmpDBTest";
|
||||
|
||||
before(function* () {
|
||||
this.timeout(5000);
|
||||
Zotero.debug("Waiting for DB activity to settle");
|
||||
yield Zotero.DB.waitForTransaction();
|
||||
yield Zotero.Promise.delay(1000);
|
||||
});
|
||||
beforeEach(function* () {
|
||||
Zotero.DB.queryAsync("DROP TABLE IF EXISTS " + tmpTable);
|
||||
yield Zotero.DB.queryAsync("DROP TABLE IF EXISTS " + tmpTable);
|
||||
});
|
||||
after(function* () {
|
||||
Zotero.DB.queryAsync("DROP TABLE IF EXISTS " + tmpTable);
|
||||
yield Zotero.DB.queryAsync("DROP TABLE IF EXISTS " + tmpTable);
|
||||
});
|
||||
|
||||
describe("#executeTransaction()", function () {
|
||||
|
|
Loading…
Add table
Reference in a new issue