Text Fragments
Контекстне меню свіжих версіях кроуму має пункт 'Copy link to highlight'. Над цією грандіозною функцією гооглівці страждали кілька років та написали специфікацію для неї--Text Fragments.
З гарного для власників сайтів:
- робити треба нічого.
З поганого для власників сайтів:
- контроль над функцією є відсутнім;
- вимкнути її не можна.
Працює вона так: коли користувач виділяє текста і клікає 'Copy link to highlight', до URL додається hash:
http://example.com/hello/#:~:text=worldЯкщо бовзера підтримує TF, той шукає рядок world на сторінці та виділяє його. З точки зору devtools жодних змін ув dom не відбувається, автор сторінки вплинути на пошук з виділенням може ніяк.
Кроум 96 має очікуваний бага: якщо URL мав hash виду
#/?route_to=heaven (це було популярно використовувати до того як
history api з'явився ув Сафарі), кроум його нахабно змінить на
#:~:text=..., хоча специфікація дозволяє додавати маркер
:~:text=... у кінець.
Власнику сайта хвилюватися про TF є непотрібним: коли він подивиться,
наприклад, на location.hash, маркера там не буде--бовзер його
заздалегідь видалить самотужки.
Що навело мене на думку: чи можна детектити TF?
Виявляється, через Navigation Timing API можна отримати анмолестед URL зі всіма маркерами:
function has_text_fragment() {
let url = performance.getEntries().find( v => v.type === 'navigate')?.name || location.href
return /^#.*:~:text=/.test(new URL(url).hash)
}Маючи детектор, як можна подратувати too clever by half користувача?
Що може бути більш дратівливим ніж модальні даялоги, які є неможливо закрити? Після намагань запхнути такий модуль ув кілька твітів, я зупинився на
export default (z_index = 999) => has_text_fragment() && draw(z_index)
function has_text_fragment() {
let url = performance.getEntries().find( v => v.type === 'navigate')?.name || location.href
return /^#.*:~:text=/.test(new URL(url).hash)
}
function draw(z_index) {
let d = document, w = d.createElement('div')
w.style.cssText = `position:fixed;top:0;left:0;height:100%;width:100%;z-index:${z_index};display:flex;justify-content:center;align-items:center;background:rgba(0,0,0,.2)`
w.innerHTML = '<img src="data:image/gif;base64,R0lGODlhFAAQAOMKAAAAAFp3N3RhMVplU41VL1iNPnyQbKGumMLHuv////b27/b27/b27/b27/b27/b27yH5BAEKAA8ALAAAAAAUABAAAARl8MmJjEUSHTz7O0UYGmJxeFmpiuhDrqrBSSAMc7U6GId1DIPDCRFLHAADTQKBTH5gwEFgZAicHjbbNZctGSSvruoUDgUIaEFgzQ4MniUBek5HX8sFtmAvt3e4NgEzFBo9FocbHhEAOw==">'
w.querySelector('img').style.cssText = 'image-rendering:pixelated;max-height:100%;max-width:100%;height:500px;width:auto'
d.body.appendChild(w)
return w
}Воно малює модальне жабеня Пепе, коли хтось заходить на сторінку з Text Fragments ув URL:
Має влізти ув 3 твіти (280*3 = 840):
$ terser pepe-the-text-fragment.js --module -mc | wc -c
832
