diff --git a/chrome/content/zotero/xpcom/data/dataObject.js b/chrome/content/zotero/xpcom/data/dataObject.js index cef23e7e29..ec7ce06212 100644 --- a/chrome/content/zotero/xpcom/data/dataObject.js +++ b/chrome/content/zotero/xpcom/data/dataObject.js @@ -1275,10 +1275,6 @@ Zotero.DataObject.prototype._initErase = Zotero.Promise.method(function (env) { if (!env.options.skipEditCheck) this.editCheck(); - if (env.options.skipDeleteLog) { - env.notifierData[this.id].skipDeleteLog = true; - } - return true; }); @@ -1294,6 +1290,10 @@ Zotero.DataObject.prototype._finalizeErase = Zotero.Promise.coroutine(function* this.ObjectsClass.unload(env.deletedObjectIDs || this.id); }.bind(this)); + if (env.options.skipDeleteLog) { + env.notifierData[this.id].skipDeleteLog = true; + } + if (!env.options.skipNotifier) { Zotero.Notifier.queue( 'delete', diff --git a/chrome/content/zotero/xpcom/data/item.js b/chrome/content/zotero/xpcom/data/item.js index 9000ea67eb..b6c4fe10e0 100644 --- a/chrome/content/zotero/xpcom/data/item.js +++ b/chrome/content/zotero/xpcom/data/item.js @@ -4538,6 +4538,7 @@ Zotero.Item.prototype._eraseData = Zotero.Promise.coroutine(function* (env) { } // Regular item else { + // Delete child items let sql = "SELECT itemID FROM itemNotes WHERE parentItemID=?1 UNION " + "SELECT itemID FROM itemAttachments WHERE parentItemID=?1"; let toDelete = yield Zotero.DB.columnQueryAsync(sql, [this.id]); @@ -4550,6 +4551,11 @@ Zotero.Item.prototype._eraseData = Zotero.Promise.coroutine(function* (env) { } } + // Don't add non-syncing items to delete log + if (!Zotero.Sync.Data.Local.isSyncItem(this)) { + env.options.skipDeleteLog = true; + } + // Remove related-item relations pointing to this item var relatedItems = yield Zotero.Relations.getByPredicateAndObject( 'item', Zotero.Relations.relatedItemPredicate, Zotero.URI.getItemURI(this) diff --git a/chrome/content/zotero/xpcom/sync/syncLocal.js b/chrome/content/zotero/xpcom/sync/syncLocal.js index 7375c8233b..1c7aeebf84 100644 --- a/chrome/content/zotero/xpcom/sync/syncLocal.js +++ b/chrome/content/zotero/xpcom/sync/syncLocal.js @@ -547,6 +547,7 @@ Zotero.Sync.Data.Local = { + "LEFT JOIN itemAnnotations IAn ON (O.itemID=IAn.itemID)"; } sql += " WHERE libraryID=? AND synced=0"; + // Don't sync external annotations if (objectType == 'item') { sql += " AND (IAn.isExternal IS NULL OR IAN.isExternal=0)"; } @@ -581,6 +582,14 @@ Zotero.Sync.Data.Local = { }), + isSyncItem: function (item) { + if (item.itemType == 'annotation' && item.annotationIsExternal) { + return false; + } + return true; + }, + + // // Cache management // diff --git a/test/tests/syncEventListenersTest.js b/test/tests/syncEventListenersTest.js index 867dfb5037..2520d51dcd 100644 --- a/test/tests/syncEventListenersTest.js +++ b/test/tests/syncEventListenersTest.js @@ -1,6 +1,39 @@ "use strict"; describe("Zotero.Sync.EventListeners", function () { + describe("ChangeListener", function () { + it("should add items to sync delete log", async function () { + var item = await createDataObject('item'); + await item.eraseTx(); + assert.ok( + await Zotero.Sync.Data.Local.getDateDeleted('item', item.libraryID, item.key) + ); + }); + + it("shouldn't add items with `skipDeleteLog: true`", async function () { + var item = await createDataObject('item'); + await item.eraseTx({ + skipDeleteLog: true + }); + assert.isFalse( + await Zotero.Sync.Data.Local.getDateDeleted('item', item.libraryID, item.key) + ); + }); + + // Technically skipped in Zotero.DataObject._finalizeErase(), which sets skipDeleteLog + // based on the result of Sync.Data.Local.isSyncItem() + it("shouldn't add non-syncing items to sync delete log", async function () { + var attachment = await importFileAttachment('test.pdf'); + var annotation = await createAnnotation('image', attachment, { isExternal: true }); + await annotation.eraseTx(); + assert.isFalse( + await Zotero.Sync.Data.Local.getDateDeleted( + 'item', attachment.libraryID, annotation.key + ) + ); + }); + }); + describe("AutoSyncListener", function () { var originalTimeout;