Fixed replacement of skip link and announcement bar on instant load

This commit is contained in:
squidfunk 2020-03-28 18:10:08 +01:00
parent edc9d6fc61
commit 908d34b853
14 changed files with 93 additions and 58 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,10 +1,10 @@
{
"assets/javascripts/bundle.js": "assets/javascripts/bundle.edc2ff56.min.js",
"assets/javascripts/bundle.js.map": "assets/javascripts/bundle.edc2ff56.min.js.map",
"assets/javascripts/bundle.js": "assets/javascripts/bundle.0ddca959.min.js",
"assets/javascripts/bundle.js.map": "assets/javascripts/bundle.0ddca959.min.js.map",
"assets/javascripts/vendor.js": "assets/javascripts/vendor.c1fcc1cc.min.js",
"assets/javascripts/vendor.js.map": "assets/javascripts/vendor.c1fcc1cc.min.js.map",
"assets/javascripts/worker/search.js": "assets/javascripts/worker/search.3bc815f0.min.js",
"assets/javascripts/worker/search.js.map": "assets/javascripts/worker/search.3bc815f0.min.js.map",
"assets/stylesheets/main.css": "assets/stylesheets/main.b32d3181.min.css",
"assets/stylesheets/main.css": "assets/stylesheets/main.c1451e9e.min.css",
"assets/stylesheets/palette.css": "assets/stylesheets/palette.4444686e.min.css"
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -41,7 +41,7 @@
{% endif %}
{% endblock %}
{% block styles %}
<link rel="stylesheet" href="{{ 'assets/stylesheets/main.b32d3181.min.css' | url }}">
<link rel="stylesheet" href="{{ 'assets/stylesheets/main.c1451e9e.min.css' | url }}">
{% if palette.primary or palette.accent %}
<link rel="stylesheet" href="{{ 'assets/stylesheets/palette.4444686e.min.css' | url }}">
{% endif %}
@ -88,19 +88,23 @@
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" for="__drawer"></label>
{% if page.toc | first is defined %}
{% set skip = page.toc | first %}
<a href="{{ skip.url | url }}" class="md-skip" data-md-component="skip">
{{ lang.t('skip.link.title') }}
</a>
{% endif %}
{% if self.announce() %}
<aside class="md-announce" data-md-component="announce">
<div class="md-announce__inner md-grid md-typeset">
{% block announce %}{% endblock %}
</div>
</aside>
{% endif %}
<div data-md-component="skip">
{% if page.toc | first is defined %}
{% set skip = page.toc | first %}
<a href="{{ skip.url | url }}" class="md-skip">
{{ lang.t('skip.link.title') }}
</a>
{% endif %}
</div>
<div data-md-component="announce">
{% if self.announce() %}
<aside class="md-announce">
<div class="md-announce__inner md-grid md-typeset">
{% block announce %}{% endblock %}
</div>
</aside>
{% endif %}
</div>
{% block header %}
{% include "partials/header.html" %}
{% endblock %}
@ -175,7 +179,7 @@
</div>
{% block scripts %}
<script src="{{ 'assets/javascripts/vendor.c1fcc1cc.min.js' | url }}"></script>
<script src="{{ 'assets/javascripts/bundle.edc2ff56.min.js' | url }}"></script>
<script src="{{ 'assets/javascripts/bundle.0ddca959.min.js' | url }}"></script>
{%- set translations = {} -%}
{%- for key in [
"clipboard.copy",

View File

@ -39,6 +39,7 @@ import { getElement, replaceElement } from "browser"
* Component
*/
export type Component =
| "announce" /* Announcement bar */
| "container" /* Container */
| "header" /* Header */
| "header-title" /* Header title */
@ -114,6 +115,7 @@ export function setupComponents(
switch (name) {
/* Top-level components: update */
case "announce":
case "header-title":
case "container":
case "skip":

View File

@ -73,6 +73,7 @@ export interface Header {
* Mount options
*/
interface MountOptions {
document$: Observable<Document> /* Document observable */
viewport$: Observable<Viewport> /* Viewport observable */
}
@ -88,11 +89,11 @@ interface MountOptions {
* @return Operator function
*/
export function mountHeader(
{ viewport$ }: MountOptions
{ document$, viewport$ }: MountOptions
): OperatorFunction<HTMLElement, Header> {
return pipe(
switchMap(el => {
const header$ = watchHeader(el)
const header$ = watchHeader(el, { document$ })
/* Compute whether the header should switch to page header */
const type$ = useComponent("main")

View File

@ -28,10 +28,12 @@ import {
pipe
} from "rxjs"
import {
distinctUntilChanged,
finalize,
map,
observeOn,
shareReplay,
switchMap,
tap
} from "rxjs/operators"
@ -43,6 +45,17 @@ import {
setHeaderTitleActive
} from "../set"
/* ----------------------------------------------------------------------------
* Helper types
* ------------------------------------------------------------------------- */
/**
* Watch options
*/
interface WatchOptions {
document$: Observable<Document> /* Document observable */
}
/* ----------------------------------------------------------------------------
* Functions
* ------------------------------------------------------------------------- */
@ -55,27 +68,36 @@ import {
* @return Header observable
*/
export function watchHeader(
el: HTMLElement
el: HTMLElement, { document$ }: WatchOptions
): Observable<Omit<Header, "type">> {
const styles = getComputedStyle(el)
if ([
"sticky", /* Modern browsers */
"-webkit-sticky" /* Safari */
].includes(styles.position)) {
return watchElementSize(el)
.pipe(
map(({ height }) => ({
sticky: true,
height
})),
shareReplay(1)
)
} else {
return of({
sticky: false,
height: 0
})
}
return document$
.pipe(
map(() => {
const styles = getComputedStyle(el)
return [
"sticky", /* Modern browsers */
"-webkit-sticky" /* Safari */
].includes(styles.position)
}),
distinctUntilChanged(),
switchMap(sticky => {
if (sticky) {
return watchElementSize(el)
.pipe(
map(({ height }) => ({
sticky: true,
height
}))
)
} else {
return of({
sticky: false,
height: 0
})
}
}),
shareReplay(1)
)
}
/* ------------------------------------------------------------------------- */

View File

@ -158,6 +158,7 @@ export function initialize(config: unknown) {
/* Set up component bindings */
setupComponents([
"announce", /* Announcement bar */
"container", /* Container */
"header", /* Header */
"header-title", /* Header title */
@ -192,7 +193,7 @@ export function initialize(config: unknown) {
/* Create header observable */
const header$ = useComponent("header")
.pipe(
mountHeader({ viewport$ }),
mountHeader({ document$, viewport$ }),
shareReplay(1)
)

View File

@ -26,6 +26,7 @@
// Announcement bar
.md-announce {
overflow: auto;
background-color: var(--md-default-fg-color);
// Actual content

View File

@ -201,21 +201,25 @@
<label class="md-overlay" for="__drawer"></label>
<!-- Link to skip to content -->
{% if page.toc | first is defined %}
{% set skip = page.toc | first %}
<a href="{{ skip.url | url }}" class="md-skip" data-md-component="skip">
{{ lang.t('skip.link.title') }}
</a>
{% endif %}
<div data-md-component="skip">
{% if page.toc | first is defined %}
{% set skip = page.toc | first %}
<a href="{{ skip.url | url }}" class="md-skip">
{{ lang.t('skip.link.title') }}
</a>
{% endif %}
</div>
<!-- Announcement bar -->
{% if self.announce() %}
<aside class="md-announce" data-md-component="announce">
<div class="md-announce__inner md-grid md-typeset">
{% block announce %}{% endblock %}
</div>
</aside>
{% endif %}
<div data-md-component="announce">
{% if self.announce() %}
<aside class="md-announce">
<div class="md-announce__inner md-grid md-typeset">
{% block announce %}{% endblock %}
</div>
</aside>
{% endif %}
</div>
<!-- Application header -->
{% block header %}