From 082a1e5bcac633ce30afe157d348f8be7ac25dd3 Mon Sep 17 00:00:00 2001 From: MxMarx Date: Mon, 2 Oct 2023 15:36:44 -0700 Subject: [PATCH] support rich text book descriptions --- client/assets/trix.css | 2 +- client/components/cards/BookMatchCard.vue | 2 +- client/components/modals/item/tabs/Match.vue | 6 +-- client/components/ui/RichTextEditor.vue | 45 +++++++++++++------ client/components/ui/VueTrix.vue | 7 +-- client/components/widgets/BookDetailsEdit.vue | 2 +- client/pages/item/_id/index.vue | 2 +- server/providers/Audible.js | 3 +- server/providers/iTunes.js | 3 +- server/utils/parsers/parseOpfMetadata.js | 2 +- 10 files changed, 47 insertions(+), 27 deletions(-) diff --git a/client/assets/trix.css b/client/assets/trix.css index 8f88c61f1..2beb6c190 100644 --- a/client/assets/trix.css +++ b/client/assets/trix.css @@ -27,7 +27,7 @@ trix-toolbar .trix-button-row { trix-toolbar .trix-button-group { display: flex; - margin-bottom: 10px; + margin-bottom: .3em; border: 1px solid rgb(75, 85, 99); border-top-color: rgb(75, 85, 99); border-bottom-color: rgb(75, 85, 99); diff --git a/client/components/cards/BookMatchCard.vue b/client/components/cards/BookMatchCard.vue index dd782d30d..c3878b694 100644 --- a/client/components/cards/BookMatchCard.vue +++ b/client/components/cards/BookMatchCard.vue @@ -24,7 +24,7 @@
-

{{ book.description }}

+

{{ book.descriptionPlain || book.description }}

diff --git a/client/components/modals/item/tabs/Match.vue b/client/components/modals/item/tabs/Match.vue index 0c5d67eba..5aad63109 100644 --- a/client/components/modals/item/tabs/Match.vue +++ b/client/components/modals/item/tabs/Match.vue @@ -85,9 +85,9 @@
-
- -

{{ $strings.LabelCurrently }} {{ mediaMetadata.description.substr(0, 100) + (mediaMetadata.description.length > 100 ? '...' : '') }}

+
+ +

{{ $strings.LabelCurrently }} {{ mediaMetadata.description || '' }}

diff --git a/client/components/ui/RichTextEditor.vue b/client/components/ui/RichTextEditor.vue index 582f5e8f0..fadf1fdb6 100644 --- a/client/components/ui/RichTextEditor.vue +++ b/client/components/ui/RichTextEditor.vue @@ -3,7 +3,7 @@

{{ label }}

- +
@@ -28,32 +28,34 @@ export default { }, config() { return { + blockAttributes: {default: {tagName: 'p'}}, + // lang: {bold: this.$strings.ButtonEditorBold}, // this should work but for some reason it doesn't if toolbar.getDefaultHTML is provided toolbar: { getDefaultHTML: () => `
- - - - + + + + - - + + - - + +
@@ -65,9 +67,24 @@ export default { methods: { trixFileAccept(e) { e.preventDefault() - } + }, + blur() { + if (this.$refs.input && this.$refs.input.blur) { + this.$refs.input.blur() + } + }, }, mounted() {}, beforeDestroy() {} } - \ No newline at end of file + + + \ No newline at end of file diff --git a/client/components/ui/VueTrix.vue b/client/components/ui/VueTrix.vue index ace1edd35..f753b1c2d 100644 --- a/client/components/ui/VueTrix.vue +++ b/client/components/ui/VueTrix.vue @@ -1,6 +1,6 @@ @@ -21,6 +21,7 @@ export default { event: 'update' }, props: { + editorClasses: String, // classes to apply to the editor but not the toolbar /** * This prop will put the editor in read-only mode */ @@ -224,12 +225,12 @@ export default { /** Disable toolbar and editor by pointer events styling */ if (editorState) { this.$refs.trix.toolbarElement.style['pointer-events'] = 'none' + this.$refs.trix.toolbarElement.style['display'] = 'none' this.$refs.trix.contentEditable = false - this.$refs.trix.style['background'] = '#e9ecef' } else { this.$refs.trix.toolbarElement.style['pointer-events'] = 'unset' + this.$refs.trix.toolbarElement.style['display'] = 'block' this.$refs.trix.style['pointer-events'] = 'unset' - this.$refs.trix.style['background'] = 'transparent' } }, overrideConfig(config) { diff --git a/client/components/widgets/BookDetailsEdit.vue b/client/components/widgets/BookDetailsEdit.vue index b42082b57..c90f57032 100644 --- a/client/components/widgets/BookDetailsEdit.vue +++ b/client/components/widgets/BookDetailsEdit.vue @@ -26,7 +26,7 @@
- +
diff --git a/client/pages/item/_id/index.vue b/client/pages/item/_id/index.vue index 176725b91..89972f2ba 100644 --- a/client/pages/item/_id/index.vue +++ b/client/pages/item/_id/index.vue @@ -125,7 +125,7 @@
-

{{ description }}

+
diff --git a/server/providers/Audible.js b/server/providers/Audible.js index 31719eef1..a7aa27cbe 100644 --- a/server/providers/Audible.js +++ b/server/providers/Audible.js @@ -45,7 +45,8 @@ class Audible { narrator: narrators ? narrators.map(({ name }) => name).join(', ') : null, publisher: publisherName, publishedYear: releaseDate ? releaseDate.split('-')[0] : null, - description: summary ? htmlSanitizer.stripAllTags(summary) : null, + description: summary ? htmlSanitizer.sanitize(summary) : null, + descriptionPlain: summary ? htmlSanitizer.stripAllTags(summary) : null, cover: image, asin, genres: genresFiltered.length ? genresFiltered : null, diff --git a/server/providers/iTunes.js b/server/providers/iTunes.js index 39f36ab29..5ce9863df 100644 --- a/server/providers/iTunes.js +++ b/server/providers/iTunes.js @@ -69,7 +69,8 @@ class iTunes { artistId: data.artistId, title: data.collectionName, author, - description: htmlSanitizer.stripAllTags(data.description || ''), + description: htmlSanitizer.sanitize(data.description || ''), + descriptionPlain: htmlSanitizer.stripAllTags(data.description || ''), publishedYear: data.releaseDate ? data.releaseDate.split('-')[0] : null, genres: data.primaryGenreName ? [data.primaryGenreName] : null, cover: this.getCoverArtwork(data) diff --git a/server/utils/parsers/parseOpfMetadata.js b/server/utils/parsers/parseOpfMetadata.js index d5fb4651c..6b053fb5d 100644 --- a/server/utils/parsers/parseOpfMetadata.js +++ b/server/utils/parsers/parseOpfMetadata.js @@ -87,7 +87,7 @@ function fetchDescription(metadata) { // check if description is HTML or plain text. only plain text allowed // calibre stores < and > as < and > description = description.replace(/</g, '<').replace(/>/g, '>') - return htmlSanitizer.stripAllTags(description) + return htmlSanitizer.sanitize(description) } function fetchGenres(metadata) {