Fixed anchor following not bringing last items into view

This commit is contained in:
squidfunk 2023-02-02 10:49:34 +01:00
parent c330a08bdc
commit c5459af35f
6 changed files with 25 additions and 18 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

@ -240,7 +240,7 @@
</script> </script>
{% endblock %} {% endblock %}
{% block scripts %} {% block scripts %}
<script src="{{ 'assets/javascripts/bundle.6bd5f0ae.min.js' | url }}"></script> <script src="{{ 'assets/javascripts/bundle.6df46069.min.js' | url }}"></script>
{% for path in config.extra_javascript %} {% for path in config.extra_javascript %}
<script src="{{ path | url }}"></script> <script src="{{ path | url }}"></script>
{% endfor %} {% endfor %}

View File

@ -273,7 +273,9 @@ const content$ = defer(() => merge(
/* Table of contents */ /* Table of contents */
...getComponentElements("toc") ...getComponentElements("toc")
.map(el => mountTableOfContents(el, { viewport$, header$, target$ })), .map(el => mountTableOfContents(el, {
viewport$, header$, main$, target$
})),
/* Back-to-top button */ /* Back-to-top button */
...getComponentElements("top") ...getComponentElements("top")

View File

@ -23,6 +23,7 @@
import { import {
Observable, Observable,
Subject, Subject,
asyncScheduler,
bufferCount, bufferCount,
combineLatestWith, combineLatestWith,
debounceTime, debounceTime,
@ -35,6 +36,7 @@ import {
ignoreElements, ignoreElements,
map, map,
merge, merge,
observeOn,
of, of,
repeat, repeat,
scan, scan,
@ -64,6 +66,7 @@ import {
getComponentElement getComponentElement
} from "../_" } from "../_"
import { Header } from "../header" import { Header } from "../header"
import { Main } from "../main"
/* ---------------------------------------------------------------------------- /* ----------------------------------------------------------------------------
* Types * Types
@ -95,6 +98,7 @@ interface WatchOptions {
interface MountOptions { interface MountOptions {
viewport$: Observable<Viewport> /* Viewport observable */ viewport$: Observable<Viewport> /* Viewport observable */
header$: Observable<Header> /* Header observable */ header$: Observable<Header> /* Header observable */
main$: Observable<Main> /* Main area observable */
target$: Observable<HTMLElement> /* Location target observable */ target$: Observable<HTMLElement> /* Location target observable */
} }
@ -275,7 +279,7 @@ export function watchTableOfContents(
* @returns Table of contents component observable * @returns Table of contents component observable
*/ */
export function mountTableOfContents( export function mountTableOfContents(
el: HTMLElement, { viewport$, header$, target$ }: MountOptions el: HTMLElement, { viewport$, header$, main$, target$ }: MountOptions
): Observable<Component<TableOfContents>> { ): Observable<Component<TableOfContents>> {
return defer(() => { return defer(() => {
const push$ = new Subject<TableOfContents>() const push$ = new Subject<TableOfContents>()
@ -307,13 +311,14 @@ export function mountTableOfContents(
viewport$.pipe(debounceTime(250), map(() => "smooth" as const)) viewport$.pipe(debounceTime(250), map(() => "smooth" as const))
) )
/* Bring active anchor into view */ /* Bring active anchor into view */ // @todo: refactor
push$ push$
.pipe( .pipe(
filter(({ prev }) => prev.length > 0), filter(({ prev }) => prev.length > 0),
combineLatestWith(main$.pipe(observeOn(asyncScheduler))),
withLatestFrom(smooth$) withLatestFrom(smooth$)
) )
.subscribe(([{ prev }, behavior]) => { .subscribe(([[{ prev }], behavior]) => {
const [anchor] = prev[prev.length - 1] const [anchor] = prev[prev.length - 1]
if (anchor.offsetHeight) { if (anchor.offsetHeight) {