Skip to content

Commit

Permalink
Added support for instant navigation progress indicator
Browse files Browse the repository at this point in the history
  • Loading branch information
squidfunk committed Oct 1, 2023
1 parent 015685f commit f8fd537
Show file tree
Hide file tree
Showing 28 changed files with 323 additions and 93 deletions.
18 changes: 18 additions & 0 deletions material/overrides/assets/javascripts/custom.9458f965.min.js

Large diffs are not rendered by default.

Large diffs are not rendered by default.

18 changes: 0 additions & 18 deletions material/overrides/assets/javascripts/custom.a4bbca43.min.js

This file was deleted.

2 changes: 1 addition & 1 deletion material/overrides/main.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,5 @@
{% endblock %}
{% block scripts %}
{{ super() }}
<script src="{{ 'assets/javascripts/custom.a4bbca43.min.js' | url }}"></script>
<script src="{{ 'assets/javascripts/custom.9458f965.min.js' | url }}"></script>
{% endblock %}
29 changes: 0 additions & 29 deletions material/templates/assets/javascripts/bundle.697ed5af.min.js

This file was deleted.

This file was deleted.

29 changes: 29 additions & 0 deletions material/templates/assets/javascripts/bundle.6eac0284.min.js

Large diffs are not rendered by default.

Large diffs are not rendered by default.

This file was deleted.

This file was deleted.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

7 changes: 5 additions & 2 deletions material/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
{% endif %}
{% endblock %}
{% block styles %}
<link rel="stylesheet" href="{{ 'assets/stylesheets/main.1dbc8ddf.min.css' | url }}">
<link rel="stylesheet" href="{{ 'assets/stylesheets/main.79e020e9.min.css' | url }}">
{% if config.theme.palette %}
{% set palette = config.theme.palette %}
<link rel="stylesheet" href="{{ 'assets/stylesheets/palette.a5377069.min.css' | url }}">
Expand Down Expand Up @@ -206,6 +206,9 @@
<div class="md-dialog" data-md-component="dialog">
<div class="md-dialog__inner md-typeset"></div>
</div>
{% if "navigation.instant.progress" in features %}
{% include "partials/progress.html" %}
{% endif %}
{% if config.extra.consent %}
<div class="md-consent" data-md-component="consent" id="__consent" hidden>
<div class="md-consent__overlay"></div>
Expand Down Expand Up @@ -250,7 +253,7 @@
</script>
{% endblock %}
{% block scripts %}
<script src="{{ 'assets/javascripts/bundle.697ed5af.min.js' | url }}"></script>
<script src="{{ 'assets/javascripts/bundle.6eac0284.min.js' | url }}"></script>
{% for script in config.extra_javascript %}
{{ script | script_tag }}
{% endfor %}
Expand Down
4 changes: 4 additions & 0 deletions material/templates/partials/progress.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{#-
This file was automatically generated - do not edit
-#}
<div class="md-progress" data-md-component="progress" role="progressbar"></div>
4 changes: 3 additions & 1 deletion mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ theme:
- navigation.footer
- navigation.indexes
# - navigation.instant
# - navigation.instant.prefetch
# - navigation.instant.progress
# - navigation.prune
- navigation.sections
- navigation.tabs
Expand Down Expand Up @@ -253,7 +255,7 @@ nav:
- Insiders:
- insiders/index.md
- Getting started: insiders/getting-started.md
- Changelog:
- Changelog:
- insiders/changelog/index.md
- How to upgrade: insiders/upgrade.md
- Blog:
Expand Down
1 change: 1 addition & 0 deletions src/templates/assets/javascripts/_/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export type Flag =
| "navigation.expand" /* Automatic expansion */
| "navigation.indexes" /* Section pages */
| "navigation.instant" /* Instant navigation */
| "navigation.instant.progress" /* Instant navigation progress */
| "navigation.sections" /* Section navigation */
| "navigation.tabs" /* Tabs navigation */
| "navigation.tabs.sticky" /* Tabs navigation (sticky) */
Expand Down
76 changes: 57 additions & 19 deletions src/templates/assets/javascripts/browser/request/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,24 @@
*/

import {
EMPTY,
Observable,
catchError,
from,
Subject,
map,
of,
shareReplay,
switchMap,
throwError
switchMap
} from "rxjs"

/* ----------------------------------------------------------------------------
* Helper types
* ------------------------------------------------------------------------- */

/**
* Options
*/
interface Options {
progress$?: Subject<number> // Progress subject
}

/* ----------------------------------------------------------------------------
* Functions
* ------------------------------------------------------------------------- */
Expand All @@ -48,16 +55,46 @@ import {
* @returns Response observable
*/
export function request(
url: URL | string, options: RequestInit = { credentials: "same-origin" }
): Observable<Response> {
return from(fetch(`${url}`, options))
.pipe(
catchError(() => EMPTY),
switchMap(res => res.status !== 200
? throwError(() => new Error(res.statusText))
: of(res)
)
)
url: URL | string, options?: Options
): Observable<Blob> {
return new Observable<Blob>(observer => {
const req = new XMLHttpRequest()
req.open("GET", `${url}`)
req.responseType = "blob"

// Handle response
req.addEventListener("load", () => {
if (req.status >= 200 && req.status < 300) {
observer.next(req.response)
observer.complete()
} else {
observer.error(new Error(req.statusText))
}
})

// Handle network errors
req.addEventListener("error", () => {
observer.error(new Error("Network Error"))
})

// Handle aborted requests
req.addEventListener("abort", () => {
observer.error(new Error("Request aborted"))
})

// Handle download progress
if (typeof options?.progress$ !== "undefined") {
req.addEventListener("progress", event => {
options.progress$!.next((event.loaded / event.total) * 100)
})

// Immediately set progress to 5% to indicate that we're loading
options.progress$.next(5)
}

// Send request
req.send()
})
}

/* ------------------------------------------------------------------------- */
Expand All @@ -73,11 +110,12 @@ export function request(
* @returns Data observable
*/
export function requestJSON<T>(
url: URL | string, options?: RequestInit
url: URL | string, options?: Options
): Observable<T> {
return request(url, options)
.pipe(
switchMap(res => res.json()),
switchMap(res => res.text()),
map(body => JSON.parse(body) as T),
shareReplay(1)
)
}
Expand All @@ -91,7 +129,7 @@ export function requestJSON<T>(
* @returns Data observable
*/
export function requestXML(
url: URL | string, options?: RequestInit
url: URL | string, options?: Options
): Observable<Document> {
const dom = new DOMParser()
return request(url, options)
Expand Down
11 changes: 10 additions & 1 deletion src/templates/assets/javascripts/bundle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ import {
mountHeader,
mountHeaderTitle,
mountPalette,
mountProgress,
mountSearch,
mountSearchHiglight,
mountSidebar,
Expand Down Expand Up @@ -143,9 +144,12 @@ const index$ = document.forms.namedItem("search")
const alert$ = new Subject<string>()
setupClipboardJS({ alert$ })

/* Set up progress indicator */
const progress$ = new Subject<number>()

/* Set up instant navigation, if enabled */
if (feature("navigation.instant"))
setupInstantNavigation({ location$, viewport$ })
setupInstantNavigation({ location$, viewport$, progress$ })
.subscribe(document$)

/* Set up version selector */
Expand Down Expand Up @@ -227,6 +231,10 @@ const control$ = merge(
...getComponentElements("palette")
.map(el => mountPalette(el)),

/* Progress bar */
...getComponentElements("progress")
.map(el => mountProgress(el, { progress$ })),

/* Search */
...getComponentElements("search")
.map(el => mountSearch(el, { index$, keyboard$ })),
Expand Down Expand Up @@ -304,4 +312,5 @@ window.tablet$ = tablet$ /* Media tablet observable */
window.screen$ = screen$ /* Media screen observable */
window.print$ = print$ /* Media print observable */
window.alert$ = alert$ /* Alert subject */
window.progress$ = progress$ /* Progress indicator subject */
window.component$ = component$ /* Component observable */
2 changes: 2 additions & 0 deletions src/templates/assets/javascripts/components/_/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export type ComponentType =
| "main" /* Main area */
| "outdated" /* Version warning */
| "palette" /* Color palette */
| "progress" /* Progress indicator */
| "search" /* Search */
| "search-query" /* Search input */
| "search-result" /* Search results */
Expand Down Expand Up @@ -86,6 +87,7 @@ interface ComponentTypeMap {
"main": HTMLElement /* Main area */
"outdated": HTMLElement /* Version warning */
"palette": HTMLElement /* Color palette */
"progress": HTMLElement /* Progress indicator */
"search": HTMLElement /* Search */
"search-query": HTMLInputElement /* Search input */
"search-result": HTMLElement /* Search results */
Expand Down
1 change: 1 addition & 0 deletions src/templates/assets/javascripts/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export * from "./dialog"
export * from "./header"
export * from "./main"
export * from "./palette"
export * from "./progress"
export * from "./search"
export * from "./sidebar"
export * from "./source"
Expand Down
87 changes: 87 additions & 0 deletions src/templates/assets/javascripts/components/progress/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* Copyright (c) 2016-2023 Martin Donath <[email protected]>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/

import {
Observable,
Subject,
defer,
finalize,
map,
tap
} from "rxjs"

import { Component } from "../_"

/* ----------------------------------------------------------------------------
* Types
* ------------------------------------------------------------------------- */

/**
* Progress indicator
*/
export interface Progress {
value: number // Progress value
}

/* ----------------------------------------------------------------------------
* Helper types
* ------------------------------------------------------------------------- */

/**
* Mount options
*/
interface MountOptions {
progress$: Subject<number> // Progress subject
}

/* ----------------------------------------------------------------------------
* Functions
* ------------------------------------------------------------------------- */

/**
* Mount progress indicator
*
* @param el - Progress indicator element
* @param options - Options
*
* @returns Progress indicator component observable
*/
export function mountProgress(
el: HTMLElement, { progress$ }: MountOptions
): Observable<Component<Progress>> {

// Mount component on subscription
return defer(() => {
const push$ = new Subject<Progress>()
push$.subscribe(({ value }) => {
el.style.setProperty("--md-progress-value", `${value}`)
})

// Create and return component
return progress$
.pipe(
tap(value => push$.next({ value })),
finalize(() => push$.complete()),
map(value => ({ ref: el, value }))
)
})
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,9 @@ import { fetchSitemap } from "../sitemap"
* Setup options
*/
interface SetupOptions {
location$: Subject<URL> /* Location subject */
viewport$: Observable<Viewport> /* Viewport observable */
location$: Subject<URL> // Location subject
viewport$: Observable<Viewport> // Viewport observable
progress$: Subject<number> // Progress suject
}

/* ----------------------------------------------------------------------------
Expand Down Expand Up @@ -138,7 +139,7 @@ function lookup(head: HTMLHeadElement): Map<string, HTMLElement> {
* @returns Document observable
*/
export function setupInstantNavigation(
{ location$, viewport$ }: SetupOptions
{ location$, viewport$, progress$ }: SetupOptions
): Observable<Document> {
const config = configuration()
if (location.protocol === "file:")
Expand Down Expand Up @@ -260,7 +261,7 @@ export function setupInstantNavigation(
startWith(getLocation()),
distinctUntilKeyChanged("pathname"),
skip(1),
switchMap(url => request(url)
switchMap(url => request(url, { progress$ })
.pipe(
catchError(() => {
setLocation(url, true)
Expand Down
1 change: 1 addition & 0 deletions src/templates/assets/stylesheets/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
@import "main/components/nav";
@import "main/components/pagination";
@import "main/components/post";
@import "main/components/progress";
@import "main/components/search";
@import "main/components/select";
@import "main/components/sidebar";
Expand Down
Loading

0 comments on commit f8fd537

Please sign in to comment.