Daha önce hiç kimsenin bağlantı kurmadığı yerlerde kalın bağlantı oluşturun: Metin Parçaları

Metin parçaları, URL parçasında bir metin snippet'i belirtmenize olanak tanır. Tarayıcı, bu tür bir metin parçası içeren bir URL'ye gittiğinde metni vurgulayabilir ve kullanıcının dikkatini çekebilir.

Parça tanımlayıcıları

Chrome 80 önemli bir sürümdü. Web Çalışanları'nda ECMAScript Modülleri, nullish birleştirme, isteğe bağlı zincirleme ve daha fazlası gibi merakla beklenen birçok özellik içeriyordu. Sürüm, her zamanki gibi Chromium blogundaki bir blog yayını aracılığıyla duyuruldu. Aşağıdaki ekran görüntüsünde blog yayınından bir alıntı görebilirsiniz.

id özelliğine sahip öğelerin etrafında kırmızı kutular bulunan Chromium blog yayını.

Kırmızı kutuların ne anlama geldiğini merak ediyor olabilirsiniz. Bunlar, Geliştirici Araçları'nda aşağıdaki snippet'i çalıştırmanın sonucudur. id özelliğine sahip tüm öğeleri vurgular.

document.querySelectorAll('[id]').forEach((el) => {
  el.style.border = 'solid 2px red';
});

Sayfanın URL'sinin karma kısmında kullandığım parça tanımlayıcı sayesinde kırmızı kutuyla vurgulanan herhangi bir öğeye derin bağlantı yerleştirebilirim. Kenar çubuğundaki Ürün Forumlarımızda bize geri bildirim gönderin kutusuna derin bağlantı vermek istediğimi varsayalım. Bunu, https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#HTML1 URL'sini manuel olarak oluşturarak yapabilirim. Geliştirici Araçları'nın Öğeler panelinde görebileceğiniz gibi, söz konusu öğenin HTML1 değerine sahip bir id özelliği var.

Bir öğenin id değerini gösteren Geliştirici Araçları.

Bu URL'yi JavaScript'in URL() oluşturucusuyla ayrıştırırsam farklı bileşenler ortaya çıkar. #HTML1 değerine sahip hash özelliğine dikkat edin.

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: ""
}
*/

Ancak bir öğenin id değerini bulmak için Geliştirici Araçları'nı açmak zorunda kalmam, sayfanın bu bölümünün blog yayınının yazarı tarafından bağlantı verilmek üzere tasarlandığı olasılığı hakkında çok şey anlatıyor.

id olmadan bir şeye bağlantı vermek istersem ne olur? Web Çalışanlarında ECMAScript Modülleri başlığına bağlantı vermek istediğimi varsayalım. Aşağıdaki ekran görüntüsünde görebileceğiniz gibi, söz konusu <h1> öğesinin id özelliği yok. Bu nedenle, bu başlığa bağlantı vermem mümkün değil. Metin Parçaları bu sorunu çözer.

Geliştirici Araçları'nda id olmadan gösterilen bir başlık.

Metin Parçaları

Metin Parçaları teklifi, URL karma değerinde bir metin snippet'i belirtme desteği ekler. Kullanıcı aracısı, bu tür bir metin parçası içeren bir URL'ye gittiğinde bu parçayı vurgulayabilir ve kullanıcının dikkatini çekebilir.

Tarayıcı uyumluluğu

Browser Support

  • Chrome: 89.
  • Edge: 89.
  • Firefox: 131.
  • Safari: 18.2.

Source

Güvenlik nedeniyle bu özellik, bağlantıların noopener bağlamında açılmasını gerektirir. Bu nedenle, <a> bağlantı işaretlemenize rel="noopener" eklediğinizden veya Window.open() pencere işlevi özellikleri listenize noopener eklediğinizden emin olun.

start

Metin Parçaları'nın söz dizimi en basit haliyle şu şekildedir: diyez simgesi #, ardından :~:text= ve son olarak bağlantı oluşturmak istediğim yüzde kodlamalı metni temsil eden start.

#:~:text=start

Örneğin, Chrome 80'deki özellikleri duyuran blog yayınındaki Web Çalışanlarında ECMAScript Modülleri başlığına bağlantı vermek istediğimi varsayalım. Bu durumda URL şöyle olur:

https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#:~:text=ECMAScript%20Modules%20in%20Web%20Workers

Metin parçası bu şekilde vurgulanır. Chrome gibi destekleyen bir tarayıcıda bağlantıyı tıklarsanız metin parçası vurgulanır ve kaydırılarak görünür hale gelir:

Metin parçası kaydırılarak görünüme getirilir ve vurgulanır.

start ve end

Peki, yalnızca başlığına değil, Web Çalışanlarında ECMAScript Modülleri başlıklı bölümün tamamına bağlantı vermek istersem ne yapmalıyım? Bölüm metninin tamamının yüzde kodlaması, sonuçta elde edilen URL'yi kullanılamayacak kadar uzun hale getirir.

Neyse ki daha iyi bir yöntem var. Metnin tamamı yerine belirli bir bölümünü start,end söz dizimiyle çerçeveleyebilirim. Metin parçasının başında yüzde kodlamalı birkaç kelime ve metin parçasının sonunda yüzde kodlamalı birkaç kelime belirtip bunları virgülle ayırıyorum.

Bu, şu şekilde görünür:

https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#:~:text=ECMAScript%20Modules%20in%20Web%20Workers,ES%20Modules%20in%20Web%20Workers..

start için ECMAScript%20Modules%20in%20Web%20Workers, ardından virgül ve end olarak ES%20Modules%20in%20Web%20Workers. var. Chrome gibi destekleyen bir tarayıcıda tıkladığınızda bölümün tamamı vurgulanır ve kaydırılarak görünür hale gelir:

Metin parçası kaydırılarak görünüme getirilir ve vurgulanır.

Şimdi start ve end seçimimin nedenini merak ediyor olabilirsiniz. Aslında her iki tarafında yalnızca iki kelime bulunan biraz daha kısa URL https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#:~:text=ECMAScript%20Modules,Web%20Workers. de işe yarardı. start ve end değerlerini önceki değerlerle karşılaştırın.

Bir adım daha ileri gidip hem start hem de end için tek bir kelime kullanırsam başımın dertte olduğunu görebilirsiniz. https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#:~:text=ECMAScript,Workers. URL'si artık daha da kısa ancak vurgulanan metin parçası artık orijinal olarak seçilen metin parçası değil. Vurgulama, Workers. kelimesinin ilk geçtiği yerde duruyor. Bu doğru ancak vurgulamak istediğim şey bu değil. Sorun, seçilen bölümün mevcut tek kelimelik start ve end değerleriyle benzersiz bir şekilde tanımlanmamasıdır:

İstenmeyen metin parçası kaydırılarak görünüme getirildi ve vurgulandı.

prefix- ve -suffix

Benzersiz bir bağlantı elde etmek için start ve end için yeterince uzun değerler kullanabilirsiniz. Ancak bazı durumlarda bu mümkün olmayabilir. Bu arada, örnek olarak neden Chrome 80 sürümünün blog yayınını seçtim? Bu sürümde metin parçaları kullanıma sunuldu:

Blog yayını metni: Metin URL parçaları. Kullanıcılar veya yazarlar artık URL'de sağlanan bir metin parçasını kullanarak sayfanın belirli bir bölümüne bağlantı verebilir. Sayfa yüklendiğinde tarayıcı, metni vurgular ve parçayı görünür hale getirir. Örneğin, aşağıdaki URL, &quot;Kedi&quot; ile ilgili bir wiki sayfasını yükler ve `text` parametresinde listelenen içeriğe kaydırır.
Metin Parçaları duyuru blog yayını alıntısı.

Yukarıdaki ekran görüntüsünde "text" kelimesinin dört kez göründüğüne dikkat edin. Dördüncü örnek, yeşil renkli kod yazı tipiyle yazılmıştır. Bu kelimeye bağlantı vermek isteseydim start değerini text olarak ayarlardım. "Metin" kelimesi tek bir kelime olduğu için end olamaz. Şimdi ne yapmalıyım? https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#:~:text=text URL'si, başlıkta zaten bulunan "Metin" kelimesinin ilk geçtiği yerle eşleşir:

"Metin" ifadesinin ilk geçtiği yerle eşleşen metin parçası.

Neyse ki bunun bir çözümü var. Bu gibi durumlarda prefix- ve -suffix belirtebilirim. Yeşil kod yazı tipindeki "text" kelimesinden önceki kelime "the", sonraki kelime ise "parameter"dır. "Metin" kelimesinin diğer üç örneğinin hiçbirinde aynı çevreleyen kelimeler yoktur. Bu bilgiden yararlanarak önceki URL'yi değiştirebilir, prefix- ve -suffix ekleyebilirim. Diğer parametreler gibi bunların da yüzde kodlamalı olması gerekir ve birden fazla kelime içerebilirler. https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#:~:text=the-,text,-parameter seçeneğine dokunun. Ayrıştırıcının prefix- ve -suffix değerlerini net bir şekilde tanımlayabilmesi için bunların start ve isteğe bağlı end değerlerinden tire - ile ayrılması gerekir.

"Metin"in seçilen örneğiyle eşleşen metin parçası.

Tam söz dizimi

Metin Parçaları'nın tam söz dizimi aşağıdaki gibidir. (Köşeli parantezler isteğe bağlı bir parametreyi gösterir.) Tüm parametrelerin değerleri yüzde kodlamalı olmalıdır. Bu, özellikle tire -, ve işareti & ve virgül , karakterleri için önemlidir. Böylece bu karakterler, metin yönergesi söz diziminin bir parçası olarak yorumlanmaz.

#:~:text=[prefix-,]start[,end][,-suffix]

prefix-, start, end ve -suffix, yalnızca tek bir blok düzeyindeki öğe içindeki metinle eşleşebilir ancak tam start,end aralıkları birden fazla bloğu kapsayabilir. Örneğin, :~:text=The quick,lazy dog aşağıdaki örnekte eşleşmez çünkü başlangıç dizesi olan "The quick", tek ve kesintisiz bir blok düzeyinde öğe içinde görünmez:

<div>
  The
  <div></div>
  quick brown fox
</div>
<div>jumped over the lazy dog</div>

Ancak şu örnekte eşleşir:

<div>The quick brown fox</div>
<div>jumped over the lazy dog</div>

Tarayıcı uzantısıyla metin parçası URL'leri oluşturma

Metin parçası URL'lerini manuel olarak oluşturmak, özellikle de benzersiz olduklarından emin olmak söz konusu olduğunda sıkıcıdır. Gerçekten istiyorsanız spesifikasyonda bazı ipuçları ve metin parçası URL'leri oluşturma adımları yer alır. Link to Text Fragment adlı açık kaynaklı bir tarayıcı uzantısı sunuyoruz. Bu uzantı, herhangi bir metni seçip bağlam menüsünde "Seçili Metnin Bağlantısını Kopyala"yı tıklayarak metne bağlantı oluşturmanıza olanak tanır. Bu uzantı aşağıdaki tarayıcılarda kullanılabilir:

Link to Text Fragment tarayıcı uzantısı.

Bir URL'de birden fazla metin parçası

Bir URL'de birden fazla metin parçası görünebilir. Belirli metin parçalarının ve işareti karakteriyle & ayrılması gerekir. Üç metin parçası içeren örnek bir bağlantı: 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.

Bir URL'de üç metin parçası.

Öğe ve metin parçalarını karıştırma

Geleneksel öğe parçaları, metin parçalarıyla birleştirilebilir. Aynı URL'de her ikisinin de bulunması tamamen normaldir. Örneğin, sayfadaki orijinal metnin değişmesi ve metin parçasının artık eşleşmemesi durumunda anlamlı bir yedek sağlamak için her ikisi de kullanılabilir. Ürün Forumlarımızda bize geri bildirim gönderin bölümüne bağlantı veren URL https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#HTML1:~:text=Give%20us%20feedback%20in%20our%20Product%20Forums. hem bir öğe parçası (HTML1) hem de bir metin parçası (text=Give%20us%20feedback%20in%20our%20Product%20Forums.) içerir:

Hem öğe parçası hem de metin parçasıyla bağlantı oluşturma

Parça yönergesi

Söz diziminde henüz açıklamadığım bir öğe var: parça yönergesi :~:. Gösterildiği gibi mevcut URL öğesi parçalarıyla uyumluluk sorunlarını önlemek için Metin Parçaları spesifikasyonu, parça yönergesini sunar. Parça yönergesi, URL parçasının :~: kod dizisiyle ayrılmış bir bölümüdür. text= gibi kullanıcı aracısı talimatları için ayrılmıştır ve yükleme sırasında URL'den çıkarılır. Böylece yazar komut dosyaları bu dizeyle doğrudan etkileşime giremez. Kullanıcı aracısı talimatları, yönergeler olarak da adlandırılır. Bu nedenle, somut durumda text=, metin yönergesi olarak adlandırılır.

Özellik algılama

Desteklenip desteklenmediğini tespit etmek için document üzerinde salt okunur fragmentDirective özelliğini test edin. Parça yönergesi, URL'lerin doküman yerine tarayıcıya yönelik talimatlar belirtmesini sağlayan bir mekanizmadır. Bu, yazar komut dosyasıyla doğrudan etkileşimi önlemek için tasarlanmıştır. Böylece, mevcut içerikte zarar veren değişiklikler yapma endişesi olmadan gelecekteki kullanıcı aracısı talimatları eklenebilir. Gelecekte eklenebilecek özelliklerden biri, çeviri ipuçları olabilir.

if ('fragmentDirective' in document) {
  // Text Fragments is supported.
}

Özellik algılama, esas olarak bağlantıların dinamik olarak oluşturulduğu (örneğin, arama motorları tarafından) durumlarda, metin parçası bağlantılarının bunları desteklemeyen tarayıcılara sunulmasını önlemek için tasarlanmıştır.

Metin parçalarını biçimlendirme

Tarayıcılar, varsayılan olarak metin parçalarını mark ile aynı şekilde biçimlendirir (genellikle sarı üzerine siyah, mark için CSS sistem renkleri). Kullanıcı aracısı stil sayfasında şuna benzer bir CSS bulunur:

:root::target-text {
  color: MarkText;
  background: Mark;
}

Gördüğünüz gibi tarayıcı, uygulanan vurgulamayı özelleştirmek için kullanabileceğiniz bir sözde seçici ::target-text sunar. Örneğin, metin parçalarınızı kırmızı arka plan üzerinde siyah metin olacak şekilde tasarlayabilirsiniz. Her zaman olduğu gibi, geçersiz kılma stilinizin erişilebilirlik sorunlarına neden olmaması için renk kontrastını kontrol ettiğinizden ve vurgulamanın içeriğin geri kalanından görsel olarak öne çıktığından emin olun.

:root::target-text {
  color: black;
  background-color: red;
}

Polyfill

Metin Parçaları özelliği bir dereceye kadar polyfill ile desteklenebilir. İşlevin JavaScript'te uygulandığı metin parçaları için yerleşik destek sunmayan tarayıcılarda uzantı tarafından dahili olarak kullanılan bir polyfill sunuyoruz.

polyfill, metin parçası bağlantıları oluşturmak için içe aktarıp kullanabileceğiniz bir fragment-generation-utils.js dosyası içerir. Bu durum, kod örneğinde gösterilmektedir:

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);
}

Analiz amacıyla metin parçaları alma

Birçok site, yönlendirme için parçayı kullanır. Bu nedenle tarayıcılar, bu sayfaları bozmamak için metin parçalarını kaldırır. Metin Parçaları bağlantılarını sayfalara göstermenin kabul edilmiş bir gereklilik olduğu (ör. analiz amacıyla) ancak önerilen çözümün henüz uygulanmadığı belirtiliyor. Şu an için geçici bir çözüm olarak, bilgileri ayıklamak için aşağıdaki kodu kullanabilirsiniz.

new URL(performance.getEntries().find(({ type }) => type === 'navigate').name).hash;

Güvenlik

Metin parçası yönergeleri, yalnızca kullanıcı etkinleştirme işleminin sonucu olan tam (aynı sayfada olmayan) gezinmelerde çağrılır. Ayrıca, hedeften farklı bir kaynaktan gelen gezinmelerin noopener bağlamında gerçekleşmesi gerekir. Böylece hedef sayfanın yeterince yalıtıldığı bilinir. Metin parçası yönergeleri yalnızca ana çerçeveye uygulanır. Bu, iFrame'lerin içinde metin aranmadığı ve iFrame gezinmesinin bir metin parçası çağırmadığı anlamına gelir.

Gizlilik

Metin Parçaları spesifikasyonunun uygulamalarının, bir sayfada metin parçası bulunup bulunmadığını sızdırmaması önemlidir. Öğe parçaları tamamen orijinal sayfa yazarının kontrolündeyken metin parçaları herkes tarafından oluşturulabilir. Örneğimde, <h1> öğesinde id bulunmadığı için Web Çalışanlarında ECMAScript Modülleri başlığına bağlantı vermenin bir yolu olmadığını, ancak ben de dahil olmak üzere herkesin metin parçasını dikkatlice oluşturarak herhangi bir yere bağlantı verebileceğini hatırlıyor musunuz?

Kötü amaçlı bir reklam ağı evil-ads.example.com yönettiğimi düşünün. Ayrıca, reklam iframe'lerimden birinde, kullanıcı reklamla etkileşime girdiğinde metin parçası URL'si dating.example.com#:~:text=Log%20Out ile dating.example.com için dinamik olarak gizli bir çapraz kaynak iframe oluşturduğumu varsayalım. "Çıkış yap" metni bulunursa kurbanın dating.example.com sitesine giriş yaptığını anlarım. Bu bilgiyi kullanıcı profili oluşturmak için kullanabilirim. Basit bir metin parçası uygulaması, başarılı bir eşleşmenin odak değişikliğine neden olması gerektiğine karar verebileceğinden evil-ads.example.com üzerinde blur etkinliğini dinleyebilir ve böylece bir eşleşmenin ne zaman gerçekleştiğini öğrenebilirim. Chrome'da, Metin Parçaları'nı bu tür bir senaryonun gerçekleşemeyeceği şekilde uyguladık.

Başka bir saldırı, kaydırma konumuna göre ağ trafiğini kötüye kullanmak olabilir. Bir şirketin intranet yöneticisi olarak kurbanımın ağ trafiği günlüklerine erişimim olduğunu varsayalım. Şimdi, Şu Sorunları Yaşıyorsanız Yapmanız Gerekenler... başlıklı uzun bir insan kaynakları belgesi olduğunu ve bu belgede tükenmişlik, anksiyete gibi durumların listelendiğini düşünün. Listedeki her öğenin yanına bir izleme pikseli yerleştirebilirim. Ardından, dokümanın yüklenmesinin, örneğin tükenmişlik öğesinin yanındaki izleme pikselinin yüklenmesiyle aynı anda gerçekleştiğini tespit edersem intranet yöneticisi olarak bir çalışanın, :~:text=burn%20out içeren bir metin parçası bağlantısını tıkladığını belirleyebilirim. Çalışan, bu bağlantının gizli olduğunu ve kimse tarafından görülemeyeceğini varsaymış olabilir. Bu örnek, başlangıçta biraz yapay olduğundan ve kötüye kullanımı çok belirli ön koşulların karşılanmasını gerektirdiğinden Chrome güvenlik ekibi, gezinme sırasında kaydırma özelliğini uygulamanın riskini yönetilebilir olarak değerlendirdi. Diğer kullanıcı aracıları, bunun yerine manuel kaydırma kullanıcı arayüzü öğesi göstermeye karar verebilir.

Chromium, kapsam dışında kalmak isteyen siteler için kullanıcı aracılarının metin parçası URL'lerini işlememesi amacıyla gönderebilecekleri bir Doküman Politikası başlık değerini destekler.

Document-Policy: force-load-at-top

Metin parçalarını devre dışı bırakma

Bu özelliği devre dışı bırakmanın en kolay yolu, HTTP yanıt başlıkları ekleyebilen bir uzantı (ör. Google ürünü olmayan ModHeader) kullanarak aşağıdaki gibi bir yanıt (istek değil) başlığı eklemektir:

Document-Policy: force-load-at-top

Kapsam dışı kalmanın bir diğer ve daha karmaşık yolu da ScrollToTextFragmentEnabled kurumsal ayarını kullanmaktır. macOS'te bunu yapmak için aşağıdaki komutu terminale yapıştırın.

defaults write com.google.Chrome ScrollToTextFragmentEnabled -bool false

Windows'da, Google Chrome Enterprise Yardım destek sitesindeki belgeleri inceleyin.

Bazı aramalarda Google arama motoru, alakalı bir web sitesinden içerik snippet'iyle birlikte hızlı bir yanıt veya özet sunar. Bu öne çıkan snippet'ler, en çok arama bir soru şeklinde olduğunda gösterilir. Öne çıkan snippet'i tıklamak kullanıcıyı, doğrudan kaynak web sayfasındaki öne çıkan snippet metnine yönlendirir. Bu özellik, otomatik olarak oluşturulan metin parçası URL'leri sayesinde çalışır.

Öne çıkan snippet'in gösterildiği Google Arama sonuçları sayfası. Durum çubuğunda metin parçaları URL'si gösterilir.
Tıklandıktan sonra sayfanın ilgili bölümü kaydırılarak görünür hale gelir.

Sonuç

Metin parçaları URL'si, web sayfalarındaki rastgele metinlere bağlantı oluşturmak için kullanabileceğiniz güçlü bir özelliktir. Akademik topluluk, bu özelliği kullanarak son derece doğru alıntı veya referans bağlantıları sağlayabilir. Arama motorları, sayfalardaki metin sonuçlarına derin bağlantı oluşturmak için bu özelliği kullanabilir. Sosyal ağ siteleri, kullanıcıların erişilemeyen ekran görüntüleri yerine bir web sayfasının belirli bölümlerini paylaşmasına izin vermek için bu API'yi kullanabilir. Metin Parçası URL'lerini kullanmaya başlayacağınızı ve bunları benim kadar faydalı bulacağınızı umuyorum. Link to Text Fragment tarayıcı uzantısını yüklemeyi unutmayın.

Onaylar

Metin Parçaları, Nick Burris ve David Bokan tarafından uygulanıp belirtildi ve Grant Wang tarafından katkıda bulunuldu. Bu dokümanı kapsamlı bir şekilde incelediği için Joe Medley'e teşekkür ederiz.