إتاحة CSS-in-JS في "أدوات مطوري البرامج"

Alex Rudenko
Alex Rudenko

تتناول هذه المقالة إتاحة استخدام CSS-in-JS في "أدوات مطوري البرامج" بدءًا من الإصدار Chrome 85، وما نعنيه بشكل عام بلغة CSS-in-JS وأوجه اختلافها عن CSS العادية التي كانت متوافقة منذ فترة طويلة مع أدوات مطوّري البرامج.

ما هي CSS-in-JS؟

تعريف CSS-in-JS غامض إلى حد ما. وهو منهج لإدارة رمز CSS باستخدام JavaScript. على سبيل المثال، قد يعني ذلك أنّه يتم تحديد محتوى CSS باستخدام JavaScript ويتم إنشاء مخرجات CSS النهائية بسرعة من خلال التطبيق.

في سياق أدوات مطوّري البرامج، يعني مصطلح CSS-in-JS أنّه تم إدخال محتوى CSS في الصفحة باستخدام واجهات برمجة تطبيقات CSSOM. يتم إدخال CSS العادي باستخدام عناصر <style> أو <link>، ويكون له مصدر ثابت (مثل عقدة DOM أو مورد شبكة). في المقابل، غالبًا ما لا يكون لـ CSS-in-JS مصدر ثابت. والحالة الخاصة هنا هي أنّه يمكن تعديل محتوى عنصر <style> باستخدام واجهة برمجة تطبيقات CSSOM، ما يؤدي إلى عدم تزامن المصدر مع ورقة أنماط CSS الفعلية.

إذا كنت تستخدم أي مكتبة CSS-in-JS (مثل styled-component أو Emotion أو JSS)، قد تُدخِل المكتبة أنماطًا باستخدام واجهات برمجة تطبيقات CSSOM ضمن الخيارات المتقدمة، وذلك بناءً على وضع التطوير والمتصفّح.

لنلقِ نظرة على بعض الأمثلة حول كيفية إدخال ورقة أنماط باستخدام واجهة برمجة تطبيقات CSSOM على نحو مشابه لمكتبات CSS-in-JS.

// Insert new rule to an existing CSS stylesheet
const element = document.querySelector('style');
const stylesheet = element.sheet;
stylesheet.replaceSync('.some { color: blue; }');
stylesheet.insertRule('.some { color: green; }');

يمكنك أيضًا إنشاء ورقة أنماط جديدة تمامًا:

// Create a completely new stylesheet
const stylesheet = new CSSStyleSheet();
stylesheet.replaceSync('.some { color: blue; }');
stylesheet.insertRule('.some { color: green; }');

// Apply constructed stylesheet to the document
document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet];

دعم CSS في "أدوات مطوري البرامج"

في "أدوات مطوري البرامج"، الميزة الأكثر استخدامًا عند التعامل مع CSS هي جزء الأنماط. في لوحة الأنماط، يمكنك الاطّلاع على القواعد التي تنطبق على عنصر معيّن ويمكنك تعديل القواعد والاطّلاع على التغييرات في الصفحة في الوقت الفعلي.

قبل العام الماضي، كان التوافق مع قواعد CSS المعدَّلة باستخدام واجهات برمجة تطبيقات CSSOM محدودًا إلى حد ما: كان بإمكانك الاطّلاع على القواعد المطبَّقة فقط ولكن تعذّر عليك تعديلها. كان هدفنا الرئيسي في العام الماضي هو السماح بتعديل قواعد CSS-in-JS باستخدام جزء الأنماط. في بعض الأحيان، نستدعي أنماط CSS-in-JS "Builded" للإشارة إلى أنه تم إنشاؤها باستخدام واجهات برمجة تطبيقات الويب.

سنعرض الآن تفاصيل حول عمليات تعديل الأنماط في "أدوات مطوري البرامج".

آلية تعديل النمط في "أدوات مطوري البرامج"

آلية تعديل النمط في &quot;أدوات مطوري البرامج&quot;

عند اختيار عنصر في "أدوات مطوري البرامج"، يتم عرض جزء الأنماط. يصدر لوحة الأنماط أمر CDP يسمى CSS.getMatchedStylesForNode للحصول على قواعد CSS التي تنطبق على العنصر. يشير الاختصار CDP إلى بروتوكول أدوات مطوري البرامج في Chrome، وهو عبارة عن واجهة برمجة تطبيقات تتيح للواجهة الأمامية لأدوات مطوّري البرامج الحصول على معلومات إضافية حول الصفحة التي تم فحصها.

عند استدعاء الدالة CSS.getMatchedStylesForNode، تحدّد جميع أوراق الأنماط في المستند ويحلّلها باستخدام محلّل CSS للمتصفّح. تنشئ بعد ذلك فهرسًا يربط كل قاعدة CSS بموضع في مصدر ورقة الأنماط.

وقد تتساءل عن سبب الحاجة إلى تحليل CSS مرة أخرى. والمشكلة هنا هي أنه لأسباب تتعلق بالأداء، لا يهتم المتصفح نفسه بمواضع المصدر لقواعد CSS، وبالتالي لا يخزِّنها. مع ذلك، تحتاج "أدوات مطوري البرامج" إلى المواضع المصدر لإتاحة التعديل في CSS. لا نريد أن يدفع مستخدمو Chrome العاديون عقوبة الأداء، ولكننا نريد أن يتمكّن مستخدمو "أدوات مطوري البرامج" من الوصول إلى مواضع المصادر. يعالج نهج إعادة التحليل هذا حالتَي الاستخدام مع الحد الأدنى من الجوانب السلبية.

بعد ذلك، تطلب عملية تنفيذ CSS.getMatchedStylesForNode من محرّك نمط المتصفّح توفير قواعد CSS التي تتطابق مع العنصر المحدّد. وأخيرًا، تربط الطريقة القواعد التي يعرضها محرك النمط برمز المصدر وتوفر استجابة منظمة حول قواعد CSS بحيث تعرف أدوات مطوّري البرامج أي جزء من القاعدة هو المحدِّد أو الخصائص. ويسمح هذا الإجراء لـ "أدوات مطوّري البرامج" بتعديل أداة الاختيار والخصائص بشكلٍ مستقل.

لنلقِ الآن نظرة على التعديل. تذكر أن CSS.getMatchedStylesForNode تعرض مواضع المصدر لكل قاعدة؟ هذا أمر بالغ الأهمية للتعديل. عند تغيير قاعدة، تصدر "أدوات مطوري البرامج" أمر CDP آخر يؤدي إلى تعديل الصفحة فعليًا. يتضمن الأمر الموضع الأصلي للجزء الذي يتم تحديثه والنص الجديد الذي يجب تحديث الجزء به.

في الخلفية، عند التعامل مع طلب التعديل، تعدِّل "أدوات مطوّري البرامج" ورقة الأنماط المستهدَفة. وتعمل أيضًا على تعديل نسخة مصدر ورقة الأنماط الذي يحتفظ به وتعديل مواضع المصدر للقاعدة المعدَّلة. استجابةً لطلب التعديل، تستعيد الواجهة الأمامية في "أدوات مطوري البرامج" المواضع المعدَّلة لجزء النص الذي تم تعديله للتو.

وهذا يفسر عدم نجاح تعديل CSS-in-JS في أدوات مطوّري البرامج: لا لدى CSS-in-JS مصدر فعلي مخزّن في أي مكان وتتواجد قواعد CSS في ذاكرة المتصفح في هياكل بيانات CSSOM.

كيف أتحنا استخدام CSS-in-JS

ولدعم تعديل قواعد CSS-in-JS، قررنا أن الحل الأفضل هو إنشاء مصدر لأوراق الأنماط التي تم إنشاؤها ويمكن تعديلها باستخدام الآلية الحالية الموضحة أعلاه.

الخطوة الأولى هي إنشاء النص المصدر. يخزِّن محرّك نمط المتصفّح قواعد CSS في الفئة CSSStyleSheet. هذه الفئة هي الفئة التي يمكنك إنشاء مثيلاتها من JavaScript كما ناقشنا سابقًا. التعليمات البرمجية لإنشاء النص المصدر هي كما يلي:

String InspectorStyleSheet::CollectStyleSheetRules() {
  StringBuilder builder;
  for (unsigned i = 0; i < page_style_sheet_->length(); i++) {
    builder.Append(page_style_sheet_->item(i)->cssText());
    builder.Append('\n');
  }
  return builder.ToString();
}

يكرر القواعد الموجودة في مثيل CSSStyleSheet وينشئ سلسلة واحدة منه. يتم استدعاء هذه الطريقة عند إنشاء مثيل لفئة InspectorStyleSheet. تعمل فئة InspectorStyleSheet على التفاف مثيل CSSStyleSheet واستخراج البيانات الوصفية الإضافية المطلوبة في أدوات مطوّري البرامج:

void InspectorStyleSheet::UpdateText() {
  String text;
  bool success = InspectorStyleSheetText(&text);
  if (!success)
    success = InlineStyleSheetText(&text);
  if (!success)
    success = ResourceStyleSheetText(&text);
  if (!success)
    success = CSSOMStyleSheetText(&text);
  if (success)
    InnerSetText(text, false);
}

في هذا المقتطف، نرى CSSOMStyleSheetText الذي يستدعي CollectStyleSheetRules داخليًا. يتم استدعاء CSSOMStyleSheetText إذا كانت ورقة الأنماط غير مضمّنة أو ورقة أنماط مورد. في الأساس، يتيح هذان المقتطفان إمكانية التعديل الأساسي لأوراق الأنماط التي تم إنشاؤها باستخدام الدالة الإنشائية new CSSStyleSheet().

الحالة الخاصة هي أوراق الأنماط المرتبطة بعلامة <style> والتي تم تغييرها باستخدام واجهة برمجة تطبيقات CSSOM. في هذه الحالة، تحتوي ورقة الأنماط على نص المصدر وقواعد إضافية غير موجودة في المصدر. لمعالجة هذه الحالة، نقدّم طريقة لدمج هذه القواعد الإضافية في النص المصدر. وهذا الترتيب مهمّ لأنّه يمكن إدراج قواعد CSS في منتصف نص المصدر الأصلي. على سبيل المثال، تخيَّل أنّ العنصر <style> الأصلي يحتوي على النص التالي:

/* comment */
.rule1 {}
.rule3 {}

بعد ذلك، أدرجت الصفحة بعض القواعد الجديدة باستخدام واجهة برمجة تطبيقات JS التي ينتج عنها ترتيب القواعد التالي: .rule0 و.rule1 و.rule2 و.rule3 و.rule4 يجب أن يكون نص المصدر الناتج بعد عملية الدمج على النحو التالي:

.rule0 {}
/* comment */
.rule1 {}
.rule2 {}
.rule3 {}
.rule4 {}

يُعد الاحتفاظ بالتعليقات الأصلية والمسافة البادئة أمرًا مهمًا في عملية التعديل لأن مواضع النص المصدر للقواعد يجب أن تكون دقيقة.

هناك جانب آخر خاص بأوراق أنماط CSS-in-JS هو أنّه يمكن أن تغيّرها الصفحة في أي وقت. إذا لم تكن قواعد CSSOM الفعلية متزامنة مع الإصدار النصي، لن تنجح عملية التعديل. لهذا السبب، أطلقنا ما يُعرف باسم الاستقصاء الذي يسمح للمتصفح بإرسال إشعار إلى الجزء الخلفي من "أدوات مطوّري البرامج" عند تغيير ورقة أنماط. ثم تتم مزامنة أوراق الأنماط التي تم تغييرها أثناء الاستدعاء التالي إلى CSS.getMatchedStylesForNode.

مع وجود كل هذه الأجزاء في مكانها الصحيح، يعمل التعديل باستخدام CSS في JS، لكننا أردنا تحسين واجهة المستخدم للإشارة إلى ما إذا كان قد تم إنشاء ورقة أنماط أم لا. لقد أضفنا سمة جديدة تُسمى isConstructed إلى CSS.CSSStyleSheetHeader في CDP، والتي تستخدمها الواجهة الأمامية لعرض مصدر قاعدة CSS بشكل صحيح:

ورقة أنماط قابلة للإنشاء

الاستنتاجات

في ما يلي ملخّص لقصتنا هنا، استعرضنا حالات الاستخدام ذات الصلة المتعلقة بخدمة CSS-in-JS التي لم توفّرها أدوات مطوّري البرامج، وشرحنا الحلّ المناسب لحالات الاستخدام هذه. الجزء المثير من عملية التنفيذ هذه هو أنّنا تمكّنا من الاستفادة من الوظائف الحالية من خلال احتواء قواعد CSSOM على نص مصدر عادي، وذلك مع تجنُّب الحاجة إلى إعادة تصميم بنية تعديل النمط بالكامل في أدوات مطوّري البرامج.

لمزيد من المعلومات الأساسية، يُرجى الاطّلاع على اقتراح التصميم أو خطأ التتبُّع في Chromium الذي يشير إلى جميع رموز التصحيح ذات الصلة.

تنزيل قنوات المعاينة

يمكنك استخدام Chrome كناري أو إصدار مطوّري البرامج أو الإصدار التجريبي من المتصفِّح التلقائي للتطوير. وتتيح لك قنوات المعاينة هذه الوصول إلى أحدث ميزات "أدوات مطوري البرامج" واختبار أحدث واجهات برمجة التطبيقات للأنظمة الأساسية للويب والعثور على المشاكل على موقعك الإلكتروني قبل أن يفعلها المستخدمون.

التواصل مع فريق "أدوات مطوري البرامج في Chrome"

يمكنك استخدام الخيارات التالية لمناقشة الميزات والتغييرات الجديدة في المشاركة أو مناقشة أي معلومات أخرى متعلّقة بأدوات مطوري البرامج.

  • يمكنك إرسال اقتراح أو ملاحظات إلينا عبر crbug.com.
  • يمكنك الإبلاغ عن مشكلة في "أدوات مطوري البرامج" باستخدام خيارات إضافية   المزيد > مساعدة > الإبلاغ عن مشاكل في "أدوات مطوري البرامج" في "أدوات مطوري البرامج".
  • يمكنك نشر تغريدة على @ChromeDevTools.
  • شارِك في التعليقات على الميزات الجديدة في فيديوهات YouTube أو نصائح حول أدوات مطوّري البرامج فيديوهات على YouTube.