From 8fc316f72796d8b7ff4e29e5f8bc3123d8d2a7e7 Mon Sep 17 00:00:00 2001 From: Dan Stillman Date: Mon, 14 Sep 2020 23:47:08 -0400 Subject: [PATCH] Fix potential error dragging to library that hasn't been loaded https://forums.zotero.org/discussion/85136/unable-to-copy-items-between-libraries Zotero.Relations.getByPredicateAndObject() is now async. --- .../zotero/import/mendeley/mendeleyImport.js | 18 +++++++++--------- chrome/content/zotero/xpcom/data/dataObject.js | 2 +- .../content/zotero/xpcom/data/dataObjects.js | 4 ++-- chrome/content/zotero/xpcom/data/item.js | 6 +++--- chrome/content/zotero/xpcom/data/relations.js | 6 +++--- chrome/content/zotero/xpcom/integration.js | 2 +- test/tests/relationsTest.js | 6 +++--- 7 files changed, 22 insertions(+), 22 deletions(-) diff --git a/chrome/content/zotero/import/mendeley/mendeleyImport.js b/chrome/content/zotero/import/mendeley/mendeleyImport.js index ad5f6037d9..f93b417234 100644 --- a/chrome/content/zotero/import/mendeley/mendeleyImport.js +++ b/chrome/content/zotero/import/mendeley/mendeleyImport.js @@ -271,7 +271,7 @@ Zotero_Import_Mendeley.prototype._saveCollections = async function (libraryID, j let collectionJSON = json[i]; // Check if the collection was previously imported - let collection = this._findExistingCollection( + let collection = await this._findExistingCollection( libraryID, collectionJSON, collectionJSON.parentCollection ? keyMap.get(collectionJSON.parentCollection) : null @@ -305,7 +305,7 @@ Zotero_Import_Mendeley.prototype._saveCollections = async function (libraryID, j }; -Zotero_Import_Mendeley.prototype._findExistingCollection = function (libraryID, collectionJSON, parentCollection) { +Zotero_Import_Mendeley.prototype._findExistingCollection = async function (libraryID, collectionJSON, parentCollection) { // Don't use existing collections if the import is creating a top-level collection if (this.createNewCollection || !collectionJSON.relations) { return false; @@ -314,7 +314,7 @@ Zotero_Import_Mendeley.prototype._findExistingCollection = function (libraryID, var predicate = 'mendeleyDB:remoteFolderUUID'; var uuid = collectionJSON.relations[predicate]; - var collections = Zotero.Relations.getByPredicateAndObject('collection', predicate, uuid) + var collections = await Zotero.Relations.getByPredicateAndObject('collection', predicate, uuid) .filter((c) => { if (c.libraryID != libraryID) { return false; @@ -829,7 +829,7 @@ Zotero_Import_Mendeley.prototype._saveItems = async function (libraryID, json) { let itemJSON = json[i]; // Check if the item has been previously imported - let item = this._findExistingItem(libraryID, itemJSON, lastExistingParentItem); + let item = await this._findExistingItem(libraryID, itemJSON, lastExistingParentItem); if (item) { if (item.isRegularItem()) { lastExistingParentItem = item; @@ -872,7 +872,7 @@ Zotero_Import_Mendeley.prototype._saveItems = async function (libraryID, json) { }; -Zotero_Import_Mendeley.prototype._findExistingItem = function (libraryID, itemJSON, existingParentItem) { +Zotero_Import_Mendeley.prototype._findExistingItem = async function (libraryID, itemJSON, existingParentItem) { var predicate; // @@ -936,7 +936,7 @@ Zotero_Import_Mendeley.prototype._findExistingItem = function (libraryID, itemJS var existingItem; predicate = 'mendeleyDB:documentUUID'; if (itemJSON.relations[predicate]) { - existingItem = this._getItemByRelation( + existingItem = await this._getItemByRelation( libraryID, predicate, itemJSON.relations[predicate] @@ -945,7 +945,7 @@ Zotero_Import_Mendeley.prototype._findExistingItem = function (libraryID, itemJS if (!existingItem) { predicate = 'mendeleyDB:remoteDocumentUUID'; if (itemJSON.relations[predicate]) { - existingItem = this._getItemByRelation( + existingItem = await this._getItemByRelation( libraryID, predicate, itemJSON.relations[predicate] @@ -962,8 +962,8 @@ Zotero_Import_Mendeley.prototype._findExistingItem = function (libraryID, itemJS } -Zotero_Import_Mendeley.prototype._getItemByRelation = function (libraryID, predicate, object) { - var items = Zotero.Relations.getByPredicateAndObject('item', predicate, object) +Zotero_Import_Mendeley.prototype._getItemByRelation = async function (libraryID, predicate, object) { + var items = await Zotero.Relations.getByPredicateAndObject('item', predicate, object) .filter(item => item.libraryID == libraryID && !item.deleted); if (!items.length) { return false; diff --git a/chrome/content/zotero/xpcom/data/dataObject.js b/chrome/content/zotero/xpcom/data/dataObject.js index 4d2d29f34b..8422db6680 100644 --- a/chrome/content/zotero/xpcom/data/dataObject.js +++ b/chrome/content/zotero/xpcom/data/dataObject.js @@ -495,7 +495,7 @@ Zotero.DataObject.prototype._getLinkedObject = Zotero.Promise.coroutine(function // Then try relations with this as an object if (bidirectional) { var thisURI = Zotero.URI['get' + this._ObjectType + 'URI'](this); - var objects = Zotero.Relations.getByPredicateAndObject( + let objects = yield Zotero.Relations.getByPredicateAndObject( this._objectType, predicate, thisURI ); for (let i = 0; i < objects.length; i++) { diff --git a/chrome/content/zotero/xpcom/data/dataObjects.js b/chrome/content/zotero/xpcom/data/dataObjects.js index 3d56c65d11..977f434b9c 100644 --- a/chrome/content/zotero/xpcom/data/dataObjects.js +++ b/chrome/content/zotero/xpcom/data/dataObjects.js @@ -617,7 +617,7 @@ Zotero.DataObjects.prototype._loadRelations = Zotero.Promise.coroutine(function* let objectURI = getURI(this); // Related items are bidirectional, so include any pointing to this object - let objects = Zotero.Relations.getByPredicateAndObject( + let objects = yield Zotero.Relations.getByPredicateAndObject( Zotero.Relations.relatedItemPredicate, objectURI ); for (let i = 0; i < objects.length; i++) { @@ -625,7 +625,7 @@ Zotero.DataObjects.prototype._loadRelations = Zotero.Promise.coroutine(function* } // Also include any owl:sameAs relations pointing to this object - objects = Zotero.Relations.getByPredicateAndObject( + objects = yield Zotero.Relations.getByPredicateAndObject( Zotero.Relations.linkedObjectPredicate, objectURI ); for (let i = 0; i < objects.length; i++) { diff --git a/chrome/content/zotero/xpcom/data/item.js b/chrome/content/zotero/xpcom/data/item.js index 9456e1e064..f8ed26c1d9 100644 --- a/chrome/content/zotero/xpcom/data/item.js +++ b/chrome/content/zotero/xpcom/data/item.js @@ -1517,7 +1517,7 @@ Zotero.Item.prototype._saveData = Zotero.Promise.coroutine(function* (env) { // If undeleting, remove any merge-tracking relations let predicate = Zotero.Relations.replacedItemPredicate; let thisURI = Zotero.URI.getItemURI(this); - let mergeItems = Zotero.Relations.getByPredicateAndObject( + let mergeItems = yield Zotero.Relations.getByPredicateAndObject( 'item', predicate, thisURI ); for (let mergeItem of mergeItems) { @@ -4172,12 +4172,12 @@ Zotero.Item.prototype._eraseData = Zotero.Promise.coroutine(function* (env) { } // Remove related-item relations pointing to this item - var relatedItems = Zotero.Relations.getByPredicateAndObject( + var relatedItems = yield Zotero.Relations.getByPredicateAndObject( 'item', Zotero.Relations.relatedItemPredicate, Zotero.URI.getItemURI(this) ); for (let relatedItem of relatedItems) { relatedItem.removeRelatedItem(this); - relatedItem.save({ + yield relatedItem.save({ skipDateModifiedUpdate: true, skipEditCheck: env.options.skipEditCheck }); diff --git a/chrome/content/zotero/xpcom/data/relations.js b/chrome/content/zotero/xpcom/data/relations.js index 20458907e6..c830091fb1 100644 --- a/chrome/content/zotero/xpcom/data/relations.js +++ b/chrome/content/zotero/xpcom/data/relations.js @@ -121,9 +121,9 @@ Zotero.Relations = new function () { * @param {String} objectType - Type of relation to search for (e.g., 'item') * @param {String} predicate * @param {String} object - * @return {Zotero.DataObject[]} + * @return {Promise} */ - this.getByPredicateAndObject = function (objectType, predicate, object) { + this.getByPredicateAndObject = async function (objectType, predicate, object) { var objectsClass = Zotero.DataObjectUtilities.getObjectsClassForObjectType(objectType); if (predicate) { predicate = this._getPrefixAndValue(predicate).join(':'); @@ -135,7 +135,7 @@ Zotero.Relations = new function () { if (!o || !o[predicateID] || !o[predicateID][object]) { return []; } - return objectsClass.get(Array.from(o[predicateID][object].values())); + return objectsClass.getAsync(Array.from(o[predicateID][object].values())); }; diff --git a/chrome/content/zotero/xpcom/integration.js b/chrome/content/zotero/xpcom/integration.js index 06a41c8848..9b5cdca6f5 100644 --- a/chrome/content/zotero/xpcom/integration.js +++ b/chrome/content/zotero/xpcom/integration.js @@ -2307,7 +2307,7 @@ Zotero.Integration.URIMap.prototype.getZoteroItemForURIs = Zotero.Promise.corout } catch(e) {} // Try merged item mapping - var replacer = Zotero.Relations.getByPredicateAndObject( + var replacer = yield Zotero.Relations.getByPredicateAndObject( 'item', Zotero.Relations.replacedItemPredicate, uri ); if (replacer.length && !replacer[0].deleted) { diff --git a/test/tests/relationsTest.js b/test/tests/relationsTest.js index 91b587d3ad..63a8ddd7dc 100644 --- a/test/tests/relationsTest.js +++ b/test/tests/relationsTest.js @@ -2,7 +2,7 @@ describe("Zotero.Relations", function () { describe("#getByPredicateAndObject()", function () { - it("should return items matching predicate and object", function* () { + it("should return items matching predicate and object", async function () { var item = createUnsavedDataObject('item'); item.setRelations({ "dc:relation": [ @@ -13,8 +13,8 @@ describe("Zotero.Relations", function () { "http://zotero.org/groups/1/items/GSMRRSSM" ] }) - yield item.saveTx(); - var objects = Zotero.Relations.getByPredicateAndObject( + await item.saveTx(); + var objects = await Zotero.Relations.getByPredicateAndObject( 'item', 'owl:sameAs', 'http://zotero.org/groups/1/items/SRRMGSRM' ); assert.lengthOf(objects, 1);