diff --git a/src/EditorFactory.ts b/src/EditorFactory.ts index 63c28825d76..af8a03f5fc6 100644 --- a/src/EditorFactory.ts +++ b/src/EditorFactory.ts @@ -46,6 +46,7 @@ const createRichEditor = ({ isEmbedded = false, mentionSearch = undefined, openLink = undefined, + noLazyImages = false, }: { extensions?: Extension[] connection?: Connection @@ -53,6 +54,7 @@ const createRichEditor = ({ isEmbedded?: boolean mentionSearch?: (query: string) => Promise> openLink?: (href: string) => void + noLazyImages?: boolean } = {}) => { return new Editor({ editorProps, @@ -63,6 +65,7 @@ const createRichEditor = ({ isEmbedded, mentionSearch, openLink, + noLazyImages, }), FocusTrap, ...extensions, diff --git a/src/components/Editor.vue b/src/components/Editor.vue index a17d25aa5c9..ee2113b4213 100644 --- a/src/components/Editor.vue +++ b/src/components/Editor.vue @@ -214,6 +214,10 @@ export default defineComponent({ type: Boolean, default: false, }, + noLazyImages: { + type: Boolean, + default: false, + }, }, setup(props) { @@ -271,6 +275,7 @@ export default defineComponent({ isEmbedded: props.isEmbedded, mentionSearch, openLink: openLinkHandler.openLink, + noLazyImages: props.noLazyImages, }) : createPlainEditor({ language, extensions }) provideEditor(editor) diff --git a/src/components/Editor/MarkdownContentEditor.vue b/src/components/Editor/MarkdownContentEditor.vue index 1be8a1ddccd..c85082197b7 100644 --- a/src/components/Editor/MarkdownContentEditor.vue +++ b/src/components/Editor/MarkdownContentEditor.vue @@ -79,6 +79,10 @@ export default { type: Boolean, default: true, }, + noLazyImages: { + type: Boolean, + default: false, + }, }, emits: ['update:content'], @@ -88,6 +92,7 @@ export default { RichText.configure({ extensions: [UndoRedo], openLink: openLinkHandler.openLink, + noLazyImages: props.noLazyImages, }), FocusTrap, ] diff --git a/src/editor.js b/src/editor.js index 3fc3ffdba92..bcb5f6639d2 100644 --- a/src/editor.js +++ b/src/editor.js @@ -256,6 +256,7 @@ window.OCA.Text.createEditor = async function ({ props: null, }, menubarLinkCustomAction = undefined, + noLazyImages = false, onCreate = ({ markdown }) => {}, onLoaded = () => {}, @@ -329,6 +330,7 @@ window.OCA.Text.createEditor = async function ({ mime: 'text/markdown', active: true, autofocus, + noLazyImages, }, on: { ready: () => vm.$emit('ready'), @@ -346,6 +348,7 @@ window.OCA.Text.createEditor = async function ({ relativePath: filePath, shareToken, readOnly: data.readOnly, + noLazyImages, }, scopedSlots, }) diff --git a/src/extensions/RichText.js b/src/extensions/RichText.js index d5807c3e737..b84161e3b4f 100644 --- a/src/extensions/RichText.js +++ b/src/extensions/RichText.js @@ -70,6 +70,7 @@ export default Extension.create({ isEmbedded: false, mentionSearch: undefined, openLink: undefined, + noLazyImages: false, } }, @@ -105,8 +106,8 @@ export default Extension.create({ isEmbedded: this.options.isEmbedded, }), Underline, - Image, - ImageInline, + Image.configure({ noLazyImages: this.options.noLazyImages }), + ImageInline.configure({ noLazyImages: this.options.noLazyImages }), Dropcursor.configure({ color: 'var(--color-primary-element)', width: 2, diff --git a/src/nodes/Image.js b/src/nodes/Image.js index 2a77fb02b37..4c9b8439e6b 100644 --- a/src/nodes/Image.js +++ b/src/nodes/Image.js @@ -49,6 +49,7 @@ const Image = TiptapImage.extend({ addOptions() { return { ...this.parent?.(), + noLazyImages: false, } }, diff --git a/src/nodes/ImageInline.js b/src/nodes/ImageInline.js index 733d170f111..64d8b4d073c 100644 --- a/src/nodes/ImageInline.js +++ b/src/nodes/ImageInline.js @@ -44,6 +44,7 @@ const ImageInline = TiptapImage.extend({ addOptions() { return { ...this.parent?.(), + noLazyImages: false, inline: true, } }, diff --git a/src/nodes/ImageView.vue b/src/nodes/ImageView.vue index dcf7aa3e180..dda5e255433 100644 --- a/src/nodes/ImageView.vue +++ b/src/nodes/ImageView.vue @@ -273,6 +273,12 @@ export default { this.loadAttachmentMetadata() this.setupResizeObserver() + // Load image directly if lazy loading is disabled + if (this.extension?.options?.noLazyImages === true) { + this.loadPreview().catch(this.onImageLoadFailure) + return + } + this.$nextTick(() => { // nextTick is necessary, intersection detection is slightly unreliable without it const options = {