diff --git a/chrome/content/zotero/xpcom/data/item.js b/chrome/content/zotero/xpcom/data/item.js index f9ef40539c..c44ec70a78 100644 --- a/chrome/content/zotero/xpcom/data/item.js +++ b/chrome/content/zotero/xpcom/data/item.js @@ -4006,6 +4006,7 @@ Zotero.Item.prototype.fromJSON = function (json) { } if (field == 'accessDate') { this.setField(field, val); + setFields[field] = true; } else { this[field] = val; @@ -4072,16 +4073,21 @@ Zotero.Item.prototype.fromJSON = function (json) { + this.libraryKey); continue; } - isValidForType[field] = Zotero.ItemFields.isValidForType( - Zotero.ItemFields.getFieldIDFromTypeAndBase(itemTypeID, fieldID) || fieldID, - this.itemTypeID - ); + // Convert to base-mapped field if necessary, so that setFields has the base-mapped field + // when it's checked for values from getUsedFields() below + let origFieldID = fieldID; + let origField = field; + fieldID = Zotero.ItemFields.getFieldIDFromTypeAndBase(itemTypeID, fieldID) || fieldID; + if (origFieldID != fieldID) { + field = Zotero.ItemFields.getName(fieldID); + } + isValidForType[field] = Zotero.ItemFields.isValidForType(fieldID, this.itemTypeID); if (!isValidForType[field]) { - Zotero.logError("Discarding invalid field '" + field + "' for type " + itemTypeID + Zotero.logError("Discarding invalid field '" + origField + "' for type " + itemTypeID + " for item " + this.libraryKey); continue; } - this.setField(field, json[field]); + this.setField(field, json[origField]); setFields[field] = true; } } @@ -4089,8 +4095,7 @@ Zotero.Item.prototype.fromJSON = function (json) { // Clear existing fields not specified var previousFields = this.getUsedFields(true); for (let field of previousFields) { - // Invalid fields will already have been cleared by the type change - if (!setFields[field] && isValidForType[field]) { + if (!setFields[field] && isValidForType[field] !== false) { this.setField(field, false); } } diff --git a/test/tests/itemTest.js b/test/tests/itemTest.js index 03cfe1f7ce..580b9e672d 100644 --- a/test/tests/itemTest.js +++ b/test/tests/itemTest.js @@ -1194,8 +1194,25 @@ describe("Zotero.Item", function () { }); }) }) - + describe("#fromJSON()", function () { + it("should clear missing fields", function* () { + var item = new Zotero.Item('book'); + item.setField('title', 'Test'); + item.setField('date', '2016'); + item.setField('accessDate', '2015-06-07T20:56:00Z'); + yield item.saveTx(); + var json = item.toJSON(); + // Remove fields, which should cause them to be cleared in fromJSON() + delete json.date; + delete json.accessDate; + + item.fromJSON(json); + assert.strictEqual(item.getField('title'), 'Test'); + assert.strictEqual(item.getField('date'), ''); + assert.strictEqual(item.getField('accessDate'), ''); + }); + it("should ignore unknown fields", function* () { var json = { itemType: "journalArticle",