Fixed ignored repeated anchor link clicks when using instant loading

This commit is contained in:
squidfunk 2023-09-23 16:32:44 +02:00
parent ef30cfea67
commit 7e6f15bb17
No known key found for this signature in database
GPG Key ID: 5ED40BC4F9C436DF
5 changed files with 65 additions and 43 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -250,7 +250,7 @@
</script>
{% endblock %}
{% block scripts %}
<script src="{{ 'assets/javascripts/bundle.18ee4812.min.js' | url }}"></script>
<script src="{{ 'assets/javascripts/bundle.55099adf.min.js' | url }}"></script>
{% for script in config.extra_javascript %}
{{ script | script_tag }}
{% endfor %}

View File

@ -30,10 +30,12 @@ import {
debounceTime,
distinctUntilKeyChanged,
endWith,
filter,
fromEvent,
ignoreElements,
map,
of,
sample,
share,
skip,
startWith,
@ -289,19 +291,17 @@ export function setupInstantLoading(
popstate$.pipe(map(getLocation))
.subscribe(location$)
// Intercept clicks on anchor links, and scroll document into position. As
// we disabled scroll restoration, we need to do this manually here.
// Intercept clicks on anchor links, and scroll document into position - as
// we disabled scroll restoration, we need to do this manually here
location$
.pipe(
startWith(getLocation()),
bufferCount(2, 1),
switchMap(([prev, next]) => (
filter(([prev, next]) => (
prev.pathname === next.pathname &&
prev.hash !== next.hash
)
? of(next)
: EMPTY
)
)),
map(([, next]) => next)
)
.subscribe(url => {
if (history.state !== null || !url.hash) {
@ -313,6 +313,29 @@ export function setupInstantLoading(
}
})
// Intercept clicks on the same anchor link - we must use a distinct pipeline
// for this, or we'd end up in a loop, setting the hash again and again
location$
.pipe(
sample(instant$),
startWith(getLocation()),
bufferCount(2, 1),
filter(([prev, next]) => (
prev.pathname === next.pathname &&
prev.hash === next.hash
)),
map(([, next]) => next)
)
.subscribe(url => {
history.scrollRestoration = "auto"
setLocationHash(url.hash)
history.scrollRestoration = "manual"
// Hack: we need to make sure that we don't end up with multiple history
// entries for the same anchor link, so we just remove the last entry
history.back()
})
// After parsing the document, check if the current history entry has a state.
// This may happen when users press the back or forward button to visit a page
// that was already seen. If there's no state, it means a new page was visited
@ -330,9 +353,8 @@ export function setupInstantLoading(
// the current history state whenever the scroll position changes. This must
// be debounced and cannot be done in popstate, as popstate has already
// removed the entry from the history.
document$
viewport$
.pipe(
switchMap(() => viewport$),
distinctUntilKeyChanged("offset"),
debounceTime(100)
)