From bd310e8d183114af631ace02993101a03e313b38 Mon Sep 17 00:00:00 2001 From: aramesh-site deploy Date: Wed, 7 Oct 2026 07:20:43 +0000 Subject: [PATCH] =?UTF-8?q?fix(blog):=20=D9=84=DB=8C=D9=86=DA=A9=20=DA=A9?= =?UTF-8?q?=D9=BE=D8=B4=D9=86=20=D8=B1=D9=86=D8=AF=D8=B1=20=D8=B9=D9=85?= =?UTF-8?q?=D9=88=D9=85=DB=8C=20=D8=B1=D8=A7=20=D9=85=DB=8C=E2=80=8C=DA=A9?= =?UTF-8?q?=D8=B1=D8=A7=D9=86=D8=AF=20(=D8=A7=D8=B3=D9=BE=D8=B1=D8=AF=20?= =?UTF-8?q?=D8=A7=D8=B3=D9=BE=DA=A9)=20+=20=D9=86=D9=88=D8=A7=D8=B1=20?= =?UTF-8?q?=D8=A7=D8=A8=D8=B2=D8=A7=D8=B1=20=D8=A8=D8=A7=20=D8=AC=D8=A7?= =?UTF-8?q?=D8=A8=D9=87=E2=80=8C=D8=AC=D8=A7=DB=8C=DB=8C=20=DA=A9=D8=B1?= =?UTF-8?q?=D8=B3=D8=B1=20=D8=A2=D9=BE=D8=AF=DB=8C=D8=AA=20=D8=B4=D9=88?= =?UTF-8?q?=D8=AF=20+=20=D8=B5=D9=81=D8=AD=D9=87=D9=94=20=D8=A7=D8=AF?= =?UTF-8?q?=DB=8C=D8=AA=D9=88=D8=B1=20=D8=A7=D9=86=DA=AF=D9=84=DB=8C=D8=B3?= =?UTF-8?q?=DB=8C=20LTR?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/admin/ArticleWritePage.tsx | 11 ++++++++++- frontend/src/components/admin/ArticleEditor.tsx | 3 +++ frontend/src/components/admin/ArticleImage.ts | 14 ++++++-------- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/frontend/src/admin/ArticleWritePage.tsx b/frontend/src/admin/ArticleWritePage.tsx index f02cecd..b6874d4 100644 --- a/frontend/src/admin/ArticleWritePage.tsx +++ b/frontend/src/admin/ArticleWritePage.tsx @@ -342,6 +342,15 @@ export function ArticleWritePage() { // در زبان انگلیسی، فیلدهای متنی به ستون‌های _en می‌روند؛ اسلاگ/تصویر/وضعیت مشترک‌اند const suf = (name: N) => `${name}${editLang === 'en' ? '_en' : ''}` as keyof Draft // مقدار فعال فیلد دوزبانه — برای value ورودی‌ها و چک‌لیست سئو + // جهت ویرایشگر محتوایی با زبان ویرایش همگام می‌شود — صفحهٔ انگلیسی LTR بماند + useEffect(() => { + const el = document.querySelector('.article-body[data-wysiwyg="true"]') + if (el) { + el.setAttribute('dir', editLang === 'en' ? 'ltr' : 'rtl') + el.setAttribute('lang', editLang) + } + }, [editLang, createdId]) + const activeVal = (name: 'title' | 'slug' | 'author' | 'seo_keyphrase' | 'meta_description' | 'excerpt'): string => String((editLang === 'en' ? draft[`${name}_en` as keyof Draft] : draft[name]) ?? '') @@ -351,7 +360,7 @@ export function ArticleWritePage() { .join(' - ') return ( -
+
{/* نوار بالا */}
diff --git a/frontend/src/components/admin/ArticleEditor.tsx b/frontend/src/components/admin/ArticleEditor.tsx index bdb3847..aa30ec0 100644 --- a/frontend/src/components/admin/ArticleEditor.tsx +++ b/frontend/src/components/admin/ArticleEditor.tsx @@ -199,10 +199,13 @@ export function ArticleEditor({ doc, onChange, contentKey }: ArticleEditorProps) extensions: ARTICLE_EXTENSIONS, content: doc && Object.keys(doc).length ? doc : undefined, immediatelyRender: false, + // نوار ابزار فقط با رندر دوباره روی هر تراکنش زنده می‌ماند (پیش‌فرض v3 خاموش است) + shouldRerenderOnTransaction: true, editorProps: { attributes: { dir: 'rtl', lang: 'fa', + 'data-base-dir': 'rtl', class: 'article-body min-h-[300px] px-4 py-4 focus:outline-none', 'data-wysiwyg': 'true', }, diff --git a/frontend/src/components/admin/ArticleImage.ts b/frontend/src/components/admin/ArticleImage.ts index 6ab05de..b6b1c71 100644 --- a/frontend/src/components/admin/ArticleImage.ts +++ b/frontend/src/components/admin/ArticleImage.ts @@ -59,19 +59,17 @@ export const ArticleImage = Image.extend({ // کپشن خالی → عنصر figcaption اصلاً رندر نمی‌شود (فقط تصویر می‌ماند) const captionHref = (HTMLAttributes.caption_href as string | undefined)?.trim() ?? '' - const figcaption: Array> = captionHref - ? [ - 'a', - { href: captionHref, target: '_blank', rel: 'noopener noreferrer nofollow' }, - caption, - ] - : [caption] + // توجه: آرایهٔ درونی به‌صورت تو در تو پاس می‌شود — اسپرد آن اسپک را تخت می‌کند + // و رندرر استاتیک با «Unsupported DomOutputSpec» می‌میرد. + const captionSpec = captionHref + ? ['a', { href: captionHref, target: '_blank', rel: 'noopener noreferrer nofollow' }, caption] + : caption return caption ? [ 'figure', { class: 'article-figure' }, image, - ['figcaption', { class: 'article-figure__caption' }, ...figcaption], + ['figcaption', { class: 'article-figure__caption' }, captionSpec], ] : ['figure', { class: 'article-figure' }, image] },