Releases: Kourosh242/Persian-Flow
Release list
PERSIAN-FLOW-1.4.0
🔢 Persian Flow 1.4.0 — فارسیسازی اعداد + دقتِ بلوکمحورِ RTL + ۱۵ فونت
خلاصه مدیریتی: نسخهی ۱.۴.۰ دو چیز را همزمان جلو میبرد: یک قابلیت تازه (فارسیسازی ارقام لاتین داخل متن فارسی، با تاگل سوم و پیشفرض خاموش) و یک بازطراحیِ دقت — از این نسخه قاعدهی احراز «ساختاری» است نه حجمی و نه تگمحور، پس فقط متنها راستچین میشوند و هرگز لیآوتِ صفحه. در کنارش فونتها از ۱۱ به ۱۵ رسید (کاتیبه، لالهزار، آمیری، نستعلیق) و سقفهای حجمی/تعدادی موتور برداشته شد تا چتهای هزارپیامی و پاسخهای صدهزارکاراکتریِ AI هم کامل پوشش داده شوند. پوشش آزمون: ۴۴۵ تست سبز در ۸ سوئیت (۲۳۱ واحد jsdom + ۲۱۴ E2E کروم واقعی).
📦 دانلود: PersianFlow-1.4.0.zip · 📄 چنجلاگ کامل: CHANGELOG.md · 🔀 مقایسه با ۱.۳.۰: 1.3.0...1.4.0
✨ چه چیزهایی تازه است؟
۱) فارسیسازی اعداد — تاگل سوم پاپآپ (پیشفرض خاموش)
درد مزمنِ جامعهی فارسیزبان: «نسخه 1.4.0 با 15 فونت» وسط یک متن فارسی. حالا ارقام لاتینِ داخل بلوکهای متنیِ فارسی به «۰۱۲۳۴۵۶۷۸۹» تبدیل میشوند و با همان فونتی که انتخاب کردهاید رندر میگیرند (چون داخل قابِ کلاسِ خانوادهی فونتاند).
چه چیزی تبدیل میشود: بازهها (10-20 → ۱۰-۲۰)، اعشار، درصد، شمارهی نسخه (1.4.0 → ۱.۴.۰)، اعداد وسط جمله، و ارقامی که همین لحظه تایپ میکنید (FIX-KB — از مسیر خطلولهی ویرایش، بدون دستکاری DOM، پس با ریاکت/ProseMirror و فریمورکها نمیجنگد).
چه چیزی هرگز دستنمیخورد: کد (code/pre/kbd/samp/tt)، لینک و ایمیل (<a>)، همهی فیلدها و ادیتورهای contenteditable (شامل فیلدهای حساسِ رمز/عدد/تلفن)، URLها، ادیتورهای کد (Monaco/CodeMirror) و متنِ انگلیسیمحور.
بازگردانیِ دقیق: تبدیل idempotent است و متنِ اصلیِ هر گرهمتنی در یک WeakMap نگه داشته میشود؛ با خاموشکردن تاگل، متن بایتبهبایت به اصلِ لاتین برمیگردد و ارقامِ فارسیِ ازپیشموجودِ متن هم سر جایشان میمانند. حتی اگر متن در حین استریم روی گرهی تبدیلشده رشد کند، مبنای بازگردانی سالم میماند (FIX-Q).
💡 چرا پیشفرض خاموش است؟ چون در بعضی کاربردها ارقامِ لاتین درستترند (شمارهی نسخهی اپ موبایل، کد خطا، هش کامیت). تصمیم با شماست — یک کلیک در پاپآپ.
۲) ۱۵ فونت فارسی متنباز (۴ فونت تازه)
چهار سبک محبوب که در سنس قبلی نبودند اضافه شد؛ همه SIL OFL با پوشش کامل فارسی (پ چ ژ گ + ارقام ۰ تا ۹) و لاتین:
| فونت | نوع | طراح / منبع | حجم |
|---|---|---|---|
| وزیرمتن (پیشفرض) | متغیر (۱۰۰–۹۰۰) | صابر راستیکردار | 109KB |
| استعداد | متغیر (۱۰۰–۹۰۰) | امین عبدی | 118KB |
| میخک | متغیر (۱۰۰–۹۰۰) | امین عبدی | 61KB |
| ساحل | متغیر (۱۰۰–۹۰۰) | صابر راستیکردار | 38KB |
| صمیم | ایستا (۴۰۰ + ۷۰۰) | صابر راستیکردار | 73KB |
| شبنم | ایستا (۴۰۰ + ۷۰۰) | صابر راستیکردار | 72KB |
| پرستو | ایستا (۴۰۰ + ۷۰۰) | صابر راستیکردار | 91KB |
| ناهید | ایستا | صابر راستیکردار | 37KB |
| گندم | ایستا | صابر راستیکردار | 44KB |
| تنها | ایستا | صابر راستیکردار | 37KB |
| بهداد | ایستا | font-store | 18KB |
| کاتیبه (جدید) | ایستا — نسخِ عناوین | استودیو KB (برنا ایزدپناه)، Lasse Fister، Eduardo Tunni | 64KB |
| لالهزار (جدید) | ایستا — رترو/نمایشی | برنا ایزدپناه — پروژهی لالهزار | 82KB |
| آمیری (جدید) | ایستا — نسخِ کلاسیک | خالد حسنی — پروژهی آمیری | 146KB |
| نستعلیق (جدید) | متغیر (۴۰۰–۷۰۰) | پروژهی Noto گوگل | 261KB |
- چهار فونت تازه ~۵۵۳KB به پکیج اضافه میکنند؛ مجموع ۱۸ فایل woff2 حدود ۱.۲۵MB است — اما چون فقط فونتِ فعال لود میشود، هزینهی ۱۴ فونتِ دیگر صفرِ شبکه و صفرِ حافظه است.
- پیشلودِ فونتِ فعال (FIX-PR): بلافاصله پس از بوت و هنگام تعویض فونت با
document.fonts.load— دیگر «اولِ ورود فونت دیر مینشیند» رخ نمیدهد و رندر با fallback تقریباً دیده نمیشود. - اعمال آنی و بدون ریلود روی همهی تبهای باز، حتی زیر سختترین CSPها (
@font-faceتزریقی با آدرس مطلقchrome-extension://وadoptedStyleSheets). - انتخاب فونت حالا با همان یک کلیک فعال میشود (پیشتر گاهی لازم بود دوبار بزنید؛ تاگلها حتی اگر پاپآپ را فوراً ببندید در
storage.syncمینشینند).
۳) دقتِ بلوکمحور: «فقط متون راستچین میشوند»
- قاعدهی احراز ساختاری است، نه تگمحور و نه حجمی: هر المانی که فرزند(های) غیریکخطیِ محتوایی داشته باشد «کانتینر» شناخته میشود و متن دقیقاً در بلوکِ واقعیاش قضاوت میگردد. تگهای سفارشیِ فریمورکها (مثل
<turbo-frame>گیتهاب) هم همینطور — چون معیار، ساختارِ فرزندان است نه نام تگ. - قفلِ گلوگاه: «نقطهی واحدِ رسمِ علامت» پیش از اعمال هر نشانه ساختار را دوباره بررسی میکند؛ پس هیچ شکافِ زمانیِ mount/hydrate نمیتواند یک wrapperِ سطحصفحه را علامت بگذارد.
- گاردِ رندر در CSS: کلاسهای علامت فقط وقتی رندر میشوند که المان نسلِ ساختاری (لیست/جدول/بلوک/UI) نداشته باشد — لایهی دومِ دفاع، مستقل از موتور.
- لیست سفیدِ جهت:
directionفقط روی واحدهای متنیِ ساده باdisplay: block / inline-block / flow-rootمینشیند. ردیفهای فلکسِ گزینهها و ابزارها، سلولهای جدول، گلولهمارکِ آیتملیستها و spanهای اینلاین هرگز جهت نمیگیرند. - فهرستهای کوتاهآیتم (divهای بلاکیِ بدون flex و بدون
ul) دیگر یکجا راستبهچپ نمیشوند؛ آیتمبهآیتم قضاوت میشوند — همتراز با<ul>/<ol>— و آیتمِ لاتینِ وسط جابهجا نمیشود.
۴) بدون هیچ سقفِ تعداد/حجمی (FIX-NL)
- گاردِ «بیشتر از ۳۰۰۰ کاراکتر = چیدمان» و گارد ۱۲۰۰کاراکتریِ «کانتینرِ شلوغ» حذف شدند — پیامِ ۵هزارکاراکتریِ AI دیگر علامتش پاک نمیشود (ریشهی حس «چت که بلند میشود RTL از کار میافتد»).
- متنهای فوقبلند (بیش از ۱۵۰هزار کاراکتر) با نمونهبرداریِ آماریِ سهپنجرهای قضاوت میشوند — ارزان، ولی همچنان قضاوتشده.
- اسکنرِ تیکِ دورهای بهجای «پیمایشِ سراسری با سقف نود»، مکاننمای پیمایش پایدار + بودجهی زمانی در هر تیک دارد: هیچ گرهای در هیچ صفحهای برای همیشه جا نمیماند؛ فقط تدریجی میرسد.
۵) کنترلها بدون ریلود و همگام
روشن/خاموشکردن هر سه تاگل (راستچین، فونت، اعداد) بلافاصله روی همان صفحه اعمال میشود؛ تغییر از یک پاپآپ/تب دیگر هم روی بقیهی تبها مینشیند (FIX-X) و شنوندهی storage فقط به ناحیهی sync گوش میدهد تا نوشتنِ کشِ ریلیز در local کاری را تحریک نکند (FIX-AR).
🐛 چه باگهایی رفع شد؟
الف) «کل صفحه آینه شد» (گزارش کاربر — بازتولید زنده روی گیتهاب)
- نشانه: در بعضی صفحهها (بهویژه حین هیدراتِ فریمورک) جهتِ کل سایت برعکس میشد و ترتیب دیداریِ همهچیز جابهجا میشد.
- ریشه: زنجیرههای wrapperِ تکفرزندهی محتوایی (مثل
div.application-mainگیتهاب) که متن را فقط عبور میدهند، «بلوکِ متنی» حساب میشدند وdirection: rtlارثیشان به کل درخت میرسید. - درمان (FIX-CT + قفلِ گلوگاه + گاردِ CSS): احراز ساختاری (بند ۳ بالا)، قفلِ نقطهی واحدِ رسمِ علامت، و قانون
:not(:has(…))درstyles.css. نتیجه روی صفحههای واقعی: ۰ آفندر در بارگذاریهای تازهی پیدرپی (در برابر صددرصدِ قبلی).
ب) علامتِ کهنه وقتی سایت فقط CSS را عوض میکند (FIX-SM)
اگر سایتی بدون تغییر DOM ساختارِ یک بلوک را بشکند (مثلاً displayاش را flex کند)، افزونه در تیک بعدی علامتِ کهنه را خودبهخود پاک میکند تا محورِ لیآوت نرهد.
ج) خطوط چیپدارِ چت بههم میریخت (FIX-P — گزارش کاربر با اسکرینشات)
ردیفهای فلکسِ ریاکتی که چیپ کد (code/kbd/samp) هم بین spanها دارند، «متنِ خردشده» شناخته نمیشدند و رد میشدند؛ در نتیجه ترتیب کلماتِ خطوطی مثل «کامیت b9afb33 + تگ v1.4.0 زده شد…» میریخت. حالا چیپهای اینلاین هم فرگمنتِ متنی حساب میشوند و خط یکدست راستچین میشود. نردهی محافظ: ردیفی که همهی فرزندانش چیپ کد است = نوار ابزار → رد.
د) کد همیشه LTR میماند (FIX-CD + FIX-U)
- زیر بلوکهای
rtldir، چیپ/بلوک کد جهتِrtlرا به ارث میبُرد و علائم انتهاییِ کدهای لاتین (مثل`npm i;`) میپرید → جهتِ کد با قانونِ مخصوص بهdirection: ltr+isolateپین شد. - کلونِ CSSِ داخل Shadow DOM با
styles.cssمنشعب شده بود (قانون مونواسپیسِ کد و تراز چپِ کد در آن نبود وdirectionقدیمی روی فلکس باقی مانده بود) →rulesCSSکاملاً باstyles.cssهمگام شد و اینورینتهایی اضافه شد که از انشعابِ مجدد جلوگیری کنند.
ه) فونت در کامپوزرهای غنی حین تایپ اعمال نمیشد (گزارش کاربر)
کلاس فونت روی rootِ کامپوزرها بهخاطر گاردِ «نسلِ ساختاری» رندر نمیشد → معافیتِ :where(:not(:has(…)), [contenteditable]) روی همهی قوانین فونت نشست؛ تایپ در چتباکسهای AI حالا هم راستچین است و هم با فونتِ انتخابی.
و) ایمنی کاملِ contenteditable (FIX-Y + FIX-ED + FIX-Z + FIX-ND)
- فرزندانِ داخل ادیتور دیگر هرگز پردازش نمیشوند (پیشتر از مسیرِ کانتینرِ عادی علامت و فارسیسازی میگرفتند) → هنگام تایپ، DOM بهتدریج mutate میشد، کرسر میپرید و ارقامِ تازه «به پشتِ متن پرتاب» میشدند. حالا فقط ریشهی ادیتور
dir=auto+ فونت میگیرد. - عمقِ محافظِ ادیتور از ۱۰ به ۲۴ رسید (تودرتویِ عمیقِ ProseMirror فرار میکرد) و عمقِ محافظِ اعداد از ۶ به ۱۶ و سپس ۲۴ — اعدادِ تودرتویِ عمیقِ خروجی AI/مارکداون (ریدمیهای عمیق) هم تبدیل میشوند.
- قوانینِ «رد» (کد/لینک/قابلویرایش) قبل از پذیرشِ
stopAtارزیابی میشوند تا محافظِ ادیتور هرگز بیاثر نماند.
ز) فیلدهای لاتینِ داخل جملهی فارسی (FIX-FD)
input/textarea/select داخل متنِ علامتخوردهی فارسی جهت را از پیرامون میگرفتند؛ حالا dir=auto بومی (سمت موتور) + unicode-bidi: plaintext (سمت CSS) دارند — جهت از محتوای خودِ فیلد میآید.
ح) خطِ فارسیِ «آغازِ لاتین» همیشه راستچین (FIX-RD — گزارش کاربر با اسکرینشات)
خطی مثل «README (نشان نسخه …): را بهروز میکنم» با plaintext جهت را از اولین نویسهی قوی میگرفت و LTR رندر میشد. حالا روی کانتینرهای غیر flex/grid/table کلاس __pf-rtldir__ با direction: rtl قطعی مینشیند.
ط) باگِ «باید دوبار بزنم» برای انتخاب فونت
انتخاب فونت از فهرست پیشتر فقط خانواده را ذخیره میکرد و تاگل خاموش میماند → کاربر دوبار میزد. حالا تاگل هم همان لحظه روشن و در storage ثبت میشود (با آزمونِ خودکارِ بستنِ فوریِ پاپآپ).
ی) سفتکاریِ عملکرد و حافظه
| کد | رفع |
|---|---|
| FIX-W | امضای کشِ متن تا ۴۰۰۰ کاراکتر کامل هش میشود (وابسته به نمونهبرداری نیست) — ویرایشِ میانمتن هم قضاوت را تازه میکند... |
PERSIAN-FLOW-1.3.0
🛠️ Persian Flow 1.3.0 — پایداری کامل: شکار عمیق باگهای RTL
خلاصه مدیریتی: نسخهی ۱.۳.۰ هیچ قابلیت UI جدیدی اضافه نمیکند و تماماً به پایداری RTL اختصاص دارد. حاصل بازبینی تمامسورس + شبیهسازی سناریوهای واقعی کاربر (از پیام کوتاه تا چت +۱۰هزارگرهای): شش باگ متمایز شکار و رفع شد تا «RTLِ اشتباه / RTLِ نشدن / فونتِ نگرفتن» به صفر برسد. پوشش آزمون از ۱۱۸ به ۱۳۷ تست واحد رسید و E2E تعاملی از ۲۳ به ۳۰ — مجموع ۲۶۱ تست سبز در ۶ سوئیت.
📦 دانلود: PersianFlow-1.3.0.zip · 📄 چنجلاگ کامل: CHANGELOG.md · 🔀 مقایسه با ۱.۲.۰: 1.2.0...1.3.0
🐛 چه باگهایی رفع شد؟
۱) بعضی پیامهای تازه (مخصوصاً آخرین پیامهای یک گفتگوی طولانی) اصلاً راستچین نمیشدند (گزارش کاربر — claude.ai و هر SPA با رندر گروهی بزرگ)
- نشانه: در چتهای طولانی، پیامهای انتهایی LTR میماندند و ترتیب کلمات متن ترکیبی فارسی/انگلیسی بههم میریخت. قابل وقوع روی ChatGPT، Gemini، arena.ai و…
- ریشهی مرکب سهگانه (FIX-K):
- الف) هنگام پُرشدن صف موتاسیون (مونت/بازرندر یکجای هزاران گره) خط
queue.length = QUEUE_CAPانتهای صف — یعنی تازهترین پیامها — را بیصدا دور میریخت و قدیمیها را نگه میداشت. - ب) اسکن جبرانیِ دورهای با سقف ۸٬۰۰۰ گرهمتنی از ابتدای سند میشمرد و در گفتگوهای طولانی هرگز به انتهای سند نمیرسید.
- ج) گارد ۶۰۰هزارکاراکتری اسکن دورهای روی صفحات خیلی بزرگ کل شبکهی اطمینان را بیصدا خاموش میکرد.
- الف) هنگام پُرشدن صف موتاسیون (مونت/بازرندر یکجای هزاران گره) خط
- درمان: سرریز صف حالا بهجای دورریختن گرههای نو، کل صف را خالی میکند و یک اسکن جبرانیِ دیبانسشده (۲۵۰ms) + پرچم sweep راه میاندازد تا هیچ گرهتازهای قربانی نشود؛ سقف گرهمتنی اسکن از ۸٬۰۰۰ به ۵۰٬۰۰۰ و سقف کاراکتری صفحه از ۶۰۰هزار به ۲٬۰۰۰٬۰۰۰ ارتقا یافت — و اسکن جبرانیِ sweep حتی فراتر از سقف کاراکتری هم پیمایش کراندار انجام میدهد (با کش امضای متن و سقف گره، همچنان ارزان روی سختافزار ضعیف).
۲) کهنگی علائم روی فلیپ زبان (بازبینی عمیق v1.3.0 — FIX-L)
- نشانه: اگر متنِ گرهی علامتخورده بعداً انگلیسی/غیرغالب میشد (ویرایش پیام، تعویض محتوای SPA)، بلوک یکدستِ بالادست (مثل
LI) یا wrapperِ مونتشده برای همیشه راستچین/فونتدار میماند. - درمان: در هر فلیپ به غیرغالب (یا تخلیه/عبور از سقف متن)، اجدادِ علامتخورده (تا ۶ سطح، با دیوارهای چیدمان) بازارزیابی و در صورت لزوم پاک میشوند.
۳) قضاوت ترکیبیِ ظرفهای چندبلوک (بازبینی عمیق v1.3.0 — FIX-M)
- نشانه: ظرفی با ≥۲ فرزندِ بلوکمتنی (دو پاراگراف، یا پاراگراف+دکمه) با متنِ چسبیدهی همهی بلوکها قضاوت میشد و پاراگراف انگلیسیِ بغلدستی هم راستچین/فونتدار میشد (یا برچسب دکمه قضاوت را منحرف میکرد).
- درمان: چنین ظرفی دیگر «یک پیام» حکم نمیگیرد؛ تصمیم به بلوکهای درونی سپرده میشود (هر بلوک مستقل — فارسی RTL، انگلیسی تمیز). قاعده برای نوههای چندبلوک هم یکسطح عمیقتر اعمال میشود تا تعویض
innerHTMLوالد دورش نزند.
۴) فونت مونواسپیسِ کد میپرید (بازبینی عمیق v1.3.0 — FIX-N)
- نشانه: قانون
*ی فونت فارسی به همهی نوادگانِ بلوک میرسید و<code>/<pre>و توکنهای هایلایتشدهی کد داخل چتهای AI را به فونت فارسی میبرد. - درمان: یک قانون پایانی با specificity بالاتر،
pre/code/kbd/samp/tt(+.cm-content/.monaco-editor) و فرزندانشان را به پشتهیui-monospace, Menlo, Consolas, …برمیگرداند — راستچین و فونت فارسیِ بقیهی متن دستنخورده.
5) باگ UI اعلان اپدیت رفع شد
دیگر اعلان اپدیت جلوی تنظیمات فونت هارا نمیگیرد
✅ آزمونها و اثبات
- ۱۳۷ تست واحد jsdom (از ۱۱۸): +۵ رگرسیون FIX-K (سند +۹٬۲۰۰گرهای، مونت گروهی ۲٬۲۵۰گرهای/سرریز صف، تداوم استریم پس از سرریز)، +۷ تست FIX-L (فلیپ به انگلیسی روی بلوک یکدست و wrapper)، +۵ تست FIX-M (ظرف دوپاراگرافی و پاراگراف+دکمه)، +۴ تست FIX-N (قاعده و کسکید مونواسپیس).
- ۳۰ تست E2E تعاملی کروم واقعی (از ۲۳): فاز «و» FIX-K (بازتولید دقیق گزارش در چت طولانی با محاسبهی
unicode-bidi/text-align) + فاز «ز» FIX-L/M/N با computed-style. - مجموع: ۲۶۱ تست سبز در ۶ سوئیت — بدون تغییر رفتاری روی صفحات کوتاه/عادی؛ همهی اصلاحات مسیرهای لبه (سند خیلی بلند، انفجار موتاسیون، فلیپ زبان، ظرف چندبلوک، کد) را پوشش میدهند.
📦 نصب و ارتقا
- فایل zip پیوست همین ریلیز را دانلود و اکسترکت کنید.
- در
chrome://extensionsحالت Developer mode را روشن کنید. - با Load unpacked پوشهی اکسترکتشده را انتخاب کنید.
- اگر نسخهی قدیمیتر (۱.۰.۰ / ۱.۱.۰ / ۱.۲.۰) را دارید، ابتدا حذفش کنید؛ تنظیمات شما (تاگلهای RTL/فونت و انتخاب فونت در
storage.sync) حفظ میشود.
🔐 سازگاری و دسترسیها
- Manifest V3 — کروم/اج و هر مرورگر MV3؛ آزمونشده روی Chrome 148.
- دسترسیها:
storage(تنظیمات و کش آپدیت)،alarms(بررسی دورهی آپدیت هر ۶ ساعت)،notifications(اعلان نسخهی جدید). پردازش تماماً لوکال؛ بدون ارسال هیچ دادهای. - سازگار با سختگیرانهترین CSPها؛ کاملاً آفلاین.
- بدون تغییر رفتاری روی صفحات کوتاه/عادی — همهی اصلاحات فقط مسیرهای لبه را پوشش میدهند.
ساختهشده با دقت برای وبِ فارسیخوان 🇮🇷 — kourosh · پروانه MIT · ۱۱ فونت متنباز فارسی (SIL OFL)
PERSIAN-FLOW-1.2.0
🎨 Persian Flow 1.2.0 — فونتهای فارسیِ انتخابی + رفع باگهای بصری
خلاصه مدیریتی: نسخهی ۱.۲.۰ بزرگترین قابلیتِ پس از انتشار اولیه را معرفی میکند: انتخاب یکی از ۱۱ فونت متنباز فارسی از داخل پاپآپ با پیشنمایش زنده و اعمال آنی و بدون ریلود حتی زیر سختترین CSPها. در کنار آن، دو باگ بصری گزارششده — بههمریختن ترتیب کلمات در جدولها/لیستهای شمارهدار و علامتنگرفتن پاراگرافها در استریمهای طولانی — ریشهای رفع شدند. پوشش آزمون از ۸۴ به ۱۱۸ تست واحد رسید و ۴۳ تست E2E جدید اضافه شد.
📦 دانلود: PersianFlow-1.2.0.zip · 📄 چنجلاگ کامل: CHANGELOG.md
🎨 قابلیت جدید: ۱۱ فونت فارسی متنباز، انتخابی از داخل پاپآپ
چرخدنده ⚙️ کنار لوگو — بدون هیچ تب جدیدی
- با کلیک روی چرخدنده، دیدِ «انتخاب فونت فارسی» داخل همان پاپآپ باز میشود.
- هر فونت با پیشنمایش زنده (عبارت نمونه رندرشده با همان فونت) نمایش داده میشود.
فهرست فونتها
| فونت | نوع | طراح / منبع |
|---|---|---|
| وزیرمتن (پیشفرض) | متغیر (وزن ۱۰۰–۹۰۰) | صابر راستیکردار |
| استعداد | متغیر (وزن ۱۰۰–۹۰۰) | امین عبدی |
| میخک | متغیر (وزن ۱۰۰–۹۰۰) | امین عبدی |
| ساحل | متغیر (وزن ۱۰۰–۹۰۰) | صابر راستیکردار |
| صمیم | ایستا (۴۰۰ + ۷۰۰) | صابر راستیکردار |
| شبنم | ایستا (۴۰۰ + ۷۰۰) | صابر راستیکردار |
| پرستو | ایستا (۴۰۰ + ۷۰۰) | صابر راستیکردار |
| ناهید | ایستا | صابر راستیکردار |
| گندم | ایستا | صابر راستیکردار |
| تنها | ایستا | صابر راستیکردار |
| بهداد | ایستا | font-store |
- همهی فونتها متنباز (SIL OFL / public domain) و از مخازن رسمی طراحان ایرانی دریافت شدهاند؛ لایسنس هر کدام در
fonts/licenses/بستهبندی شده است. - فونتهای تجاری محبوب (ایرانسنس، یکانبخ، بینازنین و…) بهدلیل محدودیت حق تکثیر و بازتوزیع عمداً قرار نگرفتهاند؛ ناهید جایگزین متنبازِ ظاهر محبوب بینازنین است.
اعمال آنی، مصون از CSP
- انتخاب همان لحظه روی تمام تبهای باز اعمال میشود — بدون ریلود؛
@font-faceتزریقی با آدرس مطلقchrome-extension://وreplaceSyncروی همان stylesheet زنده بازنویسی میشود و فقط فونتِ فعال لود میشود (۱۰ فونت دیگر هزینهی صفر شبکه/حافظه دارند). - با آزمایش زنده روی کروم ۱۴۸ اثبات شد: فونت حتی زیر
font-src 'none'هم لود میشود. - لیبل تاگل دوم داینامیک است: «فونت فارسی (وزیرمتن)» → «فونت فارسی (استعداد)» و…
- انتخاب کاربر در
storage.sync(کلیدpfFontFamily) ذخیره و بین دستگاهها سینک میشود؛ ارتقا از نسخههای قدیمیتر بدون هیچ مهاجرت دستی، به وزیرمتن پیشفرض میرسد.
🐛 چه باگهایی رفع شد؟
۱) ترتیب کلمات در جدولها و لیستهای شمارهدار بههم میریخت (گزارش کاربر — arena.ai و هر سایتی که متن را بین چند <span> خرد میکند)
- نشانه: متنِ داخل
td/liبا ترتیب کلماتِ بههمریخته نمایش داده میشد (شبیه «در که است غیرقانونی»!). - ریشه: درون یک بلوک، بعضی ریلهای متنی RTL میگرفتند و بعضی نه؛ در نتیجه الگوریتم دوطرفهی یونیکود (UBA) بین جزیرههای LTR/RTL ترتیب را قاطی میکرد.
- درمان (FIX-H): وقتی ریلی از یک بلوک متنیِ فارسیمحور (LI/TD/TH/BLOCKQUOTE/P/…) RTL گرفت، کل آن بلوک یکدست علامتگذاری میشود تا جهتِ پایهی کل پاراگراف یکی باشد. محافظها: سقف ۳۰۰۰ کاراکتر، تگهای چیدمانی (TR/TABLE/UL…) رد میشوند و بلوکهای داخل
nav/role=menuهرگز یکدست علامت نمیگیرند — منوها و چیدمان سایت سالم میمانند.
۲) بعضی پاراگرافهای پیامهای استریمشونده علامت نمیگرفتند (گزارش کاربر)
- نشانه: مثلاً در کلود، خط اولهای پیامِ در حال استریم راستچین/فونتدار میشد اما پاراگرافهای بعدی نه.
- ریشه: صف موتاسیون با
characterDataهای پیدرپی روی «همان گره متن» (الگوی استریم ریاکت) پر میشد و سقف ۲۰۰۰، گرههای جدید را بیصدا حذف میکرد؛ صفحههای بالای ۳۰۰ هزار کاراکتر هم از اسکن دورهای خارج بودند. - درمان (FIX-J): گرههای پیدرپیِ تکراری dedupe میشوند؛ در سرریز، بهجای دور ریختن، پرچم sweep فعال میشود و اسکن دورهای جبران میکند؛ سقف صفحهی قابل اسکن از ۳۰۰ هزار به ۶۰۰ هزار کاراکتر ارتقا یافت (با سقف گره برای حفظ پرفورمنس سیستمهای ضعیف).
۳) همگامسازی تست آپدیت (داخلی — نه باگ کاربر)
- فایل جدید
pf-fonts.js(رجیستری مشترک فونتها) به مرحلهی کلون اکستنشن در تست E2E بررسی آپدیت اضافه شد.
🏗️ زیرساخت
- رجیستری مشترک
pf-fonts.js: تعریف ۱۱ فونت (id، نام فارسی برای UI، خانوادهی CSS، فایلهای woff2 با وزن، variable یا static، طراح) بهعنوان منبع واحد بین content script و پاپآپ؛ تست jsdom همیشه بررسی میکند کهstyles.cssو فایلهای دیسک با رجیستری drift نشوند. - معماری قبلیِ تزریق فونت (ضد-CSP) پابرجاست و فقط به چند خانوادهی داینامیک تعمیم یافت — هندلِ stylesheet ثبت و با
replaceSyncروی همان sheet زنده بازنویسی میشود.
✅ آزمونها و اثبات
- ۱۱۸ تست واحد jsdom (از ۸۴ تست).
- ۲۰ تست E2E جدید (
test/e2e-1.2.0.mjs): ترتیب بصری = ترتیب منطقی در جدول/لیستِ رندرشده به سبک arena، استریم ۴۰ پاراگراف با پویش فشرده بدون هیچ گمشدن، تعویض فونت زنده از پاپآپ واقعی زیر CSP باfont-src 'none'، بازگشت تمیز به وزیرمتن، کنسول بدون خطا. - ۲۳ تست E2E تعاملی (
test/e2e-interactive.mjs+test/battery-page.html): باتری ۲۰+ حالت پیام واقعی (ایموجی/لینک/هشتگ/منشن/اعداد/RLM/بولد/قانون هایبرید…)، حباب flex با و بدون آواتار، استریم ریاکتی ۱۵ پیام، چرخش سراسری هر ۱۱ فونت (کلاس + computed + لود واقعی) و پایداری هدر پاپآپ زیر نشان آپدیت. - سوئیتهای قبلی همچنان سبز: e2e-chrome ۲۹، e2e-repro ۲۹، e2e-updater ۱۶.
- اسکرینشاتهای مدرک:
test/scramble-1.2.0.png،test/font-switch-1.2.0.png،test/popup-*.png(بایگانی داخلی).
📦 نصب و ارتقا
- فایل zip پیوست همین ریلیز را دانلود و اکسترکت کنید.
- در
chrome://extensionsحالت Developer mode را روشن کنید. - با Load unpacked پوشهی اکسترکتشده را انتخاب کنید.
- اگر نسخهی قدیمیتر (۱.۰.۰/۱.۱.۰) را دارید، ابتدا حذفش کنید؛ تنظیمات شما (تاگلهای RTL/فونت با کلیدهای storage بدون تغییر) حفظ میشود و فونت بهصورت پیشفرض وزیرمتن میماند.
🔐 سازگاری و دسترسیها
- Manifest V3 — کروم/اج و هر مرورگر MV3؛ آزمونشده روی Chrome 148.
- دسترسیها:
storage(تنظیمات و کش آپدیت)،alarms(بررسی دورهی آپدیت هر ۶ ساعت)،notifications(اعلان نسخهی جدید). پردازش تماماً لوکال؛ بدون ارسال هیچ دادهای. - سازگار با سختگیرانهترین CSPها؛ کاملاً آفلاین.
ساختهشده با دقت برای وبِ فارسیخوان 🇮🇷 — kourosh · پروانه MIT · ۱۱ فونت متنباز فارسی (SIL OFL)
PERSIAN-FLOW-1.1.0
🛠️ Persian Flow 1.1.0 — انتشار رفع باگ و پایداری
خلاصه مدیریتی: نسخهی ۱.۱.۰ هیچ قابلیت جدیدی اضافه نمیکند و تماماً به رفع ۹ باگ گزارششده/کشفشده و پایداری رفتار شناختهشده اختصاص دارد. هستهی تشخیص متن ترکیبی بازنویسی شد، تاگلها از هم باز شدند، صف موتاسیون دیگر گره از دست نمیدهد و پیامهای خردشدهی React یکپارچه رندر میشوند. پوشش آزمون از ۶۰ به ۸۴ تست واحد رسید و ۲۹ تست E2E روی کروم واقعی با CSP سختگیرانه اجرا شد.
📦 دانلود: persian-flow-1.1.0.zip · 📄 چنجلاگ کامل: CHANGELOG.md · 🔀 مقایسه با ۱.۰.۰: 1.0.0...1.1.0
🐛 چه باگهایی رفع شد؟
۱) متن فارسیِ دارای کلمات/اعداد لاتین راستچین نمیشد
- نشانه: پیامهایی مثل «سلام پوشه
uploadsرو پاک کن…» فقط فونت میگرفتند و چپچین میماندند. - ریشه: قانون نسبتِ ثابت ۴۰٪ برای متنهای واقعیِ دارای اصطلاحات فنی بیشازحد سختگیر بود.
- درمان: جایگزینی با تشخیص هایبرید دومرحلهای در
analyze(): شروع با فارسی ⇒ همیشه راستچین (همراستا با استانداردplaintext)؛ شروع با لاتین ⇒ راستچین اگر سهم حروف فارسی ≥ ۰٫۳۵ باشد. جملهی انگلیسیِ دارای یک کلمهی فارسی همچنان LTR میماند و فقط فونت میگیرد.
۲) خاموشکردن فونت، راستچینسازی را هم میپراند و روشنکردن مجدد نیاز به ریلود داشت
- نشانه: بعد از خاموش/روشنکردن تاگل فونت، RTL تا ریلود صفحه برنمیگشت؛ در چتهای سنگین (بالای ۳۰۰ هزار کاراکتر) اسکن مجدد اصلاً اجرا نمیشد.
- ریشه: تاگلها کل صفحه را strip و اسکن سراسری میکردند؛ در صفحات غولپیکر از سقف
MAX_PAGE_TEXTرد میشد و هیچ اتفاقی نمیافتاد. - درمان: معرفی فهرست
markedاز المانهای علامتخورده +reapplyMarked(): تغییر تنظیمات فقط همان المانها را بازارزیابی میکند — فوری، مستقل از بزرگی صفحه و بدون ریلود.
۳) خاموشکردن راستچینسازی، فونت را هم میپراند
- ریشه و درمان: همان باگ ردیف ۲؛ اکنون هر المان با وضعیت هر دو پرچم دوباره کلاس میگیرد، پس دو سوییچ کاملاً مستقلاند.
۴) گرههای موتاسیون در استریمهای طولانی بیصدا گم میشدند
- نشانه: در استریم زندهی چت، بخشی از پیامهای تازه راستچین/فونتدار نمیشدند.
- ریشه: بیش از سقف ۱۵۰ گره در هر فریم (
FLUSH_CAP) بیصدا دور ریخته میشد. - درمان: باقیماندهی صف به فریم بعدی منتقل میشود (
FIX-C)؛ رگرسیون آن با تست E2E شامل ۴۰۰ گره تثبیت شد.
۵) فونت رابط پاپآپ وزیرمتن نبود
- درمان: تزریق
@font-faceوزیرمتن در خودِpopup.html(در صفحات با منشأchrome-extension://آدرس نسبی امن است).
۶) پیام شروعشده با کلمهی لاتین اما غالباً فارسی اشتباهی LTR میماند
- نشانه: «
aptرو نصب کن و بعدnpmرو اجرا کن» با وجود فارسیبودنِ متن، چپچین میماند. - درمان: همان تشخیص هایبرید ردیف ۱ (حذف قانون تکعاملی «فقط اولین کاراکتر»).
۷) متن دارای کوتیشن/پرانتز/ایموجی «ناقص و بههمریخته» نمایش داده میشد (گزارش کاربر + اسکرینشات)
- ریشه: حبابهای flex که متن را بین چند
<span>تکهتکه میکنند (الگوی رندر React)؛ ظرف flex هر span را پاراگراف جدا میدید و جزیرههای bidi بههم میریخت. - درمان: این ظرفها — فقط وقتی همهی فرزندان inline باشند — یکسره بلوک متنی میشوند (
__pf-rtlflex__) و باdirection: rtlروی ظرف، ترتیب بصری فرگمنتها یکپارچه میگردد؛justify-content: *-endهم با__pf-rtlflexend__جبران میشود تا حباب کاربر همچنان به لبهی راست بچسبد. حضور آواتار،img، دکمه یا منوی لینکمحور این حالت را غیرفعال میکند تا لیآوت سایت سالم بماند.
۸) علائم کهنه روی کانتینرِ تغییرشکلیافته باقی میماند (باگشکار داخلی)
- ریشه: کانتینر flex که ابتدا فقط فرگمنت متنی داشت و بعداً React یک آواتار/دکمه/بلوک داخلی به آن تزریق میکرد، کلاسهای
__pf-rtlflex__/directionرا نگه میداشت؛ چون کشjustifyContentهرگز بیاعتبار نمیشد و والدِ علامتدار در موتاسیونِ «افزودن فرزند» به صف نمیرفت. - درمان: با هر تغییر ساختاری کش بیاعتبار میشود و والد علامتدار به صف پردازش میرود؛ علائم کهنه پاک و فرگمنتهای متنیِ سالم مستقل دوباره علامت میگیرند (
FIX-F).
۹) عبور متن از سقف ۳۰۰ کاراکتر، علائم کهنه را حبس میکرد (باگشکار داخلی)
- ریشه: وقتی متن یک کانتینر علامتخورده (مثلاً پس از ویرایش پیام) از
MAX_CONTAINER_TEXTرد میشد، تابع بدون پاکسازیreturnمیشد وdirection/کلاسهای کهنه میماندند. - درمان: عبور از سقف اکنون «برچیدن همزمان کلاسها، کشها و
dirذخیرهشده» را هم اجرا میکند (clearEl).
10) رفع باگ اعلان اپدیت: حالا اعلان اپدیت به درستی اعمال میشود
⚡ بهبودهای عملکرد (سیستمهای ضعیف)
- اعمال تغییر تنظیمات بدون
requestIdleCallbackو بدون اسکن سراسری ⇒ تاگل فوری بدون حسِ هنگ (دیبانس ۶۰ms برای تاگلهای پشتسرهم). - هرس خودکار فهرست المانهای علامتخوردهی حذفشده از DOM ⇒ بدون نشت حافظه در سشنهای طولانی.
- حفظ بهینهسازیهای پیشین: تحلیل تکپاس بدون regex، کش امضای متن (
WeakMap)، حذف گرههای پوشششده توسط اجداد از صف، اسکن دورهای فقط وقتی صفحه «کثیف» است و توقف کامل در تب پنهان.
📦 نصب و ارتقا
- فایل zip پیوست همین ریلیز را دانلود و اکسترکت کنید.
- در
chrome://extensionsحالت Developer mode را روشن کنید. - با Load unpacked پوشهی اکسترکتشده را انتخاب کنید.
- اگر نسخهی ۱.۰.۰ را دارید، ابتدا حذفش کنید؛ تنظیمات شما (کلیدهای storage بدون تغییر ماندهاند) حفظ میشود.
🔐 سازگاری و دسترسیها
- Manifest V3 — کروم/اج و هر مرورگر MV3؛ آزمونشده روی Chrome 148.
- تنها دسترسی:
storage. پردازش تماماً لوکال؛ بدون ارسال هیچ دادهای. - سازگار با سختگیرانهترین CSPها؛ کاملاً آفلاین.
ساختهشده با دقت برای وبِ فارسیخوان 🇮🇷 — kourosh · پروانه MIT · فونت وزیرمتن (OFL)
PERSIAN-FLOW-1.0.0
🎉 Persian Flow 1.0.0 — اولین انتشار
Persian Flow راستچینسازی خودکار پیامها و متنهای فارسی در هر وبسایت + فونت وزیرمتن داخلی است — سبک، آفلاین، مصون از CSP و بدون شکستن چیدمان سایتها.
📦 دانلود: persian-flow-V1.0.0.zip
✨ قابلیتهای این نسخه
🔤 فونت وزیرمتن کاملاً داخلی
- وزیرمتن متغیر (وزن ۱۰۰–۹۰۰) از داخل پکیج اکستنشن لود میشود — بدون نیاز به اینترنت.
- تزریق
@font-faceبا آدرس مطلقchrome-extension://وadoptedStyleSheets؛ سایتهایی مثل GitHub که با CSP جلوی فونت خارجی را میگیرند، هیچ اثری ندارند.
⟵ راستچینسازی هوشمند و ایمن
- تشخیص ترکیب فارسی/انگلیسی: متن فارسیِ غالب راستچین میشود؛ جملهی انگلیسیِ دارای کلمهی فارسی فقط فونت میگیرد.
- هدفگیری نزدیکترین کانتینر متنی، نه کل سایت — بلاکهای چیدمانی (flex/grid/جدولها) دستنخورده میمانند.
- استفاده از
unicode-bidi: plaintextبهجایdirectionروی بلوکها تا لیآوت حبابهای چت نشکند.
💬 پشتیبانی از وبِ امروز
- چتها، سشنها و سایدبار سایتهای AI (ساختارهای flex و spanهای تودرتو).
- ایموجیها خنثی شمرده میشوند؛ فونت ایموجی خراب نمیشود.
- Shadow DOM و وبکامپوننتهای تازهنصبشده با پروب سبک کشف میشوند.
- فیدها و استریم زندهی پیام با MutationObserver بهینه پایش میشوند.
⌨️ فیلدهای هوشمند
input/textarea/contenteditableهنگام تایپ فارسی باdir=autoبومی راستچین میشوند و با پاکشدن متن به حالت سایت برمیگردند.
🔔 اعلان آپدیت
- مقایسهی تگ آخرین ریلیز گیتهاب با نسخهی نصبشده در پاپآپ؛ کش ۶ ساعته و بدون پرمیشن اضافه.
⚡ بهینه برای سیستمهای ضعیف
- تحلیل تکپاس
charCodeبدون regex + کش امضای متن (WeakMap). - حذف گرههای تکراری صف موتاسیون و سقف پردازش در هر فریم.
- اسکن اولیه با تأخیر ۱۵۰ms و توقف کامل پردازش در تب پنهان (مصرف ۰٪).
🧪 تست
- ۴۱+ تست خودکار jsdom و صفحهی تست محلی
test-page.htmlبا CSP سختگیرانهی شبیه GitHub (۹ سناریو).
📦 نصب
- zip پیوست را اکسترکت کنید.
- در
chrome://extensionsحالت Developer mode را روشن کنید. - با Load unpacked پوشهی اکسترکتشده را انتخاب کنید.
🔐 دسترسیها
- تنها دسترسی:
storage· Manifest V3 · پردازش تماماً لوکال و آفلاین.
ساختهشده با دقت برای وبِ فارسیخوان 🇮🇷 — kourosh · پروانه MIT · فونت وزیرمتن (OFL)