התכונה 'קטעי טקסט' מאפשרת לציין קטע טקסט במקטע של כתובת האתר. כשמנווטים לכתובת URL עם קטע טקסט כזה, הדפדפן יכול להדגיש ו/או למשוך את תשומת הלב של המשתמש.
מזהי מקטעים
Chrome 80 היה הפצה גדולה. התוכנה כללה כמה תכונות שכולם מצפים להן, ECMAScript Modules in Web Workers, nullish coalescing, שרשורים אופציונליים ועוד. הפרסום היה, כרגיל, שהוכרז באמצעות פוסט בבלוג ב- הבלוג של Chromium. בצילום המסך למטה אפשר לראות קטע מהפוסט בבלוג.
בטח שאלת את עצמך מה המשמעות של כל התיבות האדומות. הן התוצאה של הפעלת
בקטע הבא בכלי הפיתוח. היא מדגישה את כל האלמנטים שיש להם מאפיין id
.
document.querySelectorAll('[id]').forEach((el) => {
el.style.border = 'solid 2px red';
});
אני יכול למקם קישור עומק לכל אלמנט שמודגש בתיבה אדומה הודות ל-
מזהה שבר
ואז אשתמש ב-hash של
כתובת האתר של הדף. בהנחה שרציתי ליצור קישור עומק אל תנו לנו משוב
בתיבה Product Forums בתיבה
אבל אוכל לעשות זאת באופן ידני
https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#HTML1
.
כפי שניתן לראות בחלונית הרכיבים ב'כלים למפתחים', לרכיב המדובר יש id
עם הערך HTML1
.
אם אנתח את כתובת ה-URL הזו באמצעות ה-constructor של 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 עם שבר טקסט כזה, סוכן משתמש יכול להדגיש ו/או להביא זאת לתשומת ליבנו של המשתמש.
תאימות דפדפן
מטעמי אבטחה, התכונה מחייבת לפתוח קישורים
noopener
הקשר.
לכן, חשוב לכלול
rel="noopener"
ב-
הוספה או תגי עיצוב של עוגן <a>
noopener
אל
רשימה של Window.open()
של תכונות הפונקציונליות של החלון.
start
בצורתו הפשוטה ביותר, התחביר של מקטעי טקסט הוא כך: סמל הגיבוב #
ואחריו
:~:text=
ולבסוף start
, שמייצג את
קידוד באחוזים
הטקסט שאני רוצה לקשר אליו.
#:~:text=start
לדוגמה, נניח שאתם רוצים לקשר לכותרת ECMAScript Modules in 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
. מאז שהמילה "text" היא, ובכן, רק מילה אחת, לא יכול להיות end
. מה עכשיו?
כתובת URL
https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#:~:text=text
תואם למופע הראשון של המילה "Text" כבר בכותרת:
למרבה המזל, יש פתרון. במקרים כאלה, אפשר לציין prefix-
ו--suffix
.
מילה לפני גופן הקוד הירוק "text" הוא 'the' והמילה שאחריה היא 'parameter'. אף אחת מהאפשרויות
שלושה מופעים אחרים של המילה "text" כולל את אותן מילים מסביב. מוצמד
אני יכול לשנות את כתובת ה-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
- קישור ל-Text Fragment ב-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
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.
):
הוראת המקטע
יש רכיב אחד בתחביר שעדיין לא הסברתי: הוראת המקטע :~:
. כדי להימנע
של בעיות תאימות עם קטעים קיימים של רכיבים בכתובת האתר כפי שמוצג למעלה,
המפרט של מקטעי טקסט כולל את המקטע
של Google. הוראת המקטע היא חלק ממקטע כתובת האתר שמופרד על ידי רצף הקוד
:~:
הכתובת הזו שמורה להוראות של סוכן משתמש, כמו 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, המשמש באופן פנימי על ידי התוסף, לדפדפנים שלא לספק תמיכה מובנית בקטעי טקסט שבהם הפונקציונליות מוטמעת ב-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;
אבטחה
הוראות לגבי קטעי טקסט מופעלות רק בניווטים מלאים (שאינם באותו דף) שנובעים מ-
a
הפעלת המשתמש.
בנוסף, ניווטים שהגיעו ממקור שונה מזה של היעד יחייבו את המאפיין הבא:
במהלך הניווט,
noopener
, כמו
שדף היעד ידוע שהוא מבודד מספיק. הוראות למקטעי טקסט הן רק
הוחלו על המסגרת הראשית. כלומר, לא יתבצע חיפוש בטקסט בתוך iframes וב-iframe
הניווט לא יפעיל קטע טקסט.
פרטיות
חשוב שהטמעות של מפרט Text Fragments לא יגרמו לדליפה
נמצא מקטע בדף, או לא. למרות שמקטעי רכיבים נמצאים במלואם בשליטה של
מחבר הדף המקורי, כל אחד יכול ליצור מקטעי טקסט. זכרו איך בדוגמה שלי שלמעלה
לא הייתה דרך לקשר לכותרת מודולים של ECMAScript ב-Web Workers, כי המדיניות <h1>
אין id
, אבל איך כולם, כולל אני, יכולים פשוט ליצור קישור למקום כלשהו על ידי
את קטע הטקסט?
נניח שהפעלתי רשת מודעות זדונית evil-ads.example.com
. נסו לדמיין שבאחת מהמודעות שלי
iframes יצרתי באופן דינמי iframe מוסתר ממקורות שונים ל-dating.example.com
עם טקסט
כתובת ה-URL של המקטע
dating.example.com#:~:text=Log%20Out
ברגע שהמשתמש קיים אינטראקציה עם המודעה. אם מופיע הכיתוב 'התנתקות' נמצא, אני יודע שהקורבן נמצא כרגע
מחובר אל dating.example.com
, ואני יכול להשתמש בו ליצירת פרופיל משתמשים. בגלל טקסט נאיבי
הטמעת מקטעים עשויה להחליט שהתאמה מוצלחת צריכה לגרום להחלפת מיקוד, מופעל
evil-ads.example.com
יכולתי להאזין לאירוע blur
וכך לדעת מתי התרחשה התאמה. לחשבון
ב-Chrome, הטמענו מקטעי טקסט כך שהתרחיש שלמעלה לא יכול לקרות.
מתקפה נוספת עשויה להיות ניצול התנועה ברשת על סמך מיקום הגלילה. נניח שהייתה לי גישה אל
של יומני התנועה של הקורבן שלי, למשל כאדמין של רשת אינטראנט של חברה. עכשיו, לדמיין
היה מסמך ארוך של משאבי אנוש, What to do if You Suffer From..., ולאחר מכן רשימה
כמו שחיקה, חרדה וכו'. אני יכול למקם פיקסל מעקב ליד כל פריט
חדשה. אם לאחר מכן אחליט שטעינת המסמך מתרחשת באופן זמני עם טעינת
פיקסל מעקב שלצידו, למשל, הפריט שחיקה, אני יכול, בתור מנהל אינטראנט, לקבוע
עובד לחץ על קישור של קטע טקסט עם :~: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 של קטעי טקסט והם יהיו שימושיים כמוני. חשוב להתקין את הדפדפן קישור ל-Text Fragment לתוסף.
קישורים רלוונטיים
- טיוטת מפרט
- סקירה של TAG
- רשומה של סטטוס פלטפורמת Chrome
- באג במעקב ב-Chrome
- הכוונה לשליחת שרשור
- שרשור WebKit-Dev
- שרשור מיקום בסטנדרטים של Mozilla
אישורים
התכונה Text Fragments הוטמעה וצוינה על ידי Nick Burris דייוויד בוקאן, עם תרומות מאת גראנט וואנג. תודה לג'ו מדלי על על הסקירה היסודית של מאמר זה. התמונה הראשית (Hero) של גרג ראקוזי בפלטפורמת ביטול הפתיחה.