إضافة حقل مكوّن إضافي إلى "مصنع الحظر"

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

تطوير "مصنع المكعبات"

يمكن العثور على الرمز المصدر الخاص بأداة Block Factory في مستودع blockly-samples ضمن الدليل examples/developer-tools.

لإرسال تغيير إلى "أدوات المطوّرين" في blockly-samples، عليك اتّباع الخطوات النموذجية للتطوير في blockly-samples. على عكس العمل باستخدام المكوّنات الإضافية، عليك تشغيل npm install من دليل examples/developer-tools مباشرةً، وليس من المستوى الجذر لـ blockly-samples.

تثبيت المكوّن الإضافي

لكي تعرض "أداة إنشاء الحظر" الحقل المخصّص في المعاينة، يجب تثبيت الحقل المخصّص. أضِف الحقل كإحدى التبعيات في npm الخاصة بـ developer-tools. بعد ذلك، سجِّل الجهاز أو نفِّذ أي عملية إعداد أخرى ضرورية في developer-tools/src/blocks/index.ts.

إنشاء مربّع للحقل

بما أنّ "مصنع الوحدات" يستخدم الوحدات لإنشاء وحدات مخصّصة، ستحتاج إلى وحدة تمثّل الحقل المخصّص.

إنشاء تعريف الحظر

عليك تصميم البلوك الخاص بالحقل، وإذا أردت الحصول على بيانات وصفية، يمكنك حتى تصميمه باستخدام Block Factory. يجب أن يتيح المكوّن للمستخدم ضبط الإعدادات التي يتطلبها الحقل، مثل القيم التلقائية والاسم. أضِف تعريف هذا المكوّن إلى developer-tools/src/blocks/fields.ts، واستورِده في developer-tools/src/blocks/index.ts.

إضافة مربّع إلى مجموعة الأدوات

بعد ذلك، عليك إضافة هذا البلوك إلى تعريف صندوق الأدوات لإتاحته للمستخدمين. يمكن العثور على تعريف صندوق الأدوات في developer-tools/src/toolbox.ts. يجب إضافة البلوك إلى فئة "الحقول".

أدوات إنشاء الرموز البرمجية

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

أنشئ ملفًا لكتلة الحقول في الدليل output-generators/fields. ستضيف إلى هذا الملف مولّدات الرموز البرمجية الخاصة بكل من المولدات التالية. استورِد هذا الملف في ملف blocks/index.ts حتى يتم تحميل دوال إنشاء الرموز البرمجية الخاصة بالكتل في التطبيق.

تعريف JavaScript

تنشئ javascriptDefinitionGenerator الرمز الذي سيتم تضمينه في تعريف JavaScript الخاص بكتلة تتضمّن الحقل المخصّص. يعني ذلك عادةً أنّ أداة إنشاء الرموز البرمجية يجب أن تعرض سطرًا من الرموز البرمجية يبدو على النحو التالي: .appendField(new YourFieldConstructor(arg1, arg2), 'userSpecifiedName'). يُرجى العِلم أنّ سطر الرمز هذا لا يتضمّن فاصلة منقوطة، لأنّ الإدخال الذي يحتوي على حقول متعدّدة سيتضمّن عدّة طلبات appendField مرتبطة ببعضها. يتم استرداد الوسيطات في الدالة الإنشائية من القيم التي يضبطها المستخدم في حزمة الحقول. في ما يلي مثال على أداة إنشاء الرمز المحظور هذه لـ FieldAngle:

javascriptDefinitionGenerator.forBlock['field_angle'] = function (
  block: Blockly.Block,
  generator: JavascriptDefinitionGenerator,
): string {
  const name = generator.quote_(block.getFieldValue('FIELDNAME'));
  const angle = block.getFieldValue('ANGLE');
  return `.appendField(new FieldAngle(${angle}), ${name})`;
};

يحتوي مربّع الزاوية الذي سحبه المستخدم من فئة "الحقول" في صندوق أدوات Block Factory على حقلَين:

  • FIELDNAME: يمكن للمستخدم ضبط اسم الحقل في الوحدة الأساسية المخصصة
  • ANGLE: يمكن للمستخدم ضبط قيمة الزاوية التلقائية

في أداة إنشاء الرموز البرمجية المستندة إلى البلوكات هذه، نحصل على قيمة الزاوية التلقائية ونمرّرها كالمَعلمة الوحيدة إلى الدالة الإنشائية FieldAngle. يتم دائمًا تمرير اسم الحقل كوسيطة ثانية إلى appendField.

تعريف JSON

الرمز jsonDefinitionGenerator مشابه، ولكنّه يعرض جزء تعريف كتلة JSON الذي يتوافق مع الحقل. عادةً، يكون هذا الرمز عبارة عن عنصر JSON يتضمّن ما يلي:

  • type: يتوافق مع اسم الحقل في سجلّ حقول Blockly
  • name: يمكن للمستخدم ضبط اسم الحقل في الوحدة الأساسية المخصصة
  • أي سمات مخصّصة أخرى يحتاجها حقل JSON الخاص بطريقة التهيئة.

إليك مثال من FieldAngle مرة أخرى:

jsonDefinitionGenerator.forBlock['field_angle'] = function (
  block: Blockly.Block,
  generator: JsonDefinitionGenerator,
): string {
  const code = {
    type: 'field_angle',
    name: block.getFieldValue('FIELDNAME'),
    angle: block.getFieldValue('ANGLE'),
  };
  return JSON.stringify(code);
};

عناوين الرموز

ينشئ "مولّد عناوين الرموز" مخرجات "عناوين الرموز" المعروضة في Block Factory. يمكن التبديل بين عمليات استيراد esmodule وعلامات البرامج النصية في هذا الناتج، وذلك حسب الطريقة التي يريد المستخدم تحميل الرمز بها، لذا هناك في الواقع مثيلان مختلفان للمنشئ: أحدهما لكل حالة. عليك إضافة أداة إنشاء رمز حظر لكل منها. في ما يلي مثال على FieldAngle:

importHeaderGenerator.forBlock['field_angle'] = function (
  block: Blockly.Block,
  generator: CodeHeaderGenerator,
): string {
  generator.addHeaderLine(
    `import {registerFieldAngle, FieldAngle} from '@blockly/field-angle';`,
  );
  generator.addHeaderLine(`registerFieldAngle();`);
  return '';
};

scriptHeaderGenerator.forBlock['field_angle'] = function (
  block: Blockly.Block,
  generator: CodeHeaderGenerator,
): string {
  generator.addHeaderLine(
    `<script src="https://unpkg.com/@blockly/field-angle"></script>`,
  );
  generator.addHeaderLine(`registerFieldAngle();`);
  return '';
};

تتضمّن هذه المولدات طريقة تُسمى addHeaderLine تتيح لك تحديد سطر من الرمز البرمجي يجب استدعاؤه قبل استخدام الحقل في الرمز البرمجي. ويشمل ذلك عادةً عمليات مثل استيراد الحقل أو تحميله من خلال علامة نصية لبرنامج نصي، وربما استدعاء دالة ستسجّل الحقل في سجلّ الحقول في Blockly.

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

رمز مميّز للمنشئ

أخيرًا، لدينا أداة إنشاء التي تنشئ رمزًا أوليًا لأداة إنشاء الحقل. في أداة إنشاء الرموز البرمجية المستنِدة إلى البلوكات هذه، ستكتب رمزًا برمجيًا ينشئ رمزًا برمجيًا يساعد المستخدم في كتابة رمز برمجي ينشئ رمزًا برمجيًا. هل تشعر بالارتباك؟ الأمر أسهل مما يبدو.

يتضمّن رمز إنشاء الوحدة النمطية لوحدة نمطية مخصّصة متغيّرًا مُعدًّا مسبقًا يمثّل كل حقل في الوحدة النمطية. ثم هناك TODO يجب أن يكملها المستخدم لتجميع كل هذه المتغيرات في سلسلة الرموز النهائية التي سيعرضها البلوك المخصّص. وهذا يعني أنّ كل ما يحتاج إليه عادةً مولّد الرموز البرمجية الخاصة بالحظر هو عرض السطر الذي ينشئ هذا المتغيّر المخصّص. لنفترض أنّ المستخدم ينشئ وحدة أساسية مخصّصة ستضيف أشعة الشمس إلى لوحة الرسم. يضيفون حقل زاوية إلى الكتلة ويسمّونه "SUN_DIRECTION". سيتضمّن رمز العنصر النائب الخاص بمنشئ هذا البلوك السطر const angle_sun_direction = block.getFieldValue("SUN_DIRECTION");. هذا هو سطر الرمز الذي يجب أن يعرضه مولّد الرمز المكوّن من مربّعات لحقل الزاوية:

generatorStubGenerator.forBlock['field_angle'] = function (
  block: Blockly.Block,
  generator: GeneratorStubGenerator,
): string {
  const name = block.getFieldValue('FIELDNAME');
  const fieldVar = generator.createVariableName('angle', name);
  return `const ${fieldVar} = block.getFieldValue(${generator.quote_(
    name,
  )});\n`;
};

للحصول على اسم موحّد للمتغيّر، يمكنك طلب generator.createVariableName وتمرير نوع الحقل (مثل angle أو number أو غير ذلك) مع الاسم الذي أطلقه المستخدم على الحقل.

اختبارها

بعد كتابة كل هذه الأجزاء، يجب أن تتمكّن من بدء Block Factory من خلال تنفيذ npm start في الدليل blockly-samples/examples/developer-tools. من المفترض أن تتمكّن من سحب البلوك من فئة الحقل، وإضافته إلى إدخال في البلوك، ومشاهدة تغيير الناتج. تأكَّد من أنّ معاينة الفقرة تبدو صحيحة، وأنّ الرمز لكل قسم من أقسام الناتج صحيح.