«تکههای نوشتاری» به شما امکان میدهد گزیده نوشتاری را در تکه نشانی وب مشخص کنید. هنگام پیمایش به نشانی وب با چنین قطعه نوشتاری، مرورگر میتواند آن را برجسته کند و توجه کاربر را به آن جلب کند.
شناسههای بخش
Chrome 80 نسخه مهمی بود. این نسخه شامل تعدادی ویژگی بسیار موردانتظار مانند واحدهای ECMAScript در Web Workers، ادغام تهی، زنجیرهسازی اختیاری، و موارد دیگر بود. این نسخه، طبق معمول، ازطریق پست وبلاگ در وبلاگ Chromium اعلام شد. در نماگرفت زیر میتوانید گزیدهای از پست وبلاگ را ببینید.
id.احتمالاً از خودتان میپرسید که معنی همه این جعبههای قرمز چیست. اینها نتیجه اجرای
تکهکد زیر در DevTools هستند. این گزینه همه عناصری را که مشخصه id دارند برجسته میکند.
document.querySelectorAll('[id]').forEach((el) => {
el.style.border = 'solid 2px red';
});
بهلطف شناسه قطعه، میتوانم پیوند عمیقی به هر عنصر برجستهشده با کادر قرمز قرار دهم که سپس از آن در درهمسازی نشانی وب صفحه استفاده میکنم. با فرض اینکه میخواستم پیوند عمیق به چارگوش در
تالارهای گفتمان محصول ما بازخورد ارائه دهید در
کنار ایجاد کنم، میتوانستم این کار را با ساختن دستی نشانی وب
https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#HTML1 انجام دهم.
همانطور که در پانل «عناصر» در «ابزارهای توسعهدهندگان» میبینید، عنصر موردنظر دارای مشخصه id با مقدار HTML1 است.
id عنصر را نشان میدهد.اگر این نشانی وب را با سازنده URL() جاوا اسکریپت تجزیه کنم، مؤلفههای مختلف آشکار میشوند.
به خصوصیت 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: ""
}
*/
The fact though that I had to open the Developer Tools to find the id of an element speaks volumes
about the probability this particular section of the page was meant to be linked to by the author of
the blog post.
اگر بخواهم به چیزی بدون id پیوند دهم چه؟ فرض کنید میخواهم به عنوان ECMAScript Modules
in Web Workers پیوند دهم. همانطور که در نماگرفت زیر میبینید، <h1> موردنظر
شاخصه id ندارد، یعنی هیچ راهی برای پیوند دادن به این عنوان ندارم. این همان مشکلی است که
«تکههای نوشتار» حل میکند.
id نشان میدهد.قطعههای نوشتاری
پیشنهاد قطعههای نوشتاری پشتیبانی از مشخص کردن گزیده نوشتاری در درهمساز نشانی وب را اضافه میکند. هنگام پیمایش به نشانی وب با چنین قطعه نوشتاری، نماینده کاربر میتواند آن را برجسته کند و توجه کاربر را به آن جلب کند.
سازگاری مرورگر
بهدلایل امنیتی، این ویژگی نیاز دارد که پیوندها در بافت
noopener باز شوند.
بنابراین، حتماً
rel="noopener" را در نشانگذاری لنگر
<a> خود بگنجانید یا
noopener را به فهرست ویژگیهای عملکرد پنجره
Window.open() خود اضافه کنید.
start
در سادهترین شکل، نحو «قطعههای نوشتاری» بهصورت زیر است: نماد هش # و بهدنبال آن
:~:text= و درنهایت start، که نشاندهنده
کدگذاریشده با درصد
نوشتاری است که میخواهم به آن پیوند دهم.
#:~:text=start
برای مثال، فرض کنید میخواهم به عنوان ECMAScript Modules in Web Workers در پست وبلاگ اعلام ویژگیها در Chrome 80 پیوند دهم، نشانی وب در این مورد این خواهد بود:
قطعه نوشتار به این صورت برجسته میشود. اگر روی پیوند در مرورگر پشتیبانیشدهای مثل Chrome کلیک کنید، قطعه نوشتار برجسته میشود و بهسمت نمای مربوطه پیمایش میشود:
start و end
اکنون اگر بخواهم به کل بخش با عنوان ECMAScript Modules in Web Workers پیوند دهم، نه فقط عنوان آن؟ کدگذاری درصدی کل نوشتار بخش باعث میشود نشانی وب حاصل بهطور غیرعملی طولانی شود.
خوشبختانه راه بهتری وجود دارد. بهجای کل نوشتار، میتوانم بخش خاصی از نوشتار را با نحو start,end قاببندی کنم. من چند کلمه کدگذاریشده با درصد را در ابتدای قطعه نوشتار و چند کلمه کدگذاریشده با درصد را در انتهای قطعه نوشتار مشخص میکنم که با ویرگول از هم جدا شدهاند.
که بهاینصورت است:
برای start، ECMAScript%20Modules%20in%20Web%20Workers را دارم، سپس یک ویرگول، و بعداز آن
ES%20Modules%20in%20Web%20Workers. بهعنوان end. وقتی در مرورگر پشتیبانیشدهای مثل Chrome روی آن کلیک میکنید، کل بخش برجسته میشود و با پیمایش در نما قرار میگیرد:
اکنون ممکن است درباره انتخاب من برای start و end کنجکاو باشید. درواقع، نشانی وب کمی کوتاهتر
https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#:~:text=ECMAScript%20Modules,Web%20Workers.
با فقط دو کلمه در هر طرف هم کار میکرد. start و end را با مقادیر قبلی مقایسه کنید.
اگر یک قدم جلوتر بروم و اکنون فقط از یک کلمه برای هر دو start و end استفاده کنم، میتوانید
ببینید که من در مشکل هستم. نشانی وب
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 وجود ندارد. حالا چی؟ نشانی وب
https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#:~:text=text
با اولین رخداد کلمه «نوشتار» که ازقبل در عنوان وجود دارد مطابقت دارد:
خوشبختانه راهحلی وجود دارد. در چنین مواردی، میتوانم prefix- و -suffix را مشخص کنم. کلمه
قبلاز «نوشتار» قلم کد سبز «the» است و کلمه بعداز آن «پارامتر» است. هیچکدام از سه مورد دیگر کلمه «نوشتار» کلمات اطراف یکسانی ندارند. با این اطلاعات، میتوانم نشانی وب قبلی را تغییر دهم و 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>
ایجاد نشانیهای وب «قطعه نوشتار» با افزونه مرورگر
ایجاد دستی نشانیهای وب «قطعه نوشتار» خستهکننده است، بهویژه وقتی که باید مطمئن شوید بیهمتا هستند. اگر واقعاً میخواهید، مشخصات دارای چند نکته است و مراحل دقیق تولید نشانیهای وب «قطعه نوشتار» را فهرست میکند. ما افزونه مرورگر متنبازی بهنام پیوند به قطعه نوشتار ارائه میدهیم که به شما امکان میدهد با انتخاب هر نوشتار و سپس کلیک کردن روی «کپی کردن پیوند به نوشتار انتخابشده» در منوِ بافت، به آن نوشتار پیوند دهید. این افزونه برای مرورگرهای زیر دردسترس است:
- پیوند به قطعه نوشتار برای Google Chrome
- پیوند به قطعه نوشتار برای Microsoft Edge
- پیوند به قطعه نوشتار برای Mozilla Firefox
- پیوند به قطعه نوشتار برای Apple Safari
چند قطعه نوشتار در یک نشانی وب
توجه داشته باشید که چند قطعه نوشتار میتواند در یک نشانی وب ظاهر شود. بخشهای نوشتاری خاص باید با نویسه اَمپرسند & از هم جدا شوند. در اینجا نمونه پیوندی با سه قطعه نوشتار آورده شده است:
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.
ترکیب کردن قطعههای نوشتار و عنصر
قطعههای عنصر سنتی را میتوان با قطعههای نوشتاری ترکیب کرد. وجود هر دو در یک نشانی وب کاملاً درست است، برای مثال، برای ارائه یک جایگزین معنادار درصورتیکه نوشتار اصلی در صفحه تغییر کند، بهطوریکه قطعه نوشتار دیگر مطابقت نداشته باشد. نشانی وب
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.) است:
دستورالعمل بخش
یک عنصر از نحو وجود دارد که هنوز توضیح ندادهام: دستورالعمل قطعه :~:. برای جلوگیری از
مشکلات سازگاری با قطعههای عنصر نشانی وب موجود، همانطور که نشان داده شده است،
مشخصات قطعههای نوشتاری دستورالعمل قطعه را
معرفی میکند. دستورالعمل قطعه بخشی از قطعه نشانی وب است که با دنباله کد
:~: محدود شده است. این پیشوند برای دستورالعملهای نماینده کاربر، مانند text=، رزرو شده است و درطول بارگیری از نشانی وب حذف میشود تا اسکریپتهای نویسنده نتوانند مستقیماً با آن تعامل داشته باشند. به دستورالعملهای نماینده کاربر
دستورالعمل نیز گفته میشود. بنابراین در این مورد خاص، text= دستورالعمل نوشتاری نامیده میشود.
تشخیص ویژگی
برای تشخیص پشتیبانی، خصوصیت فقط خواندنی fragmentDirective را در document آزمایش کنید. دستورالعمل fragment
سازوکاری برای نشانیهای وب است تا دستورالعملهای هدایتشده به مرورگر را بهجای
سند مشخص کنند. هدف از آن اجتناب از تعامل مستقیم با اسکریپت نویسنده است تا دستورالعملهای آینده نماینده کاربر بتواند بدون ترس از ایجاد تغییرات مخرب در محتوای موجود اضافه شود. یک
نمونه بالقوه از این افزودنیهای آینده میتواند راهنماییهای ترجمه باشد.
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;
}
شبیهساز مرورگر
ویژگی «قطعات نوشتاری» را میتوان تا حدودی شبیهسازی کرد. ما یک شبیهساز مرورگر ارائه میدهیم که بهطور داخلی توسط افزونه استفاده میشود، برای مرورگرهایی که پشتیبانی داخلی برای «قطعههای نوشتاری» ارائه نمیدهند، جایی که عملکرد در جاوا اسکریپت پیادهسازی شده است.
تولید پیوند «قطعه نوشتار» برنامهای
شبیهساز مرورگر
حاوی فایل 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 Modules in Web Workers وجود نداشت، چون <h1>
id نداشت، اما چطور هرکسی، ازجمله من، میتوانست با ساختن دقیق
قطعه نوشتار به هرجایی پیوند دهد؟
تصور کنید من یک شبکه آگهی مخرب evil-ads.example.com را اجرا میکردم. همچنین تصور کنید که در یکی از iframeهای آگهیام، بهطور پویا یک iframe میانمبدئی پنهان برای dating.example.com با «نشانی وب قطعه نوشتار»
dating.example.com#:~:text=Log%20Out
ایجاد کردهام که وقتی کاربر با آگهی تعامل میکند، فعال میشود. اگر نوشتار «خروج از سیستم» پیدا شود، متوجه میشوم که قربانی به سیستم dating.example.com وارد شده است و میتوانم از آن برای نمایهسازی کاربر استفاده کنم. ازآنجاییکه یک پیادهسازی ساده Text Fragments ممکن است تصمیم بگیرد که یک تطابق موفق باید باعث تغییر تمرکز شود، در evil-ads.example.com میتوانم به رویداد blur گوش دهم و بنابراین بدانم چه زمانی تطابق رخ داده است. در
Chrome، «قطعات نوشتاری» را بهگونهای پیادهسازی کردهایم که چنین سناریویی نمیتواند اتفاق بیفتد.
حمله دیگر میتواند سوءاستفاده از ترافیک شبکه براساس موقعیت پیمایش باشد. فرض کنید من به گزارشهای ترافیک شبکه قربانیام دسترسی داشتم، مثلاً بهعنوان سرپرست اینترانت شرکت. حالا تصور کنید که یک سند طولانی منابع انسانی با عنوان اگر از … رنج میبرید چه باید بکنید وجود داشته باشد و سپس فهرستی از شرایط مانند فرسودگی شغلی، اضطراب و غیره ارائه شود. من میتوانم یک پیکسل ردیابی را در کنار هر مورد در فهرست قرار دهم. اگر سپس تشخیص دهم که بار کردن سند بهطور موقت با بار کردن پیکسل ردیابی درکنار، مثلاً، مورد فرسودگی همزمان است، میتوانم بهعنوان سرپرست اینترانت تشخیص دهم که کارمندی روی پیوند قطعه نوشتار با :~:text=burn%20out کلیک کرده است که ممکن است کارمند تصور کرده باشد محرمانه است و برای هیچکس قابلمشاهده نیست. ازآنجاییکه این مثال تاحدودی ساختگی است و بهرهبرداری از آن مستلزم برآورده شدن پیششرطهای بسیار خاصی است، تیم امنیتی Chrome خطر پیادهسازی پیمایش در پیمایش را قابلمدیریت ارزیابی کرد.
سایر نمایندههای کاربر ممکن است تصمیم بگیرند بهجای آن، عنصر میانای کاربر پیمایش دستی را نشان دهند.
برای سایتهایی که میخواهند انصراف دهند، Chromium از مقدار سرصفحه خطمشی سند پشتیبانی میکند که میتوانند ارسال کنند تا نمایندههای کاربر نشانیهای وب «قطعه نوشتار» را پردازش نکنند.
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 پاسخ یا خلاصه سریعی با گزیده محتوا از وبسایت مربوط ارائه میدهد. این گزیدههای ویژه بیشتر زمانی نشان داده میشوند که جستجو بهصورت سؤال باشد. کلیک کردن روی گزیده ویژه، کاربر را مستقیماً به نوشتار گزیده ویژه در صفحه وب منبع میبرد. این ویژگی بهلطف نشانیهای وب «قطعه نوشتار» که بهطور خودکار ایجاد شدهاند کار میکند.
نتیجهگیری
«نشانی وب قطعههای نوشتاری» ویژگی قدرتمندی برای پیوند دادن به نوشتار دلخواه در صفحههای وب است. جامعه علمی میتواند از آن برای ارائه پیوندهای ارجاع یا نقلقول بسیار دقیق استفاده کند. موتورهای جستجو میتوانند از آن برای پیوند عمیق به نتایج نوشتاری در صفحهها استفاده کنند. سایتهای شبکهسازی اجتماعی میتوانند از آن استفاده کنند تا به کاربران اجازه دهند بخشهای خاصی از صفحه وب را بهجای نماگرفتهای غیرقابلدسترس همرسانی کنند. امیدوارم شما هم شروع به استفاده از نشانیهای وب «قطعه نوشتار» کنید و آنها را بهاندازه من مفید بدانید. حتماً افزونه مرورگر پیوند به قطعه نوشتار را نصب کنید.
پیوندهای مرتبط
- پیشنویس مشخصات
- بررسی TAG
- ورودی وضعیت پلاتفرم Chrome
- اشکال ردیابی Chrome
- رشته Intent to Ship
- رشته WebKit-Dev
- رشته موقعیت استانداردهای Mozilla
تصدیقها
«قطعات نوشتار» توسط نیک بوریس و دیوید بوکان، با مشارکت گرانت وانگ پیادهسازی و مشخص شده است. از جو مدلی برای مرور کامل این سند سپاسگزاریم.