import Image from '@tiptap/extension-image' import { mergeAttributes } from '@tiptap/core' import { ReactNodeViewRenderer } from '@tiptap/react' import { ImageNodeView } from './ImageNodeView' /** * تصویر مقاله با کپشن. * خروجی HTML در سایت:
کپشن
* و در ویرایشگر با NodeView سفارشی (ورودی کپشن + دکمه حذف) نمایش داده می‌شود. */ export const ArticleImage = Image.extend({ addAttributes() { return { // ویژگی‌های استاندارد تصویر (src/alt/title/width/height) از افزونه پایه ...this.parent?.(), caption: { default: '', parseHTML: (element) => element.closest('figure')?.querySelector('figcaption')?.textContent?.trim() ?? '', }, } }, parseHTML() { return [ { tag: 'figure', priority: 60, getAttrs: (element) => { if (!(element instanceof HTMLElement)) return false const img = element.querySelector('img') if (!img) return false return { src: img.getAttribute('src'), alt: img.getAttribute('alt'), title: img.getAttribute('title'), caption: element.querySelector('figcaption')?.textContent?.trim() ?? '', } }, }, // تصاویر بدون figure (محتوای قدیمی یا چسبانده‌شده) { tag: 'img[src]:not([src^="data:"])' }, ] }, renderHTML({ HTMLAttributes }) { const { caption, ...imageAttributes } = HTMLAttributes const image: [string, Record] = [ 'img', mergeAttributes(this.options.HTMLAttributes, imageAttributes), ] // کپشن خالی → عنصر figcaption اصلاً رندر نمی‌شود (فقط تصویر می‌ماند) return caption ? [ 'figure', { class: 'article-figure' }, image, ['figcaption', { class: 'article-figure__caption' }, caption], ] : ['figure', { class: 'article-figure' }, image] }, addNodeView() { return ReactNodeViewRenderer(ImageNodeView) }, })