Added animated auto-opening link modal, custom image node with isolated caption deletion, fixed single-select category data binding, improved featured image layout, and updated README.
68 lines
2.2 KiB
TypeScript
68 lines
2.2 KiB
TypeScript
import Image from '@tiptap/extension-image'
|
|
import { mergeAttributes } from '@tiptap/core'
|
|
import { ReactNodeViewRenderer } from '@tiptap/react'
|
|
import { ImageNodeView } from './ImageNodeView'
|
|
|
|
/**
|
|
* تصویر مقاله با کپشن.
|
|
* خروجی HTML در سایت: <figure><img><figcaption>کپشن</figcaption></figure>
|
|
* و در ویرایشگر با 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<string, unknown>] = [
|
|
'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)
|
|
},
|
|
})
|