تتيح لك ميزة "أجزاء النص" تحديد مقتطف نص في جزء من عنوان URL. عند الانتقال إلى عنوان URL يحتوي على جزء نصي من هذا النوع، يمكن للمتصفّح إبرازه ولفت انتباه المستخدم إليه.
معرّفات الأجزاء
كان الإصدار 80 من Chrome إصدارًا مهمًا. وتضمّن عددًا من الميزات التي طال انتظارها، مثل وحدات ECMAScript في مشغّلات الويب والدمج الفارغ والتسلسل الاختياري والمزيد. وكالعادة، تم الإعلان عن الإصدار من خلال منشور المدوّنة على مدوّنة Chromium. يمكنك الاطّلاع على مقتطف من منشور المدوّنة في لقطة الشاشة التالية.
idقد تتساءلون عن معنى كل المربّعات الحمراء. وهي نتيجة تشغيل المقتطف التالي في "أدوات مطوّري البرامج". ويتم تمييز جميع العناصر التي تحتوي على السمة id.
document.querySelectorAll('[id]').forEach((el) => {
el.style.border = 'solid 2px red';
});
يمكنني وضع رابط عميق لأي عنصر مميّز بمربّع أحمر بفضل معرّف الجزء الذي أستخدمه بعد ذلك في تجزئة عنوان URL الخاص بالصفحة. لنفترض أنّني أردت إنشاء رابط عميق يؤدي إلى المربّع تقديم الملاحظات في
منتديات المنتجات في
القسم الجانبي، يمكنني إجراء ذلك من خلال إنشاء عنوان URL
https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#HTML1 يدويًا.
كما يظهر في لوحة "العناصر" ضمن "أدوات المطوّرين"، يتضمّن العنصر المعنيّ السمة id
بالقيمة HTML1.
id لعنصر معيّنإذا حلّلت عنوان 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، ما يعني أنّه لا يمكنني الربط بهذا العنوان. هذه هي المشكلة التي
تحلّها مقتطفات النص.
id.مقتطفات نصية
يضيف اقتراح مقتطفات النص إمكانية تحديد مقتطف نصي في تجزئة عنوان URL. عند الانتقال إلى عنوان URL يحتوي على جزء نصي من هذا النوع، يمكن لوكيل المستخدم إبرازه ولفت انتباه المستخدم إليه.
توافُق المتصفح
لأسباب تتعلق بالأمان، تتطلّب الميزة فتح الروابط في سياق noopener.
لذلك، تأكَّد من تضمين
rel="noopener" في ترميز علامة الارتساء
<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 كمثال؟ الجواب هو أنّه تم تقديم ميزة "مقتطفات النص" في هذا الإصدار:
لاحظ كيف تظهر كلمة "text" في لقطة الشاشة أعلاه أربع مرات. يتم كتابة التكرار الرابع
بخط رمز أخضر. إذا أردتُ الربط بهذه الكلمة تحديدًا، سأضبط start على text. بما أنّ كلمة "نص" هي كلمة واحدة فقط، لا يمكن أن يكون هناك end. فماذا أفعل الآن؟ يتطابق عنوان URL https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#:~:text=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 لمقتطفات النص. نوفّر إضافة متصفّح مفتوحة المصدر تُسمى رابط إلى مقتطف النص تتيح لك الربط بأي نص من خلال اختياره، ثم النقر على "نسخ الرابط إلى النص المحدّد" في قائمة السياق. تتوفّر هذه الإضافة للمتصفّحات التالية:
- إضافة Link to Text Fragment لمتصفّح Google Chrome
- Link to Text Fragment لمتصفّح Microsoft Edge
- إضافة Link to Text Fragment لمتصفّح Mozilla Firefox
- Link to Text Fragment لمتصفّح 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 (عادةً ما يكون اللون أسود على خلفية صفراء، وهي ألوان النظام في CSS لـ mark). تحتوي ورقة أنماط وكيل المستخدم على CSS يشبه ما يلي:
:root::target-text {
color: MarkText;
background: Mark;
}
كما ترون، يعرض المتصفّح أداة اختيار زائفة
::target-text يمكنكم استخدامها
لتخصيص التمييز المطبَّق. على سبيل المثال، يمكنك تصميم أجزاء النص لتكون نصًا أسود على خلفية حمراء. كالعادة، تأكَّد من
التحقّق من تباين الألوان
كي لا يتسبب نمط الإلغاء في حدوث مشاكل في تسهيل الاستخدام، وتأكَّد من أنّ التمييز يبرز
بشكل مرئي عن بقية المحتوى.
:root::target-text {
color: black;
background-color: red;
}
Polyfill
يمكن إضافة رموز polyfill إلى ميزة "مقتطفات النص" إلى حدٍّ ما. نوفّر ملف 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. لنفترض أيضًا أنّني أنشأتُ في أحد إطارات iframe الخاصة بإعلاناتي إطار 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)، لإدراج عنوان استجابة (وليس عنوان طلب) على النحو التالي:
Document-Policy: force-load-at-top
هناك طريقة أخرى أكثر تعقيدًا لإيقاف هذه الميزة، وهي استخدام الإعداد المخصّص للمؤسسات
ScrollToTextFragmentEnabled.
لتنفيذ ذلك على نظام التشغيل macOS، الصِق الأمر التالي في الوحدة الطرفية.
defaults write com.google.Chrome ScrollToTextFragmentEnabled -bool false
على أجهزة Windows، اتّبِع المستندات الواردة في موقع الدعم الإلكتروني مساعدة Google Chrome Enterprise.
مقتطفات النص في بحث الويب
في بعض عمليات البحث، يقدّم محرّك البحث Google إجابة سريعة أو ملخّصًا مع مقتطف من المحتوى من موقع إلكتروني ذي صلة. ومن المرجّح أن تظهر هذه المقتطفات المميَّزة عندما يكون البحث على شكل سؤال. يؤدي النقر على مقتطف مميَّز إلى نقل المستخدم مباشرةً إلى نص المقتطف المميَّز على صفحة الويب المصدر. ويتم ذلك بفضل عناوين URL الخاصة بأجزاء النص التي يتم إنشاؤها تلقائيًا.
الخاتمة
عنوان URL لأجزاء النص هو ميزة فعّالة تتيح الربط بنص عشوائي على صفحات الويب. ويمكن للمجتمع الأكاديمي استخدامها لتوفير روابط اقتباسات أو مراجع دقيقة للغاية. ويمكن لمحرّكات البحث استخدامها لإنشاء روابط لصفحات معيّنة تؤدي إلى نتائج نصية على الصفحات. يمكن لشبكات التواصل الاجتماعي استخدامها للسماح للمستخدمين بمشاركة فقرات معيّنة من صفحة ويب بدلاً من لقطات الشاشة التي يتعذّر الوصول إليها. آمل أن تبدأ باستخدام عناوين URL لمقتطفات النص وأن تجدها مفيدة مثلي. تأكَّد من تثبيت إضافة المتصفّح رابط إلى مقتطف النص.
روابط ذات صلة
- مسودة المواصفات
- مراجعة TAG
- إدخال حالة Chrome Platform Status
- خطأ في تتبُّع Chrome
- سلسلة محادثات "النية في الشحن"
- سلسلة محادثات WebKit-Dev
- سلسلة محادثات حول موقف Mozilla من المعايير
الإقرارات
تم تنفيذ ميزة "مقتطفات النص" وتحديدها من قِبل بوريس وديفيد بوكان، مع مساهمات من غرانت وانغ. نشكر جو ميدلي على المراجعة الشاملة لهذا المستند.