Item.fromJSON(): Dedupe invalid-for-type fields when storing in Extra
3de54455f6
removed redundant base-mapped fields when a valid-for-type
field was also set, but that still left duplicate fields in Extra when a
valid field wasn't set. This will happen until translators (most notably
Embedded Metadata) are fixed to stop setting redundant fields.
https://forums.zotero.org/discussion/81262/translator-error-sage-lots-of-extra-data-in-extra
This commit is contained in:
parent
11caa1b719
commit
b2bf60e1d7
2 changed files with 119 additions and 1 deletions
|
@ -4362,7 +4362,7 @@ Zotero.Item.prototype.fromJSON = function (json, options = {}) {
|
||||||
// try to save multiple versions of base-mapped fields, which they shouldn't need to do.
|
// try to save multiple versions of base-mapped fields, which they shouldn't need to do.
|
||||||
//
|
//
|
||||||
// https://github.com/zotero/zotero/issues/1504#issuecomment-572415083
|
// https://github.com/zotero/zotero/issues/1504#issuecomment-572415083
|
||||||
if (extraFields.size) {
|
if (!strict && extraFields.size) {
|
||||||
for (let field of setFields.keys()) {
|
for (let field of setFields.keys()) {
|
||||||
let baseField;
|
let baseField;
|
||||||
if (Zotero.ItemFields.isBaseField(field)) {
|
if (Zotero.ItemFields.isBaseField(field)) {
|
||||||
|
@ -4385,6 +4385,52 @@ Zotero.Item.prototype.fromJSON = function (json, options = {}) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Deduplicate remaining Extra fields
|
||||||
|
//
|
||||||
|
// For each invalid-for-type base field, remove any mapped fields with the same value
|
||||||
|
let baseFields = [];
|
||||||
|
for (let field of extraFields.keys()) {
|
||||||
|
if (Zotero.ItemFields.getID(field) && Zotero.ItemFields.isBaseField(field)) {
|
||||||
|
baseFields.push(field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (let baseField of baseFields) {
|
||||||
|
let value = extraFields.get(baseField);
|
||||||
|
let mappedFieldNames = Zotero.ItemFields.getTypeFieldsFromBase(baseField, true);
|
||||||
|
for (let mappedField of mappedFieldNames) {
|
||||||
|
if (extraFields.has(mappedField) && extraFields.get(mappedField) === value) {
|
||||||
|
Zotero.warn(`Removing redundant Extra field '${mappedField}' for item `
|
||||||
|
+ this.libraryKey);
|
||||||
|
extraFields.delete(mappedField);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Special handling for Type fields, since Type isn't a base field and therefore isn't set
|
||||||
|
// in translators that are doing this
|
||||||
|
if (!extraFields.has('type')) {
|
||||||
|
let typeFieldNames = Zotero.ItemFields.getTypeFieldsFromBase('type', true)
|
||||||
|
// This is actually 'medium' but as of 2/2020 the Embedded Metadata translator
|
||||||
|
// assigns it along with the other 'type' fields.
|
||||||
|
.concat('audioFileType');
|
||||||
|
let typeValue = false;
|
||||||
|
for (let typeFieldName of typeFieldNames) {
|
||||||
|
let value = extraFields.get(typeFieldName);
|
||||||
|
if (value !== undefined) {
|
||||||
|
if (typeValue === false) {
|
||||||
|
typeValue = value;
|
||||||
|
extraFields.set('type', value);
|
||||||
|
}
|
||||||
|
if (typeValue == value) {
|
||||||
|
Zotero.warn(`Removing redundant Extra field '${typeFieldName}' for item `
|
||||||
|
+ this.libraryKey);
|
||||||
|
extraFields.delete(typeFieldName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setField('extra', Zotero.Utilities.Internal.combineExtraFields(extra, extraFields));
|
this.setField('extra', Zotero.Utilities.Internal.combineExtraFields(extra, extraFields));
|
||||||
|
|
|
@ -1885,6 +1885,78 @@ describe("Zotero.Item", function () {
|
||||||
assert.equal(item.getField('label'), 'B');
|
assert.equal(item.getField('label'), 'B');
|
||||||
assert.equal(item.getField('extra'), 'Foo: D');
|
assert.equal(item.getField('extra'), 'Foo: D');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should remove invalid-for-type base-mapped fields with same values and use base field if not present when storing in Extra", function () {
|
||||||
|
var json = {
|
||||||
|
itemType: "artwork",
|
||||||
|
publisher: "Foo", // Invalid base field
|
||||||
|
company: "Foo", // Invalid base-mapped field
|
||||||
|
label: "Foo" // Invaid base-mapped field
|
||||||
|
};
|
||||||
|
var item = new Zotero.Item;
|
||||||
|
item.fromJSON(json);
|
||||||
|
assert.equal(item.getField('extra'), 'Publisher: Foo');
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should deduplicate invalid-for-type base-mapped Type fields with same values and keep Type when storing in Extra", function () {
|
||||||
|
var json = {
|
||||||
|
itemType: "document",
|
||||||
|
type: "Foo", // Invalid base field
|
||||||
|
reportType: "Foo", // Invalid base-mapped field
|
||||||
|
websiteType: "Foo" // Invaid base-mapped field
|
||||||
|
};
|
||||||
|
// Confirm that 'type' is still invalid for 'document', in case this changes
|
||||||
|
assert.isFalse(Zotero.ItemFields.isValidForType(
|
||||||
|
Zotero.ItemFields.getID('type'),
|
||||||
|
Zotero.ItemTypes.getID('document')
|
||||||
|
));
|
||||||
|
var item = new Zotero.Item;
|
||||||
|
item.fromJSON(json);
|
||||||
|
assert.equal(item.getField('extra'), 'Type: Foo');
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should remove invalid-for-type base-mapped Type fields with same values and use Type if not present when storing in Extra", function () {
|
||||||
|
var json = {
|
||||||
|
itemType: "document",
|
||||||
|
reportType: "Foo", // Invalid base-mapped field
|
||||||
|
websiteType: "Foo" // Invaid base-mapped field
|
||||||
|
};
|
||||||
|
// Confirm that 'type' is still invalid for 'document', in case this changes
|
||||||
|
assert.isFalse(Zotero.ItemFields.isValidForType(
|
||||||
|
Zotero.ItemFields.getID('type'),
|
||||||
|
Zotero.ItemTypes.getID('document')
|
||||||
|
));
|
||||||
|
var item = new Zotero.Item;
|
||||||
|
item.fromJSON(json);
|
||||||
|
assert.equal(item.getField('extra'), 'Type: Foo');
|
||||||
|
});
|
||||||
|
|
||||||
|
it("shouldn't deduplicate invalid-for-type base-mapped Type fields with different values when storing in Extra", function () {
|
||||||
|
var json = {
|
||||||
|
itemType: "document",
|
||||||
|
reportType: "Foo", // Invalid base-mapped field
|
||||||
|
type: "Foo", // Invalid base field
|
||||||
|
websiteType: "Bar" // Invaid base-mapped field with different value
|
||||||
|
};
|
||||||
|
var item = new Zotero.Item;
|
||||||
|
item.fromJSON(json);
|
||||||
|
assert.equal(item.getField('extra'), 'Type: Foo\nWebsite Type: Bar');
|
||||||
|
});
|
||||||
|
|
||||||
|
it("shouldn't deduplicate invalid-for-type base-mapped Type fields with different values when storing in Extra", function () {
|
||||||
|
var json = {
|
||||||
|
itemType: "artwork",
|
||||||
|
publisher: "Foo", // Invalid base field
|
||||||
|
company: "Foo", // Invalid base-mapped field
|
||||||
|
label: "Bar" // Invaid base-mapped field with different value
|
||||||
|
};
|
||||||
|
var item = new Zotero.Item;
|
||||||
|
item.fromJSON(json);
|
||||||
|
var parts = item.getField('extra').split('\n');
|
||||||
|
assert.lengthOf(parts, 2);
|
||||||
|
assert.include(parts, 'Publisher: Foo');
|
||||||
|
assert.include(parts, 'Label: Bar');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("strict mode", function () {
|
describe("strict mode", function () {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue