Fragmen Teks memungkinkan Anda menentukan cuplikan teks dalam fragmen URL. Saat membuka URL dengan fragmen teks seperti itu, browser dapat menekankan dan/atau mengarahkannya untuk menarik perhatian pengguna.
ID Fragmen
Chrome 80 adalah rilis besar. Versi ini berisi sejumlah fitur yang sangat dinantikan seperti Modul ECMAScript di Pekerja Web, penggabungan null, rantai opsional, dan banyak lagi. Rilis ini, seperti biasa, diumumkan melalui postingan blog di blog Chromium. Anda dapat melihat kutipan postingan blog tersebut di screenshot di bawah.
Anda mungkin bertanya-tanya arti semua kotak merah itu. Cuplikan tersebut dihasilkan dari menjalankan
cuplikan berikut di DevTools. Menandai semua elemen yang memiliki atribut id
.
document.querySelectorAll('[id]').forEach((el) => {
el.style.border = 'solid 2px red';
});
Saya dapat menempatkan deep link ke elemen apa pun yang ditandai dengan kotak merah berkat
ID fragmen
yang kemudian saya gunakan dalam hash
URL halaman. Dengan asumsi saya ingin membuat deep link ke kotak Beri kami masukan di
Forum Produk kami, saya dapat melakukannya dengan membuat URL
https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#HTML1
.
Seperti yang dapat Anda lihat di panel Elemen pada Developer Tools, elemen yang dimaksud memiliki atribut id
dengan nilai HTML1
.
Jika saya mengurai URL ini dengan konstruktor URL()
JavaScript, komponen yang berbeda akan ditampilkan.
Perhatikan properti hash
dengan nilai #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: ""
}
*/
Meskipun saya harus membuka Developer Tools untuk menemukan id
elemen menunjukkan volume
tentang kemungkinan bagian tertentu dari halaman ini dimaksudkan untuk ditautkan oleh penulis
postingan blog.
Bagaimana jika saya ingin menautkan ke sesuatu tanpa id
? Misalnya, saya ingin membuat link ke judul Modul ECMAScript
di Pekerja Web. Seperti yang dapat Anda lihat pada screenshot di bawah, <h1>
yang dimaksud tidak
memiliki atribut id
, yang berarti saya tidak dapat menautkan ke judul ini. Inilah masalah yang
dipecahkan oleh Fragmen Teks.
Fragmen Teks
Proposal Fragmen Teks menambahkan dukungan untuk menentukan cuplikan teks dalam hash URL. Saat membuka URL dengan fragmen teks seperti itu, agen pengguna dapat menekankan dan/atau mengarahkannya untuk menarik perhatian pengguna.
Kompatibilitas browser
Untuk alasan keamanan, fitur ini mengharuskan link dibuka dalam konteks
noopener
.
Oleh karena itu, pastikan untuk menyertakan
rel="noopener"
dalam
markup anchor <a>
atau menambahkan
noopener
ke daftar
Window.open()
fitur fungsi jendela Anda.
start
Dalam bentuknya yang paling sederhana, sintaksis Fragment Teks adalah sebagai berikut: Simbol hash #
diikuti dengan :~:text=
dan terakhir start
, yang mewakili teks dienkode persen yang ingin saya tautkan.
#:~:text=start
Misalnya, saya ingin menautkan ke judul Modul ECMAScript di Web Workers dalam postingan blog yang mengumumkan fitur di Chrome 80, dalam hal ini adalah:
Fragmen teks ditekankan seperti ini. Jika Anda mengklik link di browser pendukung seperti Chrome, fragmen teks akan ditandai dan di-scroll ke tampilan:
start
dan end
Sekarang, bagaimana jika saya ingin menautkan ke seluruh bagian yang berjudul Modul ECMAScript di Web Worker, bukan hanya heading-nya? Encoding persen seluruh teks pada bagian akan membuat URL yang dihasilkan menjadi sangat panjang.
Untungnya ada cara yang lebih baik. Alih-alih seluruh teks, saya dapat membingkai teks yang diinginkan menggunakan
sintaksis start,end
. Oleh karena itu, saya menentukan beberapa persen kata yang dienkode di awal
teks yang diinginkan, dan beberapa persen kata yang dienkode di akhir teks yang diinginkan, yang dipisahkan
dengan koma ,
.
Terlihat seperti ini:
Untuk start
, saya memiliki ECMAScript%20Modules%20in%20Web%20Workers
, lalu koma ,
yang diikuti
dengan ES%20Modules%20in%20Web%20Workers.
sebagai end
. Saat Anda mengeklik browser pendukung seperti Chrome, seluruh bagian akan disorot dan di-scroll hingga terlihat:
Sekarang Anda mungkin bertanya-tanya tentang pilihan start
dan end
saya. Sebenarnya, URL yang sedikit lebih pendek
https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#:~:text=ECMAScript%20Modules,Web%20Workers.
yang hanya memiliki dua kata di setiap sisi juga bisa berfungsi. Bandingkan start
dan end
dengan
nilai sebelumnya.
Jika saya mengambil satu langkah lebih jauh dan sekarang hanya menggunakan satu kata untuk start
dan end
, Anda dapat melihat bahwa saya dalam masalah. URL
https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#:~:text=ECMAScript,Workers.
sekarang lebih pendek, tetapi fragmen teks yang ditandai bukan lagi fragmen teks yang awalnya diinginkan. Sorotan
berhenti pada kemunculan pertama kata Workers.
, yang benar, tetapi bukan yang
ingin saya soroti. Masalahnya adalah bagian yang diinginkan tidak diidentifikasi secara unik oleh nilai start
dan end
satu kata saat ini:
prefix-
dan -suffix
Menggunakan nilai yang cukup panjang untuk start
dan end
adalah salah satu solusi untuk mendapatkan link unik.
Namun, dalam beberapa situasi, hal ini tidak mungkin. Sebagai catatan, mengapa saya memilih
postingan blog rilis Chrome 80 sebagai contoh? Jawabannya adalah bahwa dalam rilis ini, Fragmen Teks diperkenalkan:
Perhatikan bagaimana kata "teks" muncul empat kali dalam screenshot di atas. Kejadian selanjutnya ditulis
dengan {i>font<i} kode hijau. Jika ingin menautkan ke kata khusus ini, saya harus menyetel start
ke text
. Karena kata "text" hanya memiliki satu kata, maka tidak boleh ada end
. Apa selanjutnya? URL
https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#:~:text=text
cocok dengan kemunculan pertama kata "Text" yang sudah ada di judul:
Untungnya ada solusinya. Dalam kasus seperti ini, saya dapat menentukan prefix-
dan -suffix
. Kata
sebelum font kode hijau "text" adalah "the", dan kata setelahnya adalah "parameter". Tidak satu pun dari
tiga kemunculan kata "teks" lainnya dengan kata-kata di sekitarnya yang sama. Berbekal pengetahuan
ini, saya dapat menyesuaikan URL sebelumnya serta menambahkan prefix-
dan -suffix
. Seperti parameter lainnya, parameter ini juga harus dienkode dengan persen dan dapat berisi lebih dari satu kata.
https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#:~:text=the-,text,-parameter
.
Agar parser dapat mengidentifikasi prefix-
dan -suffix
dengan jelas, keduanya harus dipisahkan
dari start
dan end
opsional dengan tanda hubung -
.
Sintaksis lengkap
Sintaksis lengkap Fragmen Teks ditampilkan di bawah ini. (Tanda kurung siku menunjukkan parameter opsional.)
Nilai untuk semua parameter harus dienkode dengan persen. Hal ini sangat penting untuk karakter tanda hubung -
, &
, dan tanda koma ,
, sehingga tidak ditafsirkan sebagai bagian dari sintaksis perintah teks.
#:~:text=[prefix-,]start[,end][,-suffix]
Masing-masing prefix-
, start
, end
, dan -suffix
hanya akan cocok dengan teks dalam satu
elemen tingkat blok,
tetapi rentang start,end
lengkap dapat mencakup beberapa blok. Misalnya,
:~:text=The quick,lazy dog
akan gagal dicocokkan dalam contoh berikut, karena
string awal "The quick" tidak muncul dalam satu elemen tingkat blok tanpa gangguan:
<div>
The
<div></div>
quick brown fox
</div>
<div>jumped over the lazy dog</div>
Namun, cocok dengan contoh ini:
<div>The quick brown fox</div>
<div>jumped over the lazy dog</div>
Membuat URL Fragmen Teks dengan ekstensi browser
Membuat URL Fragmen Teks dengan tangan memang merepotkan, terutama jika harus memastikan URL tersebut unik. Jika Anda ingin, spesifikasinya memiliki beberapa tips dan mencantumkan langkah-langkah yang tepat untuk menghasilkan URL Fragmen Teks. Kami menyediakan ekstensi browser open source yang disebut Link to Text Fragment yang memungkinkan Anda menautkan ke teks apa pun dengan memilihnya, lalu mengklik "Copy Link to Selected Text" di menu konteks. Ekstensi ini tersedia untuk browser berikut:
- Menautkan ke Text Fragment untuk Google Chrome
- Menautkan ke Text Fragment untuk Microsoft Edge
- Link ke Text Fragment untuk Mozilla Firefox
- Link ke Text Fragment untuk Apple Safari
Beberapa fragmen teks dalam satu URL
Perhatikan bahwa beberapa fragmen teks dapat muncul dalam satu URL. Fragmen teks tertentu harus dipisahkan dengan karakter ampersand &
. Berikut adalah contoh link dengan tiga fragmen teks:
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
.
Mencampur elemen dan fragmen teks
Fragmen elemen tradisional dapat digabungkan dengan fragmen teks. Anda dapat menempatkan keduanya
di URL yang sama, misalnya, untuk memberikan penggantian yang bermakna jika teks asli di halaman
berubah, sehingga fragmen teks tidak cocok lagi. URL
https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#HTML1:~:text=Give%20us%20feedback%20in%20our%20Product%20Forums.
yang ditautkan ke Beri kami masukan di
bagian Forum Produk
berisi fragmen elemen (HTML1
), serta fragmen teks
(text=Give%20us%20feedback%20in%20our%20Product%20Forums.
):
Perintah fragmen
Ada satu elemen sintaksis yang belum saya jelaskan: perintah fragmen :~:
. Untuk menghindari
masalah kompatibilitas dengan fragmen elemen URL yang ada seperti ditunjukkan di atas, spesifikasi Fragmen Teks memperkenalkan perintah
fragmen. Perintah fragmen adalah bagian dari fragmen URL yang dibatasi oleh urutan kode
:~:
. Kolom ini dicadangkan untuk petunjuk agen pengguna, seperti text=
, dan dihapus dari URL
selama pemuatan sehingga skrip penulis tidak dapat berinteraksi langsung dengannya. Petunjuk agen pengguna
juga disebut perintah. Dalam kasus konkret, text=
disebut perintah teks.
Deteksi fitur
Untuk mendeteksi dukungan, uji properti fragmentDirective
hanya baca di document
. Perintah fragmen adalah mekanisme bagi URL untuk menentukan petunjuk yang ditujukan ke browser, bukan dokumen. Hal ini dimaksudkan untuk menghindari interaksi langsung dengan skrip penulis, sehingga petunjuk agen pengguna
di masa mendatang dapat ditambahkan tanpa takut menimbulkan perubahan yang dapat menyebabkan gangguan pada konten yang sudah ada. Salah satu
contoh potensial dari penambahan di masa mendatang adalah petunjuk terjemahan.
if ('fragmentDirective' in document) {
// Text Fragments is supported.
}
Deteksi fitur terutama ditujukan untuk kasus saat link dihasilkan secara dinamis (misalnya oleh mesin telusur) untuk menghindari penayangan link fragmen teks ke browser yang tidak mendukungnya.
Menata gaya fragmen teks
Secara default, browser menata gaya fragmen teks dengan cara yang sama seperti menata gaya
mark
(biasanya hitam dengan kuning,
warna sistem CSS
untuk mark
). Stylesheet agen pengguna berisi CSS yang terlihat seperti ini:
:root::target-text {
color: MarkText;
background: Mark;
}
Seperti yang dapat Anda lihat, browser menampilkan pemilih pseudo
::target-text
yang dapat Anda gunakan untuk
menyesuaikan penyorotan yang diterapkan. Misalnya, Anda dapat mendesain fragmen teks menjadi teks hitam dengan latar belakang merah. Seperti biasa, pastikan untuk
memeriksa kontras warna
agar gaya visual penggantian tidak menyebabkan masalah aksesibilitas dan pastikan sorotan benar-benar
terlihat secara visual menonjol dari konten lainnya.
:root::target-text {
color: black;
background-color: red;
}
Kemampuan isi otomatis
Fitur Text Fragments dapat di-polyfill hingga batas tertentu. Kami menyediakan polyfill, yang digunakan secara internal oleh ekstensi, untuk browser yang tidak menyediakan dukungan bawaan untuk Fragmen Teks tempat fungsi tersebut diimplementasikan di JavaScript.
Pembuatan link Fragmen Teks Terprogram
polyfill berisi file fragment-generation-utils.js
yang dapat Anda impor dan gunakan untuk menghasilkan link Fragmen Teks. Hal ini diuraikan dalam contoh kode di bawah ini:
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);
}
Mendapatkan Text Fragment untuk tujuan analisis
Banyak situs menggunakan fragmen ini untuk perutean, itulah sebabnya browser menghapus Fragmen Teks agar tidak merusak halaman tersebut. Ada keperluan yang dikonfirmasi untuk mengekspos link Fragmen Teks ke halaman, misalnya, untuk tujuan analisis, tetapi solusi yang diusulkan belum diterapkan. Sebagai solusi untuk saat ini, Anda dapat menggunakan kode di bawah ini untuk mengekstrak informasi yang diinginkan.
new URL(performance.getEntries().find(({ type }) => type === 'navigate').name).hash;
Keamanan
Perintah fragmen teks hanya dipanggil pada navigasi penuh (yang tidak sama) yang merupakan hasil dari
aktivasi pengguna.
Selain itu, navigasi yang berasal dari asal yang berbeda dengan tujuan akan memerlukan
navigasi untuk terjadi dalam
konteks noopener
, sehingga
halaman tujuan diketahui telah terisolasi secara memadai. Perintah fragmen teks hanya
diterapkan pada frame utama. Artinya, teks tidak akan ditelusuri di dalam iframe, dan navigasi iframe tidak akan memanggil fragmen teks.
Privasi
Implementasi spesifikasi Text Fragment harus dilakukan agar tidak membocorkan apakah fragmen teks
ditemukan di halaman atau tidak. Meskipun fragmen elemen sepenuhnya berada di bawah kontrol
penulis halaman asli, fragmen teks dapat dibuat oleh siapa saja. Ingat, dalam contoh saya di atas, tidak ada cara untuk menautkan ke heading ECMAScript Modules in Web Workers, karena <h1>
tidak memiliki id
, tetapi bagaimana orang, termasuk saya, dapat menautkan ke mana saja dengan membuat fragmen teks secara hati-hati?
Bayangkan saya menjalankan jaringan iklan jahat evil-ads.example.com
. Selanjutnya, bayangkan bahwa di salah satu iframe iklan, saya secara dinamis membuat iframe lintas origin tersembunyi ke dating.example.com
dengan URL Fragmen Teks dating.example.com#:~:text=Log%20Out
setelah pengguna berinteraksi dengan iklan. Jika teks "Logout" ditemukan, saya tahu bahwa korban saat ini
login ke dating.example.com
, yang dapat saya gunakan untuk pembuatan profil pengguna. Karena penerapan Text
Fragment yang naif mungkin memutuskan bahwa kecocokan yang berhasil akan menyebabkan tombol fokus, pada
evil-ads.example.com
saya dapat memproses peristiwa blur
sehingga dapat mengetahui kapan kecocokan terjadi. Di
Chrome, kami telah mengimplementasikan Fragmen Teks sedemikian rupa sehingga skenario di atas tidak dapat terjadi.
Serangan lain mungkin untuk mengeksploitasi
lalu lintas jaringan berdasarkan posisi {i>scroll<i}. Asumsikan saya memiliki akses ke log lalu lintas
jaringan korban, seperti admin intranet perusahaan. Sekarang, bayangkan ada dokumen personalia yang panjang What to Do if You Suffer From..., lalu daftar kondisi seperti burn out, kecemasan, dll. Saya dapat menempatkan piksel pelacakan di samping setiap item dalam daftar. Jika kemudian saya memutuskan bahwa pemuatan dokumen untuk sementara terjadi bersamaan dengan pemuatan piksel pelacakan di sebelah, misalnya, item kejenuhan, maka saya dapat, sebagai admin intranet, menentukan bahwa seorang karyawan telah mengklik link fragmen teks dengan :~:text=burn%20out
yang mungkin telah dianggap karyawan itu rahasia dan tidak dapat dilihat oleh siapa pun. Karena contoh ini agak dibuat-buat
untuk dimulai dan karena eksploitasinya memerlukan prasyarat yang sangat spesifik untuk dipenuhi,
tim keamanan Chrome mengevaluasi risiko penerapan scroll pada navigasi agar dapat dikelola.
Agen pengguna lain dapat memutuskan untuk menampilkan elemen UI scroll manual sebagai gantinya.
Untuk situs yang tidak ingin ikut serta, Chromium mendukung nilai header Document Policy yang dapat dikirim sehingga agen pengguna tidak akan memproses URL Fragmen Teks.
Document-Policy: force-load-at-top
Menonaktifkan fragmen teks
Cara termudah untuk menonaktifkan fitur ini adalah dengan menggunakan ekstensi yang dapat memasukkan header respons HTTP, misalnya, ModHeader (bukan produk Google), untuk menyisipkan header respons (bukan permintaan) sebagai berikut:
Document-Policy: force-load-at-top
Cara lain yang lebih rumit untuk memilih tidak ikut adalah dengan menggunakan setelan perusahaan
ScrollToTextFragmentEnabled
.
Untuk melakukannya di macOS, tempel perintah di bawah ini di terminal.
defaults write com.google.Chrome ScrollToTextFragmentEnabled -bool false
Di Windows, ikuti dokumentasi di situs dukungan Bantuan Google Chrome Enterprise.
Fragmen teks di penelusuran web
Untuk beberapa penelusuran, mesin telusur Google memberikan jawaban atau ringkasan cepat dengan cuplikan konten dari situs yang relevan. Cuplikan pilihan ini kemungkinan besar akan muncul saat penelusuran berupa pertanyaan. Mengklik cuplikan pilihan akan mengarahkan pengguna langsung ke teks cuplikan pilihan di halaman web sumber. Ini berfungsi berkat URL Fragmen Teks yang dibuat secara otomatis.
Kesimpulan
URL Fragmen Teks adalah fitur canggih untuk menautkan ke teks arbitrer di halaman web. Komunitas ilmiah dapat menggunakannya untuk memberikan kutipan atau link referensi yang sangat akurat. Mesin telusur dapat menggunakannya untuk membuat deeplink ke hasil teks di halaman. Situs jaringan sosial dapat menggunakannya untuk memungkinkan pengguna membagikan bagian tertentu dari halaman web, bukan screenshot yang tidak dapat diakses. Semoga Anda mulai menggunakan URL Fragmen Teks dan mendapatkan manfaat seperti saya. Pastikan untuk menginstal ekstensi browser Link to Text Fragment.
Link terkait
- Draf spesifikasi
- Tinjauan TAG
- Entri Status Platform Chrome
- Bug pelacakan Chrome
- Thread Intent to Ship
- Rangkaian pesan WebKit-Dev
- Thread posisi standar Mozilla
Ucapan terima kasih
Text Fragment diimplementasikan dan ditentukan oleh Nick Burris dan David Bokan, dengan kontribusi dari Grant Wang. Terima kasih kepada Joe Medley untuk peninjauan menyeluruh atas artikel ini. Banner besar oleh Greg Rakozy di Unsplash.