From 2d4d2afb5cbb6190bab27eab3d3234fb1e14cca8 Mon Sep 17 00:00:00 2001 From: Gerben Date: Thu, 20 Aug 2020 16:09:31 +0200 Subject: [PATCH] Trigger polyfill for page-local links MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Chromium’s implementation currently does not trigger when clicking links pointing to quotes within the same page. As a workaround, listen to link clicks, and activate the polyfill when a link points to a fragment within the same page. --- demo.html | 2 +- src/polyfill.ts | 29 +++++++++++++++++++++++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/demo.html b/demo.html index 1b21756..01f45cc 100644 --- a/demo.html +++ b/demo.html @@ -59,7 +59,7 @@ const message = (fragmentDirective ? fragmentDirective._implementation === 'text-fragments-ts' ? 'Yes' - : 'No (your browser appears to support text fragments already!)' + : 'Partially (your browser appears to support text fragments already! But it might not work when clicking links that point to fragments within this same page, so the polyfill is invoked when clicking the links below)' : 'No (something went wrong?)' ); usingPolyfill.innerHTML = message; diff --git a/src/polyfill.ts b/src/polyfill.ts index e410831..c2fceb2 100644 --- a/src/polyfill.ts +++ b/src/polyfill.ts @@ -69,10 +69,35 @@ function highlightRanges(ranges: Range[]): void { } } +// Listen to link clicks, and activate the polyfill when a link points to a fragment within the same page. +function addLinkClickListeners() { + const linkElements = [ + ...document.getElementsByTagName('a'), + ...document.getElementsByTagName('area'), + ] + linkElements.forEach(element => { + element.addEventListener('click', () => { + if (element.href.split('#')[0] === document.URL.split('#')[0]) { + const fragId = element.href.split('#')[1]; + if (fragId && fragId.includes(':~:')) { + const fragmentDirective = fragId.substring(fragId.indexOf(':~:') + 3); + applyFragmentDirective({ + document, + documentFragmentDirective: fragmentDirective, + }); + } + } + }); + }); +} + function install(): void { - // Do nothing if the browser already supports (text) fragment directives. - if (browserSupportsTextFragments()) + if (browserSupportsTextFragments()) { + // Chromium’s implementation currently does not trigger when clicking links pointing to quotes within the same page. Use this as a workaround (listening to hashchange won’t help, as we cannot access the fragment directive). + addLinkClickListeners(); + return; + } pretendBrowserSupportsTextFragments();