Skip to content

Commit

Permalink
Add support for attachment type priority customization
Browse files Browse the repository at this point in the history
  • Loading branch information
AbeJellinek committed May 21, 2024
1 parent eab0922 commit 0f8c61e
Show file tree
Hide file tree
Showing 2 changed files with 250 additions and 0 deletions.
175 changes: 175 additions & 0 deletions test/tests/utilitiesTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -361,4 +361,179 @@ describe("Zotero.Utilities", function() {
assert.equal(newHTML, html);
});
});

describe("getAutomaticAttachmentPreferences()", function () {
describe("Zotero.Prefs unavailable", function () {
it("should return defaults", function () {
let { enabledTypes, typeOrder } = Zotero.Utilities.getAutomaticAttachmentPreferences();
assert.deepEqual(Array.from(enabledTypes), ['pdf', 'epub', 'html']);
assert.deepEqual(typeOrder, ['pdf', 'epub', 'html']);
});
});

describe("Zotero.Prefs available", function () {
let automaticAttachmentTypes = new Set(['epub']);
let automaticAttachmentTypesOrder = ['html', 'epub', 'pdf'];

before(function () {
Zotero.Prefs = {
get: function (pref) {
if (pref === 'automaticAttachmentTypes') {
return Array.from(automaticAttachmentTypes).join(',');
}
else if (pref === 'automaticAttachmentTypes.order') {
return automaticAttachmentTypesOrder.join(',');
}
return null;
}
};
});

after(function () {
delete Zotero.Prefs;
});

it("should return pref values", function () {
let { enabledTypes, typeOrder } = Zotero.Utilities.getAutomaticAttachmentPreferences();
assert.deepEqual(Array.from(enabledTypes), ['epub']);
assert.deepEqual(typeOrder, ['html', 'epub', 'pdf']);
});
});
});

describe("shouldSaveAttachmentOfType()", function () {
let automaticAttachmentTypes = new Set(['epub']);
let automaticAttachmentTypesOrder = ['html', 'epub', 'pdf'];

before(function () {
Zotero.Prefs = {
get: function (pref) {
if (pref === 'automaticAttachmentTypes') {
return Array.from(automaticAttachmentTypes).join(',');
}
else if (pref === 'automaticAttachmentTypes.order') {
return automaticAttachmentTypesOrder.join(',');
}
return null;
}
};
});

after(function () {
delete Zotero.Prefs;
});

it("should use pref values", function () {
assert.isTrue(Zotero.Utilities.shouldSaveAttachmentOfType('epub'));
assert.isFalse(Zotero.Utilities.shouldSaveAttachmentOfType('pdf'));
assert.isFalse(Zotero.Utilities.shouldSaveAttachmentOfType('html'));
});

it("should throw on an unknown type", function () {
assert.throws(() => Zotero.Utilities.shouldSaveAttachmentOfType('nonexistent--type'));
});
});

describe("filterAttachmentsToSave()", function () {
let automaticAttachmentTypes = new Set(['html', 'epub']);
let automaticAttachmentTypesOrder = ['html', 'epub', 'pdf'];

before(function () {
Zotero.Prefs = {
get: function (pref) {
if (pref === 'automaticAttachmentTypes') {
return Array.from(automaticAttachmentTypes).join(',');
}
else if (pref === 'automaticAttachmentTypes.order') {
return automaticAttachmentTypesOrder.join(',');
}
return null;
}
};
});

after(function () {
delete Zotero.Prefs;
});

it("should keep non-attachments", function () {
assert.deepEqual(
Zotero.Utilities.filterAttachmentsToSave([
{ itemType: 'book', title: 'Other stuff' },
{ itemType: 'attachment', mimeType: 'application/pdf' }
]),
[
{ itemType: 'book', title: 'Other stuff' }
]
);
});

it("should keep attachments of unknown types", function () {
assert.deepEqual(
Zotero.Utilities.filterAttachmentsToSave([
{ itemType: 'attachment', mimeType: 'application/pdf' },
{ mimeType: 'text/x-unknown' }
]),
[
{ mimeType: 'text/x-unknown' }
]
);
});

it("should keep only attachments of the first matching type", function () {
assert.deepEqual(
Zotero.Utilities.filterAttachmentsToSave([
{ mimeType: 'application/pdf' },
{ mimeType: 'text/html' },
{ mimeType: 'text/html' },
{ mimeType: 'application/epub+zip' },
{ mimeType: 'application/epub+zip' }
]),
[
{ mimeType: 'text/html' },
{ mimeType: 'text/html' }
]
);
});

it("should recognize multiple HTML MIME types and keep unknown type", function () {
assert.deepEqual(
Zotero.Utilities.filterAttachmentsToSave([
{ mimeType: 'text/html' },
{ mimeType: 'text/html' },
{ mimeType: 'application/xhtml+xml' },
{ mimeType: 'application/epub+zip' },
{ mimeType: 'application/octet-stream' }
]),
[
{ mimeType: 'text/html' },
{ mimeType: 'text/html' },
{ mimeType: 'application/xhtml+xml' },
{ mimeType: 'application/octet-stream' }
]
);
});

it("should recognize attachment with 'document' property as HTML", function () {
assert.deepEqual(
Zotero.Utilities.filterAttachmentsToSave([
{ mimeType: 'text/html' },
{ document: {} },
{ mimeType: 'application/epub+zip' }
]),
[
{ mimeType: 'text/html' },
{ document: {} }
]
);
});

it("should return the exact same objects", function () {
let obj = { mimeType: 'text/html' };
assert.equal(
Zotero.Utilities.filterAttachmentsToSave([obj])[0],
obj
);
});
});
});
75 changes: 75 additions & 0 deletions utilities.js
Original file line number Diff line number Diff line change
Expand Up @@ -1830,6 +1830,81 @@ var Utilities = {
}
return root.innerHTML;
},

getAutomaticAttachmentPreferences() {
let enabledTypes = Zotero.Prefs && Zotero.Prefs.get('automaticAttachmentTypes').split(',');
let typeOrder = Zotero.Prefs && Zotero.Prefs.get('automaticAttachmentTypes.order').split(',');

// If either pref isn't available (not just empty), use defaults
enabledTypes = new Set(enabledTypes || ['pdf', 'epub', 'html']);
typeOrder = typeOrder || ['pdf', 'epub', 'html'];

return { enabledTypes, typeOrder };
},

shouldSaveAttachmentOfType(type) {
if (!['pdf', 'epub', 'html'].includes(type)) {
throw new Error('Unknown type: ' + type);
}

let { enabledTypes } = this.getAutomaticAttachmentPreferences();
return enabledTypes.has(type);
},

/**
* Given an array of items in translator JSON format, return the items that
* should be saved according to the user's preferences. Non-attachment items
* are always returned.
*
* @typedef {{ mimeType: string, url?: string, document?: Document, itemType?: string }} TranslatorItem
* @param {TranslatorItem[]} itemsJSON
* @returns {TranslatorItem[]}
*/
filterAttachmentsToSave(itemsJSON) {
let { enabledTypes, typeOrder } = this.getAutomaticAttachmentPreferences();

let attachmentTypes = itemsJSON.map((attachment) => {
if (typeof attachment.itemType === 'string' && attachment.itemType !== 'attachment') {
return null;
}
if (attachment.mimeType === 'application/pdf') {
return 'pdf';
}
if (attachment.mimeType === 'application/epub+zip') {
return 'epub';
}
if (attachment.document
|| (Zotero.MIME
? Zotero.MIME.isWebPageType(attachment.mimeType)
: ['text/html', 'application/xhtml+xml'].includes(attachment.mimeType))
) {
return 'html';
}
return null;
});

// We want to keep everything that isn't an identifiable file attachment
let isNotKnownTypeFileAttachment = (attachment, i) => {
return attachmentTypes[i] === null
|| attachmentTypes[i] === 'html' && attachment.snapshot === false;
};

for (let type of typeOrder) {
if (!enabledTypes.has(type)) {
continue;
}
if (attachmentTypes.includes(type)) {
return itemsJSON.filter((attachment, i) => {
if (isNotKnownTypeFileAttachment(attachment, i)) {
return true;
}
return attachmentTypes[i] === type || attachmentTypes[i] === null;
});
}
}

return itemsJSON.filter(isNotKnownTypeFileAttachment);
},

// /**
// * Provides unicode support and other additional features for regular expressions
Expand Down

0 comments on commit 0f8c61e

Please sign in to comment.