تتيح لك "أجزاء النص" تحديد مقتطف نصي في جزء عنوان URL. عند الانتقال إلى عنوان URL يتضمّن هذا المقتطف النصي، يمكن للمتصفّح التأكيد عليه و/أو توجيه انتباه المستخدم إليه.
معرّفات الأجزاء
كان الإصدار 80 من Chrome إصدارًا مهمًا. وقد تضمّن عددًا من الميزات التي طال انتظارها، مثل وحدات ECMAScript في Web Workers، دمج القيم الخالية، التسلسل الاختياري، وغير ذلك. وكما هو الحال دائمًا، تم الإعلان عن الإصدار من خلال مشاركة مدونة على مدونة Chromium. يمكنك الاطّلاع على مقتطف من مشاركة المدوّنة في لقطة الشاشة أدناه.
ربما تتساءل عن معنى كل الصناديق الحمراء. وهي نتيجة تشغيل القطعة التالية في "أدوات مطوّري البرامج". ويُبرز جميع العناصر التي تحتوي على سمة id
.
document.querySelectorAll('[id]').forEach((el) => {
el.style.border = 'solid 2px red';
});
يمكنني وضع رابط لصفحة في التطبيق يؤدي إلى أي عنصر مميّز بصندوق أحمر، وذلك باستخدام
معرّف الجزء
الذي أستخدمه بعد ذلك في التجزئة لعنوان URL
للصفحة. لنفترض أنّني أردت إنشاء رابط لصفحة في التطبيق تؤدي إلى مربّع أرسِل لنا ملاحظاتك في
منتديات المنتجات في ملف APK. يمكنني إجراء ذلك من خلال إنشاء عنوان URL يدويًا
https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#HTML1
.
كما هو موضّح في لوحة "العناصر" ضمن "أدوات المطوّرين"، يتضمّن العنصر المعنيّ سمة id
بالقيمة HTML1
.
إذا عالجت عنوان URL هذا باستخدام أداة إنشاء URL()
في JavaScript، سيتم الكشف عن المكونات المختلفة.
لاحظ السمة hash
التي تحمل القيمة #HTML1
.
new URL('https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#HTML1');
/* Creates a new `URL` object
URL {
hash: "#HTML1"
host: "blog.chromium.org"
hostname: "blog.chromium.org"
href: "https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#HTML1"
origin: "https://blog.chromium.org"
password: ""
pathname: "/2019/12/chrome-80-content-indexing-es-modules.html"
port: ""
protocol: "https:"
search: ""
searchParams: URLSearchParams {}
username: ""
}
*/
على الرغم من أنّني اضطررت إلى فتح "أدوات المطوّرين" للعثور على id
لأحد العناصر، يشير ذلك إلى احتمالية أنّ مؤلف تدوينة المدونة أراد الربط بهذا القسم المحدّد من الصفحة.
ماذا لو أردت الربط بمحتوى لا يتضمّن id
؟ لنفترض أنّني أريد الربط بعنوان وحدات ECMAScript
في Web Workers. كما هو موضّح في لقطة الشاشة أدناه، لا يحتوي <h1>
المعنيّ
على سمة id
، ما يعني أنّه لا يمكنني الربط بهذا العنوان. هذه هي المشكلة التي تحلّها
"أجزاء النص".
أجزاء النص
يضيف اقتراح أجزاء النص إمكانية تحديد مقتطف نص في تجزئة عنوان URL. عند الانتقال إلى عنوان URL يتضمّن هذا المقتطف النصي، يمكن لوكيل المستخدم التأكيد عليه و/أو توجيه انتباه المستخدم إليه.
توافُق المتصفح
لأسباب تتعلق بالأمان، تتطلّب الميزة فتح الروابط في سياق
noopener
.
لذلك، احرص على تضمين
rel="noopener"
في markup
<a>
العنصر النائب أو أضِف
noopener
إلى
Window.open()
قائمة ميزات وظائف النافذة.
start
في أبسط أشكالها، تكون بنية "أجزاء النص" على النحو التالي: رمز التجزئة #
متبوعًا بعلامة
:~:text=
وstart
أخيرًا، ما يمثّل
النص المشفَّر بالتنسيق %
الذي أريد الربط به.
#:~:text=start
على سبيل المثال، لنفترض أنّني أريد الربط بعنوان وحدات ECMAScript في Web Workers في مشاركة المدونة التي تعلن عن الميزات في Chrome 80، سيكون عنوان URL في هذه الحالة:
يتم تمييز المقتطف النصي على هذا النحو. إذا نقرت على الرابط في متصفّح متوافق، مثل Chrome، سيتم تمييز جزء النص ونقله إلى أعلى الصفحة:
start
وend
ماذا لو أردت الربط بالقسم بأكمله بعنوان وحدات ECMAScript في Web Workers، وليس بعنوانه فقط؟ سيؤدي ترميز النص الكامل للقسم بالتنسيق العشري إلى جعل عنوان URL الناتج طويلًا بشكل غير عملي.
لحسن الحظ، هناك طريقة أفضل. بدلاً من النص الكامل، يمكنني وضع إطار حول النص المطلوب باستخدام بنية
start,end
. لذلك، أُحدِّد بضع كلمات مُشفَّرة بالنسب المئوية في بداية
النص المطلوب، وبضع كلمات مُشفَّرة بالنسب المئوية في نهاية النص المطلوب، مفصولة
بفاصلة ,
.
يظهر ذلك على النحو التالي:
بالنسبة إلى start
، لديّ ECMAScript%20Modules%20in%20Web%20Workers
، ثمّ فاصلة ,
متبوعة
بـ ES%20Modules%20in%20Web%20Workers.
على أنّه end
. عند النقر على الرابط باستخدام متصفّح متوافق،
مثل Chrome، يتم تمييز القسم بالكامل والانتقال إليه:
قد تتساءل الآن عن سبب اختياري start
وend
. في الواقع، كان بإمكانك أيضًا استخدام عنوان URL أقصر قليلاً، وهو https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#:~:text=ECMAScript%20Modules,Web%20Workers.
يتألف من كلمتين فقط على كل جانب. قارِن start
وend
بال
القيم السابقة.
إذا اتّخذت خطوة أخرى واستخدمت الآن كلمة واحدة فقط لكل من start
وend
، يمكنك
التعرّف على مشكلتي. أصبح عنوان URL
https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#:~:text=ECMAScript,Workers.
أقصر الآن، ولكن لم يعُد الجزء المميّز من النص هو الجزء المطلوب في الأصل. تتوقف عملية
التظليل عند أول مرّة تظهر فيها الكلمة Workers.
، وهذا صحيح، ولكنّه ليس ما
أردت تمييزه. تكمن المشكلة في أنّ القسم المطلوب لا يتم تحديده بشكل فريد من خلال
قيمتَي start
وend
اللتين تتألفان من كلمة واحدة:
prefix-
و-suffix
إنّ استخدام قيم طويلة بما يكفي للمعلَمتَين start
وend
هو أحد الحلول للحصول على رابط فريد.
في بعض الحالات، لا يكون ذلك ممكنًا. ملاحظة: لماذا اخترت
مقالة مدونة حول إصدار Chrome 80 كمثال؟ الإجابة هي أنّه تمّ تقديم "أجزاء النص"
في هذا الإصدار:
لاحظ أنّ كلمة "نص" تظهر أربع مرات في لقطة الشاشة أعلاه. أما الظهور الرابع، فهناك
يتم كتابته بخط رموز برمجية أخضر. إذا أردت الربط بهذه الكلمة تحديدًا، سأضبط start
على text
. بما أنّ كلمة "نص" هي كلمة واحدة فقط، لا يمكن أن يكون هناك end
. فماذا أفعل الآن؟ تتم مطابقة
عنوان URL
https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#:~:text=text
عند أول مرّة تظهر فيها الكلمة "نص" في العنوان:
لحسن الحظ، هناك حلّ. في مثل هذه الحالات، يمكنني تحديد prefix-
و-suffix
.
الكلمة التي تسبق نص الرمز الأخضر "text" هي "the"، والكلمة التي تليها هي "parameter". لا تتضمّن أيّ من
مواقع الكلمة "نص" الثلاثة الأخرى الكلمات المحيطة نفسها. استنادًا إلى هذه
المعلومات، يمكنني تعديل عنوان URL السابق وإضافة prefix-
و-suffix
. ويجب أيضًا ترميزها باستخدام النسبة المئوية، كما يمكن أن تحتوي على أكثر من كلمة واحدة، تمامًا مثل غيرها من
المَعلمات.
https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#:~:text=the-,text,-parameter
.
للسماح لبرنامج التحليل بتحديد prefix-
و-suffix
بوضوح، يجب فصلهما عنstart
وend
الاختياريَين باستخدام واصلة -
.
البنية الكاملة
في ما يلي البنية الكاملة لـ "أجزاء النص". (تشير الأقواس المربّعة إلى مَعلمة اختيارية).
يجب ترميز قيم جميع المَعلمات بنسبة مئوية. وهذا مهم بشكل خاص لحرف الشرطة
-
وعلامة العطف &
والفاصلة ,
، حتى لا يتم تفسيرها كجزء من بنية توجيه
النص.
#:~:text=[prefix-,]start[,end][,-suffix]
لن تتطابق كل من prefix-
وstart
وend
و-suffix
إلا مع النص ضمن عنصر على مستوى الكتلة واحد،
ولكن يمكن أن تمتد نطاقات start,end
الكاملة على مجموعات متعددة من الكتل. على سبيل المثال، لن يتطابق الرمز
:~:text=The quick,lazy dog
في المثال التالي، لأنّ السلسلة الافتتاحية "The quick" لا تظهر ضمن عنصر واحد على مستوى الكتلة بدون انقطاع:
<div>
The
<div></div>
quick brown fox
</div>
<div>jumped over the lazy dog</div>
ومع ذلك، يتطابق في هذا المثال:
<div>The quick brown fox</div>
<div>jumped over the lazy dog</div>
إنشاء عناوين URL لمقاطع نصية باستخدام إضافة متصفّح
إنّ إنشاء عناوين URL لأجزاء النص يدويًا أمر شاق، خاصةً عندما يتعلق الأمر بالتأكّد من أنّها فريدة. إذا أردت، تتضمّن المواصفة بعض النصائح وتسرد الخطوات الدقيقة لإنشاء عناوين URL لمقاطع نصية. نوفّر إضافة متصفّح مفتوحة المصدر تُسمى رابط إلى مقطع نصي تتيح لك الربط بأي نص من خلال اختياره، ثم النقر على "نسخ الرابط إلى النص المحدّد" في قائمة السياق. تتوفّر هذه الإضافة للمتصفّحات التالية:
- رابط يؤدي إلى جزء من النص في Google Chrome
- رابط إلى جزء نص في Microsoft Edge
- إنشاء رابط إلى جزء من النص في Mozilla Firefox
- رابط إلى جزء من النص في متصفّح Apple Safari
أجزاء نصية متعددة في عنوان URL واحد
يُرجى العِلم أنّه يمكن أن تظهر عدة أجزاء نصية في عنوان URL واحد. يجب أن تكون أجزاء النص المحدّدة
مفصولة برمز العطف اللاتيني &
. في ما يلي مثال على رابط يتضمّن ثلاثة أجزاء نصية:
https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#:~:text=Text%20URL%20Fragments&text=text,-parameter&text=:~:text=On%20islands,%20birds%20can%20contribute%20as%20much%20as%2060%25%20of%20a%20cat's%20diet
.
خلط أجزاء العناصر والنصوص
يمكن دمج أجزاء العناصر التقليدية مع أجزاء نصية. لا بأس من استخدام كلا الخيارين
في عنوان URL نفسه، على سبيل المثال، لتوفير بديل ذي معنى في حال تغيّر النص الأصلي على الصفحة
، لكي لا يتطابق جزء النص بعد ذلك. إنّ عنوان URL
https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#HTML1:~:text=Give%20us%20feedback%20in%20our%20Product%20Forums.
الذي ينقل إلى قسم تقديم ملاحظاتك في
منتديات المنتجات
يحتوي على جزء عنصر (HTML1
) بالإضافة إلى جزء نص (text=Give%20us%20feedback%20in%20our%20Product%20Forums.
):
توجيه المقتطف
هناك عنصر واحد من البنية لم أشرحه بعد: توجيه العنصر :~:
. لتجنّب
مشاكل التوافق مع أجزاء عناصر عناوين URL الحالية كما هو موضّح أعلاه، تقدّم مواصفة أجزاء النص توجيه الصعق الكهربي. عنصر التوجيه المخصّص للجزء هو جزء من جزء عنوان URL الذي يحدّده تسلسل الرمز
:~:
. وهي مخصّصة لتعليمات وكيل المستخدم، مثل text=
، ويتمّ اقتصاصها من عنوان URL
أثناء التحميل كي لا تتمكّن نصوص المؤلفين البرمجية من التفاعل معها مباشرةً. يُطلق على تعليمات وكيل المستخدم أيضًا اسم التوجيهات. في الحالة المحدّدة، يُطلق على text=
اسم توجيه نصي.
رصد الميزات
لرصد مدى توفّر الميزة، اختبِر سمة fragmentDirective
للقراءة فقط على document
. إنّ توجيه القطعة
هو آلية لعناوين URL لتحديد تعليمات موجّهة إلى المتصفّح بدلاً من
المستند. ويهدف ذلك إلى تجنُّب التفاعل المباشر مع نص المؤلف، حتى يمكن إضافة تعليمات وكيل المستخدم في المستقبل بدون الخوف من إجراء تغييرات جذرية على المحتوى الحالي. يمكن أن يكون أحد
الأمثلة المحتملة على هذه الإضافات المستقبلية هي نصائح الترجمة.
if ('fragmentDirective' in document) {
// Text Fragments is supported.
}
يُستخدَم رصد الميزات بشكل أساسي في الحالات التي يتم فيها إنشاء الروابط ديناميكيًا (على سبيل المثال، من خلال محرّكات البحث) لتجنُّب عرض روابط أجزاء نصية للمتصفّحات التي لا تتوافق معها.
تنسيق أجزاء النص
بشكلٍ تلقائي، تنظِّم المتصفّحات أجزاء النص بالطريقة نفسها التي تنظِّم بها
mark
(عادةً ما يكون اللون الأسود على الأصفر،
ألوان نظام
mark
في CSS). تحتوي ورقة أنماط وكيل المستخدم على CSS بالشكل التالي:
:root::target-text {
color: MarkText;
background: Mark;
}
كما هو موضّح، يعرض المتصفّح أداة اختيار زائفة
::target-text
يمكنك استخدامها
لتخصيص التمييز المُطبَّق. على سبيل المثال، يمكنك تصميم أجزاء النص بحيث تكون أسود
نصًا على خلفية حمراء. كعادتك، احرص على
التحقّق من تباين الألوان
كي لا يتسبب أسلوب الاستبدال في حدوث مشاكل في تسهيل الاستخدام، وتأكَّد من أنّ التمييز
يبرز بشكل مرئي عن بقية المحتوى.
:root::target-text {
color: black;
background-color: red;
}
إمكانية استخدام العناصر المتعددة
يمكن إضافة رموز polyfill إلى ميزة "أجزاء النص" إلى حدّ ما. نوفّر تعويضًا يتم استخدامه داخليًا من قِبل الإضافة للمتصفحات التي لا تقدّم دعمًا مضمّنًا لـ "مقتطفات النص" التي يتم تنفيذ وظيفتها في JavaScript.
إنشاء روابط أجزاء النص آليًا
يحتوي polyfill على ملف
fragment-generation-utils.js
يمكنك استيراده واستخدامه لإنشاء روابط مقتطفات نصية. تم توضيح ذلك في رمز النموذج أدناه:
const { generateFragment } = await import('https://unpkg.com/text-fragments-polyfill/dist/fragment-generation-utils.js');
const result = generateFragment(window.getSelection());
if (result.status === 0) {
let url = `${location.origin}${location.pathname}${location.search}`;
const fragment = result.fragment;
const prefix = fragment.prefix ?
`${encodeURIComponent(fragment.prefix)}-,` :
'';
const suffix = fragment.suffix ?
`,-${encodeURIComponent(fragment.suffix)}` :
'';
const start = encodeURIComponent(fragment.textStart);
const end = fragment.textEnd ?
`,${encodeURIComponent(fragment.textEnd)}` :
'';
url += `#:~:text=${prefix}${start}${end}${suffix}`;
console.log(url);
}
الحصول على أجزاء نص لأغراض متعلقة بالإحصاءات
تستخدِم الكثير من المواقع الإلكترونية هذا المقتطف للتوجيه، ولهذا السبب تزيل المتصفّحات "أجزاء النص" كي لا تؤدي إلى تعطُّل هذه الصفحات. هناك حاجة معترف بها لعرض روابط "أجزاء النص" للصفحات، على سبيل المثال، لأغراض الإحصاءات، ولكن لم يتم تنفيذ الحل المقترَح بعد. كحلّ مؤقت في الوقت الحالي، يمكنك استخدام الرمز البرمجي أدناه لاستخراج المعلومات المطلوبة.
new URL(performance.getEntries().find(({ type }) => type === 'navigate').name).hash;
الأمان
لا يتمّ استدعاء توجيهات أجزاء النص إلّا في عمليات التنقّل الكاملة (غير التي تتمّ على الصفحة نفسها) والتي تكون نتيجة
تفعيل المستخدِم.
بالإضافة إلى ذلك، فإنّ عمليات التنقّل التي تبدأ من مصدر مختلف عن الوجهة تتطلّب أن تتم عملية التنقّل في سياق
noopener
، بحيث يكون معروفًا أنّ الصفحة المقصودة معزولة بشكل كافٍ. لا يتم تطبيق توجيهات أجزاء النص إلا
على الإطار الرئيسي. وهذا يعني أنّه لن يتم البحث عن النص داخل إطارات iframe، ولن يؤدي التنقّل في إطار iframe
إلى استدعاء جزء من النص.
الخصوصية
من المهم أن لا تؤدي عمليات تنفيذ مواصفات "أجزاء النص" إلى تسرُّب ما إذا تم العثور على قطعة نص
في الصفحة أم لا. في حين أنّه يمكن لمؤلف الصفحة الأصلي
التحكّم بالكامل في أجزاء العناصر، يمكن لأي مستخدم إنشاء أجزاء نصية. تذكَّر في المثال أعلاه
أنّه لم تكن هناك طريقة للربط بعنوان وحدات ECMAScript في Web Workers، لأنّ <h1>
لم يكن يتضمّن id
، ولكن كيف يمكن لأي شخص، بما في ذلك أنا، الربط بأي مكان من خلال صياغة
القطعة النصية بعناية؟
لنفترض أنّني أدير شبكة مواقع إعلانية evil-ads.example.com
. لنفترض أيضًا أنّني أنشأت في أحد divs
الإعلانية إطارًا iframe مخفيًا من مصدر مختلف ينقل إلى dating.example.com
باستخدام عنوان URL لفقرة
نصية
dating.example.com#:~:text=Log%20Out
بعد تفاعل المستخدم مع الإعلان. إذا تم العثور على النص "تسجيل الخروج"، أعلم أنّ الضحية سجّل الدخول حاليًا
إلى dating.example.com
، ما يمكنني استخدامه لإنشاء ملف شخصي للمستخدم. بما أنّ عملية تنفيذ Text
Fragments قد تحدّد أنّ المطابقة الناجحة يجب أن تؤدي إلى تبديل التركيز، يمكنني في
evil-ads.example.com
الاستماع إلى حدث blur
وبالتالي معرفة وقت حدوث المطابقة. في Chrome، نفّذنا "أجزاء النص" بطريقة لا يمكن بها حدوث السيناريو أعلاه.
قد يكون هناك هجوم آخر يستغل حركة المرور على الشبكة استنادًا إلى موضع الانتقال للأعلى أو للأسفل. لنفترض أنّني تمكّنت من الوصول إلى
سجلّات حركة مرور الشبكة الخاصة بضحيتي، مثلاً كمشرف لشبكة داخلية تابعة لشركة. لنفترض الآن أنّه
توفّر مستند طويل عن الموارد البشرية بعنوان الإجراءات التي يجب اتّخاذها في حال المعاناة من… ثم قائمة بحالة
الموظفين، مثل الإرهاق والقلق وما إلى ذلك. يمكنني وضع بكسل تتبُّع بجانب كل عنصر في
القائمة. إذا تبيّن لي بعد ذلك أنّ تحميل المستند يحدث في الوقت نفسه مع تحميل حبيبات قياس الأداء بجانب عنصر الإرهاق مثلاً، يمكنني بعد ذلك، بصفتي مشرف الشبكة الداخلية، تحديد أنّ أحد الموظفين قد نقر على رابط مقتطف نصي يتضمّن :~:text=burn%20out
والذي قد يكون الموظف قد افترض أنّه سري وغير مرئي لأي شخص. بما أنّ هذا المثال هو نوعًا ما
مُصطنَع في البداية، وبما أنّ استغلاله يتطلّب استيفاء شروط مسبقة جدًا محدّدة،
قيّم فريق أمان Chrome خطر تنفيذ ميزة "الانتقال أثناء التمرير" على أنّه قابل للإدارة.
قد تقرّر برامج وكيل المستخدم الأخرى عرض عنصر واجهة مستخدم للتنقّل اليدوي بدلاً من ذلك.
بالنسبة إلى المواقع الإلكترونية التي تريد إيقاف هذه الميزة، يتيح Chromium استخدام قيمة سياسة المستند لعنوان يمكن إرسالها حتى لا تعالج وكلاء المستخدمين عناوين URL الخاصة بـ "أجزاء النص".
Document-Policy: force-load-at-top
إيقاف أجزاء النص
إنّ أسهل طريقة لإيقاف الميزة هي استخدام إضافة يمكنها إدراج عناوين ملفّ تعريف HTTP، على سبيل المثال، ModHeader (ليس منتجًا من Google)، لإدراج عنوان استجابة (وليس طلبًا) على النحو التالي:
Document-Policy: force-load-at-top
هناك طريقة أخرى أكثر تعقيدًا لإيقاف هذه الميزة، وهي استخدام إعدادات المؤسسة
ScrollToTextFragmentEnabled
.
لإجراء ذلك على نظام التشغيل macOS، الصِق الأمر أدناه في الوحدة الطرفية.
defaults write com.google.Chrome ScrollToTextFragmentEnabled -bool false
على نظام التشغيل Windows، اتّبِع التعليمات الواردة في المستندات على موقع دعم مساعدة Google Chrome Enterprise.
أجزاء نصية في بحث الويب
بالنسبة إلى بعض عمليات البحث، يوفّر محرّك بحث Google إجابةً سريعة أو ملخصًا مع مقتطف محتوى من موقع إلكتروني ذي صلة. ومن المرجّح أن تظهر هذه المقتطفات المميَّزة في عمليات البحث التي تتم صياغتها في شكل سؤال. يؤدي النقر على مقتطف مميَّز إلى نقل المستخدِم مباشرةً إلى نص المقتطف المميَّز في صفحة الويب المصدر. ويحدث ذلك بفضل عناوين URL الخاصة بـ "المقاطع النصية" التي يتم إنشاؤها تلقائيًا.
الخاتمة
إنّ عناوين URL الخاصة بأجزاء النص هي ميزة فعّالة للربط بنص عشوائي على صفحات الويب. ويمكن للمجتمع العلمي استخدامها لتقديم روابط مراجع أو اقتباسات دقيقة للغاية. يمكن لمحرّكات البحث استخدام هذا الرابط لإنشاء رابط لصفحة معيّنة في نتائج البحث النصية. يمكن لمواقع التواصل الاجتماعي استخدامها للسماح للمستخدمين بمشاركة مقاطع معيّنة من صفحة ويب بدلاً من لقطات الشاشة التي لا يمكن الوصول إليها. نأمل أن تبدأ في استخدام عناوين URL الخاصة بمقاطع النص وتجدها مفيدة كما نجد نحن. احرص على تثبيت إضافة رابط إلى مقطع نص في المتصفّح.
روابط ذات صلة
- مسودة المواصفات
- مراجعة العلامة
- إدخال حالة نظام Chrome الأساسي
- خطأ تتبُّع في Chrome
- سلسلة محادثات حول نية الشحن
- سلسلة محادثات WebKit-Dev
- سلسلة محادثات حول موقف Mozilla من المعايير
الشكر والتقدير
تم تنفيذ أجزاء النص وتحديدها بواسطة Nick Burris و ديفيد بوكان، بمساهمات من جرانت وانغ. نشكر Joe Medley على المراجعة الشاملة لهذه المقالة. الصورة الرئيسية مقدمة من Greg Rakozy على Unsplash.