# دليل المساهمة في الإضافات يعتمد نظام إضافات Voyager في المقام الأول على الإضافات التعريفية: يصف `plugin.json` معلومات الإضافة وعمليات DOM، بينما يصف CSS التغييرات البصرية. لا تشغّل الإضافة JavaScript بعيدًا؛ بل يفسّر محرك الإضافات المدمج في Voyager ملف manifest والأنماط. هذا يجعل الإضافات أسهل في المراجعة والصيانة. إذا أردت المساهمة بإضافة، فابدأ من هنا. ## المسار الموصى به 1. تأكد أولًا أن الفكرة مناسبة كإضافة: عرض القراءة، إصلاحات التخطيط، تعديلات السمة، إخفاء أو تمييز عناصر الصفحة، والتكييف البسيط للمواقع غالبًا تناسب الإضافات التعريفية. 2. افتح Issue أو PR في مستودع Voyager الرئيسي أولًا. اشرح المشكلة، والموقع المستهدف، والاختلاف عن الإضافات الموجودة. 3. استخدم `plugin.json` للبيانات الوصفية، ومطابقات المواقع، والإعدادات، والمساهمات. 4. ضع الأنماط في `style.css` داخل نفس المجلد، ثم أشر إليه من `contributes.styles`. 5. اختبر محليًا وأرفق في PR صفحات اختبار أو لقطات شاشة أو تسجيلًا قصيرًا. سيقرر المشرفون ما إذا كانت الإضافة جاهزة للدخول في catalog الرسمي. ## نطاق الإضافة ينبغي أن يحدد نطاق الإضافة المشكلة التي يريد المستخدم حلها، لا أن يُقسّم آليًا حسب المنصة. إذا كانت الوظيفة نفسها تقدم تجربة وإعدادات شبه متطابقة على عدة منصات، فالأفضل إنشاء إضافة واحدة متعددة المنصات. مثلًا يمكن لوظائف عرض القراءة أو تجربة التنقل أو تنسيق كتل الكود أن تغطي Claude وChatGPT وغيرهما عبر عدة `matches`. أما إذا احتاجت كل منصة إلى إعدادات أو منطق DOM أو نصوص مختلفة جدًا، فالفصل إلى إضافات متعددة يكون أوضح. لا تضع وظائف غير مترابطة في إضافة واحدة لمجرد أنها "تفعل كل شيء"؛ الأفضل أن تحل الإضافة مشكلة واحدة واضحة. قاعدة سريعة: - الهدف نفسه والإعدادات نفسها، والاختلاف في المحددات فقط: فضّل إضافة واحدة. - الموضوع نفسه لكن التجربة تختلف كثيرًا حسب المنصة: يمكن الفصل مع إبقاء الأسماء والأوصاف مترابطة. - الأهداف مختلفة: لا تدمجها. ## تجنب الإضافات المكررة قبل الإرسال، راجع متجر الإضافات والإضافات الرسمية الموجودة. إذا كانت هناك إضافة جيدة بالفعل، فالأفضل تحسينها بدل إنشاء إضافة مشابهة. لا تستحق الإضافة المكررة القبول إلا إذا قدمت تحسينًا واضحًا، مثل: - دعم منصة مهمة لا تدعمها الإضافة الأصلية. - إصلاح مشكلة توافق لا تستطيع الإضافة الأصلية حلها. - تحسين واضح في الأداء أو قابلية الوصول أو الصيانة. - تقديم تجربة مستخدم مختلفة ومفيدة، لا مجرد اسم جديد أو تعديلات بسيطة في النمط. بهذا يبقى المتجر أنظف وأسهل للاختيار. ## مثال بسيط ```json { "id": "your-name.example-plugin", "name": "Example Plugin", "version": "1.0.0", "description": "A short description of what this plugin improves.", "author": "your-name", "category": "readability", "license": "MIT", "engine": ">=1.0.0", "tier": "declarative", "matches": ["https://claude.ai/*"], "contributes": { "styles": [{ "file": "style.css" }], "domOps": [ { "op": "addClass", "target": "body", "className": "gv-plugin-example" } ] } } ``` يمكن كتابة `style.css` كأي CSS عادي، لكن يُفضّل أن تبقى كل أنماط الإضافة تحت فئة خاصة بك تبدأ بـ `gv-plugin-*`: ```css .gv-plugin-example .some-target { max-width: 880px; } ``` ## ملاحظات manifest - استخدم بادئة للمؤلف أو أسلوب نطاق عكسي في `id`، مثل `your-name.reading-width`، لتجنب التعارض. - اجعل `matches` محدودة قدر الإمكان، ولا تطابق إلا المواقع التي تحتاج الإضافة أن تعمل فيها فعلًا. - يمكن لإضافة واحدة أن تحتوي عدة `matches` إذا كانت هذه المنصات تشترك في هدف وظيفي واضح. - القيم الموصى بها لـ `category`: `render-fix` أو `theme` أو `layout` أو `readability` أو `productivity` أو `integration` أو `other`. - اكتب في `engine` نسخة محرك الإضافات المطلوبة. يمكن الرجوع إلى الإضافات الرسمية كأمثلة. - أضف `i18n` للصينية والإنجليزية واللغات الشائعة الأخرى عندما يكون ذلك ممكنًا. ## قيود CSS والموارد تُفحص الإضافات التعريفية كمدخلات غير موثوقة، لذلك أبق الموارد ذاتية الاحتواء: - لا تستخدم `@import`. - لا تشير إلى صور بعيدة أو خطوط خارجية أو CSS بعيد. - يمكنك استخدام CSS عادي، وخصائص مخصصة، واستبدالات قيم الإعدادات التي يوفرها Voyager. - استخدم بادئة `gv-plugin-` في أسماء الفئات لتجنب تلويث الموقع المضيف أو أنماط Voyager. إذا احتاجت الإضافة إلى إعدادات، فابدأ بالقيم الرقمية إن أمكن. مثلًا يمكن لإضافة عرض القراءة أن تكتب قيمة الإعداد في متغير CSS ثم يستخدمه CSS. ## حدود عمليات DOM تدعم الإضافات التعريفية حاليًا العمليات التالية: - `addClass`: إضافة فئة إلى العناصر المستهدفة. - `setAttribute`: ضبط سمة. - `setStyle`: ضبط نمط inline أو متغير CSS. - `hide`: إخفاء العناصر المستهدفة. يمكن أن يكون الهدف محدد CSS أو محددًا دلاليًا توفره محولات المواقع في Voyager. المحددات الدلالية غالبًا أكثر ثباتًا، لكنها تتطلب أن يوفر محول الموقع هذا الهدف. يجب أن تكون العمليات التعريفية قابلة للتراجع وآمنة عند تكرار تنفيذها. لا تعتمد على حالة صفحة لمرة واحدة، ولا تفترض أن DOM لن يتغير. ## متى لا تناسب الإضافة العادية إذا كانت الوظيفة تحتاج إلى تشغيل JavaScript، أو اعتراض الطلبات، أو قراءة/كتابة بيانات Voyager الداخلية، أو تعتمد على منطق تشغيل معقد، فهي لا تناسب إضافة تعريفية عادية. افتح Issue أولًا واشرح الحاجة. إذا كانت تحتاج فعلًا إلى قدرة مدمجة، فقد ندرس تنفيذها داخل مستودع Voyager كإضافة builtin/native، مثل Formula Copy. ## قبل فتح PR - الإضافة معطلة افتراضيًا، والمستخدم يفعّلها بنفسه. - تأكدت من عدم وجود إضافة شبه مطابقة؛ إن وجدت، حسّن الإضافة الموجودة أولًا. - اختبرت الموقع المستهدف في السمة الفاتحة والداكنة. - لا تغطي `matches` مواقع غير مرتبطة. - لا توجد موارد بعيدة. - يحتوي مجلد الإضافة على `plugin.json` وملفات CSS اللازمة وREADME قصير. - يوضح وصف PR صفحات الاختبار أو اللقطات أو التسجيلات، ومناطق الصفحة المتأثرة. حافظ عليها بسيطة ومحددة وقابلة للتراجع. الإضافة التي تحل مشكلة واحدة واضحة تكون أسهل في الدمج والصيانة.