Text Fragments به شما امکان می دهد یک قطعه متن را در قطعه URL مشخص کنید. هنگام پیمایش به یک URL با چنین قطعه متنی، مرورگر می تواند بر آن تأکید کند و/یا توجه کاربر را جلب کند.
شناسه های قطعه
کروم 80 نسخه بزرگی بود. این شامل تعدادی از ویژگی های بسیار مورد انتظار مانند ماژول های ECMAScript در Web Workers ، ادغام بی اثر ، زنجیره اختیاری ، و موارد دیگر بود. انتشار طبق معمول از طریق یک پست وبلاگ در وبلاگ Chromium اعلام شد. شما می توانید گزیده ای از پست وبلاگ را در تصویر زیر مشاهده کنید.
احتمالاً از خود میپرسید همه جعبههای قرمز به چه معنا هستند. آنها نتیجه اجرای قطعه زیر در DevTools هستند. تمام عناصری که دارای ویژگی 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
انجام دهم. https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html #HTML1
. همانطور که در پنل عناصر Developer Tools می بینید، عنصر مورد نظر دارای یک ویژگی id
با مقدار HTML1
است.
اگر این URL را با سازنده 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: ""
}
*/
این واقعیت که من مجبور شدم ابزارهای توسعه دهنده را باز کنم تا id
یک عنصر را بیابم، در مورد احتمال اینکه نویسنده پست وبلاگ به این بخش خاص از صفحه پیوند داده شده است، گویای این است.
اگر بخواهم بدون id
به چیزی پیوند دهم چه می شود؟ بگویید من می خواهم به عنوان ماژول های ECMAScript در Web Workers پیوند دهم. همانطور که در تصویر زیر می بینید، <h1>
مورد نظر دارای ویژگی id
نیست، به این معنی که هیچ راهی وجود ندارد که بتوانم به این عنوان پیوند دهم. این مشکلی است که Text Fragments حل می کند.
تکه های متن
پیشنهاد Text Fragments پشتیبانی برای مشخص کردن یک قطعه متن در هش URL را اضافه می کند. هنگام پیمایش به یک URL با چنین قطعه متنی، عامل کاربر می تواند بر آن تاکید کند و/یا توجه کاربر را جلب کند.
سازگاری مرورگر
به دلایل امنیتی ، این ویژگی نیاز دارد که پیوندها در یک زمینه noopener
باز شوند. بنابراین، مطمئن شوید که rel="noopener"
در <a>
anchor markup خود اضافه کنید یا 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
. وقتی روی یک مرورگر پشتیبانی مانند کروم کلیک میکنید، کل بخش برجسته میشود و برای مشاهده اسکرول میشود:
اکنون ممکن است در مورد انتخاب من برای 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
استفاده کنم، می بینید که در مشکل هستم. نشانی اینترنتی 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 Fragments معرفی شدند:
توجه کنید که چگونه در تصویر بالای صفحه کلمه "متن" چهار بار ظاهر می شود. رخداد چهارم با فونت کد سبز نوشته شده است. اگر بخواهم به این کلمه خاص پیوند دهم، start
به text
تنظیم می کنم. از آنجایی که کلمه "متن" فقط یک کلمه است، end
وجود ندارد. حالا چی؟ نشانی وب https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html #:~:text=text
با اولین تکرار کلمه "Text" در حال حاضر مطابقت دارد عنوان:
خوشبختانه راه حلی وجود دارد. در مواردی مانند این، من می توانم یک prefix-
و یک -suffix
مشخص کنم. کلمه قبل از فونت کد سبز "text" "the" و کلمه بعد "پارامتر" است. هیچ یک از سه رخداد دیگر کلمه "متن" کلمات اطراف یکسانی ندارند. با داشتن این دانش، میتوانم 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 Fragments در زیر نشان داده شده است. (براکت های مربع یک پارامتر اختیاری را نشان می دهد.) مقادیر همه پارامترها باید به صورت درصد رمزگذاری شوند. این به ویژه برای نویسههای خط -
، علامت &
علامت ,
و ویرگول مهم است، بنابراین آنها به عنوان بخشی از نحو دستور متن تفسیر نمیشوند.
#:~: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 ارائه می دهیم که به شما امکان می دهد با انتخاب هر متنی به آن پیوند دهید و سپس روی "Copy Link to Selected Text" در منوی زمینه کلیک کنید. این افزونه برای مرورگرهای زیر موجود است:
- پیوند به بخش متن برای Google Chrome
- پیوند به بخش متن برای مایکروسافت اج
- پیوند به بخش متن برای موزیلا فایرفاکس
- پیوند به بخش متن برای 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 داشته باشید، به عنوان مثال، برای ارائه یک بازگشت معنی دار در صورت تغییر متن اصلی در صفحه، به طوری که قطعه متن دیگر مطابقت نداشته باشد. نشانی وب 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
). شیوه نامه user-agent حاوی CSS است که به شکل زیر است:
:root::target-text {
color: MarkText;
background: Mark;
}
همانطور که می بینید، مرورگر یک شبه انتخابگر ::target-text
را نشان می دهد که می توانید از آن برای سفارشی کردن برجسته سازی اعمال شده استفاده کنید. به عنوان مثال، می توانید قطعات متن خود را به صورت متن سیاه روی پس زمینه قرمز طراحی کنید. مثل همیشه، حتما کنتراست رنگ را بررسی کنید تا استایل نادیده گرفته شده شما باعث مشکلات دسترسی نشود و مطمئن شوید که هایلایت واقعاً از نظر بصری از بقیه محتوا متمایز است.
:root::target-text {
color: black;
background-color: red;
}
قابلیت چندپر شدن
ویژگی Text Fragments را می توان تا حدی چند پر کرد. ما یک polyfill ارائه می دهیم که به صورت داخلی توسط برنامه افزودنی استفاده می شود، برای مرورگرهایی که پشتیبانی داخلی برای قطعات متنی که در جاوا اسکریپت اجرا می شود، ارائه نمی دهند.
تولید پیوند قطعه متن برنامهای
polyfill حاوی یک فایل fragment-generation-utils.js
است که می توانید آن را وارد کرده و از آن برای ایجاد پیوندهای Text Fragment استفاده کنید. این در نمونه کد زیر مشخص شده است:
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
گوش دهم و بنابراین بدانم چه زمانی تطابق رخ داده است. در کروم، تکست فرگمنت ها را به گونه ای پیاده سازی کرده ایم که سناریوی بالا نمی تواند اتفاق بیفتد.
حمله دیگر ممکن است سوء استفاده از ترافیک شبکه بر اساس موقعیت اسکرول باشد. فرض کنید من به گزارشهای ترافیک شبکه قربانیم دسترسی داشتم، مثلاً به عنوان مدیر اینترانت شرکت. حالا تصور کنید که یک سند طولانی منابع انسانی وجود دارد که اگر از آن رنج میبرید چه باید کرد... و سپس فهرستی از شرایطی مانند فرسودگی ، اضطراب ، و غیره وجود داشت. من میتوانم یک پیکسل ردیابی را در کنار هر مورد در لیست قرار دهم. سپس اگر تشخیص دهم که بارگیری سند به طور موقت با بارگذاری پیکسل ردیابی در کنار، مثلاً مورد سوخته شده، همزمان اتفاق می افتد، می توانم به عنوان سرپرست اینترانت تعیین کنم که یک کارمند روی پیوند قطعه متن کلیک کرده است. با :~:text=burn%20out
که ممکن است کارمند فرض کرده باشد محرمانه بوده و برای کسی قابل مشاهده نیست. از آنجایی که این مثال برای شروع تا حدی ساختگی است و از آنجایی که بهره برداری از آن نیازمند پیش شرط های بسیار خاصی است، تیم امنیتی Chrome خطر پیاده سازی اسکرول در ناوبری را به عنوان قابل مدیریت ارزیابی کرد. سایر عوامل کاربر ممکن است تصمیم بگیرند به جای آن یک عنصر اسکرول دستی UI را نشان دهند.
برای سایتهایی که میخواهند انصراف دهند، 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 Help را دنبال کنید.
قطعات متن در جستجوی وب
برای برخی از جستجوها، موتور جستجوی گوگل پاسخ یا خلاصه ای سریع با یک قطعه محتوا از یک وب سایت مرتبط ارائه می دهد. این قطعههای برجسته به احتمال زیاد زمانی که جستجو در قالب یک سؤال است نشان داده میشوند. با کلیک بر روی یک قطعه برجسته، کاربر مستقیماً به متن قطعه برجسته در صفحه وب منبع میرود. این به لطف URL های قطعه متنی ایجاد شده به طور خودکار کار می کند.
نتیجه گیری
URL Fragments متن یک ویژگی قدرتمند برای پیوند دادن به متن دلخواه در صفحات وب است. جامعه علمی می تواند از آن برای ارائه پیوندهای استنادی یا مرجع بسیار دقیق استفاده کند. موتورهای جستجو می توانند از آن برای پیوند عمیق به نتایج متنی در صفحات استفاده کنند. سایتهای شبکههای اجتماعی میتوانند از آن استفاده کنند تا به کاربران اجازه دهند بخشهای خاصی از یک صفحه وب را بهجای اسکرینشاتهای غیرقابل دسترس به اشتراک بگذارند. امیدوارم شروع به استفاده از URL های تکست فرگمنت کنید و آنها را مانند من مفید بیابید. پسوند مرورگر Link to Text Fragment را حتما نصب کنید.
لینک های مرتبط
- پیش نویس مشخصات
- بررسی تگ
- ورودی وضعیت پلتفرم Chrome
- اشکال ردیابی کروم
- قصد ارسال موضوع
- موضوع WebKit-Dev
- موضوع موقعیت استاندارد موزیلا
قدردانی ها
تکست فرگمنت ها توسط نیک بوریس و دیوید بوکان و با مشارکت گرانت وانگ پیاده سازی و مشخص شد. با تشکر از جو مدلی برای بررسی کامل این مقاله. تصویر قهرمان توسط گرگ راکوزی در Unsplash .