diff --git a/chrome/content/zotero/xpcom/reader.js b/chrome/content/zotero/xpcom/reader.js index 94b423e9e9..13bea81fae 100644 --- a/chrome/content/zotero/xpcom/reader.js +++ b/chrome/content/zotero/xpcom/reader.js @@ -46,6 +46,18 @@ const READ_ALOUD_VOICE_DEFAULTS_PATH = PathUtils.join(Zotero.Profile.dir, 'readA // Whether the Read Aloud audio cache has been pruned of stale versions this session let readAloudCachePruned = false; +/** + * Return the custom reader themes from the synced setting + * + * Plugins can write to the setting, and the reader fails to load if the value isn't an array. + * + * @return {Object[]} + */ +function getCustomThemes() { + let customThemes = Zotero.SyncedSettings.get(Zotero.Libraries.userLibraryID, 'readerCustomThemes'); + return Array.isArray(customThemes) ? customThemes : []; +} + class ReaderInstance { constructor(options) { this.stateFileName = '.zotero-reader-state'; @@ -251,7 +263,7 @@ class ReaderInstance { ftl, showAnnotations: true, textSelectionAnnotationMode: Zotero.Prefs.get('reader.textSelectionAnnotationMode'), - customThemes: Zotero.SyncedSettings.get(Zotero.Libraries.userLibraryID, 'readerCustomThemes') ?? [], + customThemes: getCustomThemes(), lightTheme: Zotero.Prefs.get('reader.lightTheme'), darkTheme: Zotero.Prefs.get('reader.darkTheme'), fontFamily: Zotero.Prefs.get('reader.ebookFontFamily'), @@ -2868,7 +2880,7 @@ class Reader { else if (type === 'setting') { let id = ids[0]; if (id === `${Zotero.Libraries.userLibraryID}/readerCustomThemes`) { - let newCustomThemes = Zotero.SyncedSettings.get(Zotero.Libraries.userLibraryID, 'readerCustomThemes') ?? []; + let newCustomThemes = getCustomThemes(); this._readers.forEach((reader) => { reader._internalReader.setCustomThemes( Components.utils.cloneInto(newCustomThemes, reader._iframeWindow) diff --git a/test/tests/readerTest.js b/test/tests/readerTest.js index 36c68d5fbb..4979ca0b9f 100644 --- a/test/tests/readerTest.js +++ b/test/tests/readerTest.js @@ -352,6 +352,25 @@ describe("Reader", function () { } }); + it('should open with an invalid custom themes setting', async function () { + var attachment = await importFileAttachment('test.pdf'); + // Plugins can write anything to a synced setting + await Zotero.SyncedSettings.set( + Zotero.Libraries.userLibraryID, + 'readerCustomThemes', + { 0: { id: 'custom1', label: 'Custom', background: '#FFFFFF', foreground: '#000000' } } + ); + + try { + var reader = await Zotero.Reader.open(attachment.itemID); + await reader._initPromise; + assert.ok(reader._internalReader); + } + finally { + await Zotero.SyncedSettings.clear(Zotero.Libraries.userLibraryID, 'readerCustomThemes'); + } + }); + describe("#importFromEPUB()", function () { let bookEpubPath; // The EPUB itself let bookSdrPath; // The KOReader "sidecar" folder