קטעי טקסט מאפשרים לציין קטע טקסט בקטע של כתובת האתר. כשמנווטים לכתובת URL עם מקטע טקסט כזה, הדפדפן יכול להדגיש ו/או להביא אותה לתשומת הלב של המשתמש.
מזהי מקטעים
Chrome 80 היה הפצה גדולה. הוא כלל כמה תכונות שכולם חיכו להם, כמו ECMAScript Modules in Web Workers , nullish colescing, יצירת שרשור אופציונלי ועוד. ההשקה פורסמה כרגיל באמצעות פוסט בבלוג בבלוג Chromium. אפשר לראות קטע מהפוסט בבלוג בצילום המסך שלמטה.
אתם בטח שואלים את עצמכם מה המשמעות של כל התיבות האדומות. הן התוצאה של הרצת קטע הקוד הבא בכלי הפיתוח. היא מדגישה את כל הרכיבים שיש להם מאפיין id
.
document.querySelectorAll('[id]').forEach((el) => {
el.style.border = 'solid 2px red';
});
תודה למזהה המקטע שבו אני משתמש ב-hash של כתובת ה-URL של הדף, כדי למקם קישור עומק לכל אלמנט שמודגש בתיבה אדומה. בהנחה שהייתי רוצה להוסיף קישור עומק לתיבה נשמח לקבל משוב בפורומים של המוצרים שבצד, אפשר לעשות זאת על ידי יצירה ידנית של כתובת ה-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 Modules in Web Workers (מודולים של ECMAScript in Web Workers). כפי שאפשר לראות בצילום המסך שבהמשך, ל-<h1>
הרלוונטי אין מאפיין id
, ולכן אין אפשרות לקשר לכותרת הזו. זו הבעיה שקטעי טקסט פותרים.
קטעי טקסט
ההצעה קטעי טקסט מוסיפה תמיכה בהגדרת קטע טקסט בגיבוב של כתובת URL. כשמנווטים לכתובת URL עם מקטע טקסט כזה, סוכן המשתמש יכול להדגיש זאת ו/או להפנות את תשומת ליבו של המשתמש.
תאימות דפדפן
מטעמי אבטחה, כדי להשתמש בתכונה הזו צריך לפתוח קישורים בהקשר של noopener
.
לכן, חשוב לכלול את הערך rel="noopener"
בתגי העיצוב של מודעות העוגן <a>
או להוסיף את noopener
לרשימת Window.open()
התכונות של פונקציונליות החלון.
start
בצורתו הפשוטה ביותר, התחביר של Text Fragments הוא: סמל הגיבוב #
ואחריו :~:text=
, ולבסוף start
, שמייצג את הטקסט בקידוד אחוזים שאליו רוצים לקשר.
#:~:text=start
לדוגמה, נניח שאני רוצה לקשר אל ECMAScript Modules in Web Workers בפוסט בבלוג שמכריז על תכונות ב-Chrome 80, כתובת ה-URL במקרה הזה תהיה:
מקטע הטקסט מודגש כך. אם לוחצים על הקישור בדפדפן תומך כמו Chrome, מקטע הטקסט יודגש וגולל לתצוגה:
start
וגם end
מה קורה אם אני רוצה לקשר את כל הקטע שכותרתו ECMAScript Modules in 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
הוא פתרון אחד לקבלת קישור ייחודי.
עם זאת, במצבים מסוימים אי אפשר לעשות זאת. תזכורת: למה בחרתי את הפוסט בבלוג
על גרסה 80 של Chrome כדוגמה? התשובה היא שבמהדורה הזו הצגנו את קטעי הטקסט:
שימו לב איך בצילום המסך שמעל המילה "טקסט" מופיעה ארבע פעמים. האירוע הרביעי נכתב בגופן קוד ירוק. כדי לקשר למילה המסוימת הזו, צריך להגדיר את 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". לאף אחד משלושת המופעים האחרים של המילה "טקסט" אין אותן מילים מסביב. בזכות הידע הזה, אני יכול לשנות את כתובת ה-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 Fast" לא מופיעה בתוך רכיב אחד ברמת הבלוק ללא הפרעות:
<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 של Text Fragment. אנחנו מספקים תוסף קוד פתוח לדפדפן שנקרא Link to Text Fragment (קישור למקטע טקסט) שמאפשר לקשר לטקסט כלשהו על ידי בחירה בו, ולאחר מכן לחיצה על Copy Link to selected Text (העתקת הקישור לטקסט שנבחר) בתפריט ההקשר. התוסף הזה זמין בדפדפנים הבאים:
- קישור למקטע טקסט ב-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
(בדרך כלל שחור על צהוב, צבעי המערכת של CSS עבור mark
). גיליון הסגנונות של סוכן המשתמש מכיל CSS שנראה כך:
:root::target-text {
color: MarkText;
background: Mark;
}
כמו שאפשר לראות, הדפדפן חושף פסאודו סלקטור ::target-text
, שאפשר להשתמש בו כדי להתאים אישית את ההדגשה שהוחלה. לדוגמה, אפשר לעצב את מקטעי הטקסט כטקסט שחור על רקע אדום. כמו תמיד, חשוב לבדוק את ניגודיות הצבעים כדי ששינוי הסגנון לא יגרום לבעיות נגישות, וכדי לוודא שההדגשה בולטת
משאר התוכן.
:root::target-text {
color: black;
background-color: red;
}
יכולת מילוי רבייה
ניתן למלא במידה מסוימת את התכונה 'קטעי טקסט'. אנחנו מספקים polyfill, שנמצא בשימוש פנימי של התוסף, לדפדפנים שלא מספקים תמיכה מובנית ל-Text Fragments שבהם הפונקציונליות מיושמת ב-JavaScript.
יצירת קישורים למקטע טקסט פרוגרמטי
ה-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 לא יפעיל קטע טקסט.
פרטיות
חשוב שהטמעות של מפרט Text Fragments לא ידלפו אם נמצא קטע טקסט בדף או לא. מקטעי טקסט נמצאים בשליטתו המלאה של מחבר הדף המקורי, אבל כל אחד יכול ליצור קטעי טקסט. חשוב לזכור שבדוגמה שלמעלה לא הייתה דרך לקשר את הכותרת ECMAScript Modules in 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, הטמענו קטעי טקסט באופן שבו התרחיש שלמעלה לא יכול לקרות.
מתקפה נוספת עלולה להיות ניצול התנועה ברשת על סמך מיקום הגלילה. נניח שהייתה לי גישה ליומני התנועה ברשת של הקורבן שלי, למשל כמנהל/ת רשת אינטראנט של חברה. עכשיו נניח שיש מסמך ארוך של משאבי אנוש What to Do If You Sufer From... ואז רשימה של מצבים כמו שחיקה, חרדה וכו'. אפשר למקם פיקסל למעקב ליד כל פריט ברשימה. אם אגיע למסקנה שטעינת המסמך מתרחשת באופן זמני בזמן הטעינה של פיקסל המעקב לצד הפריט השחיקה, למשל, כאדמין אינטראנט אוכל לקבוע שעובד לחץ על קישור למקטע טקסט עם :~:text=burn%20out
שהעובד הניח שהוא סודי ולא גלוי לאף אחד. מכיוון שהדוגמה הזו קצת מובנת בהתחלה, ומכיוון שהניצול של המידע דורש מאוד תנאים מוקדמים ספציפיים, צוות האבטחה של Chrome העריך את הסיכון בהטמעה של גלילה בניווט.
סוכני משתמש אחרים יכולים להחליט אם להציג במקום זאת רכיב של גלילה ידנית בממשק המשתמש.
באתרים שרוצים לבטל את ההסכמה לשימוש בהם, Chromium תומך בערך כותרת Document Policy שניתן לשלוח, כדי שסוכני המשתמש לא יעבדו כתובות 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 של Text Fragment, והן יהיו מועילות כמוני. הקפידו להתקין את תוסף הדפדפן Link to Text Fragment.
קישורים רלוונטיים
- טיוטת המפרט
- תיוג ביקורת
- רשומה בסטטוס הפלטפורמה של Chrome
- באג במעקב ב-Chrome
- כוונה לשלוח את השרשור
- שרשור WebKit-Dev
- שרשור מיקום בסטנדרטים של Mozilla
אישורים
Text Fragments יושם וסופק על ידי ניק בוריס ודייוויד בוקאן, עם תרומות מאת גרנט וואנג. תודה ל-Joe Medley על הביקורת היסודית של מאמר זה. תמונה ראשית (Hero) מאת Greg Rakozy באתר UnFlood.