تتيح لك الأجزاء النصية تحديد مقتطف نصي في جزء عنوان 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
في المثال التالي، لأنّ سلسلة البداية
"السريعة" لا تظهر داخل عنصر واحد بلا انقطاع على مستوى الكتلة:
<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 لأجزاء من النص. نوفر إضافة مفتوحة المصدر للمتصفح تسمى Link to Text Fragment تتيح لك إنشاء رابط إلى أي نص عن طريق تحديده ثم النقر على "نسخ الرابط إلى النص المحدد" في قائمة السياق. تتوفّر هذه الإضافة للمتصفّحات التالية:
- رابط يؤدي إلى جزء من النص في 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
، ما يمكنني استخدامه لإنشاء ملف شخصي للمستخدم. وبما أنّ تنفيذ أجزاء النص البسيطة قد يقرّر أنّ المطابقة الناجحة من المفترض أن تؤدي إلى تبديل التركيز، يمكنني في evil-ads.example.com
متابعة حدث blur
وبالتالي معرفة وقت حدوث المطابقة. في Chrome، نفّذنا "أجزاء النص" بطريقة لا يمكن بها حدوث السيناريو أعلاه.
قد يكون هناك هجوم آخر يستغل حركة المرور على الشبكة استنادًا إلى موضع الانتقال للأعلى أو للأسفل. لنفترض أنّني تمكّنت من الوصول إلى
سجلّات حركة مرور الشبكة الخاصة بالضحية، مثلاً كمشرف لشبكة داخلية تابعة للشركة. لنفترض الآن أنّه
توفّر مستند طويل عن الموارد البشرية بعنوان الإجراءات التي يجب اتّخاذها في حال المعاناة من… ثم قائمة بحالة
الموظفين، مثل الإرهاق والقلق وما إلى ذلك. يمكنني وضع بكسل تتبُّع بجانب كل عنصر في
القائمة. إذا تبيّن لي بعد ذلك أنّ تحميل المستند يحدث في الوقت نفسه مع تحميل حبيبات قياس الأداء بجانب عنصر الإرهاق مثلاً، يمكنني بعد ذلك، بصفتي مشرف الشبكة الداخلية، تحديد أنّ أحد الموظفين قد نقر على رابط مقتطف نصي يتضمّن :~:text=burn%20out
والذي قد يكون الموظف قد افترض أنّه سري وغير مرئي لأي شخص. بما أنّ هذا المثال مفترَض إلى حدّ ما، وبما أنّ استغلاله يتطلّب استيفاء شروط مسبقة جدًا، قيّم فريق الأمان في Chrome خطر تطبيق ميزة الانتقال عند التنقّل في الصفحة لكي يكون قابلاً للإدارة.
قد تقرّر برامج وكيل المستخدم الأخرى عرض عنصر واجهة مستخدم للتنقّل اليدوي بدلاً من ذلك.
بالنسبة إلى المواقع الإلكترونية التي تريد إيقاف هذه الميزة، يتيح Chromium استخدام قيمة سياسة المستند في العنوان يمكن إرسالها حتى لا تعالج برامج وكيل المستخدم عناوين URL الخاصة بـ "أجزاء النص".
Document-Policy: force-load-at-top
إيقاف أجزاء النص
وتتمثل أسهل طريقة لإيقاف هذه الميزة في استخدام إضافة يمكنها إدخال رؤوس استجابة HTTP، على سبيل المثال، ModHeader (وليس أحد منتجات Google)، لإدراج عنوان استجابة (not request) على النحو التالي:
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 من المعايير
الشكر والتقدير
نفَّذ نيك بوريز و ديفيد بوكان مقتطفات النصوص وحدّدوها، بمساهمة من غرانت وانغ. نشكر Joe Medley على المراجعة الشاملة لهذه المقالة. الصورة الرئيسية مقدمة من Greg Rakozy على Unsplash.