mirror of
https://github.com/squidfunk/mkdocs-material.git
synced 2026-07-31 01:48:20 -04:00
Merge branch 'master' into feature/scrollable-content-tabs
This commit is contained in:
@@ -33,8 +33,10 @@ export type Flag =
|
||||
| "header.autohide" /* Hide header */
|
||||
| "navigation.expand" /* Automatic expansion */
|
||||
| "navigation.instant" /* Instant loading */
|
||||
| "navigation.sections" /* Sections navigation */
|
||||
| "navigation.indexes" /* Section pages */
|
||||
| "navigation.sections" /* Section navigation */
|
||||
| "navigation.tabs" /* Tabs navigation */
|
||||
| "navigation.tabs.sticky" /* Tabs navigation (sticky) */
|
||||
| "navigation.top" /* Back-to-top button */
|
||||
| "search.highlight" /* Search highlighting */
|
||||
| "search.share" /* Search sharing */
|
||||
@@ -96,7 +98,7 @@ export interface Config {
|
||||
*/
|
||||
const script = getElementOrThrow("#__config")
|
||||
const config: Config = JSON.parse(script.textContent!)
|
||||
config.base = new URL(config.base, getLocation()).toString()
|
||||
config.base = `${new URL(config.base, getLocation())}`
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Functions
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
*/
|
||||
export function getElement<T extends keyof HTMLElementTagNameMap>(
|
||||
selector: T, node?: ParentNode
|
||||
): HTMLElementTagNameMap[T]
|
||||
): HTMLElementTagNameMap[T] | undefined
|
||||
|
||||
export function getElement<T extends HTMLElement>(
|
||||
selector: string, node?: ParentNode
|
||||
@@ -74,6 +74,8 @@ export function getElementOrThrow<T extends HTMLElement>(
|
||||
throw new ReferenceError(
|
||||
`Missing element: expected "${selector}" to be present`
|
||||
)
|
||||
|
||||
/* Return element */
|
||||
return el
|
||||
}
|
||||
|
||||
@@ -114,21 +116,6 @@ export function getElements<T extends HTMLElement>(
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Create an element
|
||||
*
|
||||
* @template T - Tag name type
|
||||
*
|
||||
* @param tagName - Tag name
|
||||
*
|
||||
* @returns Element
|
||||
*/
|
||||
export function createElement<T extends keyof HTMLElementTagNameMap>(
|
||||
tagName: T
|
||||
): HTMLElementTagNameMap[T] {
|
||||
return document.createElement(tagName)
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace an element with the given list of nodes
|
||||
*
|
||||
|
||||
@@ -20,10 +20,16 @@
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import { Observable, fromEvent, of } from "rxjs"
|
||||
import { filter, map, share, startWith, switchMap } from "rxjs/operators"
|
||||
import { Observable, fromEvent } from "rxjs"
|
||||
import {
|
||||
filter,
|
||||
map,
|
||||
shareReplay,
|
||||
startWith
|
||||
} from "rxjs/operators"
|
||||
|
||||
import { createElement, getElement } from "~/browser"
|
||||
import { getElement } from "~/browser"
|
||||
import { h } from "~/utilities"
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Functions
|
||||
@@ -49,8 +55,7 @@ export function getLocationHash(): string {
|
||||
* @param hash - Location hash
|
||||
*/
|
||||
export function setLocationHash(hash: string): void {
|
||||
const el = createElement("a")
|
||||
el.href = hash
|
||||
const el = h("a", { href: hash })
|
||||
el.addEventListener("click", ev => ev.stopPropagation())
|
||||
el.click()
|
||||
}
|
||||
@@ -68,7 +73,7 @@ export function watchLocationHash(): Observable<string> {
|
||||
map(getLocationHash),
|
||||
startWith(getLocationHash()),
|
||||
filter(hash => hash.length > 0),
|
||||
share()
|
||||
shareReplay(1)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -80,6 +85,7 @@ export function watchLocationHash(): Observable<string> {
|
||||
export function watchLocationTarget(): Observable<HTMLElement> {
|
||||
return watchLocationHash()
|
||||
.pipe(
|
||||
switchMap(id => of(getElement(`[id="${id}"]`)!))
|
||||
map(id => getElement(`[id="${id}"]`)!),
|
||||
filter(el => typeof el !== "undefined")
|
||||
)
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ import { getElementOrThrow, getElements } from "~/browser"
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Component
|
||||
* Component type
|
||||
*/
|
||||
export type ComponentType =
|
||||
| "announce" /* Announcement bar */
|
||||
@@ -52,7 +52,7 @@ export type ComponentType =
|
||||
| "top" /* Back-to-top button */
|
||||
|
||||
/**
|
||||
* A component
|
||||
* Component
|
||||
*
|
||||
* @template T - Component type
|
||||
* @template U - Reference type
|
||||
|
||||
@@ -31,6 +31,7 @@ import {
|
||||
} from "rxjs"
|
||||
import {
|
||||
distinctUntilKeyChanged,
|
||||
finalize,
|
||||
map,
|
||||
switchMap,
|
||||
tap,
|
||||
@@ -175,7 +176,8 @@ export function mountCodeBlock(
|
||||
/* Create and return component */
|
||||
return watchCodeBlock(el, options)
|
||||
.pipe(
|
||||
tap(internal$),
|
||||
tap(state => internal$.next(state)),
|
||||
finalize(() => internal$.complete()),
|
||||
map(state => ({ ref: el, ...state }))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
import { Observable, Subject } from "rxjs"
|
||||
import {
|
||||
filter,
|
||||
finalize,
|
||||
map,
|
||||
mapTo,
|
||||
mergeWith,
|
||||
@@ -38,7 +39,9 @@ import { Component } from "../../_"
|
||||
/**
|
||||
* Details
|
||||
*/
|
||||
export interface Details {}
|
||||
export interface Details {
|
||||
scroll?: boolean /* Scroll into view */
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Helper types
|
||||
@@ -79,8 +82,8 @@ export function watchDetails(
|
||||
.pipe(
|
||||
map(target => target.closest("details:not([open])")!),
|
||||
filter(details => el === details),
|
||||
mergeWith(print$),
|
||||
mapTo(el)
|
||||
mapTo({ scroll: true }),
|
||||
mergeWith(print$.pipe(mapTo({})))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -99,15 +102,17 @@ export function mountDetails(
|
||||
el: HTMLDetailsElement, options: MountOptions
|
||||
): Observable<Component<Details>> {
|
||||
const internal$ = new Subject<Details>()
|
||||
internal$.subscribe(() => {
|
||||
internal$.subscribe(({ scroll }) => {
|
||||
el.setAttribute("open", "")
|
||||
el.scrollIntoView()
|
||||
if (scroll)
|
||||
el.scrollIntoView()
|
||||
})
|
||||
|
||||
/* Create and return component */
|
||||
return watchDetails(el, options)
|
||||
.pipe(
|
||||
tap(internal$),
|
||||
tap(state => internal$.next(state)),
|
||||
finalize(() => internal$.complete()),
|
||||
mapTo({ ref: el })
|
||||
)
|
||||
}
|
||||
|
||||
@@ -22,8 +22,9 @@
|
||||
|
||||
import { Observable, of } from "rxjs"
|
||||
|
||||
import { createElement, replaceElement } from "~/browser"
|
||||
import { replaceElement } from "~/browser"
|
||||
import { renderTable } from "~/templates"
|
||||
import { h } from "~/utilities"
|
||||
|
||||
import { Component } from "../../_"
|
||||
|
||||
@@ -43,7 +44,7 @@ export interface DataTable {}
|
||||
/**
|
||||
* Sentinel for replacement
|
||||
*/
|
||||
const sentinel = createElement("table")
|
||||
const sentinel = h("table")
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Functions
|
||||
|
||||
@@ -29,6 +29,7 @@ import {
|
||||
} from "rxjs"
|
||||
import {
|
||||
delay,
|
||||
finalize,
|
||||
map,
|
||||
observeOn,
|
||||
switchMap,
|
||||
@@ -131,7 +132,8 @@ export function mountDialog(
|
||||
/* Create and return component */
|
||||
return watchDialog(el, options)
|
||||
.pipe(
|
||||
tap(internal$),
|
||||
tap(state => internal$.next(state)),
|
||||
finalize(() => internal$.complete()),
|
||||
map(state => ({ ref: el, ...state }))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import {
|
||||
} from "rxjs"
|
||||
import {
|
||||
distinctUntilKeyChanged,
|
||||
finalize,
|
||||
map,
|
||||
observeOn,
|
||||
tap
|
||||
@@ -139,7 +140,8 @@ export function mountHeaderTitle(
|
||||
/* Create and return component */
|
||||
return watchHeaderTitle(headline, options)
|
||||
.pipe(
|
||||
tap(internal$),
|
||||
tap(state => internal$.next(state)),
|
||||
finalize(() => internal$.complete()),
|
||||
map(state => ({ ref: el, ...state }))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import {
|
||||
of
|
||||
} from "rxjs"
|
||||
import {
|
||||
finalize,
|
||||
map,
|
||||
mapTo,
|
||||
mergeMap,
|
||||
@@ -140,7 +141,8 @@ export function mountPalette(
|
||||
const inputs = getElements<HTMLInputElement>("input", el)
|
||||
return watchPalette(inputs)
|
||||
.pipe(
|
||||
tap(internal$),
|
||||
tap(state => internal$.next(state)),
|
||||
finalize(() => internal$.complete()),
|
||||
map(state => ({ ref: el, ...state }))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -95,7 +95,8 @@ export function mountSearch(
|
||||
): Observable<Component<Search>> {
|
||||
const config = configuration()
|
||||
try {
|
||||
const worker = setupSearchWorker(config.search, index$)
|
||||
const url = __search?.worker || config.search
|
||||
const worker = setupSearchWorker(url, index$)
|
||||
|
||||
/* Retrieve query and result components */
|
||||
const query = getComponentElement("search-query", el)
|
||||
@@ -212,7 +213,7 @@ export function mountSearch(
|
||||
|
||||
/* Search sharing */
|
||||
...getComponentElements("search-share", el)
|
||||
.map(child => mountSearchShare(child, { query$ })),
|
||||
.map(child => mountSearchShare(child, { query$ })),
|
||||
|
||||
/* Search suggestions */
|
||||
...getComponentElements("search-suggest", el)
|
||||
|
||||
@@ -83,7 +83,7 @@ export function mountSearchHiglight(
|
||||
)
|
||||
])
|
||||
.pipe(
|
||||
map(([index, url]) => setupSearchHighlighter(index.config)(
|
||||
map(([index, url]) => setupSearchHighlighter(index.config, true)(
|
||||
url.searchParams.get("h")!
|
||||
)),
|
||||
map(fn => {
|
||||
|
||||
@@ -32,6 +32,7 @@ import {
|
||||
distinctUntilChanged,
|
||||
distinctUntilKeyChanged,
|
||||
filter,
|
||||
finalize,
|
||||
map,
|
||||
take,
|
||||
takeLast,
|
||||
@@ -172,7 +173,8 @@ export function mountSearchQuery(
|
||||
/* Create and return component */
|
||||
return watchSearchQuery(el, { tx$, rx$ })
|
||||
.pipe(
|
||||
tap(internal$),
|
||||
tap(state => internal$.next(state)),
|
||||
finalize(() => internal$.complete()),
|
||||
map(state => ({ ref: el, ...state }))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import {
|
||||
import {
|
||||
bufferCount,
|
||||
filter,
|
||||
finalize,
|
||||
map,
|
||||
observeOn,
|
||||
switchMap,
|
||||
@@ -152,7 +153,8 @@ export function mountSearchResult(
|
||||
/* Create and return component */
|
||||
return result$
|
||||
.pipe(
|
||||
tap(internal$),
|
||||
tap(state => internal$.next(state)),
|
||||
finalize(() => internal$.complete()),
|
||||
map(state => ({ ref: el, ...state }))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -25,7 +25,11 @@ import {
|
||||
Subject,
|
||||
fromEvent
|
||||
} from "rxjs"
|
||||
import { map, tap } from "rxjs/operators"
|
||||
import {
|
||||
finalize,
|
||||
map,
|
||||
tap
|
||||
} from "rxjs/operators"
|
||||
|
||||
import { getLocation } from "~/browser"
|
||||
|
||||
@@ -112,7 +116,8 @@ export function mountSearchShare(
|
||||
/* Create and return component */
|
||||
return watchSearchShare(el, options)
|
||||
.pipe(
|
||||
tap(internal$),
|
||||
tap(state => internal$.next(state)),
|
||||
finalize(() => internal$.complete()),
|
||||
map(state => ({ ref: el, ...state }))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import {
|
||||
combineLatestWith,
|
||||
distinctUntilChanged,
|
||||
filter,
|
||||
finalize,
|
||||
map,
|
||||
observeOn,
|
||||
tap
|
||||
@@ -144,7 +145,8 @@ export function mountSearchSuggest(
|
||||
/* Create and return component */
|
||||
return result$
|
||||
.pipe(
|
||||
tap(internal$),
|
||||
tap(state => internal$.next(state)),
|
||||
finalize(() => internal$.complete()),
|
||||
map(() => ({ ref: el }))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import {
|
||||
} from "rxjs"
|
||||
import {
|
||||
distinctUntilChanged,
|
||||
finalize,
|
||||
map,
|
||||
observeOn,
|
||||
tap,
|
||||
@@ -157,7 +158,8 @@ export function mountSidebar(
|
||||
/* Create and return component */
|
||||
return watchSidebar(el, options)
|
||||
.pipe(
|
||||
tap(internal$),
|
||||
tap(state => internal$.next(state)),
|
||||
finalize(() => internal$.complete()),
|
||||
map(state => ({ ref: el, ...state }))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import { NEVER, Observable, Subject, defer, of } from "rxjs"
|
||||
import {
|
||||
catchError,
|
||||
filter,
|
||||
finalize,
|
||||
map,
|
||||
shareReplay,
|
||||
tap
|
||||
@@ -117,7 +118,8 @@ export function mountSource(
|
||||
/* Create and return component */
|
||||
return watchSource(el)
|
||||
.pipe(
|
||||
tap(internal$),
|
||||
tap(state => internal$.next(state)),
|
||||
finalize(() => internal$.complete()),
|
||||
map(state => ({ ref: el, ...state }))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -20,15 +20,22 @@
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import { Observable, Subject, animationFrameScheduler } from "rxjs"
|
||||
import {
|
||||
Observable,
|
||||
Subject,
|
||||
animationFrameScheduler,
|
||||
of
|
||||
} from "rxjs"
|
||||
import {
|
||||
distinctUntilKeyChanged,
|
||||
finalize,
|
||||
map,
|
||||
observeOn,
|
||||
switchMap,
|
||||
tap
|
||||
} from "rxjs/operators"
|
||||
|
||||
import { feature } from "~/_"
|
||||
import { resetTabsState, setTabsState } from "~/actions"
|
||||
import {
|
||||
Viewport,
|
||||
@@ -133,9 +140,14 @@ export function mountTabs(
|
||||
})
|
||||
|
||||
/* Create and return component */
|
||||
return watchTabs(el, options)
|
||||
return (
|
||||
feature("navigation.tabs.sticky")
|
||||
? of({ hidden: false })
|
||||
: watchTabs(el, options)
|
||||
)
|
||||
.pipe(
|
||||
tap(internal$),
|
||||
tap(state => internal$.next(state)),
|
||||
finalize(() => internal$.complete()),
|
||||
map(state => ({ ref: el, ...state }))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import {
|
||||
bufferCount,
|
||||
distinctUntilChanged,
|
||||
distinctUntilKeyChanged,
|
||||
finalize,
|
||||
map,
|
||||
observeOn,
|
||||
scan,
|
||||
@@ -267,7 +268,8 @@ export function mountTableOfContents(
|
||||
const anchors = getElements<HTMLAnchorElement>("[href^=\\#]", el)
|
||||
return watchTableOfContents(anchors, options)
|
||||
.pipe(
|
||||
tap(internal$),
|
||||
tap(state => internal$.next(state)),
|
||||
finalize(() => internal$.complete()),
|
||||
map(state => ({ ref: el, ...state }))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import {
|
||||
bufferCount,
|
||||
distinctUntilChanged,
|
||||
distinctUntilKeyChanged,
|
||||
finalize,
|
||||
map,
|
||||
observeOn,
|
||||
tap,
|
||||
@@ -39,8 +40,10 @@ import {
|
||||
import {
|
||||
resetBackToTopOffset,
|
||||
resetBackToTopState,
|
||||
resetFocusable,
|
||||
setBackToTopOffset,
|
||||
setBackToTopState
|
||||
setBackToTopState,
|
||||
setFocusable
|
||||
} from "~/actions"
|
||||
import { Viewport, setElementFocus } from "~/browser"
|
||||
|
||||
@@ -155,8 +158,10 @@ export function mountBackToTop(
|
||||
if (hidden) {
|
||||
setBackToTopState(el, "hidden")
|
||||
setElementFocus(el, false)
|
||||
setFocusable(el, -1)
|
||||
} else {
|
||||
resetBackToTopState(el)
|
||||
resetFocusable(el)
|
||||
}
|
||||
},
|
||||
|
||||
@@ -164,13 +169,15 @@ export function mountBackToTop(
|
||||
complete() {
|
||||
resetBackToTopOffset(el)
|
||||
resetBackToTopState(el)
|
||||
resetFocusable(el)
|
||||
}
|
||||
})
|
||||
|
||||
/* Create and return component */
|
||||
return watchBackToTop(el, { viewport$, header$, main$ })
|
||||
.pipe(
|
||||
tap(internal$),
|
||||
tap(state => internal$.next(state)),
|
||||
finalize(() => internal$.complete()),
|
||||
map(state => ({ ref: el, ...state }))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -45,11 +45,10 @@ import {
|
||||
switchMap
|
||||
} from "rxjs/operators"
|
||||
|
||||
import { configuration } from "~/_"
|
||||
import { configuration, feature } from "~/_"
|
||||
import {
|
||||
Viewport,
|
||||
ViewportOffset,
|
||||
createElement,
|
||||
getElement,
|
||||
getElements,
|
||||
replaceElement,
|
||||
@@ -60,6 +59,7 @@ import {
|
||||
setViewportOffset
|
||||
} from "~/browser"
|
||||
import { getComponentElement } from "~/components"
|
||||
import { h } from "~/utilities"
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Types
|
||||
@@ -283,7 +283,10 @@ export function setupInstantLoading(
|
||||
"[data-md-component=container]",
|
||||
"[data-md-component=header-topic]",
|
||||
"[data-md-component=logo], .md-logo", // compat
|
||||
"[data-md-component=skip]"
|
||||
"[data-md-component=skip]",
|
||||
...feature("navigation.tabs.sticky")
|
||||
? ["[data-md-component=tabs]"]
|
||||
: []
|
||||
]) {
|
||||
const source = getElement(selector)
|
||||
const target = getElement(selector, replacement)
|
||||
@@ -303,7 +306,7 @@ export function setupInstantLoading(
|
||||
map(() => getComponentElement("container")),
|
||||
switchMap(el => of(...getElements("script", el))),
|
||||
concatMap(el => {
|
||||
const script = createElement("script")
|
||||
const script = h("script")
|
||||
if (el.src) {
|
||||
for (const name of el.getAttributeNames())
|
||||
script.setAttribute(name, el.getAttribute(name)!)
|
||||
|
||||
@@ -167,7 +167,7 @@ export class Search {
|
||||
|
||||
/* Set up document map and highlighter factory */
|
||||
this.documents = setupSearchDocumentMap(docs)
|
||||
this.highlight = setupSearchHighlighter(config)
|
||||
this.highlight = setupSearchHighlighter(config, false)
|
||||
|
||||
/* Set separator for tokenizer */
|
||||
lunr.tokenizer.separator = new RegExp(config.separator)
|
||||
|
||||
@@ -54,11 +54,12 @@ export type SearchHighlightFactoryFn = (query: string) => SearchHighlightFn
|
||||
* Create a search highlighter
|
||||
*
|
||||
* @param config - Search index configuration
|
||||
* @param escape - Whether to escape HTML
|
||||
*
|
||||
* @returns Search highlight factory function
|
||||
*/
|
||||
export function setupSearchHighlighter(
|
||||
config: SearchIndexConfig
|
||||
config: SearchIndexConfig, escape: boolean
|
||||
): SearchHighlightFactoryFn {
|
||||
const separator = new RegExp(config.separator, "img")
|
||||
const highlight = (_: unknown, data: string, term: string) => {
|
||||
@@ -79,8 +80,12 @@ export function setupSearchHighlighter(
|
||||
})`, "img")
|
||||
|
||||
/* Highlight string value */
|
||||
return value => escapeHTML(value)
|
||||
.replace(match, highlight)
|
||||
.replace(/<\/mark>(\s+)<mark[^>]*>/img, "$1")
|
||||
return value => (
|
||||
escape
|
||||
? escapeHTML(value)
|
||||
: value
|
||||
)
|
||||
.replace(match, highlight)
|
||||
.replace(/<\/mark>(\s+)<mark[^>]*>/img, "$1")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ export const enum SearchMessageType {
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* A message containing the data necessary to setup the search index
|
||||
* Message containing the data necessary to setup the search index
|
||||
*/
|
||||
export interface SearchSetupMessage {
|
||||
type: SearchMessageType.SETUP /* Message type */
|
||||
@@ -47,14 +47,14 @@ export interface SearchSetupMessage {
|
||||
}
|
||||
|
||||
/**
|
||||
* A message indicating the search index is ready
|
||||
* Message indicating the search index is ready
|
||||
*/
|
||||
export interface SearchReadyMessage {
|
||||
type: SearchMessageType.READY /* Message type */
|
||||
}
|
||||
|
||||
/**
|
||||
* A message containing a search query
|
||||
* Message containing a search query
|
||||
*/
|
||||
export interface SearchQueryMessage {
|
||||
type: SearchMessageType.QUERY /* Message type */
|
||||
@@ -62,7 +62,7 @@ export interface SearchQueryMessage {
|
||||
}
|
||||
|
||||
/**
|
||||
* A message containing results for a search query
|
||||
* Message containing results for a search query
|
||||
*/
|
||||
export interface SearchResultMessage {
|
||||
type: SearchMessageType.RESULT /* Message type */
|
||||
@@ -72,7 +72,7 @@ export interface SearchResultMessage {
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* A message exchanged with the search worker
|
||||
* Message exchanged with the search worker
|
||||
*/
|
||||
export type SearchMessage =
|
||||
| SearchSetupMessage
|
||||
|
||||
@@ -33,7 +33,7 @@ import { Version, renderVersionSelector } from "~/templates"
|
||||
*/
|
||||
export function setupVersionSelector(): void {
|
||||
const config = configuration()
|
||||
requestJSON<Version[]>(new URL("versions.json", config.base))
|
||||
requestJSON<Version[]>(new URL("../versions.json", config.base))
|
||||
.subscribe(versions => {
|
||||
const topic = getElementOrThrow(".md-header__topic")
|
||||
topic.appendChild(renderVersionSelector(versions))
|
||||
|
||||
@@ -51,7 +51,7 @@ function renderVersion(version: Version): HTMLElement {
|
||||
const config = configuration()
|
||||
|
||||
/* Ensure trailing slash, see https://bit.ly/3rL5u3f */
|
||||
const url = new URL(`${version.version}/`, config.base)
|
||||
const url = new URL(`../${version.version}/`, config.base)
|
||||
return (
|
||||
<li class="md-version__item">
|
||||
<a href={url.toString()} class="md-version__link">
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"rules": {
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
"@typescript-eslint/no-namespace": "off"
|
||||
"@typescript-eslint/no-namespace": "off",
|
||||
"jsdoc/require-jsdoc": "off"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,15 +77,25 @@ function appendChild(el: HTMLElement, child: Child | Child[]): void {
|
||||
/**
|
||||
* JSX factory
|
||||
*
|
||||
* @template T - Element type
|
||||
*
|
||||
* @param tag - HTML tag
|
||||
* @param attributes - HTML attributes
|
||||
* @param children - Child elements
|
||||
*
|
||||
* @returns Element
|
||||
*/
|
||||
export function h(
|
||||
tag: string, attributes: Attributes | null, ...children: Child[]
|
||||
): HTMLElement {
|
||||
export function h<T extends keyof HTMLElementTagNameMap>(
|
||||
tag: T, attributes?: Attributes | null, ...children: Child[]
|
||||
): HTMLElementTagNameMap[T]
|
||||
|
||||
export function h<T extends h.JSX.Element>(
|
||||
tag: string, attributes?: Attributes | null, ...children: Child[]
|
||||
): T
|
||||
|
||||
export function h<T extends h.JSX.Element>(
|
||||
tag: string, attributes?: Attributes | null, ...children: Child[]
|
||||
): T {
|
||||
const el = document.createElement(tag)
|
||||
|
||||
/* Set attributes, if any */
|
||||
@@ -101,7 +111,7 @@ export function h(
|
||||
appendChild(el, child)
|
||||
|
||||
/* Return element */
|
||||
return el
|
||||
return el as T
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user