مرحباً ![]()
الفكرة الأساسية
كان الهدف هو بناء حمّال عظمي (skeleton loader) يُولَّد من واجهة Discourse الفعلية، بدلاً من الاعتماد على قالب حمّال عظمي مُرمَّز مسبقاً.
يسمح المُنشئ (builder) للمشرف باختيار عناصر حقيقية في الصفحة وتحويلها إلى مناطق حمّال عظمي.
على سبيل المثال:
.title
.avatar
.topic-excerpt
.btn
.category-breadcrumb
ثم يستخدم المكوّن هذه المُنتقيات (selectors) لتوليد الحمّال العظمي وقت التشغيل.
معاينة الحمّال العظمي
الجزء المثير للاهتمام هو أن المشرف لا يحتاج إلى كتابة المُنتقيات يدوياً. يحلل المُنشئ العنصر المحدد ويولّد عدة مُنتقيات مرشحة.
تبيّن أن توليد مُنتقيات مفيدة أصعب مما كان متوقعاً
كانت إحدى أولى المشكلات التي واجهتني هي توليد المُنتقيات.
يمكن لتنفيذ بسيط أن ينتج بسهولة شيئاً مثل:
.container.list-container.--topic-list .row.full-width .contents ...
صحيح تقنياً، لكنه محدد للغاية ليكون إعداداً قابلاً لإعادة الاستخدام.
يمكن أن يصبح الأمر أسوأ مع الأيقونات، حيث قد يتضمن المُنتق المولّد تفاصيل تنفيذية مثل الفئات المتعلقة بـ SVG.
ما أردته حقاً كان شيئاً أقرب إلى:
.badge-category__name
أو:
.badge-category__wrapper .d-icon
بدلاً من مُنتق يصف مسار DOM بالكامل.
لذلك أصبح المُنشئ الآن يولّد عدة مرشحين ويقيّمهم بناءً على أشياء مثل:
- عمق المُنتق
- عدد الفئات
- التطابقات المتكررة
- فئات مرتبطة بالحالة
- فئات SVG/الأيقونات التقنية
- ما إذا كان المُنتق لا يزال يطابق العنصر المحدد
النتيجة هي قائمة من المُنتقيات الموصى بها يمكن للمشرف الاختيار منها أو تحريرها يدوياً.
العناصر المخفية
يوجد أيضاً مُنتق منفصل للعناصر التي يجب أن تختفي ببساطة أثناء عرض الحمّال العظمي.
على سبيل المثال:
.alert.alert-info
تبيّن أن هذا مفيد لأشياء مثل لافتات الإعلانات أو الإشعارات المؤقتة التي توجد أثناء البناء/الاختبار ولكن يجب ألا تؤثر على تخطيط الحمّال العظمي.
كانت إحدى المشكلات المثيرة للاهتمام هنا هي أن إخفاء عنصر يجب ألا يترك مساحة فارغة خلفه.
لذلك لا يُعامل العناصر المستبعدة فقط كقائمة بسيطة لـ display: none - بل يجب أن يفهم حساب الهندسة أيضاً أن العنصر ليس جزءاً من التخطيط النهائي.
معاينة الحمّال العظمي
التنقل
ربما كانت أكبر تحدٍّ هو التنقل.
كان السلوك المطلوب هو:
نقرة
↓
عرض الحمّال العظمي فوراً
↓
تغيير Discourse للمسار
↓
ظهور DOM الوجهة
↓
إخفاء الحمّال العظمي
كان الحل الجذاب هو التعمق في دورة حياة التنقل والانتظار حتى يستقر DOM بالكامل.
تبيّن أن هذا كان النهج الخاطئ.
في لحظة معينة، كان الحمّال العظمي يبقى مرئياً لعدة ثوانٍ بعد أن أصبح المحتوى الفعلي موجوداً بالفعل.
كان الدرس بسيطاً:
يجب ألا يصبح الحمّال العظمي بوابة جاهزية DOM.
بمجرد أن تحتوي الوجهة على محتوى حقيقي كافٍ للتعامل مع الأمر، يجب أن يتراجع الحمّال العظمي.
حدث ذلك فرقاً كبيراً في السرعة المُدركة للتنقل.
مقاسات العرض (Viewports)
تتمتع Discourse بالفعل بنظام مقاسات عرض متجاوب، لذا يستخدم المكوّن الآن نفس تجريد نقاط الكسر (breakpoints):
xs
sm
md
lg
xl
2xl
يمكن أيضاً تجميع إعداد الحمّال العظمي كالتالي:
mobile → xs / sm
tablet → md
desktop → lg / xl / 2xl
all → everything
هذا يعني أن المكوّن لا يحتاج إلى معرفة القيم الفعلية بالبكسل على الإطلاق.
إذا غيّرت Discourse قيم نقاط الكسر، فلا يجب إعادة كتابة مكوّن الحمّال العظمي حول أرقام جديدة مُرمَّزة مسبقاً.
تخزين مؤقت للهندسة (Geometry caching)
تخبرنا المُنتقيات ماذا يجب عرضه، لكنها لا تخبرنا بالضبط أين يجب أن تظهر أشكال الحمّال العظمي.
لذلك، أضفت التقاط الهندسة.
يمكن للمُنشئ قياس المناطق المُعرضة الفعلية وتخزين هندستها حتى يتمكن المحمّل من عرض حمّال عظمي للوجهة فوراً أثناء تنقل SPA.
يوجد أيضاً خيار صريح لقفل الهندسة للحالات التي لا أريد فيها أن تغيّر الزيارات اللاحقة الهندسة المرجعية باستمرار.
كان هذا تمييزاً مهماً آخر:
تعريف المُنتق والهندسة المُعرضة شيآن مختلفان.
المسودات
شيء آخر أصبح ضرورياً هو حالة المسودة.
لم أريد هذا سير العمل:
فتح المُنشئ
→ قضاء 10 دقائق في ضبطه
→ إغلاق المُنشئ
→ يختفي كل شيء
لذلك يحتفظ المُنشئ بمسودة قيد الإنشاء بشكل منفصل عن إعداد المظهر الفعلي.
المسودة محددة بمجموعة الصفحة/المسار/مقاس العرض، لذا على سبيل المثال:
topic-list / lg
topic-list / md
topic-list / xs
لا تتجاوز بعضها البعض عن طريق الخطأ.
إغلاق المُنشئ لا يدمر العمل.
التراجع (Undo)
بمجرد أن أصبح المُنشئ تفاعلياً أكثر، أصبح نظام التراجع شبه حتمي.
يخزن المُنشئ لقطات من حالة إعداده:
{
"regions": \[\],
"excludes": \[\]
}
بدلاً من محاولة الحفاظ على سجل لعمليات DOM.
يجعل ذلك نظام التراجع أسهل بكثير في الفهم ويحافظ أيضاً على استقلاليته عن DOM الصفحة الفعلي.
هذا المشروع قيد التطوير النشط. آمل أن يكون جاهزاً قريباً لمكوّن مظهر! ![]()




