نقدّم لك طريقة جديدة لإنشاء تجارب مخصّصة لتعديل المواقع الإلكترونية باستخدام واجهة برمجة التطبيقات EditContext API

لم يكن دمج إمكانيات التعديل المتقدّمة في تطبيقات الويب أمرًا سهلاً على المطوّرين على الدوام. تتيح منصة الويب إمكانية التعديل لكلّ من النص العادي ومستندات HTML باستخدام عناصر مثل <input> و<textarea>، أو من خلال تطبيق السمة contenteditable على العناصر. ومع ذلك، غالبًا ما تكون القدرات الأساسية لأنواع العناصر هذه غير كافية لتحقيق ما يرغب المطوّرون في تحقيقه في تطبيقاتهم.

غالبًا ما انتهى المطوّرون إلى تنفيذ عرض المحرِّر المخصَّص لديهم والذي يُنفِّذ الوظائف التي يحتاجها المستخدمون. قد يتم إنشاء طريقة عرض المحرِّر باستخدام نموذج كائن المستند (DOM) معقّد، أو حتى باستخدام عنصر <canvas>، ولكن بما أنّ الطريقة الوحيدة لكي يتلقّى مطوّر البرامج إدخال نص يتطلّب عنصرًا قابلاً للتعديل، سيكون عليه وضع عنصر contenteditable مخفي على الصفحة في مكان ما.

والنتيجة هي بينما يبدو أنّ المستخدم يعدِّل المحتوى مباشرةً في طريقة عرض المحرِّر المخصّصة للتطبيق، ويتلقّى مطوّر البرامج البيانات من خلال معالِجات الأحداث في العنصر المخفي، ثم يطابقه في عرض المحرِّر المرئي. قد يؤدي ذلك إلى مشاكل، إذ ينتهي الأمر بمطوّري البرامج إلى مواجهة سلوك التعديل التلقائي في المتصفّح في عنصر contenteditable المخفي.

ولمعالجة هذه الفئة من المشاكل، قاد فريق Microsoft Edge إلى توحيد EditContext، وهي واجهة برمجة تطبيقات جديدة لمنصة الويب تتيح للمطوّرين تلقّي إدخالات النص مباشرةً بدون الارتباط بسلوكيات التعديل التلقائية في المتصفّح.

مثال من العالم الحقيقي

مثلاً، عندما يتعاون المستخدمون في Word Online. يمكن للمستخدمين المشاركة في التعديل والاطّلاع على تغييرات بعضهم وموضعات المؤشر. على سبيل المثال، إذا كان أحد المتعاونين يستخدم نافذة محرِّر أسلوب الإدخال (IME) لإنشاء نص ياباني، لن يتم تحديث المحرِّر لديه لإظهار التغييرات من المستخدمين الآخرين إلى أن ينتهي مستخدم محرِّر طريقة الإدخال من إنشاء نصه. ويرجع ذلك إلى أنّ إجراء تغييرات على منطقة نموذج العناصر في المستند (DOM) التي يتم تعديلها أثناء توفُّر تركيبة أداة IME نشطة، قد يؤدي إلى إلغاء المقطوعة قبل أوانها. يجب أن ينتظر التطبيق حتى يتم إغلاق نافذة IME حتى يتم تعديل العرض، ما قد يتسبب في حدوث تأخيرات وإعاقة التعاون.

حدثت مشكلة أثناء التعاون في Word Online أثناء إنشاء نص

لتوفير تجربة أفضل للمطوّرين والمستخدم، يحتاج المطوّرون إلى طريقة لفصل إدخال النص من طريقة عرض HTML DOM. واجهة برمجة تطبيقات EditContext هي الحل لهذه المشكلة.

أساسيات EditContext

باستخدام EditContext، يمكنك تلقّي إدخالات النص والمقطوعة الموسيقية مباشرةً من خلال واجهة برمجة التطبيقات EditContext API، بدلاً من ملاحظة التغييرات في DOM. ويتيح ذلك التحكّم بشكل أكبر في طريقة التعامل مع الإدخال، ويتيح إمكانية تعديل العنصر <canvas>.

يؤدي ربط مثيل EditContext بعنصر إلى جعله قابلاً للتعديل:

// This will be our editable element.
const element = document.querySelector('#editor-element');

// Creating the EditContext object.
const editContext = new EditContext();

// Associating the EditContext object with our DOM element.
// The element is now focusable and can receive text input.
element.editContext = editContext;

// In order to render the text typed by the user onto the
// page, as well as the user's selection, you'll need to
// receive the input in a textupdate event callback.
editContext.addEventListener('textupdate', event => {
  element.textContent = editContext.text;

  // For brevity, the code to render the selection
  // isn't shown here.
    renderSelection(event.selectionStart, event.selectionEnd);
 });

مسئوليات المؤلف

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

إدارة جانب منطقة قابلة للتعديل أو في حال تغيير في اختيار المستخدم

يمكنك استدعاء الطريقتَين updateControlBounds() وupdateSelectionBounds() لإبلاغ مثيل EditContext كلما تغيّر حجم المنطقة القابلة للتعديل أو تغيير المستخدم. يساعد هذا النظام الأساسي في تحديد مكان عرض نوافذ أداة IME وواجهة مستخدم التعديل الأخرى الخاصة بالنظام الأساسي.

// It's necessary to provide bounds information because EditContext
// is generic enough to work with any type of web editor, even
// <canvas>-based editors. The API doesn't make any assumptions as
// to how the editor is implemented or how the selection is rendered.
// Bounds are given in the client coordinate space.
const controlBound = editorElement.getBoundingClientRect();
const selection = document.getSelection();
const selectionBound = selection.getRangeAt(0).getBoundingClientRect();
editContext.updateControlBounds(controlBound);
editContext.updateSelectionBounds(selectionBound);

إدارة موضع واجهة مستخدم المحرِّر

استمع إلى حدث characterboundsupdate واتصِل بالرمز updateCharacterBounds() كاستجابة عن ذلك لمساعدة النظام الأساسي في تحديد مكان عرض نوافذ أداة IME وواجهة مستخدم التعديل الأخرى الخاصة بالنظام الأساسي.

تطبيق التنسيق

استمع إلى حدث textformatupdate وطبِّق التنسيق الذي يحدّده الحدث على عرض المحرّر. وتستخدم أدوات IME هذه الزخارف النصية عند إنشاء لغات معينة. على سبيل المثال، سيستخدم أداة تحرير أسلوب الإدخال (IME) اليابانية تسطيرًا لإظهار جزء النص الذي يتم إنشاؤه بشكل نشط.

لقطة شاشة لنافذة &quot;محرّر أسلوب الإدخال&quot; المستخدَمة لإدخال الأحرف اليابانية.

التعامل مع سلوكيات تعديل النصوص المنسّقة

استمِع إلى حدث beforeinput للتعامل مع أي سلوكيات لتعديل النصوص المنسّقة تريد استخدامها، مثل مفاتيح التشغيل السريع لكتابة النص بخط غامق أو مائل أو تطبيق تصحيح إملائي.

إدارة التغييرات في اختيارات المستخدمين

عندما يتغير اختيار المستخدم بسبب إدخال لوحة المفاتيح أو الماوس، ستحتاج إلى إبلاغ مثيل EditContext بهذا التغيير. وهذا الإجراء ضروري لأنّ واجهة برمجة التطبيقات EditContext API قابلة للتطبيق على عدد كبير من حالات الاستخدام، بما في ذلك أدوات التحرير التي يتم عرضها باستخدام العنصر <canvas> حيث لا يمكن للمتصفّح اكتشاف التغييرات المحدَّدة تلقائيًا.

document.addEventListener('selectionchange', () => {
  const selection = document.getSelection();

  // EditContext doesn't handle caret navigation, so all the caret navigation/selection that happens
  // in DOM space needs to be mapped to plain text space by the author and passed to EditContext.
  // This example code assumes the editable area only contains text under a single node.
  editContext.updateSelection(selection.anchorOffset, selection.focusOffset);
});

إذا كان العنصر الذي تستخدمه مع EditContext هو عنصر <canvas>، عليك أيضًا تنفيذ سلوكيات الاختيار والتنقّل بين علامة الإقحام، مثل التنقّل خلال النص باستخدام مفاتيح الأسهم. بالإضافة إلى ذلك، لا تعمل ميزة التدقيق الإملائي المضمَّن في المتصفح إلا مع العناصر التي لا تستخدم <canvas>.

EditContext مقابل contenteditable

يعد EditContext خيارًا رائعًا إذا كنت تنفذ محررًا مكتمل الميزات وتريد التحكم الكامل في كيفية التعامل مع إدخال النص أو إذا كنت تضيف ميزات متقدمة مثل التعديل المشترك مع مستخدمين متعددين. ومع ذلك، ونظرًا إلى جميع المتطلّبات السابقة لاستخدام EditContext، إذا كنت بحاجة إلى دعم بسيط لتعديل النصوص، من المُرجَّح أنّك ستظل بحاجة إلى استخدام العناصر <input> أو <textarea> أو السمة contenteditable.

التطلّع إلى المستقبل

نفّذ فريق Microsoft Edge برنامج EditContext في Chromium من خلال التعاون مع مهندسي Chrome، وسيتم طرح الإصدار 121 من Chrome وEdge في كانون الثاني (يناير) 2024. وهو متاح حاليًا في المتصفِّحات المستنِدة إلى Chromium فقط، ولكن يمكنك الاطّلاع على مواضع Mozilla وWebKit على واجهة برمجة التطبيقات EditContext API.

نحن نريد أن نسهّل على المطوّرين على الويب إنشاء تجارب تعديل مخصّصة فعّالة على الويب، ونعتقد أنّ واجهة برمجة التطبيقات EditContext API تحقّق ذلك من خلال معالجة التحديات الحالية وتوفير طريقة مباشرة أكثر للتعامل مع الإدخال النصي.

لمزيد من المعلومات حول واجهة برمجة التطبيقات، يمكنك مراجعة مستندات MDN. لإرسال ملاحظات وآراء عن تصميم واجهة برمجة التطبيقات، افتح مشكلة في مستودع جيت هب في واجهة برمجة التطبيقات EditContext API. للإبلاغ عن أخطاء في عملية تنفيذ واجهة برمجة التطبيقات، يمكنك إرسال خطأ على الرابط crbug.com.