Fixes #728, Tag selector refreshing
This commit is contained in:
parent
cbbdebc5b7
commit
2bd246e2ea
|
@ -132,7 +132,7 @@
|
|||
if (!this._scope[tag.tag]) {
|
||||
this._scope[tag.tag] = [];
|
||||
}
|
||||
this._scope[tag.tag].push(tag.type);
|
||||
this._scope[tag.tag].push(tag.type || 0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -174,7 +174,11 @@
|
|||
<![CDATA[
|
||||
this._initialized = true;
|
||||
this.selection = {};
|
||||
this._notifierID = Zotero.Notifier.registerObserver(this, ['collection-item', 'item-tag', 'tag', 'setting'], 'tagSelector');
|
||||
this._notifierID = Zotero.Notifier.registerObserver(
|
||||
this,
|
||||
['collection-item', 'item', 'item-tag', 'tag', 'setting'],
|
||||
'tagSelector'
|
||||
);
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
@ -455,12 +459,32 @@
|
|||
this.id('no-tags-deck').selectedIndex = 1;
|
||||
|
||||
Zotero.debug("Loaded tag selector in " + (new Date - t) + " ms");
|
||||
|
||||
var event = new Event('refresh');
|
||||
this.dispatchEvent(event);
|
||||
}, this);
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
|
||||
<method name="getVisible">
|
||||
<body><![CDATA[
|
||||
var tagsBox = this.id('tags-toggle');
|
||||
var labels = tagsBox.getElementsByTagName('label');
|
||||
var visible = [];
|
||||
for (let i = 0; i < labels.length; i++){
|
||||
let label = labels[i];
|
||||
if (label.getAttribute('hidden') != 'true'
|
||||
&& label.getAttribute('inScope') == 'true') {
|
||||
visible.push(label.value);
|
||||
}
|
||||
}
|
||||
return visible;
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
|
||||
<method name="getNumSelected">
|
||||
<body>
|
||||
<![CDATA[
|
||||
|
@ -522,10 +546,15 @@
|
|||
}
|
||||
}
|
||||
|
||||
// Ignore item events other than 'trash'
|
||||
if (type == 'item' && event != 'trash') {
|
||||
return;
|
||||
}
|
||||
|
||||
var selectionChanged = false;
|
||||
|
||||
// If a selected tag no longer exists, deselect it
|
||||
if (event == 'delete' || event == 'modify') {
|
||||
if (event == 'delete' || event == 'trash' || event == 'modify') {
|
||||
// TODO: necessary, or just use notifier value?
|
||||
this._tags = yield Zotero.Tags.getAll(this.libraryID, this._types);
|
||||
|
||||
|
|
|
@ -53,7 +53,8 @@ Zotero.CollectionTreeView = function()
|
|||
'trash',
|
||||
'bucket'
|
||||
],
|
||||
'collectionTreeView'
|
||||
'collectionTreeView',
|
||||
25
|
||||
);
|
||||
this._containerState = {};
|
||||
this._duplicateLibraries = [];
|
||||
|
@ -2091,7 +2092,7 @@ Zotero.CollectionTreeCache = {
|
|||
"lastSearch":null,
|
||||
"lastResults":null,
|
||||
|
||||
"clear": Zotero.Promise.coroutine(function* () {
|
||||
"clear": function () {
|
||||
this.lastTreeRow = null;
|
||||
this.lastSearch = null;
|
||||
if(this.lastTempTable) {
|
||||
|
@ -2102,7 +2103,7 @@ Zotero.CollectionTreeCache = {
|
|||
}
|
||||
this.lastTempTable = null;
|
||||
this.lastResults = null;
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
Zotero.CollectionTreeRow = function(type, ref, level, isOpen)
|
||||
|
@ -2306,8 +2307,8 @@ Zotero.CollectionTreeRow.prototype.getItems = Zotero.Promise.coroutine(function*
|
|||
});
|
||||
|
||||
Zotero.CollectionTreeRow.prototype.getSearchResults = Zotero.Promise.coroutine(function* (asTempTable) {
|
||||
if(Zotero.CollectionTreeCache.lastTreeRow !== this) {
|
||||
yield Zotero.CollectionTreeCache.clear();
|
||||
if (Zotero.CollectionTreeCache.lastTreeRow && Zotero.CollectionTreeCache.lastTreeRow !== this) {
|
||||
Zotero.CollectionTreeCache.clear();
|
||||
}
|
||||
|
||||
if(!Zotero.CollectionTreeCache.lastResults) {
|
||||
|
@ -2332,7 +2333,7 @@ Zotero.CollectionTreeRow.prototype.getSearchResults = Zotero.Promise.coroutine(f
|
|||
*/
|
||||
Zotero.CollectionTreeRow.prototype.getSearchObject = Zotero.Promise.coroutine(function* () {
|
||||
if(Zotero.CollectionTreeCache.lastTreeRow !== this) {
|
||||
yield Zotero.CollectionTreeCache.clear();
|
||||
Zotero.CollectionTreeCache.clear();
|
||||
}
|
||||
|
||||
if(Zotero.CollectionTreeCache.lastSearch) {
|
||||
|
@ -2417,15 +2418,15 @@ Zotero.CollectionTreeRow.prototype.getChildTags = Zotero.Promise.coroutine(funct
|
|||
});
|
||||
|
||||
|
||||
Zotero.CollectionTreeRow.prototype.setSearch = Zotero.Promise.coroutine(function* (searchText) {
|
||||
yield Zotero.CollectionTreeCache.clear();
|
||||
Zotero.CollectionTreeRow.prototype.setSearch = function (searchText) {
|
||||
Zotero.CollectionTreeCache.clear();
|
||||
this.searchText = searchText;
|
||||
});
|
||||
}
|
||||
|
||||
Zotero.CollectionTreeRow.prototype.setTags = Zotero.Promise.coroutine(function* (tags) {
|
||||
yield Zotero.CollectionTreeCache.clear();
|
||||
Zotero.CollectionTreeRow.prototype.setTags = function (tags) {
|
||||
Zotero.CollectionTreeCache.clear();
|
||||
this.tags = tags;
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns TRUE if saved search, quicksearch or tag filter
|
||||
|
|
|
@ -54,7 +54,10 @@ Zotero.ItemTreeView = function (collectionTreeRow, sourcesOnly) {
|
|||
this._refreshPromise = Zotero.Promise.resolve();
|
||||
|
||||
this._unregisterID = Zotero.Notifier.registerObserver(
|
||||
this, ['item', 'collection-item', 'item-tag', 'share-items', 'bucket'], 'itemTreeView'
|
||||
this,
|
||||
['item', 'collection-item', 'item-tag', 'share-items', 'bucket'],
|
||||
'itemTreeView',
|
||||
50
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -277,7 +280,7 @@ Zotero.ItemTreeView.prototype.setTree = Zotero.serial(Zotero.Promise.coroutine(f
|
|||
* (doesn't call the tree.invalidate methods, etc.)
|
||||
*/
|
||||
Zotero.ItemTreeView.prototype.refresh = Zotero.serial(Zotero.Promise.coroutine(function* () {
|
||||
Zotero.debug('Refreshing items list');
|
||||
Zotero.debug('Refreshing items list for ' + this.id);
|
||||
//if(!Zotero.ItemTreeView._haveCachedFields) yield Zotero.Promise.resolve();
|
||||
|
||||
var cacheFields = ['title', 'date'];
|
||||
|
@ -455,6 +458,7 @@ Zotero.ItemTreeView.prototype.notify = Zotero.Promise.coroutine(function* (actio
|
|||
var collectionTreeRow = this.collectionTreeRow;
|
||||
|
||||
var madeChanges = false;
|
||||
var refreshed = false;
|
||||
var sort = false;
|
||||
|
||||
var savedSelection = this.getSelectedItems(true);
|
||||
|
@ -495,16 +499,19 @@ Zotero.ItemTreeView.prototype.notify = Zotero.Promise.coroutine(function* (actio
|
|||
if (type == 'share-items') {
|
||||
if (collectionTreeRow.isShare()) {
|
||||
yield this.refresh();
|
||||
refreshed = true;
|
||||
}
|
||||
}
|
||||
else if (type == 'bucket') {
|
||||
if (collectionTreeRow.isBucket()) {
|
||||
yield this.refresh();
|
||||
refreshed = true;
|
||||
}
|
||||
}
|
||||
else if (type == 'publications') {
|
||||
if (collectionTreeRow.isPublications()) {
|
||||
yield this.refresh();
|
||||
refreshed = true;
|
||||
}
|
||||
}
|
||||
// If refreshing a single item, clear caches and then unselect and reselect row
|
||||
|
@ -567,6 +574,7 @@ Zotero.ItemTreeView.prototype.notify = Zotero.Promise.coroutine(function* (actio
|
|||
if (collectionTreeRow.isDuplicates()) {
|
||||
previousRow = this._rowMap[ids[0]];
|
||||
yield this.refresh();
|
||||
refreshed = true;
|
||||
madeChanges = true;
|
||||
sort = true;
|
||||
}
|
||||
|
@ -630,6 +638,7 @@ Zotero.ItemTreeView.prototype.notify = Zotero.Promise.coroutine(function* (actio
|
|||
if (collectionTreeRow.isTrash() || collectionTreeRow.isSearch())
|
||||
{
|
||||
yield this.refresh();
|
||||
refreshed = true;
|
||||
madeChanges = true;
|
||||
sort = true;
|
||||
}
|
||||
|
@ -741,6 +750,7 @@ Zotero.ItemTreeView.prototype.notify = Zotero.Promise.coroutine(function* (actio
|
|||
// In some modes, just re-run search
|
||||
if (collectionTreeRow.isSearch() || collectionTreeRow.isTrash() || collectionTreeRow.isUnfiled()) {
|
||||
yield this.refresh();
|
||||
refreshed = true;
|
||||
madeChanges = true;
|
||||
sort = true;
|
||||
}
|
||||
|
@ -792,6 +802,11 @@ Zotero.ItemTreeView.prototype.notify = Zotero.Promise.coroutine(function* (actio
|
|||
|
||||
if(madeChanges)
|
||||
{
|
||||
// If we made individual changes, we have to clear the cache
|
||||
if (!refreshed) {
|
||||
Zotero.CollectionTreeCache.clear();
|
||||
}
|
||||
|
||||
var singleSelect = false;
|
||||
// If adding a single top-level item and this is the active window, select it
|
||||
if (action == 'add' && activeWindow) {
|
||||
|
@ -1819,7 +1834,6 @@ Zotero.ItemTreeView.prototype.deleteSelection = Zotero.Promise.coroutine(functio
|
|||
ids.push(this.getRow(j).id);
|
||||
}
|
||||
|
||||
Zotero.CollectionTreeCache.clear();
|
||||
var collectionTreeRow = this.collectionTreeRow;
|
||||
|
||||
if (collectionTreeRow.isBucket()) {
|
||||
|
@ -1867,8 +1881,6 @@ Zotero.ItemTreeView.prototype.setFilter = Zotero.Promise.coroutine(function* (ty
|
|||
|
||||
//this._treebox.endUpdateBatch();
|
||||
this.selection.selectEventsSuppressed = false;
|
||||
|
||||
yield this._runListeners('load');
|
||||
});
|
||||
|
||||
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
***** END LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
Zotero.Notifier = new function(){
|
||||
var _observers = {};
|
||||
var _disabled = false;
|
||||
|
@ -35,9 +37,6 @@ Zotero.Notifier = new function(){
|
|||
var _locked = false;
|
||||
var _queue = [];
|
||||
|
||||
this.registerObserver = registerObserver;
|
||||
this.unregisterObserver = unregisterObserver;
|
||||
this.untrigger = untrigger;
|
||||
this.begin = begin;
|
||||
this.reset = reset;
|
||||
this.disable = disable;
|
||||
|
@ -45,13 +44,13 @@ Zotero.Notifier = new function(){
|
|||
this.isEnabled = isEnabled;
|
||||
|
||||
|
||||
function registerObserver(ref, types, id) {
|
||||
this.registerObserver = function (ref, types, id, priority) {
|
||||
if (types){
|
||||
types = Zotero.flattenArguments(types);
|
||||
|
||||
for (var i=0; i<types.length; i++){
|
||||
if (_types.indexOf(types[i]) == -1){
|
||||
throw new Error('Invalid type ' + types[i] + ' in registerObserver()');
|
||||
throw new Error("Invalid type '" + types[i] + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -70,16 +69,23 @@ Zotero.Notifier = new function(){
|
|||
}
|
||||
while (_observers[hash]);
|
||||
|
||||
Zotero.debug('Registering observer for '
|
||||
+ (types ? '[' + types.join() + ']' : 'all types')
|
||||
+ ' in notifier with hash ' + hash + "'", 4);
|
||||
_observers[hash] = {ref: ref, types: types};
|
||||
var msg = "Registering observer '" + hash + "' for "
|
||||
+ (types ? '[' + types.join() + ']' : 'all types');
|
||||
if (priority) {
|
||||
msg += " with priority " + priority;
|
||||
}
|
||||
Zotero.debug(msg);
|
||||
_observers[hash] = {
|
||||
ref: ref,
|
||||
types: types,
|
||||
priority: priority || false
|
||||
};
|
||||
return hash;
|
||||
}
|
||||
|
||||
function unregisterObserver(hash){
|
||||
Zotero.debug("Unregistering observer in notifier with hash '" + hash + "'", 4);
|
||||
delete _observers[hash];
|
||||
this.unregisterObserver = function (id) {
|
||||
Zotero.debug("Unregistering observer in notifier with id '" + id + "'", 4);
|
||||
delete _observers[id];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -116,7 +122,7 @@ Zotero.Notifier = new function(){
|
|||
Zotero.debug("Notifier.trigger('" + event + "', '" + type + "', " + '[' + ids.join() + '], ' + extraData + ')'
|
||||
+ (queue ? " queued" : " called " + "[observers: " + Object.keys(_observers).length + "]"));
|
||||
if (extraData) {
|
||||
Zotero.debug("EXTRA DATA:");
|
||||
Zotero.debug("Extra data:");
|
||||
Zotero.debug(extraData);
|
||||
}
|
||||
|
||||
|
@ -138,7 +144,6 @@ Zotero.Notifier = new function(){
|
|||
|
||||
// Merge extraData keys
|
||||
if (extraData) {
|
||||
Zotero.debug("ADDING EXTRA DATA");
|
||||
// If just a single id, extra data can be keyed by id or passed directly
|
||||
if (ids.length == 1) {
|
||||
let id = ids[0];
|
||||
|
@ -159,25 +164,24 @@ Zotero.Notifier = new function(){
|
|||
return true;
|
||||
}
|
||||
|
||||
for (var i in _observers){
|
||||
Zotero.debug("Calling notify() with " + event + "/" + type + " on observer with hash '" + i + "'", 4);
|
||||
var order = _getObserverOrder(type);
|
||||
for (let id of order) {
|
||||
Zotero.debug("Calling notify() with " + event + "/" + type
|
||||
+ " on observer with id '" + id + "'", 4);
|
||||
|
||||
if (!_observers[i]) {
|
||||
if (!_observers[id]) {
|
||||
Zotero.debug("Observer no longer exists");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Find observers that handle notifications for this type (or all types)
|
||||
if (!_observers[i].types || _observers[i].types.indexOf(type)!=-1){
|
||||
// Catch exceptions so all observers get notified even if
|
||||
// one throws an error
|
||||
try {
|
||||
yield Zotero.Promise.resolve(_observers[i].ref.notify(event, type, ids, extraData));
|
||||
}
|
||||
catch (e) {
|
||||
Zotero.debug(e);
|
||||
Components.utils.reportError(e);
|
||||
}
|
||||
// Catch exceptions so all observers get notified even if
|
||||
// one throws an error
|
||||
try {
|
||||
yield Zotero.Promise.resolve(_observers[id].ref.notify(event, type, ids, extraData));
|
||||
}
|
||||
catch (e) {
|
||||
Zotero.debug(e);
|
||||
Components.utils.reportError(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -185,7 +189,33 @@ Zotero.Notifier = new function(){
|
|||
});
|
||||
|
||||
|
||||
function untrigger(event, type, ids) {
|
||||
/**
|
||||
* Get order of observer by priority, with lower numbers having higher priority.
|
||||
* If an observer doesn't have a priority, sort it last.
|
||||
*/
|
||||
function _getObserverOrder(type) {
|
||||
var order = [];
|
||||
for (let i in _observers) {
|
||||
// Skip observers that don't handle notifications for this type (or all types)
|
||||
if (_observers[i].types && _observers[i].types.indexOf(type) == -1) {
|
||||
continue;
|
||||
}
|
||||
order.push({
|
||||
id: i,
|
||||
priority: _observers[i].priority || false
|
||||
});
|
||||
}
|
||||
order.sort((a, b) => {
|
||||
if (a.priority === false && b.priority === false) return 0;
|
||||
if (a.priority === false) return 1;
|
||||
if (b.priority === false) return -1;
|
||||
return a.priority - b.priority;
|
||||
});
|
||||
return order.map(o => o.id);
|
||||
}
|
||||
|
||||
|
||||
this.untrigger = function (event, type, ids) {
|
||||
if (!_inTransaction) {
|
||||
throw ("Zotero.Notifier.untrigger() called with no active event queue")
|
||||
}
|
||||
|
|
|
@ -1128,8 +1128,8 @@ var ZoteroPane = new function()
|
|||
});
|
||||
if (deferred.promise.isPending()) {
|
||||
Zotero.debug("Waiting for items view " + this.itemsView.id + " to finish loading");
|
||||
yield deferred.promise;
|
||||
}
|
||||
yield deferred.promise;
|
||||
|
||||
this.itemsView.unregister();
|
||||
document.getElementById('zotero-items-tree').view = this.itemsView = null;
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
describe("Zotero.CollectionTreeView", function() {
|
||||
var win, collectionsView;
|
||||
|
||||
// Load Zotero pane and select library
|
||||
before(function* () {
|
||||
win = yield loadZoteroPane();
|
||||
collectionsView = win.ZoteroPane.collectionsView;
|
||||
|
@ -140,13 +139,13 @@ describe("Zotero.CollectionTreeView", function() {
|
|||
var collection = new Zotero.Collection;
|
||||
collection.name = "Test";
|
||||
var collectionID = yield collection.saveTx();
|
||||
var cv = win.ZoteroPane.collectionsView;
|
||||
|
||||
var search = new Zotero.Search;
|
||||
search.name = "A Test Search";
|
||||
search.addCondition('title', 'contains', 'test');
|
||||
var searchID = yield search.saveTx();
|
||||
|
||||
var cv = win.ZoteroPane.collectionsView;
|
||||
var collectionRow = cv._rowMap["C" + collectionID];
|
||||
var searchRow = cv._rowMap["S" + searchID];
|
||||
var duplicatesRow = cv._rowMap["D" + Zotero.Libraries.userLibraryID];
|
||||
|
|
145
test/tests/tagSelectorTest.js
Normal file
145
test/tests/tagSelectorTest.js
Normal file
|
@ -0,0 +1,145 @@
|
|||
"use strict";
|
||||
|
||||
describe("Tag Selector", function () {
|
||||
var win, doc, collectionsView;
|
||||
|
||||
before(function* () {
|
||||
win = yield loadZoteroPane();
|
||||
doc = win.document;
|
||||
collectionsView = win.ZoteroPane.collectionsView;
|
||||
|
||||
// Wait for things to settle
|
||||
yield Zotero.Promise.delay(100);
|
||||
});
|
||||
after(function () {
|
||||
win.close();
|
||||
});
|
||||
|
||||
function waitForTagSelector() {
|
||||
var deferred = Zotero.Promise.defer();
|
||||
var tagSelector = doc.getElementById('zotero-tag-selector');
|
||||
var onRefresh = function (event) {
|
||||
tagSelector.removeEventListener('refresh', onRefresh);
|
||||
deferred.resolve();
|
||||
}
|
||||
tagSelector.addEventListener('refresh', onRefresh);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
describe("#notify()", function () {
|
||||
it("should add a tag when added to an item in the current view", function* () {
|
||||
var promise, tagSelector;
|
||||
|
||||
if (collectionsView.selection.currentIndex != 0) {
|
||||
promise = waitForTagSelector();
|
||||
yield collectionsView.selectLibrary();
|
||||
yield promise;
|
||||
}
|
||||
|
||||
// Add item with tag to library root
|
||||
var item = createUnsavedDataObject('item');
|
||||
item.setTags([
|
||||
{
|
||||
tag: 'A'
|
||||
}
|
||||
]);
|
||||
promise = waitForTagSelector();
|
||||
yield item.saveTx();
|
||||
yield promise;
|
||||
|
||||
// Tag selector should have at least one tag
|
||||
tagSelector = doc.getElementById('zotero-tag-selector');
|
||||
assert.isAbove(tagSelector.getVisible().length, 0);
|
||||
|
||||
// Add collection
|
||||
promise = waitForTagSelector();
|
||||
var collection = yield createDataObject('collection');
|
||||
yield promise;
|
||||
|
||||
// Tag selector should be empty in new collection
|
||||
tagSelector = doc.getElementById('zotero-tag-selector');
|
||||
assert.equal(tagSelector.getVisible().length, 0);
|
||||
|
||||
// Add item with tag to collection
|
||||
var item = createUnsavedDataObject('item');
|
||||
item.setTags([
|
||||
{
|
||||
tag: 'B'
|
||||
}
|
||||
]);
|
||||
item.setCollections([collection.id]);
|
||||
promise = waitForTagSelector()
|
||||
yield item.saveTx();
|
||||
yield promise;
|
||||
|
||||
// Tag selector should show the new item's tag
|
||||
tagSelector = doc.getElementById('zotero-tag-selector');
|
||||
assert.equal(tagSelector.getVisible().length, 1);
|
||||
})
|
||||
|
||||
it("should remove a tag when an item is removed from a collection", function* () {
|
||||
// Add collection
|
||||
var promise = waitForTagSelector();
|
||||
var collection = yield createDataObject('collection');
|
||||
yield promise;
|
||||
|
||||
// Add item with tag to collection
|
||||
var item = createUnsavedDataObject('item');
|
||||
item.setTags([
|
||||
{
|
||||
tag: 'A'
|
||||
}
|
||||
]);
|
||||
item.setCollections([collection.id]);
|
||||
promise = waitForTagSelector()
|
||||
yield item.saveTx();
|
||||
yield promise;
|
||||
|
||||
// Tag selector should show the new item's tag
|
||||
var tagSelector = doc.getElementById('zotero-tag-selector');
|
||||
assert.equal(tagSelector.getVisible().length, 1);
|
||||
|
||||
item.setCollections();
|
||||
promise = waitForTagSelector();
|
||||
yield item.saveTx();
|
||||
yield promise;
|
||||
|
||||
// Tag selector shouldn't show the removed item's tag
|
||||
tagSelector = doc.getElementById('zotero-tag-selector');
|
||||
assert.equal(tagSelector.getVisible().length, 0);
|
||||
})
|
||||
|
||||
it("should remove a tag when an item in a collection is moved to the trash", function* () {
|
||||
// Add collection
|
||||
var promise = waitForTagSelector();
|
||||
var collection = yield createDataObject('collection');
|
||||
yield promise;
|
||||
|
||||
// Add item with tag to collection
|
||||
var item = createUnsavedDataObject('item');
|
||||
item.setTags([
|
||||
{
|
||||
tag: 'A'
|
||||
}
|
||||
]);
|
||||
item.setCollections([collection.id]);
|
||||
promise = waitForTagSelector()
|
||||
yield item.saveTx();
|
||||
yield promise;
|
||||
|
||||
// Tag selector should show the new item's tag
|
||||
var tagSelector = doc.getElementById('zotero-tag-selector');
|
||||
assert.equal(tagSelector.getVisible().length, 1);
|
||||
|
||||
// Move item to trash
|
||||
item.deleted = true;
|
||||
promise = waitForTagSelector();
|
||||
yield item.saveTx();
|
||||
yield promise;
|
||||
|
||||
// Tag selector shouldn't show the deleted item's tag
|
||||
tagSelector = doc.getElementById('zotero-tag-selector');
|
||||
assert.equal(tagSelector.getVisible().length, 0);
|
||||
})
|
||||
})
|
||||
})
|
Loading…
Reference in New Issue
Block a user